For: PsSetLoadImageNotifyRoutine
| 438 | |
| 439 | // For: PsSetLoadImageNotifyRoutine |
| 440 | void LoadImageNotifyRoutine(PUNICODE_STRING FullImageName, HANDLE ProcessId, PIMAGE_INFO ImageInfo) { |
| 441 | UNREFERENCED_PARAMETER(ImageInfo); |
| 442 | |
| 443 | // Still execute even if we are globally disabled, but need kapc injection |
| 444 | if (!g_Settings.enable_logging && !g_Settings.enable_kapc_injection) { |
| 445 | return; |
| 446 | } |
| 447 | if (FullImageName == NULL) { |
| 448 | return; |
| 449 | } |
| 450 | |
| 451 | ULONG64 systemTime; |
| 452 | KeQuerySystemTime(&systemTime); |
| 453 | wchar_t ImageName[PATH_LEN] = { 0 }; |
| 454 | char AsciiImageName[PATH_LEN] = { 0 }; |
| 455 | |
| 456 | // We may only have KAPC injection, and no logging |
| 457 | if (g_Settings.enable_logging) { |
| 458 | PROCESS_INFO* procInfo = LookupProcessInfo(ProcessId); |
| 459 | if (procInfo != NULL && procInfo->observe) { |
| 460 | Unicodestring2wcharAlloc(FullImageName, ImageName, PATH_LEN); |
| 461 | WcharToAscii(ImageName, sizeof(ImageName), AsciiImageName, sizeof(AsciiImageName)); |
| 462 | JsonEscape(AsciiImageName, sizeof(AsciiImageName)); |
| 463 | char ImageLine[DATA_BUFFER_SIZE]; |
| 464 | RtlStringCbPrintfA(ImageLine, DATA_BUFFER_SIZE, "{\"type\":\"kernel\",\"time\":%llu,\"func\":\"image_load\",\"krn_pid\":%llu,\"pid\":%llu,\"image\":\"%s\"}", |
| 465 | systemTime, |
| 466 | (unsigned __int64)PsGetCurrentProcessId(), |
| 467 | (unsigned __int64)ProcessId, |
| 468 | AsciiImageName |
| 469 | ); |
| 470 | LogEvent(ImageLine); |
| 471 | } |
| 472 | } |
| 473 | if (g_Settings.enable_kapc_injection) { |
| 474 | PPROCESS_INFO processInfo = LookupProcessInfo(ProcessId); |
| 475 | if (processInfo != NULL && processInfo->observe) { |
| 476 | // Atomically claim injection: only the first thread to succeed injects. |
| 477 | if (InterlockedCompareExchange(&processInfo->injected, 1, 0) == 0) { |
| 478 | int result = KapcInjectDll(FullImageName, ProcessId, ImageInfo); |
| 479 | if (result) { |
| 480 | LOG_A(LOG_INFO, "Injected DLL into pid: %d\n", ProcessId); |
| 481 | } else { |
| 482 | // Reset so injection can be retried on the next image load. |
| 483 | InterlockedExchange(&processInfo->injected, 0); |
| 484 | } |
| 485 | } |
| 486 | } |
| 487 | } |
| 488 | } |
| 489 | |
| 490 | |
| 491 | // For: ObRegisterCallbacks |
nothing calls this directly
no test coverage detected