吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 854|回复: 2
收起左侧

[学习记录] 驱动开发中内核SSDT函数的 HOOK跳板选择

[复制链接]
syw6616 发表于 2023-3-15 16:49
/*此程序于2022年3月17日下午正式调试修改完成,涉及很多知识*/
/*64位的内核跳出转很有讲究,不能直接改,因为驱动程序的内存地址与内核需要修改的地址之间的差距过大,超过0xFFFFFFFF*/
/*所以必须得有跳板,这个跳板通常很难选择,用KeBugCheckEx()是个好办法*/

下面提供一下思路,有一定基础的朋友,应该可以实现功能:



/*处理跳板函数*/
VOID FuckKeBugCheckEx()
{
        KIRQL irql;
        ULONGLONG myfun;
       
        UCHAR jmp_code[] = "\xFF\x25\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF";
        myfun = (ULONGLONG)New_ZwQueryDirectoryFile;
        DbgPrint("myfun地址是========%p\n", myfun);

        memcpy(jmp_code + 6, &myfun, 8);                // &myfun 取函数的地址
       
        //DbgPrint("KeBugCheckEx2地址是========%p\n", KeBugCheckEx2);


        ori_head_byte = kmalloc(15);
       
        irql = WPOFFx64();
       
        //保存原头部15字节
        memcpy(ori_head_byte, KeBugCheckEx2, 15);     //在UNLOAD时恢复03-17
                                                     //直接写函数名,即操作此函数的代码!
                                                     //memcpy(KeBugCheckEx, ori_head_byte, 15);
                                                 //保存地址时需要申请内存。
    //以下改写原函数开头代码
        memset(KeBugCheckEx2, 0x90, 15);
        memcpy(KeBugCheckEx2, jmp_code, 14);
   /*---------------------------------*/
        WPONx64(irql);

}


// SSDT Unhook
BOOLEAN SSDTUnhook()
{

        return TRUE;
}

// SSDT Hook
BOOLEAN SSDTHook()
{
        UNICODE_STRING ustrDllFileName;
        ULONG ulSSDTFunctionIndex = 0;
        PMDL pMdl = NULL;
        PVOID pNewAddress = NULL;
        ULONGLONG ulNewFuncAddr = 0;
        NTSTATUS status;

        KIRQL irql;

        KeBugCheckEx2 = (PVOID)((ULONGLONG)KeBugCheckEx + 16);
        /*lkd> u KeBugCheckEx      //原始数据
         t!KeBugCheckEx:
fffff800`01e82640 48894c2408      mov     qword ptr [rsp+8],rcx
fffff800`01e82645 4889542410      mov     qword ptr [rsp+10h],rdx
fffff800`01e8264a 4c89442418      mov     qword ptr [rsp+18h],r8
fffff800`01e8264f 4c894c2420      mov     qword ptr [rsp+20h],r9
fffff800`01e82654 9c              pushfq
*/

        /*lkd> u KeBugCheckEx     //HOOK以后的
nt!KeBugCheckEx:
fffff800`01e82640 48894c2408      mov     qword ptr [rsp+8],rcx
fffff800`01e82645 4889542410      mov     qword ptr [rsp+10h],rdx
fffff800`01e8264a 4c89442418      mov     qword ptr [rsp+18h],r8
fffff800`01e8264f 4cff2500000000  jmp     qword ptr [nt!KeBugCheckEx+0x16 (fffff800`01e82656)]
fffff800`01e82656 cc              int     3
fffff800`01e82657 3a3e            cmp     bh,byte ptr [rsi]
fffff800`01e82659 17              ???
fffff800`01e8265a 80f8ff          cmp     al,0FFh
       
        ff250000000  jmp     qword ptr [nt!KeBugCheckEx+0x16 (fffff800`01e82656)  
        //跳转到相对偏址为0,即接下地址中储存值(8字节长)为地址的地方
        fffff880-173e3acc
        */



        RtlInitUnicodeString(&ustrDllFileName, L"\\??\\C:\\Windows\\System32\\ntdll.dll");
        // 从 ntdll.dll 中获取 SSDT 函数索引号

        ulSSDTFunctionIndex = GetSSDTFunctionIndex(ustrDllFileName, "ZwQueryDirectoryFile");
        DbgPrint("ZwQueryDirectoryFile== ulSSDTFunctionIndex ====>%d", ulSSDTFunctionIndex);

       
        ULONG dwtmp = 0;
        ULONGLONG Ldwtmp = 0;
        ULONGLONG addr = 0;
        PULONG ServiceTableBase = NULL;
        ServiceTableBase = (PULONG)(((PSYSTEM_SERVICE_DESCRIPTOR_TABLE)SSDTAddress)->ServiceTableBase);
        DbgPrint("服务表基址ServiceTableBasenAddre======>%p", ServiceTableBase);



        dwtmp = (ULONGLONG)(((PULONG32)((PSYSTEM_SERVICE_DESCRIPTOR_TABLE)SSDTAddress)->ServiceTableBase)[ulSSDTFunctionIndex]);//PULONG=PLONG32只能这样,64都不行.
        ssdtfunaddr = &((PULONG32)((PSYSTEM_SERVICE_DESCRIPTOR_TABLE)SSDTAddress)->ServiceTableBase)[ulSSDTFunctionIndex];
        DbgPrint("存放原始偏址的地址ssdtfunaddr===%p", ssdtfunaddr);

        oldaddr = dwtmp;                                 //原来的偏移地址,没有
        DbgPrint("原偏移地址值 oldaddr======>%p", oldaddr);
       
        dwtmp = dwtmp >> 4;
        g_pOldSSDTFunctionAddress = (PVOID)(dwtmp + (ULONGLONG)ServiceTableBase);//&0xFFFFFFF0; 原函数地址
       
        DbgPrint("换算后的真实原函数地址g_pOldSSDTFunctionAddre======>%p", g_pOldSSDTFunctionAddress);

        FuckKeBugCheckEx();

        irql = WPOFFx64();

    (ULONG)(*ssdtfunaddr) =GetOffsetAddress((ULONGLONG)KeBugCheckEx2, 11);     //HOOK的关键步骤
        //GetOffsetAddress((ULONGLONG)KeBugCheckEx2, 11);


        WPONx64(irql);
//
//        DbgPrint("KeBugCheckEx: %llx", (ULONGLONG)KeBugCheckEx);

       
        DbgPrint("KeBugCheckEx: %llx", (ULONGLONG)KeBugCheckEx);  
        DbgPrint("KeBugCheckEx: %p\n", &KeBugCheckEx);



        DbgPrint("KeBugCheckEx2: %llx", (ULONGLONG)KeBugCheckEx2);
       
       
//跳板函数的地址,与原SSDT应该较近
//DbgPrint("TEST======>%p\n", &((PULONG32)((PSYSTEM_SERVICE_DESCRIPTOR_TABLE)SSDTAddress)->ServiceTableBase)[ulSSDTFunctionIndex]);
//DbgPrint("TEST======>%p\n", &(((PULONG64)((PSYSTEM_SERVICE_DESCRIPTOR_TABLE)SSDTAddress)->ServiceTableBase)[ulSSDTFunctionIndex]));

       

        return TRUE;
}

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

13525372903 发表于 2023-5-9 17:10
大神,有个软件1分钟闪退,经测试是软件调用了terminateprocess关闭的,想通过hook这个来达到避免软件关闭的目的,是否可行?
 楼主| syw6616 发表于 2023-6-8 10:20
13525372903 发表于 2023-5-9 17:10
大神,有个软件1分钟闪退,经测试是软件调用了terminateprocess关闭的,想通过hook这个来达到避免软件关闭 ...

这个肯定可以的了!
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 23:02

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表