首页
社区
课程
招聘
hook call疑问
发表于: 2010-9-16 13:59 7090

hook call疑问

2010-9-16 13:59
7090
目标程序某函数Func.A反汇编后如下:

sub esp,100
push ebx
push ebp
push esi
push edi
mov esi,ecx
......
call dword ptr[edx+10]
mov ecx,edi
and ecx,1F
test bl,bl
je ...
......
......

我现在需要替换红色部分的dword ptr[edx+10]函数,采用自己的函数算法

请问通常做法是在自己代码里面直接hook红色部分函数,处理完成后再jmp到蓝色部分地址?
还是直接hook Func.A这个函数?

如果我直接hook红色部分函数,在OD里面看,原本蓝色部分的代码会被覆盖掉,直接变成后面的比如test bl,bl等。。。

新人学汇编,可能hook方法不对,希望大大们释疑,Thx!

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (15)
雪    币: 175
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
忘记一点,我不可以直接hook红色的函数,因为这个原始函数会有很多地方调用,所以我只能屏蔽Fun.A中调用它的代码,替换成我自己的另一个函数call,但是又不能影响Fun.A下面的move ecx,edi蓝色部分。

不知道我的描述是否清楚,请见谅!
2010-9-16 14:02
0
雪    币: 517
活跃值: (84)
能力值: ( LV12,RANK:250 )
在线值:
发帖
回帖
粉丝
3
00406690           FF52 10                  call    dword ptr [edx+10]
只有3 byte 的修改空间,你想要如何?
做一个最简单的inline hook也需要5 byte做jmp,所以你需要向上再找一些代码数据做合并处理。才能实现jmp XXX或jmp dword ptr [XXX]。
当然,如果你只有这3 byte可以用了,非如此不可,也不是不行。告诉你:INT3配合UEF:SetUnhandledExceptionFilter。它可以实现你想要的目标。其它不多说了,理解了,这个技术就是你的了。
2010-9-16 15:32
0
雪    币: 175
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
明白了,感谢指点!
2010-9-16 15:41
0
雪    币: 23
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
学习下...........
2010-9-16 16:29
0
雪    币: 468
活跃值: (52)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
只有3个字节,远jmp要5个字节,不够用是不是?
没关系,你尽管用5个字节,返回时,记得帮忙执行一些所有被覆盖的语句,也就是
mov edx,edi语句在你跳回来的时候你要先执行一下。在你自己的hook程序中执行即可,被hook的地方不是空间不够了吗?
2010-9-16 17:38
0
雪    币: 468
活跃值: (52)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
不用int3那么麻烦,呵呵,int3?何必,太麻烦了。直接远jmp ptr 32位地址,返回时候记得先执行mov edx,edi,总之保证所有寄存器的值要正确就行了。
2010-9-16 17:40
0
雪    币: 468
活跃值: (52)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
另外,关于更加安全的考虑,确保原来的程序段不存在jmp和call到你覆盖的那条语句,就是不存在jmp或者call到mov ecx,edi的语句,这样确保可以安全用5个字节远跳转jmp来hook,如果有call到或者jmp 到mov ecx,edi,那么很不幸,mov ecx,edi不能被覆盖了,另想办法,那就是修改jmp或者call到mov ecx,edi的语句,修改成jmp或者call到下一条的地方。
2010-9-16 17:44
0
雪    币: 175
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
感谢aait的帮助,另外我再问一下:
我call成功后在OD里面查看,它占用了6个字节,不知道是不是apihook类的问题。。。
那么原本正常代码是这样:
FF 52 10         call    dword ptr [edx+10]
8B CF             mov   ecx, edi
83 E1 1F        and    ecx, 1F
我改了call后,变成了:
69:E9 5E7A690E     jmp XXXXXX
E1 1F                       loopde short XXXXXX
83这个字节被我的call给覆盖掉了。。。
2010-9-16 18:45
0
雪    币: 175
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
那个call    dword ptr [edx+10]就是我想替换掉的函数,他原本只占用了3个字节
我在vc中的代码如下:
__declspec(naked) void newCall(int a,strcut_s *ptr)
{
       __asm {
                    pushad;
                    call MyProc;//我自己的算法函数
                    mov   ecx, edi
                    popad;
                    ret;
       }
       printf("Done.\n");
}
就这样一个函数,如果他的指针只占用5个字节,那么就应该替换掉:
FF 52 10         call    dword ptr [edx+10]
8B CF             mov   ecx, edi
结果是替换掉了,还多占用了一个字节,把下一语句的83 E1 1F        and    ecx, 1F
给占用了,结果下一语句变成了:E1 1F                       loopde short XXXXXX

无语。。。
2010-9-16 18:50
0
雪    币: 175
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
占用了83不说,结果我的MyProc最后一句Done也打印不出来,直接挂掉了!
2010-9-16 18:53
0
雪    币: 468
活跃值: (52)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
那这样,直接把E1,1F用90,90nop掉,然后记得返回之前,先恢复2条指令,第一条mov ecx,edi,第二条and ecx,1F
2010-9-17 08:19
0
雪    币: 468
活跃值: (52)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
你用 jmp要注意堆栈平衡的问题,如果先前压入若干参数入栈,那么返回时候要注意参数出栈。
2010-9-17 08:22
0
雪    币: 468
活跃值: (52)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
你的print DONE,要写在RET之前。写在ret之后,肯定不被执行啦。
2010-9-17 08:25
0
雪    币: 468
活跃值: (52)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
而且你 简单的 mov ecx,edi,然后ret,这样是不行的。你要在popad之后,然后再mov ecx,edi,这样才能保证ecx的值正确,否则,你先mov ecx,edi,然后又 popad,那不是又把ecx变成pushad时候的值了,把你 mov ecx,edi的结果又给冲掉了?所以,应该这样。
__declspec(naked) void newCall(int a,strcut_s *ptr)
{
       __asm {
                    pushad;
                    call MyProc;//我自己的算法函数
                    mov   ecx, edi
                    popad;
           (printf("Done.\n");)
           因为printf 不能在asm中使用,所以改成MssageBoxA,用invoke
            invoke MessageBoxA,参数自己填
                    mov ecx,edi
                    and ecx,1fh
                    ret;
       }
      }

另外你hook时候,不能用远跳转,而要用远call指令,因为你这里使用ret返回的。改成了远call以后,再nop,nop掉2个字节,原因已经说明。如果用远跳转,那么返回的时候也要用远跳转而不是ret,这就是堆栈平衡的问题。
2010-9-17 08:31
0
雪    币: 175
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
0196B33F    8B10            mov     edx, dword ptr [eax]
0196B341    53              push    ebx
0196B342    55              push    ebp
0196B343    8BC8            mov     ecx, eax

// jump call
0196B345    FF52 10         call    dword ptr [edx+10]
0196B348    8BCF            mov     ecx, edi

// +1+2 nop掉
0196B34A    83E1 1F         and     ecx, 1F

以上是源代码,我hook了0x196B345改为call newFunction,请问,从0x196B33F~0x196B343都是给call dword ptr[edx+10]压栈,那么我在newFunction里面如何调用前面push进去的参数呢?

函数原型是:
void newFunction(int,struct *ptr)
{
}
2010-9-17 17:20
0
游客
登录 | 注册 方可回帖
返回
//