阅读:5810回复:23
关于读文件恢复 SSDT 的问题
前段时间实现了 SSDT Shadow 的读文件恢复,在各个环境下测试了下都没有失败。
方法是: 表头地址与模块地址偏移 减去 RVA 加上 POINTTORAWDATA 等于表文件偏移。 这两天想试试用相同的方法,恢复 SSDT 试试,结果发现只在部分机器上生效。 在安装了卡巴的机器上,表头地址居然不在 ntoskrnl.exe 的范围内——;?? -------------下面是输出--------- DbgView_SSDT() g_pSST: 0x80562480 DbgView_SSDT() ServiceTable: 0x85583B58 **** 这地址不在模块内啊 DbgView_SSDT() TableSize: 0x00000129 (297) DbgView_SSDT() gs_pSSTShadow: 0x80562450 DbgView_SSDT() ServiceTable: 0xBF998300 DbgView_SSDT() TableSize: 0x29B (667) --------------------------- CTSSDTReserve::GetRealSSDT() pImageBase: 00400000 CTSSDTReserve::GetRealSSDT() pModuleBase: 804E0000 **** 模块起始地址 CTSSDT::GetRealSSDT() pModuleLen: 00213F80 **** 模块大小 CTSSDTReserve::GetRealSSDT() pSSTAddr: 85583B58 **** 表头(明显不在模块内) CTSSDTReserve::GetRealSSDT() get image file: ntoskrnl.exe offset failed! 希望大虾们指点指点,感谢! |
|
最新喜欢:![]()
|
沙发#
发布于:2007-07-05 09:21
KeServiceDecriptorTable.ServiceTable FFA5E8E0 ??????
这个地址明显不在模块内,那是获取错了? ![]() |
|
|
板凳#
发布于:2007-07-03 17:20
KeServiceDecriptorTable.ServiceTable FFA5E8E0 >>>???
90210代码不就是你发的那个吗? SDTrestore-0.2好像并不具通用性,部分机子成功、部分失败, 说来说去,好像就是你发帖时的问题吧。 |
|
地板#
发布于:2007-07-03 15:42
我也没有 90210 的代码,
TKeHook: DbgView_SSDT() ************************** 43.711 Default TKeHook: DbgView_SSDT() g_pCurSST: 0x80562680 43.711 Default TKeHook: DbgView_SSDT() ServiceTable: 0x804EB6A8 43.711 Default TKeHook: DbgView_SSDT() TableSize: 0x0000011C (284) 你那两个地址,貌似一个是 g_pCurSST 0x80562680(就是总表的那个),一个是 ServiceTable: 0x804EB6A8 就是子表的那个。。。。 |
|
|
地下室#
发布于:2007-07-03 12:21
90210的代码运行后:
========================= &KiServiceTable==804FD624 ========================= SDTrestore-0.2运行后: ========================= KeServiceDescriptorTable 80545C00 KeServiceDecriptorTable.ServiceTable FFA5E8E0 KeServiceDescriptorTable.ServiceLimit 297 Failed to map physical memory view of length 2000 at 7FA5E8E0! ========================= |
|
5楼#
发布于:2007-07-03 10:08
引用第17楼aliwy于2007-07-03 00:00发表的 : 有不同吗?不会吧? 我取到的地址貌似和 PJF 的 iceword 取到的一样... |
|
|
6楼#
发布于:2007-07-03 10:07
引用第16楼wingsoft于2007-06-03 10:33发表的 : 为什么要放里面呢? 我这样子运行貌似木有失败啊。。。 |
|
|
7楼#
发布于:2007-07-03 00:00
SDTrestore0.2不是按90210的方法做了更新吗?
为什么两个程序找到的KiServiceTable值却不同? |
|
8楼#
发布于:2007-06-03 10:33
还是有错的,
static HMODULE hNtoskrnl = LoadLibrary("Ntdll.dll"); static PNtQuerySystemInformation pfnNtQuerySystemInformation = (PNtQuerySystemInformation)GetProcAddress(hNtoskrnl, "NtQuerySystemInformation"); 应该放到main里面, |
|
|
9楼#
发布于:2007-04-16 15:11
![]() |
|
10楼#
发布于:2007-04-13 11:39
上面的代码只是稍微整理了下,现在我又改正了释放资源的分支和其他若干不合理的地方,再把它做成了一个函数
// // FUNCTION: // get original ssdt table // PARAMETER: // OUT pTable buffer point // IN uSize buffer size //RETURN VALUE: // ULONG table size (0 indicate failed) // ULONG GetOriginalSSDT(PULONG pTable, const ULONG uSize); 貌似工作的蛮好,接下来全面测试中 :) |
|
|
11楼#
发布于:2007-04-13 11:35
在导出表中查找地址?? 那得到的不是服务地址吧?
Nt××× 系列函数地址跟 SSDT 里面的服务地址不一样的不 这些函数调用中断转到服务函数里的 |
|
|
12楼#
发布于:2007-04-12 18:42
我是没有好的Findaddr实现方法才没贴,,用的在导出表中查找地址(理论上这种方法没啥问题吧??),不过我在网吧的电脑上不能得到正确的地址(家里不能上网)就没贴,
ring3+mdl加载给驱动解决了, |
|
13楼#
发布于:2007-04-11 17:45
哦,是的
![]() |
|
|
14楼#
发布于:2007-04-11 14:32
baigan 你是假设 NtReadFile 和 NtClose 没有被改变的情况搜索,是么?
___ NtReadFile 和 NtClose 从文件中得到的 , |
|
15楼#
发布于:2007-04-11 11:48
I've found a way how to locate original KiServiceTable in the ntoskrnl file even if KeServiceDescriptorTable.Base has been changed. Method works both in the user mode and in the kmode.
This may be useful to bypass SDT-patching hooks, and not only to restore old SDT. For example, KAV uses SDT relocation ;) KeServiceDescriptorTable is initialized by KiInitSystem(): KeServiceDescriptorTable[0].Base = &KiServiceTable[0]; KeServiceDescriptorTable[0].Count = NULL; KeServiceDescriptorTable[0].Limit = KiServiceLimit; KeServiceDescriptorTable[0].Number = &KiArgumentTable[0]; for (Index = 1; Index < NUMBER_SERVICE_TABLES; Index += 1) { KeServiceDescriptorTable[Index].Limit = 0; } Thus, we can find KiServiceTable by examining all xrefs to KeServiceDescriptorTable in the kernel. We will search for C7 05 ..8 bytes.. mov ds:_KeServiceDescriptorTable.Base, offset _KiServiceTable from which we will get _KiServiceTable rva. It's easy to find KeServiceDescriptorTable xrefs by scanning the code, but this is dangerous and time-consuming. It's better to use ntoskrnl's relocation information - it is always present in all nt systems. This "mov [mem32], imm32" instruction will have 2 relocs pointing in it, and the second is the one we're searching for. So, the usermode code will do these steps: 1. Load ntosknrl as a dll. 2. Locate KeServiceDescriptorTable - it is exported. 3. Enumerate all relocations to find xrefs to the KeServiceDescriptorTable. 4. Check these opcodes to be a "mov [mem32],imm32". 5. Get KiServiceTable - it's offset is +6 from the opcode beginning. The example code dumps KiServiceTable data from file and does no comparings with the existing sdt. So, it's a must to a SDT-patching rootkit to hook file system and show "patched" version of ntoskrnl to all readers. And of course, services hooks code must reside in the ntoskrnl region and have no codepaths outside it. Otherwise it may be tracked in seconds. /////////////////////////////////////////////////////////// // main.cpp // // 这是整理之后可以直接编译运行的代码(win32 console application) // /////////////////////////////////////////////////////////// #include <windows.h> #include <winnt.h> #include <stdio.h> #include <conio.h> #define RVATOVA(base,offset) ((PVOID)((DWORD)(base)+(DWORD)(offset))) #define ibaseDD *(PDWORD)&ibase #define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L) #define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0) typedef struct { WORD offset:12; WORD type:4; } IMAGE_FIXUP_ENTRY, *PIMAGE_FIXUP_ENTRY; typedef LONG NTSTATUS; typedef struct _SYSTEM_MODULE_INFORMATION {//Information Class 11 ULONG Reserved[2]; PVOID Base; ULONG Size; ULONG Flags; USHORT Index; USHORT Unknown; USHORT LoadCount; USHORT ModuleNameOffset; CHAR ImageName[256]; }SYSTEM_MODULE_INFORMATION,*PSYSTEM_MODULE_INFORMATION; typedef struct { DWORD dwNumberOfModules; SYSTEM_MODULE_INFORMATION smi; } MODULES, *PMODULES; //* // // NtQuerySystemInformation // #define SystemModuleInformation 11 #ifdef __cplusplus extern "C" { #endif typedef NTSTATUS (WINAPI *PNtQuerySystemInformation)( DWORD SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength ); #ifdef __cplusplus } #endif static HMODULE hNtoskrnl = LoadLibrary("Ntdll.dll"); static PNtQuerySystemInformation pfnNtQuerySystemInformation = (PNtQuerySystemInformation)GetProcAddress(hNtoskrnl, "NtQuerySystemInformation"); //*/ // // GetHeaders // DWORD GetHeaders( PBYTE ibase, PIMAGE_FILE_HEADER* pfh, PIMAGE_OPTIONAL_HEADER* poh, PIMAGE_SECTION_HEADER* psh ) { PIMAGE_DOS_HEADER mzhead = (PIMAGE_DOS_HEADER)ibase; if ((mzhead->e_magic!=IMAGE_DOS_SIGNATURE) || (ibaseDD[mzhead->e_lfanew]!=IMAGE_NT_SIGNATURE)) return FALSE; *pfh=(PIMAGE_FILE_HEADER)&ibase[mzhead->e_lfanew]; if (((PIMAGE_NT_HEADERS)*pfh)->Signature!=IMAGE_NT_SIGNATURE) return FALSE; *pfh=(PIMAGE_FILE_HEADER)((PBYTE)*pfh+sizeof(IMAGE_NT_SIGNATURE)); *poh=(PIMAGE_OPTIONAL_HEADER)((PBYTE)*pfh+sizeof(IMAGE_FILE_HEADER)); if ((*poh)->Magic!=IMAGE_NT_OPTIONAL_HDR32_MAGIC) return FALSE; *psh=(PIMAGE_SECTION_HEADER)((PBYTE)*poh+sizeof(IMAGE_OPTIONAL_HEADER)); return TRUE; } // // FindKiServiceTable // DWORD FindKiServiceTable(HMODULE hModule,DWORD dwKSDT) { PIMAGE_FILE_HEADER pfh; PIMAGE_OPTIONAL_HEADER poh; PIMAGE_SECTION_HEADER psh; PIMAGE_BASE_RELOCATION pbr; PIMAGE_FIXUP_ENTRY pfe; DWORD dwFixups=0,i,dwPointerRva,dwPointsToRva,dwKiServiceTable; BOOL bFirstChunk; GetHeaders((PBYTE)hModule,&pfh,&poh,&psh); // loop thru relocs to speed up the search if ((poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress) && (!((pfh->Characteristics)&IMAGE_FILE_RELOCS_STRIPPED))) { pbr=(PIMAGE_BASE_RELOCATION)RVATOVA(poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress,hModule); bFirstChunk=TRUE; // 1st IMAGE_BASE_RELOCATION.VirtualAddress of ntoskrnl is 0 while (bFirstChunk || pbr->VirtualAddress) { bFirstChunk=FALSE; pfe=(PIMAGE_FIXUP_ENTRY)((DWORD)pbr + sizeof(IMAGE_BASE_RELOCATION)); for (i = 0; i < (pbr->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION))>>1; i++,pfe++) { if (pfe->type==IMAGE_REL_BASED_HIGHLOW) { dwFixups++; dwPointerRva=pbr->VirtualAddress+pfe->offset; // DONT_RESOLVE_DLL_REFERENCES flag means relocs aren't fixed dwPointsToRva=*(PDWORD)((DWORD)hModule+dwPointerRva)-(DWORD)poh->ImageBase; // does this reloc point to KeServiceDescriptorTable.Base? if (dwPointsToRva==dwKSDT) { // check for mov [mem32],imm32. we are trying to find // "mov ds:_KeServiceDescriptorTable.Base, offset _KiServiceTable" // from the KiInitSystem. if (*(PWORD)((DWORD)hModule + dwPointerRva - 2)==0x05c7) { // should check for a reloc presence on KiServiceTable here // but forget it dwKiServiceTable=*(PDWORD)((DWORD)hModule+dwPointerRva+4)-poh->ImageBase; return dwKiServiceTable; } } } else if (pfe->type!=IMAGE_REL_BASED_ABSOLUTE) // should never get here printf("\trelo type %d found at .%X\n",pfe->type,pbr->VirtualAddress+pfe->offset); } *(PDWORD)&pbr+=pbr->SizeOfBlock; } } if (!dwFixups) // should never happen - nt, 2k, xp kernels have relocation data printf("No fixups!\n"); return 0; } int main(int argc,char *argv[]) { HMODULE hKernel; DWORD dwKSDT; // rva of KeServiceDescriptorTable DWORD dwKiServiceTable; // rva of KiServiceTable PMODULES pModules = NULL; DWORD dwNeededSize; DWORD rc; DWORD dwKernelBase; DWORD dwServices = 0; PCHAR pKernelName; PDWORD pService; PIMAGE_FILE_HEADER pfh; PIMAGE_OPTIONAL_HEADER poh; PIMAGE_SECTION_HEADER psh; // get system modules - ntoskrnl is always first there rc = pfnNtQuerySystemInformation( SystemModuleInformation, // 11 NULL, 0, &dwNeededSize ); if (rc == STATUS_INFO_LENGTH_MISMATCH) { pModules = (PMODULES)GlobalAlloc (GPTR, dwNeededSize); rc = pfnNtQuerySystemInformation( SystemModuleInformation, pModules, dwNeededSize, NULL ); } else { strange: printf("strange NtQuerySystemInformation()!\n"); return 0; } if (!NT_SUCCESS(rc)) goto strange; // imagebase dwKernelBase=(DWORD)pModules->smi.Base; // filename - it may be renamed in the boot.ini pKernelName=pModules->smi.ModuleNameOffset+pModules->smi.ImageName; // map ntoskrnl - hopefully it has relocs hKernel=LoadLibraryEx(pKernelName,0,DONT_RESOLVE_DLL_REFERENCES); if (!hKernel) { printf("Failed to load! LastError=%i\n",GetLastError()); return 0; } GlobalFree(pModules); // our own export walker is useless here - we have GetProcAddress :) if (!(dwKSDT=(DWORD)GetProcAddress(hKernel,"KeServiceDescriptorTable"))) { printf("Can't find KeServiceDescriptorTable\n"); return 0; } // get KeServiceDescriptorTable rva dwKSDT-=(DWORD)hKernel; // find KiServiceTable if (!(dwKiServiceTable=FindKiServiceTable(hKernel,dwKSDT))) { printf("Can't find KiServiceTable...\n"); return 0; } printf("&KiServiceTable==%08X\n\nDumping 'old' ServiceTable:\n\n", dwKiServiceTable+dwKernelBase); // let's dump KiServiceTable contents // MAY FAIL!!! // should get right ServiceLimit here, but this is trivial in the kernel mode GetHeaders((PBYTE)hKernel,&pfh,&poh,&psh); for (pService=(PDWORD)((DWORD)hKernel+dwKiServiceTable); *pService-poh->ImageBase<poh->SizeOfImage; pService++,dwServices++) printf("%08X\n",*pService-poh->ImageBase+dwKernelBase); printf("\n\nPossibly KiServiceLimit==%08X\n",dwServices); FreeLibrary(hKernel); getch(); return 0; } wbr, 90210 |
|
|
16楼#
发布于:2007-04-11 10:03
90210 - A more stable way to locate real KiServiceTable
http://www.rootkit.com/newsread.php?newsid=176 |
|
|
17楼#
发布于:2007-04-11 09:59
在SDTrestore工具发布后,90210在rootkit.com提出了一种定位KiServiceTable更有效的办法。该技术主要基于KeServiceDescriptorTable是在KiInitSystem函数中通过下面的指令初始化:
mov ds:KeServiceDescriptorTable, offset KiServiceTable 可以通过搜索ntoskrnl.exe的重定位表找到这条指令。使用重定位表的搜索如上的指令比在整个ntoskrnl.exe的程序区中搜索,更加有效和可靠。一旦找到这条指令,KiServiceTable的偏移地址就找到了 |
|
|
18楼#
发布于:2007-04-11 09:41
baigan 你是假设 NtReadFile 和 NtClose 没有被改变的情况搜索,是么?
貌似代码还有些小错误 ^^ 不管怎么说,谢谢回复! 如果实在没办法也只好暴力了~~ ![]() |
|
|
19楼#
发布于:2007-04-10 18:02
|
|
上一页
下一页