我从网上下了部分代码,写了一个钩子函数获取textout输出内容。一个是包含钩子函数的DLL程序包,另一个应用程序安装了改钩子,调用了TextOut之后。
DLL里的TextOut钩子函数未被调用,请大侠指点一下问题出在哪儿?
附DLL 钩子程序包。
CPP部分:
#include "stdafx.h"
#include "hook.h"
#include "winuser.h"
#include
#include
#pragma comment(lib,"ImageHlp") //定义全局共享数据段
#pragma data_seg("Shared")
HMODULE hmodDll=NULL;
HHOOK hHook=NULL;
#pragma data_seg()
#pragma comment(linker,"/Section:Shared,rws") //设置全局共享数据段的属性
//dll的入口点
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch(ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
break;
case DLL_PROCESS_DETACH:
break;
}
hmodDll=hModule;
return TRUE;
}
void WINAPI HookOneAPI(LPCTSTR pszCalleeModuleName,PROC pfnOriginApiAddress,
PROC pfnDummyFuncAddress,HMODULE hModCallerModule)
{
ULONG size;
//获取指向PE文件中的Import中IMAGE_DIRECTORY_DESCRIPTOR数组的指针
PIMAGE_IMPORT_DESCRIPTOR pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)
ImageDirectoryEntryToData(hModCallerModule,TRUE,IMAGE_DIRECTORY_ENTRY_IMPORT,&size);
if (pImportDesc == NULL)
return;
//查找记录,看看有没有我们想要的DLL
for (;pImportDesc->Name;pImportDesc++)
{
LPSTR pszDllName = (LPSTR)((PBYTE)hModCallerModule+pImportDesc->Name);
if (lstrcmpiA(pszDllName,pszCalleeModuleName) == 0)
break;
}
if (pImportDesc->Name == NULL) return;
//寻找我们想要的函数
PIMAGE_THUNK_DATA pThunk = (PIMAGE_THUNK_DATA)((PBYTE)hModCallerModule+pImportDesc->FirstThunk);
for (;pThunk->u1.Function;pThunk++)
{
//ppfn记录了与IAT表项相应的函数的地址
PROC * ppfn= (PROC *)&pThunk->u1.Function;
if (*ppfn == pfnOriginApiAddress)
{
//如果地址相同,也就是找到了我们想要的函数,进行改写,将其指向我们所定义的函数
WriteProcessMemory(GetCurrentProcess(),ppfn,&(pfnDummyFuncAddress),
sizeof(pfnDummyFuncAddress),NULL);
return;
}
}
}
//查找所挂钩的进程所应用的dll模块的
BOOL WINAPI HookAllAPI (LPCTSTR pszCalleeModuleName,PROC pfnOriginApiAddress,
PROC pfnDummyFuncAddress,HMODULE hModCallerModule)
{
if (pszCalleeModuleName == NULL) return FALSE;
if (pfnOriginApiAddress == NULL) return FALSE;
MEMORY_BASIC_INFORMATION mInfo;
HMODULE hModHookDLL;
HANDLE hSnapshot;
MODULEENTRY32 me = {sizeof(MODULEENTRY32)};
//MODULEENTRY32:描述了一个被指定进程所应用的模块的struct
VirtualQuery(HookOneAPI,&mInfo,sizeof(mInfo));
hModHookDLL=(HMODULE)mInfo.AllocationBase;
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,0);
BOOL bOk = Module32First(hSnapshot,&me);
if (bOk == FALSE) return FALSE;
while (bOk)
{
if (me.hModule != hModHookDLL)
{
hModCallerModule = me.hModule;//赋值
//me.hModule:指向当前被挂钩进程的每一个模块
HookOneAPI(pszCalleeModuleName,pfnOriginApiAddress,
pfnDummyFuncAddress,hModCallerModule);
}
bOk = Module32Next(hSnapshot,&me);
}
return TRUE;
}
//通过使pfnDummyFuncAddress与pfnOriginApiAddress相等的方法,取消对IAT的修改
BOOL WINAPI UnhookAllAPIHooks(LPCTSTR pszCalleeModuleName,PROC pfnOriginApiAddress,
PROC pfnDummyFuncAddress,HMODULE hModCallerModule)
{
PROC temp;
temp = pfnOriginApiAddress;
pfnOriginApiAddress = pfnDummyFuncAddress;
pfnDummyFuncAddress = temp;
return HookAllAPI(pszCalleeModuleName,pfnOriginApiAddress,
pfnDummyFuncAddress,hModCallerModule);
}
//钩子子程。与其它钩子子程不大相同,没做什么有意义的事情,继续调用下一个钩子子程,形成循环
LRESULT CALLBACK GetMsgProc(int code,WPARAM wParam,LPARAM lParam)
{
return CallNextHookEx(hHook,code,wParam,lParam);
}
void __declspec(dllexport) WINAPI InstallHook(BOOL IsHook,DWORD dwThreadId)
{
if(IsHook)
{
hHook=SetWindowsHookEx(WH_GETMESSAGE,(HOOKPROC)GetMsgProc,hmodDll,dwThreadId);
//GetProcAddress(GetModuleHandle("GDI32.dll"),"ExtTextOutA"):取得要钩的函数在所在dll中的地址
HookAllAPI("GDI32.dll",GetProcAddress(GetModuleHandle("GDI32.dll"),
"TextOutW"),(PROC)&H_TextOutW,NULL);
HookAllAPI("GDI32.dll",GetProcAddress(GetModuleHandle("GDI32.dll"),
"TextOutA"),(PROC)&H_TextOutA,NULL);
}
else
{
UnInstallHook();
//Beep(440,1000);
UnhookAllAPIHooks("GDI32.dll",GetProcAddress(GetModuleHandle("GDI32.dll"),
"TextOutA"),(PROC)&H_TextOutA,NULL);
UnhookAllAPIHooks("GDI32.dll",GetProcAddress(GetModuleHandle("GDI32.dll"),
"TextOutW"),(PROC)&H_TextOutW,NULL);
}
}
//卸载钩子
BOOL WINAPI UnInstallHook()
{
UnhookWindowsHookEx(hHook);
return TRUE;
}
/*======================TextOutA/W 接口函数=========================================*/
BOOL WINAPI H_TextOutA(HDC hdc,int nXStart,int nYStart,LPCSTR lpString,int cbString)
{
MessageBox(NULL,"textout captured!!!","test",MB_OK);
TextOut(hdc,nXStart,nYStart,LPCSTR(lpString),cbString);//返回原来的函数,以显示字符
return TRUE;
}
BOOL WINAPI H_TextOutW(HDC hdc,int nXStart,int nYStart,LPCSTR lpString,int cbString)
{
MessageBox(NULL,"TextOutW","APIHook_Dll ---rivershan",MB_OK);
TextOut(hdc,nXStart,nYStart,LPCSTR(lpString),cbString);//返回原来的函数,以显示字符
return TRUE;
}
H文件部分:
#ifdef HOOK_EXPORTS
#define HOOK_API __declspec(dllexport)
#else
#define HOOK_API __declspec(dllimport)
#endif
extern HOOK_API int nHook;
HOOK_API int fnHook(void);
void __declspec(dllexport) WINAPI InstallHook(BOOL,DWORD);
BOOL WINAPI UnInstallHook();
LRESULT CALLBACK GetMsgProC(int code,WPARAM wParam,LPARAM lParam);
void WINAPI HookOneAPI(LPCTSTR pszCalleeModuleName,PROC pfnOriginApiAddress,
PROC pfnDummyFuncAddress,HMODULE hModCallerModule);
BOOL WINAPI HookAllAPI(LPCTSTR pszCalleeModuleName,PROC pfnOriginApiAddress,
PROC pfnDummyFuncAddress,HMODULE hModCallerModule);
BOOL WINAPI UnhookAllAPIHooks(LPCTSTR pszCalleeModuleName,PROC pfnOriginApiAddress,
PROC pfnDummyFuncAddress,HMODULE hModCallerModule);
BOOL WINAPI H_TextOutA(HDC, int, int, LPCSTR, int);
BOOL WINAPI H_TextOutW(HDC, int, int, LPCSTR, int);