宝峰科技

 找回密码
 注册

QQ登录

只需一步,快速开始

智能终端设备维修查询系统注册会员邮箱认证须知!
查看: 1987|回复: 0

[转载] RING0 与 RING3之间的简单交互

[复制链接]
  • TA的每日心情
    开心
    2024-12-9 18:45
  • 签到天数: 124 天

    [LV.7]常住居民III

    admin 发表于 2009-12-12 23:14:27 | 显示全部楼层 |阅读模式

    欢迎您注册加入!这里有您将更精采!

    您需要 登录 才可以下载或查看,没有账号?注册

    x
    恩...记下笔记...算入门吧...根本没什么时间玩这个...学习真是麻烦
                一开始没怎么看事例,自己想当然的写了一个 发现问题一大堆...上周就纠结与一些内核模式中很恶心的弱智问题,列举一下以祭奠我已逝的青春.....
    2008.5.1      
    1.当初我就没学C...直接C++...现在用纯C的时候就2了...编译之后错误100+ 我竟然不知道c不能这样:
          int i = 5; //wrong
    2.SSDT HOOK时,一开始NtOpenProcess的地址搞错了...运行之后一开icesword就BSOD 后来用kd反汇编发现ClientId赋值的时候蓝屏的,恍然发现我把NtOpenProcess的索引号看错了...hook成别的函数了 晕......
    2008.5.10
    3.尝试ring3 ring0交互,结果问题更多...蓝屏——虚拟机崩溃(虚拟机完蛋了 可虚拟机里面的系统还没事........就是告诉我要CPU硬件重置...要是真机我不心疼死.....)——重装虚拟机——蓝屏——.....原因就不列举了
    ===============================分割你=======================================

    RING0 RING3之间的简单交互


             叫简单交互的原因是,只从ring3传给ring0一个变量的值,不涉及到锁事件的问题(有点像多线程的那个东东...)。这里我使用了最简单的例子,就是SSDT HOOK NtOpenProcess. ring3的应用程序将自己的PID传给ring0的驱动,驱动hook NtOpenProcess之后就无法从任务管理器终止应用程序了。
             加载驱动的方式用的是SCM....而且是《windows程序设计里》封装之后的CDRIVER类...(我承认我有点懒了....以后在用ZWLoadDriver 或者别的什么 rootkit.com里面有篇文章讲了好多种...)
    ==============================kernel mode,FIRSTDRIVER.C========================

    1. /////////////////////////////////////////////////
    2. // SSDT NtOpenProcess,
    3. //FIRSTDRIVER.C
    4. //2008年5月10日
    5. #include <ntddk.h>
    6. #include <stdlib.h>
    7. #include "IoCTL.h"
    8. // 自定义函数的声明
    9. NTSTATUS DispatchCreateClose(PDEVICE_OBJECT pDevObj, PIRP pIrp);
    10. void DriverUnload(PDRIVER_OBJECT pDriverObj);
    11. NTSTATUS DispatchIoctl(PDEVICE_OBJECT pDevObj, PIRP pIrp);

    12. VOID Hook();
    13. VOID UnHook();
    14. // 驱动内部名称和符号连接名称
    15. #define DEVICE_NAME L"\\Device\\devDriverDemo"
    16. #define LINK_NAME L"\\??\\slDriverDemo"
    17. ULONG    g_uRealServiceAddress;    //真实函数地址
    18. ULONG    g_uPID;                        //把PID传进来

    19. typedef struct _SystemServiceDescriptorTable
    20. {
    21. PVOID    ServiceTableBase;
    22. PULONG    ServiceCounterTableBase;
    23. ULONG    NumberOfService;
    24. ULONG    ParamTableBase;
    25. }SystemServiceDescriptorTable,*PSystemServiceDescriptorTable;
    26. // KeServiceDescriptorTable为ntoskrnl.exe导出
    27. extern    PSystemServiceDescriptorTable    KeServiceDescriptorTable;

    28. // 定义NtOpenProcess
    29. typedef    NTSTATUS    (__stdcall *NTOPENPROCESS)( OUT PHANDLE ProcessHandle,

    30.               IN ACCESS_MASK AccessMask,

    31.               IN POBJECT_ATTRIBUTES ObjectAttributes,

    32.               IN PCLIENT_ID ClientId

    33.               );

    34. NTOPENPROCESS   RealNtOpenProcess;   //原来的函数


    35. // 自定义的NtOpenProcess函数
    36. NTSTATUS __stdcall MyNtOpenProcess( OUT    PHANDLE ProcessHandle,
    37.            IN    ACCESS_MASK DesiredAccess,
    38.            IN    POBJECT_ATTRIBUTES ObjectAttributes,
    39.            IN    PCLIENT_ID ClientId )
    40. {
    41. NTSTATUS nt;
    42. ULONG uPID;
    43. nt=(NTSTATUS)(NTOPENPROCESS)RealNtOpenProcess(ProcessHandle,DesiredAccess,ObjectAttributes,ClientId);
    44. if((ClientId!=NULL))
    45. {
    46.    uPID=(ULONG)ClientId->UniqueProcess;
    47.    if (uPID==g_uPID)
    48.    {
    49.     DbgPrint("PID:%u is hooked",uPID);
    50.     ProcessHandle=NULL;
    51.     nt=STATUS_ACCESS_DENIED;
    52.    }
    53. }
    54. return nt;
    55. }

    56. // 驱动程序加载时调用DriverEntry例程
    57. NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryString)
    58. {
    59. ////////////////初始化动作////////////////////////////////
    60. NTSTATUS status;
    61. UNICODE_STRING ustrDevName;
    62. UNICODE_STRING ustrLinkName;
    63. PDEVICE_OBJECT pDevObj;
    64. g_uPID = 0;
    65. status = STATUS_SUCCESS;
    66. // 初始化各个派遣例程
    67. pDriverObj->MajorFunction[IRP_MJ_CREATE] = DispatchCreateClose;
    68. pDriverObj->MajorFunction[IRP_MJ_CLOSE] = DispatchCreateClose;
    69. pDriverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL]=DispatchIoctl;
    70. pDriverObj->DriverUnload = DriverUnload ;
    71. // 创建、初始化设备对象
    72. // 设备名称
    73. RtlInitUnicodeString(&ustrDevName, DEVICE_NAME);
    74. // 创建设备对象
    75. status = IoCreateDevice(pDriverObj,
    76.    0,
    77.    &ustrDevName,
    78.    FILE_DEVICE_UNKNOWN,
    79.    0,
    80.    FALSE,
    81.    &pDevObj);
    82. if(!NT_SUCCESS(status))
    83. {
    84.    return status;
    85. }
    86. // 创建符号连接名称
    87. // 符号连接名称
    88. RtlInitUnicodeString(&ustrLinkName, LINK_NAME);
    89. // 创建关联
    90. status = IoCreateSymbolicLink(&ustrLinkName, &ustrDevName);
    91. if(!NT_SUCCESS(status))
    92. {
    93.    IoDeleteDevice(pDevObj);
    94.    return status;
    95. }
    96. ////////////////////////初始化完毕////////////////////////////////////////
    97. Hook();
    98. return STATUS_SUCCESS;
    99. }

    100. // I/O控制派遣例程
    101. NTSTATUS DispatchIoctl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
    102. {
    103. ///////////////////////DispatchIoctl///////////////////////////////
    104. NTSTATUS IoCtlNtstus;
    105. PIO_STACK_LOCATION pIRPStack;
    106. ULONG uIoControlCode;
    107. PVOID pIoBuffer;
    108. ULONG uInSize;
    109. ULONG uOutSize ;
    110. //假设失败
    111. IoCtlNtstus = STATUS_INVALID_DEVICE_REQUEST;
    112. //IRP堆栈
    113. pIRPStack = IoGetCurrentIrpStackLocation(pIrp);
    114. //控制代码
    115. uIoControlCode = pIRPStack->Parameters.DeviceIoControl.IoControlCode;
    116. uInSize = pIRPStack->Parameters.DeviceIoControl.InputBufferLength;
    117. uOutSize = pIRPStack->Parameters.DeviceIoControl.OutputBufferLength;
    118. //
    119. pIoBuffer= pIrp-> AssociatedIrp.SystemBuffer;

    120. switch(uIoControlCode)
    121. {
    122. case IO_PID_CTL:
    123.    {
    124.     DbgPrint("the PID is %s",pIoBuffer);
    125.     g_uPID = atol(pIoBuffer);
    126.     DbgPrint("the PID is %u",g_uPID);
    127.    }
    128.    break;
    129. default:
    130.    break;
    131. }
    132. //完成请求
    133. if(IoCtlNtstus == STATUS_SUCCESS)
    134.    pIrp->IoStatus.Information = uOutSize;
    135. else
    136.    pIrp->IoStatus.Information = 0;

    137. // 完成请求

    138. pIrp->IoStatus.Status = IoCtlNtstus;
    139. IoCompleteRequest(pIrp, IO_NO_INCREMENT);
    140. return IoCtlNtstus;
    141. }

    142. void DriverUnload(PDRIVER_OBJECT pDriverObj)
    143. {

    144. UNICODE_STRING strLink;
    145. /////收尾工作 /////////////////////////////////
    146. UnHook();
    147. DbgPrint("unload");
    148. // 删除符号连接名称
    149. RtlInitUnicodeString(&strLink, LINK_NAME);
    150. IoDeleteSymbolicLink(&strLink);
    151. // 删除设备对象
    152. IoDeleteDevice(pDriverObj->DeviceObject);
    153. }
    154. // 处理IRP_MJ_CREATE、IRP_MJ_CLOSE功能代码
    155. NTSTATUS DispatchCreateClose(PDEVICE_OBJECT pDevObj, PIRP pIrp)
    156. {
    157. pIrp->IoStatus.Status = STATUS_SUCCESS;
    158. // 完成此请求

    159. IoCompleteRequest(pIrp, IO_NO_INCREMENT);
    160. return STATUS_SUCCESS;
    161. }
    162. VOID Hook()
    163. {
    164. ULONG uAddr;
    165. DbgPrint("hook");
    166. //得到NtOpenProcess的地址
    167. uAddr=(ULONG)KeServiceDescriptorTable->ServiceTableBase +0x7A*4;
    168. g_uRealServiceAddress = *(ULONG*)uAddr;
    169. //记录真实地址一会儿用
    170. RealNtOpenProcess= (NTOPENPROCESS)g_uRealServiceAddress;
    171. DbgPrint( "Address of Real NtOpenProcess: 0x%08X\n", g_uRealServiceAddress );
    172. DbgPrint(" Address of MyNtOpenProcess: 0x%08X\n", MyNtOpenProcess );
    173. //取消内存保护
    174. __asm
    175. {
    176.    cli
    177.     mov    eax, cr0
    178.     and    eax, not 10000h
    179.     mov    cr0, eax
    180. }
    181. //NND....废了这么大劲其实就为了这一句
    182. *((ULONG*)uAddr)=(ULONG)MyNtOpenProcess;
    183. //回复内存
    184. __asm
    185. {
    186.    mov    eax, cr0
    187.     or    eax, 10000h
    188.     mov    cr0, eax
    189.     sti
    190. }
    191. }
    192. VOID UnHook()
    193. {
    194. ULONG uUnhookAddr;
    195. //得到NtOpenProcess的地址
    196. uUnhookAddr=(ULONG)KeServiceDescriptorTable->ServiceTableBase +0x7A*4;
    197. //取消内存保护
    198. __asm
    199. {
    200.    cli
    201.     mov    eax, cr0
    202.     and    eax, not 10000h
    203.     mov    cr0, eax
    204. }
    205. //NND....废了这么大劲其实就为了这一句
    206. *((ULONG*)uUnhookAddr)=(ULONG)g_uRealServiceAddress;
    207. //回复内存
    208. __asm
    209. {
    210.    mov    eax, cr0
    211.     or    eax, 10000h
    212.     mov    cr0, eax
    213.     sti
    214. }
    215. }
    216. =============================kernel mode,IoCTL.h ==========================  
    217. // IoCTL.h         
    218. #define IO_PID_CTL \
    219. CTL_CODE(FILE_DEVICE_UNKNOWN, 0x810, METHOD_BUFFERED, FILE_ANY_ACCESS)      
    220. =============================user mode,Demo.cpp===========================     
    221. #include "stdafx.h"
    222. #include <Windows.h>
    223. #include <stdlib.h>
    224. #include <winioctl.h>
    225. #include "IoCTL.h"               //和驱动里面的一样
    226. #include "driver.h"
    227. int main(int argc, CHAR* argv[])
    228. {
    229. printf("****************************************************\n");
    230. printf("                  用户模式交互程序                  \n\n");
    231. printf("                  By Returns                            \n");
    232. printf("****************************************************\n\n");
    233. DWORD dwPID = GetCurrentProcessId();

    234. printf("my pid is %u \n",dwPID);
    235. char szAppPath[256];
    236. char * p;

    237. GetFullPathName("FIRSTDRIVER.sys",256,szAppPath,&p);
    238. CDriver DriverCon(szAppPath,"slDriverDemo");
    239. if (DriverCon.StartDriver())
    240. {
    241.    printf("The Driver is started successfully \n");
    242.    if (DriverCon.OpenDevice())
    243.    {
    244.     char strOut[256],strInput[4];
    245.     ltoa(dwPID,strInput,10);
    246.     printf("the handle is open...%s \n",strInput);
    247.     if (DriverCon.IoControl(IO_PID_CTL,&strInput,4,&strOut,256)!=-1)
    248.     {
    249.      printf("返回信息: %x \n",&strOut);
    250.     }
    251.    }
    252. }
    253. system("pause");

    254. return 0;
    255. }
    复制代码
    用户模式中的 Dirver.h 是CDriver类的封装 简化了SCM的操作...引自《windows程序设计》
    下载地址: Dirver.h

    效果是这样的.....返回的信息是有点bug的...懒得改了...要想传多个PID用数组就可以了...我也懒得改了..
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    免责声明

    本站中所有被研究的素材与信息全部来源于互联网,版权争议与本站无关。本站所发布的任何软件编程开发或软件的逆向分析文章、逆向分析视频、补丁、注册机和注册信息,仅限用于学习和研究软件安全的目的。全体用户必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。学习编程开发技术或逆向分析技术是为了更好的完善软件可能存在的不安全因素,提升软件安全意识。所以您如果喜欢某程序,请购买注册正版软件,获得正版优质服务!不得将上述内容私自传播、销售或者用于商业用途!否则,一切后果请用户自负!

    QQ|Archiver|手机版|小黑屋|联系我们|宝峰科技 ( 滇公网安备 53050202000040号 | 滇ICP备09007156号-2 )

    Copyright © 2001-2023 Discuz! Team. GMT+8, 2025-5-8 13:39 , File On Powered by Discuz! X3.49

    快速回复 返回顶部 返回列表