-
-
[转帖]使用ZwSystemDebugControl的简易用户模式Rootkit检测器代码
-
发表于: 2007-3-7 20:23 5620
-
转自MJ0011的内核驱动研究所
NTSTATUS ReadKernelMemory(IN PVOID BaseAddress, OUT PVOID Buffer, IN ULONG Length) { NTSTATUS Status; SYSDBG_VIRTUAL DbgMemory; // // Setup the request // DbgMemory.Address = BaseAddress; DbgMemory.Buffer = Buffer; DbgMemory.Request = Length; // // Do the read // Status = NtSystemDebugControl(SysDbgReadVirtual, &DbgMemory, sizeof(DbgMemory), NULL, 0, NULL); return Status; } PCHAR FindDriverForAddress(IN PVOID Pointer) { NTSTATUS Status; PRTL_PROCESS_MODULES ModuleInfo; PRTL_PROCESS_MODULE_INFORMATION ModuleEntry; ULONG ReturnedLength; ULONG i; // // Figure out how much size we need // Status = NtQuerySystemInformation(SystemModuleInformation, NULL, 0, &ReturnedLength); if (Status != STATUS_INFO_LENGTH_MISMATCH) return NULL; // // Allocate a buffer large enough // ModuleInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, ReturnedLength); if (!ModuleInfo) return NULL; // // Now query the data again // Status = NtQuerySystemInformation(SystemModuleInformation, ModuleInfo, ReturnedLength, &ReturnedLength); if (!NT_SUCCESS(Status)) return NULL; // // Loop all the drivers // for (i = 0; i < ModuleInfo->NumberOfModules; i++) { // // Get the current entry and check if the pointer is within it // ModuleEntry = &ModuleInfo->Modules[i]; if ((Pointer > ModuleEntry->ImageBase) && (Pointer < ((PVOID)((ULONG_PTR)ModuleEntry->ImageBase + ModuleEntry->ImageSize)))) { // // Found a match, return it // return ModuleEntry->FullPathName; } } } PCHAR DetectDriver(VOID) { BOOLEAN Old; NTSTATUS Status; ULONG_PTR MappedAddress; PVOID KernelBase, TableBase; UNICODE_STRING KernelName; ANSI_STRING TableName = RTL_CONSTANT_STRING("KeServiceDescriptorTable"); RTL_PROCESS_MODULES ModuleInfo; ULONG Flags; KSERVICE_TABLE_DESCRIPTOR ServiceTable; // // Give our thread the debug privilege // Status = RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, TRUE, FALSE, &Old); if (!NT_SUCCESS(Status)) return NULL; // // Query the kernel's module entry // Status = NtQuerySystemInformation(SystemModuleInformation, &ModuleInfo, sizeof(ModuleInfo), NULL); if (Status != STATUS_INFO_LENGTH_MISMATCH) return NULL; // // Initialize the kernel's full path name // Status = RtlCreateUnicodeStringFromAsciiz(&KernelName, ModuleInfo.Modules[0].FullPathName); if (!Status) return NULL; // // Keep only the short name // KernelName.Buffer = KernelName.Buffer + (KernelName.Length / sizeof(WCHAR)) - 12; // // Map the kernel // Flags = IMAGE_FILE_EXECUTABLE_IMAGE; Status = LdrLoadDll(NULL, &Flags, &KernelName, &KernelBase); if (!NT_SUCCESS(Status)) return NULL; // // Find the address of KeServiceDescriptorTable // Status = LdrGetProcedureAddress(KernelBase, &TableName, 0, &TableBase); if (!NT_SUCCESS(Status)) return NULL; // // Unload the kernel image, we're done with it // Status = LdrUnloadDll(KernelBase); if (!NT_SUCCESS(Status)) return NULL; // // Get the virtual address we need // MappedAddress = (ULONG_PTR)ModuleInfo.Modules[0].ImageBase; MappedAddress -= (ULONG_PTR)KernelBase; MappedAddress += (ULONG_PTR)TableBase; // // Now read the SSDT // Status = ReadKernelMemory((PVOID)MappedAddress, &ServiceTable, sizeof(ServiceTable)); if (!NT_SUCCESS(Status)) return NULL; // // Setup the argument table // ArgumentTable = RtlAllocateHeap(RtlGetProcessHeap(), 0, ServiceTable.Limit * sizeof(ULONG_PTR)); if (!ArgumentTable) return NULL; // // Now fill it up // Status = ReadKernelMemory(ServiceTable.Base, ArgumentTable, ServiceTable.Limit * sizeof(ULONG_PTR)); if (!NT_SUCCESS(Status)) return NULL; // // Now scan it // for (i = 0; i < ServiceTable.Limit; i++) { // // Make sure no pointer is outside the kernel area // if (ArgumentTable[i] > 0x8FFFFFFF) { // // Find the driver file that this belongs to // return FindDriverForAddress(UlongToPtr(ArgumentTable[i])); } } // // If we got here, then you don't have any rootkit // return NULL; }
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
赞赏
他的文章
看原图
赞赏
雪币:
留言: