【笔记】RING0 与 RING3之间的简单交互

2023-12-03 00:38

本文主要是介绍【笔记】RING0 与 RING3之间的简单交互,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

RING0 与 RING3之间的简单交互

         叫简单交互的原因是,只从ring3传给ring0一个变量的值,不涉及到锁事件的问题(有点像多线程的那个东东...)。这里我使用了最简单的例子,就是SSDT HOOK NtOpenProcess. ring3的应用程序将自己的PID传给ring0的驱动,驱动hook NtOpenProcess之后就无法从任务管理器终止应用程序了。

         加载驱动的方式用的是SCM....而且是《windows程序设计里》封装之后的CDRIVER类...(我承认我有点懒了....以后在用ZWLoadDriver 或者别的什么 rootkit.com里面有篇文章讲了好多种...)


/
// SSDT NtOpenProcess,
//FIRSTDRIVER.C 
//2008年5月10日
#include <ntddk.h>
#include <stdlib.h>
#include "IoCTL.h"
// 自定义函数的声明
NTSTATUS DispatchCreateClose(PDEVICE_OBJECT pDevObj, PIRP pIrp);
void DriverUnload(PDRIVER_OBJECT pDriverObj);
NTSTATUS DispatchIoctl(PDEVICE_OBJECT pDevObj, PIRP pIrp);VOID Hook();
VOID UnHook();
// 驱动内部名称和符号连接名称
#define DEVICE_NAME L"\\Device\\devDriverDemo"
#define LINK_NAME L"\\??\\slDriverDemo"
ULONG    g_uRealServiceAddress;    //真实函数地址
ULONG    g_uPID;                        //把PID传进来typedef struct _SystemServiceDescriptorTable 
{ 
PVOID    ServiceTableBase; 
PULONG    ServiceCounterTableBase; 
ULONG    NumberOfService; 
ULONG    ParamTableBase; 
}SystemServiceDescriptorTable,*PSystemServiceDescriptorTable;
// KeServiceDescriptorTable为ntoskrnl.exe导出 
extern    PSystemServiceDescriptorTable    KeServiceDescriptorTable;// 定义NtOpenProcess
typedef    NTSTATUS    (__stdcall *NTOPENPROCESS)( OUT PHANDLE ProcessHandle,IN ACCESS_MASK AccessMask,IN POBJECT_ATTRIBUTES ObjectAttributes,IN PCLIENT_ID ClientId);NTOPENPROCESS   RealNtOpenProcess;   //原来的函数
// 自定义的NtOpenProcess函数 
NTSTATUS __stdcall MyNtOpenProcess( OUT    PHANDLE ProcessHandle, IN    ACCESS_MASK DesiredAccess, IN    POBJECT_ATTRIBUTES ObjectAttributes, IN    PCLIENT_ID ClientId )
{
NTSTATUS nt;
ULONG uPID;
nt=(NTSTATUS)(NTOPENPROCESS)RealNtOpenProcess(ProcessHandle,DesiredAccess,ObjectAttributes,ClientId);
if((ClientId!=NULL))
{uPID=(ULONG)ClientId->UniqueProcess;if (uPID==g_uPID){DbgPrint("PID:%u is hooked",uPID);ProcessHandle=NULL;nt=STATUS_ACCESS_DENIED;}
}
return nt;
}
// 驱动程序加载时调用DriverEntry例程
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryString)
{
初始化动作
NTSTATUS status;
UNICODE_STRING ustrDevName;
UNICODE_STRING ustrLinkName;
PDEVICE_OBJECT pDevObj;
g_uPID = 0;
status = STATUS_SUCCESS;
// 初始化各个派遣例程
pDriverObj->MajorFunction[IRP_MJ_CREATE] = DispatchCreateClose;
pDriverObj->MajorFunction[IRP_MJ_CLOSE] = DispatchCreateClose;
pDriverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL]=DispatchIoctl;
pDriverObj->DriverUnload = DriverUnload ;
// 创建、初始化设备对象
// 设备名称
RtlInitUnicodeString(&ustrDevName, DEVICE_NAME);
// 创建设备对象
status = IoCreateDevice(pDriverObj, 0,&ustrDevName, FILE_DEVICE_UNKNOWN,0,FALSE,&pDevObj);
if(!NT_SUCCESS(status))
{return status;
}
// 创建符号连接名称
// 符号连接名称
RtlInitUnicodeString(&ustrLinkName, LINK_NAME);
// 创建关联
status = IoCreateSymbolicLink(&ustrLinkName, &ustrDevName); 
if(!NT_SUCCESS(status))
{IoDeleteDevice(pDevObj); return status;
}
初始化完毕
Hook();
return STATUS_SUCCESS;
}
// I/O控制派遣例程
NTSTATUS DispatchIoctl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
///DispatchIoctl///
NTSTATUS IoCtlNtstus;
PIO_STACK_LOCATION pIRPStack;
ULONG uIoControlCode;
PVOID pIoBuffer;
ULONG uInSize;
ULONG uOutSize ;
//假设失败
IoCtlNtstus = STATUS_INVALID_DEVICE_REQUEST;
//IRP堆栈
pIRPStack = IoGetCurrentIrpStackLocation(pIrp);
//控制代码
uIoControlCode = pIRPStack->Parameters.DeviceIoControl.IoControlCode;
uInSize = pIRPStack->Parameters.DeviceIoControl.InputBufferLength;
uOutSize = pIRPStack->Parameters.DeviceIoControl.OutputBufferLength;
//
pIoBuffer= pIrp-> AssociatedIrp.SystemBuffer;switch(uIoControlCode)
{
case IO_PID_CTL:{DbgPrint("the PID is %s",pIoBuffer);g_uPID = atol(pIoBuffer);DbgPrint("the PID is %u",g_uPID);}break;
default:break;
}
//完成请求
if(IoCtlNtstus == STATUS_SUCCESS)pIrp->IoStatus.Information = uOutSize;
elsepIrp->IoStatus.Information = 0;// 完成请求pIrp->IoStatus.Status = IoCtlNtstus;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return IoCtlNtstus;
}void DriverUnload(PDRIVER_OBJECT pDriverObj)
{UNICODE_STRING strLink;
/收尾工作 /
UnHook();
DbgPrint("unload");
// 删除符号连接名称
RtlInitUnicodeString(&strLink, LINK_NAME);
IoDeleteSymbolicLink(&strLink);
// 删除设备对象
IoDeleteDevice(pDriverObj->DeviceObject);
}
// 处理IRP_MJ_CREATE、IRP_MJ_CLOSE功能代码
NTSTATUS DispatchCreateClose(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
pIrp->IoStatus.Status = STATUS_SUCCESS;
// 完成此请求IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
VOID Hook()
{
ULONG uAddr;
DbgPrint("hook");
//得到NtOpenProcess的地址
uAddr=(ULONG)KeServiceDescriptorTable->ServiceTableBase +0x7A*4;
g_uRealServiceAddress = *(ULONG*)uAddr;
//记录真实地址一会儿用
RealNtOpenProcess= (NTOPENPROCESS)g_uRealServiceAddress;
DbgPrint( "Address of Real NtOpenProcess: 0x%08X\n", g_uRealServiceAddress );
DbgPrint(" Address of MyNtOpenProcess: 0x%08X\n", MyNtOpenProcess );
//取消内存保护
__asm 
{ cli mov    eax, cr0 and    eax, not 10000h mov    cr0, eax 
}
//NND....废了这么大劲其实就为了这一句
*((ULONG*)uAddr)=(ULONG)MyNtOpenProcess;
//回复内存
__asm 
{ mov    eax, cr0 or    eax, 10000h mov    cr0, eax sti 
} 
}
VOID UnHook()
{
ULONG uUnhookAddr;
//得到NtOpenProcess的地址
uUnhookAddr=(ULONG)KeServiceDescriptorTable->ServiceTableBase +0x7A*4;
//取消内存保护
__asm 
{ cli mov    eax, cr0 and    eax, not 10000h mov    cr0, eax 
}
//NND....废了这么大劲其实就为了这一句
*((ULONG*)uUnhookAddr)=(ULONG)g_uRealServiceAddress;
//回复内存
__asm 
{ mov    eax, cr0 or    eax, 10000h mov    cr0, eax sti 
} 
}
=============================kernel mode,IoCTL.h ==========================  
// IoCTL.h         
#define IO_PID_CTL \
CTL_CODE(FILE_DEVICE_UNKNOWN, 0x810, METHOD_BUFFERED, FILE_ANY_ACCESS)      
=============================user mode,Demo.cpp===========================     
#include "stdafx.h"
#include <Windows.h>
#include <stdlib.h>
#include <winioctl.h>
#include "IoCTL.h"               //和驱动里面的一样
#include "driver.h"
int main(int argc, CHAR* argv[])
{
printf("****************************************************\n");
printf("                  用户模式交互程序                  \n\n");
printf("                  By Returns                            \n");
printf("****************************************************\n\n");
DWORD dwPID = GetCurrentProcessId();printf("my pid is %u \n",dwPID);
char szAppPath[256];
char * p;GetFullPathName("FIRSTDRIVER.sys",256,szAppPath,&p);
CDriver DriverCon(szAppPath,"slDriverDemo");
if (DriverCon.StartDriver())
{printf("The Driver is started successfully \n");if (DriverCon.OpenDevice()){char strOut[256],strInput[4];ltoa(dwPID,strInput,10);printf("the handle is open...%s \n",strInput);if (DriverCon.IoControl(IO_PID_CTL,&strInput,4,&strOut,256)!=-1){printf("返回信息: %x \n",&strOut);}}
}
system("pause");return 0;
}

用户模式中的 Dirver.h 是CDriver类的封装 简化了SCM的操作...引自《windows程序设计》


效果是这样的.....返回的信息是有点bug的...懒得改了...要想传多个PID用数组就可以了...我也懒得改了..



这篇关于【笔记】RING0 与 RING3之间的简单交互的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/447458

相关文章

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

hdu2289(简单二分)

虽说是简单二分,但是我还是wa死了  题意:已知圆台的体积,求高度 首先要知道圆台体积怎么求:设上下底的半径分别为r1,r2,高为h,V = PI*(r1*r1+r1*r2+r2*r2)*h/3 然后以h进行二分 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#includ

usaco 1.3 Prime Cryptarithm(简单哈希表暴搜剪枝)

思路: 1. 用一个 hash[ ] 数组存放输入的数字,令 hash[ tmp ]=1 。 2. 一个自定义函数 check( ) ,检查各位是否为输入的数字。 3. 暴搜。第一行数从 100到999,第二行数从 10到99。 4. 剪枝。 代码: /*ID: who jayLANG: C++TASK: crypt1*/#include<stdio.h>bool h

uva 10387 Billiard(简单几何)

题意是一个球从矩形的中点出发,告诉你小球与矩形两条边的碰撞次数与小球回到原点的时间,求小球出发时的角度和小球的速度。 简单的几何问题,小球每与竖边碰撞一次,向右扩展一个相同的矩形;每与横边碰撞一次,向上扩展一个相同的矩形。 可以发现,扩展矩形的路径和在当前矩形中的每一段路径相同,当小球回到出发点时,一条直线的路径刚好经过最后一个扩展矩形的中心点。 最后扩展的路径和横边竖边恰好组成一个直

day-51 合并零之间的节点

思路 直接遍历链表即可,遇到val=0跳过,val非零则加在一起,最后返回即可 解题过程 返回链表可以有头结点,方便插入,返回head.next Code /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}*

poj 1113 凸包+简单几何计算

题意: 给N个平面上的点,现在要在离点外L米处建城墙,使得城墙把所有点都包含进去且城墙的长度最短。 解析: 韬哥出的某次训练赛上A出的第一道计算几何,算是大水题吧。 用convexhull算法把凸包求出来,然后加加减减就A了。 计算见下图: 好久没玩画图了啊好开心。 代码: #include <iostream>#include <cstdio>#inclu

uva 10130 简单背包

题意: 背包和 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

论文阅读笔记: Segment Anything

文章目录 Segment Anything摘要引言任务模型数据引擎数据集负责任的人工智能 Segment Anything Model图像编码器提示编码器mask解码器解决歧义损失和训练 Segment Anything 论文地址: https://arxiv.org/abs/2304.02643 代码地址:https://github.com/facebookresear