两种方法获取shadow ssdt
- ULONG
- GetShadowSsdtCurrentAddresses(
- PSSDT_ADDRESS AddressInfo,
- PULONG Length
- )
- {
- PSYSTEM_SERVICE_TABLE KeServiceDescriptorTableShadow = NULL;
- ULONG NumberOfService = 0;
- ULONG ServiceId = 0;
- PKAPC_STATE ApcState;
- ULONG i;
- if (AddressInfo == NULL || Length == NULL)
- {
- KdPrint(("[GetShadowSsdtCurrentAddresses] 输入参数无效"));
- return 0;
- }
- //KdPrint(("pid = %d", PsGetCurrentProcessId()));
- ServiceId = (ULONG)PsGetCurrentProcessId();
- if (!g_CsrssProcess) {
- PsLookupProcessByProcessId((PVOID)ScPsGetCsrssProcessId(), &g_CsrssProcess);
- }
- KeServiceDescriptorTableShadow = GetKeServiceDescriptorTableShadow();
- if (KeServiceDescriptorTableShadow == NULL)
- {
- KdPrint(("[GetShadowSsdtCurrentAddresses] GetKeServiceDescriptorTableShadow failed"));
- return 0;
- }
- NumberOfService = KeServiceDescriptorTableShadow->NumberOfService;
- if (Length[0] < NumberOfService * sizeof(SSDT_ADDRESS))
- {
- Length[0] = NumberOfService * sizeof(SSDT_ADDRESS);
- return 0;
- }
- ApcState = ExAllocatePoolWithTag(NonPagedPool, sizeof(KAPC_STATE), MEM_TAG);
- KeStackAttachProcess((PRKPROCESS)g_CsrssProcess, ApcState);
- for (ServiceId = 0; ServiceId < NumberOfService; ServiceId ++)
- {
- AddressInfo[ServiceId].FunAddress = (ULONG)
- KeServiceDescriptorTableShadow->ServiceTableBase[ServiceId];
- AddressInfo[ServiceId].nIndex = ServiceId;
- }
- KeUnstackDetachProcess(ApcState);
- ExFreePool(ApcState);
- Length[0] = NumberOfService * sizeof(SSDT_ADDRESS);
- return NumberOfService;
- }
- ///////////////////////////////////////////////////////////////////////////////////
- //
- // 功能实现:枚举当前Shadow SSDT 表函数地址
- // 输入参数:void
- // 输出参数:返回Shadow ssdt table
- //
- ///////////////////////////////////////////////////////////////////////////////////
- PSYSTEM_SERVICE_TABLE
- GetKeServiceDescriptorTableShadow(VOID)
- {
- PSYSTEM_SERVICE_TABLE ShadowTable = NULL;
- ULONG ServiceTableAddress = 0;
- PUCHAR cPtr = NULL;
- for (cPtr = (PUCHAR)KeAddSystemServiceTable;
- cPtr < (PUCHAR)KeAddSystemServiceTable + PAGE_SIZE;
- cPtr += 1 )
- {
- if (!MmIsAddressValid(cPtr)) continue;
- ServiceTableAddress = *(PULONG)cPtr;
- if (!MmIsAddressValid((PVOID)ServiceTableAddress)) continue;
- if (memcmp((PVOID)ServiceTableAddress, &KeServiceDescriptorTable, 16) == 0)
- {
- if ((PVOID)ServiceTableAddress == &KeServiceDescriptorTable) continue;
- ShadowTable = (PSYSTEM_SERVICE_TABLE)ServiceTableAddress;
- ShadowTable ++;
- return ShadowTable;
- }
- }
- return NULL;
- }
- //
- // 方法2,通过硬编码实现,不通用
- //
- PSYSTEM_SERVICE_TABLE
- GetKeServiceDescriptorTableShadow_2(VOID)
- /*++
- KeAddSystemServiceTable函数
- 805ba5a3 8d8840a65580 lea ecx,nt!KeServiceDescriptorTableShadow (8055a640)[eax]
- 805ba5a9 833900 cmp dword ptr [ecx],0
- --*/
- {
- PSYSTEM_SERVICE_TABLE ShadowTable;
- ULONG ServiceTableAddress;
- PUCHAR cPtr, pOpcode;
- ULONG Length = 0;
- for (cPtr = (PUCHAR)KeAddSystemServiceTable;
- cPtr < (PUCHAR)KeAddSystemServiceTable + PAGE_SIZE;
- cPtr += Length )
- {
- if (!MmIsAddressValid(cPtr)) return NULL;
- Length = SizeOfCode(cPtr, &pOpcode);
- if (!Length || (Length == 1 && *pOpcode == 0xC3)) return NULL;
- if (*(PUSHORT)pOpcode == 0x888D)
- {
- ServiceTableAddress = *(PULONG)(pOpcode + 2);
- ShadowTable = (PSYSTEM_SERVICE_TABLE)ServiceTableAddress;
- ShadowTable ++;
- return ShadowTable;
- }
- }
- return NULL;
- }

