Panoptes 1.0.0
Endpoint Detection and Response
Loading...
Searching...
No Matches
Classes | Functions | Variables
callbacks.cpp File Reference
#include "callbacks.h"
#include "inject.h"
#include "pano_query.h"
#include <ntstrsafe.h>
#include "shellcode.h"

Go to the source code of this file.

Classes

struct  InjectArgs
 

Functions

PVOID NTAPI RtlxFindExportedRoutineByName (_In_ PVOID DllBase, _In_ PANSI_STRING ExportName)
 
OB_PREOP_CALLBACK_STATUS PreOperationCallback (PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION OperationInformation)
 
PPANO_PROCESS_INFO GetProcessInfo (HANDLE ProcessId)
 
VOID RemoveProcessInfo (HANDLE ProcessId)
 
void NTAPI KernelRoutine (PKAPC apc, PKNORMAL_ROUTINE *NormalRoutine, PVOID *NormalContext, PVOID *SystemArgument1, PVOID *SystemArgument2)
 
BOOLEAN CanInject (PPANO_PROCESS_INFO processInfo)
 
VOID InjectDllKernelApc (PVOID NormalContext, PVOID SystemArgument1, PVOID SystemArgument2)
 
NTSTATUS InstallKernelModeApcToInjectDll (HANDLE ProcessId)
 
BOOLEAN Is64BitProcess (PEPROCESS targetProcess)
 
VOID LoadImageNotifyRoutine (PUNICODE_STRING FullImageName, HANDLE ProcessId, PIMAGE_INFO ImageInfo)
 
VOID ProcessCreateCallback (PEPROCESS Process, HANDLE ProcessId, PPS_CREATE_NOTIFY_INFO CreateInfo)
 
NTSTATUS InitializeKernelCallbacks ()
 
VOID RemoveCallbacks ()
 

Variables

LIST_ENTRY g_ProcessList {}
 
KSPIN_LOCK g_ProcessListLock {}
 
PVOID g_ObRegistrationHandle {}
 

Function Documentation

◆ CanInject()

BOOLEAN CanInject ( PPANO_PROCESS_INFO  processInfo)

Definition at line 253 of file callbacks.cpp.

254{
255 if (processInfo->ntdllLoaded && processInfo->kernel32Loaded && processInfo->kernelBaseLoaded)
256 {
257 return TRUE;
258 }
259 return FALSE;
260}
BOOLEAN ntdllLoaded
Definition structs.h:10
BOOLEAN kernel32Loaded
Definition structs.h:11
BOOLEAN kernelBaseLoaded
Definition structs.h:12

References _PANO_PROCESS_INFO::kernel32Loaded, _PANO_PROCESS_INFO::kernelBaseLoaded, and _PANO_PROCESS_INFO::ntdllLoaded.

Referenced by LoadImageNotifyRoutine().

◆ GetProcessInfo()

PPANO_PROCESS_INFO GetProcessInfo ( HANDLE  ProcessId)

Definition at line 207 of file callbacks.cpp.

208{
209 //KIRQL OldIRQL;
210 //ExAcquireSpinLock(&g_ProcessListLock, &OldIRQL);
211 PLIST_ENTRY entry = g_ProcessList.Flink;
212 while (entry != &g_ProcessList) {
213 PPANO_PROCESS_INFO processInfo = CONTAINING_RECORD(entry, PANO_PROCESS_INFO, ListEntry);
214 if (processInfo->ProcessId == ProcessId) {
215 return processInfo;
216 }
217 entry = entry->Flink;
218 }
219 //ExReleaseSpinLock(&g_ProcessListLock, NULL);
220 return NULL;
221}
LIST_ENTRY g_ProcessList
Definition callbacks.cpp:8
HANDLE ProcessId
Definition structs.h:8

References g_ProcessList, and _PANO_PROCESS_INFO::ProcessId.

Referenced by InjectDllKernelApc(), and LoadImageNotifyRoutine().

◆ InitializeKernelCallbacks()

NTSTATUS InitializeKernelCallbacks ( )

Definition at line 558 of file callbacks.cpp.

