按照《WINDOWS核心编程》上的方法想HOOK MessageBoxA函数 我的实现如下
PopMB.exe 按确定键弹出一个MessageBox
PushDLL.exe 用来注入DLL
bool PushDll(ULONG ID){ //PopMB 的PROCESS ID
void* pMemAddr=NULL;
HANDLE hProc=NULL,hth=NULL;
char DllName[128];
strncpy(DllName,DLLNAME,127);
bool bOK=false;
__try{
hProc=OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_CREATE_THREAD|PROCESS_VM_OPERATION|PROCESS_VM_WRITE,FALSE,ID);
if (hProc==NULL) __leave;
UINT size=strlen(DllName)+1;
size*=sizeof(char);
pMemAddr=VirtualAllocEx(hProc,NULL,size,MEM_COMMIT,PAGE_READWRITE);
if (!WriteProcessMemory(hProc,pMemAddr,DllName,size,NULL)) __leave;
LPTHREAD_START_ROUTINE pAddr=(LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle("Kernel32.dll"),"LoadLibraryA");
if (pAddr==NULL) __leave;
hth=CreateRemoteThread(hProc,NULL,0,pAddr,(LPVOID)pMemAddr,0,NULL);
if (hth==NULL) __leave;
MessageBox(NULL,"Now WaitForSingleObject","",MB_OK);
WaitForSingleObject(hth,INFINITE);
bOK=true;
}
__finally{
MessageBox(NULL,"Finally","",MB_OK);
if (pMemAddr!=NULL)
VirtualFreeEx(hProc,pMemAddr,0,MEM_RELEASE);
if (hProc!=NULL)
CloseHandle(hProc);
if (hth!=NULL)
CloseHandle(hth);
}
return bOK;
}
MB HOOK.DLL 用来HOOK MessageBoxA函数
// stdafx.h
#include <windows.h>
#include <windowsx.h>
#include <stdlib.h>
#include <conio.h>
#include <ImageHlp.h>
#include <string.h>
#include <stdio.h>
#pragma comment (lib,"ImageHlp")
// TODO: reference additional headers your program requires here
//MessageBoxA
//#define EXE_NAME "E:\\desk\\PushDLL\\Debug\\PopMB.exe"
WINUSERAPI int WINAPI MyMessageBox(HWND hWnd ,LPCSTR lpText,LPCSTR lpCaption,UINT uType);
typedef int (WINAPI* OldMessageBox)( HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType ) ;
//WINBASEAPI VOID WINAPI MyExitProcess(UINT uExitCode);
//typedef VOID (WINAPI* OldExitProcess)(UINT uExitCode);
bool HookAPI(const char *DllName,PROC OldAddr,PROC NewAddr,HMODULE ExeHandle);
bool HookDLL(void);
/////////////end/////////
//stdafx.cpp
#include "stdafx.h"
PROC OldAddr;
int WINAPI MyMessageBox(HWND hWnd ,LPCSTR lpText,LPCSTR lpCaption,UINT uType){
OldMessageBox pMB=(OldMessageBox)OldAddr;
int ret=pMB(hWnd,lpText,lpCaption,uType);
char S[16]="\0";
sprintf(S,"%d",ret);
pMB(NULL,S,"Return Value",MB_ICONWARNING|MB_OK);
return ret;
}
bool HookDLL(void){
OldAddr=GetProcAddress(GetModuleHandle("user32.dll"),"MessageBoxA");
if (OldAddr==NULL)
return false;
char S[128];
sprintf(S,"%p",OldAddr);
MessageBox(NULL,"GetProcAddress succeed","",MB_OK);
MessageBox(NULL,S,"",MB_OK|MB_ICONWARNING);
HMODULE ExeHandle=GetModuleHandle(NULL);
if (ExeHandle==NULL)
return false;
MessageBox(NULL,"GetModuleHandle succeed","",MB_OK);
PROC NewAddr=(PROC)MyMessageBox;
//PROC NewAddr=(PROC)MyExitProcess;
if (NewAddr==NULL)
return false;
MessageBox(NULL,"get new fun succeed","",MB_OK);
return HookAPI("user32.dll",OldAddr,NewAddr,ExeHandle);
}
bool HookAPI(const char *DllName,PROC OldAddr,PROC NewAddr,HMODULE ExeHandle){
ULONG ulSize=0L;
IMAGE_IMPORT_DESCRIPTOR *pID=NULL;
__try{
pID=(IMAGE_IMPORT_DESCRIPTOR*)ImageDirectoryEntryToData(ExeHandle,TRUE,IMAGE_DIRECTORY_ENTRY_IMPORT,&ulSize);
}
__except(GetExceptionInformation()){
;
}
if (pID==NULL)
return false;
MessageBox(NULL,"ImageDirectoryEntryToData succeed","",MB_OK);
for(;pID->Name;pID++){
char *Name=(char*)((BYTE*)ExeHandle+pID->Name);
MessageBox(NULL,Name,"",MB_ICONWARNING|MB_OK);
if (stricmp(DllName,Name)==0){
MessageBox(NULL,"DLL has founded","",MB_OK);
IMAGE_THUNK_DATA *pThunk=(IMAGE_THUNK_DATA*) ((BYTE*)ExeHandle+pID->FirstThunk);
for(;(pThunk->u1.Function)!=NULL;pThunk++){
PROC *pFun=(PROC*)&pThunk->u1.Function;
bool bFound=(*pFun==OldAddr)?true:false;
if (bFound){
MessageBox(NULL,"function has founded","",MB_OK);
if (!WriteProcessMemory(GetCurrentProcess(),pFun,&NewAddr,sizeof(NewAddr),NULL) && (ERROR_NOACCESS==GetLastError())){
DWORD OldPermit;
if (VirtualProtect(pFun,sizeof(NewAddr),PAGE_WRITECOPY,&OldPermit)){
WriteProcessMemory(GetCurrentProcess(),pFun,&NewAddr,sizeof(NewAddr),NULL);
VirtualProtect(pFun,sizeof(NewAddr),OldPermit,&OldPermit);
}
}
return true;
}
}
}
}
return false;
}
///////end//////
//MB_HOOK.cpp
#include "stdafx.h"
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch(ul_reason_for_call){
case DLL_PROCESS_ATTACH:
MessageBox(NULL,"DLL called","",MB_OK);
char S[512];
GetModuleFileName(NULL,S,512);
MessageBox(NULL,S,"",MB_OK);
MessageBox(NULL,(HookDLL())?"Succeed":"Failed","",MB_OK);
break;
}
return TRUE;
}
////////end//////////
问题是,每次成功注入DLL后,每次HookAPI函数只能找到USER32.dll并弹出"DLL has founded",但是就是找不到匹配的MessageBoxA的地址("function has founded"始终不出现)。
Debug Release都试过,改成HOOKKERNEL32.dll里的ExitProcess (《WINDOWS核心编程》上的例子) 也不行。但是如果把DLL中的函数全部复制到一个EXE中且让这个EXE HOOK 自身总能成功。编译器是VC++ 6.0