From a98b7bc0ef2b495bc67aa32eb1be48b7b7ba6370 Mon Sep 17 00:00:00 2001 From: Dark Byte Date: Thu, 12 Jan 2017 00:33:51 +0100 Subject: [PATCH] add IOCTL_CE_ENABLE_DRM --- DBKKernel/DBKDrvr.c | 23 ++- DBKKernel/DBKDrvr.h | 2 +- DBKKernel/DBKFunc.h | 3 + DBKKernel/IOPLDispatcher.c | 252 ++++++++++++++++++++---- DBKKernel/IOPLDispatcher.h | 3 + DBKKernel/SOURCES | 3 +- DBKKernel/ces.bat | 1 + DBKKernel/processlist.c | 392 ++++++++++++++++++++++++------------- DBKKernel/processlist.h | 14 +- DBKKernel/sources.ce | 3 +- DBKKernel/sources.cesigned | 5 +- DBKKernel/threads.c | 245 +++++++++++------------ DBKKernel/ultimap2.c | 13 +- 13 files changed, 649 insertions(+), 310 deletions(-) diff --git a/DBKKernel/DBKDrvr.c b/DBKKernel/DBKDrvr.c index 7ac7d4743f..387ef60277 100644 --- a/DBKKernel/DBKDrvr.c +++ b/DBKKernel/DBKDrvr.c @@ -387,9 +387,8 @@ Return Value: //Processlist init #ifndef CETC - ProcessEventCount=0; - KeInitializeSpinLock(&ProcesslistSL); + ExInitializeResourceLite(&ProcesslistR); #endif CreateProcessNotifyRoutineEnabled=FALSE; @@ -673,7 +672,15 @@ void UnloadDriver(PDRIVER_OBJECT DriverObject) if (CreateProcessNotifyRoutineEnabled) { + DbgPrint("Removing process watch"); +#if (NTDDI_VERSION >= NTDDI_VISTASP1) + PsSetCreateProcessNotifyRoutineEx(CreateProcessNotifyRoutineEx,TRUE); +#else PsSetCreateProcessNotifyRoutine(CreateProcessNotifyRoutine,TRUE); +#endif + + + DbgPrint("Removing thread watch"); PsRemoveCreateThreadNotifyRoutine2(CreateThreadNotifyRoutine); } @@ -700,4 +707,16 @@ void UnloadDriver(PDRIVER_OBJECT DriverObject) ExFreePool(BufDeviceString); #endif + CleanProcessList(); + + ExDeleteResourceLite(&ProcesslistR); + + RtlZeroMemory(&ProcesslistR, sizeof(ProcesslistR)); + + if (DRMHandle) + { + DbgPrint("Unregistering DRM handle"); + ObUnRegisterCallbacks(DRMHandle); + DRMHandle = NULL; + } } \ No newline at end of file diff --git a/DBKKernel/DBKDrvr.h b/DBKKernel/DBKDrvr.h index 1183ece309..36e994b3b9 100644 --- a/DBKKernel/DBKDrvr.h +++ b/DBKKernel/DBKDrvr.h @@ -3,7 +3,7 @@ -#define dbkversion 2000021 +#define dbkversion 2000022 diff --git a/DBKKernel/DBKFunc.h b/DBKKernel/DBKFunc.h index b0b8be52fd..ae08060671 100644 --- a/DBKKernel/DBKFunc.h +++ b/DBKKernel/DBKFunc.h @@ -2,6 +2,9 @@ #define DBKFUNC_H #include "ntifs.h" +//#include +#include + #include #include "interruptHook.h" diff --git a/DBKKernel/IOPLDispatcher.c b/DBKKernel/IOPLDispatcher.c index 56a8ac1048..0a0f6d0386 100644 --- a/DBKKernel/IOPLDispatcher.c +++ b/DBKKernel/IOPLDispatcher.c @@ -1,5 +1,6 @@ #pragma warning( disable: 4103) + #include "IOPLDispatcher.h" #include "DBKFunc.h" #include "DBKDrvr.h" @@ -20,9 +21,14 @@ #include "ultimap.h" #include "ultimap2.h" + + UINT64 PhysicalMemoryRanges=0; //initialized once, and used thereafter. If the user adds/removes ram at runtime, screw him and make him the reload the driver UINT64 PhysicalMemoryRangesListSize=0; +PVOID DRMHandle = NULL; +PEPROCESS DRMProcess = NULL; + PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTableShadow=NULL; PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable=NULL; @@ -130,10 +136,121 @@ void CreateRemoteAPC(ULONG threadid,PVOID addresstoexecute) ); KeInsertQueueApc (kApc, addresstoexecute, addresstoexecute, 0); - - } +#define PROCESS_TERMINATE (0x0001) +#define PROCESS_CREATE_THREAD (0x0002) +#define PROCESS_SET_SESSIONID (0x0004) +#define PROCESS_VM_OPERATION (0x0008) +#define PROCESS_VM_READ (0x0010) +#define PROCESS_VM_WRITE (0x0020) +#define PROCESS_DUP_HANDLE (0x0040) +#define PROCESS_CREATE_PROCESS (0x0080) +#define PROCESS_SET_QUOTA (0x0100) +#define PROCESS_SET_INFORMATION (0x0200) +#define PROCESS_QUERY_INFORMATION (0x0400) +#define PROCESS_SUSPEND_RESUME (0x0800) +#define PROCESS_QUERY_LIMITED_INFORMATION (0x1000) + + + +OB_PREOP_CALLBACK_STATUS ThreadPreCallback(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION OperationInformation) +{ + if (DRMProcess == NULL) + return OB_PREOP_SUCCESS; + + if (PsGetCurrentProcess() == DRMProcess) + return OB_PREOP_SUCCESS; + + if (OperationInformation->ObjectType == *PsThreadType) + { + + if (PsGetProcessId(DRMProcess) == PsGetThreadProcessId(OperationInformation->Object)) + { + //probably block it + + if (OperationInformation->Operation == OB_OPERATION_HANDLE_CREATE) + { + //create handle + + ACCESS_MASK da = OperationInformation->Parameters->CreateHandleInformation.DesiredAccess; + + DbgPrint("PID %d opened a handle to the a CE thread with access mask %x", PsGetCurrentProcessId(), da); + + da = da & (THREAD_SET_LIMITED_INFORMATION | THREAD_QUERY_LIMITED_INFORMATION); + + OperationInformation->Parameters->CreateHandleInformation.DesiredAccess = da; + } + else if (OperationInformation->Operation == OB_OPERATION_HANDLE_DUPLICATE) + { + //duplicate handle + ACCESS_MASK da = OperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess; + + DbgPrint("PID %d duplicated a handle to a CE thread with access mask %x", PsGetCurrentProcessId(), da); + + da = da & (THREAD_SET_LIMITED_INFORMATION | THREAD_QUERY_LIMITED_INFORMATION); + OperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess = da; + } + } + } + return OB_PREOP_SUCCESS; +} + + +VOID ThreadPostCallback(PVOID RegistrationContext, POB_POST_OPERATION_INFORMATION OperationInformation) +{ + //DbgPrint("ProcessPostCallback"); +} + + +OB_PREOP_CALLBACK_STATUS ProcessPreCallback(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION OperationInformation) +{ + if (DRMProcess == NULL) + return OB_PREOP_SUCCESS; + + if (PsGetCurrentProcess() == DRMProcess) + return OB_PREOP_SUCCESS; + + if (OperationInformation->ObjectType == *PsProcessType) + { + if (OperationInformation->Object == DRMProcess) + { + //probably block it + + if (OperationInformation->Operation == OB_OPERATION_HANDLE_CREATE) + { + //create handle + + ACCESS_MASK da = OperationInformation->Parameters->CreateHandleInformation.DesiredAccess; + + DbgPrint("PID %d opened a handle to the CE process with access mask %x", PsGetCurrentProcessId(), da); + + da = da & (PROCESS_TERMINATE | PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_SUSPEND_RESUME); + + OperationInformation->Parameters->CreateHandleInformation.DesiredAccess = da; + } + else if (OperationInformation->Operation == OB_OPERATION_HANDLE_DUPLICATE) + { + //duplicate handle + ACCESS_MASK da = OperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess; + + DbgPrint("PID %d duplicated a handle to the CE process with access mask %x", PsGetCurrentProcessId(), da); + + da = da & (PROCESS_TERMINATE | PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_SUSPEND_RESUME); + OperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess = da; + } + } + } + return OB_PREOP_SUCCESS; +} + + +VOID ProcessPostCallback(PVOID RegistrationContext, POB_POST_OPERATION_INFORMATION OperationInformation) +{ + //DbgPrint("ProcessPostCallback"); +} + + BOOL DispatchIoctlDBVM(IN PDEVICE_OBJECT DeviceObject, ULONG IoControlCode, PVOID lpInBuffer, DWORD nInBufferSize, PVOID lpOutBuffer, DWORD nOutBufferSize, PDWORD lpBytesReturned) /* Called if dbvm has loaded the driver. Use this to setup a fake irp @@ -247,35 +364,36 @@ NTSTATUS DispatchIoctl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { PEPROCESS selectedprocess; ULONG processid=*(PULONG)Irp->AssociatedIrp.SystemBuffer; - HANDLE ProcessHandle; - + HANDLE ProcessHandle = GetHandleForProcessID((HANDLE)processid); - ntStatus=STATUS_SUCCESS; - - __try + ntStatus = STATUS_SUCCESS; + if (ProcessHandle == 0) { - ProcessHandle=0; + __try + { + ProcessHandle = 0; - if (PsLookupProcessByProcessId((PVOID)(UINT_PTR)(processid),&selectedprocess)==STATUS_SUCCESS) - { + if (PsLookupProcessByProcessId((PVOID)(UINT_PTR)(processid), &selectedprocess) == STATUS_SUCCESS) + { //DbgPrint("Calling ObOpenObjectByPointer\n"); - ntStatus=ObOpenObjectByPointer ( - selectedprocess, - 0, - NULL, - PROCESS_ALL_ACCESS, - *PsProcessType, - KernelMode, //UserMode, - &ProcessHandle); + ntStatus = ObOpenObjectByPointer( + selectedprocess, + 0, + NULL, + PROCESS_ALL_ACCESS, + *PsProcessType, + KernelMode, //UserMode, + &ProcessHandle); //DbgPrint("ntStatus=%x",ntStatus); + } + } + __except (1) + { + ntStatus = STATUS_UNSUCCESSFUL; } } - __except(1) - { - ntStatus=STATUS_UNSUCCESSFUL; - } *(PUINT64)Irp->AssociatedIrp.SystemBuffer=(UINT64)ProcessHandle; break; @@ -928,21 +1046,31 @@ NTSTATUS DispatchIoctl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) case IOCTL_CE_STARTPROCESSWATCH: { - KIRQL OldIrql; + NTSTATUS r; - - KeAcquireSpinLock(&ProcesslistSL,&OldIrql); + ExAcquireResourceExclusiveLite(&ProcesslistR, TRUE); ProcessEventCount=0; - KeReleaseSpinLock(&ProcesslistSL,OldIrql); + ExReleaseResourceLite(&ProcesslistR); - DbgPrint("IOCTL_CE_STARTPROCESSWATCH\n"); + + CleanProcessList(); + WatcherProcess = PsGetCurrentProcess(); if (CreateProcessNotifyRoutineEnabled==FALSE) { + DbgPrint("calling PsSetCreateProcessNotifyRoutine\n"); - CreateProcessNotifyRoutineEnabled=(PsSetCreateProcessNotifyRoutine(CreateProcessNotifyRoutine,FALSE)==STATUS_SUCCESS); - CreateThreadNotifyRoutineEnabled=(PsSetCreateThreadNotifyRoutine(CreateThreadNotifyRoutine)==STATUS_SUCCESS); + + +#if (NTDDI_VERSION >= NTDDI_VISTASP1) + r=PsSetCreateProcessNotifyRoutineEx(CreateProcessNotifyRoutineEx, FALSE); + CreateProcessNotifyRoutineEnabled = r== STATUS_SUCCESS; +#else + CreateProcessNotifyRoutineEnabled = (PsSetCreateProcessNotifyRoutine(CreateProcessNotifyRoutine,FALSE)==STATUS_SUCCESS); +#endif + if (CreateProcessNotifyRoutineEnabled) + CreateThreadNotifyRoutineEnabled = (PsSetCreateThreadNotifyRoutine(CreateThreadNotifyRoutine) == STATUS_SUCCESS); } ntStatus=(CreateProcessNotifyRoutineEnabled) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL; @@ -950,7 +1078,7 @@ NTSTATUS DispatchIoctl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) if (ntStatus==STATUS_SUCCESS) DbgPrint("CreateProcessNotifyRoutineEnabled worked\n"); else - DbgPrint("CreateProcessNotifyRoutineEnabled failed\n"); + DbgPrint("CreateProcessNotifyRoutineEnabled failed (r=%x)\n",r); break; @@ -960,15 +1088,14 @@ NTSTATUS DispatchIoctl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) case IOCTL_CE_GETPROCESSEVENTS: { - KIRQL OldIrql; - KeAcquireSpinLock(&ProcesslistSL,&OldIrql); + ExAcquireResourceExclusiveLite(&ProcesslistR, TRUE); *(PUCHAR)Irp->AssociatedIrp.SystemBuffer=ProcessEventCount; RtlCopyMemory((PVOID)((UINT_PTR)Irp->AssociatedIrp.SystemBuffer+1),&ProcessEventdata[0],ProcessEventCount*sizeof(ProcessEventdta)); ProcessEventCount=0; //there's room for new events - KeReleaseSpinLock(&ProcesslistSL,OldIrql); + ExReleaseResourceLite(&ProcesslistR); ntStatus=STATUS_SUCCESS; break; @@ -977,15 +1104,13 @@ NTSTATUS DispatchIoctl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) case IOCTL_CE_GETTHREADEVENTS: { - KIRQL OldIrql; - - KeAcquireSpinLock(&ProcesslistSL,&OldIrql); + ExAcquireResourceExclusiveLite(&ProcesslistR, TRUE); *(PUCHAR)Irp->AssociatedIrp.SystemBuffer=ThreadEventCount; RtlCopyMemory((PVOID)((UINT_PTR)Irp->AssociatedIrp.SystemBuffer+1),&ThreadEventData[0],ThreadEventCount*sizeof(ThreadEventDta)); ThreadEventCount=0; //there's room for new events - KeReleaseSpinLock(&ProcesslistSL,OldIrql); + ExReleaseResourceLite(&ProcesslistR); ntStatus=STATUS_SUCCESS; break; @@ -2034,6 +2159,59 @@ NTSTATUS DispatchIoctl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) break; } + case IOCTL_CE_ENABLE_DRM: + { + DRMProcess = PsGetCurrentProcess(); + + if (DRMHandle == NULL) + { + WCHAR wcAltitude[10]; + UNICODE_STRING usAltitude; + OB_CALLBACK_REGISTRATION r; + LARGE_INTEGER tc; + OB_OPERATION_REGISTRATION obr[2]; + int RandomVal; + + tc.QuadPart = 0; + KeQueryTickCount(&tc); + RandomVal = 1000 + (tc.QuadPart % 50000); + + DbgPrint("Activating CE's super advanced DRM"); //yeah right.... + + DbgPrint("RandomVal=%d", RandomVal); + RtlStringCbPrintfW(wcAltitude, sizeof(wcAltitude) - 2, L"%d", RandomVal); + + DbgPrint("wcAltitude=%S", wcAltitude); + RtlInitUnicodeString(&usAltitude, wcAltitude); + + r.Version = OB_FLT_REGISTRATION_VERSION; + r.Altitude = usAltitude; + r.RegistrationContext = NULL; + + + obr[0].ObjectType = PsProcessType; + obr[0].Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE; + obr[0].PreOperation = ProcessPreCallback; + obr[0].PostOperation = ProcessPostCallback; + + obr[1].ObjectType = PsThreadType; + obr[1].Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE; + obr[1].PreOperation = ThreadPreCallback; + obr[1].PostOperation = ThreadPostCallback; + + r.OperationRegistration = obr; + r.OperationRegistrationCount = 2; + + ntStatus = ObRegisterCallbacks(&r, &DRMHandle); + DbgPrint("ntStatus=%X", ntStatus); + } + else + ntStatus = STATUS_SUCCESS; + + + break; + } + default: DbgPrint("Unhandled IO request: %x\n", IoControlCode); break; diff --git a/DBKKernel/IOPLDispatcher.h b/DBKKernel/IOPLDispatcher.h index a695449962..6574dde56e 100644 --- a/DBKKernel/IOPLDispatcher.h +++ b/DBKKernel/IOPLDispatcher.h @@ -108,10 +108,13 @@ #define IOCTL_CE_ULTIMAP2_GETTRACESIZE CTL_CODE(IOCTL_UNKNOWN_BASE, 0x085a, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) #define IOCTL_CE_ULTIMAP2_RESETTRACESIZE CTL_CODE(IOCTL_UNKNOWN_BASE, 0x085b, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) +#define IOCTL_CE_ENABLE_DRM CTL_CODE(IOCTL_UNKNOWN_BASE, 0x085c, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) extern PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTableShadow; extern PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable; +extern PVOID DRMHandle; + #define SYSTEMSERVICE(_function) KeServiceDescriptorTable->ServiceTable[ *(PULONG)((PUCHAR)_function+1)] #define SYSTEMSERVICELINK(_function) KeServiceDescriptorTable->ServiceTable[*((PUCHAR)(*(PULONG)*((PULONG)((PUCHAR)_function+2)))+1)] diff --git a/DBKKernel/SOURCES b/DBKKernel/SOURCES index 159c8638e6..1febd8fdda 100644 --- a/DBKKernel/SOURCES +++ b/DBKKernel/SOURCES @@ -4,4 +4,5 @@ TARGETTYPE=DRIVER TARGETLIBS=$(DDK_LIB_PATH)\Ntstrsafe.lib AMD64_SOURCES=dbkfunca.asm vmxhelpera.asm debuggera.asm vmxoffloada.asm ultimapa.asm noexceptionsa.asm I386_SOURCES=noexceptionsa.asm -SOURCES=DBKDrvr.c DBKFunc.c IOPLDispatcher.c memscan.c threads.c processlist.c vmxhelper.c interrupthook.c debugger.c vmxoffload.c deepkernel.c ultimap.c ultimap2.c noexceptions.c \ No newline at end of file +SOURCES=DBKDrvr.c DBKFunc.c IOPLDispatcher.c memscan.c threads.c processlist.c vmxhelper.c interrupthook.c debugger.c vmxoffload.c deepkernel.c ultimap.c ultimap2.c noexceptions.c +LINK=/INTEGRITYCHECK \ No newline at end of file diff --git a/DBKKernel/ces.bat b/DBKKernel/ces.bat index 02769acb9c..0e779c5d2c 100644 --- a/DBKKernel/ces.bat +++ b/DBKKernel/ces.bat @@ -1,6 +1,7 @@ @echo off command /C echo changing to dos-16 file structure set C_DEFINES= +set LINKER_FLAGS=/INTEGRITYCHECK set copycmd=/Y copy sources.cesigned sources diff --git a/DBKKernel/processlist.c b/DBKKernel/processlist.c index 38986b7097..c57eab911d 100644 --- a/DBKKernel/processlist.c +++ b/DBKKernel/processlist.c @@ -5,6 +5,34 @@ #include "threads.h" #include "memscan.h" +PRTL_GENERIC_TABLE InternalProcessList = NULL; + + +RTL_GENERIC_COMPARE_RESULTS NTAPI ProcessListCompare(__in struct _RTL_GENERIC_TABLE *Table, __in PProcessListData FirstStruct, __in PProcessListData SecondStruct) +{ + if (FirstStruct->ProcessID == SecondStruct->ProcessID) + return GenericEqual; + else + { + if (SecondStruct->ProcessID < FirstStruct->ProcessID) + return GenericLessThan; + else + return GenericGreaterThan; + } +} + +PVOID NTAPI ProcessListAlloc(__in struct _RTL_GENERIC_TABLE *Table, __in CLONG ByteSize) +{ + PVOID r=ExAllocatePoolWithTag(PagedPool, ByteSize, 0); + RtlZeroMemory(r, ByteSize); +} + +VOID NTAPI ProcessListDealloc(__in struct _RTL_GENERIC_TABLE *Table, __in __drv_freesMem(Mem) __post_invalid PVOID Buffer) +{ + ExFreePoolWithTag(Buffer, 0); +} + + VOID GetThreadData(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context) { KIRQL OldIrql; @@ -23,36 +51,37 @@ VOID GetThreadData(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context) selectedthread=NULL; - KeAcquireSpinLock(&ProcesslistSL,&OldIrql); - tid=tempThreadEntry->ThreadID; - AP=&tempThreadEntry->SuspendApc; - PsLookupThreadByThreadId((PVOID)tid,&selectedthread); - - if (selectedthread) + if (ExAcquireResourceSharedLite(&ProcesslistR, TRUE)) { - DbgPrint("PEThread=%p\n",selectedthread); - KeInitializeApc(AP, - (PKTHREAD)selectedthread, - 0, - (PKKERNEL_ROUTINE)Ignore, - (PKRUNDOWN_ROUTINE)NULL, - (PKNORMAL_ROUTINE)SuspendThreadAPCRoutine, - KernelMode, - NULL); - - ObDereferenceObject(selectedthread); - } - else - { - DbgPrint("Failed getting the pethread.\n"); - } - KeReleaseSpinLock(&ProcesslistSL,OldIrql); + tid = tempThreadEntry->ThreadID; + AP = &tempThreadEntry->SuspendApc; + PsLookupThreadByThreadId((PVOID)tid, &selectedthread); + + if (selectedthread) + { + DbgPrint("PEThread=%p\n", selectedthread); + KeInitializeApc(AP, + (PKTHREAD)selectedthread, + 0, + (PKKERNEL_ROUTINE)Ignore, + (PKRUNDOWN_ROUTINE)NULL, + (PKNORMAL_ROUTINE)SuspendThreadAPCRoutine, + KernelMode, + NULL); + + ObDereferenceObject(selectedthread); + } + else + { + DbgPrint("Failed getting the pethread.\n"); + } + } + ExReleaseResourceLite(&ProcesslistR); } VOID CreateThreadNotifyRoutine(IN HANDLE ProcessId,IN HANDLE ThreadId,IN BOOLEAN Create) { - KIRQL OldIrql; PETHREAD CurrentThread; if (KeGetCurrentIrql()==PASSIVE_LEVEL) @@ -62,120 +91,184 @@ VOID CreateThreadNotifyRoutine(IN HANDLE ProcessId,IN HANDLE ThreadId,IN BOOLE // PsSetContextThread (bah, xp only) }*/ - KeAcquireSpinLock(&ProcesslistSL,&OldIrql); //perhaps a check for winxp and then call KeAcquireInStackQueuedSpinLock instead.... - - - if (ThreadEventCount<50) - { - ThreadEventData[ThreadEventCount].Created=Create; - ThreadEventData[ThreadEventCount].ProcessID=(UINT_PTR)ProcessId; - ThreadEventData[ThreadEventCount].ThreadID=(UINT_PTR)ThreadId; + if (ExAcquireResourceExclusiveLite(&ProcesslistR, TRUE)) + { + if (ThreadEventCount < 50) + { + ThreadEventData[ThreadEventCount].Created = Create; + ThreadEventData[ThreadEventCount].ProcessID = (UINT_PTR)ProcessId; + ThreadEventData[ThreadEventCount].ThreadID = (UINT_PTR)ThreadId; - /* if (Create) - DbgPrint("Create ProcessID=%x\nThreadID=%x\n",(UINT_PTR)ProcessId,(UINT_PTR)ThreadId); - else - DbgPrint("Destroy ProcessID=%x\nThreadID=%x\n",(UINT_PTR)ProcessId,(UINT_PTR)ThreadId); - */ + /* if (Create) + DbgPrint("Create ProcessID=%x\nThreadID=%x\n",(UINT_PTR)ProcessId,(UINT_PTR)ThreadId); + else + DbgPrint("Destroy ProcessID=%x\nThreadID=%x\n",(UINT_PTR)ProcessId,(UINT_PTR)ThreadId); + */ - ThreadEventCount++; + ThreadEventCount++; + } } + ExReleaseResourceLite(&ProcesslistR); - - KeReleaseSpinLock(&ProcesslistSL,OldIrql); - - /* - if (CurrentThread!=NULL) - { - DbgPrint("Dereferencing thread\n"); - }*/ - - //signal thread event (if there's one waiting for a signal) KeSetEvent(ThreadEvent, 0, FALSE); KeClearEvent(ThreadEvent); - } } VOID CreateProcessNotifyRoutine( IN HANDLE ParentId, IN HANDLE ProcessId, IN BOOLEAN Create) { - //LARGE_INTEGER wt; - //HANDLE TH; - KIRQL OldIrql; - PEPROCESS CurrentProcess; - //CLIENT_ID CI; - - //DbgPrint("CreateProcessNotifyRoutine called (ParentID=%x ProcessID=%d Create=%d\n",ParentId, ProcessId, Create); + PEPROCESS CurrentProcess = NULL; + HANDLE ProcessHandle = 0; + if (KeGetCurrentIrql()==PASSIVE_LEVEL) { struct ProcessData *tempProcessEntry; - - CurrentProcess=NULL; - PsLookupProcessByProcessId((PVOID)ProcessId,&CurrentProcess); //aquire a spinlock - KeAcquireSpinLock(&ProcesslistSL,&OldIrql); //perhaps a check for winxp and then call KeAcquireInStackQueuedSpinLock instead.... - - //fill in a processcreateblock with data - if (ProcessEventCount<50) - { - ProcessEventdata[ProcessEventCount].Created=Create; - ProcessEventdata[ProcessEventCount].ProcessID=(UINT_PTR)ProcessId; - ProcessEventdata[ProcessEventCount].PEProcess=(UINT_PTR)CurrentProcess; - ProcessEventCount++; - } - - //if (!HiddenDriver) - if (FALSE) //moved till next version - { - if (Create) + if (ExAcquireResourceExclusiveLite(&ProcesslistR, TRUE)) + { + if (WatcherProcess) { - - //allocate a block of memory for the processlist - - tempProcessEntry=ExAllocatePoolWithTag(NonPagedPool,sizeof(struct ProcessData),0); - tempProcessEntry->ProcessID=ProcessId; - tempProcessEntry->PEProcess=CurrentProcess; - tempProcessEntry->Threads=NULL; - - DbgPrint("Allocated a process at:%p\n",tempProcessEntry); - - if (!processlist) + if (PsLookupProcessByProcessId((PVOID)ProcessId, &CurrentProcess) == STATUS_SUCCESS) { - processlist=tempProcessEntry; - processlist->next=NULL; - processlist->previous=NULL; + if (Create) + { + //Open a handle to this process + KAPC_STATE oldstate; + KeStackAttachProcess(WatcherProcess, &oldstate); + __try + { + __try + { + NTSTATUS r = ObOpenObjectByPointer(CurrentProcess, 0, NULL, PROCESS_ALL_ACCESS, *PsProcessType, KernelMode, &ProcessHandle); + if (r == STATUS_SUCCESS) + DbgPrint("Opened handle for pid %d", ProcessId); + else + DbgPrint("Failed opening handle for pid %d"); + } + __except (1) + { + DbgPrint("Exception during ObOpenObjectByPointer"); + } + } + __finally + { + KeUnstackDetachProcess(&oldstate); + } + } } - else + + if (InternalProcessList == NULL) { - tempProcessEntry->next=processlist; - tempProcessEntry->previous=NULL; - processlist->previous=tempProcessEntry; - processlist=tempProcessEntry; + InternalProcessList = ExAllocatePoolWithTag(PagedPool, sizeof(RTL_GENERIC_TABLE), 0); + if (InternalProcessList) + RtlInitializeGenericTable(InternalProcessList, ProcessListCompare, ProcessListAlloc, ProcessListDealloc, NULL); } + + if (InternalProcessList) + { + ProcessListData d, *r; + + d.ProcessID = ProcessId; + d.PEProcess = CurrentProcess; + d.ProcessHandle = ProcessHandle; + + r = RtlLookupElementGenericTable(InternalProcessList, &d); + + if (Create) + { + //add it to the list + if (r) //weird + RtlDeleteElementGenericTable(InternalProcessList, r); + + RtlInsertElementGenericTable(InternalProcessList, &d, sizeof(ProcessListData), NULL); + } + else + { + //remove it from the list (if it's there) + if (r) + { + if (r->ProcessHandle) + ZwClose(r->ProcessHandle); + + RtlDeleteElementGenericTable(InternalProcessList, r); + } + + if (CurrentProcess == WatcherProcess) + { + DbgPrint("CE Closed"); + WatcherProcess = 0; + + CleanProcessList(); //CE closed + } + } + } + else + ZwClose(ProcessHandle); } - else + + + //fill in a processcreateblock with data + if (ProcessEventCount < 50) { - //find this process and delete it - tempProcessEntry=processlist; - while (tempProcessEntry) + ProcessEventdata[ProcessEventCount].Created = Create; + ProcessEventdata[ProcessEventCount].ProcessID = (UINT_PTR)ProcessId; + ProcessEventdata[ProcessEventCount].PEProcess = (UINT_PTR)CurrentProcess; + ProcessEventCount++; + } + + //if (!HiddenDriver) + if (FALSE) //moved till next version + { + if (Create) { - if (tempProcessEntry->ProcessID==ProcessId) - { - int i; - if (tempProcessEntry->next) - tempProcessEntry->next->previous=tempProcessEntry->previous; - if (tempProcessEntry->previous) - tempProcessEntry->previous->next=tempProcessEntry->next; - else - processlist=tempProcessEntry->next; //it had no previous entry, so it's the root + //allocate a block of memory for the processlist + tempProcessEntry = ExAllocatePoolWithTag(PagedPool, sizeof(struct ProcessData), 0); + tempProcessEntry->ProcessID = ProcessId; + tempProcessEntry->PEProcess = CurrentProcess; + tempProcessEntry->Threads = NULL; + DbgPrint("Allocated a process at:%p\n", tempProcessEntry); - /* - if (tempProcessEntry->Threads) + if (!processlist) + { + processlist = tempProcessEntry; + processlist->next = NULL; + processlist->previous = NULL; + } + else + { + tempProcessEntry->next = processlist; + tempProcessEntry->previous = NULL; + processlist->previous = tempProcessEntry; + processlist = tempProcessEntry; + } + } + else + { + //find this process and delete it + tempProcessEntry = processlist; + while (tempProcessEntry) + { + if (tempProcessEntry->ProcessID == ProcessId) { + int i; + if (tempProcessEntry->next) + tempProcessEntry->next->previous = tempProcessEntry->previous; + + if (tempProcessEntry->previous) + tempProcessEntry->previous->next = tempProcessEntry->next; + else + processlist = tempProcessEntry->next; //it had no previous entry, so it's the root + + + + /* + if (tempProcessEntry->Threads) + { struct ThreadData *tempthread,*tempthread2; KIRQL OldIrql2; @@ -186,39 +279,38 @@ VOID CreateProcessNotifyRoutine( IN HANDLE ParentId, IN HANDLE ProcessId, IN B while (tempthread) { - tempthread=tempthread->next; - DbgPrint("Free thread %p (next thread=%p)\n",tempthread2,tempthread); - ExFreePool(tempthread2); - tempthread2=tempthread; - } + tempthread=tempthread->next; + DbgPrint("Free thread %p (next thread=%p)\n",tempthread2,tempthread); + ExFreePool(tempthread2); + tempthread2=tempthread; + } - } + } - - ExFreePool(tempProcessEntry);*/ - i=0; - tempProcessEntry=processlist; - while (tempProcessEntry) - { - i++; - tempProcessEntry=tempProcessEntry->next; - } + ExFreePool(tempProcessEntry);*/ + + i = 0; + tempProcessEntry = processlist; + while (tempProcessEntry) + { + i++; + tempProcessEntry = tempProcessEntry->next; + } - DbgPrint("There are %d processes in the list\n",i); + DbgPrint("There are %d processes in the list\n", i); - break; + break; + } + tempProcessEntry = tempProcessEntry->next; } - tempProcessEntry=tempProcessEntry->next; + + } - } - } - - //release spinlock - KeReleaseSpinLock(&ProcesslistSL,OldIrql); + ExReleaseResourceLite(&ProcesslistR); if (CurrentProcess!=NULL) ObDereferenceObject(CurrentProcess); @@ -230,7 +322,45 @@ VOID CreateProcessNotifyRoutine( IN HANDLE ParentId, IN HANDLE ProcessId, IN B KeClearEvent(ProcessEvent); } } +} + +VOID CreateProcessNotifyRoutineEx(IN HANDLE ParentId, IN HANDLE ProcessId, __in_opt PPS_CREATE_NOTIFY_INFO CreateInfo) +{ + DbgPrint("CreateProcessNotifyRoutineEx"); + CreateProcessNotifyRoutine(ParentId, ProcessId, CreateInfo!=NULL); +} +HANDLE GetHandleForProcessID(IN HANDLE ProcessID) +{ + if (InternalProcessList) + { + ProcessListData d, *r; + d.ProcessID = ProcessID; + r = RtlLookupElementGenericTable(InternalProcessList, &d); + if (r) + return r->ProcessHandle; + } + else + return 0; } +VOID CleanProcessList() +{ + if (InternalProcessList) + { + PProcessListData li; + + while (li = RtlGetElementGenericTable(InternalProcessList, 0)) + { + if (li->ProcessHandle) + ZwClose(li->ProcessHandle); + + RtlDeleteElementGenericTable(InternalProcessList, li); + } + + ExFreePoolWithTag(InternalProcessList, 0); + InternalProcessList = NULL; + } + +} \ No newline at end of file diff --git a/DBKKernel/processlist.h b/DBKKernel/processlist.h index ac3c16614a..3ca0ecd736 100644 --- a/DBKKernel/processlist.h +++ b/DBKKernel/processlist.h @@ -4,6 +4,7 @@ VOID CreateProcessNotifyRoutine(IN HANDLE ParentId, IN HANDLE ProcessId, IN BOOLEAN Create); +VOID CreateProcessNotifyRoutineEx(IN HANDLE ParentId, IN HANDLE ProcessId, __in_opt PPS_CREATE_NOTIFY_INFO CreateInfo); struct ThreadData { @@ -16,6 +17,14 @@ struct ThreadData struct ThreadData *next; }; +typedef struct +{ + HANDLE ProcessID; + PEPROCESS PEProcess; + HANDLE ProcessHandle; +} ProcessListData, *PProcessListData; + + struct ProcessData { HANDLE ProcessID; @@ -37,7 +46,7 @@ PKEVENT ProcessEvent; //HANDLE ProcessEventHandle; BOOLEAN CreateProcessNotifyRoutineEnabled; -KSPIN_LOCK ProcesslistSL; +ERESOURCE ProcesslistR; VOID CreateThreadNotifyRoutine(IN HANDLE ProcessId, IN HANDLE ThreadId, IN BOOLEAN Create); @@ -52,4 +61,7 @@ UCHAR ThreadEventCount; PKEVENT ThreadEvent; //HANDLE ThreadEventHandle; +PEPROCESS WatcherProcess; BOOLEAN CreateThreadNotifyRoutineEnabled; +VOID CleanProcessList(); +HANDLE GetHandleForProcessID(IN HANDLE ProcessID); \ No newline at end of file diff --git a/DBKKernel/sources.ce b/DBKKernel/sources.ce index 159c8638e6..1febd8fdda 100644 --- a/DBKKernel/sources.ce +++ b/DBKKernel/sources.ce @@ -4,4 +4,5 @@ TARGETTYPE=DRIVER TARGETLIBS=$(DDK_LIB_PATH)\Ntstrsafe.lib AMD64_SOURCES=dbkfunca.asm vmxhelpera.asm debuggera.asm vmxoffloada.asm ultimapa.asm noexceptionsa.asm I386_SOURCES=noexceptionsa.asm -SOURCES=DBKDrvr.c DBKFunc.c IOPLDispatcher.c memscan.c threads.c processlist.c vmxhelper.c interrupthook.c debugger.c vmxoffload.c deepkernel.c ultimap.c ultimap2.c noexceptions.c \ No newline at end of file +SOURCES=DBKDrvr.c DBKFunc.c IOPLDispatcher.c memscan.c threads.c processlist.c vmxhelper.c interrupthook.c debugger.c vmxoffload.c deepkernel.c ultimap.c ultimap2.c noexceptions.c +LINK=/INTEGRITYCHECK \ No newline at end of file diff --git a/DBKKernel/sources.cesigned b/DBKKernel/sources.cesigned index 2e507e05cf..4d114f9033 100644 --- a/DBKKernel/sources.cesigned +++ b/DBKKernel/sources.cesigned @@ -3,5 +3,6 @@ TARGETPATH=obj TARGETTYPE=DRIVER TARGETLIBS=$(DDK_LIB_PATH)\ksecdd.lib $(DDK_LIB_PATH)\Ntstrsafe.lib C_DEFINES=/DTOBESIGNED -AMD64_SOURCES=dbkfunca.asm vmxhelpera.asm debuggera.asm vmxoffloada.asm ultimapa.asm -SOURCES=DBKDrvr.c DBKFunc.c IOPLDispatcher.c memscan.c threads.c processlist.c vmxhelper.c interrupthook.c debugger.c vmxoffload.c deepkernel.c ultimap.c ultimap2.c sigcheck.c +AMD64_SOURCES=dbkfunca.asm vmxhelpera.asm debuggera.asm vmxoffloada.asm ultimapa.asm noexceptionsa.asm +I386_SOURCES=noexceptionsa.asm +SOURCES=DBKDrvr.c DBKFunc.c IOPLDispatcher.c memscan.c threads.c processlist.c vmxhelper.c interrupthook.c debugger.c vmxoffload.c deepkernel.c ultimap.c ultimap2.c sigcheck.c noexceptions.c diff --git a/DBKKernel/threads.c b/DBKKernel/threads.c index c781ffbe75..993ead6ec5 100644 --- a/DBKKernel/threads.c +++ b/DBKKernel/threads.c @@ -60,45 +60,45 @@ void DBKSuspendThread(ULONG ThreadID) struct ThreadData *t_data; - KeAcquireSpinLock(&ProcesslistSL,&OldIrql); + if (ExAcquireResourceSharedLite(&ProcesslistR, TRUE)) + { + DbgPrint("Going to suspend this thread\n"); - DbgPrint("Going to suspend this thread\n"); + //find the thread in the threadlist - //find the thread in the threadlist + //find the threadid in the processlist + t_data = GetThreaddata(ThreadID); + if (t_data) + { + DbgPrint("Suspending thread....\n"); - //find the threadid in the processlist - t_data=GetThreaddata(ThreadID); - if (t_data) - { - DbgPrint("Suspending thread....\n"); - - if (!t_data->PEThread) - { - //not yet initialized - t_data->PEThread=(PETHREAD)getPEThread(ThreadID); - KeInitializeApc(&t_data->SuspendApc, - (PKTHREAD)t_data->PEThread, - 0, - (PKKERNEL_ROUTINE)Ignore, - (PKRUNDOWN_ROUTINE)NULL, - (PKNORMAL_ROUTINE)SuspendThreadAPCRoutine, - KernelMode, - t_data); - - } - DbgPrint("x should be %p",t_data); - t_data->suspendcount++; - - if (t_data->suspendcount==1) //not yet suspended so suspend it - KeInsertQueueApc(&t_data->SuspendApc, t_data, t_data, 0); - } - else - DbgPrint("Thread not found in the list\n"); + if (!t_data->PEThread) + { + //not yet initialized + t_data->PEThread = (PETHREAD)getPEThread(ThreadID); + KeInitializeApc(&t_data->SuspendApc, + (PKTHREAD)t_data->PEThread, + 0, + (PKKERNEL_ROUTINE)Ignore, + (PKRUNDOWN_ROUTINE)NULL, + (PKNORMAL_ROUTINE)SuspendThreadAPCRoutine, + KernelMode, + t_data); - KeReleaseSpinLock(&ProcesslistSL,OldIrql); + } + DbgPrint("x should be %p", t_data); + t_data->suspendcount++; + + if (t_data->suspendcount == 1) //not yet suspended so suspend it + KeInsertQueueApc(&t_data->SuspendApc, t_data, t_data, 0); + } + else + DbgPrint("Thread not found in the list\n"); + } + ExReleaseResourceLite(&ProcesslistR); } void DBKResumeThread(ULONG ThreadID) @@ -108,29 +108,29 @@ void DBKResumeThread(ULONG ThreadID) struct ThreadData *t_data; - KeAcquireSpinLock(&ProcesslistSL,&OldIrql); - + if (ExAcquireResourceSharedLite(&ProcesslistR, TRUE)) + { - DbgPrint("Going to resume this thread\n"); + DbgPrint("Going to resume this thread\n"); - //find the thread in the threadlist + //find the thread in the threadlist - //find the threadid in the processlist - t_data=GetThreaddata(ThreadID); - if (t_data) - { - if (t_data->suspendcount) + //find the threadid in the processlist + t_data = GetThreaddata(ThreadID); + if (t_data) { - t_data->suspendcount--; - if (!t_data->suspendcount) //suspendcount=0 so resume - KeReleaseSemaphore(&t_data->SuspendSemaphore,0,1,FALSE); + if (t_data->suspendcount) + { + t_data->suspendcount--; + if (!t_data->suspendcount) //suspendcount=0 so resume + KeReleaseSemaphore(&t_data->SuspendSemaphore, 0, 1, FALSE); + } } + else + DbgPrint("Thread not found in the list\n"); } - else - DbgPrint("Thread not found in the list\n"); - - KeReleaseSpinLock(&ProcesslistSL,OldIrql); + ExReleaseResourceLite(&ProcesslistR); } @@ -142,60 +142,61 @@ void DBKSuspendProcess(ULONG ProcessID) struct ProcessData *tempProcessData=NULL; - KeAcquireSpinLock(&ProcesslistSL,&OldIrql); - + if (ExAcquireResourceSharedLite(&ProcesslistR, TRUE)) + { - DbgPrint("Going to suspend this process\n"); - //find the process in the threadlist + DbgPrint("Going to suspend this process\n"); - tempProcessData=processlist; - while (tempProcessData) - { - if (tempProcessData->ProcessID==(HANDLE)(UINT_PTR)ProcessID) + //find the process in the threadlist + + tempProcessData = processlist; + while (tempProcessData) { - t_data=tempProcessData->Threads; - break; + if (tempProcessData->ProcessID == (HANDLE)(UINT_PTR)ProcessID) + { + t_data = tempProcessData->Threads; + break; + } + tempProcessData = tempProcessData->next; } - tempProcessData=tempProcessData->next; - } - - if (!t_data) - { - DbgPrint("This process was not found\n"); - KeReleaseSpinLock(&ProcesslistSL,OldIrql); - return; //no process found - } + if (!t_data) + { + DbgPrint("This process was not found\n"); + ExReleaseResourceLite(&ProcesslistR); + return; //no process found + } - while (t_data) - { - DbgPrint("Suspending thread....\n"); - if (!t_data->PEThread) + while (t_data) { - //not yet initialized - t_data->PEThread=(PETHREAD)getPEThread((UINT_PTR)t_data->ThreadID); - KeInitializeApc(&t_data->SuspendApc, - (PKTHREAD)t_data->PEThread, - 0, - (PKKERNEL_ROUTINE)Ignore, - (PKRUNDOWN_ROUTINE)NULL, - (PKNORMAL_ROUTINE)SuspendThreadAPCRoutine, - KernelMode, - t_data); - - } - DbgPrint("x should be %p",t_data); - t_data->suspendcount++; - - if (t_data->suspendcount==1) //not yet suspended so suspend it - KeInsertQueueApc(&t_data->SuspendApc, t_data, t_data, 0); - - t_data=t_data->next; //next thread + DbgPrint("Suspending thread....\n"); + + if (!t_data->PEThread) + { + //not yet initialized + t_data->PEThread = (PETHREAD)getPEThread((UINT_PTR)t_data->ThreadID); + KeInitializeApc(&t_data->SuspendApc, + (PKTHREAD)t_data->PEThread, + 0, + (PKKERNEL_ROUTINE)Ignore, + (PKRUNDOWN_ROUTINE)NULL, + (PKNORMAL_ROUTINE)SuspendThreadAPCRoutine, + KernelMode, + t_data); + + } + DbgPrint("x should be %p", t_data); + t_data->suspendcount++; + + if (t_data->suspendcount == 1) //not yet suspended so suspend it + KeInsertQueueApc(&t_data->SuspendApc, t_data, t_data, 0); + + t_data = t_data->next; //next thread + } } - - KeReleaseSpinLock(&ProcesslistSL,OldIrql); + ExReleaseResourceLite(&ProcesslistR); } @@ -207,47 +208,47 @@ void DBKResumeProcess(ULONG ProcessID) struct ProcessData *tempProcessData=NULL; - KeAcquireSpinLock(&ProcesslistSL,&OldIrql); - + if (ExAcquireResourceSharedLite(&ProcesslistR, TRUE)) + { - DbgPrint("Going to suspend this process\n"); + DbgPrint("Going to suspend this process\n"); - //find the process in the threadlist + //find the process in the threadlist - tempProcessData=processlist; - while (tempProcessData) - { - if (tempProcessData->ProcessID==(HANDLE)(UINT_PTR)ProcessID) + tempProcessData = processlist; + while (tempProcessData) { - t_data=tempProcessData->Threads; - break; + if (tempProcessData->ProcessID == (HANDLE)(UINT_PTR)ProcessID) + { + t_data = tempProcessData->Threads; + break; + } + tempProcessData = tempProcessData->next; } - tempProcessData=tempProcessData->next; - } - if (!t_data) - { - DbgPrint("This process was not found\n"); - KeReleaseSpinLock(&ProcesslistSL,OldIrql); - return; //no process found - } + if (!t_data) + { + DbgPrint("This process was not found\n"); + ExReleaseResourceLite(&ProcesslistR); + return; //no process found + } - while (t_data) - { - DbgPrint("Resuming thread....\n"); - - if (t_data->suspendcount) + while (t_data) { - t_data->suspendcount--; - if (!t_data->suspendcount) //suspendcount=0 so resume - KeReleaseSemaphore(&t_data->SuspendSemaphore,0,1,FALSE); - } + DbgPrint("Resuming thread....\n"); + if (t_data->suspendcount) + { + t_data->suspendcount--; + if (!t_data->suspendcount) //suspendcount=0 so resume + KeReleaseSemaphore(&t_data->SuspendSemaphore, 0, 1, FALSE); + } - t_data=t_data->next; //next thread - } - KeReleaseSpinLock(&ProcesslistSL,OldIrql); + t_data = t_data->next; //next thread + } + } + ExReleaseResourceLite(&ProcesslistR); } diff --git a/DBKKernel/ultimap2.c b/DBKKernel/ultimap2.c index 2bd63c12cb..a08455f15a 100644 --- a/DBKKernel/ultimap2.c +++ b/DBKKernel/ultimap2.c @@ -8,17 +8,6 @@ #include "ultimap2.h" -typedef ULONG(NTUSERSETWINDOWSHOOKEX)( - IN HANDLE hmod, - IN PUNICODE_STRING pstrLib OPTIONAL, - IN DWORD idThread, - IN int nFilterType, - IN PVOID pfnFilterProc, - IN DWORD dwFlags - ); -NTUSERSETWINDOWSHOOKEX OldNtUserSetWindowsHookEx; - - typedef NTSTATUS(*PSSUSPENDPROCESS)(PEPROCESS p); @@ -937,7 +926,7 @@ RTL_GENERIC_COMPARE_RESULTS NTAPI ToPACompare(__in struct _RTL_GENERIC_TABLE *Ta { //DbgPrint("Comparing %p with %p", FirstStruct->PhysicalAddress, FirstStruct->PhysicalAddress); - if (FirstStruct->PhysicalAddress == FirstStruct->PhysicalAddress) + if (FirstStruct->PhysicalAddress == SecondStruct->PhysicalAddress) return GenericEqual; else {