559{
560 PAGED_CODE();
561 NTSTATUS status;
562 //UNICODE_STRING callbackAltitude;
564 //RtlInitUnicodeString(&callbackAltitude, L"1931");
565
566 //OB_CALLBACK_REGISTRATION callbackRegistration;
567 //OB_OPERATION_REGISTRATION operationRegistration;
568 //RtlSecureZeroMemory(&operationRegistration, sizeof(OB_OPERATION_REGISTRATION));
569 //RtlSecureZeroMemory(&callbackRegistration, sizeof(OB_CALLBACK_REGISTRATION));
570 //operationRegistration.ObjectType = PsProcessType;
571 //operationRegistration.Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE;
572 //operationRegistration.PreOperation = PreOperationCallback;
574 //operationRegistration.PostOperation = NULL;
575
576 //callbackRegistration.Version = OB_FLT_REGISTRATION_VERSION;
577 //callbackRegistration.OperationRegistrationCount = 1;
578 //callbackRegistration.Altitude = callbackAltitude;
579 //callbackRegistration.OperationRegistration = &operationRegistration;
580 //callbackRegistration.RegistrationContext = NULL;
581
582 //status = ObRegisterCallbacks(&callbackRegistration, &g_ObRegistrationHandle);
583 //if (!NT_SUCCESS(status)) {
584 // DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[!] Panoptes: Driver Failed to Set Object Registration Callbacks - Ensure /INTEGRITYCHECK is added to the linker options\n");
585 // return status;
586 //}
587 //DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[+] Panoptes: Set Object Registration Callbacks\n");
588
589 InitializeListHead(&g_ProcessList);
590 //KeInitializeSpinLock(&g_ProcessListLock);
591 status = PsSetCreateProcessNotifyRoutineEx(ProcessCreateCallback, FALSE);
592 if (!NT_SUCCESS(status)) {
593 //ObUnRegisterCallbacks(g_ObRegistrationHandle);
594 DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[!] Panoptes: Driver Failed to Set Process Creation Notify Routine Notify Routine - Ensure /INTEGRITYCHECK is added to the linker options\n");
595 return status;
596 }
597 DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[+] Panoptes: Set Process Creation Notify Callbacks\n");
598
599 status = PsSetLoadImageNotifyRoutine(LoadImageNotifyRoutine);
600 if (!NT_SUCCESS(status)) {
601 NTSTATUS removeStatus = PsSetCreateProcessNotifyRoutineEx(ProcessCreateCallback, TRUE);
602 if (!NT_SUCCESS(removeStatus)) {
603 DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[!] Panoptes: Driver Failed to remove callback for Set Process Creation Notify Routine Notify Routine\n");
604 return removeStatus;
605 }
606 DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[!] Panoptes: Driver Failed to Set Process Load Image Notify Routine - Ensure /INTEGRITYCHECK is added to the linker options\n");
607 return status;
608 }
609 DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[+] Panoptes: Set Image Load Notify Callbacks\n");
610
611 return STATUS_SUCCESS;
612}
VOID LoadImageNotifyRoutine(PUNICODE_STRING FullImageName, HANDLE ProcessId, PIMAGE_INFO ImageInfo)
VOID ProcessCreateCallback(PEPROCESS Process, HANDLE ProcessId, PPS_CREATE_NOTIFY_INFO CreateInfo)

References g_ProcessList, LoadImageNotifyRoutine(), and ProcessCreateCallback().

Referenced by DriverEntry().

◆ InjectDllKernelApc()

VOID InjectDllKernelApc ( PVOID  NormalContext,
PVOID  SystemArgument1,
PVOID  SystemArgument2 
)

Definition at line 262 of file callbacks.cpp.

