ring0-新建SSDT项进行通讯(随手代码)

http://blog.csdn.net/hgy413/article/details/7107009

以下仅针对32位系统,在XP下测试:
以下是XP在ring3的调用方式:

[cpp] view plaincopy

  1. // xp
  2. ntdll!NtReadFile:
  3. 7c92d9b0 b8b7000000   mov    eax,0B7h
  4. 7c92d9b5 ba0003fe7f   mov    edx,offset SharedUserData!SystemCallStub (7ffe0300)
  5. 7c92d9ba ff12           call    dword ptr [edx]   ds:0023:7ffe0300={ntdll!KiFastSystemCall (7c92e4f0)}
  6. 7c92d9bc c22400       ret    24h
  7. 7c92d9bf 90           nop
  8. ntdll!KiFastSystemCall:
  9. 7c92e4f0 8bd4           mov  edx,esp
  10. 7c92e4f2 0f34           sysenter

所以原理也比较简单了,仿写即可,注意SSDT要去掉写保护!
ring3:

[cpp] view plaincopy

  1. #include "stdafx.h"
  2. #include <Windows.h>
  3. __declspec(naked) void MyKiFastSystemCall()
  4. {
  5. __asm
  6. {
  7. mov  edx,esp;
  8. __emit 0x0f;
  9. __emit 0x34;
  10. }
  11. };
  12. __declspec(naked) NTSTATUS NTAPI
  13. IOSystemControl(
  14. IN ULONG IoCtrl,
  15. IN PVOID InputBuf,
  16. IN ULONG InputBufLen,
  17. OUT PVOID OutputBuf,
  18. IN ULONG OutputLen,
  19. OUT PULONG ReturnLen)
  20. {
  21. __asm
  22. {
  23. mov eax, 11Ch;
  24. call MyKiFastSystemCall
  25. retn 0x18;
  26. }
  27. }
  28. int _tmain(int argc, _TCHAR* argv[])
  29. {
  30. char szBuf[100] = {0};
  31. ULONG outlen = 0;
  32. IOSystemControl(0x12345678,"hgy413",strlen("hgy413"),szBuf,99,&outlen);
  33. printf("%s-%d\n",szBuf, outlen);
  34. getchar();
  35. return 0;
  36. }

ring0:

