{
if (pfn == p->m_pfnOrig)
{
pfn = p->m_pfnHook;
break;
}
}
return (pfn);
}
void WINAPI CAPIHOOK::ReplaceIATEntryInOneMod(PCSTR pszCalleeModName, PROC
pfnCurrent, PROC pfnHook, HMODULE hmodcaller, HANDLE handle)
{
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 && (*ppfn > sm_pvMaxAppAddr))
{
PBYTE pbInFunc = (PBYTE) *ppfn;
if (pbInFunc[0] == cPushOpCode)
{
ppfn = (PROC*) &pbInFunc;
fFound = (*ppfn == pfnCurrent);
}
}
if (fFound)
{
HANDLE handle1 = OpenProcess(PROCESS_ALL_ACCESS, FALSE,
GetCurrentProcessId());
DWORD dwIdOld;
VirtualProtectEx(handle1, ppfn, sizeof(pfnHook), PAGE_READWRITE, &dwIdOld);
if (WriteProcessMemory(handle1, ppfn, &pfnHook, sizeof(pfnHook), NULL) == false)
{
return ;
}
else
{
VirtualProtectEx(handle1, ppfn, sizeof(pfnHook), dwIdOld, &dwIdOld);
return ;
}
}
}
}
上面是APIHOOK的完整代码。下面是使用的例子(拦截WString2ID函数):
typedef unsigned long(__stdcall *WString2ID)(char const*);
unsigned long __stdcall myWString2ID(char const*);
CAPIHOOK *My_WString2ID;
My_WString2ID = new CAPIHOOK("windsoul.dll", "?WString2ID@@YGKPBD@Z",
(PROC)myWString2ID, gamehandle, gameInstance);
自己的myWString2ID的实现:
unsigned long __stdcall myWString2ID(char const *a)
{
// SendMessage(wghandle,WM_USER 1,(WPARAM)a,NULL);
return (((WString2ID)My_WString2ID->m_pfnOrig)(a));
}
下面是用来拦截游戏的WndProc函数的,当时写的时候为了全面,至于如何去用,随便自己了,反正我没有用。
gamehWnd = GetActiveWindow();
gamehandle =GetCurrentProcess();
gameInstance = (HINSTANCE)GetWindowLong(gamehWnd, GWL_HINSTANCE);
gameproc = (WNDPROC)SetWindowLong(gamehWnd, GWL_WNDPROC, (LONG) MyMsgProc);
自己用来替换游戏的WndProc函数:
LRESULT APIENTRY MyMsgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM
lParam)
{
/*在这里做自己想做的事情,剩下的让游戏的WndProc来处理*/
return CallWindowProc(gameproc, hwnd, message, wParam, lParam);
}
这一节到这里就结束了,下一节开始游戏程序的研究。最好准备大话客户端9.16更新之前的最后一个版本,不使用最新的版本有下面的原因:
1、 如果对现在客户端作过多的透漏的话,将会发现做盗号类的程序比做外挂要简单,这不是我所