关于SSDT
百度上比较好的解释是: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.usingnamespacestd; 005.  006.#define RVATOVA(base,offset)             ((PVOID)((DWORD)(base)+(DWORD)(offset)))007.#define ibaseDD *(PDWORD)&ibase008.#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.typedefLONGNTSTATUS; 019.  020.long( __stdcall *NtQuerySystemInformation )(
DWORD,PVOID,
DWORD,DWORD); 021.  022.typedefstruct_SYSTEM_MODULE_INFORMATION {//Information Class 11023.    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    11040.  041.  042.  043.  044.DWORDGetHeaders(PCHARibase, 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,DWORDdwKSDT) 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 search084.    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 0091.        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 it111.                            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 KeServiceDescriptorTable132.    DWORD   dwKiServiceTable;   
// rva of KiServiceTable133.    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.exe143.    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的更多相关文章
- [教程] [授权翻译] 使用补丁修改DSDT/SSDT [DSDT/SSDT综合教程]
		
[教程] [授权翻译] 使用补丁修改DSDT/SSDT [DSDT/SSDT综合教程] http://bbs.pcbeta.com/viewthread-1571455-1-1.html [教程] [ ...
 - SSDT旧版本对于xml数据的处理BUG
		
在早期版本中,CLR中声明sqlxml时,SSDT会将CLR函数中使用的类型解析为NVARCHAR(4000),最终导致传向CLR函数的数据不完整
 - About SSDT BI
		
Welcome to Microsoft Marketing Speak hell. With the 2012 release of SQL Server, the BIDS, Business I ...
 - Shadow SSDT详解、WinDbg查看Shadow SSDT
		
一.获取ShadowSSDT 好吧,我们已经在R3获取SSDT的原始地址及SDT.SST.KiServiceTbale的关系里面提到:所有的SST都保存在系统服务描述表(SDT)中.系统中一共有两个S ...
 - 两种方法获取shadow ssdt
		
ULONG GetShadowSsdtCurrentAddresses( PSSDT_ADDRESS AddressInfo, PULONG Length ) { PSYSTEM ...
 - 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 ...
 - SSDT Hook实现简单的进程隐藏和保护【转载】
		
原文链接:http://www.blogfshare.com/ssdthook-hide-protect.html 原文作者:AloneMonkey SSDT Hook实现简单的进程隐藏和保护 Alo ...
 - Headless MSBuild Support for SSDT (*.sqlproj) Projects
		
http://sqlproj.com/index.php/2012/03/headless-msbuild-support-for-ssdt-sqlproj-projects/ Update: bre ...
 - 菜鸟开始学习SSDT HOOK((附带源码)
		
看了梦无极的ssdt_hook教程,虽然大牛讲得很细,但是很多细节还是要自己去体会,才会更加深入.在这里我总结一下我的分析过程,若有不对的地方,希望大家指出来.首先我们应该认识 ssdt是什么?从梦无 ...
 - SSDT Hook
		
一.效果图 二.分析 这里对NtCreateProcessEx做拦截,用WinDbg来定位该函数在SSDT中的记录地址: : kd> dd KeServiceDescriptorTable 80 ...
 
随机推荐
- C之多线程(例子很不错)
			
1.线程 线程池是一个树状结构. 多线程解决并发问题. 一个线程内部的执行顺序是线性的.而线程之间是乱序的. 若要创建一个多线程程序,它的参数必须是空指针类型. 变色龙程序: #define _CRT ...
 - Log4Net记录到MySql
			
1.新建控制台程序. 2.添加Log4Net nuget 3.添加MySql 引用 4.添加配置文件如下: <?xml version="1.0"?> <conf ...
 - 对把JDK源码的一些注解,笔记
			
//对treeMap的红黑树理解注解. 2017.02.16 by 何锦彬 JDK,1.7.51 /** From CLR */ private void fixAfterInsertion(Entr ...
 - Linux 虚拟机忘记root密码
			
Linux 虚拟机忘记root密码可以按照下面的步骤重新设置密码: 1.在grub界面,也就是有press any key的那个界面,按下任意键 2.键入e,出现三行文字,按上下键选择kernel那一 ...
 - 使用exe4j工具制作简单的java应用程序
			
首先需要下载exe4j工具并进行安装,下面是利用exe4j工具制作应用程序的步骤. 1.首先将工程导出为可运行的jar包,选择extract required libralies into gener ...
 - bzoj 2618: [Cqoi2006]凸多边形 [半平面交]
			
2618: [Cqoi2006]凸多边形 半平面交 注意一开始多边形边界不要太大... #include <iostream> #include <cstdio> #inclu ...
 - BZOJ 4129: Haruna’s Breakfast [树上莫队 分块]
			
传送门 题意: 单点修改,求一条链的mex 分块维护权值,$O(1)$修改$O(S)$求mex...... 带修改树上莫队 #include <iostream> #include < ...
 - BZOJ 3105: [cqoi2013]新Nim游戏 [高斯消元XOR 线性基]
			
以后我也要用传送门! 题意:一些数,选择一个权值最大的异或和不为0的集合 终于有点明白线性基是什么了...等会再整理 求一个权值最大的线性无关子集 线性无关子集满足拟阵的性质,贪心选择权值最大的,用高 ...
 - python dns查询与DNS传输漏洞查询
			
前言: 昨天晚上在看DNS协议,然后想到了 DNS传输漏洞.便想写一个DNS查询与DNS传输漏洞查询 DNS传输漏洞介绍: DNS传输漏洞:若DNS服务器配置不当,可能导致匿名用户获取某个域的所有记录 ...
 - WEB-INF目录下文件复制的几种方式
			
2018年1月31日 10:42:55 工作完写点博客记录下. 需求:从web-inf下拷贝文件到指定目录. 目录结构 直接贴代码 第一种方式,字节流读取 try { int index = 0; S ...