263{
264 DbgPrint("InjectDll Entered");
265 HANDLE pProcessId = (HANDLE)NormalContext;
266 UNREFERENCED_PARAMETER(SystemArgument1);
267 UNREFERENCED_PARAMETER(SystemArgument2);
268
269 if (nullptr == pProcessId)
270 {
271 DbgPrint("InjectDll - pProcessId is null");
272 }
273
274 PPANO_PROCESS_INFO pi = GetProcessInfo(pProcessId);
275 ANSI_STRING loadDllRoutineName = RTL_CONSTANT_STRING("LoadLibraryExW");
276 PVOID shellcodeAddress = RtlxFindExportedRoutineByName(pi->kernel32BaseAddress, &loadDllRoutineName);
277
278
279
280 UNICODE_STRING dllToInject;
281 UNICODE_STRING dllFullPathx64;
282 UNICODE_STRING dllFullPathx86;
283 RtlInitUnicodeString(&dllFullPathx64, L"C:\\Program Files\\Panoptes\\PanoptesDLLx64.dll");
284 RtlInitUnicodeString(&dllFullPathx86, L"C:\\Program Files\\Panoptes\\PanoptesDLLx86.dll");
285 PVOID allocatedAddressContainingDllFullPath = nullptr;
286
287 if (pi->is64Bit)
288 {
289 dllToInject = dllFullPathx64;
290 }
291 else
292 {
293 dllToInject = dllFullPathx86;
294 }
295
296 NTSTATUS status = ZwAllocateVirtualMemory(NtCurrentProcess(), &allocatedAddressContainingDllFullPath, 0, (PSIZE_T)&dllToInject.Length, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
297 if (!NT_SUCCESS(status))
298 {
299 DbgPrint("Error: Unable to allocate memory in the target process.");
300 return;
301 }
302 RtlCopyMemory(allocatedAddressContainingDllFullPath, dllToInject.Buffer, dllToInject.Length);
303
304 PKAPC pKapc = (PKAPC)ExAllocatePool2(POOL_FLAG_NON_PAGED, sizeof(KAPC), 'tikt'); // Allocate the APC object
305 if (!pKapc)
306 {
307 DbgPrint("Error: Unable to allocate the APC object.");
308 ZwFreeVirtualMemory(NtCurrentProcess(), &allocatedAddressContainingDllFullPath, (PSIZE_T)&dllToInject.Length, MEM_RELEASE); // Free the allocated memory
309 return;
310 }
311
312 KeInitializeApc(pKapc, KeGetCurrentThread(), OriginalApcEnvironment, KernelRoutine, NULL, (PKNORMAL_ROUTINE)(shellcodeAddress), UserMode, allocatedAddressContainingDllFullPath); // Initialize the APC
313
314 DbgPrint("Inserting APC to target thread");
315 if (!KeInsertQueueApc(pKapc, NULL, NULL, IO_NO_INCREMENT))
316 {
317 DbgPrint("Error: Unable to insert APC to target thread.");
318 ZwFreeVirtualMemory(NtCurrentProcess(), &allocatedAddressContainingDllFullPath, (PSIZE_T)&dllToInject.Length, MEM_RELEASE); // Free the allocated memory
319 ExFreePool(pKapc); // Free the APC object
320 return;
321 }
322
323 KeTestAlertThread(UserMode);
324
325 DbgPrint("InjectDllKernelApc exiting");
326}
PPANO_PROCESS_INFO GetProcessInfo(HANDLE ProcessId)
void NTAPI KernelRoutine(PKAPC apc, PKNORMAL_ROUTINE *NormalRoutine, PVOID *NormalContext, PVOID *SystemArgument1, PVOID *SystemArgument2)
PVOID NTAPI RtlxFindExportedRoutineByName(_In_ PVOID DllBase, _In_ PANSI_STRING ExportName)
Definition callbacks.cpp:14
BOOLEAN NTAPI KeTestAlertThread(IN KPROCESSOR_MODE AlertMode)
VOID(NTAPI * PKNORMAL_ROUTINE)(_In_ PVOID NormalContext, _In_ PVOID SystemArgument1, _In_ PVOID SystemArgument2)
Definition inject.h:208
BOOLEAN NTAPI KeInsertQueueApc(_Inout_ PRKAPC Apc, _In_opt_ PVOID SystemArgument1, _In_opt_ PVOID SystemArgument2, _In_ KPRIORITY Increment)
@ OriginalApcEnvironment
Definition inject.h:202
VOID NTAPI KeInitializeApc(_Out_ PRKAPC Apc, _In_ PRKTHREAD Thread, _In_ KAPC_ENVIRONMENT Environment, _In_ PKKERNEL_ROUTINE KernelRoutine, _In_opt_ PKRUNDOWN_ROUTINE RundownRoutine, _In_opt_ PKNORMAL_ROUTINE NormalRoutine, _In_opt_ KPROCESSOR_MODE ProcessorMode, _In_opt_ PVOID NormalContext)
PVOID kernel32BaseAddress
Definition structs.h:13
BOOLEAN is64Bit
Definition structs.h:7

References GetProcessInfo(), _PANO_PROCESS_INFO::is64Bit, KeInitializeApc(), KeInsertQueueApc(), _PANO_PROCESS_INFO::kernel32BaseAddress, KernelRoutine(), KeTestAlertThread(), OriginalApcEnvironment, and RtlxFindExportedRoutineByName().

Referenced by InstallKernelModeApcToInjectDll().

◆ InstallKernelModeApcToInjectDll()

NTSTATUS InstallKernelModeApcToInjectDll ( HANDLE  ProcessId)

Definition at line 328 of file callbacks.cpp.

329{
330 PRKAPC pKapc = nullptr;
331 PETHREAD pThread = nullptr;
332
333 pKapc = (PKAPC)ExAllocatePool2(POOL_FLAG_NON_PAGED, sizeof(KAPC), 'tiky'); // Allocate the APC object
334 if (nullptr == pKapc)
335 {
336 DbgPrint("InstallKernelModeApcToInjectDll Failed to allocate memory for the APC");
337 return STATUS_INSUFFICIENT_RESOURCES;
338 }
339
340 pThread = KeGetCurrentThread();
341 KeInitializeApc(pKapc, pThread,
343 KernelRoutine, NULL,
345 KernelMode, (PVOID)ProcessId);
346 if (!KeInsertQueueApc(pKapc, NULL, NULL, IO_NO_INCREMENT))
347 {
348 DbgPrint("InstallKernelModeApcToInjectDll Failed to insert APC");
349 ExFreePool(pKapc); // Free the APC object
350 return STATUS_UNSUCCESSFUL;
351 }
352 else
353 {
354 DbgPrint("InstallKernelModeApcToInjectDll APC delivered");
355 }
356
357 return STATUS_SUCCESS;
358}
VOID InjectDllKernelApc(PVOID NormalContext, PVOID SystemArgument1, PVOID SystemArgument2)

References InjectDllKernelApc(), KeInitializeApc(), KeInsertQueueApc(), KernelRoutine(), and OriginalApcEnvironment.

Referenced by LoadImageNotifyRoutine().

◆ Is64BitProcess()

BOOLEAN Is64BitProcess ( PEPROCESS  targetProcess)

Definition at line 360 of file callbacks.cpp.

360 {
361 UINT64* processAsUint64 = reinterpret_cast<UINT64*>(targetProcess);
362 PVOID* wow64ProcessPtr = reinterpret_cast<PVOID*>(processAsUint64 + 0x580 / sizeof(UINT64));
363 if (*wow64ProcessPtr == NULL)
364 {
365 return TRUE;
366 }
367 return FALSE;
368}

Referenced by LoadImageNotifyRoutine().

◆ KernelRoutine()

void NTAPI KernelRoutine ( PKAPC  apc,
PKNORMAL_ROUTINE NormalRoutine,
PVOID *  NormalContext,
PVOID *  SystemArgument1,
PVOID *  SystemArgument2 
)

Definition at line 237 of file callbacks.cpp.

238{
239 UNREFERENCED_PARAMETER(NormalRoutine);
240 UNREFERENCED_PARAMETER(NormalContext);
241 UNREFERENCED_PARAMETER(SystemArgument1);
242 UNREFERENCED_PARAMETER(SystemArgument2);
243
244 ExFreePool(apc);
245}

Referenced by InjectDllKernelApc(), and InstallKernelModeApcToInjectDll().

◆ LoadImageNotifyRoutine()

VOID LoadImageNotifyRoutine ( PUNICODE_STRING  FullImageName,
HANDLE  ProcessId,
PIMAGE_INFO  ImageInfo 
)

Definition at line 370 of file callbacks.cpp.

371{
372 PAGED_CODE();
373 UNREFERENCED_PARAMETER(ImageInfo);
374
375 PPANO_PROCESS_INFO processInfo = GetProcessInfo(ProcessId);
376 if (!processInfo || processInfo->Injected)
377 {
378 return;
379 }
380
381 if (PsIsProtectedProcess(PsGetCurrentProcess()))
382 {
383 DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[-] Panoptes: Skipping protected process %llu", (ULONG64)ProcessId);
384 RemoveProcessInfo(ProcessId);
385 return;
386 }
387
388 if (!CanInject(processInfo))
389 {
390 UNICODE_STRING ntdllLoadImage;
391 RtlInitUnicodeString(&ntdllLoadImage, L"ntdll.dll");
392 if (wcsstr(FullImageName->Buffer, ntdllLoadImage.Buffer) != NULL) {
393 //DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[+] Panoptes: Loaded ntdll in %llu\n", (ULONG64)ProcessId);
394 processInfo->ntdllLoaded = TRUE;
395 return;
396 }
397
398 UNICODE_STRING kernel32LoadImage;
399 RtlInitUnicodeString(&kernel32LoadImage, L"kernel32.dll");
400 if (wcsstr(FullImageName->Buffer, kernel32LoadImage.Buffer) != NULL) {
401 //DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[+] Panoptes: Loaded kernel32 in %llu\n", (ULONG64)ProcessId);
402 processInfo->kernel32Loaded = TRUE;
403 processInfo->kernel32BaseAddress = ImageInfo->ImageBase;
404 return;
405 }
406
407 UNICODE_STRING kernelbaseLoadImage;
408 RtlInitUnicodeString(&kernelbaseLoadImage, L"KernelBase.dll");
409 if (wcsstr(FullImageName->Buffer, kernelbaseLoadImage.Buffer) != NULL) {
410 //DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[+] Panoptes: Loaded kernelbase in %llu\n", (ULONG64)ProcessId);
411 processInfo->kernelBaseLoaded = TRUE;
412 return;
413 }
414 }
415 else
416 {
417 PEPROCESS targetProcess = NULL;
418 NTSTATUS status = PsLookupProcessByProcessId(ProcessId, &targetProcess);
419 if (!NT_SUCCESS(status)) {
420 return;
421 }
422
423 PUNICODE_STRING processPath{};
424 status = SeLocateProcessImageName(targetProcess, &processPath);
425 if (!NT_SUCCESS(status)) {
426 DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[-] Panoptes: Failed to get process name, status: 0x%X\n", status);
427 return;
428 }
429
430 processInfo->is64Bit = Is64BitProcess(targetProcess);
431 if (processInfo->is64Bit) {
432 DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[+] Panoptes: Injecting into x64: (%llu) %wZ\n", (ULONG64)ProcessId, processPath);
433 }
434 else {
435 DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[+] Panoptes: Injecting Into x86: (%llu) %wZ\n", (ULONG64)ProcessId, processPath);
436 }
437
439 processInfo->Injected = TRUE;
440 }
441
442 //PEPROCESS ProcessStruct;
443 //PsLookupProcessByProcessId(ProcessId, &ProcessStruct);
444 // We dont want to deal with trying to inject into protected processes
445 //if (PsIsProtectedProcess(ProcessStruct))
446 //{
447 // //RemoveProcessInfoByProcessId(ProcessId);
448 // return;
449 //}
450 //if (ZwQueryInformationProcessPtr == NULL)
451 //{
452 // DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[-] Panoptes: Cannot resolve ZwQueryInformationProcess\n");
453 // InitializeZwQueryInformationProcessCallback();
454 //}
455 //ZwQueryInformationProcessPtr(
456 // ProcessStruct,
457 // ProcessBasicInformation,
458 // NULL,
459 // 0,
460 // NULL
461 //);
462 //HANDLE processHandle;
463 //NTSTATUS status = ObOpenObjectByPointer(
464 // ProcessStruct,
465 // OBJ_KERNEL_HANDLE,
466 // NULL,
467 // PROCESS_ALL_ACCESS,
468 // *PsProcessType,
469 // KernelMode,
470 // &processHandle
471 //);
472 //PROCESS_BASIC_INFORMATION pbi;
473 //ULONG returnLength;
474 //status = ZwQueryInformationProcessPtr(
475 // processHandle,
476 // ProcessBasicInformation,
477 // &pbi,
478 // sizeof(PROCESS_BASIC_INFORMATION),
479 // &returnLength
480 //);
481 //if (!processInfo->LdrLoadDllRoutineAddress) {
482 // ANSI_STRING ldrLoadDll;
483 // RtlInitAnsiString(&ldrLoadDll, "LdrLoadDll");
484 // UNICODE_STRING kernel32LoadImage;
485 // RtlInitUnicodeString(&kernel32LoadImage, L"*\\ntdll.dll");
486 // if (FsRtlIsNameInExpression(&kernel32LoadImage, FullImageName, TRUE, NULL)) {
487 // processInfo->LdrLoadDllRoutineAddress = RtlFindExportedRoutineByName((PVOID)ImageInfo->ImageBase, ldrLoadDll.Buffer);
488 // processInfo->NtdllLoaded = TRUE;
489 // return;
490 // }
491 //}
492 //else
493 //{
494 // //UINT64 Process, ProcessHead;
495 // //NTSTATUS status = PsLookupProcessByProcessId(ProcessId, (PEPROCESS*)&ProcessHead);
496 // //if (!NT_SUCCESS(status))
497 // //{
498 // // return;
499 // //}
500 // //Process = ProcessHead;
501 // //UINT64 Thread, ThreadHead = *(UINT64*)(Process + 0x5e0) - 0x538; // Thread->ThreadListHead.Flink
502 // //Thread = ThreadHead;
503 // //bool found = false;
504 // //do {
505 // // if (*(UINT32*)(Thread + 0x74) & (1 << 4)) { // Thread.Tcb.MiscFlags & Alertable
506 // // found = true;
507 // // break;
508 // // }
509 // // Thread = *(UINT64*)(Thread + 0x538) - 0x538; // Thread->ThreadListEntry.Flink
510 // //} while (Thread != ThreadHead);
511 // DbgBreakPoint();
512 // InjectDLL(ProcessId, processInfo);
513 //}
514
515 return;
516}
BOOLEAN Is64BitProcess(PEPROCESS targetProcess)
NTSTATUS InstallKernelModeApcToInjectDll(HANDLE ProcessId)
VOID RemoveProcessInfo(HANDLE ProcessId)
BOOLEAN CanInject(PPANO_PROCESS_INFO processInfo)
BOOLEAN NTAPI PsIsProtectedProcess(_In_ PEPROCESS Process)
BOOLEAN Injected
Definition structs.h:9

References CanInject(), GetProcessInfo(), _PANO_PROCESS_INFO::Injected, InstallKernelModeApcToInjectDll(), _PANO_PROCESS_INFO::is64Bit, Is64BitProcess(), _PANO_PROCESS_INFO::kernel32BaseAddress, _PANO_PROCESS_INFO::kernel32Loaded, _PANO_PROCESS_INFO::kernelBaseLoaded, _PANO_PROCESS_INFO::ntdllLoaded, PsIsProtectedProcess(), and RemoveProcessInfo().

Referenced by InitializeKernelCallbacks(), and RemoveCallbacks().

◆ PreOperationCallback()

OB_PREOP_CALLBACK_STATUS PreOperationCallback ( PVOID  RegistrationContext,
POB_PRE_OPERATION_INFORMATION  OperationInformation 
)

Definition at line 153 of file callbacks.cpp.

154{
155 PAGED_CODE();
156 UNREFERENCED_PARAMETER(RegistrationContext);
157 UNREFERENCED_PARAMETER(OperationInformation);
158 //if (OperationInformation->ObjectType == *IoDeviceObjectType)
159 //{
160 // ULONG returnLength;
161 // PDEVICE_OBJECT deviceObject = (PDEVICE_OBJECT)OperationInformation->Object;
162 // // Query the object name
163 // NTSTATUS status = ObQueryNameString(deviceObject, NULL, 0, &returnLength);
164 // if (status != STATUS_INFO_LENGTH_MISMATCH)
165 // {
166 // return OB_PREOP_SUCCESS;
167 // }
168 // // Allocate memory for the name information
169 // POBJECT_NAME_INFORMATION objectNameInfo = NULL;
170 // objectNameInfo = (POBJECT_NAME_INFORMATION)ExAllocatePool2(POOL_FLAG_NON_PAGED, returnLength, 'NveD');
171 // if (objectNameInfo == NULL)
172 // {
173 // return OB_PREOP_SUCCESS;
174 // }
175 // // Get the object name
176 // UNICODE_STRING deviceName;
177 // // Initialize the UNICODE_STRING
178 // RtlInitUnicodeString(&deviceName, NULL);
179 // // Allocate a buffer for the device name
180 // deviceName.Buffer = (PWCH)ExAllocatePool2(POOL_FLAG_NON_PAGED, returnLength, 'NveD');
181 // if (deviceName.Buffer == NULL)
182 // {
183 // return OB_PREOP_SUCCESS;
184 // }
185 // status = ObQueryNameString(deviceObject, objectNameInfo, returnLength, &returnLength);
186 // if (NT_SUCCESS(status))
187 // {
188 // // Copy the name to the output parameter
189 // RtlCopyUnicodeString(&deviceName, &objectNameInfo->Name);
190 // }
191 // if (deviceName.Buffer && wcsstr(deviceName.Buffer, L"\\Device\\NamedPipe\\") != NULL)
192 // {
193 // DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[+] Panoptes: Named Pipe created: %wZ\n", deviceName.Buffer);
194 // }
195 // return OB_PREOP_SUCCESS;
196 //}
197
198 return OB_PREOP_SUCCESS;
199}

◆ ProcessCreateCallback()

VOID ProcessCreateCallback ( PEPROCESS  Process,
HANDLE  ProcessId,
PPS_CREATE_NOTIFY_INFO  CreateInfo 
)

Definition at line 518 of file callbacks.cpp.

519{
520 UNREFERENCED_PARAMETER(Process);
521
522 if (CreateInfo != NULL) {
523 UNICODE_STRING onlyProc;
524 RtlInitUnicodeString(&onlyProc, L"die.exe");
525 if (wcsstr(CreateInfo->ImageFileName->Buffer, onlyProc.Buffer) != NULL) {
526 PPANO_PROCESS_INFO processInfo = (PPANO_PROCESS_INFO)ExAllocatePool2(POOL_FLAG_NON_PAGED, sizeof(PANO_PROCESS_INFO), 'corP');
527 if (processInfo) {
528 processInfo->ProcessId = ProcessId;
529 processInfo->Injected = FALSE;
530 processInfo->ntdllLoaded = FALSE;
531 processInfo->kernel32Loaded = FALSE;
532 processInfo->kernelBaseLoaded = FALSE;
533
534 InsertTailList(&g_ProcessList, &processInfo->ListEntry);
535 }
536
538 NTSTATUS status = QueryProcessMitigationPolicy(ProcessId, &policyInfo);
539 if (!NT_SUCCESS(status)) {
540 DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[-] Panoptes: Failed to get process mitigation policy, status: 0x%X\n", status);
541 }
542 }
543
544 //if (CreateInfo->ImageFileName->Buffer != NULL) {
545 //DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[+] Panoptes: Process Starting: %wZ\n", CreateInfo->ImageFileName->Buffer);
546
547
548 // //EventWriteProcessCreation(NULL, (UINT64)ProcessId, processPath->Buffer, (UINT64)CreateInfo->ParentProcessId, 0, (UINT64)&policyInfo);
549 // EventWriteProcessCreation(NULL, (UINT64)ProcessId, processPath->Buffer, (UINT64)CreateInfo->ParentProcessId, 0, 0);
550 // ExFreePool(processPath->Buffer);
551 //}
552 }
553 else {
554 RemoveProcessInfo(ProcessId);
555 }
556}
NTSTATUS QueryProcessMitigationPolicy(HANDLE ProcessId, PROCESS_MITIGATION_POLICY_INFORMATION *policyInfo)
Definition pano_query.cpp:5
LIST_ENTRY ListEntry
Definition structs.h:6
struct _PANO_PROCESS_INFO * PPANO_PROCESS_INFO

References g_ProcessList, _PANO_PROCESS_INFO::Injected, _PANO_PROCESS_INFO::kernel32Loaded, _PANO_PROCESS_INFO::kernelBaseLoaded, _PANO_PROCESS_INFO::ListEntry, _PANO_PROCESS_INFO::ntdllLoaded, _PANO_PROCESS_INFO::ProcessId, QueryProcessMitigationPolicy(), and RemoveProcessInfo().

Referenced by InitializeKernelCallbacks(), and RemoveCallbacks().

◆ RemoveCallbacks()

VOID RemoveCallbacks ( )

Definition at line 614 of file callbacks.cpp.

614 {
615 //ObUnRegisterCallbacks(g_ObRegistrationHandle);
616 PsSetCreateProcessNotifyRoutineEx(ProcessCreateCallback, TRUE);
617 PsRemoveLoadImageNotifyRoutine(LoadImageNotifyRoutine);
618 return;
619}

References LoadImageNotifyRoutine(), and ProcessCreateCallback().

Referenced by UnloadPanoptes().

◆ RemoveProcessInfo()

VOID RemoveProcessInfo ( HANDLE  ProcessId)

Definition at line 223 of file callbacks.cpp.

224{
225 PLIST_ENTRY entry = g_ProcessList.Flink;
226 while (entry != &g_ProcessList) {
227 PPANO_PROCESS_INFO processInfo = CONTAINING_RECORD(entry, PANO_PROCESS_INFO, ListEntry);
228 if (processInfo->ProcessId == ProcessId) {
229 RemoveEntryList(entry);
230 return;
231 }
232 entry = entry->Flink;
233 }
234 return;
235}

References g_ProcessList, and _PANO_PROCESS_INFO::ProcessId.

Referenced by LoadImageNotifyRoutine(), and ProcessCreateCallback().

◆ RtlxFindExportedRoutineByName()

PVOID NTAPI RtlxFindExportedRoutineByName ( _In_ PVOID  DllBase,
_In_ PANSI_STRING  ExportName 
)

Definition at line 14 of file callbacks.cpp.

18{
19 //
20 // RtlFindExportedRoutineByName is not exported by ntoskrnl until Win10.
21 // Following code is borrowed from ReactOS.
22 //
23
24 PULONG NameTable;
25 PUSHORT OrdinalTable;
26 PIMAGE_EXPORT_DIRECTORY ExportDirectory;
27 LONG Low = 0, Mid = 0, High, Ret;
28 USHORT Ordinal;
29 PVOID Function;
30 ULONG ExportSize;
31 PULONG ExportTable;
32
33 //
34 // Get the export directory.
35 //
36
38 TRUE,
40 &ExportSize);
41
42 if (!ExportDirectory)
43 {
44 return NULL;
45 }
46
47 //
48 // Setup name tables.
49 //
50
51 NameTable = (PULONG)((ULONG_PTR)DllBase + ExportDirectory->AddressOfNames);
52 OrdinalTable = (PUSHORT)((ULONG_PTR)DllBase + ExportDirectory->AddressOfNameOrdinals);
53
54 //
55 // Do a binary search.
56 //
57
58 High = ExportDirectory->NumberOfNames - 1;
59 while (High >= Low)
60 {
61 //
62 // Get new middle value.
63 //
64
65 Mid = (Low + High) >> 1;
66
67 //
68 // Compare name.
69 //
70
71 Ret = strcmp(ExportName->Buffer, (PCHAR)DllBase + NameTable[Mid]);
72 if (Ret < 0)
73 {
74 //
75 // Update high.
76 //
77 High = Mid - 1;
78 }
79 else if (Ret > 0)
80 {
81 //
82 // Update low.
83 //
84 Low = Mid + 1;
85 }
86 else
87 {
88 //
89 // We got it.
90 //
91 break;
92 }
93 }
94
95 //
96 // Check if we couldn't find it.
97 //
98
99 if (High < Low)
100 {
101 return NULL;
102 }
103
104 //
105 // Otherwise, this is the ordinal.
106 //
107
108 Ordinal = OrdinalTable[Mid];
109
110 //
111 // Validate the ordinal.
112 //
113
114 if (Ordinal >= ExportDirectory->NumberOfFunctions)
115 {
116 return NULL;
117 }
118
119 //
120 // Resolve the address and write it.
121 //
122
123 ExportTable = (PULONG)((ULONG_PTR)DllBase + ExportDirectory->AddressOfFunctions);
124 Function = (PVOID)((ULONG_PTR)DllBase + ExportTable[Ordinal]);
125
126 //
127 // We found it!
128 //
129
130 NT_ASSERT(
131 (Function < (PVOID)ExportDirectory) ||
132 (Function > (PVOID)((ULONG_PTR)ExportDirectory + ExportSize))
133 );
134
135 return Function;
136}
PVOID NTAPI RtlImageDirectoryEntryToData(_In_ PVOID BaseOfImage, _In_ BOOLEAN MappedAsImage, _In_ USHORT DirectoryEntry, _Out_ PULONG Size)
#define IMAGE_DIRECTORY_ENTRY_EXPORT
Definition inject.h:9
struct _IMAGE_EXPORT_DIRECTORY * PIMAGE_EXPORT_DIRECTORY

References _IMAGE_EXPORT_DIRECTORY::AddressOfFunctions, _IMAGE_EXPORT_DIRECTORY::AddressOfNameOrdinals, _IMAGE_EXPORT_DIRECTORY::AddressOfNames, IMAGE_DIRECTORY_ENTRY_EXPORT, _IMAGE_EXPORT_DIRECTORY::NumberOfFunctions, _IMAGE_EXPORT_DIRECTORY::NumberOfNames, and RtlImageDirectoryEntryToData().

Referenced by InjectDllKernelApc().

Variable Documentation

◆ g_ObRegistrationHandle

PVOID g_ObRegistrationHandle {}

Definition at line 10 of file callbacks.cpp.

10{};

◆ g_ProcessList

LIST_ENTRY g_ProcessList {}

◆ g_ProcessListLock

KSPIN_LOCK g_ProcessListLock {}

Definition at line 9 of file callbacks.cpp.

9{};