ULONG
GetShadowSsdtCurrentAddresses(
PSSDT_ADDRESS AddressInfo,
PULONG Length
)
{
PSYSTEM_SERVICE_TABLE KeServiceDescriptorTableShadow = NULL;
ULONG NumberOfService = 0;
ULONG ServiceId = 0;
PKAPC_STATE ApcState;
ULONG i;
if (AddressInfo == NULL || Length == NULL)
{
KdPrint(("[GetShadowSsdtCurrentAddresses] 输入参数无效"));
return 0;
}
//KdPrint(("pid = %d", PsGetCurrentProcessId()));
ServiceId = (ULONG)PsGetCurrentProcessId();
if (!g_CsrssProcess) {
PsLookupProcessByProcessId((PVOID)ScPsGetCsrssProcessId(), &g_CsrssProcess);
}
KeServiceDescriptorTableShadow = GetKeServiceDescriptorTableShadow();
if (KeServiceDescriptorTableShadow == NULL)
{
KdPrint(("[GetShadowSsdtCurrentAddresses] GetKeServiceDescriptorTableShadow failed"));
return 0;
}
NumberOfService = KeServiceDescriptorTableShadow->NumberOfService;
if (Length[0] < NumberOfService * sizeof(SSDT_ADDRESS))
{
Length[0] = NumberOfService * sizeof(SSDT_ADDRESS);
return 0;
}
ApcState = ExAllocatePoolWithTag(NonPagedPool, sizeof(KAPC_STATE), MEM_TAG);
KeStackAttachProcess((PRKPROCESS)g_CsrssProcess, ApcState);
for (ServiceId = 0; ServiceId < NumberOfService; ServiceId ++)
{
AddressInfo[ServiceId].FunAddress = (ULONG)
KeServiceDescriptorTableShadow->ServiceTableBase[ServiceId];
AddressInfo[ServiceId].nIndex = ServiceId;
}
KeUnstackDetachProcess(ApcState);
ExFreePool(ApcState);
Length[0] = NumberOfService * sizeof(SSDT_ADDRESS);
return NumberOfService;
}
///////////////////////////////////////////////////////////////////////////////////
//
// 功能实现:枚举当前Shadow SSDT 表函数地址
// 输入参数:void
// 输出参数:返回Shadow ssdt table
//
///////////////////////////////////////////////////////////////////////////////////
PSYSTEM_SERVICE_TABLE
GetKeServiceDescriptorTableShadow(VOID)
{
PSYSTEM_SERVICE_TABLE ShadowTable = NULL;
ULONG ServiceTableAddress = 0;
PUCHAR cPtr = NULL;
for (cPtr = (PUCHAR)KeAddSystemServiceTable;
cPtr < (PUCHAR)KeAddSystemServiceTable + PAGE_SIZE;
cPtr += 1 )
{
if (!MmIsAddressValid(cPtr)) continue;
ServiceTableAddress = *(PULONG)cPtr;
if (!MmIsAddressValid((PVOID)ServiceTableAddress)) continue;
if (memcmp((PVOID)ServiceTableAddress, &KeServiceDescriptorTable, 16) == 0)
{
if ((PVOID)ServiceTableAddress == &KeServiceDescriptorTable) continue;
ShadowTable = (PSYSTEM_SERVICE_TABLE)ServiceTableAddress;
ShadowTable ++;
return ShadowTable;
}
}
return NULL;
}
//
// 方法2,通过硬编码实现,不通用
//
PSYSTEM_SERVICE_TABLE
GetKeServiceDescriptorTableShadow_2(VOID)
/*++
805ba5a3 8d8840a65580 lea ecx,nt!KeServiceDescriptorTableShadow (8055a640)[eax]
805ba5a9 833900 cmp dword ptr [ecx],0
--*/
{
PSYSTEM_SERVICE_TABLE ShadowTable;
ULONG ServiceTableAddress;
PUCHAR cPtr, pOpcode;
ULONG Length = 0;
for (cPtr = (PUCHAR)KeAddSystemServiceTable;
cPtr < (PUCHAR)KeAddSystemServiceTable + PAGE_SIZE;
cPtr += Length )
{
if (!MmIsAddressValid(cPtr)) return NULL;
Length = SizeOfCode(cPtr, &pOpcode);
if (!Length || (Length == 1 && *pOpcode == 0xC3)) return NULL;
if (*(PUSHORT)pOpcode == 0x888D)
{
ServiceTableAddress = *(PULONG)(pOpcode + 2);
ShadowTable = (PSYSTEM_SERVICE_TABLE)ServiceTableAddress;
ShadowTable ++;
return ShadowTable;
}
}
return NULL;
}
两种方法获取shadow ssdt的更多相关文章
- 两种方法获取MyBatis刚刚插入的id
主要就是在xml文件中的写法,其他省略 方法一: <insert id="insert" parameterType="com.xxx.xxxx.pojo.User ...
- Delphi使用两种不同方法获取系统端口信息--(装载)
Delphi使用两种方法获取windows系统的端口,还可测试发送消息,点击获取端口信息后,可依次得到如下信息:DCB结构大小.波特率大小.XON的临界值.XOFF的临界值.字符位数.奇偶检验位.停止 ...
- 用easyui从servlet传递json数据到前端页面的两种方法
用easyui从servlet传递json数据到前端页面的两种方法 两种方法获取的数据在servlet层传递的方法相同,下面为Servlet中代码,以查询表中所有信息为例. //重写doGet方法 p ...
- windows下获取IP地址的两种方法
windows下获取IP地址的两种方法: 一种可以获取IPv4和IPv6,但是需要WSAStartup: 一种只能取到IPv4,但是不需要WSAStartup: 如下: 方法一:(可以获取IPv4和I ...
- 获取网页URL地址及参数等的两种方法(js和C#)
转:获取网页URL地址及参数等的两种方法(js和C#) 一 js 先看一个示例 用javascript获取url网址信息 <script type="text/javascript&q ...
- Java 获取*.properties配置文件中的内容 ,常见的两种方法
import java.io.InputStream; import java.util.Enumeration; import java.util.List; import java.util.Pr ...
- php获取数组中重复数据的两种方法
分享下php获取数组中重复数据的两种方法. 1,利用php提供的函数,array_unique和array_diff_assoc来实现 <?php function FetchRepeatMem ...
- javascript获取json对象的key名称的两种方法
javascript获取json对象的key名称的两种方法 数据处理中,你可能接收到一个不确定内容格式的json对象,然后要把key的值提取出来.今天试过两种可以提取json key的方法,均可以正常 ...
- 使用JavaScript获取URL中的参数(两种方法)
本文给大家分享两种方法使用js获取url中的参数,其中方法二是使用的正则表达式方法,大家可以根据需要选择比较好的方法,废话不多说了,直接看详细介绍吧. 方法一: //取url参数 var type = ...
随机推荐
- python之打包相关
打包手册:https://python-packaging-user-guide.readthedocs.org/en/latest/installing.html#installing-from-a ...
- jdbc事务处理和连接池
JDBC: * JDBC概念:Java DataBase Connectivity(Java数据库连接) SUN公司提供的一组连接数据库API. * JDBC开发步骤: * 1.注册驱动. * 2.获 ...
- ACM/ICPC 之 暴力打表(求解欧拉回路)-编码(POJ1780)
///找到一个数字序列包含所有n位数(连续)一次且仅一次 ///暴力打表 ///Time:141Ms Memory:2260K #include<iostream> #include< ...
- 算法手记 之 数据结构(线段树详解)(POJ 3468)
依然延续第一篇读书笔记,这一篇是基于<ACM/ICPC 算法训练教程>上关于线段树的讲解的总结和修改(这本书在线段树这里Error非常多),但是总体来说这本书关于具体算法的讲解和案例都是不 ...
- Session原理浅析
什么是Sesson? 简单说就是一个会话级的cookie,外加服务器端内存中一组散列表. 当你关闭浏览器的时候,这个cookie将消失. 这个cookie不写在磁盘上,而是存在于浏览器缓存. 关于Se ...
- DB2 SQLCODE 大全
DB2错误信息sqlcode sqlstate 说明 000 00000 SQL语句成功完成 01xxx SQL语句成功完成,但是有警告 +012 01545 未限定的列名被解释为一个有相互关系的引用 ...
- 【leetcode】Anagrams (middle)
Given an array of strings, return all groups of strings that are anagrams. Note: All inputs will be ...
- 动手动脑及java程序之用消息框进行数的运算
动手动脑 自信成就人生 动手动脑1 ✿仔细阅读示例: EnumTest.java,运行它,分析运行结果? package demo; public class Test { publi ...
- hdu 1513
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1513 思路:正反分别求一次LCS,利用滚动数组对二取余滚动 #include<stdio.h&g ...
- C#学习笔记---协变和逆变
http://www.cnblogs.com/alphafly/p/4048608.html 协变是指方法能从委托的返回类型派生的一个类型. 逆变之方法获取的参数可以是委托参数类型的基类.