RING0 与 RING3之间的简单交互

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

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

==============================kernel mode,FIRSTDRIVER.C========================

/////////////////////////////////////////////////
// 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;
else
   pIrp->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程序设计》

下载地址: Dirver.h

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值