请大家先看看代码,我的问题在代码后面。
程序源代码如下:
#include <windows.h>
PROC lpAddr = MessageBoxA;
PROC SetHook(LPCSTR lpModuleName, PROC lpFuncAddr, PROC pNewProc) {
LPBYTE lpByte;
LPDWORD lpAddr;
DWORD dwAddr;
lpByte = (LPBYTE)lpFuncAddr;
if(lpByte[0] == 0xff && lpByte[1] == 0x25) {
lpAddr = (LPDWORD)(&lpByte[2]);
dwAddr = lpAddr[0];
lpAddr = dwAddr;
dwAddr = lpAddr[0];
WriteProcessMemory(GetCurrentProcess(), lpAddr,
&pNewProc, sizeof(DWORD), NULL);
return (PROC)dwAddr;
}
return NULL;
}
int APIENTRY MyMessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType) {
int ret = 0;
if(lpAddr) {
ret = lpAddr(NULL, "new", "new", MB_OK);
}
return ret;
}
int main() {
lpAddr = SetHook("user32.dll", lpAddr, MyMessageBox);
MessageBoxA(NULL, "old", "old", MB_OK);
return 0;
}
程序类似于API HOOK,main中调用MessageBoxA时给的参数是"old",运行后显示的对话框文本是"new"。这就是效果。现在我的问题是:
上述程序稍微改动一下,主要是,在main函数调用SetHook之前再次使用
lpAddr = MessageBoxA
赋一次值,这个程序就不会有上述的运行效果了。所以自己写了个打印内存的函数,有以下五种情形,自己百思不得其解:
(dumpMem是自己写的一个函数,第一个参数是内存地址,后面的参数不用管,这个函数输出时首先输出地址值,然后输出这个地址处的内存内容,下面是用16进制输出的内存内容,最后输出与这些内存内容相对应的ASCII文本)
情形一:
PROC lpAddr = MessageBoxA;
int main() {
dumpMem(lpAddr, 16, 16, UNIT_BYTE, 16);
return 0;
}
输出:
004015D2 ff 25 ac a2 42 0 cc cc cc cc cc cc cc cc 55 8b .%..B.........U.
情形二:
PROC lpAddr = MessageBoxA;
int main() {
dumpMem(MessageBoxA, 16, 16, UNIT_BYTE, 16);
return 0;
}
输出:
77D5050B 8b ff 55 8b ec 83 3d 1c 4 d7 77 0 74 24 64 a1 ..U...=...w.t$d.
情形三:
int main() {
PROC lpAddr = MessageBoxA;
dumpMem(lpAddr, 16, 16, UNIT_BYTE, 16);
return 0;
}
输出:
77D5050B 8b ff 55 8b ec 83 3d 1c 4 d7 77 0 74 24 64 a1 ..U...=...w.t$d.
情形四:
PROC lpAddr;
int main() {
lpAddr = MessageBoxA;
dumpMem(lpAddr, 16, 16, UNIT_BYTE, 16);
return 0;
}
输出:
77D5050B 8b ff 55 8b ec 83 3d 1c 4 d7 77 0 74 24 64 a1 ..U...=...w.t$d.
情形五:
PROC lpAddr = MessageBoxA;
int main() {
lpAddr = MessageBoxA;
dumpMem(lpAddr, 16, 16, UNIT_BYTE, 16);
return 0;
}
输出:
77D5050B 8b ff 55 8b ec 83 3d 1c 4 d7 77 0 74 24 64 a1 ..U...=...w.t$d.