Hook API为何不成功?
我将Hook API(拦截MessageBox)做成DLL,然后由另一个程序将此DLL注入别的进程(如Notepad),为什么执行时出现内存读写错误?DLL代码很简单:
void ReplaceATEntryInOneMod(PCSTR pszCalleeModName, PROC pfnCurrent, PROC pfnNew, HMODULE hmodCaller);
int WINAPI MyMessageBoxA(HWND, PCSTR, PCSTR, UINT);
int WINAPI MyMessageBoxW(HWND, PCWSTR, PCWSTR, UINT);
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
PROC pfnOrig1 = ::GetProcAddress(GetModuleHandleA("User32.dll"), "MessageBoxA");
ReplaceATEntryInOneMod("User32.dll", pfnOrig1, (PROC)MyMessageBoxA, GetModuleHandle(NULL));
PROC pfnOrig2 = ::GetProcAddress(GetModuleHandleA("User32.dll"), "MessageBoxW");
ReplaceATEntryInOneMod("User32.dll", pfnOrig2, (PROC)MyMessageBoxW, GetModuleHandle(NULL));
}
}
void ReplaceATEntryInOneMod(PCSTR pszCalleeModName, PROC pfnCurrent, PROC pfnNew, HMODULE hmodCaller)
{
ULONG ulSize;
PIMAGE_IMPORT_DESCRIPTOR pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData(hmodCaller, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &ulSize);
if (pImportDesc == NULL)
return;
for(; pImportDesc->Name; pImportDesc++)
{
PSTR pszModName = (PSTR)((PBYTE) hmodCaller + pImportDesc->Name);
if (lstrcmpiA(pszModName, pszCalleeModName) == 0)
break;
}
if (pImportDesc->Name == 0)
return;
PIMAGE_THUNK_DATA pThunk = (PIMAGE_THUNK_DATA) ((PBYTE)hmodCaller + pImportDesc->FirstThunk);
for(; pThunk->u1.Function; pThunk++)
{
PROC* ppfn = (PROC*)&pThunk->u1.Function;
BOOL fFound = (*ppfn == pfnCurrent);
if (fFound)
{
WriteProcessMemory(GetCurrentProcess(),pfnCurrent, &pfnNew,sizeof(pfnNew), NULL);
return;
}
}
}
int WINAPI MyMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)
{
return 0;
}
int WINAPI MyMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType)
{
return 0;
}