[cpp] view plaincopy

  1. #include "main.h"
  2. // def
  3. typedef struct _KSERVICE_TABLE_DESCRIPTOR
  4. {
  5. PULONG ServiceTableBase;//SSTD基地址
  6. PULONG Count;               //包含着 SSDT 中每个服务被调用次数的计数器。这个计数器一般由sysenter 更新
  7. ULONG TableSize;            //由 ServiceTableBase 描述的服务的数目
  8. PUCHAR ArgumentTable;       //包含每个系统服务参数字节数表的基地址-系统服务参数表 每个表项是一个UCHAR,表示一个函数参数长度
  9. } KSERVICE_TABLE_DESCRIPTOR, *PKSERVICE_TABLE_DESCRIPTOR;
  10. //ssdt表已经导出了,这里例行公事下
  11. extern PKSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable;
  12. KSERVICE_TABLE_DESCRIPTOR ssdt_copy;
  13. ULONG NewSsdtServiceTableBase[1024] = {0};
  14. UCHAR NewSsdtServiceTableNumber[1024] = {0};
  15. NTSTATUS
  16. IoSystemControl(IN ULONG ControlCode,
  17. IN PVOID InputBuffer OPTIONAL,
  18. IN ULONG InputBufferLength,
  19. OUT PVOID OutputBuffer OPTIONAL,
  20. IN ULONG OutputBufferLength,
  21. OUT PULONG ReturnLength OPTIONAL
  22. )
  23. {
  24. NTSTATUS Status = STATUS_SUCCESS;
  25. if (OutputBuffer&&MmIsAddressValid(OutputBuffer))
  26. {
  27. KdPrint(("%s\r\n",InputBuffer));
  28. memset(OutputBuffer, 0x41, OutputBufferLength);//传出buf变为AAAAA...
  29. if (ReturnLength&& MmIsAddressValid(ReturnLength))
  30. {
  31. *ReturnLength = 10; //传出size随便设置为10
  32. }
  33. }
  34. return Status;
  35. }
  36. void  NtosAddSsdtServiceTable(
  37. PVOID NewFunction,
  38. ULONG NewNumber
  39. )
  40. {
  41. NTSTATUS Status = STATUS_SUCCESS;
  42. PEPROCESS Process;
  43. //禁止写保护,不然蓝屏
  44. __asm
  45. {
  46. MOV EAX, CR0;
  47. OR  EAX, 10000H;
  48. MOV CR0, EAX;
  49. STI;
  50. }
  51. //复制原始服务表
  52. //把原始表复制到我们的数组
  53. memcpy(
  54. NewSsdtServiceTableBase,
  55. KeServiceDescriptorTable->ServiceTableBase,
  56. KeServiceDescriptorTable->TableSize * 4
  57. );
  58. //原始函数个数
  59. memcpy(
  60. NewSsdtServiceTableNumber,
  61. KeServiceDescriptorTable->ArgumentTable,
  62. KeServiceDescriptorTable->TableSize
  63. );
  64. //修改SSDT表添加服务函数
  65. NewSsdtServiceTableBase[ssdt_copy.TableSize] = NewFunction;
  66. NewSsdtServiceTableNumber[ssdt_copy.TableSize] = NewNumber;
  67. //更新内存里面导出 KeServiceDescriptorTable Ssdt 表
  68. KeServiceDescriptorTable->ServiceTableBase = NewSsdtServiceTableBase;
  69. KeServiceDescriptorTable->ArgumentTable = NewSsdtServiceTableNumber;
  70. KeServiceDescriptorTable->TableSize = ssdt_copy.TableSize + 1;
  71. //恢复写保护
  72. __asm
  73. {
  74. MOV EAX, CR0;
  75. OR  EAX, 10000H;
  76. MOV CR0, EAX;
  77. STI;
  78. }
  79. }
  80. VOID DDKUnload (IN PDRIVER_OBJECT pDriverObject)
  81. {
  82. KdPrint(("[DDKUnload]-start\n"));
  83. //恢复原始的
  84. KeServiceDescriptorTable->ServiceTableBase = ssdt_copy.ServiceTableBase;
  85. KeServiceDescriptorTable->Count = ssdt_copy.Count;
  86. KeServiceDescriptorTable->TableSize = ssdt_copy.TableSize;
  87. KeServiceDescriptorTable->ArgumentTable = ssdt_copy.ArgumentTable;
  88. KdPrint(("[DDKUnload]-end\n"));
  89. }
  90. NTSTATUS DriverEntry (IN PDRIVER_OBJECT pDriverObject,
  91. IN PUNICODE_STRING pRegistryPath)
  92. {
  93. KdPrint(("[DriverEntry]-start\n"));
  94. pDriverObject->DriverUnload = DDKUnload;
  95. // 保存原始的
  96. ssdt_copy.ServiceTableBase = KeServiceDescriptorTable->ServiceTableBase;
  97. ssdt_copy.Count = KeServiceDescriptorTable->Count;
  98. ssdt_copy.TableSize = KeServiceDescriptorTable->TableSize;
  99. ssdt_copy.ArgumentTable = KeServiceDescriptorTable->ArgumentTable;
  100. //我们调用自定义函数,往SSDT表添加内存
  101. NtosAddSsdtServiceTable(IoSystemControl, 24);
  102. KdPrint(("[DriverEntry]-end\n"));
  103. return STATUS_SUCCESS;
  104. }

在驱动加载后,可以看到:

运行ring3小程序,可以看到outbuf为AAAAA..,大小为10:

时间: 2024-11-06 03:53:29

ring0-新建SSDT项进行通讯(随手代码)的相关文章

