这上面是SSDT--SSSDT一致 需要注意的是相对文件偏移和相对内存偏移
我这里使用符号获取SSSDT名
关于符号解析请看我上一篇文章
代码实现 查看SSSDT原始函数地址
一次显示100个 一共有837个
#include <windows.h> #include <stdio.h> #include <Dbghelp.h> #include <psapi.h> #pragma comment(lib, "Dbghelp.lib") #pragma comment(lib, "Imagehlp.lib") //去除警告 PLOADED_IMAGE IMAGEAPI ImageLoad( PCSTR DllName, PCSTR DllPath ); BOOL IMAGEAPI ImageUnload( PLOADED_IMAGE LoadedImage ); BOOL MapAndLoad( PSTR ImageName, PSTR DllPath, PLOADED_IMAGE LoadedImage, BOOL DotDll, BOOL ReadOnly ); BOOL UnMapAndLoad( PLOADED_IMAGE LoadedImage ); //SSSDT函数地址 ULONGLONG sssdt[827] = {0}; ULONGLONG g_w32pServiceTable = 0; ULONGLONG K = 0; ULONG64 ulBaseDll = 0; PLOADED_IMAGE ploadImage = {0}; int i = 0; typedef struct _SHADOWFUNC { CHAR FuncName[100]; ULONG64 FuncAddr; }SHADOWFUNC, *PSHADOWFUNC; SHADOWFUNC g_ShadowFunc[827] = {0}; BOOL IsExist(ULONGLONG pSystemAdd) { int i = 0; BOOL exist = FALSE; for(i = 0;i < 827; i++) { if(sssdt[i] == pSystemAdd) { exist = TRUE; } } return exist; } BOOL CALLBACK SymEnumSymbolsProc( PSYMBOL_INFO pSymInfo, ULONG SymbolSize, PVOID64 UserContext ) { if(IsExist((ULONGLONG)pSymInfo->Address)) { printf("0x%llx\t%s\n",(ULONGLONG)pSymInfo->Address,pSymInfo->Name); } return TRUE; } BOOL CALLBACK SymEnumSymbolsProcForTable( PSYMBOL_INFO pSymInfo, ULONG SymbolSize, PVOID64 UserContext ) { if(strcmp("W32pServiceTable",pSymInfo->Name)==0) { *(PULONG64)UserContext = pSymInfo->Address; printf("W32pServiceTable:%llx\n",pSymInfo->Address); } return TRUE; } BOOL CALLBACK SymEnumSymbolsProcTest( PSYMBOL_INFO pSymInfo, ULONG SymbolSize, PVOID64 UserContext ) { PULONGLONG temp = 0; if(UserContext == 0)//获取w32p { if(strcmp("W32pServiceTable",pSymInfo->Name)==0) { //printf("W32pServiceTable:%llx\n\n",pSymInfo->Address); g_w32pServiceTable = pSymInfo->Address; } }else { temp = (PULONGLONG)UserContext; for (i = 0; i < 827; i++) { if ((ULONG64)*(temp + i) == (ULONG64)pSymInfo->Address) { g_ShadowFunc[i].FuncAddr = (ULONG64)pSymInfo->Address; lstrcpynA(g_ShadowFunc[i].FuncName, pSymInfo->Name, 100); //printf("i:%d---Address:%llx,Name:%s\n",i,(ULONG64)pSymInfo->Address,&pSymInfo->Name); } } } return TRUE; } //这个用来测试用的 void OrigFunction() { HANDLE hHandle = 0; hHandle = GetCurrentProcess(); printf("Are enumerated symbolic...\n\n"); SymInitialize(hHandle, NULL, TRUE); ploadImage = ImageLoad("win32k.sys", NULL); sssdt[0] = 0xFFFFF97FFF0DC4EC; sssdt[1] = 0xFFFFF97FFF0D5070; sssdt[2] = 0xFFFFF97FFF077FA0; sssdt[3] = 0xFFFFF97FFF085510; ulBaseDll = SymLoadModule64(hHandle,\ ploadImage->hFile,\ "win32k.sys",\ "win32k.pdb",\ 0,\ ploadImage->SizeOfImage); printf("SSSDTFunctionAddr\tSSSDTFunctionName\n"); printf("------------------\t------------------\n"); SymEnumSymbols(hHandle,\ ulBaseDll,\ NULL,\ SymEnumSymbolsProc,\ NULL); printf("\nEnumerations end of symbols...\n"); ImageUnload(ploadImage); SymCleanup(hHandle); getchar(); } void GetOrigSSSDTAddr() { HANDLE hHandle = 0; PVOID pDrvAddr[128*8]; DWORD dwcbNeeded=0,n=0; DWORD64 dwBaseAddr = 0; CHAR *chName=(CHAR*)malloc(260); SetConsoleTitleA("GetSSSDTOriginalFunctionAddrForWin7x64R3"); if (EnumDeviceDrivers(pDrvAddr,sizeof(pDrvAddr),&dwcbNeeded)) { for (n=0 ; n<(dwcbNeeded/8) ; n++) { GetDeviceDriverBaseNameA(pDrvAddr[n],(LPSTR)chName,MAX_PATH); if(strcmp("win32k.sys",chName)==0) { dwBaseAddr = (DWORD64)pDrvAddr[n]; //printf("%s 0x%llx\n\n",chName,(DWORD64)dwBaseAddr); free(chName); break; } } } hHandle = GetCurrentProcess(); printf("Are enumerated symbolic...\n\n"); SymInitialize(hHandle, NULL, TRUE); ploadImage = ImageLoad("win32k.sys", NULL); ulBaseDll = SymLoadModule64(hHandle,\ ploadImage->hFile,\ "win32k.sys",\ "win32k.pdb",\ 0,\ ploadImage->SizeOfImage); SymEnumSymbols(hHandle,\ ulBaseDll,\ NULL,\ SymEnumSymbolsProcTest,\ NULL); if(g_w32pServiceTable!=0) { printf("Index\tSSSDTFunctionAddr\t\tSSSDTFunctionName\n"); printf("----\t------------------\t\t------------------\n"); //printf("g_w32pServiceTable:%llx ------ulBaseDll:%llx-------MappedAddr:%llx\n",g_w32pServiceTable,ulBaseDll,ploadImage->MappedAddress); //getchar(); g_w32pServiceTable = g_w32pServiceTable - (ULONG64)ulBaseDll + (ULONG64)ploadImage->MappedAddress; g_w32pServiceTable = g_w32pServiceTable - (ULONG64)0xc00;//ida中是以相对内存偏移对齐(1000)--内存映射是以相对稳健偏移对齐(400) 1000-400=0xc00 SymEnumSymbols(hHandle,ulBaseDll,NULL,SymEnumSymbolsProcTest,(PVOID64)g_w32pServiceTable); } for (i = 0; i < 827; i++) { //printf("%d\t0x%llx\t\t%s\n", i, g_ShadowFunc[i].FuncAddr, g_ShadowFunc[i].FuncName); printf("%d\t0x%llx\t\t%s\n",i,g_ShadowFunc[i].FuncAddr - ulBaseDll + (ULONG64)dwBaseAddr,g_ShadowFunc[i].FuncName); K++; if(K==100) { K = 0; printf("\nInput [Enter] Continue running...\n\n"); getchar(); } } ImageUnload(ploadImage); SymCleanup(hHandle); printf("\nThe current system consists of %d functions\n\n",i); printf("Input [Enter] Exit...\n"); getchar(); } //运行会很慢, //需要的符号文件 //dbghelp.pdb //imagehlp.pdb //kernel32.pdb //kernelbase.pdb //msvcr110d.amd64.pdb //msvcrt.pdb //ntdll.pdb //win32k.pdb //首次运行成功后,在同目录下sym文件中可以找到相应的pdb文件,复制到同目录即可. //这个是传入地址给出名称 void GetImageW32pSeviceTable(PULONG64 pW32SeviceTableAddr) { HANDLE hHandle = 0; ULONG64 ulBaseDll = 0; PLOADED_IMAGE ploadImage = {0}; hHandle = GetCurrentProcess(); printf("Are enumerated symbolic...\n\n"); SymInitialize(hHandle, NULL, TRUE); ploadImage = ImageLoad("win32k.sys", NULL); ulBaseDll = SymLoadModule64(hHandle,\ ploadImage->hFile,\ "win32k.sys",\ "win32k.pdb",\ 0,\ ploadImage->SizeOfImage); SymEnumSymbols(hHandle,\ ulBaseDll,\ NULL,\ SymEnumSymbolsProcForTable,\ pW32SeviceTableAddr); printf("\nEnumerations end of symbols...\n"); ImageUnload(ploadImage); SymCleanup(hHandle); } void main() { GetOrigSSSDTAddr(); return; }
我在测试中并没有将
dbghelp.dll symsrv.dll 放到exe目录
如果不能正常输出,可以到windbg目录下复制过来
如果还不没有效果,检测了自己网络没有问题后
那么这个代码不是我写的
测试图: