看流星社区

 找回密码
 注册账号
查看: 4118|回复: 0

[求助] 求帮望解决x64 SSDT NtUserBuildHwndList问题

[复制链接]

该用户从未签到

发表于 2014-7-8 09:17:15 | 显示全部楼层 |阅读模式
求帮望解决下x64位SSDT hook 代码是引用别人的代码.
其他函数的HOOK没问题唯独NtUserBuildHwndList错误....
求帮望解决



00000015    13:07:25    NTUSERBUILDHWNDLISTHook: 0 0 0 fffffa8000000000 fffff96000000000 1fa002010000 0    //NtUserBuildHwndList参数
00000016    13:07:25    NTUSERBUILDHWNDLISTHook: c0000008 0      //NtUserBuildHwndList返回值
00000017    13:07:25    NTUSERBUILDHWNDLISTHook: 0 0 0 fffffa8000000000 fffff96000000000 1fa002010000 0    //NtUserBuildHwndList参数
00000018    13:07:25    NTUSERBUILDHWNDLISTHook: c0000008 0    //NtUserBuildHwndList返回值
00000019    13:07:26    NTUSERBUILDHWNDLISTHook: 0 0 0 fffffa8000000000 fffff96000000000 1fa002010000 0    //NtUserBuildHwndList参数
00000020    13:07:26    NTUSERBUILDHWNDLISTHook: c0000008 0    //NtUserBuildHwndList返回值

00000021    13:07:43    NTUSERBUILDHWNDLISTHook: 0 2028c 1 0 0 1f8002000000 8e2f8    //NtUserBuildHwndList参数00000022    13:07:43    NTUSERBUILDHWNDLISTHook: c0000023 0    //NtUserBuildHwndList返回值
x64错误代码0xc0000008和c0000023
//余下代码和解释
//替换函数  

NTSTATUS   NTUSERBUILDHWNDLISTHook(
                                         HDESK hdesk,
                                         HWND hwndNext,  
                                         ULONG fEnumChildren,  
                                         DWORD idThread,  
                                         UINT cHwndMax,  
                                         HWND *phwndFirst,  
                                         ULONG *pcHwndNeeded)
{
     NTSTATUS   status;


     //打印参数
     DbgPrint("NTUSERBUILDHWNDLISTHook: %llx %llx %llx %llx %llx %llx %llx",hdesk,hwndNext,fEnumChildren,idThread,cHwndMax,phwndFirst,pcHwndNeeded);

        //调用真正函数
     status = g_NtUserBuildHwndList(hdesk,  
         hwndNext,  
         fEnumChildren,  
         idThread,  
         cHwndMax,  
         phwndFirst,  
         pcHwndNeeded);
         //打印返回值
     DbgPrint("NTUSERBUILDHWNDLISTHook: %llx %llx",status,hdesk);


     return status;
}


//替换SSDT函数

VOID ModifySSSDT(ULONG64 Index, ULONG64 Address)
{

    ULONGLONG                W32pServiceTable=0, qwTemp=0;
    LONG                     dwTemp=0;
    PSYSTEM_SERVICE_TABLE    pWin32k;
    KIRQL                    irql;
    DbgPrint("ModifySSSDTAddress: %llx %llx",Address,Index);
    pWin32k = (PSYSTEM_SERVICE_TABLE)((ULONG64)KeServiceDescriptorTableShadow + sizeof(SYSTEM_SERVICE_TABLE));    //4*8
    W32pServiceTable=(ULONGLONG)(pWin32k->ServiceTableBase);
    qwTemp = W32pServiceTable + 4 * (Index);
    dwTemp = (LONG)(Address - W32pServiceTable);
    DbgPrint("ModifySSSDTAddress: %llx %llx",dwTemp,Address - W32pServiceTable);
    dwTemp = dwTemp << 4;    //DbgPrint("*(PLONG)qwTemp: %x, dwTemp: %x",*(PLONG)qwTemp,dwTemp);
    DbgPrint("ModifySSSDTAddress: %llx %llx",dwTemp,qwTemp);
    irql=WPOFFx64();
    *(PLONG)qwTemp = dwTemp;
    WPONx64(irql);
}

