一 调用系统函数 MessageBoxA
VC | MessageBoxA(NULL,NULL,NULL,MB_OK) | CALL dword ptr [0040d244] | VC作了优化 |
ASM | invoke MessageBoxA,NULL,NULL,NULL,MB_OK | Call 401abc 401abc :jmp dword ptr [0040d244] | 未优化时,函数名代表了jmp dword ptr [0040d244]的地址 |
二 调用内部函数 (函数名就是一个标号,均代表一个地址,VC的标号指向JMP XXXX,ASM的标号则直接指向函数体)
VC
SetHook(lpAddr,MyMessageBox); | CALL 40100f 40100f:jmp 401030(E91C000000) | 1C0(步长)+40100f(本条地址)+5(本条所占地址)=401030 1C(步长)+5(本条所占地址) = 本条地址到目标函数地址的距离 |
ASM
CALL _SubProc | Call 40170D 40170D:push ebp mov ebp,esp |
例子:
#include <windows.h>
PROClpAdder = MessageBoxA;//存了E9 +步长的地址, E9 + 步长会跳转到 JMP DWORD PTR [AD]处 (VC6中会直接指向JMP DWORD PTR [XXXXXXXX] )
//【知识点】
//1运算时一定要先把地址存入指向指向单字节指针中
//2要取单字节就将地址存入指向单字节指针中,要取四字节就将地址存入指向四字节的指针中,之后用指针[0]输出即可
PROC SetHook(PROClpFucAdder, PROC pNewProc )
{
LPBYTE lpByte;
LPDWORD lpAddr;
DWORD dwAddr;
lpByte= (LPBYTE) lpFucAdder;//【运算时一定要先把地址存入指向指向单字节指针中】
// JMP DWORD PTR [XXXXXXXX] => FF 25 XX XX XX XX ,由于JMP +DWORD PTR 操作码就变成了FF25
if(lpByte[0] == 0xFF && lpByte[1] == 0x25)
{
lpAddr =(LPDWORD)(&lpByte[2]);
dwAddr =lpAddr[0];//将XXXXXXXX存入dwAddr中
lpAddr =(unsigned long *)dwAddr;//XXXXXXXX指向的就是函数体的4字节地址值,要修改函数体的四字节地址值,就要写上XXXXXXXX,见下方的WriteProcessMemory
dwAddr =lpAddr[0];//将[XXXXXXXX]输出的系统API函数体的地址值存入dwAddr中
WriteProcessMemory(GetCurrentProcess(),lpAddr,&pNewProc,sizeof(DWORD),NULL);//修改[XXXXXXXX]输出的地址,即函数体地址
return(PROC)dwAddr;
}
returnNULL;
}
int APIENTRYMyMessageBox(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType)
{
int ret= 0;
if(lpAdder != NULL)
ret =lpAdder(NULL,"new","new",MB_OK);
returnret;
}
void main()
{
//lpAdder= MessageBoxA;//存了 " E9 + 步长 "的地址, E9 + 步长会跳转到 " JMP DWORD PTR [AD] " 处
LPBYTEpByte;
LPDWORD pAddr;
DWORDdwAddr;
//从JMP后取出步长。先取出步长的地址然后存入LPDWORD的指针中,之后再输出即可得到步长
pByte =(LPBYTE) lpAdder;//将 " E9 + 步长 "的地址存入到字节的指针中,为了计算地址用【运算时一定要先把地址存入指向指向单字节指针中】
pAddr =(LPDWORD)(&pByte[1]);//LPDOWD类型的pAddr是为了输取出4个字节的步长,&pByte[1]见指针逆向来理解【要取四字节就将地址存入指向四字节的指针中,之后用指针[0]输出即可】
dwAddr =pAddr[0];//取出步长并存入dwAddr中
pByte +=5;//加上E9 + 步长所占的5个字节
pByte +=dwAddr;//加上步长,得到JMP DWORD PTR [AD]处的地址
//进行HOOK操作
lpAdder= SetHook((PROC)pByte, MyMessageBox);//pByte 指向了 ff 25 dc 73 0c 01 即 JMP DWORD PTR [XXXXXXXX]
//调用系统API时,进入MyMessageBox函数,实现HOOK系统API的效果
MessageBoxA(NULL,"old","old",MB_OK);
}
| XX |
|
| XX |
|
| XX |
|
| XXX |
|
| XXX |
|
| XX |
|
| EDI |
|
| EDI |
|
7674EA11 | MOV | 函数体 |
| 。 |
|
| 。 |
|
| 。 |
|
| 76 |
|
| 74 |
|
| EA |
|
0xDB73DC | 11 |
|
| 。 |
|
| 。 |
|
| 。 |
|
| 00 |
|
| DB |
|
| 73 |
|
| DC |
|
| DWORD PTR |
|
0x1068428 | JMP | 1067045 + 13DE + 5 = 0x1068428 |
| 。 |
|
| 。 |
|
| 。 |
|
| 00 |
|
| 00 |
|
| 13 |
|
| DE |
|
(MessageBoxA)1067045 | E9 | E9DE13 |