码迷,mamicode.com
首页 > 其他好文 > 详细

HOOK钩子技术5 SSDT Inline Hook

时间:2015-05-14 23:58:08      阅读:352      评论:0      收藏:0      [点我收藏+]

标签:ssdt-hook

原理

内联钩子的原理在R3和R0下是相同的,就是不改变SSDT表项,而是改变函数内部前几条指令。
内联钩子的典型伪函数为:

  • 恢复原指令
  • 执行目标操作,或改写参数
  • 执行原函数
  • 返回时重新挂钩

demo

#include "stdafx.h"



#ifdef __cplusplus
extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING  RegistryPath);
#endif

typedef NTSTATUS (*NtCreateProcess)(
                                      OUT PHANDLE           ProcessHandle,
                                      IN ACCESS_MASK        DesiredAccess,
                                      IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
                                      IN HANDLE             ParentProcess,
                                      IN BOOLEAN            InheritObjectTable,
                                      IN HANDLE             SectionHandle OPTIONAL,
                                      IN HANDLE             DebugPort OPTIONAL,
                                      IN HANDLE             ExceptionPort OPTIONAL ,
                                      IN ULONG                JobMemberLevel  ); 
typedef struct _SERVICE_DESCRIPTOR_TABLE
{
    PULONG ServiceTableBase;
    PULONG ServiceCounterTableBase;
    ULONG  NumberOfService;
    PUCHAR ParamTableBase;
}SERVICE_DESCRIPTOR_TABLE,*PSERVICE_DESCRIPTOR_TALBE;

NtCreateProcess  real_func_addr = NULL;
unsigned char bOldBytes[5];
unsigned char bNewBytes[5];
extern "C" PSERVICE_DESCRIPTOR_TALBE KeServiceDescriptorTable;//name can‘t change.  import member must be global variable.


/*
cr0 -16th bit = 0 means page can write
*/
bool REMOVE_ONLYREAD()
{
    __asm
    {
            push eax
            mov eax,CR0
            and eax, not 10000h
            mov CR0,eax
            pop eax
    }
    return TRUE;
}

/*
cr0 -16th bit(WP) = 1,reset to the attribute of ONLY READ
*/
bool RESET_ONLYREAD()
{
    __asm
    {
        push eax
            mov eax,CR0
            or  eax,10000h
            mov CR0,eax
            pop eax
    }
    return TRUE;
}





VOID RelineHookCreateProcess()
{
    REMOVE_ONLYREAD();
    //writememory with "jmp xxxxxxxx";
    RtlCopyMemory((PVOID)real_func_addr,(CONST PVOID)bNewBytes,5); 
    RESET_ONLYREAD();
}
VOID UnHookCreateProcess()
{
    REMOVE_ONLYREAD();
    //__asm int 3
    RtlCopyMemory((PVOID)real_func_addr,(const PVOID)bOldBytes,5);
    RESET_ONLYREAD();
}


void InlineSSDTHookUnload(PDRIVER_OBJECT pDriverObject) //no return ,with return compiler error
{
    UnHookCreateProcess();
    DbgPrint("GoodBye from InlineHook!\n");

}

NTSTATUS MyNtCreateProcessEx(
                             OUT PHANDLE           ProcessHandle,
                             IN ACCESS_MASK        DesiredAccess,
                             IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
                             IN HANDLE             ParentProcess,
                             IN BOOLEAN            InheritObjectTable,
                             IN HANDLE             SectionHandle OPTIONAL,
                             IN HANDLE             DebugPort OPTIONAL,
                             IN HANDLE             ExceptionPort OPTIONAL ,
                             IN ULONG                JobMemberLevel 
                             )
{
    NTSTATUS Status = STATUS_SUCCESS;
    UnHookCreateProcess();
    Status = real_func_addr(
        ProcessHandle,
        DesiredAccess,
        ObjectAttributes,
        ParentProcess,
        InheritObjectTable,
        SectionHandle ,
        DebugPort ,
        ExceptionPort ,
        JobMemberLevel
        );
    RelineHookCreateProcess();
    DbgPrint("have hook CreateProcess!\r\n");


    return Status;
}


NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING  RegistryPath)
{
    unsigned i;

    DbgPrint("Hello from InlineSSDTHook!\n");
    DriverObject->DriverUnload = InlineSSDTHookUnload;

    //hook
    PULONG PSsdt = (PULONG)KeServiceDescriptorTable->ServiceTableBase;
    PULONG p_real_func_addr =PSsdt+0x30;       //(unsigned char *) pssdt+0x30*4;
    DbgPrint("%08x,%08x",p_real_func_addr,PSsdt+0x30); //diff compared with ssdt hook
    real_func_addr = (NtCreateProcess)(*p_real_func_addr);
    //__asm int 3
    RtlCopyMemory((PVOID)bOldBytes,(CONST PVOID)real_func_addr,5);
    bNewBytes[0] =‘\xe9‘;
    *(PULONG)&bNewBytes[1]=(ULONG)MyNtCreateProcessEx-(ULONG)real_func_addr-5;
    //__asm int 3
    RtlCopyMemory((PVOID)real_func_addr,(CONST PVOID)bNewBytes,5);

    return STATUS_SUCCESS;
}

今天在做实验的时候,老是出错,无语了。在本地加载了程序的符号文件后调试出现各种奇葩问题,比如说函数入口指令的第一个字节总是没有改回来,后来也不知道怎么解决的。

挂钩后不能打开程序,提示文件错误 ,但是停止服务后恢复正常,所以怀疑是伪函数执行时候有错误,查了半天也没有错误。最后发现是少了一个参数,我函数指针定义成nt!NtCreatProcess 的参数了,nt!NtCreateProcessExnt!ntCreateProces 多了一个参数JobMemeberLevel

typedef NTSTATUS (*NtCreateProcessEx)(
                                      OUT PHANDLE           ProcessHandle,
                                      IN ACCESS_MASK        DesiredAccess,
                                      IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
                                      IN HANDLE             ParentProcess,
                                      IN BOOLEAN            InheritObjectTable,
                                      IN HANDLE             SectionHandle OPTIONAL,
                                      IN HANDLE             DebugPort OPTIONAL,
                                      IN HANDLE             ExceptionPort OPTIONAL ,
        /*************/               IN ULONG                JobMemberLevel  ); 

可是非常奇怪,参数错误函数执行肯定出错,昨天的SSDT HOOK却也是少了这个参数,挂钩函数也是nt!ntCreateProcessEx,按理说应该出错啊,为什么昨天的又是正确的呢???参数不一致也可以?仔细研究一下。

HOOK钩子技术5 SSDT Inline Hook

标签:ssdt-hook

原文地址:http://blog.csdn.net/bugmeout/article/details/45727147

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!