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
原创粉丝点击