找到原始的SSDT表的内容

DWORD GetOrgWindowsServiceTable() 1.Mb45.{  
{ qrMhg2'k  
     CLocalFileIO LocalFileIO; zN'MZVj  
     gpFileIO = &LocalFileIO; hYxh2Lp  
     CPEFile PEFile; &"#lrfhN/  
     DWORD NtKernelBaseAddress=0; 0xsvx?9  
     CPEFile PEFile2; tv:/+O9G  
     HANDLE hFile,hFile2; C$CT;g&uS  
     DWORD n,m,k,MaxServiceNum=0; oq,e`aH5  
     bool bOK; >? ?cj!3  
     DWORD Func1Addr,NtdllAddr1,ServiceNum1; q9I]2o@kW  
     DWORD Func2Addr,NtDllAddr2,ServiceNum2,ReadBufferLen; }N)v|  
     char Fun1[30]; [L9I4  
     char Fun2[30]; d3&Et`  
     BYTE CodeBuffer[0x0f]; QVc qb i  
     ULSIZE ReadLen,Pos; u0h6=/BR47  
     char* FunctionName; oV !b  
     char *ReadBuffer; p }e !bRQ  
     PEFile.m_OpenMode = PE_OPEN_NO_IMPORT|PE_OPEN_SYS; $+|&U  
     if(gpPsLoadedModuleListHeader==NULL) OA zr)=8D8  
           return 0; 8|s-Pl  
     NtKernelBaseAddress = GetKernelName(&gszKernelName[TStrLen(gszKernelName)],NULL); d_LSLD  
     if(NtKernelBaseAddress==0) njRA7:  
           return 0; |B {+{  
     bOK = PEFile.Open(gszKernelName,&hFile); FK<H60,[  
     if(bOK==false) "u@ /(=*%  
     { % M6KL[d  
           return 0; Bl}y[,  
     } APCi~hsg  
     Fun1[0]=0; (y>, Xt  
     Fun2[0]=0; e9bP "#C  
     for(n=0;n<(DWORD)PEFile.m_ExportFuncCount;n++) a3,~a7 U!  
     { @:B7m:oH  
           FunctionName = PEFile.m_ExportFunc[n].FuncName; #qNiSjP?  
           if(FunctionName[0]!='N'||FunctionName[1]!='t')continue; ra<R(j  
           if(TStrLen(FunctionName)>=30)continue; %,P7V8}o  
           if(Fun1[0]==0) eC]t'a$@  
           { $57nkL re  
                 TStrCpy(Fun1,FunctionName); &gQj+f/  
                 Func1Addr=PEFile.m_ExportFunc[n].Address; =vR<r-u_h  
                 continue; W A/"'Z?  
           } ER}/6[][  
           if(Fun2[0]==0) 4Ee+c-d8C  
           { ?C[T9X  
                 TStrCpy(Fun2,FunctionName); w<]`qmgI  
                 Func2Addr=PEFile.m_ExportFunc[n].Address; /wp| eSUt  
                 break; 6f6lPdO  
           } Gz/]g j#  
     } tfm9 _$9D  
      -mYl~eV(G  
      *F##gCjz|  
     PEFile2.m_OpenMode=PE_OPEN_NO_IMPORT|PE_OPEN_DLL; k4_-Io|r  
     bOK = PEFile2.Open(gszNtdllName,&hFile2); ?>Xl.Uv$C  
     if(bOK==false) dC"Irw  
     { Td/NWz  
           DbgPrint("Open ntdll.dll error/n"); &ari|} :  
           PEFile.Close(); ~2~Tlb;  
           return 0; kT;=Vw  
     } GrtS 3  
     NtdllAddr1 = PEFile2.GetExportFunc(Fun1); /Y? R#  
     NtDllAddr2 = PEFile2.GetExportFunc(Fun2); +FiT?q  
     memset(CodeBuffer,0,sizeof(CodeBuffer)); C/Byw:  
     ReadLen = PEFile2.ReadImageMemory(NtdllAddr1,CodeBuffer,sizeof(CodeBuffer)); molwfPo/r  
     if(ReadLen!=sizeof(CodeBuffer)) 3 ]5|z  
     { SY"8iWE  
           PEFile.Close(); =pK2R LI  
     } n&br&q  
     ServiceNum1 = *(DWORD*)&CodeBuffer[1]; n%97jD3W  
     memset(CodeBuffer,0,sizeof(CodeBuffer)); >yZ~t|o  
     ReadLen = PEFile2.ReadImageMemory(NtDllAddr2,CodeBuffer,sizeof(CodeBuffer)); #KWh5/  
     ServiceNum2 = *(DWORD*)&CodeBuffer[1]; ^hVwho  
8D@Q;-g  
     DbgPrint("%s = %08x %08x %08x/n",Fun1,NtdllAddr1,ServiceNum1,Func1Addr); &-?{X {  
     DbgPrint("%s = %08x %08x %08x/n",Fun2,NtDllAddr2,ServiceNum2,Func2Addr); cqy5JK t  
#~KrPZZf  
     for(n=0;n<(DWORD)PEFile2.m_ExportFuncCount;n++) Pbtr9KzT|`  
     { f07EWOsJ  
           FunctionName = PEFile2.m_ExportFunc[n].FuncName; V6b8y*=  
           if((FunctionName[0]=='N'&&FunctionName[1]=='t')||(FunctionName[0]=='Z'&&FunctionName[1]=='w')) dl>6  
           { )k&cT#qr}  
                 ReadLen = PEFile2.ReadImageMemory(PEFile2.m_ExportFunc[n].Address,CodeBuffer,sizeof(CodeBuffer)); BO[(S|  
                 if(ReadLen<sizeof(CodeBuffer))continue; 9 )k;R42,  
                 if(*(DWORD*)&CodeBuffer[1] > MaxServiceNum&&CodeBuffer[0]==0xb8) e+7A:F  
                 { ;)/^ZO j  
                       MaxServiceNum=*(DWORD*)&CodeBuffer[1]; sMCB7:  
                       DbgPrint("%s %d/n",FunctionName,MaxServiceNum); +*ID "k  
                 } [-g$?-V  
           } a}}{u+?N  
            #<ce'MHd  
     } $VEI&}k":z  
tDbj _&X*  
     PEFile2.Close(); 4[ws5A  
     if(ServiceNum1>ServiceNum2) J;'K^QGFZ  
     { |nhttk?  
           ServiceNum1+=ServiceNum2; ."TP Q7%/  
           ServiceNum2=ServiceNum1-ServiceNum2; 6 /5Vn  
           ServiceNum1-=ServiceNum2; -|U MC  
           Func1Addr+=Func2Addr; .k/hWn  
           Func2Addr=Func1Addr-Func2Addr; {Df#W7  
           Func1Addr-=Func2Addr; 5!?A>=g  
     } ^_^<]T.  
     ReadBuffer = new char[0x1007]; w9NL3U  
     memset(ReadBuffer,0,0x1007); 8L+24[,  
     ReadBufferLen = 0x1000; [;E=j8 !  
     ULONG KeServiceDescriptorTableFilePos=0; (f@w]ztTM  
     bool bFindOk=false; tnn`{ZnG  
     for(n = 0; n < PEFile.m_FileSize;n+=ReadBufferLen) Lm*v2w*$p  
     { Wv-Hq4  
           if(PEFile.m_FileSize-n<0x1000) rc86=5fg  
                 ReadBufferLen=PEFile.m_FileSize-n; N_RF(O  
           PEFile.ReadFile(n,&ReadBuffer[0x3],ReadBufferLen); X6q6p59N|  
           for(k=0;k<ReadBufferLen+3;k++) . Gq#1,T  
           { )ata=C{  
                 if(*(DWORD*)&ReadBuffer[k]==Func1Addr) bd/U?<ZH+  
                 { vi )*_  
                       m = k+(ServiceNum2-ServiceNum1)*sizeof(ULONG); 1 $t/+N  
                       if(m < ReadBufferLen) %~E;DSG.  
                       { iGyC  
                             if(*(DWORD*)&ReadBuffer[m]==Func2Addr) 8/Jy&  
                             { & phT,f  
                                   KeServiceDescriptorTableFilePos = n+k-3-ServiceNum1*sizeof(ULONG); @e'4]{$  
                                   bFindOk=true; ,-g5}N@  
                                   break; 7V|g}q0 /  
                             } %,W0:zC`J/  
                       } r*q}[MT  
                       else ," V&~n>  
                       { 3l'v n;  
                             m=m+n-3; fle+m:Z?>  
                             ULONG FuncAddr=0; .,e 3>Q  
                             PEFile.ReadFile(m,&FuncAddr,sizeof(ULONG)); O1: C^  
                             if(FuncAddr==Func2Addr) 2NLHs* X  
                             { }XN@4MS;P  
                                   KeServiceDescriptorTableFilePos=m; Y9fE V/.  
                                   bFindOk=true; Yv? Mz  
                                   break; }wYnMu  
                             } XKR8~nj:v  
                       } ra{/_(ba/  
                 } f9$!pGp  
           } +jZ s|O`  
           if(bFindOk)break; Z&I8<. U  
           *(DWORD*)&ReadBuffer[0] = *(DWORD*)&ReadBuffer[0xffd]; 6m0Kxp_EE  
     } SD!I Nm  
     if(bFindOk) }'^$tj  
     { &++*Z/:%B  
           DbgPrint("KeServiceDescriptorTableFilePos = %08x %d %08x %d/n",KeServiceDescriptorTableFilePos,KeServiceDescriptorTableFilePos,MaxServiceNum,MaxServiceNum); v7dm]<)/  
           if(MaxServiceNum>=0x1000) $_/Pu/T5  
                 MaxServiceNum=0x1000; *ct(JsN y  
           gOrgWindowsKeServiceDescriptorTable=new DWORD[MaxServiceNum]; 9jQnRz  
           if(gOrgWindowsKeServiceDescriptorTable) (|.4*w2*8  
           { lf5K4TGSj  
                 memset(gOrgWindowsKeServiceDescriptorTable,0,sizeof(DWORD)*MaxServiceNum); ~ 'pcx<t]  
                 ReadBufferLen=sizeof(DWORD)*MaxServiceNum; &JFvLQ8  
                 if(ReadBufferLen+KeServiceDescriptorTableFilePos>PEFile.m_FileSize) 2e0@-/5J`y  
                       ReadBufferLen=PEFile.m_FileSize-KeServiceDescriptorTableFilePos; Q0J[GE9:{  
                 PEFile.ReadFile(KeServiceDescriptorTableFilePos,gOrgWindowsKeServiceDescriptorTable,ReadBufferLen); QdvjI"P6  
                 gMaxServiceNum=ReadBufferLen/sizeof(DWORD); =|{ ;Ob  
                 for(n = 0; n < gMaxServiceNum;n++) Hmg@VgTR  
                 { 8o*(e`mm  
                       gOrgWindowsKeServiceDescriptorTable[n]+=(NtKernelBaseAddress - PEFile.m_ImageBase); d2w=MP  
                 } e9VA,r  
           } ,vK8-ba  
     } [ Zq~c6nl  
     delete []ReadBuffer; 9Y8+uw"2  
     PEFile.Close(); f/( ;QGI  
     return KeServiceDescriptorTableFilePos; J+7> ei  
}

 
本实例由VS2008开发,在提供了一套驱动开发框架的同时,又演示了如何获取Shadow SSDT函数原始地址的办法。 主要函数:ULONG GetShadowSSDT_Function_OriAddr(ULONG index); 原理说明: 根据特征码搜索导出函数KeAddSystemServiceTable来获取Shadow SSDT基址,以及通过ZwQuerySystemInformation()函数获取win32k.sys基址,然后解析PE定位到Shadow SSDT在win32k.sys的偏移地址,并通过进一步计算来得到Shadow SSDT函数的原始地址。 这里只测试了三个函数:(460)NtUserMessageCall、(475)NtUserPostMessage和(502)NtUserSendInput,具体使用时可以举一反三,网上完整的源代码实例并不太多,希望可以帮到真正有需要的朋友。 系统环境: 在WinXP SP3系统 + 瑞星杀毒软件 打印输出: [ LemonInfo : Loading Shadow SSDT Original Address Driver... ] [ LemonInfo : 创建“设备”值为:0 ] [ LemonInfo : 创建“设备”成功... ] [ LemonInfo : 创建“符号链接”状态值为:0 ] [ LemonInfo : 创建“符号链接”成功... ] [ LemonInfo : 驱动加载成功... ] [ LemonInfo : 派遣函数(DispatchRoutine) IRP 开始... ] [ LemonInfo : 派遣函数(DispatchRoutine) IRP Enter IRP_MJ_DEVICE_CONTROL... ] [ LemonInfo : 获取ShadowSSDT (460)NtUserMessageCall 函数的“当前地址”为:0xB83ECFC4,“起源地址”为:0xBF80EE6B ] [ LemonInfo : 获取ShadowSSDT (475)NtUserPostMessage 函数的“当前地址”为:0xB83ECFA3,“起源地址”为:0xBF8089B4 ] [ LemonInfo : 获取ShadowSSDT (502)NtUserSendInput 函数的“当前地址”为:0xBF8C31E7,“起源地址”为:0xBF8C31E7 ] [ LemonInfo : 派遣函数(DispatchRoutine) IRP_MJ_DEVICE_CONTROL 成功执行... ] [ LemonInfo : 派遣函数(DispatchRoutine) IRP 结束... ] [ LemonInfo : UnLoading Shadow SSDT Original Address Driver... ] [ LemonInfo : 删除“符号链接”成功... ] [ LemonInfo : 删除“设备”成功... ] [ LemonInfo : 驱动卸载成功... ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值