关于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 ...
随机推荐
- Java - 双冒泡法排序
最开始的代码 我采用的是我原来进行快速排序所用的方法,一直做不出来. 为什么我会采用原来快速排序的方法?因为我的记忆中好像就是这样的,因此我根据记忆中的快速排序在进行改变,然而,却无法真正的写出双冒泡 ...
- H5WebSocket前后台代码
1.效果图 2.后台代码: public void Demo() { //return "Hello World"; HttpContextBase content = this. ...
- 安装supervisor
机器版本 centos 6.5 python 版本 2.6.6 在终端输入 easy_install supervisor 并回车,linux会自动联网并下载supervisor源码解压并安装 安装成 ...
- Effective Java 之-----静态工厂与构造器
一. 考虑用静态工厂方法代替构造器: 1)静态工厂方法与构造器不同的第一大优势在于:他们有名称.当一个类需要多个带有相同签名的构造器时,就用静态方法代替构造器,并慎重的选择名称以突出他们间的区别: 2 ...
- javascript中的字符串对象和数组对象
1.javascript的对象的概念 在javascript中,除了null和undefined以处,其他的数据类型都被定义成了对象 也可以用创建对象的方法定义变量,string,math,array ...
- Halcon一日一练:图像、变量实时更新
某些场合,我们需要刷新图像来识别图像处理过程的差异性,便于调试判断问题和预测.Halcon提供了图像刷新操作,这些操作不会改变程序的最终处理结果. 例程: **实时刷新图像 dev_update_wi ...
- 洛谷 [P1113] 杂务
图论的做法是topsort 一看见有序我们就想到了DAG图,于是用topsort做,对于每一个加入队列的顶点,都用它的时间去更新它所指向的点的时间,本质上仍是DP的思想,dp[i]=max{dp[j] ...
- BZOJ 2115: [Wc2011] Xor [高斯消元XOR 线性基 图]
啦啦啦 题意: N 个点M条边的边带权的无向图,求1到n一条XOR和最大的路径 感觉把学的东西都用上了.... 1到n的所有路径可以由一条1到n的简单路径异或上任意个简单环得到 证明: 如果环与路径有 ...
- JAVA 二进制基础
主要内容 1.十进制二进制互转 2.二进制的位运算 3.JDK内置的进制转换 4.JAVA中的进制 十进制二进制互转 57 111001 二进制的位运算:优点:特定情况下,计算方便,被支持面广泛. ① ...
- Flask-Moment----探索
前言: Flask-Moment在所有的flask扩展中算是相对简单的一个了,但是还是有很多需要理解的地方.那么今天就跟着笔者一起,来学习一下flask-moment在flask项目中的应用. 首先 ...