BOOL GetWindowsRootName(WCHAR *WindowsRootName) { UNICODE_STRING RootName,ObjectName; OBJECT_ATTRIBUTES ObjectAttributes; HANDLE hLink; NTSTATUS status; WCHAR *SystemRootName; WCHAR* ObjectNameBuffer; SystemRootName =(WCHAR*)0x7FFE0030; ObjectNameBuffer = (WCHAR*)ExAllocatePool(NonPagedPool,260*2); if (ObjectNameBuffer==NULL) { return FALSE; } RtlZeroMemory(ObjectNameBuffer,260*2); RtlInitUnicodeString(&RootName,L"\\SystemRoot"); InitializeObjectAttributes(&ObjectAttributes,&RootName,OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); status=ZwOpenSymbolicLinkObject(&hLink,1,&ObjectAttributes); if (NT_SUCCESS(status)) { ObjectName.Buffer=ObjectNameBuffer; ObjectName.Length=0; ObjectName.MaximumLength=260*2; status=ZwQuerySymbolicLinkObject(hLink,&ObjectName,NULL); if (NT_SUCCESS(status)) { int ObjectNameLength=ObjectName.Length/2; int Index; for (Index=ObjectNameLength-1;Index>0;Index--) { if (ObjectNameBuffer[Index]==0x005C) { if (!MmIsAddressValidEx(&WindowsRootName[ObjectNameLength-Index])) { break; } RtlCopyMemory(WindowsRootName,&ObjectNameBuffer[Index],(ObjectNameLength-Index)*2); ExFreePool(ObjectNameBuffer); return TRUE; } } } } ExFreePool(ObjectNameBuffer); if (!MmIsAddressValidEx(SystemRootName)) { return FALSE; } if (SystemRootName[1]!=0x003A||SystemRootName[2]!=0x005C) { return FALSE; } wcscpy(WindowsRootName,&SystemRootName[2]); return TRUE; }
VOID ParseVadTree(BYTE* VadNode,PDLLINFO PDll) { DWORD LeftChildOfsset=0,RightChildOffset=0; WIN_VER_DETAIL WinVer; WinVer=GetWindowsVersion(); switch (WinVer) { case WINDOWS_VERSION_XP: LeftChildOfsset=0x0c; RightChildOffset=0x10; break; case WINDOWS_VERSION_2K3: LeftChildOfsset=0x04; RightChildOffset=0x08; break; case WINDOWS_VERSION_2K3_SP1_SP2: LeftChildOfsset=0x04; RightChildOffset=0x08; break; case WINDOWS_VERSION_VISTA_2008: //vista + 2008 LeftChildOfsset=0x04; RightChildOffset=0x08; break; /*case 6002: //2008 LeftChildOfsset=0x04; RightChildOffset=0x08; break; */ case WINDOWS_VERSION_7_7000: case WINDOWS_VERSION_7_7600_UP: LeftChildOfsset=0x04; RightChildOffset=0x08; break; } if (LeftChildOfsset==0||RightChildOffset==0) { return; } if (MmIsAddressValidEx(VadNode)) { if (MmIsAddressValidEx((VadNode+LeftChildOfsset)) && MmIsAddressValidEx((VadNode+RightChildOffset))) { ParseVadTree((BYTE*)(*(DWORD*)(VadNode+LeftChildOfsset)),PDll); MyParseVadTreeRoutine(VadNode,PDll); ParseVadTree((BYTE*)(*(DWORD*)(VadNode+RightChildOffset)),PDll); } } }
NTSTATUS ReLoadKbdclassFree() { WIN_VER_DETAIL WinVer; WinVer = GetWindowsVersion(); if (WinVer == WINDOWS_VERSION_2K3_SP1_SP2) return STATUS_UNSUCCESSFUL; if (MmIsAddressValidEx(PKbdclassDriverObjectBakup)) { if (ulReal_KBDCLASS_IRP_MJ_CREATE && ulReal_KBDCLASS_IRP_MJ_CLOSE && ulReal_KBDCLASS_IRP_MJ_READ && ulReal_KBDCLASS_IRP_MJ_FLUSH_BUFFERS && ulReal_KBDCLASS_IRP_MJ_DEVICE_CONTROL && ulReal_KBDCLASS_IRP_MJ_INTERNAL_DEVICE_CONTROL && ulReal_KBDCLASS_IRP_MJ_CLEANUP && ulReal_KBDCLASS_IRP_MJ_POWER && ulReal_KBDCLASS_IRP_MJ_SYSTEM_CONTROL && ulReal_KBDCLASS_IRP_MJ_PNP_POWER) { PKbdclassDriverObjectBakup->MajorFunction[IRP_MJ_CREATE] = ulReal_KBDCLASS_IRP_MJ_CREATE; PKbdclassDriverObjectBakup->MajorFunction[IRP_MJ_CLOSE] = ulReal_KBDCLASS_IRP_MJ_CLOSE; PKbdclassDriverObjectBakup->MajorFunction[IRP_MJ_READ] = ulReal_KBDCLASS_IRP_MJ_READ; PKbdclassDriverObjectBakup->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = ulReal_KBDCLASS_IRP_MJ_FLUSH_BUFFERS; PKbdclassDriverObjectBakup->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ulReal_KBDCLASS_IRP_MJ_DEVICE_CONTROL; PKbdclassDriverObjectBakup->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = ulReal_KBDCLASS_IRP_MJ_INTERNAL_DEVICE_CONTROL; PKbdclassDriverObjectBakup->MajorFunction[IRP_MJ_CLEANUP] = ulReal_KBDCLASS_IRP_MJ_CLEANUP; PKbdclassDriverObjectBakup->MajorFunction[IRP_MJ_POWER] = ulReal_KBDCLASS_IRP_MJ_POWER; PKbdclassDriverObjectBakup->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = ulReal_KBDCLASS_IRP_MJ_SYSTEM_CONTROL; PKbdclassDriverObjectBakup->MajorFunction[IRP_MJ_PNP_POWER] = ulReal_KBDCLASS_IRP_MJ_PNP_POWER; } } return STATUS_SUCCESS; }
//填充各个结构发送至ring3 VOID FixFixKbdclass(PKBDCLASSDISPATCHBAKUP KbdclassDispatchBakUp,PDRIVER_OBJECT PKbdclassDriverObject,int i,ULONG ulReal_Dispatch,WCHAR *lpwzDispatchName,ULONG Dispatch) { ULONG ulCurrentKbdclassDispatch; ULONG ulHookModuleBase; ULONG ulHookModuleSize; BOOL bIsHooked = FALSE; ULONG ulReloadKbdclassDispatch; KbdclassDispatchBakUp->KbdclassDispatch[i].ulKbdclassDispatch = ulReal_Dispatch; KbdclassDispatchBakUp->KbdclassDispatch[i].ulNumber = Dispatch; memset(KbdclassDispatchBakUp->KbdclassDispatch[i].lpwzKbdclassDispatchName,0,sizeof(KbdclassDispatchBakUp->KbdclassDispatch[0].lpwzKbdclassDispatchName)); wcsncpy(KbdclassDispatchBakUp->KbdclassDispatch[i].lpwzKbdclassDispatchName,lpwzDispatchName,wcslen(lpwzDispatchName)); ulCurrentKbdclassDispatch = PKbdclassDriverObject->MajorFunction[Dispatch]; if (DebugOn) KdPrint(("ulCurrentKbdclassDispatch:%08x-%08x",ulCurrentKbdclassDispatch,PKbdclassDriverObject)); if (ulCurrentKbdclassDispatch == ulReal_Dispatch) { bIsHooked = TRUE; ulReloadKbdclassDispatch = ulReal_Dispatch - ulKbdclassModuleBase + ulReLoadKbdclassModuleBase; //检查是否inline hook if (GetFunctionCodeSize(ulReal_Dispatch) == GetFunctionCodeSize(ulReloadKbdclassDispatch) && memcmp(ulReal_Dispatch,ulReloadKbdclassDispatch,GetFunctionCodeSize(ulReal_Dispatch)) != NULL) { KbdclassDispatchBakUp->KbdclassDispatch[i].Hooked = 2; // inline hook //简单的处理一下头5字节的hook的检查 ulCurrentKbdclassDispatch = *(PULONG)(ulReal_Dispatch+1)+(ULONG)(ulReal_Dispatch+5); //如果不是开头jmp hook,就写回原始地址 if (!MmIsAddressValidEx(ulCurrentKbdclassDispatch)) { ulCurrentKbdclassDispatch = ulReal_Dispatch; } } } if (!bIsHooked) { KbdclassDispatchBakUp->KbdclassDispatch[i].Hooked = 1; // hook } memset(KbdclassDispatchBakUp->KbdclassDispatch[i].lpszBaseModule,0,sizeof(KbdclassDispatchBakUp->KbdclassDispatch[0].lpszBaseModule)); if (!IsAddressInSystem( ulCurrentKbdclassDispatch, &ulHookModuleBase, &ulHookModuleSize, KbdclassDispatchBakUp->KbdclassDispatch[i].lpszBaseModule)) { strcat(KbdclassDispatchBakUp->KbdclassDispatch[i].lpszBaseModule,"Unknown"); } KbdclassDispatchBakUp->KbdclassDispatch[i].ulCurrentKbdclassDispatch = ulCurrentKbdclassDispatch; KbdclassDispatchBakUp->KbdclassDispatch[i].ulModuleSize = ulHookModuleSize; KbdclassDispatchBakUp->KbdclassDispatch[i].ulModuleBase = ulHookModuleBase; }
NTSTATUS __stdcall NewZwWriteFile( __in HANDLE FileHandle, __in_opt HANDLE Event, __in_opt PIO_APC_ROUTINE ApcRoutine, __in_opt PVOID ApcContext, __out PIO_STATUS_BLOCK IoStatusBlock, __in PVOID Buffer, __in ULONG Length, __in_opt PLARGE_INTEGER ByteOffset, __in_opt PULONG Key ) { ZWWRITEFILE OldZwWriteFile; NTSTATUS status; PFILE_OBJECT FileObject; BOOL bInit = FALSE; ULONG WriteSize = 0; //如果A盾退出了 if (!bIsInitSuccess) goto _FunctionRet; if (RPsGetCurrentProcess){ if (RPsGetCurrentProcess() == ProtectEProcess){ goto _FunctionRet; } } //如果禁止回写文件 if (bDisWriteFile == FALSE){ return STATUS_UNSUCCESSFUL; } _FunctionRet: if (MmIsAddressValidEx(OriginalServiceDescriptorTable->ServiceTable[ZwWriteFileIndex])) { OldZwWriteFile = OriginalServiceDescriptorTable->ServiceTable[ZwWriteFileIndex]; }else OldZwWriteFile = KeServiceDescriptorTable->ServiceTable[ZwWriteFileIndex]; return OldZwWriteFile( FileHandle, Event, ApcRoutine, ApcContext, IoStatusBlock, Buffer, Length, ByteOffset, Key ); }
NTSTATUS SafeCopyMemory(PVOID SrcAddr, PVOID DstAddr, ULONG Size) { PMDL pSrcMdl, pDstMdl; PUCHAR pSrcAddress, pDstAddress; NTSTATUS st = STATUS_UNSUCCESSFUL; ULONG r; BOOL bInit = FALSE; pSrcMdl = IoAllocateMdl(SrcAddr, Size, FALSE, FALSE, NULL); if (MmIsAddressValidEx(pSrcMdl)) { MmBuildMdlForNonPagedPool(pSrcMdl); pSrcAddress = (PUCHAR)MmGetSystemAddressForMdlSafe(pSrcMdl, NormalPagePriority); if (MmIsAddressValidEx(pSrcAddress)) { pDstMdl = IoAllocateMdl(DstAddr, Size, FALSE, FALSE, NULL); if (MmIsAddressValidEx(pDstMdl)) { __try { MmProbeAndLockPages(pDstMdl, KernelMode, IoWriteAccess); pDstAddress = (PUCHAR)MmGetSystemAddressForMdlSafe(pDstMdl, NormalPagePriority); if (MmIsAddressValidEx(pDstAddress)) { RtlZeroMemory(pDstAddress,Size); RtlCopyMemory(pDstAddress, pSrcAddress, Size); st = STATUS_SUCCESS; } MmUnlockPages(pDstMdl); } __except(EXCEPTION_EXECUTE_HANDLER) { if (pDstMdl) MmUnlockPages(pDstMdl); if (pDstMdl) IoFreeMdl(pDstMdl); if (pSrcMdl) IoFreeMdl(pSrcMdl); return GetExceptionCode(); } IoFreeMdl(pDstMdl); } } IoFreeMdl(pSrcMdl); } return st; }
NTSTATUS __stdcall NewNtOpenProcess ( __out PHANDLE ProcessHandle, __in ACCESS_MASK DesiredAccess, __in POBJECT_ATTRIBUTES ObjectAttributes, PCLIENT_ID ClientId ) { NTSTATUS st; PEPROCESS eprocess_debugger; PEPROCESS eprocess_ctfmon; HANDLE CsrId = (HANDLE)0; NTOPENPROCESS SSDT_NtOpenProcess; SSDT_NtOpenProcess=(NTOPENPROCESS)g_RealOpenProcessAddress; if (IsFromGameProcess()) { //CodeVprint("tp is calling NtOpenProcess\r\n"); if (MmIsAddressValidEx(ClientId)) { if (ClientId->UniqueProcess) { if ((ULONG)(ClientId->UniqueProcess) == g_nProtectId) { /* 把我们的进程id改为csrss的id */ CodeVprint("TP is detecting our process\r\n"); //CsrId = GetCsrPid(); ClientId->UniqueProcess = (HANDLE)4; } } } return SSDT_NtOpenProcess(ProcessHandle, DesiredAccess, ObjectAttributes, ClientId); } ReloadNtOpenProcess = (NTOPENPROCESS)(g_RealOpenProcessAddress - SystemKernelModuleBase + (ULONG)ReloadNtosImageBase); return ReloadNtOpenProcess(ProcessHandle, DesiredAccess, ObjectAttributes, ClientId); }
//为什么VAD的地址有时候是无效呢 VOID EunmProcessModule(ULONG Eprocess,PDLLINFO PDll) { WIN_VER_DETAIL WinVer; ULONG ulPid; if (!MmIsAddressValidEx(Eprocess) || !IsExitProcess(Eprocess)) { return; } if (PDll) { ModuleCount = 0; ProcessFullPathFromVAD(Eprocess,PDll); if (!PDll->ulCount) { EunmProcessModuleByVirtualMemory(Eprocess,PDll); /* ReLoadNtosCALL(&RKeAttachProcess,L"KeAttachProcess",SystemKernelModuleBase,ImageModuleBase); ReLoadNtosCALL(&RKeDetachProcess,L"KeDetachProcess",SystemKernelModuleBase,ImageModuleBase); if (RKeAttachProcess && RKeDetachProcess) { RKeAttachProcess(Eprocess); //如果VAD和VirtualMemory都失败,就从peb里获取吧 //挂载进程 GetDllModuleFromPeb(Eprocess,PDll); RKeDetachProcess(); } */ } } return; }
void GetBugCheckReasonCallBack(PSYSTEM_NOTIFY SystemNotify) { //UCHAR* Base=(UCHAR*)KeRegisterBugCheckReasonCallback; UCHAR* Base=(UCHAR*)GetFunctionAddr(L"KeRegisterBugCheckReasonCallback"); int i=0; PKBUGCHECK_CALLBACK_RECORD pBugCheckRecordPack; PLIST_ENTRY pListEntry; PLIST_ENTRY pListNext; ULONG Address; Address=0; for(i=0;i<0x512;i++) { if((*(UCHAR*)Base==0xc7)&&(*(UCHAR*)(Base+1)==0x40)&&(*(UCHAR*)(Base+2)==0x04)) { Address=*(ULONG*)(Base+3); break; } Base++; } if (!MmIsAddressValidEx(Address)){ return; } BugCheckNum = SystemNotify->ulCount; pBugCheckRecordPack=Address; pListEntry=&(pBugCheckRecordPack->Entry); pListNext=pListEntry->Flink; { pBugCheckRecordPack=pListNext; if (DebugOn) DbgPrint("回调入口:%X 类型:BugCheckReasonCallBack 包地址:%X\n",pBugCheckRecordPack->CallbackRoutine,pBugCheckRecordPack); memset(SystemNotify->NotifyInfo[BugCheckNum].lpwzObject,0, sizeof(SystemNotify->NotifyInfo[BugCheckNum].lpwzObject)); swprintf(SystemNotify->NotifyInfo[BugCheckNum].lpwzObject, L"KBUGCHECK_CALLBACK_RECORD:0x%08X",pBugCheckRecordPack); SystemNotify->NotifyInfo[BugCheckNum].ulObject = pBugCheckRecordPack; SystemNotify->NotifyInfo[BugCheckNum].ulNotifyBase = (ULONG)(pBugCheckRecordPack->CallbackRoutine); memset(SystemNotify->NotifyInfo[BugCheckNum].lpwzType,0,sizeof(SystemNotify->NotifyInfo[BugCheckNum].lpwzType)); wcscat(SystemNotify->NotifyInfo[BugCheckNum].lpwzType,L"BugCheckReasonCallBack"); memset(SystemNotify->NotifyInfo[BugCheckNum].lpszModule,0,sizeof(SystemNotify->NotifyInfo[BugCheckNum].lpszModule)); if (!IsAddressInSystem( pBugCheckRecordPack->CallbackRoutine, &ulModuleBase, &ulModuleSize, SystemNotify->NotifyInfo[BugCheckNum].lpszModule)) { strcat(SystemNotify->NotifyInfo[BugCheckNum].lpszModule,"Unknown"); } BugCheckNum++; SystemNotify->ulCount++; } while(pListNext->Flink!=pListEntry) { pListNext=pListNext->Flink; pBugCheckRecordPack=pListNext; if (DebugOn) DbgPrint("回调入口:%X 类型:BugCheckReasonCallBack 包地址:%X\n",pBugCheckRecordPack->CallbackRoutine,pBugCheckRecordPack); memset(SystemNotify->NotifyInfo[BugCheckNum].lpwzObject,0, sizeof(SystemNotify->NotifyInfo[BugCheckNum].lpwzObject)); swprintf(SystemNotify->NotifyInfo[BugCheckNum].lpwzObject, L"KBUGCHECK_CALLBACK_RECORD:0x%08X",pBugCheckRecordPack); SystemNotify->NotifyInfo[BugCheckNum].ulObject = pBugCheckRecordPack; SystemNotify->NotifyInfo[BugCheckNum].ulNotifyBase = (ULONG)(pBugCheckRecordPack->CallbackRoutine); memset(SystemNotify->NotifyInfo[BugCheckNum].lpwzType,0,sizeof(SystemNotify->NotifyInfo[BugCheckNum].lpwzType)); wcscat(SystemNotify->NotifyInfo[BugCheckNum].lpwzType,L"BugCheckReasonCallBack"); memset(SystemNotify->NotifyInfo[BugCheckNum].lpszModule,0,sizeof(SystemNotify->NotifyInfo[BugCheckNum].lpszModule)); if (!IsAddressInSystem( pBugCheckRecordPack->CallbackRoutine, &ulModuleBase, &ulModuleSize, SystemNotify->NotifyInfo[BugCheckNum].lpszModule)) { strcat(SystemNotify->NotifyInfo[BugCheckNum].lpszModule,"Unknown"); } //KdPrint(("[%d]%s\r\n",SystemNotify->ulCount,SystemNotify->NotifyInfo[BugCheckNum].lpszModule)); BugCheckNum++; SystemNotify->ulCount++; } }
/* NTKERNELAPI BOOLEAN KeRegisterBugCheckCallback ( __out PKBUGCHECK_CALLBACK_RECORD CallbackRecord, __in PKBUGCHECK_CALLBACK_ROUTINE CallbackRoutine, __in PVOID Buffer, __in ULONG Length, __in PUCHAR Component ) typedef struct _KBUGCHECK_CALLBACK_RECORD { LIST_ENTRY Entry; PKBUGCHECK_CALLBACK_ROUTINE CallbackRoutine; PVOID Buffer; ULONG Length; PUCHAR Component; ULONG_PTR Checksum; UCHAR State; } KBUGCHECK_CALLBACK_RECORD, *PKBUGCHECK_CALLBACK_RECORD; LIST_ENTRY KeBugCheckCallbackListHead; LIST_ENTRY KeBugCheckReasonCallbackListHead; */ void GetBugCheckCallBack(PSYSTEM_NOTIFY SystemNotify) { //UCHAR* Base=(UCHAR*)KeRegisterBugCheckCallback; PUCHAR Base=(UCHAR*)GetFunctionAddr(L"KeRegisterBugCheckCallback"); PUCHAR i=0; PKBUGCHECK_CALLBACK_RECORD pBugCheckRecordPack; PLIST_ENTRY pListEntry; PLIST_ENTRY pListNext; ULONG Address; Address=0; if (DebugOn) KdPrint(("Base:%08x",Base)); for(i=Base;i<i+SizeOfProc(Base);i++) { if (DebugOn) KdPrint(("i:%08x",i)); if(*i==0xc6 && *(i+1)==0x40 && *(i+2)==0x1c && *(i+3)==0x01) { Address=*(ULONG*)(i+6); if (DebugOn) KdPrint(("Base:%08x Address:%08x\r\n",Base,Address)); break; } } if (!MmIsAddressValidEx(Address)){ return; } BugCheckNum = SystemNotify->ulCount; pBugCheckRecordPack=Address; pListEntry=&(pBugCheckRecordPack->Entry); pListNext=pListEntry->Flink; { pBugCheckRecordPack=pListNext; if (DebugOn) DbgPrint("回调入口:%X 类型:BugCheckCallBack 包地址:%X\n",pBugCheckRecordPack->CallbackRoutine,pBugCheckRecordPack); memset(SystemNotify->NotifyInfo[BugCheckNum].lpwzObject,0, sizeof(SystemNotify->NotifyInfo[BugCheckNum].lpwzObject)); swprintf(SystemNotify->NotifyInfo[BugCheckNum].lpwzObject, L"KBUGCHECK_CALLBACK_RECORD:0x%08X",pBugCheckRecordPack); SystemNotify->NotifyInfo[BugCheckNum].ulObject = pBugCheckRecordPack; SystemNotify->NotifyInfo[BugCheckNum].ulNotifyBase = (ULONG)(pBugCheckRecordPack->CallbackRoutine); memset(SystemNotify->NotifyInfo[BugCheckNum].lpwzType,0,sizeof(SystemNotify->NotifyInfo[BugCheckNum].lpwzType)); wcscat(SystemNotify->NotifyInfo[BugCheckNum].lpwzType,L"BugCheckCallBack"); memset(SystemNotify->NotifyInfo[BugCheckNum].lpszModule,0,sizeof(SystemNotify->NotifyInfo[BugCheckNum].lpszModule)); if (!IsAddressInSystem( pBugCheckRecordPack->CallbackRoutine, &ulModuleBase, &ulModuleSize, SystemNotify->NotifyInfo[BugCheckNum].lpszModule)) { strcat(SystemNotify->NotifyInfo[BugCheckNum].lpszModule,"Unknown"); } BugCheckNum++; SystemNotify->ulCount++; } while(pListNext->Flink!=pListEntry) { pListNext=pListNext->Flink; pBugCheckRecordPack=pListNext; if (DebugOn) DbgPrint("回调入口:%X 类型:BugCheckCallBack 包地址:%X\n",pBugCheckRecordPack->CallbackRoutine,pBugCheckRecordPack); memset(SystemNotify->NotifyInfo[BugCheckNum].lpwzObject,0, sizeof(SystemNotify->NotifyInfo[BugCheckNum].lpwzObject)); swprintf(SystemNotify->NotifyInfo[BugCheckNum].lpwzObject, L"KBUGCHECK_CALLBACK_RECORD:0x%08X",pBugCheckRecordPack); SystemNotify->NotifyInfo[BugCheckNum].ulObject = pBugCheckRecordPack; SystemNotify->NotifyInfo[BugCheckNum].ulNotifyBase = (ULONG)(pBugCheckRecordPack->CallbackRoutine); memset(SystemNotify->NotifyInfo[BugCheckNum].lpwzType,0,sizeof(SystemNotify->NotifyInfo[BugCheckNum].lpwzType)); wcscat(SystemNotify->NotifyInfo[BugCheckNum].lpwzType,L"BugCheckCallBack"); memset(SystemNotify->NotifyInfo[BugCheckNum].lpszModule,0,sizeof(SystemNotify->NotifyInfo[BugCheckNum].lpszModule)); if (!IsAddressInSystem( pBugCheckRecordPack->CallbackRoutine, &ulModuleBase, &ulModuleSize, SystemNotify->NotifyInfo[BugCheckNum].lpszModule)) { strcat(SystemNotify->NotifyInfo[BugCheckNum].lpszModule,"Unknown"); } BugCheckNum++; SystemNotify->ulCount++; } }
void GetRegisterNotify(PSYSTEM_NOTIFY SystemNotify) { PEX_FAST_REF Ref; //UCHAR* Base=(UCHAR*)CmRegisterCallback; UCHAR* Base=(UCHAR*)GetFunctionAddr(L"CmRegisterCallback"); int i=0; ULONG Address; PEX_CALLBACK_ROUTINE_BLOCK Point; Address=0; for(i=0;i<0x512;i++) { if((*(UCHAR*)Base==0xc7)&&(*(UCHAR*)(Base+1)==0x45)&&(*(UCHAR*)(Base+2)==0x08)) { Address=*(ULONG*)(Base+3); break; } Base++; } if (!MmIsAddressValidEx(Address)){ return; } Ref=(PEX_FAST_REF)(Address); RegNum = SystemNotify->ulCount; for(i=0;i<8;i++) { Point=(PEX_CALLBACK_ROUTINE_BLOCK)((Ref->Value>>3)<<3); if(MmIsAddressValidEx((PVOID)Point)) { if (DebugOn) DbgPrint("回调入口:%X 类型:CmpCallBack\n",(ULONG)(Point->Function)); memset(SystemNotify->NotifyInfo[RegNum].lpwzObject,0, sizeof(SystemNotify->NotifyInfo[RegNum].lpwzObject)); swprintf(SystemNotify->NotifyInfo[RegNum].lpwzObject, L"EX_CALLBACK_ROUTINE_BLOCK:0x%08X",Point); SystemNotify->NotifyInfo[RegNum].ulNotifyBase = (ULONG)(Point->Function); memset(SystemNotify->NotifyInfo[RegNum].lpwzType,0,sizeof(SystemNotify->NotifyInfo[RegNum].lpwzType)); wcscat(SystemNotify->NotifyInfo[RegNum].lpwzType,L"CmpCallBack"); memset(SystemNotify->NotifyInfo[RegNum].lpszModule,0,sizeof(SystemNotify->NotifyInfo[RegNum].lpszModule)); if (!IsAddressInSystem( Point->Function, &ulModuleBase, &ulModuleSize, SystemNotify->NotifyInfo[RegNum].lpszModule)) { strcat(SystemNotify->NotifyInfo[RegNum].lpszModule,"Unknown"); } RegNum++; SystemNotify->ulCount++; } Ref++; } return; }
void GetCreateProcessNotify(PSYSTEM_NOTIFY SystemNotify) { PEX_FAST_REF Ref; //UCHAR* Base=(UCHAR*)PsSetCreateProcessNotifyRoutine; PUCHAR Base; PUCHAR i=0,x=0; ULONG Address=0; PEX_CALLBACK_ROUTINE_BLOCK Point; WIN_VER_DETAIL WinVer; PUCHAR ulPspSetCreateProcessNotifyRoutine; Base=(UCHAR*)GetFunctionAddr(L"PsSetCreateProcessNotifyRoutine"); if (DebugOn) KdPrint(("Base:%08x\r\n",Base)); if (!MmIsAddressValidEx(Base)) { return ; } WinVer = GetWindowsVersion(); switch(WinVer) { case WINDOWS_VERSION_2K3_SP1_SP2: case WINDOWS_VERSION_XP: /* 805d0c27 56 push esi 805d0c28 57 push edi 805d0c29 7464 je nt!PsSetCreateProcessNotifyRoutine+0x73 (805d0c8f) 805d0c2b bf404a5680 mov edi,offset nt!PspCreateProcessNotifyRoutine (80564a40) 指令bf 40 4a 56 80即包含地址80564a40 805d0c30 57 push edi */ for(i=Base;i<i+SizeOfProc(Base);i++) { if (DebugOn) KdPrint(("[%08x]Base:%08x\r\n",i,Base)); if(*i == 0xbf) { Address=*(ULONG*)(i+1); if (DebugOn) KdPrint(("[%08x]Base:%08x %08x\r\n",i,Base,Address)); //DbgPrint("进程创建回调函数数组地址:%d\n",Address); //数组是EX_FAST_REF类型 break; } } break; case WINDOWS_VERSION_7_7000: case WINDOWS_VERSION_7_7600_UP: /* 83f9c821 33db xor ebx,ebx 83f9c823 c7450ca0a9f483 mov dword ptr [ebp+0Ch],offset nt!PspCreateProcessNotifyRoutine (83f4a9a0) 83f9c82a ff750c push dword ptr [ebp+0Ch] */ for(i=Base;i<i+SizeOfProc(Base);i++) { if(*i == 0xe8) { ulPspSetCreateProcessNotifyRoutine=*(ULONG*)(i+1)+(i+5); if (DebugOn) KdPrint(("[%08x]ulPspSetCreateProcessNotifyRoutine:%08x\r\n",i,ulPspSetCreateProcessNotifyRoutine)); if (MmIsAddressValidEx(ulPspSetCreateProcessNotifyRoutine)) { for(x=ulPspSetCreateProcessNotifyRoutine;x<x+SizeOfProc(ulPspSetCreateProcessNotifyRoutine);x++) { if (DebugOn) KdPrint(("[%08x]Base:%08x\r\n",x,Base)); if (*x == 0xc7) { //DbgPrint("进程创建回调函数数组地址:%d\n",Address); //数组是EX_FAST_REF类型 Address=*(ULONG*)(x+3); if (DebugOn) KdPrint(("[%08x]Base:%08x %08x\r\n",x,ulPspSetCreateProcessNotifyRoutine,Address)); break; } } } break; } } break; } //KdPrint(("没有找到进程创建回调函数数组\n")); if (!MmIsAddressValidEx(Address)){ return ; } Ref=(PEX_FAST_REF)(Address); CreateProcessNum = SystemNotify->ulCount; for(i=0;i<8;i++) { Point=(PEX_CALLBACK_ROUTINE_BLOCK)((Ref->Value>>3)<<3);//得到存有函数地址的结构 if(MmIsAddressValidEx((PVOID)Point)) { if (DebugOn) DbgPrint("回调入口:%X 类型:CreateProcess\n",(ULONG)(Point->Function)); memset(SystemNotify->NotifyInfo[CreateProcessNum].lpwzObject,0, sizeof(SystemNotify->NotifyInfo[CreateProcessNum].lpwzObject)); swprintf(SystemNotify->NotifyInfo[CreateProcessNum].lpwzObject, L"EX_CALLBACK_ROUTINE_BLOCK:0x%08X",Point); SystemNotify->NotifyInfo[CreateProcessNum].ulNotifyBase = (ULONG)(Point->Function); memset(SystemNotify->NotifyInfo[CreateProcessNum].lpwzType,0,sizeof(SystemNotify->NotifyInfo[CreateProcessNum].lpwzType)); wcscat(SystemNotify->NotifyInfo[CreateProcessNum].lpwzType,L"CreateProcess"); memset(SystemNotify->NotifyInfo[CreateProcessNum].lpszModule,0,sizeof(SystemNotify->NotifyInfo[CreateProcessNum].lpszModule)); if (!IsAddressInSystem( Point->Function, &ulModuleBase, &ulModuleSize, SystemNotify->NotifyInfo[CreateProcessNum].lpszModule)) { strcat(SystemNotify->NotifyInfo[CreateProcessNum].lpszModule,"Unknown"); } CreateProcessNum++; SystemNotify->ulCount++; } Ref++; } return; }
void GetLoadImageNotify(PSYSTEM_NOTIFY SystemNotify) { PEX_FAST_REF Ref; //UCHAR* Base=(UCHAR*)PsSetLoadImageNotifyRoutine; UCHAR* Base=(UCHAR*)GetFunctionAddr(L"PsSetLoadImageNotifyRoutine"); int i=0; ULONG Address; PEX_CALLBACK_ROUTINE_BLOCK Point; WIN_VER_DETAIL WinVer; Address=0; for(i=0;i<0x512;i++) { WinVer = GetWindowsVersion(); switch(WinVer) { case WINDOWS_VERSION_2K3_SP1_SP2: case WINDOWS_VERSION_XP: if((*(UCHAR*)Base==0x56)&&(*(UCHAR*)(Base+1)==0xbe)) { Address=*(ULONG*)(Base+2); if (DebugOn) DbgPrint("加载模块回调函数数组地址:%08x\n",Address); break; } break; case WINDOWS_VERSION_7_7000: case WINDOWS_VERSION_7_7600_UP: if((*(UCHAR*)Base==0x25)&&(*(UCHAR*)(Base+1)==0xbe)) { Address=*(ULONG*)(Base+2); if (DebugOn) DbgPrint("加载模块回调函数数组地址:%08x\n",Address); break; } break; } Base++; } if(!MmIsAddressValidEx(Address)){ return; } Ref=(PEX_FAST_REF)(Address); LoadImageNum = SystemNotify->ulCount; for(i=0;i<8;i++) { Point=(PEX_CALLBACK_ROUTINE_BLOCK)((Ref->Value>>3)<<3); if(MmIsAddressValidEx((PVOID)Point)) { if (DebugOn) DbgPrint("回调入口:%X 类型:LoadImage\n",(ULONG)(Point->Function)); memset(SystemNotify->NotifyInfo[LoadImageNum].lpwzObject,0, sizeof(SystemNotify->NotifyInfo[LoadImageNum].lpwzObject)); swprintf(SystemNotify->NotifyInfo[LoadImageNum].lpwzObject, L"EX_CALLBACK_ROUTINE_BLOCK:0x%08X",Point); SystemNotify->NotifyInfo[LoadImageNum].ulNotifyBase = (ULONG)(Point->Function); memset(SystemNotify->NotifyInfo[LoadImageNum].lpwzType,0,sizeof(SystemNotify->NotifyInfo[LoadImageNum].lpwzType)); wcscat(SystemNotify->NotifyInfo[LoadImageNum].lpwzType,L"LoadImage"); memset(SystemNotify->NotifyInfo[LoadImageNum].lpszModule,0,sizeof(SystemNotify->NotifyInfo[LoadImageNum].lpszModule)); if (!IsAddressInSystem( Point->Function, &ulModuleBase, &ulModuleSize, SystemNotify->NotifyInfo[LoadImageNum].lpszModule)) { strcat(SystemNotify->NotifyInfo[LoadImageNum].lpszModule,"Unknown"); } LoadImageNum++; SystemNotify->ulCount++; } Ref++; } return; }
void GetCreateThreadNotify(PSYSTEM_NOTIFY SystemNotify) { PEX_FAST_REF Ref; //UCHAR* Base=(UCHAR*)PsSetCreateThreadNotifyRoutine; UCHAR* Base=(UCHAR*)GetFunctionAddr(L"PsSetCreateThreadNotifyRoutine"); int i=0; PEX_CALLBACK_ROUTINE_BLOCK Point; ULONG Address; if(!MmIsAddressValidEx(Base)){ return; } Address=0; for(i=0;i<0x512;i++) { if((*(UCHAR*)Base==0x56)&&(*(UCHAR*)(Base+1)==0xbe)) { Address=*(ULONG*)(Base+2); if (DebugOn) KdPrint(("线程创建回调函数数组地址:%08x\n",Address)); //数组是EX_FAST_REF类型 break; } Base++; } if(!MmIsAddressValidEx(Address)){ return; } Ref=(PEX_FAST_REF)(Address); CreateThreadNum = SystemNotify->ulCount; for(i=0;i<8;i++) { Point=(PEX_CALLBACK_ROUTINE_BLOCK)((Ref->Value>>3)<<3);//得到存有函数地址的结构 if(MmIsAddressValidEx((PVOID)Point)) { if (DebugOn) DbgPrint("回调入口:%X 类型:CreateThread\n",(ULONG)(Point->Function)); memset(SystemNotify->NotifyInfo[CreateThreadNum].lpwzObject,0, sizeof(SystemNotify->NotifyInfo[CreateThreadNum].lpwzObject)); swprintf(SystemNotify->NotifyInfo[CreateThreadNum].lpwzObject, L"EX_CALLBACK_ROUTINE_BLOCK:0x%08X",Point); SystemNotify->NotifyInfo[CreateThreadNum].ulNotifyBase = (ULONG)(Point->Function); memset(SystemNotify->NotifyInfo[CreateThreadNum].lpwzType,0,sizeof(SystemNotify->NotifyInfo[CreateThreadNum].lpwzType)); wcscat(SystemNotify->NotifyInfo[CreateThreadNum].lpwzType,L"CreateThread"); memset(SystemNotify->NotifyInfo[CreateThreadNum].lpszModule,0,sizeof(SystemNotify->NotifyInfo[CreateThreadNum].lpszModule)); if (!IsAddressInSystem( Point->Function, &ulModuleBase, &ulModuleSize, SystemNotify->NotifyInfo[CreateThreadNum].lpszModule)) { strcat(SystemNotify->NotifyInfo[CreateThreadNum].lpszModule,"Unknown"); } CreateThreadNum++; SystemNotify->ulCount++; } Ref++; } return; }
NTSTATUS ReLoadKbdclass(PDRIVER_OBJECT DriverObject,PKBDCLASSDISPATCHBAKUP KbdclassDispatchBakUp,int Type) { PDRIVER_OBJECT PKbdclassDriverObject = NULL; PUCHAR i; WIN_VER_DETAIL WinVer; BOOL bInit = FALSE; PUCHAR KbdclassDriverEntry; PUCHAR ulJmpAddress,ulAddress; ULONG ulDispatch; ULONG ulDriverEntryToDispatchCodeOffset; ULONG ulOffset; BOOL bIsReLoadSuccess = FALSE; UNICODE_STRING UnicodeModule; HANDLE hSection; ULONG ulModuleBase; //获取driverobject if (GetDriverObject(L"\\Driver\\Kbdclass",&PKbdclassDriverObject) == STATUS_SUCCESS) { PKbdclassDriverObjectBakup = PKbdclassDriverObject; ulKbdclassModuleBase = PKbdclassDriverObject->DriverStart; ulKbdclassModuleSize = PKbdclassDriverObject->DriverSize; //reload if (PeLoad( L"\\SystemRoot\\system32\\drivers\\Kbdclass.sys", &ulReLoadKbdclassModuleBase, DriverObject, ulKbdclassModuleBase )) { bIsReLoadSuccess = TRUE; } if (!bIsReLoadSuccess) { return STATUS_UNSUCCESSFUL; } if (GetDriverEntryPoint(ulReLoadKbdclassModuleBase,&KbdclassDriverEntry)) { /* IRP_MJ_CREATE 0xF875FDD0 - 0xF875FDD0 C:\WINDOWS\system32\DRIVERS\kbdclass.sys IRP_MJ_CLOSE 0xF875FFE0 - 0xF875FFE0 C:\WINDOWS\system32\DRIVERS\kbdclass.sys IRP_MJ_READ C:\WINDOWS\system32\DRIVERS\kbdclass.sys IRP_MJ_FLUSH_BUFFERS 0xF875FD4A - 0xF875FD4A C:\WINDOWS\system32\DRIVERS\kbdclass.sys IRP_MJ_DEVICE_CONTROL IRP_MJ_INTERNAL_DEVICE_CONTROL 0xF8761386 - 0xF8761386 C:\WINDOWS\system32\DRIVERS\kbdclass.sys IRP_MJ_CLEANUP 0xF875FD06 - 0xF875FD06 C:\WINDOWS\system32\DRIVERS\kbdclass.sys IRP_MJ_POWER 0xF8762180 - 0xF8762180 C:\WINDOWS\system32\DRIVERS\kbdclass.sys IRP_MJ_SYSTEM_CONTROL 0xF8761842 - 0xF8761842 C:\WINDOWS\system32\DRIVERS\kbdclass.sys IRP_MJ_PNP_POWER 0xF876078A - 0xF876078A C:\WINDOWS\system32\DRIVERS\kbdclass.sys */ /* 8105e610 8bff mov edi,edi 8105e612 55 push ebp 8105e613 8bec mov ebp,esp 8105e615 a12c4095f8 mov eax,dword ptr ds:[F895402Ch] 8105e61a 85c0 test eax,eax 8105e61c b940bb0000 mov ecx,0BB40h 8105e621 7404 je 8105e627 8105e623 3bc1 cmp eax,ecx 8105e625 7523 jne 8105e64a 8105e627 8b15ec3e95f8 mov edx,dword ptr ds:[0F8953EECh] 8105e62d b82c4095f8 mov eax,0F895402Ch 8105e632 c1e808 shr eax,8 8105e635 3302 xor eax,dword ptr [edx] 8105e637 25ffff0000 and eax,0FFFFh 8105e63c a32c4095f8 mov dword ptr ds:[F895402Ch],eax 8105e641 7507 jne 8105e64a 8105e643 8bc1 mov eax,ecx 8105e645 a32c4095f8 mov dword ptr ds:[F895402Ch],eax 8105e64a f7d0 not eax 8105e64c a3284095f8 mov dword ptr ds:[F8954028h],eax 8105e651 5d pop ebp 8105e652 e9d9f9ffff jmp 8105e030 <-----获取这里的地址 即driverentry(xp) */ for (i=(ULONG)KbdclassDriverEntry;i < (ULONG)KbdclassDriverEntry+0x1000;i++) { if (*i == 0xe9) { ulJmpAddress = *(PULONG)(i+1)+(ULONG)(i+5); if (MmIsAddressValidEx(ulJmpAddress)) { if (DebugOn) KdPrint(("i:%08x,DriverEntry:%08x\n",i,ulJmpAddress)); bInit = TRUE; break; } } } if (!bInit) { return; } WinVer = GetWindowsVersion(); switch (WinVer) { case WINDOWS_VERSION_XP: ulDriverEntryToDispatchCodeOffset = 0x2c2; //硬编码了,xp break; case WINDOWS_VERSION_7_7000: ulDriverEntryToDispatchCodeOffset = 0x27C; //硬编码了,win7 7000 break; case WINDOWS_VERSION_7_7600_UP: ulDriverEntryToDispatchCodeOffset = 0x2BE; //硬编码了,win7 7600 UP break; case WINDOWS_VERSION_2K3_SP1_SP2: ulDriverEntryToDispatchCodeOffset = 0x2c2; //硬编码了,2003 //ulOffset = (ULONG)PKbdclassDriverObject->DriverStart - 0x10000; break; } ulDispatch = ulJmpAddress + ulDriverEntryToDispatchCodeOffset; if (DebugOn) KdPrint(("ulAddress:%08x\r\n",ulDispatch)); ulReal_KBDCLASS_IRP_MJ_CREATE = *(PULONG)(ulDispatch+3); ulReal_KBDCLASS_IRP_MJ_CLOSE = *(PULONG)(ulDispatch+0xA); ulReal_KBDCLASS_IRP_MJ_READ = *(PULONG)(ulDispatch+0x11); ulReal_KBDCLASS_IRP_MJ_FLUSH_BUFFERS = *(PULONG)(ulDispatch+0x18); ulReal_KBDCLASS_IRP_MJ_DEVICE_CONTROL = *(PULONG)(ulDispatch+0x1F); ulReal_KBDCLASS_IRP_MJ_INTERNAL_DEVICE_CONTROL = *(PULONG)(ulDispatch+0x26); ulReal_KBDCLASS_IRP_MJ_CLEANUP = *(PULONG)(ulDispatch+0x30); ulReal_KBDCLASS_IRP_MJ_PNP_POWER = *(PULONG)(ulDispatch+0x3A); ulReal_KBDCLASS_IRP_MJ_POWER = *(PULONG)(ulDispatch+0x44); ulReal_KBDCLASS_IRP_MJ_SYSTEM_CONTROL = *(PULONG)(ulDispatch+0x4E); if (DebugOn) KdPrint(("%08x\r\n" "%08x\r\n" "%08x\r\n" "%08x\r\n" "%08x\r\n" "%08x\r\n" "%08x\r\n" "%08x\r\n" "%08x\r\n" "%08x\r\n", ulReal_KBDCLASS_IRP_MJ_CREATE, ulReal_KBDCLASS_IRP_MJ_CLOSE, ulReal_KBDCLASS_IRP_MJ_READ, ulReal_KBDCLASS_IRP_MJ_FLUSH_BUFFERS, ulReal_KBDCLASS_IRP_MJ_DEVICE_CONTROL, ulReal_KBDCLASS_IRP_MJ_INTERNAL_DEVICE_CONTROL, ulReal_KBDCLASS_IRP_MJ_CLEANUP, ulReal_KBDCLASS_IRP_MJ_POWER, ulReal_KBDCLASS_IRP_MJ_SYSTEM_CONTROL, ulReal_KBDCLASS_IRP_MJ_PNP_POWER )); if (Type == 1) { //填充结构 FixFixKbdclass(KbdclassDispatchBakUp,PKbdclassDriverObjectBakup,0,ulReal_KBDCLASS_IRP_MJ_CREATE,L"IRP_MJ_CREATE",IRP_MJ_CREATE); FixFixKbdclass(KbdclassDispatchBakUp,PKbdclassDriverObjectBakup,1,ulReal_KBDCLASS_IRP_MJ_CLOSE,L"IRP_MJ_CLOSE",IRP_MJ_CLOSE); FixFixKbdclass(KbdclassDispatchBakUp,PKbdclassDriverObjectBakup,2,ulReal_KBDCLASS_IRP_MJ_READ,L"IRP_MJ_READ",IRP_MJ_READ); FixFixKbdclass(KbdclassDispatchBakUp,PKbdclassDriverObjectBakup,3,ulReal_KBDCLASS_IRP_MJ_FLUSH_BUFFERS,L"IRP_MJ_FLUSH_BUFFERS",IRP_MJ_FLUSH_BUFFERS); FixFixKbdclass(KbdclassDispatchBakUp,PKbdclassDriverObjectBakup,4,ulReal_KBDCLASS_IRP_MJ_DEVICE_CONTROL,L"IRP_MJ_DEVICE_CONTROL",IRP_MJ_DEVICE_CONTROL); FixFixKbdclass(KbdclassDispatchBakUp,PKbdclassDriverObjectBakup,5,ulReal_KBDCLASS_IRP_MJ_INTERNAL_DEVICE_CONTROL,L"IRP_MJ_INTERNAL_DEVICE_CONTROL",IRP_MJ_INTERNAL_DEVICE_CONTROL); FixFixKbdclass(KbdclassDispatchBakUp,PKbdclassDriverObjectBakup,6,ulReal_KBDCLASS_IRP_MJ_CLEANUP,L"IRP_MJ_CLEANUP",IRP_MJ_CLEANUP); FixFixKbdclass(KbdclassDispatchBakUp,PKbdclassDriverObjectBakup,7,ulReal_KBDCLASS_IRP_MJ_POWER,L"IRP_MJ_POWER",IRP_MJ_POWER); FixFixKbdclass(KbdclassDispatchBakUp,PKbdclassDriverObjectBakup,8,ulReal_KBDCLASS_IRP_MJ_SYSTEM_CONTROL,L"IRP_MJ_SYSTEM_CONTROL",IRP_MJ_SYSTEM_CONTROL); FixFixKbdclass(KbdclassDispatchBakUp,PKbdclassDriverObjectBakup,9,ulReal_KBDCLASS_IRP_MJ_PNP_POWER,L"IRP_MJ_PNP_POWER",IRP_MJ_PNP_POWER); KbdclassDispatchBakUp->ulCount = 10; return STATUS_SUCCESS; } //所有调用都走reload PKbdclassDriverObjectBakup->MajorFunction[IRP_MJ_CREATE] = ulReal_KBDCLASS_IRP_MJ_CREATE - ulKbdclassModuleBase + ulReLoadKbdclassModuleBase; PKbdclassDriverObjectBakup->MajorFunction[IRP_MJ_CLOSE] = ulReal_KBDCLASS_IRP_MJ_CLOSE - ulKbdclassModuleBase + ulReLoadKbdclassModuleBase; PKbdclassDriverObjectBakup->MajorFunction[IRP_MJ_READ] = ulReal_KBDCLASS_IRP_MJ_READ - ulKbdclassModuleBase + ulReLoadKbdclassModuleBase; PKbdclassDriverObjectBakup->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = ulReal_KBDCLASS_IRP_MJ_FLUSH_BUFFERS - ulKbdclassModuleBase + ulReLoadKbdclassModuleBase; PKbdclassDriverObjectBakup->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ulReal_KBDCLASS_IRP_MJ_DEVICE_CONTROL - ulKbdclassModuleBase + ulReLoadKbdclassModuleBase; PKbdclassDriverObjectBakup->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = ulReal_KBDCLASS_IRP_MJ_INTERNAL_DEVICE_CONTROL - ulKbdclassModuleBase + ulReLoadKbdclassModuleBase; PKbdclassDriverObjectBakup->MajorFunction[IRP_MJ_CLEANUP] = ulReal_KBDCLASS_IRP_MJ_CLEANUP - ulKbdclassModuleBase + ulReLoadKbdclassModuleBase; PKbdclassDriverObjectBakup->MajorFunction[IRP_MJ_POWER] = ulReal_KBDCLASS_IRP_MJ_POWER - ulKbdclassModuleBase + ulReLoadKbdclassModuleBase; PKbdclassDriverObjectBakup->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = ulReal_KBDCLASS_IRP_MJ_SYSTEM_CONTROL - ulKbdclassModuleBase + ulReLoadKbdclassModuleBase; PKbdclassDriverObjectBakup->MajorFunction[IRP_MJ_PNP_POWER] = ulReal_KBDCLASS_IRP_MJ_PNP_POWER - ulKbdclassModuleBase + ulReLoadKbdclassModuleBase; } } return STATUS_SUCCESS; }
//通过遍历驱动链表获取模块基地址 PVOID GetKernelModuleBase(PDRIVER_OBJECT DriverObject,CHAR *KernelModuleName) { PLDR_DATA_TABLE_ENTRY DriverSection,LdrEntry; ANSI_STRING AnsiKernelModuleName; UNICODE_STRING UniKernelModuleName; UNICODE_STRING ModuleName; WCHAR *Buffer; int Lentgh,Index; RtlInitAnsiString(&AnsiKernelModuleName,KernelModuleName); RtlAnsiStringToUnicodeString(&UniKernelModuleName,&AnsiKernelModuleName,TRUE); Buffer=ExAllocatePool(NonPagedPool,260*2); if (Buffer==NULL) { return NULL; } RtlZeroMemory(Buffer,206*2); DriverSection=DriverObject->DriverSection; LdrEntry=(PLDR_DATA_TABLE_ENTRY)DriverSection->InLoadOrderLinks.Flink; while (LdrEntry&&DriverSection!=LdrEntry) { if ((DWORD)LdrEntry->DllBase>=*(DWORD*)&MmSystemRangeStart && LdrEntry->FullDllName.Length >0 && LdrEntry->FullDllName.Buffer != NULL) { if (MmIsAddressValidEx(&LdrEntry->FullDllName.Buffer[LdrEntry->FullDllName.Length/2-1])) { Lentgh=LdrEntry->FullDllName.Length/2; for (Index=Lentgh-1;Index>0;Index--) { if (LdrEntry->FullDllName.Buffer[Index]==0x005C) { break; } } if (LdrEntry->FullDllName.Buffer[Index]==0x005C) { RtlCopyMemory(Buffer,&(LdrEntry->FullDllName.Buffer[Index+1]),(Lentgh-Index-1)*2); ModuleName.Buffer=Buffer; ModuleName.Length=(Lentgh-Index-1)*2; ModuleName.MaximumLength=260*2; } else { RtlCopyMemory(Buffer,LdrEntry->FullDllName.Buffer,Lentgh*2); ModuleName.Buffer=Buffer; ModuleName.Length=Lentgh*2; ModuleName.MaximumLength=260*2; } if (RtlEqualUnicodeString(&ModuleName,&UniKernelModuleName,TRUE)) { ExFreePool(Buffer); return LdrEntry->DllBase; } } } LdrEntry = (PLDR_DATA_TABLE_ENTRY)LdrEntry->InLoadOrderLinks.Flink; } ExFreePool(Buffer); return NULL; }
/* NTSTATUS SafeMmUnmapViewOfSection(PEPROCESS Process,ULONG lpBase) //NtUnmapViewOfSection { NTSTATUS status = STATUS_UNSUCCESSFUL; RMmUnmapViewOfSection = ReLoadNtosCALL(L"MmUnmapViewOfSection",SystemKernelModuleBase,ImageModuleBase); if (RMmUnmapViewOfSection) { ObReferenceObject(Process); status = RMmUnmapViewOfSection(Process,lpBase); ObDereferenceObject(Process); } return status; } */ BOOL MyParseVadTreeRoutine(BYTE* VadNode,PDLLINFO PDll) { DWORD ControlAreaOffset; PCONTROL_AREA ControlArea=NULL; PFILE_OBJECT FileObject=NULL; DWORD StartingVpnOffset=0; DWORD StartingVpn; DWORD Subsection; DWORD SubsectionOffset; PEX_FAST_REF FilePointer; POBJECT_NAME_INFORMATION UnicodeDosFullPath = NULL; WIN_VER_DETAIL WinVer; BOOL bRetOK = FALSE; if (KeGetCurrentIrql() > PASSIVE_LEVEL) { return bRetOK; } __try { WinVer=GetWindowsVersion(); switch (WinVer) { case WINDOWS_VERSION_XP: StartingVpnOffset=0x00; ControlAreaOffset=0x18; break; case WINDOWS_VERSION_2K3: StartingVpnOffset=0x0c; ControlAreaOffset=0x18; break; case WINDOWS_VERSION_2K3_SP1_SP2: StartingVpnOffset=0x0c; ControlAreaOffset=0x18; break; case WINDOWS_VERSION_VISTA_2008: //Vista+2008开始 StartingVpnOffset=0x0c; SubsectionOffset=0x24; break; /*case 6002: //2008 StartingVpnOffset=0x0c; SubsectionOffset=0x24; break; */ case WINDOWS_VERSION_7_7000: case WINDOWS_VERSION_7_7600_UP: StartingVpnOffset=0x0c; SubsectionOffset=0x24; break; } if ( WinVer == WINDOWS_VERSION_XP || WinVer == WINDOWS_VERSION_2K3 || WinVer == WINDOWS_VERSION_2K3_SP1_SP2 ) //xp || 2003 { if (!MmIsAddressValidEx((VadNode+StartingVpnOffset))) { bRetOK = FALSE; __leave; } StartingVpn=*(DWORD*)(VadNode+StartingVpnOffset); if (!StartingVpn) { bRetOK = FALSE; __leave; } // StartingVpn<<12 is base (xp下exe模块的地址一般都是 0x01000000) if (NULL != StartingVpn<<12) { if (!MmIsAddressValidEx((VadNode+ControlAreaOffset))) { bRetOK = FALSE; __leave; } ControlArea=(PCONTROL_AREA)(*(DWORD*)(VadNode+ControlAreaOffset)); //好像这里用RMmIsAddressValidEx判断VCS_TRANSITION内存不准确蓝屏,无语~~ //(蓝屏其实就是没有判断VCS_TRANSITION类型,这个类型也是无法访问) if (MmIsAddressValidEx(ControlArea)) { FileObject=ControlArea->FilePointer; if (MmIsAddressValidEx(FileObject) && ValidateUnicodeString(&FileObject->FileName) && FileObject->FileName.Buffer != NULL && FileObject->FileName.Length > 0) { if (ModuleCount < 518) //会有518个dll么? { if (sizeof(PDll->DllInfo[ModuleCount].lpwzDllModule) > FileObject->FileName.Length) { memset(PDll->DllInfo[ModuleCount].lpwzDllModule,0,sizeof(PDll->DllInfo[ModuleCount].lpwzDllModule)); //KdPrint(("%d:%ws\n",FileObject->FileName.Buffer,FileObject->FileName.Length)); SafeCopyMemory( FileObject->FileName.Buffer, PDll->DllInfo[ModuleCount].lpwzDllModule, FileObject->FileName.Length ); PDll->DllInfo[ModuleCount].ulBase = (ULONG)StartingVpn<<12; ModuleCount++; PDll->ulCount = ModuleCount; bRetOK = TRUE; } } } } } } else if ( WinVer == WINDOWS_VERSION_VISTA_2008 || WinVer == WINDOWS_VERSION_7_7000 || WinVer == WINDOWS_VERSION_7_7600_UP) //win7||vista||2008 { if (!MmIsAddressValidEx((VadNode+StartingVpnOffset))) { bRetOK = FALSE; __leave; } StartingVpn=*(DWORD*)(VadNode+StartingVpnOffset); if (!StartingVpn) { bRetOK = FALSE; __leave; } // StartingVpn<<12 is base (xp下exe模块的地址一般都是 0x01000000) if (NULL != StartingVpn<<12) { if (DebugOn) KdPrint(("[%08x]VadNode:%X\n",StartingVpn<<12,VadNode)); if (!MmIsAddressValidEx((VadNode+SubsectionOffset))) { bRetOK = FALSE; __leave; } Subsection=*(DWORD*)(VadNode+SubsectionOffset); //win7下新加的结构 if (MmIsAddressValidEx(Subsection)) { ControlArea=(PCONTROL_AREA)(*(DWORD*)Subsection); //好像这里用RMmIsAddressValidEx判断VCS_TRANSITION内存不准确蓝屏,无语~~ //(蓝屏其实就是没有判断VCS_TRANSITION类型,这个类型也是无法访问) if (MmIsAddressValidEx(ControlArea)) { FilePointer=(PEX_FAST_REF)&ControlArea->FilePointer; if (MmIsAddressValidEx(FilePointer)) { FileObject=(PFILE_OBJECT)(((DWORD)FilePointer->Object)&(~FilePointer->RefCnt)); if (MmIsAddressValidEx(FileObject) && ValidateUnicodeString(&FileObject->FileName) && FileObject->FileName.Buffer != NULL && FileObject->FileName.Length > 0) { if (ModuleCount < 518) //会有518个dll么? { if (sizeof(PDll->DllInfo[ModuleCount].lpwzDllModule) > FileObject->FileName.Length) { memset(PDll->DllInfo[ModuleCount].lpwzDllModule,0,sizeof(PDll->DllInfo[ModuleCount].lpwzDllModule)); SafeCopyMemory( FileObject->FileName.Buffer, PDll->DllInfo[ModuleCount].lpwzDllModule, FileObject->FileName.Length ); PDll->DllInfo[ModuleCount].ulBase = (ULONG)StartingVpn<<12; ModuleCount++; PDll->ulCount = ModuleCount; bRetOK = TRUE; } } } } } } } } } __except(EXCEPTION_EXECUTE_HANDLER) { if (DebugOn) DbgPrint("VadTree Error \r\n"); } return bRetOK; }
//注销 回调 void GetLeaveSessionCallback(PSYSTEM_NOTIFY SystemNotify) { UCHAR* Base; int i=0; ULONG Address; PSEP_LOGON_SESSION_TERMINATED_NOTIFICATION CallbackList=NULL; PSEP_LOGON_SESSION_TERMINATED_NOTIFICATION TmpCallbackList=NULL; Address=0; Base=(UCHAR*)GetFunctionAddr(L"SeRegisterLogonSessionTerminatedRoutine"); for(i=0;i<0x512;i++) { if((*(UCHAR*)(Base)==0xff)&&(*(UCHAR*)(Base+1)==0xa1)) { Address=*(ULONG*)(Base+2); break; } Base++; } if (!MmIsAddressValidEx(Address)){ return; } if (DebugOn) DbgPrint("获取注销回调:%08x\n",Address); CallbackList=Address; if(CallbackList->Next==0) { ; } else { TmpCallbackList=CallbackList->Next; LeaveSessionNum = SystemNotify->ulCount; while(1) { if (DebugOn) DbgPrint("回调入口:%X 类型:SeFileSystem\n",(ULONG)TmpCallbackList->CallbackRoutine); memset(SystemNotify->NotifyInfo[LeaveSessionNum].lpwzObject,0, sizeof(SystemNotify->NotifyInfo[LeaveSessionNum].lpwzObject)); swprintf(SystemNotify->NotifyInfo[LeaveSessionNum].lpwzObject, L"SEP_LOGON_SESSION_TERMINATED_NOTIFICATION:0x%08X",(ULONG)TmpCallbackList); SystemNotify->NotifyInfo[LeaveSessionNum].ulObject = (ULONG)TmpCallbackList; SystemNotify->NotifyInfo[LeaveSessionNum].ulNotifyBase = (ULONG)(TmpCallbackList->CallbackRoutine); memset(SystemNotify->NotifyInfo[LeaveSessionNum].lpwzType,0,sizeof(SystemNotify->NotifyInfo[LeaveSessionNum].lpwzType)); wcscat(SystemNotify->NotifyInfo[LeaveSessionNum].lpwzType,L"SeFileSystem"); memset(SystemNotify->NotifyInfo[LeaveSessionNum].lpszModule,0,sizeof(SystemNotify->NotifyInfo[LeaveSessionNum].lpszModule)); if (!IsAddressInSystem( TmpCallbackList->CallbackRoutine, &ulModuleBase, &ulModuleSize, SystemNotify->NotifyInfo[LeaveSessionNum].lpszModule)) { strcat(SystemNotify->NotifyInfo[LeaveSessionNum].lpszModule,"Unknown"); } LeaveSessionNum++; SystemNotify->ulCount++; if(TmpCallbackList->Next==0) { break; } TmpCallbackList=TmpCallbackList->Next; } } }
BOOLEAN SKillDeleteFile( IN HANDLE FileHandle ) { NTSTATUS ntStatus = STATUS_SUCCESS; PFILE_OBJECT fileObject; PDEVICE_OBJECT DeviceObject; PIRP Irp; KEVENT event; FILE_DISPOSITION_INFORMATION FileInformation; IO_STATUS_BLOCK ioStatus; PIO_STACK_LOCATION irpSp; PSECTION_OBJECT_POINTERS pSectionObjectPointer; //////////////////// BOOL bInit = FALSE; ReLoadNtosCALL(&RObReferenceObjectByHandle,L"ObReferenceObjectByHandle",SystemKernelModuleBase,ImageModuleBase); ReLoadNtosCALL(&RKeInitializeEvent,L"KeInitializeEvent",SystemKernelModuleBase,ImageModuleBase); ReLoadNtosCALL(&RIoAllocateIrp,L"IoAllocateIrp",SystemKernelModuleBase,ImageModuleBase); ReLoadNtosCALL(&RIoCallDriver,L"IoCallDriver",SystemKernelModuleBase,ImageModuleBase); ReLoadNtosCALL(&RKeWaitForSingleObject,L"KeWaitForSingleObject",SystemKernelModuleBase,ImageModuleBase); if (RObReferenceObjectByHandle && RKeInitializeEvent && RIoAllocateIrp && RIoCallDriver && RKeWaitForSingleObject) { bInit = TRUE; } if (!bInit) return NULL; SKillStripFileAttributes( FileHandle); //去掉只读属性,才能删除只读文件 ntStatus = RObReferenceObjectByHandle(FileHandle, DELETE, *IoFileObjectType, KernelMode, &fileObject, NULL); if (!NT_SUCCESS(ntStatus)) { return FALSE; } DeviceObject = IoGetRelatedDeviceObject(fileObject); Irp = RIoAllocateIrp(DeviceObject->StackSize, TRUE); if (Irp == NULL) { ObDereferenceObject(fileObject); return FALSE; } RKeInitializeEvent(&event, SynchronizationEvent, FALSE); FileInformation.DeleteFile = TRUE; Irp->AssociatedIrp.SystemBuffer = &FileInformation; Irp->UserEvent = &event; Irp->UserIosb = &ioStatus; Irp->Tail.Overlay.OriginalFileObject = fileObject; Irp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread(); Irp->RequestorMode = KernelMode; irpSp = IoGetNextIrpStackLocation(Irp); irpSp->MajorFunction = IRP_MJ_SET_INFORMATION; irpSp->DeviceObject = DeviceObject; irpSp->FileObject = fileObject; irpSp->Parameters.SetFile.Length = sizeof(FILE_DISPOSITION_INFORMATION); irpSp->Parameters.SetFile.FileInformationClass = FileDispositionInformation; irpSp->Parameters.SetFile.FileObject = fileObject; IoSetCompletionRoutine( Irp, SkillSetFileCompletion, &event, TRUE, TRUE, TRUE); //再加上下面这三行代码 ,MmFlushImageSection 函数通过这个结构来检查是否可以删除文件。 //这个和Hook ulImageSectionObject = NULL; ulDataSectionObject = NULL; ulSharedCacheMap = NULL; pSectionObjectPointer = NULL; pSectionObjectPointer = fileObject->SectionObjectPointer; if (MmIsAddressValidEx(pSectionObjectPointer)) { ulImageSectionObject = pSectionObjectPointer->ImageSectionObject; // 备份之~~~ pSectionObjectPointer->ImageSectionObject = 0; //清零,准备删除 ulDataSectionObject = pSectionObjectPointer->DataSectionObject; //备份之 pSectionObjectPointer->DataSectionObject = 0; //清零,准备删除 ulSharedCacheMap = pSectionObjectPointer->SharedCacheMap; pSectionObjectPointer->SharedCacheMap = 0; } //发irp删除 RIoCallDriver(DeviceObject, Irp); //等待操作完毕 RKeWaitForSingleObject(&event, Executive, KernelMode, TRUE, NULL); //删除文件之后,从备份那里填充回来 pSectionObjectPointer = NULL; pSectionObjectPointer = fileObject->SectionObjectPointer; if (MmIsAddressValidEx(pSectionObjectPointer)) { if (ulImageSectionObject) pSectionObjectPointer->ImageSectionObject = ulImageSectionObject; //填充回来,不然蓝屏哦 if (ulDataSectionObject) pSectionObjectPointer->DataSectionObject = ulDataSectionObject; if (ulSharedCacheMap) pSectionObjectPointer->SharedCacheMap = ulSharedCacheMap; } ObDereferenceObject(fileObject); fileObject = NULL; return TRUE; }
VOID ProcessFullPathFromVAD(PEPROCESS Process,PDLLINFO PDll) { DWORD VadOffset=0; PVOID VadRootParent; WIN_VER_DETAIL WinVer; DWORD LeftChildOffset=0,RightChildOffset=0; DWORD ControlAreaOffset; PCONTROL_AREA ControlArea=NULL; DWORD Subsection; DWORD SubsectionOffset; PMMVAD MmvadLeft; PMMVAD MmvadRight; PFILE_OBJECT FileObject; BOOL bMmvad = FALSE; WinVer=GetWindowsVersion(); switch (WinVer) { case WINDOWS_VERSION_XP: VadOffset=0x11c; ControlAreaOffset=0x18; LeftChildOffset=0x0c; RightChildOffset=0x10; VadRootParent=(PVOID)*(ULONG*)((DWORD)Process+VadOffset); break; case WINDOWS_VERSION_2K3: VadOffset=0x258; ControlAreaOffset=0x18; LeftChildOffset=0x04; RightChildOffset=0x08; VadRootParent=(PVOID)*(ULONG*)((DWORD)Process+VadOffset); break; case WINDOWS_VERSION_2K3_SP1_SP2: //2003sp1 sp2 VadOffset=0x250; ControlAreaOffset=0x18; LeftChildOffset=0x04; RightChildOffset=0x08; VadRootParent=(PVOID)*(ULONG*)((DWORD)Process+VadOffset); break; case WINDOWS_VERSION_VISTA_2008: //Vista+2008 VadOffset=0x238; SubsectionOffset=0x24; LeftChildOffset=0x04; RightChildOffset=0x08; VadRootParent=(PVOID)((DWORD)Process+VadOffset); break; /*case WINDOWS_VERSION_VISTA_2008: //2008的版本号其实和Vista一样~ VadOffset=0x238; break; */ case WINDOWS_VERSION_7_7000: VadOffset=0x270; SubsectionOffset=0x24; LeftChildOffset=0x04; RightChildOffset=0x08; VadRootParent=(PVOID)((DWORD)Process+VadOffset); break; case WINDOWS_VERSION_7_7600_UP: VadOffset=0x278; SubsectionOffset=0x24; LeftChildOffset=0x04; RightChildOffset=0x08; VadRootParent=(PVOID)((DWORD)Process+VadOffset); break; } if (LeftChildOffset==0||RightChildOffset==0) { return; } if (!MmIsAddressValidEx(VadRootParent)) //要对vadroot(PMM_AVL_TABLE)进行检查即可,因为windows2008下没有 MMVAD 这个结构了 { if (DebugOn) KdPrint(("VAD is not a Valid Address\n")); return; } //首先判断PCONTROL_AREA是可以访问的,然后再枚举,修正: //http://bbs.pediy.com/showthread.php?t=148971 switch (WinVer) { case WINDOWS_VERSION_XP: case WINDOWS_VERSION_2K3_SP1_SP2: ControlArea = (PCONTROL_AREA)(*(DWORD*)((ULONG)VadRootParent+ControlAreaOffset)); if (MmIsAddressValidEx(ControlArea)){ bMmvad = TRUE; break; } //MmvadLeft,MmvadRight其实是指向一个VadRoot MmvadLeft = (PMMVAD)(*(DWORD*)((ULONG)VadRootParent+LeftChildOffset)); if (MmIsAddressValidEx(MmvadLeft)){ ControlArea = (PCONTROL_AREA)(*(DWORD*)((ULONG)MmvadLeft+ControlAreaOffset)); if (MmIsAddressValidEx(ControlArea)){ bMmvad = TRUE; break; } } MmvadRight = (PMMVAD)(*(DWORD*)((ULONG)VadRootParent+RightChildOffset)); if (MmIsAddressValidEx(MmvadRight)){ ControlArea = (PCONTROL_AREA)(*(DWORD*)((ULONG)MmvadRight+ControlAreaOffset)); if (MmIsAddressValidEx(ControlArea)){ bMmvad = TRUE; break; } } break; case WINDOWS_VERSION_7_7000: case WINDOWS_VERSION_7_7600_UP: Subsection = *(DWORD*)((ULONG)VadRootParent+SubsectionOffset); if (MmIsAddressValidEx(Subsection)){ ControlArea=(PCONTROL_AREA)(*(DWORD*)Subsection); if (MmIsAddressValidEx(ControlArea)){ bMmvad = TRUE; break; } } //MmvadLeft,MmvadRight其实是指向一个VadRoot MmvadLeft = (PMMVAD)(*(DWORD*)((ULONG)VadRootParent+LeftChildOffset)); if (MmIsAddressValidEx(MmvadLeft)){ Subsection = *(DWORD*)((ULONG)MmvadLeft+SubsectionOffset); if (MmIsAddressValidEx(Subsection)){ ControlArea=(PCONTROL_AREA)(*(DWORD*)Subsection); if (MmIsAddressValidEx(ControlArea)){ bMmvad = TRUE; break; } } } MmvadRight = (PMMVAD)(*(DWORD*)((ULONG)VadRootParent+RightChildOffset)); if (MmIsAddressValidEx(MmvadRight)){ Subsection = *(DWORD*)((ULONG)MmvadRight+SubsectionOffset); if (MmIsAddressValidEx(Subsection)){ ControlArea=(PCONTROL_AREA)(*(DWORD*)Subsection); if (MmIsAddressValidEx(ControlArea)){ bMmvad = TRUE; break; } } } break; } if (!bMmvad){ return; } if (DebugOn) KdPrint(("ControlArea=0x%08X success\n",ControlArea)); ParseVadTree(VadRootParent,PDll); }
/* DWORD GetDllModuleFromPeb(PEPROCESS Process,PDLLINFO PDll) { DWORD PebOffset=0; DWORD PebLdrOffset = 0; DWORD Peb; PPEB_LDR_DATA PebLdr; PLDR_DATA_TABLE_ENTRY LdrTableEntry; PLIST_ENTRY pListHead,pListNext; int i = 0; WIN_VER_DETAIL WinVer; BOOL bRetOK = FALSE; if (!MmIsAddressValidEx(Process)) { return bRetOK; } __try { WinVer=GetWindowsVersion(); switch (WinVer) { case WINDOWS_VERSION_XP: //xp PebOffset=0x1b0; PebLdrOffset = 0x0c; break; case WINDOWS_VERSION_2K3_SP1_SP2: //2003 PebOffset=0x1a0; PebLdrOffset = 0x0c; break; case WINDOWS_VERSION_7_7000: //win7 7000 PebOffset=0x1a0; PebLdrOffset = 0x0c; break; case WINDOWS_VERSION_7_7600_UP: //win7 7600 PebOffset=0x1a8; PebLdrOffset = 0x0c; break; } if (PebOffset==0 || PebLdrOffset==0) { bRetOK = FALSE; __leave; } Peb = *(DWORD*)((DWORD)Process+PebOffset); ProbeForRead((PVOID)Peb,4,1);//PEB是用户空间的,可能会不能访问 if (Peb == 0 || !MmIsAddressValidEx(Peb)) { if (DebugOn) DbgPrint("Peb is null\n"); bRetOK = FALSE; __leave; } PebLdr=(PPEB_LDR_DATA)*(DWORD*)(Peb+PebLdrOffset); ProbeForRead((PVOID)PebLdr,4,1); if (!MmIsAddressValidEx(PebLdr)) { if (DebugOn) DbgPrint("PebLdr offset is null\n"); bRetOK = FALSE; __leave; } pListHead=&PebLdr->InLoadOrderModuleList; pListNext=pListHead->Flink; while (pListHead!=pListNext) { LdrTableEntry=(PLDR_DATA_TABLE_ENTRY)pListNext; if (!MmIsAddressValidEx(LdrTableEntry)) { break; } if (ValidateUnicodeString(&LdrTableEntry->FullDllName) && LdrTableEntry->FullDllName.Buffer != NULL && LdrTableEntry->FullDllName.Length > 0 ) { if (i < 518) //会有518个dll么? { if (sizeof(PDll->DllInfo[i].lpwzDllModule) > LdrTableEntry->FullDllName.Length) { if (DebugOn) DbgPrint("DllBase:%x dll path %ws:%d\n",LdrTableEntry->DllBase,LdrTableEntry->FullDllName.Buffer,LdrTableEntry->FullDllName.Length); PDll->DllInfo[i].ulBase = LdrTableEntry->DllBase; memset(PDll->DllInfo[i].lpwzDllModule,0,sizeof(PDll->DllInfo[i].lpwzDllModule)); SafeCopyMemory( LdrTableEntry->FullDllName.Buffer, PDll->DllInfo[i].lpwzDllModule, LdrTableEntry->FullDllName.Length ); i++; PDll->ulCount = i; } } } pListNext=pListNext->Flink; } bRetOK = TRUE; } __except(EXCEPTION_EXECUTE_HANDLER) { if (DebugOn) DbgPrint("GetDllNameFromPeb Error \r\n"); } return bRetOK; } */ VOID EunmProcessModuleByVirtualMemory(ULONG EProcess,PDLLINFO PDll) { ULONG dwStartAddr = 0x00000000; HANDLE hProcess; MEMORY_BASIC_INFORMATION mbi; PUNICODE_STRING SectionName = NULL; OBJECT_ATTRIBUTES ObjectAttributes; CLIENT_ID ClientId={0}; NTSTATUS status; int i=0; int count = 0; ULONG ulDllSize; BOOL bInit = FALSE; WinVer = GetWindowsVersion(); switch(WinVer) { case WINDOWS_VERSION_XP: if (!MmIsAddressValidEx(RZwQueryVirtualMemory)){ RZwQueryVirtualMemory = GetZwQueryVirtualMemoryAddress(); } break; case WINDOWS_VERSION_7_7600_UP: case WINDOWS_VERSION_7_7000: ReLoadNtosCALL(&RZwQueryVirtualMemory,L"ZwQueryVirtualMemory",SystemKernelModuleBase,ImageModuleBase); //win7导出了,可以直接用 break; case WINDOWS_VERSION_2K3_SP1_SP2: if (!MmIsAddressValidEx(RZwQueryVirtualMemory)){ RZwQueryVirtualMemory = GetZwQueryVirtualMemoryAddress(); } break; } ReLoadNtosCALL(&RObOpenObjectByPointer,L"ObOpenObjectByPointer",SystemKernelModuleBase,ImageModuleBase); ReLoadNtosCALL(&RExAllocatePool,L"ExAllocatePool",SystemKernelModuleBase,ImageModuleBase); ReLoadNtosCALL(&RExFreePool,L"ExFreePool",SystemKernelModuleBase,ImageModuleBase); ReLoadNtosCALL(&RZwClose,L"ZwClose",SystemKernelModuleBase,ImageModuleBase); if (RZwQueryVirtualMemory && RObOpenObjectByPointer && RExAllocatePool && RExFreePool && RZwClose) { bInit = TRUE; } if (!bInit) return FALSE; //进程已经退出鸟 if (!IsExitProcess(EProcess)){ return FALSE; } status = RObOpenObjectByPointer( EProcess, // Object OBJ_KERNEL_HANDLE, // HandleAttributes NULL, // PassedAccessState OPTIONAL NULL, // DesiredAccess *PsProcessType, // ObjectType KernelMode, // AccessMode &hProcess); if (!NT_SUCCESS(status)) { if (DebugOn) KdPrint(("ObOpenObjectByPointer failed:%d",RtlNtStatusToDosError(status))); return NULL; } SectionName = (PUNICODE_STRING)RExAllocatePool(NonPagedPool,260*sizeof(WCHAR)); if (!SectionName) { RZwClose(hProcess); return; } memset(SectionName,0,260*sizeof(WCHAR)); __try { for (dwStartAddr=0; dwStartAddr<0x80000000; dwStartAddr=dwStartAddr+0x10000) { status = RZwQueryVirtualMemory( hProcess, (PVOID)dwStartAddr, MemoryBasicInformation, &mbi, sizeof(MEMORY_BASIC_INFORMATION), 0 ); if (NT_SUCCESS(status)) { if(mbi.Type == MEM_IMAGE) { status = RZwQueryVirtualMemory( hProcess, (PVOID)dwStartAddr, MemorySectionName, SectionName, 260*sizeof(WCHAR), 0 ); if (NT_SUCCESS(status)) { if (i) count = i - 1; //如果当前的DLL模块路径 不等于前一个,则说明是开始了下一个DLL的枚举了。比如: //c:\windows\system32\ntdll.dll //c:\windows\system32\ntdll.dll //c:\windows\system32\ntdll.dll //c:\windows\system32\ntdll.dll //c:\windows\system32\ntdll.dll //c:\windows\system32\kernel32.dll if (_wcsnicmp(PDll->DllInfo[count].lpwzDllModule,SectionName->Buffer,SectionName->Length/2) != 0 && sizeof(PDll->DllInfo[i].lpwzDllModule) > SectionName->Length) { if (DebugOn) KdPrint(("DLL-->%08x:%08x:%ws\r\n",mbi.BaseAddress,dwStartAddr,SectionName->Buffer)); PDll->DllInfo[i].ulBase = dwStartAddr; SafeCopyMemory( SectionName->Buffer, PDll->DllInfo[i].lpwzDllModule, SectionName->Length ); i++; PDll->ulCount = i; if (i > 518) { break; } /* //获取dll大小 //备注一下这个方法 for (ulDllSize = dwStartAddr+mbi.RegionSize;ulDllSize < 0x80000000;ulDllSize += mbi.RegionSize) { status = ZwQueryVirtualMemory( hProcess, (PVOID)ulDllSize, MemoryBasicInformation, &mbi, sizeof(MEMORY_BASIC_INFORMATION), 0 ); if (NT_SUCCESS(status)) { if(mbi.Type != MEM_IMAGE) { KdPrint(("DLL-->%08x:%08x:%ws\r\n",dwStartAddr,ulDllSize-dwStartAddr,SectionName->Buffer)); break; } } } */ } } } } } }__except(EXCEPTION_EXECUTE_HANDLER){ goto _FunctionRet; } _FunctionRet: RExFreePool(SectionName); if (DebugOn) KdPrint(("ZwQueryVirtualMemory DLL count:%d-%d\r\n",i,PDll->ulCount)); RZwClose(hProcess); }
void GetFileSystemNotifyCallBack(PSYSTEM_NOTIFY SystemNotify) { PLIST_ENTRY pListEntry; PLIST_ENTRY pListNext; PNOTIFICATION_PACKET pNotificationPacket; PDRIVER_OBJECT Driver_Object_Temp;//用于遍历文件系统回调时保存遍历到的驱动对象以便比较 GetListHeadAddr(); if (!MmIsAddressValidEx(IopFsNotifyChangeQueueHead)){ return; } if (DebugOn) KdPrint(("IopFsNotifyChangeQueueHead:%08x\r\n",IopFsNotifyChangeQueueHead)); pNotificationPacket=IopFsNotifyChangeQueueHead; pListEntry=&(pNotificationPacket->ListEntry); if (!MmIsAddressValidEx(pListEntry)){ return; } pListEntry=pListEntry->Flink; if (!MmIsAddressValidEx(pListEntry)){ return; } pListNext=pListEntry; FsNotifyNum = SystemNotify->ulCount; Driver_Object_Temp=*(ULONG*)((ULONG)(pListNext)+8); { if (!MmIsAddressValidEx(((ULONG)(pListNext)+12))){ return; } FileSystemRoutine=*(ULONG*)((ULONG)(pListNext)+12); if (DebugOn) DbgPrint("回调入口:%X 类型:FsNotifyChange 驱动对象:%X 驱动名称:%wZ 包地址:%X\n",FileSystemRoutine,(ULONG)Driver_Object_Temp,&Driver_Object_Temp->DriverName,(ULONG)pListNext); memset(SystemNotify->NotifyInfo[FsNotifyNum].lpwzObject,0, sizeof(SystemNotify->NotifyInfo[FsNotifyNum].lpwzObject)); swprintf(SystemNotify->NotifyInfo[FsNotifyNum].lpwzObject, L"DEVICE_OBJECT:0x%08X",(ULONG)Driver_Object_Temp); SystemNotify->NotifyInfo[FsNotifyNum].ulNotifyBase = (ULONG)(FileSystemRoutine); memset(SystemNotify->NotifyInfo[FsNotifyNum].lpwzType,0,sizeof(SystemNotify->NotifyInfo[FsNotifyNum].lpwzType)); wcscat(SystemNotify->NotifyInfo[FsNotifyNum].lpwzType,L"FsNotifyChange"); memset(SystemNotify->NotifyInfo[FsNotifyNum].lpszModule,0,sizeof(SystemNotify->NotifyInfo[FsNotifyNum].lpszModule)); if (!IsAddressInSystem( FileSystemRoutine, &ulModuleBase, &ulModuleSize, SystemNotify->NotifyInfo[FsNotifyNum].lpszModule)) { strcat(SystemNotify->NotifyInfo[FsNotifyNum].lpszModule,"Unknown"); } FsNotifyNum++; SystemNotify->ulCount++; } if(!MmIsAddressValidEx((PVOID)pListNext)) { return; } if(!MmIsAddressValidEx((PVOID)pListNext->Flink)) { return; } if(!MmIsAddressValidEx((PVOID)pListNext->Flink->Flink)) { return; } while(pListNext->Flink->Flink!=pListEntry) { pListNext=pListNext->Flink; Driver_Object_Temp=*(ULONG*)((ULONG)(pListNext)+8); { if (!MmIsAddressValidEx(((ULONG)(pListNext)+12))){ continue; } FileSystemRoutine=*(ULONG*)((ULONG)(pListNext)+12); if (DebugOn) DbgPrint("回调入口:%X 类型:FsNotifyChange 驱动对象:%X 驱动名称:%wZ 包地址:%X\n",FileSystemRoutine,(ULONG)Driver_Object_Temp,&Driver_Object_Temp->DriverName,(ULONG)pListNext); memset(SystemNotify->NotifyInfo[FsNotifyNum].lpwzObject,0, sizeof(SystemNotify->NotifyInfo[FsNotifyNum].lpwzObject)); swprintf(SystemNotify->NotifyInfo[FsNotifyNum].lpwzObject, L"DEVICE_OBJECT:0x%08X",(ULONG)Driver_Object_Temp); SystemNotify->NotifyInfo[FsNotifyNum].ulNotifyBase = (ULONG)(FileSystemRoutine); memset(SystemNotify->NotifyInfo[FsNotifyNum].lpwzType,0,sizeof(SystemNotify->NotifyInfo[FsNotifyNum].lpwzType)); wcscat(SystemNotify->NotifyInfo[FsNotifyNum].lpwzType,L"FsNotifyChange"); memset(SystemNotify->NotifyInfo[FsNotifyNum].lpszModule,0,sizeof(SystemNotify->NotifyInfo[FsNotifyNum].lpszModule)); if (!IsAddressInSystem( FileSystemRoutine, &ulModuleBase, &ulModuleSize, SystemNotify->NotifyInfo[FsNotifyNum].lpszModule)) { strcat(SystemNotify->NotifyInfo[FsNotifyNum].lpszModule,"Unknown"); } FsNotifyNum++; SystemNotify->ulCount++; } } }
void GetShutDownCallBack(PSYSTEM_NOTIFY SystemNotify) { //UCHAR* Base=(UCHAR*)IoRegisterShutdownNotification; UCHAR* Base=(UCHAR*)GetFunctionAddr(L"IoRegisterShutdownNotification"); int i=0; ULONG NotifyAddr;//回调函数地址 PSHUTDOWN_PACKET pShutDownPack; PLIST_ENTRY pListEntry; PLIST_ENTRY pListNext; ULONG Address; WIN_VER_DETAIL WinVer; Address=0; for(i=0;i<0x512;i++) { WinVer = GetWindowsVersion(); switch(WinVer) { case WINDOWS_VERSION_2K3_SP1_SP2: case WINDOWS_VERSION_XP: if((*(UCHAR*)Base==0x8b)&&(*(UCHAR*)(Base+1)==0xd7)&&(*(UCHAR*)(Base+2)==0xb9)) { Address=*(ULONG*)(Base+3); break; } break; case WINDOWS_VERSION_7_7000: if((*(UCHAR*)Base==0xf0)&&(*(UCHAR*)(Base+1)==0xff)&&(*(UCHAR*)(Base+2)==0xbf)) { Address=*(ULONG*)(Base+3); break; } break; case WINDOWS_VERSION_7_7600_UP: if((*(UCHAR*)Base==0xef)&&(*(UCHAR*)(Base+1)==0xff)&&(*(UCHAR*)(Base+2)==0xbf)) { Address=*(ULONG*)(Base+3); break; } break; } Base++; } if (!MmIsAddressValidEx(Address)){ return; } if (DebugOn) DbgPrint("获取ShutDown回调数组:%08x\n",Address); pShutDownPack=Address; pListEntry=&(pShutDownPack->ListEntry); ShutDownNum = SystemNotify->ulCount; pListNext=pListEntry->Flink; { pShutDownPack=pListNext; NotifyAddr=GetNotifyAddr(pShutDownPack->DeviceObject); if (DebugOn) DbgPrint("回调入口:%X 类型:ShutDown 设备对象:%X\n",NotifyAddr,pShutDownPack->DeviceObject); memset(SystemNotify->NotifyInfo[ShutDownNum].lpwzObject,0, sizeof(SystemNotify->NotifyInfo[ShutDownNum].lpwzObject)); swprintf(SystemNotify->NotifyInfo[ShutDownNum].lpwzObject, L"DEVICE_OBJECT:0x%08X",(ULONG)pShutDownPack->DeviceObject); SystemNotify->NotifyInfo[ShutDownNum].ulObject = (ULONG)pShutDownPack->DeviceObject; SystemNotify->NotifyInfo[ShutDownNum].ulNotifyBase = (ULONG)(NotifyAddr); memset(SystemNotify->NotifyInfo[ShutDownNum].lpwzType,0,sizeof(SystemNotify->NotifyInfo[ShutDownNum].lpwzType)); wcscat(SystemNotify->NotifyInfo[ShutDownNum].lpwzType,L"ShutDown"); memset(SystemNotify->NotifyInfo[ShutDownNum].lpszModule,0,sizeof(SystemNotify->NotifyInfo[ShutDownNum].lpszModule)); if (!IsAddressInSystem( NotifyAddr, &ulModuleBase, &ulModuleSize, SystemNotify->NotifyInfo[ShutDownNum].lpszModule)) { strcat(SystemNotify->NotifyInfo[ShutDownNum].lpszModule,"Unknown"); } ShutDownNum++; SystemNotify->ulCount++; } while(pListNext->Flink!=pListEntry) { pListNext=pListNext->Flink; pShutDownPack=pListNext; NotifyAddr=GetNotifyAddr(pShutDownPack->DeviceObject); if (DebugOn) DbgPrint("回调入口:%X 类型:ShutDown 设备对象:%X\n",NotifyAddr,pShutDownPack->DeviceObject); memset(SystemNotify->NotifyInfo[ShutDownNum].lpwzObject,0, sizeof(SystemNotify->NotifyInfo[ShutDownNum].lpwzObject)); swprintf(SystemNotify->NotifyInfo[ShutDownNum].lpwzObject, L"DEVICE_OBJECT:0x%08X",(ULONG)pShutDownPack->DeviceObject); SystemNotify->NotifyInfo[ShutDownNum].ulObject = (ULONG)pShutDownPack->DeviceObject; SystemNotify->NotifyInfo[ShutDownNum].ulNotifyBase = (ULONG)(NotifyAddr); memset(SystemNotify->NotifyInfo[ShutDownNum].lpwzType,0,sizeof(SystemNotify->NotifyInfo[ShutDownNum].lpwzType)); wcscat(SystemNotify->NotifyInfo[ShutDownNum].lpwzType,L"ShutDown"); memset(SystemNotify->NotifyInfo[ShutDownNum].lpszModule,0,sizeof(SystemNotify->NotifyInfo[ShutDownNum].lpszModule)); if (!IsAddressInSystem( NotifyAddr, &ulModuleBase, &ulModuleSize, SystemNotify->NotifyInfo[ShutDownNum].lpszModule)) { strcat(SystemNotify->NotifyInfo[ShutDownNum].lpszModule,"Unknown"); } ShutDownNum++; SystemNotify->ulCount++; } }
//L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\"; NTSTATUS ReadRegistry(PSTARTUP_INFO Startup,WCHAR *DriverServiceNamePath,WCHAR *ReadKey) { NTSTATUS Status = STATUS_UNSUCCESSFUL; OBJECT_ATTRIBUTES NetworkClassKeyObject; OBJECT_ATTRIBUTES SubKeyObject; HANDLE NetworkClassKeyHandle; HANDLE SubKeyHandle; ULONG i, SubkeyIndex, ResultLength, InterfacesKeyStringLength; PWCHAR InterfacesKeyString; UNICODE_STRING NetworkClassKey, InterfacesKey, UnicodeReadKey, DriverServiceName; PKEY_BASIC_INFORMATION KeyInformation; PKEY_VALUE_PARTIAL_INFORMATION KeyValueInformation; WCHAR *KeyName = NULL; BOOL bInit = FALSE; ReLoadNtosCALL(&RRtlInitUnicodeString,L"RtlInitUnicodeString",SystemKernelModuleBase,ImageModuleBase); ReLoadNtosCALL(&RZwOpenKey,L"ZwOpenKey",SystemKernelModuleBase,ImageModuleBase); ReLoadNtosCALL(&RExAllocatePool,L"ExAllocatePool",SystemKernelModuleBase,ImageModuleBase); ReLoadNtosCALL(&RExFreePool,L"ExFreePool",SystemKernelModuleBase,ImageModuleBase); ReLoadNtosCALL(&RZwEnumerateKey,L"ZwEnumerateKey",SystemKernelModuleBase,ImageModuleBase); ReLoadNtosCALL(&RZwQueryValueKey,L"ZwQueryValueKey",SystemKernelModuleBase,ImageModuleBase); ReLoadNtosCALL(&RZwClose,L"ZwClose",SystemKernelModuleBase,ImageModuleBase); if (RRtlInitUnicodeString && RZwOpenKey && RExAllocatePool && RExFreePool && RZwEnumerateKey && RZwQueryValueKey && RZwClose) { bInit = TRUE; } if (!bInit) { return Status; } if (DebugOn) KdPrint(("Starting")); RRtlInitUnicodeString(&UnicodeReadKey,ReadKey); RRtlInitUnicodeString(&NetworkClassKey,DriverServiceNamePath); InitializeObjectAttributes( &NetworkClassKeyObject, &NetworkClassKey, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL ); Status = RZwOpenKey( &NetworkClassKeyHandle, KEY_ALL_ACCESS, &NetworkClassKeyObject ); if (!NT_SUCCESS(Status)) { if (DebugOn) DbgPrint("Failed to open Network Class key\n"); return Status; } if (DebugOn) KdPrint(("ZwOpenKey success")); SubkeyIndex = 0; i = Startup->ulCount; while ((Status = RZwEnumerateKey(NetworkClassKeyHandle, SubkeyIndex, KeyBasicInformation, NULL, 0, &ResultLength)) != STATUS_NO_MORE_ENTRIES) { if ((Status != STATUS_SUCCESS) && (Status != STATUS_BUFFER_OVERFLOW) && (Status != STATUS_BUFFER_TOO_SMALL)) { if (DebugOn) DbgPrint("ZwEnumerateKey 1 failed in SetupRegistry (%lx)\n", Status); Status = STATUS_UNSUCCESSFUL; break; } if ((KeyInformation = (PKEY_BASIC_INFORMATION)RExAllocatePool(NonPagedPool, ResultLength)) == NULL) { if (DebugOn) DbgPrint("ExAllocatePool KeyData failed in SetupRegistry\n"); Status = STATUS_UNSUCCESSFUL; break; } memset(KeyInformation,0,ResultLength); Status = RZwEnumerateKey( NetworkClassKeyHandle, SubkeyIndex, KeyBasicInformation, KeyInformation, ResultLength, &ResultLength ); if (!NT_SUCCESS(Status)) { if (DebugOn) DbgPrint("ZwEnumerateKey 2 failed in SetupRegistry\n"); Status = STATUS_UNSUCCESSFUL; RExFreePool(KeyInformation); break; } if ((KeyName = (WCHAR *)RExAllocatePool(NonPagedPool, 260*sizeof(WCHAR))) == NULL){ continue; } memset(KeyName,0,260*sizeof(WCHAR)); SafeCopyMemory(KeyInformation->Name,KeyName,KeyInformation->NameLength); //KdPrint(("Key:%ws\n",KeyName)); //读取UnicodeReadKey RRtlInitUnicodeString(&DriverServiceName,KeyName); InitializeObjectAttributes( &SubKeyObject, &DriverServiceName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NetworkClassKeyHandle, NULL ); Status = RZwOpenKey( &SubKeyHandle, KEY_ALL_ACCESS, &SubKeyObject ); if (NT_SUCCESS(Status)) { if ((Status = RZwQueryValueKey(SubKeyHandle, &UnicodeReadKey, KeyValuePartialInformation, NULL, 0, &ResultLength)) != STATUS_OBJECT_NAME_NOT_FOUND) { if ((Status != STATUS_SUCCESS) && (Status != STATUS_BUFFER_OVERFLOW) && (Status != STATUS_BUFFER_TOO_SMALL)) { RZwClose(SubKeyHandle); RExFreePool(KeyInformation); break; } KeyValueInformation = (PKEY_VALUE_PARTIAL_INFORMATION)RExAllocatePool(NonPagedPool, ResultLength); if (KeyValueInformation) { memset(KeyValueInformation,0,ResultLength); Status = RZwQueryValueKey( SubKeyHandle, &UnicodeReadKey, KeyValuePartialInformation, KeyValueInformation, ResultLength, &ResultLength ); if (NT_SUCCESS(Status)) { //KdPrint(("%ws -> %ws\n",KeyName,KeyValueInformation->Data)); if (MmIsAddressValidEx(KeyValueInformation->Data) && KeyValueInformation->DataLength > 0) { SafeCopyMemory(DriverServiceName.Buffer,Startup->Startup[i].lpwzName,DriverServiceName.Length); SafeCopyMemory(DriverServiceNamePath,Startup->Startup[i].lpwzKeyPath,wcslen(DriverServiceNamePath)*2); SafeCopyMemory(KeyValueInformation->Data,Startup->Startup[i].lpwzKeyValue,KeyValueInformation->DataLength); i++; Startup->ulCount = i; if (DebugOn) KdPrint(("%ws -> %ws\n",KeyName,KeyValueInformation->Data)); } } RExFreePool(KeyValueInformation); } } RZwClose(SubKeyHandle); } RExFreePool(KeyName); RExFreePool(KeyInformation); KeyName = NULL; KeyInformation = NULL; SubkeyIndex++; } if (NetworkClassKeyHandle) RZwClose(NetworkClassKeyHandle); return Status; }
//得到文件系统回调链表头地址 VOID GetListHeadAddr() { PUCHAR Addr; PUCHAR x,i; UNICODE_STRING IoRegisterFsRegistrationChangeString={0}; PVOID EnumParameter; WIN_VER_DETAIL WinVer; ULONG ulIoRegisterFsRegistrationChangeMountAware; RtlInitUnicodeString(&IoRegisterFsRegistrationChangeString, L"IoRegisterFsRegistrationChange"); Addr=MmGetSystemRoutineAddress(&IoRegisterFsRegistrationChangeString); IopFsNotifyChangeQueueHead = NULL; WinVer = GetWindowsVersion(); switch(WinVer) { case WINDOWS_VERSION_2K3_SP1_SP2: case WINDOWS_VERSION_XP: case WINDOWS_VERSION_7_7000: // Addr=*(ULONG*)((BYTE*)Addr+25); // IopFsNotifyChangeQueueHead=Addr; for (i=(ULONG)Addr;i < i+SizeOfProc(Addr);i++) { if (*i == 0xbe) { IopFsNotifyChangeQueueHead = *(PULONG)(i+1); if (MmIsAddressValidEx(IopFsNotifyChangeQueueHead)) { return; } } } break; case WINDOWS_VERSION_7_7600_UP: for (i=(ULONG)Addr;i < i+SizeOfProc(Addr);i++) { if (*i == 0xe8) { ulIoRegisterFsRegistrationChangeMountAware = *(PULONG)(i+1)+(ULONG)(i+5); if (MmIsAddressValidEx(ulIoRegisterFsRegistrationChangeMountAware)) { if (DebugOn) KdPrint(("ulIoRegisterFsRegistrationChangeMountAware:%08x\r\n",ulIoRegisterFsRegistrationChangeMountAware)); for (x=(ULONG)ulIoRegisterFsRegistrationChangeMountAware;x < x+SizeOfProc(ulIoRegisterFsRegistrationChangeMountAware);x++) { if (*x == 0xbf) { if (DebugOn) KdPrint(("x:%08x\r\n",x)); IopFsNotifyChangeQueueHead = *(PULONG)(x+1); if (MmIsAddressValidEx(IopFsNotifyChangeQueueHead)) { return; } break; } } } break; } } break; } }
BOOL GetNtosInformation(WCHAR** pKernelFullPath,ULONG* ulKernelBase, ULONG* ulKernelSize) { ULONG ulBase = 0; ULONG ulSize = 0; ULONG ulBufferLength = 0; ULONG ulUnicodeKernelFullPath = 0; WCHAR wszNtosFullPath[260]; KeSetSystemAffinityThread(1); //使当前线程运行在第一个处理器上 __asm { push eax push ebx mov eax, fs:[0x34] //+0x34得到KdVersionBlock的地址 add eax,0x18 //得到指向PsLoadedModuleList的地址 mov eax,[eax] //得到PsLoadedModuleList的地址 mov ebx,[eax] //取出PsLoadedModuleList里面的内容, 即KLDR_DATA_TABLE_ENTRY结构 mov eax,[ebx+0x18] //取出DllBase, 即ntoskrnl.exe的基地址 mov ulBase, eax mov eax,[ebx+0x20] //+20h SizeOfImage mov ulSize,eax mov eax,ebx add eax,0x24 //+24h 是ntos在3环下的UNICODE_STRING全路径 mov ulUnicodeKernelFullPath,eax pop ebx pop eax } KeRevertToUserAffinityThread();//恢复线程运行的处理器 //PsLoadedModuleList的第一个就是ntos //nt!_LDR_DATA_TABLE_ENTRY //+0x000 InLoadOrderLinks : _LIST_ENTRY [ 0x82195338 - 0x8055e720 ] //+0x008 InMemoryOrderLinks : _LIST_ENTRY [ 0x0 - 0x0 ] //+0x010 InInitializationOrderLinks : _LIST_ENTRY [ 0x0 - 0x0 ] //+0x018 DllBase : 0x804d8000 Void //+0x01c EntryPoint : 0x806a3c08 Void //+0x020 SizeOfImage : 0x20e000 //+0x024 FullDllName : _UNICODE_STRING "\WINDOWS\system32\ntkrnlpa.exe" //+0x02c BaseDllName : _UNICODE_STRING "ntoskrnl.exe" //+0x034 Flags : 0xc004000 //+0x038 LoadCount : 1 //+0x03a TlsIndex : 0 //+0x03c HashLinks : _LIST_ENTRY [ 0x0 - 0x1f107a ] //+0x03c SectionPointer : (null) //+0x040 CheckSum : 0x1f107a //+0x044 TimeDateStamp : 0 //+0x044 LoadedImports : (null) //+0x048 EntryPointActivationContext : (null) //+0x04c PatchInformation : 0x0074006e Void RtlZeroMemory(wszNtosFullPath,260*2); //UNICODE_STRING->Length 不包括NULL字符 if (!MmIsAddressValidEx((PUNICODE_STRING)ulUnicodeKernelFullPath)) { return FALSE; } ulBufferLength = (((PUNICODE_STRING)ulUnicodeKernelFullPath)->Length + 1) * 2; if (SafeCopyMemory((PVOID)((PUNICODE_STRING)ulUnicodeKernelFullPath)->Buffer, wszNtosFullPath, ulBufferLength) != STATUS_SUCCESS) { *ulKernelBase = 0; *ulKernelSize = 0; return FALSE; } //拷贝成功的话,就进行对比 *pKernelFullPath = (WCHAR*)ExAllocatePool(NonPagedPool,260*2); if (!*pKernelFullPath) { *ulKernelBase = 0; *ulKernelSize = 0; return FALSE; } wcscat(*pKernelFullPath,L"\\SystemRoot\\system32\\"); if (wcsstr((const wchar_t*)wszNtosFullPath,L"ntoskrnl.exe") != NULL) { wcscat(*pKernelFullPath,L"ntoskrnl.exe"); } else if (wcsstr((const wchar_t*)wszNtosFullPath,L"ntkrnlpa.exe") != NULL) { wcscat(*pKernelFullPath,L"ntkrnlpa.exe"); } else if (wcsstr((const wchar_t*)wszNtosFullPath,L"ntkrnlmp.exe") != NULL) { wcscat(*pKernelFullPath,L"ntkrnlmp.exe"); } else if (wcsstr((const wchar_t*)wszNtosFullPath,L"ntkrpamp.exe") != NULL) { wcscat(*pKernelFullPath,L"ntkrpamp.exe"); } //else if (wcsstr((const wchar_t*)wszNtosFullPath,L"ntkrnlup.exe") != NULL) //{ // wcscat(*pKernelFullPath,L"ntkrnlup.exe"); //} else//失败了 { *ulKernelBase = 0; *ulKernelSize = 0; ExFreePool(*pKernelFullPath); return FALSE; } *ulKernelBase = ulBase; *ulKernelSize = ulSize; return TRUE; }