码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2015-09-26 08:06:40      阅读:224      评论:0      收藏:0      [点我收藏+]

标签:

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.    
  9.    
  10. ntdll!KiFastSystemCall:  
  11. 7c92e4f0 8bd4           mov  edx,esp  
  12. 7c92e4f2 0f34           sysenter  

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

 

 

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

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.    
  11. //ssdt表已经导出了,这里例行公事下  
  12. extern PKSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable;  
  13. KSERVICE_TABLE_DESCRIPTOR ssdt_copy;  
  14. ULONG NewSsdtServiceTableBase[1024] = {0};  
  15. UCHAR NewSsdtServiceTableNumber[1024] = {0};  
  16.    
  17. NTSTATUS  
  18. IoSystemControl(IN ULONG ControlCode,  
  19.                      IN PVOID InputBuffer OPTIONAL,  
  20.                      IN ULONG InputBufferLength,  
  21.                      OUT PVOID OutputBuffer OPTIONAL,  
  22.                      IN ULONG OutputBufferLength,  
  23.                      OUT PULONG ReturnLength OPTIONAL  
  24.                      )  
  25. {  
  26.     NTSTATUS Status = STATUS_SUCCESS;  
  27.    
  28.     if (OutputBuffer&&MmIsAddressValid(OutputBuffer))  
  29.     {  
  30.         KdPrint(("%s\r\n",InputBuffer));  
  31.         memset(OutputBuffer, 0x41, OutputBufferLength);//传出buf变为AAAAA...  
  32.         if (ReturnLength&& MmIsAddressValid(ReturnLength))  
  33.         {  
  34.             *ReturnLength = 10; //传出size随便设置为10  
  35.         }  
  36.     }  
  37.     return Status;  
  38. }  
  39.    
  40.    
  41. void  NtosAddSsdtServiceTable(  
  42.                               PVOID NewFunction,  
  43.                               ULONG NewNumber  
  44.                               )  
  45. {  
  46.     NTSTATUS Status = STATUS_SUCCESS;  
  47.     PEPROCESS Process;  
  48.    
  49.     //禁止写保护,不然蓝屏  
  50.     __asm  
  51.     {  
  52.         MOV EAX, CR0;  
  53.         OR  EAX, 10000H;  
  54.         MOV CR0, EAX;  
  55.         STI;  
  56.     }  
  57.    
  58.     //复制原始服务表  
  59.     //把原始表复制到我们的数组  
  60.     memcpy(  
  61.         NewSsdtServiceTableBase,  
  62.         KeServiceDescriptorTable->ServiceTableBase,  
  63.         KeServiceDescriptorTable->TableSize * 4  
  64.         );  
  65.    
  66.     //原始函数个数  
  67.     memcpy(  
  68.         NewSsdtServiceTableNumber,  
  69.         KeServiceDescriptorTable->ArgumentTable,  
  70.         KeServiceDescriptorTable->TableSize  
  71.         );  
  72.    
  73.     //修改SSDT表添加服务函数  
  74.     NewSsdtServiceTableBase[ssdt_copy.TableSize] = NewFunction;  
  75.     NewSsdtServiceTableNumber[ssdt_copy.TableSize] = NewNumber;  
  76.    
  77.     //更新内存里面导出 KeServiceDescriptorTable Ssdt 表  
  78.     KeServiceDescriptorTable->ServiceTableBase = NewSsdtServiceTableBase;  
  79.     KeServiceDescriptorTable->ArgumentTable = NewSsdtServiceTableNumber;  
  80.     KeServiceDescriptorTable->TableSize = ssdt_copy.TableSize + 1;  
  81.    
  82.     //恢复写保护  
  83.     __asm  
  84.     {  
  85.         MOV EAX, CR0;  
  86.         OR  EAX, 10000H;  
  87.         MOV CR0, EAX;  
  88.         STI;  
  89.     }  
  90. }  
  91.    
  92. VOID DDKUnload (IN PDRIVER_OBJECT pDriverObject)  
  93. {  
  94.     KdPrint(("[DDKUnload]-start\n"));  
  95.    
  96.     //恢复原始的  
  97.     KeServiceDescriptorTable->ServiceTableBase = ssdt_copy.ServiceTableBase;  
  98.     KeServiceDescriptorTable->Count = ssdt_copy.Count;  
  99.     KeServiceDescriptorTable->TableSize = ssdt_copy.TableSize;  
  100.     KeServiceDescriptorTable->ArgumentTable = ssdt_copy.ArgumentTable;  
  101.    
  102.     KdPrint(("[DDKUnload]-end\n"));  
  103. }  
  104.    
  105. NTSTATUS DriverEntry (IN PDRIVER_OBJECT pDriverObject,  
  106.                       IN PUNICODE_STRING pRegistryPath)  
  107. {  
  108.     KdPrint(("[DriverEntry]-start\n"));  
  109.     pDriverObject->DriverUnload = DDKUnload;  
  110.    
  111.     // 保存原始的  
  112.     ssdt_copy.ServiceTableBase = KeServiceDescriptorTable->ServiceTableBase;  
  113.     ssdt_copy.Count = KeServiceDescriptorTable->Count;  
  114.     ssdt_copy.TableSize = KeServiceDescriptorTable->TableSize;  
  115.     ssdt_copy.ArgumentTable = KeServiceDescriptorTable->ArgumentTable;  
  116.    
  117.     //我们调用自定义函数,往SSDT表添加内存  
  118.     NtosAddSsdtServiceTable(IoSystemControl, 24);  
  119.    
  120.     KdPrint(("[DriverEntry]-end\n"));  
  121.     return STATUS_SUCCESS;  
  122. }  

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

 

技术分享

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

技术分享



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

标签:

原文地址:http://www.cnblogs.com/gamekk/p/4839937.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!