驱动编程-ssdt hook--系统服务表
来源:互联网 发布:js 触发事件 编辑:程序博客网 时间:2024/05/16 05:12
整理下自己的驱动编程。
ssdt是系统服务表,每个window系统都会维护自己的系统服务表。我们可以使用kernel detective看下ssdt表。
以openProcess为例子:
开windbg
kd> u nt!ZwOpenProcess
nt!ZwOpenProcess:
804ff720 b87a000000 mov eax,7Ah //7A
804ff725 8d542404 lea edx,[esp+4]
804ff729 9c pushfd
804ff72a 6a08 push 8
804ff72c e850ed0300 call nt!KiSystemService (8053e481)
804ff731 c21000 ret 10h
nt!ZwOpenProcessToken:
804ff734 b87b000000 mov eax,7Bh
804ff739 8d542404 lea edx,[esp+4]
ZwOpenPeocess的开头
mov eax,7Ah
7A的十进制就是190对应的ssdt表的第190个。
现在来说下openProcess的hook方法
分为两种:
修改ssdt表:
修改ssdt表的第190地址,在修改之前先保存原来的ssdt地址,然后跳到自己定义的MyopenProcess,在MyOpenProcess结束跳回原来保存的地址。这种修改方法容易被检测出来。
inline hook:
第二种修改openProcess函数的入口使用jmp跳转到自己的函数上,据我所知,大部分保护驱动都是这样的。
代码献上:
miniddk.cpp
#include "miniDDK.h"#include "SSDT.h"#include "IDThook.h"#pragma INITCODE extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject,PUNICODE_STRING b){//=================Init============================//分开注册 派遣函数KdPrint(("\n\n驱动被加载----------\n"));pDriverObject->MajorFunction[IRP_MJ_CREATE]=ddk_DispatchRoutine_CREATE;pDriverObject->MajorFunction[IRP_MJ_CLOSE]=ddk_DispatchRoutine_CLOSE;pDriverObject->MajorFunction[IRP_MJ_READ]=ddk_DispatchRoutine_READ;pDriverObject->MajorFunction[IRP_MJ_WRITE]=ddk_DispatchRoutine_WRITE;pDriverObject->MajorFunction[ IRP_MJ_DEVICE_CONTROL]=ddk_DispatchRoutine_CONTROL;CreateMyDriver(pDriverObject);pDriverObject->DriverUnload = DDK_Unload;//=================Init============================//=============inlinehook==================SSDT_NtoldProcess_Addr = GetNt_OldAddress();KdPrint(("SSDT_NtoldProcess_Addr %x\n",SSDT_NtoldProcess_Addr));//利用SSDT读取当前的NtOpenProcess的地址SSDT_NtcurProcess_Addr = GetCurNtOpenProcess();KdPrint(("NtOpenProcessAddr: %x\n",SSDT_NtcurProcess_Addr));//构建inlinehook的参数newAddr.jmp= 0xE9;newAddr.addr = SSDT_NtoldProcess_Addr - SSDT_NtcurProcess_Addr -5;//if(SSDT_NtoldProcess_Addr!=SSDT_NtcurProcess_Addr){//KdPrint(("OpenProcess被HOOK 已修复------------\n"));//temp = (pjmpCode)SSDT_NtcurProcess_Addr;//oldAddr.jmp = temp->jmp;//oldAddr.addr = temp->addr;//temp->jmp = newAddr.jmp;//temp->addr = newAddr.addr;////}//=============inlinehook==================//================ssdt hook==================//Hook();//================ssdt hook==================//==================IDT hook=================//test();IDThook();//==================IDT hook=================return (1);}#pragma PAGECODEVOID DDK_Unload(IN PDRIVER_OBJECT pDriverObject){UNICODE_STRING symbolName;//=============ssdthook==================//UnHook();//还原SSDT表//=============ssdthook==================//=============inlinehook==================//if(SSDT_NtoldProcess_Addr!=SSDT_NtcurProcess_Addr){//oldAddr.jmp=temp->jmp; //oldAddr.addr=temp->addr ;//}//=============inlinehook==================//==================IDT hook=================IDTunhook();//==================IDT hook=================//删除驱动IoDeleteDevice()IoDeleteDevice(pDriverObject->DeviceObject);//删除符号链接IoDeleteSymbolicLink(symLinkName);RtlInitUnicodeString(&symbolName,L"\\??\\djj_DriverSymbol");IoDeleteSymbolicLink(&symbolName);KdPrint(("驱动被卸载------------\n"));}//INITCODE的代码一最好放在CPP吧 毕初始化一次就消失了#pragma INITCODENTSTATUS CreateMyDriver(IN PDRIVER_OBJECT pDriverObject){NTSTATUS status;PDEVICE_OBJECT pDevObj;//创建设备名称 用RtlInitUnicodeString初始化设备名称指针UNICODE_STRING devName;UNICODE_STRING symbolName;RtlInitUnicodeString(&devName,L"\\Driver\\djj_Driver");RtlInitUnicodeString(&symbolName,L"\\??\\djj_DriverSymbol");//创建设备 用IoCreateDevice创建设备,如果不成功则返回status = IoCreateDevice(pDriverObject,0,&devName,FILE_DEVICE_UNKNOWN,0,TRUE,&pDevObj);if(!NT_SUCCESS(status)){KdPrint(("创建设备失败"));return status;}pDevObj->Flags |= DO_BUFFERED_IO;//创建符号链接 用IoCreateSymlicLink创建符号链接,创建成功返回 STATUS_SUCCESS; 创建不成功则调用 status = IoCreateSymbolicLink(&symbolName,&devName);if(!NT_SUCCESS(status)){KdPrint(("创建符号链接失败"));return status;}return STATUS_SUCCESS;}
ssdt.h
#include<ntddk.h>#include <windef.h>#include "defStruct.h"#ifdef __cplusplusextern "C"{#endif#include <NTDDK.h> //这里包含需要用C方式编译的头文件#ifdef __cplusplus}#endif //==================inline ssdt hook==================ULONG SSDT_NtcurProcess_Addr;//声明要再前面 有点无语 只是CULONG SSDT_NtoldProcess_Addr;jmpCode oldAddr,newAddr;pjmpCode temp;//extern "C" extern long KeServiceDescriptorTable;typedef struct _ServiceDescriptorTable {PVOID ServiceTableBase; //System Service Dispatch Table 的基地址 PVOID ServiceCounterTable;//包含着 SSDT 中每个服务被调用次数的计数器。这个计数器一般由sysenter 更新。 unsigned int NumberOfServices;//由 ServiceTableBase 描述的服务的数目。 PVOID ParamTableBase; //包含每个系统服务参数字节数表的基地址-系统服务参数表 }*PServiceDescriptorTable; extern "C" extern PServiceDescriptorTable KeServiceDescriptorTable;//NtOpenProcess获取当前地址long GetCurNtOpenProcess(){long SSDT_NtProcess_Addr;_asm{push eaxmov eax,KeServiceDescriptorTablemov eax,[eax]lea eax,[eax+4*7Ah]mov eax,[eax]mov SSDT_NtProcess_Addr,eaxpop eax}return SSDT_NtProcess_Addr;}//获取原来的地址NtOpenProcesslong GetNt_OldAddress(){UNICODE_STRING Old_Address_Name;long Old_Addr;RtlInitUnicodeString(&Old_Address_Name,L"NtOpenProcess");Old_Addr = (long)MmGetSystemRoutineAddress(&Old_Address_Name);//KdPrint(("old_Addr:%x\n",Old_Addr));return Old_Addr;} //==============inline ssdt hook end===========================//============ssdt hook end========================extern "C" typedef NTSTATUS __stdcall NTOPENPROCESS ( OUT PHANDLE ProcessHandle, IN ACCESS_MASK AccessMask, IN POBJECT_ATTRIBUTES ObjectAttributes, IN PCLIENT_ID ClientId );NTOPENPROCESS *RealNtOpenProcess ; NTSTATUS MyOpenProcess( OUT PHANDLE ProcessHandle, IN ACCESS_MASK AccessMask, IN POBJECT_ATTRIBUTES ObjectAttributes, IN PCLIENT_ID ClientId){NTSTATUS rc;//KdPrint(("MyOpenProcess hook\n"));//KdPrint(("RealNtOpenProcess %x\n",RealNtOpenProcess));//KdPrint(("*RealNtOpenProcess %x\n",*RealNtOpenProcess));rc = (NTSTATUS)RealNtOpenProcess(ProcessHandle,AccessMask,ObjectAttributes,ClientId);return rc;}//hook住OpenProcess使得无法附加 利用修改当前的KeServiceDescriptorTable 7A #pragma PAGECODEvoid Hook(){LONG t_addr;t_addr = (LONG)KeServiceDescriptorTable->ServiceTableBase;LONG *SSDT_Adr = (PLONG)(t_addr+0x7A*4);RealNtOpenProcess = ( NTOPENPROCESS *)(*SSDT_Adr);KdPrint(("*RealNtOpenProcess %x\n",*RealNtOpenProcess));KdPrint(("RealNtOpenProcess %x\n",RealNtOpenProcess));long test1,test2,test3;//OpenProcess();[KeServiceDescriptorTable]+4*7Ah__asm //去掉页面保护{ climov eax,cr0and eax,not 10000h //and eax,0FFFEFFFFhmov cr0,eax}_asm{push eaxpush ebxmov eax,KeServiceDescriptorTablemov eax,[eax] //服务表列表mov test1,eaxlea eax,[eax+4*7Ah] //服务表的指向OpenProcess的首地址mov test2,eaxmov ebx,MyOpenProcess//mov eax,[eax] //NtOpenProcess的首地址mov [eax],ebxmov eax,[eax]mov test3,eax//mov eax,MyOpenProcess //修改服务表为MyOpenProcesspop ebxpop eax}KdPrint(("KeServiceDescriptorTable: %x\n",KeServiceDescriptorTable));KdPrint(("[KeServiceDescriptorTable]: %x\n",test1));KdPrint(("[KeServiceDescriptorTable]+4*7Ah: %x\n",test2));KdPrint(("[[KeServiceDescriptorTable]+4*7Ah]: %x\n",test3));KdPrint(("MyOpenProcess: %x\n",MyOpenProcess));__asm { mov eax, cr0 or eax, 10000h mov cr0, eax sti } }#pragma PAGECODEvoid UnHook(){long test1,test2,test3;//OpenProcess();[KeServiceDescriptorTable]+4*7Ah__asm //去掉页面保护{ climov eax,cr0and eax,not 10000h //and eax,0FFFEFFFFhmov cr0,eax}_asm{push eaxpush ebxmov eax,KeServiceDescriptorTablemov eax,[eax] //服务表列表mov test1,eaxlea eax,[eax+4*7Ah] //服务表的指向OpenProcess的首地址mov test2,eaxmov ebx,RealNtOpenProcess//mov eax,[eax] //NtOpenProcess的首地址mov [eax],ebxmov eax,[eax]mov test3,eax//mov eax,MyOpenProcess //修改服务表为MyOpenProcesspop ebxpop eax}KdPrint(("KeServiceDescriptorTable: %x\n",KeServiceDescriptorTable));KdPrint(("[KeServiceDescriptorTable]: %x\n",test1));KdPrint(("[KeServiceDescriptorTable]+4*7Ah: %x\n",test2));KdPrint(("[[KeServiceDescriptorTable]+4*7Ah]: %x\n",test3));KdPrint(("MyOpenProcess: %x\n",MyOpenProcess));__asm { mov eax, cr0 or eax, 10000h mov cr0, eax sti } }//============ssdt hook end========================
- 驱动编程-ssdt hook--系统服务表
- Win64 驱动内核编程-19.HOOK-SSDT
- Win64 驱动内核编程-22.SHADOW SSDT HOOK
- 驱动笔记:SSDT HOOK实现进程保护
- SSDT HOOK驱动开发(1):进程隐藏
- SSDT HOOK驱动开发(2):进程保护
- SSDT HOOK驱动开发(2):进程保护
- SSDT HOOK驱动开发(1):进程隐藏
- SSDT HOOK中的获取函数服务号
- SSDT表函数Hook原理
- Hook SSDT
- SSDT hook
- HOOK SSDT
- SSDT HOOK
- SSDT HOOK
- hook ssdt
- SSDT HOOK
- HOOK SSDT
- java判断运行环境是linux还是windows
- VIM复制和粘贴
- android studio断点调试
- Android广播机制基础
- bootStrap table spring mvc 详细运用实例
- 驱动编程-ssdt hook--系统服务表
- AM335x ramdisk支持
- unityshader剔除前面
- 百度地图API地理位置和坐标转换
- (一般)POJ-1017 装载问题
- Shiro 如何主动调用doGetAuthorizationInfo方法
- Java 容器(一) Arrays
- Hadoop入门指导
- 纯代码实现自定义UITableView的cell