妙用mov edi,edi和5个nop实现inline hook
这方法MJ很早时就说过了,简单重复下。
大家应该发现大部分API的第一条指令都是mov edi,edi,比如在我的电脑上MessageBoxA的代码如下:
77D5058A > 8BFF mov edi, edi 77D5058C /. 55 push ebp 77D5058D |. 8BEC mov ebp, esp 77D5058F |. 833D BC04D777 >cmp dword ptr [77D704BC], 0 77D50596 |. 74 24 je short 77D505BC 77D50598 |. 64:A1 18000000 mov eax, dword ptr fs:[18]
mov edi,edi完全没起任何作用,貌似一条垃圾指令。不过大家是否还发现除了mov edi,edi外,大部分API前面刚好还有5个nop,如下:
77D50585 90 nop 77D50586 90 nop 77D50587 90 nop 77D50588 90 nop 77D50589 90 nop 77D5058A > 8BFF mov edi, edi 77D5058C /. 55 push ebp 77D5058D |. 8BEC mov ebp, esp 77D5058F |. 833D BC04D777 >cmp dword ptr [77D704BC], 0 77D50596 |. 74 24 je short 77D505BC 77D50598 |. 64:A1 18000000 mov eax, dword ptr fs:[18]
5个nop不是刚好可以改成一个远jmp吗,而mov edi,edi这条“垃圾”指令刚好可以改成一个短jmp,这样新型的inline hook就出世了,呵呵,我们只要把mov edi,edi改为往回跳5个字节,而把5个nop改成jmp到自己的代码就行了,如下:
77D50585 - E9 XXXXXXXX jmp XXXXXXXX 77D5058A > ^ EB F9 jmp short 77D50585 77D5058C /. 55 push ebp 77D5058D |. 8BEC mov ebp, esp 77D5058F |. 833D BC04D777 >cmp dword ptr [77D704BC], 0 77D50596 |. 74 24 je short 77D505BC 77D50598 |. 64:A1 18000000 mov eax, dword ptr fs:[18]
当需要调用原函数时只需jmp到原函数地址+2就行了,这样就不用像以前那样需要保存/恢复前5个字节,真是妙啊!Microsoft故意这样设计还真让某些人捡了便宜。不过这种方法并不能通用,有些API并没有mov edi,edi和5个nop,而且XP SP2之前的系统貌似也不是这样的。