能力值:
(RANK:410 )
|
-
-
2 楼
那一句作用是取得HOOK API函数的执行地址。然后从HOOK API函数头中读取头5个字节,再写回原API头中恢复原API代码。
|
能力值:
( LV2,RANK:10 )
|
-
-
3 楼
哪位大虾有时间,能给这段代码加上详细的注视呢?
俺越看越蒙了
|
能力值:
( LV12,RANK:300 )
|
-
-
4 楼
char ResetApiName[APICOUT][255] =
{
"ZwCreateFile",
"ZwOpenFile",
"ZwCreateProcess",
"ZwCreateProcessEx"
};//这里是需要被恢复的四个函数的名称
#define NONEHOOK 0
#define ANTIHOOKFAILD 1
#define ANTIHOOKTRUE 2
//恢复原来的代码
int ResetCode(HANDLE theHandle)//恢复进程的API HOOK。theHandle为进程句柄。
{
BYTE code[5] = {0};
BYTE Newcode[5] = {0};
DWORD dwReadnum;
DWORD oldpro;
BOOL ret = NONEHOOK;
for(int i = 0; i < APICOUT; i++)//对每个函数进行恢复hook操作。
{
DWORD ApiAddr = (DWORD)GetProcAddress(GetModuleHandle("NTDLL.DLL"),ResetApiName[i]);//得到API地址
if( ApiAddr )
{
VirtualProtectEx(theHandle,(LPVOID)ApiAddr,5,PAGE_EXECUTE_READWRITE,&oldpro);//修改内存地址属性为RWE
ReadProcessMemory(theHandle,(LPVOID)ApiAddr,code,5,&dwReadnum);//从API开头读5字节
if( dwReadnum != 0)
{
if( 0xE8 == code[0] )//if Hook,即开头是一个jmp
{
DWORD NewAddr = ApiAddr + *(DWORD*)&code[1] + 5;//相对jmp地址计算,计算出jmp到的代码位置
VirtualProtectEx(theHandle,(LPVOID)NewAddr,5,PAGE_EXECUTE_READWRITE,&oldpro);
ReadProcessMemory(theHandle,(LPVOID)NewAddr,Newcode,5,&dwReadnum);//将此处的5字节读出
if( dwReadnum != 0)
{
//restore hook
if( !WriteProcessMemory(theHandle,(LPVOID)ApiAddr,Newcode,5,&dwReadnum) )//将读出的5字节内容写回原API函数开头
{
ret = ANTIHOOKFAILD;
}
else
{
ret = ANTIHOOKTRUE;
}
}
}
}
}
}
return ret;
}
|
能力值:
( LV12,RANK:300 )
|
-
-
5 楼
如上,我觉得这份代码已经十分简明了。楼主不能理解代码,我看还是对INLINE HOOK的细节以及汇编中相对jmp代码的机器码不了解。
对API函数的INLINE HOOK,将API函数开头的5字节替换为
jmp hookfunction
这5个字节的代码,变成机器码,第一个字节为0xE8,后面四个字节为一个DWORD值。
这个相对jmp的DWORD值的计算方法是:
目标代码地址-jmp命令位置-jmp命令长度(5字节)
当API函数开头jmp入hookfunction开头时,hookfunction的开头:
实现原API函数开头的5个字节代码,然后跳回原API函数5个字节后的代码。
以上就是楼主的代码所要面对的现实情况,这样你才可以理解这个代码是在干什么:
从API函数头部5字节的jmp中,找到跳转到的hookfunction的地址
从hookfunction处拷贝5个字节的内容,也即是API函数前5字节的原始内容
将这5字节内容覆盖回原API函数头部
这样就解除了INLINE HOOK
不知道楼主现在明白没有。
|
能力值:
( LV2,RANK:10 )
|
-
-
6 楼
谢谢楼上的两位,我明白了
|
能力值:
( LV9,RANK:180 )
|
-
-
7 楼
是吗? 我怎么感觉你们的解释都怪怪的 ?
第一点. E8 是 call , 不是 jmp
第二点. 他前面写的四个api是 Zw开头的, 显然是 ntdll.dll
以 ZwCreateFile 为例, 入点为 :
B820000000 mov eax,20h
8d542404 lea edx,[esp+04]
cd2e int 2Eh
注意: 是B8开头, 不是 E8 开头.
所以, 他已经自我预设为, 被人用Call的方式 Hook, 而不是以 jmp 的方式 Hook
ZwCreateFile:
E8xxxxxxxx call NewAddr
8d542404 lea edx,[esp+04]
cd2e int 2Eh
当然了. 在他的Hook函式(NewAddr)在返回前会还原 EAX 的值 再 ret
接下来, 他写:
NewAddr = ApiAddr + *(DWORD*)&code[1] + 5 (这是算出 Hook 函数的入点没错)
最后他读NewAddr函数的前5个byte, 填入(还原) ZwCreateFile 的开头.
关于这一点. 他又自我预设了Hook函数(NewAddr)的前5个byte为原API的5个byte
亦即他预设了,
NewAddr:
B820000000 mov eax,20h
.....
.....
由于我没看到整个Project, (这里只贴上这 ResetCode 函数而己)
除非 Hook 函式也是作者自己写的, 否则...这根本不能用. 更谈不上
"这段代码是来自珠海金山2007逆向分析挑战赛里面的代码用于恢复被hook的函数的"
(取自于楼主的话)
刚接触破解, 若有错误请指教.
|