SSDT的例子1-inlineHook的jmp验证
来源:互联网 发布:广电网络一年多少钱 编辑:程序博客网 时间:2024/06/04 18:09
前言
SSDT Hook后, 如果要跳过函数开始的一些opcode, 就只能跳到没有call语句之前的代码.
因为call有重定位问题,即使opcode一样,call的实际地址也是不同的.
试验记录
#include <Ntddk.h>#include <stdlib.h>#include <stdio.h>typedef char CHAR;typedef unsigned char BYTE;typedef unsigned short WORD;typedef unsigned int size_t;typedef unsigned long DWORD;#define MAXBYTE 0xff#define MAKEDWORD(L, H) (((WORD)((DWORD_PTR)(L) & 0xffff)) | ((DWORD)((WORD)((DWORD_PTR)(H) & 0xffff))) << 16)#pragma pack(push)#pragma pack(1)typedef struct _SYSTEM_SERVICE_TABLE { PVOID ServiceTableBase; //这个指向系统服务函数地址表 PULONG ServiceCounterTableBase; ULONG NumberOfService; //服务函数的个数,NumberOfService*4 就是整个地址表的大小 ULONG ParamTableBase;} SYSTEM_SERVICE_TABLE, *PSYSTEM_SERVICE_TABLE;typedef struct _SERVICE_DESCRIPTOR_TABLE { SYSTEM_SERVICE_TABLE ntoskrnel; //ntoskrnl.exe的服务函数 SYSTEM_SERVICE_TABLE win32k; //win32k.sys的服务函数,(gdi.dll/user.dll的内核支持) SYSTEM_SERVICE_TABLE NotUsed1; SYSTEM_SERVICE_TABLE NotUsed2;} SYSTEM_DESCRIPTOR_TABLE, *PSYSTEM_DESCRIPTOR_TABLE;#pragma pack(pop)extern PSYSTEM_DESCRIPTOR_TABLE KeServiceDescriptorTable;SYSTEM_SERVICE_TABLE* g_pSST = NULL;// typedef NTSTATUS (__stdcall *PFN_ZwOpenProcess)(// __out PHANDLE ProcessHandle,// __in ACCESS_MASK DesiredAccess,// __in POBJECT_ATTRIBUTES ObjectAttributes,// __in_opt PCLIENT_ID ClientId// );// PFN_ZwOpenProcess g_pfn = NULL;DWORD g_dwSsdtFunIndexAddr_NtOpenProcess = 0;DWORD g_dwPfnNtOpenProcessOrg = 0;// naked 函数内不能初始化变量// 在裸函数内使用的变量必须在函数外定义DWORD g_dwAddrJmp_MyNtOpenProcess = 0x805c22a0;__declspec(naked) NTSTATUS __stdcall MyNtOpenProcess(PHANDLE ProcessHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PCLIENT_ID ClientId){ /** kd> u 805C2296 nt!NtOpenProcess: 805c2296 68c4000000 push 0C4h 805c229b 68a8aa4d80 push offset nt!ObWatchHandles+0x25c (804daaa8) // 用 __asm + _emit, 在InlineHook函数后,可以跳到任意地址 // 但是call指令有重定位问题, 如果不修正, 只能在call之前打住 // 跳到这 805c22a0 e86b6cf7ff call nt!_SEH_prolog (80538f10) 805c22a5 33f6 xor esi,esi 805c22a7 8975d4 mov dword ptr [ebp-2Ch],esi 805c22aa 33c0 xor eax,eax 805c22ac 8d7dd8 lea edi,[ebp-28h] 805c22af ab stos dword ptr es:[edi] */ __asm { // 这里可以用int 3来调试 // int 3 // 68c4000000 // 805c2296 68c4000000 push 0C4h _emit 0x68 _emit 0xc4 _emit 0x00 _emit 0x00 _emit 0x00 // 68a8aa4d80 // 805c229b 68a8aa4d80 push offset nt!ObWatchHandles+0x25c (804daaa8) _emit 0x68 _emit 0xa8 _emit 0xaa _emit 0x4d _emit 0x80 // e86b6cf7ff // 805c22a0 e86b6cf7ff call nt!_SEH_prolog (80538f10) // f8dc841a e86b6cf7ff call f8d3f08a // call 指令涉及到重定位了, opcode一模一样也不是相同的反汇编指令 // 怪不得人家只跳过前10个字节// _emit 0xe8// _emit 0x6b// _emit 0x6c// _emit 0xf7// _emit 0xff pushf pusha } // do my hook task // 调用 KdPrint 可以正常打印 KdPrint(("MyNtOpenProcess\r\n")); __asm { popa popf jmp g_dwAddrJmp_MyNtOpenProcess } // return STATUS_SUCCESS; // return 0;}void fnHook_SSDT(){ DWORD dwAddr = 0; do { if (NULL == KeServiceDescriptorTable) { break; } g_pSST = &KeServiceDescriptorTable->ntoskrnel; if (NULL == g_pSST) { break; } KdPrint(("g_pSST = %p\r\n", g_pSST)); if (NULL == g_pSST->ServiceTableBase) { break; } KdPrint(("g_pSST->ServiceTableBase = %p\r\n", g_pSST->ServiceTableBase)); // 0x7a is OpenProcess Index On SSDT dwAddr = (DWORD)g_pSST->ServiceTableBase + 0x7a * sizeof(DWORD); if (0 == dwAddr) { break; } // 要换的就是g_dwSsdtFunIndexAddr_NtOpenProcess地址中的内容 g_dwSsdtFunIndexAddr_NtOpenProcess = dwAddr; KdPrint(("g_dwSsdtFunIndexAddr_NtOpenProcess = %p\r\n", g_dwSsdtFunIndexAddr_NtOpenProcess)); g_dwPfnNtOpenProcessOrg = *((DWORD*)(g_dwSsdtFunIndexAddr_NtOpenProcess)); KdPrint(("g_dwPfnNtOpenProcessOrg = %p\r\n", g_dwPfnNtOpenProcessOrg)); /** >> DriverEntry g_pSST = 80553FA0 g_pSST->ServiceTableBase = 80502B8C g_dwSsdtFunIndexAddr_NtOpenProcess = 80502D74 g_dwPfnNtOpenProcessOrg = 805C2296 kd> u 805C2296 nt!NtOpenProcess: 805c2296 68c4000000 push 0C4h 805c229b 68a8aa4d80 push offset nt!ObWatchHandles+0x25c (804daaa8) 805c22a0 e86b6cf7ff call nt!_SEH_prolog (80538f10) 805c22a5 33f6 xor esi,esi 805c22a7 8975d4 mov dword ptr [ebp-2Ch],esi 805c22aa 33c0 xor eax,eax 805c22ac 8d7dd8 lea edi,[ebp-28h] 805c22af ab stos dword ptr es:[edi] */ __asm { //去掉内存保护 cli mov eax, cr0 and eax, not 10000h mov cr0, eax } *((DWORD*)(g_dwSsdtFunIndexAddr_NtOpenProcess)) = (DWORD)MyNtOpenProcess; __asm { //恢复内存保护 mov eax, cr0 or eax, 10000h mov cr0, eax sti } KdPrint(("Hook By MyNtOpenProcess = %p\r\n", MyNtOpenProcess)); } while (0);}void fnUnHook_SSDT(){ __asm { //去掉内存保护 cli mov eax, cr0 and eax, not 10000h mov cr0, eax } *((DWORD*)(g_dwSsdtFunIndexAddr_NtOpenProcess)) = (DWORD)g_dwPfnNtOpenProcessOrg; __asm { //恢复内存保护 mov eax, cr0 or eax, 10000h mov cr0, eax sti } KdPrint(("UnHook By g_dwPfnNtOpenProcessOrg = %p\r\n", g_dwPfnNtOpenProcessOrg));}VOID fnDrvUnLoad(__in struct _DRIVER_OBJECT* DriverObject){ KdPrint((">> fnDrvUnLoad")); fnUnHook_SSDT();}NTSTATUS fnDrvDisPatch(__in struct _DEVICE_OBJECT* DeviceObject, __inout struct _IRP* Irp){ KdPrint((">> fnDrvDisPatch")); return STATUS_SUCCESS;}NTSTATUS DriverEntry(__in struct _DRIVER_OBJECT* DriverObject, __in PUNICODE_STRING RegistryPath){ KdPrint((">> DriverEntry")); DriverObject->DriverUnload = fnDrvUnLoad; DriverObject->MajorFunction[IRP_MJ_CREATE] = fnDrvDisPatch; DriverObject->MajorFunction[IRP_MJ_CREATE_NAMED_PIPE] = fnDrvDisPatch; DriverObject->MajorFunction[IRP_MJ_CLOSE] = fnDrvDisPatch; DriverObject->MajorFunction[IRP_MJ_READ] = fnDrvDisPatch; DriverObject->MajorFunction[IRP_MJ_WRITE] = fnDrvDisPatch; DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = fnDrvDisPatch; DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = fnDrvDisPatch; DriverObject->MajorFunction[IRP_MJ_QUERY_EA] = fnDrvDisPatch; DriverObject->MajorFunction[IRP_MJ_SET_EA] = fnDrvDisPatch; DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = fnDrvDisPatch; DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = fnDrvDisPatch; DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] = fnDrvDisPatch; DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = fnDrvDisPatch; DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = fnDrvDisPatch; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = fnDrvDisPatch; DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = fnDrvDisPatch; DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = fnDrvDisPatch; DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = fnDrvDisPatch; DriverObject->MajorFunction[IRP_MJ_CLEANUP] = fnDrvDisPatch; DriverObject->MajorFunction[IRP_MJ_CREATE_MAILSLOT] = fnDrvDisPatch; DriverObject->MajorFunction[IRP_MJ_QUERY_SECURITY] = fnDrvDisPatch; DriverObject->MajorFunction[IRP_MJ_SET_SECURITY] = fnDrvDisPatch; DriverObject->MajorFunction[IRP_MJ_POWER] = fnDrvDisPatch; DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = fnDrvDisPatch; DriverObject->MajorFunction[IRP_MJ_DEVICE_CHANGE] = fnDrvDisPatch; DriverObject->MajorFunction[IRP_MJ_QUERY_QUOTA] = fnDrvDisPatch; DriverObject->MajorFunction[IRP_MJ_SET_QUOTA] = fnDrvDisPatch; DriverObject->MajorFunction[IRP_MJ_PNP] = fnDrvDisPatch; DriverObject->MajorFunction[IRP_MJ_MAXIMUM_FUNCTION] = fnDrvDisPatch; fnHook_SSDT(); return STATUS_SUCCESS;}
0 0
- SSDT的例子1-inlineHook的jmp验证
- SSDT的例子2-NtOpenProcess
- 天书上的练习-inlinehook IoCallDriver函数
- Jmp指令的格式
- 关于SSDT的详解
- SSDT HOOK的框架
- 关于SSDT的详解
- SSDT HOOK的恢复
- SSDT表的遍历
- 汇编指令jmp的理解
- jmp指令对应的机器码
- CALL和JMP的区别
- jmp指令对应的机器码
- jmp指令的机器码编写
- inlineHook
- 一个验证的小例子
- 验证码的简单例子
- 一个验证登陆的例子
- [Unity3D] Unity3D游戏开发之UGUI实现伤害数值显示
- 怎么学汇编---dosbox 环境配置,怎么用
- linux后台开发常用调试工具
- 网络后台开发面试题
- 2016最热门的编程语言与薪资
- SSDT的例子1-inlineHook的jmp验证
- 2016年收入最高的5个编程语言
- 为什么游戏引擎大多选择使用 C++ 而不是 C 开发?
- linux常用的内核参数的设置
- Java—IO流详解(一)
- go开源cache2go项目蛤蟆笔记——简单使用-
- WE WANT U ┃中天微 国防科技大学2017届硕士专场校园宣讲会
- 基于ARM的智能灯光控制系统(8)设备添加
- 极客们都在关注:将会改变未来IT世界的十种编程语言!