MCPcopy Create free account
hub / github.com/NoMercy-ac/NoMercy / QueueUserApc

Function QueueUserApc

Source/Client/NM_Sys/API/ProcessesUtils.cpp:409–480  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

407 {
408 _IRQL_requires_max_(APC_LEVEL)
409 NTSTATUS QueueUserApc(PETHREAD Thread, PKNORMAL_ROUTINE NormalRoutine, PVOID Argument)
410 {
411 auto KeInitializeApc = static_cast<_KeInitializeApc>(Importer::GetKernelProcAddress(L"KeInitializeApc"));
412 auto KeInsertQueueApc = static_cast<_KeInsertQueueApc>(Importer::GetKernelProcAddress(L"KeInsertQueueApc"));
413
414 if (!KeInitializeApc || !KeInsertQueueApc)
415 return STATUS_NOT_IMPLEMENTED;
416
417 // Initializing user APC:
418 auto UserApc = static_cast<PKAPC>(VirtualMemory::AllocFromPool(sizeof(KAPC)));
419 KeInitializeApc(UserApc, Thread, OriginalApcEnvironment,
420 [](PRKAPC Apc, PKNORMAL_ROUTINE NormalRoutine, PVOID NormalContext, PVOID SystemArgument1, PVOID SystemArgument2) -> VOID
421 {
422 UNREFERENCED_PARAMETER(SystemArgument1);
423 UNREFERENCED_PARAMETER(SystemArgument2);
424
425 if (PsIsThreadTerminating(PsGetCurrentThread()))
426 return;
427
428#ifdef _AMD64_
429 // Fixing APC to Wow64-processes:
430 using _PsGetCurrentProcessWow64Process = PEPROCESS(NTAPI*)();
431 auto GetWow64Process = static_cast<_PsGetCurrentProcessWow64Process>(Importer::GetKernelProcAddress(L"PsGetCurrentProcessWow64Process"));
432 if (!GetWow64Process || GetWow64Process())
433 {
434 PsWrapApcWow64Thread(static_cast<PVOID*>(NormalContext), reinterpret_cast<PVOID*>(NormalRoutine));
435 }
436#else
437 UNREFERENCED_PARAMETER(NormalRoutine);
438 UNREFERENCED_PARAMETER(NormalContext);
439#endif
440
441 VirtualMemory::FreePoolMemory(Apc);
442 },
443
444 NULL, NormalRoutine, UserMode, Argument);
445
446 // Enforcing delivery of user APCs:
447 auto KernelApc = static_cast<PKAPC>(VirtualMemory::AllocFromPool(sizeof(KAPC)));
448 KeInitializeApc(KernelApc, Thread, OriginalApcEnvironment,
449 [](PRKAPC Apc, PKNORMAL_ROUTINE NormalRoutine, PVOID NormalContext, PVOID SystemArgument1, PVOID SystemArgument2) -> VOID
450 {
451 UNREFERENCED_PARAMETER(NormalRoutine);
452 UNREFERENCED_PARAMETER(NormalContext);
453 UNREFERENCED_PARAMETER(SystemArgument1);
454 UNREFERENCED_PARAMETER(SystemArgument2);
455
456 // Enforcing all user APCs delivery:
457 auto KeTestAlertThread = static_cast<_KeTestAlertThread>(Importer::GetKernelProcAddress(L"KeTestAlertThread"));
458 if (KeTestAlertThread) KeTestAlertThread(UserMode);
459
460 VirtualMemory::FreePoolMemory(Apc);
461 },
462 NULL, NULL, KernelMode, NULL
463 );
464
465 if (KeInsertQueueApc(UserApc, NULL, NULL, KernelMode))
466 {

Callers 1

KbQueueUserApcFunction · 0.85

Calls 3

GetKernelProcAddressFunction · 0.85
AllocFromPoolFunction · 0.85
FreePoolMemoryFunction · 0.85

Tested by

no test coverage detected