能力值:
( LV2,RANK:10 )
|
-
-
2 楼
忘记一点,我不可以直接hook红色的函数,因为这个原始函数会有很多地方调用,所以我只能屏蔽Fun.A中调用它的代码,替换成我自己的另一个函数call,但是又不能影响Fun.A下面的move ecx,edi蓝色部分。
不知道我的描述是否清楚,请见谅!
|
能力值:
( 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。它可以实现你想要的目标。其它不多说了,理解了,这个技术就是你的了。
|
能力值:
( LV2,RANK:10 )
|
-
-
4 楼
明白了,感谢指点!
|
能力值:
( LV2,RANK:10 )
|
-
-
5 楼
学习下...........
|
能力值:
( LV2,RANK:10 )
|
-
-
6 楼
只有3个字节,远jmp要5个字节,不够用是不是?
没关系,你尽管用5个字节,返回时,记得帮忙执行一些所有被覆盖的语句,也就是
mov edx,edi语句在你跳回来的时候你要先执行一下。在你自己的hook程序中执行即可,被hook的地方不是空间不够了吗?
|
能力值:
( LV2,RANK:10 )
|
-
-
7 楼
不用int3那么麻烦,呵呵,int3?何必,太麻烦了。直接远jmp ptr 32位地址,返回时候记得先执行mov edx,edi,总之保证所有寄存器的值要正确就行了。
|
能力值:
( 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到下一条的地方。
|
能力值:
( 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给覆盖掉了。。。
|
能力值:
( 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
无语。。。
|
能力值:
( LV2,RANK:10 )
|
-
-
11 楼
占用了83不说,结果我的MyProc最后一句Done也打印不出来,直接挂掉了!
|
能力值:
( LV2,RANK:10 )
|
-
-
12 楼
那这样,直接把E1,1F用90,90nop掉,然后记得返回之前,先恢复2条指令,第一条mov ecx,edi,第二条and ecx,1F
|
能力值:
( LV2,RANK:10 )
|
-
-
13 楼
你用 jmp要注意堆栈平衡的问题,如果先前压入若干参数入栈,那么返回时候要注意参数出栈。
|
能力值:
( LV2,RANK:10 )
|
-
-
14 楼
你的print DONE,要写在RET之前。写在ret之后,肯定不被执行啦。
|
能力值:
( 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,这就是堆栈平衡的问题。
|
能力值:
( 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)
{
}
|
|
|