我们知道ShadowSSDT的实现存在于win32k.sys中,所以我们只要分析win32k.sys文件就能获取原始的ShadowSSDT地址。
A primary default array table, KeServiceDescriptorTable, defines the core executive system services implemented in Ntosrknl.exe. The other table array, KeServiceDescriptorTableShadow, includes the Windows USER and GDI services implemented in the kernel-mode part of the Windows subsystem, Win32k.sys. The first time a Windows thread calls a Windows USER or GDI service, the address of the thread’s system service table is changed to point to a table that includes the Windows USER and GDI services. The KeAddSystemServiceTable function allows Win32k.sys to add a system service table.
上面是摘自深入解析Windows 操作系统里面的一段话,说的是win32k.sys会调用KeAddSystemServiceTable 这个方法来初始化ShadowSSDT。
那么我们用IDA来打开win32k.sys这个文件,找到KeAddSystemServiceTable 这个函数。
我们可以看到,确实使用KeAddSystemServiceTable来初始化ShadowSSDT的。而且第一个参数就是W32pServiceTable也就是我们所要找的ShadowSSDT原始函数数组。
是不是我们跟进去看一下就知道了。。。
确实是。。。
所以我们就可以根据KeAddSystemServiceTable这个函数来找到W32pServiceTable的地址,然后根据这个地址,分别取得函数的地址。那么KeAddSystemServiceTable要怎么获取,其实我们可以在导入表中找到这个函数,所以只要解析PE文件,从导入表中找到这个函数的地址即可。
从导入表获取KeAddSystemServiceTable的地址:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | ULONG GetKeAddSTAddress(HANDLE hWin32k) { PIMAGE_DOS_HEADER pImageDosHeader = (PIMAGE_DOS_HEADER)hWin32k; PIMAGE_NT_HEADERS pImageNtHeader = (PIMAGE_NT_HEADERS)((ULONG)hWin32k + (ULONG)pImageDosHeader->e_lfanew); PIMAGE_IMPORT_DESCRIPTOR pImageImportDir = (PIMAGE_IMPORT_DESCRIPTOR)((ULONG)hWin32k + pImageNtHeader->OptionalHeader.DataDirectory[1].VirtualAddress); PIMAGE_IMPORT_DESCRIPTOR pImageImportDesc; PULONG pOriginalThunkData; PULONG pFirstThunkData; PIMAGE_IMPORT_BY_NAME pImageImportByName; ULONG uRetAddress; CHAR buf[8]; BOOL bStop = FALSE; if(pImageNtHeader->OptionalHeader.DataDirectory[1].VirtualAddress == 0 && pImageNtHeader->OptionalHeader.DataDirectory[1].Size == 0) { return -1; } __try { for (pImageImportDesc = pImageImportDir; pImageImportDesc->Name; pImageImportDesc++) { for (pOriginalThunkData = (PULONG)((DWORD)hWin32k + pImageImportDesc->OriginalFirstThunk), pFirstThunkData = (PULONG)((DWORD)hWin32k + pImageImportDesc->FirstThunk);*pOriginalThunkData && *pFirstThunkData; pOriginalThunkData++,pFirstThunkData++) { if((*pOriginalThunkData) & IMAGE_ORDINAL_FLAG) { sprintf_s(buf, "#%d", (*pOriginalThunkData) & 0x7fffffff); if(_stricmp(buf, "KeAddSystemServiceTable") == 0) { uRetAddress = (ULONG)pFirstThunkData; bStop = TRUE; break; } } else { pImageImportByName = (PIMAGE_IMPORT_BY_NAME)((DWORD)hWin32k + ((PIMAGE_THUNK_DATA)pOriginalThunkData)->u1.AddressOfData); if(_stricmp((PCHAR)pImageImportByName->Name, "KeAddSystemServiceTable") == 0) { uRetAddress = (ULONG)pFirstThunkData; bStop = TRUE; break; } } } if(bStop)break; } } __except(1) { return -1; } } |
根据KeAddSystemServiceTable和特征码来得到W32pServiceTable的地址:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | hWin32k = ::LoadLibraryEx(L"win32k.sys", 0, DONT_RESOLVE_DLL_REFERENCES); PIMAGE_DOS_HEADER pImageDosHeader = (PIMAGE_DOS_HEADER)hWin32k; PIMAGE_NT_HEADERS pImageNtHeader = (PIMAGE_NT_HEADERS)((ULONG)hWin32k + (ULONG)pImageDosHeader->e_lfanew); uImageBase = pImageNtHeader->OptionalHeader.ImageBase; uImageEntryPoint= pImageNtHeader->OptionalHeader.AddressOfEntryPoint; uWin32kBase = GetModuleBaseR3(szWin32kName); uKeAddSystemServiceTableVA = GetKeAddSTAddress(hWin32k); uKeAddSystemServiceTableRVA = uKeAddSystemServiceTableVA - (ULONG)hWin32k; uMagicAddr = uKeAddSystemServiceTableRVA + uImageBase; uImageEntry = (ULONG)((DWORD)hWin32k + uImageEntryPoint); for (i = 0; i < 0x10000; i++) { pShadowSsdtMagic = (PSHADOW_SSDT_MAGIC)(uImageEntry + i); if(pShadowSsdtMagic->uMagic == 0x15ff) { if(pShadowSsdtMagic->uMagicNum == uMagicAddr) { pWin32ServiceTable = (PULONG)(*(PULONG)(uImageEntry + i - 4)); break; } } } pWin32ServiceTable = (PULONG )((ULONG)pWin32ServiceTable - uImageBase + (DWORD)hWin32k); |
下面是我在win7 32位下面获取shadowssdt当前地址和原始地址的效果图:
本文链接:http://www.alonemonkey.com/get-original-shadowssdt.html