webDAV服务的开启以及客户端的上传、下载、删除、新建文件夾、列表的代码(C#)

windows server 2003开启webDAV服务 1. 启动“IIS管理器”选择“WEB服务扩展”,选择“WEBDAV”的允许按钮启动WEBDAV功能 2.建立一个虚拟目录,对应到一个本地目录. 3.启动系统“服务”中的“WebClient”服务 参考网址 WebDAV文档rfc2518    http://www.ietf.org/rfc/rfc2518.txt webdav常用方法和概念总结   http://blog.csdn.net/mahongming/archive/200

Office 2016 - 下载、安装、激活后,右键新建菜单中,出现 Micorosoft Excel 97-2003 工作表,而不是 Micorosoft Excel 工作表、以及对新建菜单项位置做调整

安装激活 Office 2016 后,新建菜单项如下: 首先,需要做的是把右键新建菜单项中的 Micorosoft Excel 09-2003 工作表去除(保存格式是 .xls),替换为 Micorosoft Excel 工作表(Excel 2016 的默认格式 .xlsx) 其次,对新建菜单项的排列顺序做调整,额,把 Micorosoft Excel 工作表 移至 Micorosoft Word 文档下面. 调整后样式:

串口通讯的代码 。是别人写的 我加了些注释。

// Communication.h: interface for the CCommunication class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_COMMUNICATION_H__6CA00576_F088_11D1_89BB_8311A0F2733D__INCLUDED_) #define AFX_COMMUNICATION_H__6CA0

极盗者-带你领略八项极限挑战(含代码)

<!-- HTML代码片段中请勿添加<body>标签 //--><div id="container"> </div> <!-- 推荐开源CDN来选取需引用的外部JS //--><script type="text/javascript" src="http://cdn.gbtags.com/jquery/1.11.1/jquery.min.js"></script&g

新建android项目报错,代码中找不到错误

通过网上资料的引导,做以下操作: 1.进入C:\Documents and Settings\Administrator\.android 删除路径下的debug.keystore及 ddms.cfg(我只删除了debug.kestore也可以.网上说两个都删除).(不同环境下的目录可能略有不同,可在eclipse中查找此路径:Window->Preferences->Android->Build下 Default debug keystore)2.进入eclipse,project 

eclipse新建python项Project interpreter not specified

安装好pydev后新建python项目时提示”Project interpreter not specified“的错误,这是因为没有导入python开发环境所致 解决方法如下:1.找到eclipse---->window----->freference.找到左侧栏边得pydev,展开,点击Interpreter-Python.2.在右侧找到New,名字可以不命名,找到python安装路径,我的是c:\python26.然后点击ok,等待导入完成,即可新建python项目

之前的Android项目报错,新建Android项目报错,代码中找不到错误解决方案

打开一年前的东西,结果发现里面的android项目全部有个红叉,也找不到错误.新建一个项目也报错,首先确定自己的环境应该没问题,然后通过查看网上的资料,发现可能是debug的keystore到期啦. 通过网上资料的引导,做以下操作: 1.进入C:\Documents and Settings\Administrator\.android 删除路径下的debug.keystore及 ddms.cfg(我只删除了debug.kestore也可以.网上说两个都删除).(不同环境下的目录可能略有不同,可

ring0-内存可读、可写、有效性、指针是否为空、深度校验字符串(随手代码)

http://blog.csdn.net/hgy413/article/details/7907057 1.如在ring3下,则要判断是否可读可写: [cpp] view plaincopy KPROCESSOR_MODE PreviousMode; ULONG PID; PreviousMode = ExGetPreviousMode(); // 如果非内核模式,就要开始检查IN的这些参数都否可读 if (PreviousMode != KernelMode) { try { ProbeFor

PHP 及时通讯机制代码

php实现实时通信一般有两种方式:socket或comet.socket是比较好的解决方案,问题在于不是所有的浏览器都兼容,服务器端实现起来也稍微有点麻烦. <?php // NovComet.php class NovComet { const COMET_OK = 0; const COMET_CHANGED = 1; private $_tries; private $_var; private $_sleep; private $_ids = array(); private $_cal