//写入替换函数
//为什么要写入机器码我解释下.......由于x64的读取SSDT是根据一个基址+偏于的 基址是64位的 偏于是32位的,所以我们无法直接替换函数地址进去....我做的解决是从ssdt的基址
//查找14个0x90机器码作为我的中转在jmp [到我的函数];这样就可以跳转64位地址了......
//还有很多种解决方案,或者重在SSDT基址这个有点复杂

VOID HOOK_ShadowSSDT(ULONG64 X_hookAddress,ULONG64 Index,ULONGLONG MyFun)
{

    KIRQL irql;
    ULONG64 myfun;
    UCHAR jmp_code[]="\xFF\x25\x00\x00\x00\x00\x90\x90\x90\x90\x90\x90\x90\x90";    //需要14字节+4字节(jmp [我的函数])
    //代理函数地址
    myfun=MyFun;//取函数地址
    DbgPrint("HOOK_SSSDTmyfun: %llx",myfun);
    //填充shellcode
    memcpy(jmp_code+6,&myfun,8);
    irql=WPOFFx64();
    memcpy((PVOID)(X_hookAddress),jmp_code,14);//写入中转的机器码
    DbgPrint("HOOK_SSSDTmyfun: %s %llx",jmp_code,X_hookAddress);//输机器码和HOOK地址
    WPONx64(irql);
    ModifySSSDT(Index, X_hookAddress);//替换SSDT表
    DbgPrint("HOOK_SSSDT OK!");
}

//根据序号获取函数

ULONGLONG GetSSSDTFuncCurAddr64(ULONG64 Index)
{
    ULONGLONG                W32pServiceTable=0, qwTemp=0;
    LONG                     dwTemp=0;
    PSYSTEM_SERVICE_TABLE    pWin32k;
    pWin32k = (PSYSTEM_SERVICE_TABLE)((ULONG64)KeServiceDescriptorTableShadow + sizeof(SYSTEM_SERVICE_TABLE));
    W32pServiceTable=(ULONGLONG)(pWin32k->ServiceTableBase);
    ul64W32pServiceTable = W32pServiceTable;
    qwTemp = W32pServiceTable + 4 * (Index);    //这里是获得偏移地址的位置,要HOOK的话修改这里即可
    dwTemp = *(PLONG)qwTemp;
    dwTemp = dwTemp >> 4;
    qwTemp = W32pServiceTable + (LONG64)dwTemp;
    return qwTemp;
}

//获取x64 ShadowSSDT特征

ULONGLONG GetKeServiceDescriptorTableShadow64()
{     
    PUCHAR StartSearchAddress = (PUCHAR)__readmsr(0xC0000082);
    PUCHAR EndSearchAddress = StartSearchAddress + 0x500;
    PUCHAR i = NULL;
    UCHAR b1=0,b2=0,b3=0;
    ULONG templong=0;
    ULONGLONG addr=0;
    //DbgPrint("templong  地址 i=: %llx",i);
    for(i=StartSearchAddress;i<EndSearchAddress;i++)
    {     
        //DbgPrint("templong地址 i=: %llx",i);
        if( MmIsAddressValid(i) && MmIsAddressValid(i+1) && MmIsAddressValid(i+2) )
        {
            b1=*i;
            b2=*(i+1);
            b3=*(i+2);
            if( b1==0x4c && b2==0x8d && b3==0x1d ) //4c8d1d
            {
                memcpy(&templong,i+3,4);
            //    DbgPrint("templong地址: %llx",i);
            //    DbgPrint("templong地址: %llx",templong);
                addr = (ULONGLONG)templong + (ULONGLONG)i + 7;
                HookNum = (int)(i+20);
                return addr;
            }
        }
    }
    return 0;
}
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-4-26 20:34

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

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