首页
社区
课程
招聘
[求助]Inline Hook NtOpenProcess虚拟机正常,本地蓝屏
发表于: 2012-12-30 23:51 7252

[求助]Inline Hook NtOpenProcess虚拟机正常,本地蓝屏

2012-12-30 23:51
7252
各位大牛帮忙看看,搞了好久,实在没辙了
在虚拟机里边跑的佷正常,在本地运行几十秒就BSOD,Hook的过程没问题,
Hook的处理函数代码缩减再缩减,只剩下简单的处理和跳转了,请大牛们帮忙指导一下

方法:Hook NtOpenProcess 中call ObOpenObjectByPointer前几个字节

1、Hook前:


2、Hook后:


3、Hook代码只是简单的处理和跳转(第2步的call F8ABC8D0):
__declspec(naked)
VOID NtOpenProcessDeepInlineHook()
{
    __asm
    {
        pop     ecx                     //得到call之后的返回地址,ecx是看了上下文后挑选的
        push    [ebp-38]            //实现原本被hook掉的两个push
        push    [ebp-24]
        add     ecx, 1                 //计算返回地址(也就是图中的0x805cc620)
        push    ecx
        ret
    }
}
整个函数其实什么都没做,只是绕个圈回去了

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 0
支持
分享
最新回复 (12)
雪    币: 22
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
应该是你自己的 Inline hook 框架有问题 (参考 KiFastCallEntry Hook、Ring3 Inline hook)

如果是 Inline Hook 了一个被频繁调用的函数 也只是会很慢而已,不会 BSOD 的。
2012-12-31 00:22
0
雪    币: 22
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
Inline Hook 的新函数一般是

__declspec(naked) VOID InlineHookNewFunction1(VOID)
{  
        _asm
        {
                //        保存各个寄存器的值
                pushfd
                pushad
        }

        //        DoSomething() ...
        KdPrint(("[Vin_Chyi] Ring0 Inline Hook ~~~ \n"));

        _asm
        {
                // 恢复各个寄存器的值
                popad
                popfd
                jmp g_HookCopyBuffer1
        }
}

DoSomething() 应该是 特定的功能,才是实际意义上的 NewFunction,而上面这个函数 应该是 ProxyFunction

g_HookCopyBuffer1 处是 从Original Function 拷贝过来的字节码 + 调回返回地址的代码
2012-12-31 00:26
0
雪    币: 796
活跃值: (370)
能力值: ( LV9,RANK:380 )
在线值:
发帖
回帖
粉丝
4
__declspec(naked)
VOID NtOpenProcessDeepInlineHook()
{
    __asm
    {
        pop     ecx
        push    [ebp-38]
        push    [ebp-24]
        add     ecx, 1
        push    ecx
        ret
    }
}

颠倒了。
2012-12-31 04:55
0
雪    币: 55
活跃值: (519)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
5
[QUOTE=Winker;1129735]__declspec(naked) VOID NtOpenProcessDeepInlineHook(){    __asm    {        pop     ecx        push    [ebp-38]        push    [ebp-24]        ...[/QUOTE]正解,+1.
2012-12-31 08:07
0
雪    币: 81
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
6
[QUOTE=Winker;1129735]__declspec(naked)
VOID NtOpenProcessDeepInlineHook()
{
    __asm
    {
        pop     ecx
        push    [ebp-38]
        push    [ebp-24]
        ...[/QUOTE]

感谢回复,这里的pop ecx是重定位,这个函数就是Hook后call的函数,pop ecx用来得到返回地址
2012-12-31 10:19
0
雪    币: 81
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
7
我这个其实只是中继函数,就是第2步Hook后call的函数,要承接上下文,不能pushad破坏原本的堆栈

另外,注意在虚拟机里边跑的没有问题的
2012-12-31 10:24
0
雪    币: 3116
活跃值: (1269)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
8
不会分析dump的别瞎玩。
目测是真机里面的这段代码可能不一样
2012-12-31 11:04
0
雪    币: 81
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
9
dump有分析过,code是一样的

NtOpenProcess Hook部分:
0: kd> u
nt!NtOpenProcess+0x217:
808f4613 8d8548ffffff    lea     eax,[ebp-0B8h]
808f4619 50              push    eax
808f461a e8b1a2cf37      call    NtHook!KernNtOpenProcessDeepInlineHook (b85ee8d0)
808f461f 90              nop
808f4620 e84706ffff      call    nt!ObOpenObjectByPointer (808e4c6c)
808f4625 8bf8            mov     edi,eax
808f4627 8d8548ffffff    lea     eax,[ebp-0B8h]
808f462d 50              push    eax

Hook函数:
0: kd> u b85ee8d0
NtHook!KernNtOpenProcessDeepInlineHook
b85ee8d0 59              pop     ecx
b85ee8d1 ff75da          push    dword ptr [ebp-26h]
b85ee8d4 ff75e8          push    dword ptr [ebp-18h]
b85ee8d7 83c101          add     ecx,1
b85ee8da 51              push    ecx
b85ee8db c3              ret
2012-12-31 11:57
0
雪    币: 81
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
10
[QUOTE=xhflovemy;1129797]dump有分析过,code是一样的

NtOpenProcess Hook部分:
0: kd> u
nt!NtOpenProcess+0x217:
808f4613 8d8548ffffff    lea     eax,[ebp-0B8h]
808f4619 50         ...[/QUOTE]

多谢提醒,没太注意,两个push真的不一样
2012-12-31 12:00
0
雪    币: 102
活跃值: (14)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
估计是内核代码不同的原因。
同一张盘装出来的,虚拟机和真实机的内核大小和代码都是不同的。
2012-12-31 12:27
0
雪    币: 267
活跃值: (438)
能力值: ( LV9,RANK:190 )
在线值:
发帖
回帖
粉丝
12
ecx寄存器因为你的钩子函数的执行它的值发生了变化了。

__declspec(naked)
VOID NtOpenProcessDeepInlineHook()
{
    __asm
    {
        pop     ecx                     //得到call之后的返回地址,ecx是看了上下文后挑选的
        push    [ebp-38]            //实现原本被hook掉的两个push
        push    [ebp-24]
        add     ecx, 1                 //计算返回地址(也就是图中的0x805cc620)
        push    ecx
        ret
    }
}

改成这样试试

__declspec(naked)
VOID NtOpenProcessDeepInlineHook()
{
    __asm
    {
        pop     eax                     //得到call之后的返回地址,ecx是看了上下文后挑选的
        push    [ebp-38]            //实现原本被hook掉的两个push
        push    [ebp-24]
        add     eax, 1                 //计算返回地址(也就是图中的0x805cc620)
        push    eax
        ret
    }
}
但是我在想 你从NtOpenProcessDeepInlineHook的 ret以后 立即来到0x805cc620,而cpu是要预取下一个指令的这会不会使得call ObOpenObjectByPointer 的指令被影响。如还是蓝屏 就把NtOpenProcessDeepInlineHook的 add     eax, 1 去掉试看看,去掉add     eax, 1 后我想运行应该不会有问题。
2013-1-5 16:38
0
雪    币: 70
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
我的虚拟机和本机里的代码就不一样,每次都得改
2013-3-19 11:00
0
游客
登录 | 注册 方可回帖
返回
//