SSDT的例子2-NtOpenProcess
2016-10-20 22:43
316 查看
前言
看人家的工程中,都不是直接返回STATUS_ACCESS_DENIED. 在MyNtOpenProcess直接返回STATUS_ACCESS_DENIED并不会影响打开进程.
试验记录
#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; const DWORD g_dw_STATUS_ERR = STATUS_ACCESS_DENIED; __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 : don't allow open process ^_^\r\n")); __asm { popa popf // 对函数入口10字节的2个push进行平栈 pop eax pop eax // 返回 // 返回其他值(不是STATUS_SUCCESS), 进程还是会打开 // 不管返回什么值, 进程还是会被打开 // 可能不能Hook这个API. // 先丢这里, 以后再玩. SSDT Hook已经成功了 mov eax, g_dw_STATUS_ERR ret // 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; }
相关文章推荐
- HOOK SSDT NtOpenProcess 保护进程
- 新手学ssdt_hook_ntopenprocess
- 读取无保护的SSDT表中的NtOpenProcess函数的当前地址
- SSDT HOOK,通过hook NtOpenProcess达到保护制定进程效果
- Hook SSDT NtOpenProcess的完整代码
- Hook SSDT NtOpenProcess的完整代码
- 通过windbg 得到我们要 hook 的api 地址的方法以及 hook NtOpenProcess 的例子。。。
- 内核编程之SSDTHook(2)Hook NtOpenProcess实现进程保护
- Hook SSDT NtOpenProcess的完整代码
- WRK-NtOpenProcess 的流程草图~
- Syser 调试驱动 查看内核NTopenprocess
- Couldn't resolve error at 'ntdll!NtOpenProcess'
- windbg下查看应用层ntdll!NtOpenProcess
- 蹂躏D&F数据之XP-NtOpenProcess(虚拟机)
- 64位下Hook NtOpenProcess的实现进程保护 + 源码 (升级篇 )
- r0调用ntOpenprocess函数枚举进程
- inline hook NtOpenProcess学习资料以及总结问题
- NtOpenProcess
- windbg跟踪NtOpenProcess
- HOOK NtOpenProcess 保护指定进程