百度上比较好的解释是:SSDT的全称是System Services Descriptor Table,系统服务描述符表。这个表就是一个把ring3的Win32 API和ring0的内核API联系起来。SSDT并不仅仅只包含一个庞大的地址索引表,它还包含着一些其它有用的信息,诸如地址索引的基地址、服务函数个数等。

说白了,SSDT就是把系统两个不同级别的函数给关联起来,因为为了安全需要,我们平常所使用的API函数基本都是在ring3下的函数,ring3的级别比较低,但是有些涉及到系统底层的函数怎么办呢?Windows就给出一个SSDT表,把ring3和ring0的函数给关联起来,这样,我们就通过使用ring3的函数就可以直接做一些底层操作了。

好吧,既然有这个东西,谁最关心呢?当然是杀毒软件最关心了,因为为了阻止某些病毒不让他破坏系统的底层,杀毒软件会把SSDT中的地址给修改并转向,这样,当病毒或程序调用这些函数的时候,就无法找到真正的对应函数,从而调用失败。

不过这玩意已经没有什么神秘的了,道高一尺魔高一丈,现在的病毒已经可以绕过SSDT去直接调用底层函数了,或者说可以找出底层函数的真实地址了,这里,我们就简单利用KeServiceDescriptorTable这个函数来读取系统的SSDT表吧。

完整代码如下:

001.#include "stdafx.h"
002.#include <windows.h>
003.#include <iostream>
004.usingnamespace
std;
005.  
006.#define RVATOVA(base,offset)             ((PVOID)((DWORD)(base)+(DWORD)(offset)))
007.#define ibaseDD *(PDWORD)&ibase
008.#define STATUS_INFO_LENGTH_MISMATCH      ((NTSTATUS)0xC0000004L)
009.#define NT_SUCCESS(Status)               ((NTSTATUS)(Status) >= 0)
010.  
011.  
012.typedefstruct
{
013.    WORD   offset:12;
014.    WORD   type:4;
015.} IMAGE_FIXUP_ENTRY, *PIMAGE_FIXUP_ENTRY;
016.  
017.  
018.typedefLONG
NTSTATUS;
019.  
020.long( __stdcall *NtQuerySystemInformation )(
DWORD,PVOID,
DWORD,DWORD
);
021.  
022.typedefstruct
_SYSTEM_MODULE_INFORMATION {//Information Class 11
023.    ULONG   Reserved[2];
024.    PVOID   Base;
025.    ULONG   Size;
026.    ULONG   Flags;
027.    USHORT   Index;
028.    USHORT   Unknown;
029.    USHORT   LoadCount;
030.    USHORT   ModuleNameOffset;
031.    CHAR   ImageName[256];
032.}SYSTEM_MODULE_INFORMATION,*PSYSTEM_MODULE_INFORMATION;
033.  
034.typedefstruct
{
035.    DWORD   dwNumberOfModules;
036.    SYSTEM_MODULE_INFORMATION    smi;
037.} MODULES, *PMODULES;
038.  
039.#define    SystemModuleInformation    11
040.  
041.  
042.  
043.  
044.DWORDGetHeaders(PCHAR
ibase,
045.                 PIMAGE_FILE_HEADER *pfh,
046.                 PIMAGE_OPTIONAL_HEADER *poh,
047.                 PIMAGE_SECTION_HEADER *psh)
048.                   
049.{
050.    PIMAGE_DOS_HEADER mzhead=(PIMAGE_DOS_HEADER)ibase;
051.      
052.    if   ((mzhead->e_magic!=IMAGE_DOS_SIGNATURE)
||        
053.        (ibaseDD[mzhead->e_lfanew]!=IMAGE_NT_SIGNATURE))
054.        returnFALSE;
055.      
056.    *pfh=(PIMAGE_FILE_HEADER)&ibase[mzhead->e_lfanew];
057.    if(((PIMAGE_NT_HEADERS)*pfh)->Signature!=IMAGE_NT_SIGNATURE) 
058.        returnFALSE;
059.    *pfh=(PIMAGE_FILE_HEADER)((PBYTE)*pfh+sizeof(IMAGE_NT_SIGNATURE));
060.      
061.    *poh=(PIMAGE_OPTIONAL_HEADER)((PBYTE)*pfh+sizeof(IMAGE_FILE_HEADER));
062.    if((*poh)->Magic!=IMAGE_NT_OPTIONAL_HDR32_MAGIC)
063.        returnFALSE;
064.      
065.    *psh=(PIMAGE_SECTION_HEADER)((PBYTE)*poh+sizeof(IMAGE_OPTIONAL_HEADER));
066.    returnTRUE;
067.}
068.  
069.  
070.DWORDFindKiServiceTable(HMODULEhModule,DWORD
dwKSDT)
071.{
072.    PIMAGE_FILE_HEADER    pfh;
073.    PIMAGE_OPTIONAL_HEADER    poh;
074.    PIMAGE_SECTION_HEADER    psh;
075.    PIMAGE_BASE_RELOCATION    pbr;
076.    PIMAGE_FIXUP_ENTRY    pfe;    
077.      
078.    DWORD   dwFixups=0,i,dwPointerRva,dwPointsToRva,dwKiServiceTable;
079.    BOOL   bFirstChunk;
080.      
081.    GetHeaders((char*)hModule,&pfh,&poh,&psh);
082.      
083.    // loop thru relocs to speed up the search
084.    if((poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress)
&&
085.        (!((pfh->Characteristics)&IMAGE_FILE_RELOCS_STRIPPED))) {
086.          
087.        pbr=(PIMAGE_BASE_RELOCATION)RVATOVA(poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress,hModule);
088.          
089.        bFirstChunk=TRUE;
090.        // 1st IMAGE_BASE_RELOCATION.VirtualAddress of ntoskrnl is 0
091.        while(bFirstChunk || pbr->VirtualAddress)
{
092.            bFirstChunk=FALSE;
093.              
094.            pfe=(PIMAGE_FIXUP_ENTRY)((DWORD)pbr+sizeof(IMAGE_BASE_RELOCATION));
095.              
096.            for(i=0;i<(pbr->SizeOfBlock-sizeof(IMAGE_BASE_RELOCATION))>>1;i++,pfe++)
{
097.                if(pfe->type==IMAGE_REL_BASED_HIGHLOW)
{
098.                    dwFixups++;
099.                    dwPointerRva=pbr->VirtualAddress+pfe->offset;
100.                    // DONT_RESOLVE_DLL_REFERENCES flag means relocs aren't
fixed
101.                    dwPointsToRva=*(PDWORD)((DWORD)hModule+dwPointerRva)-(DWORD)poh->ImageBase;
102.                      
103.                    // does this reloc point to KeServiceDescriptorTable.Base?
104.                    if(dwPointsToRva==dwKSDT)
{
105.                        // check for mov [mem32],imm32. we are trying to
find 
106.                        // "mov ds:_KeServiceDescriptorTable.Base, offset
_KiServiceTable"
107.                        // from the KiInitSystem.
108.                        if(*(PWORD)((DWORD)hModule+dwPointerRva-2)==0x05c7)
{
109.                            // should check for a reloc presence on KiServiceTable
here
110.                            // but forget it
111.                            dwKiServiceTable=*(PDWORD)((DWORD)hModule+dwPointerRva+4)-poh->ImageBase;
112.                            returndwKiServiceTable;
113.                        }
114.                    }
115.                      
116.                
117.            }
118.            *(PDWORD)&pbr+=pbr->SizeOfBlock;
119.        }
120.    }    
121.      
122.      
123.      
124.    return0;
125.}
126.  
127.  
128.intEnumSSDT()
129.{
130.    HMODULE hKernel;
131.    DWORD   dwKSDT;               
// rva of KeServiceDescriptorTable
132.    DWORD   dwKiServiceTable;   
// rva of KiServiceTable
133.    PMODULES    pModules=(PMODULES)&pModules;
134.    DWORD   dwNeededSize,rc;
135.    DWORD   dwKernelBase,dwServices=0;
136.    PCHAR   pKernelName;
137.    PDWORD    pService;
138.    PIMAGE_FILE_HEADER    pfh;
139.    PIMAGE_OPTIONAL_HEADER    poh;
140.    PIMAGE_SECTION_HEADER    psh;
141.    NtQuerySystemInformation = (long(__stdcall*)(DWORD,PVOID,DWORD,DWORD))GetProcAddress(
GetModuleHandle(
"ntdll.dll"
),
"NtQuerySystemInformation"
); 
142.    //通过NtQuerySystemInformation取得系统内核文件,判断为是ntoskrnl.exe ntkrnlmp.exe ntkrnlpa.exe
143.    rc=NtQuerySystemInformation(SystemModuleInformation,pModules,4,(ULONG)&dwNeededSize);
144.    if(rc==STATUS_INFO_LENGTH_MISMATCH)
//如果内存不够
145.    {
146.        pModules=(PMODULES)GlobalAlloc(GPTR,dwNeededSize) ;//重新分配内存
147.        rc=NtQuerySystemInformation(SystemModuleInformation,pModules,dwNeededSize,NULL);//系统内核文件是总是在第一个,枚举1次
148.    
149.      
150.    if(!NT_SUCCESS(rc))
151.    {
152.        cout <<"NtQuerySystemInformation() Failed
!\n"
;//NtQuerySystemInformation执行失败,检查当前进程权限
153.        return0;
154.    }
155.      
156.    dwKernelBase=(DWORD)pModules->smi.Base;  //
imagebase
157.    pKernelName=pModules->smi.ModuleNameOffset+pModules->smi.ImageName;
158.    hKernel=LoadLibraryEx(pKernelName,0,DONT_RESOLVE_DLL_REFERENCES);    //
映射ntoskrnl //高 
159.    if(!hKernel)
160.    {
161.        cout <<"Failed to load \n";
162.        return0;        
163.    }
164.    GlobalFree(pModules);
165.    if(!(dwKSDT=(DWORD)GetProcAddress(hKernel,"KeServiceDescriptorTable")))//在内核文件中查找KeServiceDescriptorTable地址
166.    {
167.        cout <<"Can't find KeServiceDescriptorTable\n";
168.        return0;
169.    }
170.      
171.    dwKSDT-=(DWORD)hKernel;      //
获取 KeServiceDescriptorTable RVA
172.    if(!(dwKiServiceTable=FindKiServiceTable(hKernel,dwKSDT)))  
// 获取KiServiceTable地址
173.    {
174.        cout <<"Can't find KiServiceTable...\n";
175.        return0;
176.    }
177.      
178.    GetHeaders((char*)hKernel,&pfh,&poh,&psh); 
179.      
180.    intdwIndex=0;
181.    for(pService=(PDWORD)((DWORD)hKernel+dwKiServiceTable);
182.        *pService-poh->ImageBase<poh->SizeOfImage;
183.        pService++,dwServices++,dwIndex++)
184.    {
185.        printf("0x%03X-0x%08X\n",dwIndex,*pService-poh->ImageBase+dwKernelBase);  //SSDT索引和地址
186.    }
187.    FreeLibrary(hKernel);
188.    return1;
189.}
190.  
191.  
192.  
193.intmain()
194.{
195.    EnumSSDT();
196.  
197.    system("pause");
198.    return0;
199.}
 

关于SSDT的更多相关文章

  1. [教程] [授权翻译] 使用补丁修改DSDT/SSDT [DSDT/SSDT综合教程]

    [教程] [授权翻译] 使用补丁修改DSDT/SSDT [DSDT/SSDT综合教程] http://bbs.pcbeta.com/viewthread-1571455-1-1.html [教程] [ ...

  2. SSDT旧版本对于xml数据的处理BUG

    在早期版本中,CLR中声明sqlxml时,SSDT会将CLR函数中使用的类型解析为NVARCHAR(4000),最终导致传向CLR函数的数据不完整              

  3. About SSDT BI

    Welcome to Microsoft Marketing Speak hell. With the 2012 release of SQL Server, the BIDS, Business I ...

  4. Shadow SSDT详解、WinDbg查看Shadow SSDT

    一.获取ShadowSSDT 好吧,我们已经在R3获取SSDT的原始地址及SDT.SST.KiServiceTbale的关系里面提到:所有的SST都保存在系统服务描述表(SDT)中.系统中一共有两个S ...

  5. 两种方法获取shadow ssdt

    ULONG GetShadowSsdtCurrentAddresses( PSSDT_ADDRESS   AddressInfo, PULONG          Length ) { PSYSTEM ...

  6. Using MSBuild to publish a VS 2012 SSDT .sqlproj database project

    http://blog.danskingdom.com/using-msbuild-to-publish-a-vs-2012-ssdt-sqlproj-database-project-the-sam ...

  7. SSDT Hook实现简单的进程隐藏和保护【转载】

    原文链接:http://www.blogfshare.com/ssdthook-hide-protect.html 原文作者:AloneMonkey SSDT Hook实现简单的进程隐藏和保护 Alo ...

  8. Headless MSBuild Support for SSDT (*.sqlproj) Projects

    http://sqlproj.com/index.php/2012/03/headless-msbuild-support-for-ssdt-sqlproj-projects/ Update: bre ...

  9. 菜鸟开始学习SSDT HOOK((附带源码)

    看了梦无极的ssdt_hook教程,虽然大牛讲得很细,但是很多细节还是要自己去体会,才会更加深入.在这里我总结一下我的分析过程,若有不对的地方,希望大家指出来.首先我们应该认识 ssdt是什么?从梦无 ...

  10. SSDT Hook

    一.效果图 二.分析 这里对NtCreateProcessEx做拦截,用WinDbg来定位该函数在SSDT中的记录地址: : kd> dd KeServiceDescriptorTable 80 ...

随机推荐

  1. mysql数据库在windows下安装与配置

      mysql是一种开源源代码的关系型数据库系统(RDBMS),使用最常用的数据库管理语言--结构化查询语句(SQL)进行数据库管理. MySQL是开放源代码的,因此任何人都可以在General Pu ...

  2. use zlib lib to compress or decompress file

    If you want to compress or decompress file when writing C++ code,you can choose zlib library,that's ...

  3. 自己做的notepad++ FTP同步插件

    平时修改FTP上的文件的时候,想先备份一下,没有合适的方法,尝试做了一个小插件. 差点忘了,下载地址   https://pan.baidu.com/s/1htdtT9E 下面是   具体的说明 Fa ...

  4. C#基础(四)--值类型和引用类型,栈和堆的含义

    本文主要是讨论栈和堆的含义,也就是讨论C#的两种类据类型:值类型和引用类型: 虽然我们在.net中的框架类库中,大多是引用类型,但是我们程序员用得最多的还是值类型. 引用类型如:string,Obje ...

  5. 01_Python入门

    Python介绍 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆(中文名字:龟叔)为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程 ...

  6. 使用localhost可以访问,但使用本地ip+端口号无法访问

    今天想使用ip访问本机的iview-admin项目,结果怎么配置都无法访问,根据iview工程执行的命令npm run dev了解到是webpack配置的问题,打开工程里的node_modules文件 ...

  7. bzoj 1598: [Usaco2008 Mar]牛跑步 [k短路 A*] [学习笔记]

    1598: [Usaco2008 Mar]牛跑步 题意:k短路 ~~貌似A*的题目除了x数码就是k短路~~ \[ f(x) = g(x) + h(x) \] \(g(x)\)为到达当前状态实际代价,\ ...

  8. HDU D Tree [点分治]

    传送门 题意:找路径积$\mod 1e6+3 = k$的字典序最小点对 作为一个点分治蒟蒻,写这道题花了两节课.... 显然只要开一个桶$c[i]$记录当前路径积为$i$的最小点 然后处理一个子树时一 ...

  9. POJ 2888 Magic Bracelet [Polya 矩阵乘法]

    传送门 题意:竟然扯到哈利波特了.... 和上一题差不多,但颜色数很少,给出不能相邻的颜色对 可以相邻的连边建图矩阵乘法求回路个数就得到$f(i)$了.... 感觉这样的环上有限制问题挺套路的...旋 ...

  10. Redis服务器启动之后3个警告信息的解决方案

    今天是年前最后一篇文章了,不想写太多的东西,就写一些有关Redis相关问题的解决方案.当我们启动了Redis服务器之后,会看到3个警告,如果没看到,那是很好的,但是我看到了.看到了就不能不管,所以就好 ...