1. ULONG
  2. GetShadowSsdtCurrentAddresses(
  3. PSSDT_ADDRESS   AddressInfo,
  4. PULONG          Length
  5. )
  6. {
  7. PSYSTEM_SERVICE_TABLE KeServiceDescriptorTableShadow = NULL;
  8. ULONG NumberOfService = 0;
  9. ULONG ServiceId = 0;
  10. PKAPC_STATE ApcState;
  11. ULONG i;
  12. if (AddressInfo == NULL || Length == NULL)
  13. {
  14. KdPrint(("[GetShadowSsdtCurrentAddresses] 输入参数无效"));
  15. return 0;
  16. }
  17. //KdPrint(("pid = %d", PsGetCurrentProcessId()));
  18. ServiceId = (ULONG)PsGetCurrentProcessId();
  19. if (!g_CsrssProcess) {
  20. PsLookupProcessByProcessId((PVOID)ScPsGetCsrssProcessId(), &g_CsrssProcess);
  21. }
  22. KeServiceDescriptorTableShadow = GetKeServiceDescriptorTableShadow();
  23. if (KeServiceDescriptorTableShadow == NULL)
  24. {
  25. KdPrint(("[GetShadowSsdtCurrentAddresses] GetKeServiceDescriptorTableShadow failed"));
  26. return 0;
  27. }
  28. NumberOfService = KeServiceDescriptorTableShadow->NumberOfService;
  29. if (Length[0] < NumberOfService * sizeof(SSDT_ADDRESS))
  30. {
  31. Length[0] = NumberOfService * sizeof(SSDT_ADDRESS);
  32. return 0;
  33. }
  34. ApcState = ExAllocatePoolWithTag(NonPagedPool, sizeof(KAPC_STATE), MEM_TAG);
  35. KeStackAttachProcess((PRKPROCESS)g_CsrssProcess, ApcState);
  36. for (ServiceId = 0; ServiceId < NumberOfService; ServiceId ++)
  37. {
  38. AddressInfo[ServiceId].FunAddress = (ULONG)
  39. KeServiceDescriptorTableShadow->ServiceTableBase[ServiceId];
  40. AddressInfo[ServiceId].nIndex = ServiceId;
  41. }
  42. KeUnstackDetachProcess(ApcState);
  43. ExFreePool(ApcState);
  44. Length[0] = NumberOfService * sizeof(SSDT_ADDRESS);
  45. return NumberOfService;
  46. }
  47. ///////////////////////////////////////////////////////////////////////////////////
  48. //
  49. //  功能实现:枚举当前Shadow SSDT 表函数地址
  50. //  输入参数:void
  51. //  输出参数:返回Shadow ssdt table
  52. //
  53. ///////////////////////////////////////////////////////////////////////////////////
  54. PSYSTEM_SERVICE_TABLE
  55. GetKeServiceDescriptorTableShadow(VOID)
  56. {
  57. PSYSTEM_SERVICE_TABLE ShadowTable = NULL;
  58. ULONG   ServiceTableAddress = 0;
  59. PUCHAR  cPtr = NULL;
  60. for (cPtr = (PUCHAR)KeAddSystemServiceTable;
  61. cPtr < (PUCHAR)KeAddSystemServiceTable + PAGE_SIZE;
  62. cPtr += 1 )
  63. {
  64. if (!MmIsAddressValid(cPtr))  continue;
  65. ServiceTableAddress = *(PULONG)cPtr;
  66. if (!MmIsAddressValid((PVOID)ServiceTableAddress)) continue;
  67. if (memcmp((PVOID)ServiceTableAddress, &KeServiceDescriptorTable, 16) == 0)
  68. {
  69. if ((PVOID)ServiceTableAddress == &KeServiceDescriptorTable) continue;
  70. ShadowTable = (PSYSTEM_SERVICE_TABLE)ServiceTableAddress;
  71. ShadowTable ++;
  72. return ShadowTable;
  73. }
  74. }
  75. return NULL;
  76. }
  77. //
  78. // 方法2,通过硬编码实现,不通用
  79. //
  80. PSYSTEM_SERVICE_TABLE
  81. GetKeServiceDescriptorTableShadow_2(VOID)
  82. /*++
  83. KeAddSystemServiceTable函数
  84. 805ba5a3 8d8840a65580    lea    ecx,nt!KeServiceDescriptorTableShadow (8055a640)[eax]
  85. 805ba5a9 833900          cmp    dword ptr [ecx],0
  86. --*/
  87. {
  88. PSYSTEM_SERVICE_TABLE ShadowTable;
  89. ULONG   ServiceTableAddress;
  90. PUCHAR  cPtr, pOpcode;
  91. ULONG   Length = 0;
  92. for (cPtr = (PUCHAR)KeAddSystemServiceTable;
  93. cPtr < (PUCHAR)KeAddSystemServiceTable + PAGE_SIZE;
  94. cPtr += Length )
  95. {
  96. if (!MmIsAddressValid(cPtr))  return NULL;
  97. Length = SizeOfCode(cPtr, &pOpcode);
  98. if (!Length || (Length == 1 && *pOpcode == 0xC3)) return NULL;
  99. if (*(PUSHORT)pOpcode == 0x888D)
  100. {
  101. ServiceTableAddress = *(PULONG)(pOpcode + 2);
  102. ShadowTable = (PSYSTEM_SERVICE_TABLE)ServiceTableAddress;
  103. ShadowTable ++;
  104. return ShadowTable;
  105. }
  106. }
  107. return NULL;
  108. }

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的更多相关文章

  1. 两种方法获取MyBatis刚刚插入的id

    主要就是在xml文件中的写法,其他省略 方法一: <insert id="insert" parameterType="com.xxx.xxxx.pojo.User ...

  2. Delphi使用两种不同方法获取系统端口信息--(装载)

    Delphi使用两种方法获取windows系统的端口,还可测试发送消息,点击获取端口信息后,可依次得到如下信息:DCB结构大小.波特率大小.XON的临界值.XOFF的临界值.字符位数.奇偶检验位.停止 ...

  3. 用easyui从servlet传递json数据到前端页面的两种方法

    用easyui从servlet传递json数据到前端页面的两种方法 两种方法获取的数据在servlet层传递的方法相同,下面为Servlet中代码,以查询表中所有信息为例. //重写doGet方法 p ...

  4. windows下获取IP地址的两种方法

    windows下获取IP地址的两种方法: 一种可以获取IPv4和IPv6,但是需要WSAStartup: 一种只能取到IPv4,但是不需要WSAStartup: 如下: 方法一:(可以获取IPv4和I ...

  5. 获取网页URL地址及参数等的两种方法(js和C#)

    转:获取网页URL地址及参数等的两种方法(js和C#) 一 js 先看一个示例 用javascript获取url网址信息 <script type="text/javascript&q ...

  6. Java 获取*.properties配置文件中的内容 ,常见的两种方法

    import java.io.InputStream; import java.util.Enumeration; import java.util.List; import java.util.Pr ...

  7. php获取数组中重复数据的两种方法

    分享下php获取数组中重复数据的两种方法. 1,利用php提供的函数,array_unique和array_diff_assoc来实现 <?php function FetchRepeatMem ...

  8. javascript获取json对象的key名称的两种方法

    javascript获取json对象的key名称的两种方法 数据处理中,你可能接收到一个不确定内容格式的json对象,然后要把key的值提取出来.今天试过两种可以提取json key的方法,均可以正常 ...

  9. 使用JavaScript获取URL中的参数(两种方法)

    本文给大家分享两种方法使用js获取url中的参数,其中方法二是使用的正则表达式方法,大家可以根据需要选择比较好的方法,废话不多说了,直接看详细介绍吧. 方法一: //取url参数 var type = ...

随机推荐

  1. 手动fsck修复

    [转自]http://blog.chinaunix.net/uid-26719405-id-3781541.html 由于硬盘常年读写,系统会造成系统文件损坏,导致重启后无法登陆到系统, fsck不仅 ...

  2. ffmpeg-20160815-bin.7z

    ESC 退出 0 进度条开关 1 屏幕原始大小 2 屏幕1/2大小 3 屏幕1/3大小 4 屏幕1/4大小 S 下一帧 [ -2秒 ] +2秒 ; -1秒 ' +1秒 下一个帧 -> -5秒 f ...

  3. Sql Server事务简单用法

    var conStr = "server=localhost;database=Data;user=sa;pwd=123456"; using (var connection = ...

  4. syslog-ng 学习心得与配置说明

    配置说明syslog-ng的主配置文件存放在:/etc/syslog-ng/syslog-ng.conf 一.基础 系统自带版本: 引用 # rpm -qa|grep syslog-ng syslog ...

  5. hdu 1972.Printer Queue 解题报告

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1972 题目意思:需要模拟打印机打印.打印机里面有一些 job,每个job被赋予1-9的其中一个值,越大 ...

  6. codeforces 500A. New Year Transportation

    题目链接:http://codeforces.com/problemset/problem/500/A 题目意思:给出 n-1 个 cell,每个 cell 有一个值 ai,表示在这个编号为 i 的 ...

  7. WP8图片缩放功能实现

    最近在学习WP8,想实现WP微信中查看图片时的放大缩小功能. 网上找了两个解决方案: 1 利用GestureListener 这个类在Microsoft.Phone.Controls.Toolkit中 ...

  8. EF查询视图只得到一条记录

    1.出错结果:数据库表视图有多条数据,在使用EF框架进行查询时却只得到一条数据(注:拦截EF得到的sql语句在数据库进行查询并没有任务问题). 2.出错原因:该视图中没有ID或者主键,EF查询时进行反 ...

  9. orace 取昨天凌晨的日期

    sysdate 为现在时间sysdate-1为昨天trunc(sysdate-1)为昨天凌晨0:00trunc(sysdate-1)+20/24 为昨天晚上8点select trunc(sysdate ...

  10. 本地Yum

    1. mkdir xxx #新建文件夹 (新建一个挂载需要的文件夹) 2.配置本地yum源(挂载光盘) 3.进入 yum.repos.d 4.ls (查看当前文件夹全部的文件) 并 mv 修改   除 ...