麻烦各位看一下我的代码,用钩子拦截api函数的,修改输入表地址
这段代码编译通过,可是些个测试程序,加载dll,start hook,再弹个messagebox,可是这个messagebox并没有被替换,怎么会事?
#ifndef _HOOK_H_
#define _HOOK_H_
typedef struct tag_HOOKAPI
{
LPCSTR szFun; //被HOOK的函数名称
PROC pNewProc; //新的函数地址
PROC pOldProc; //被替代的函数地址
}HOOKAPI,*LPHOOKAPI;
class AFX_EXT_CLASS CKeyHook: public CObject
{
public:
CKeyHook();
~CKeyHook();
public:
HHOOK Start();
bool Stop();
};
#endif
#include "stdafx.h"
#include <afxdllx.h>
#include "ActiveKey.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
static AFX_EXTENSION_MODULE HookDLL = { NULL, NULL };
#pragma data_seg("sharedata")
HHOOK g_Hook=NULL;
#pragma data_seg()
HINSTANCE g_Instance=NULL;
extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
// Remove this if you use lpReserved
UNREFERENCED_PARAMETER(lpReserved);
if (dwReason == DLL_PROCESS_ATTACH)
{
TRACE0("HOOK.DLL Initializing!\n");
// Extension DLL one-time initialization
if (!AfxInitExtensionModule(HookDLL, hInstance))
{
return 0;
}
new CDynLinkLibrary(HookDLL);
g_Instance = (HINSTANCE)hInstance;
}
else if (dwReason == DLL_PROCESS_DETACH)
{
TRACE0("HOOK.DLL Terminating!\n");
AfxTermExtensionModule(HookDLL);
}
return 1; // ok
}
CKeyHook m_hook;
//函数声明
static int WINAPI MessageBoxA1(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCation,UINT uType);
extern "C" __declspec(dllexport) HookAPIByName(HMODULE hModule,/*进程模块句柄*/
LPCSTR szImportMod,/*输入库名称*/
LPHOOKAPI pHookApi)/*HOOKAPI结构指针*/;
//键盘钩子处理过程
extern "C" LRESULT WINAPI KeyBoardProc(int nCode,WPARAM wParam,LPARAM lParam)
{
return CallNextHookEx(g_Hook,nCode,wParam,lParam);
}
CKeyHook::CKeyHook()
{
HOOKAPI api;
api.szFun= "MessageBoxA"; //被拦截R的函数名
api.pNewProc = (PROC)MessageBoxA1;//设置替换函数的地址
HookAPIByName(g_Instance,"User32.dll",&api);
}
CKeyHook::~CKeyHook()
{
}
//导出类的启动钩子函数
HHOOK CKeyHook::Start()
{
g_Hook=SetWindowsHookEx(WH_GETMESSAGE,KeyBoardProc,g_Instance,0);
return g_Hook;
}
//停止钩子函数
bool CKeyHook::Stop()
{
if(g_Hook)
{
return UnhookWindowsHookEx(g_Hook);
}
return true;
}
extern "C" __declspec(dllexport)PIMAGE_IMPORT_DESCRIPTOR LocationIAT(HMODULE hModule,
LPCSTR szImportMod)
{
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER) hModule;
//检查是否为DOS程序,如果是返回NULL,因为DOS没有IAT
if( pDosHeader->e_magic != IMAGE_DOS_SIGNATURE )
{
return NULL;
}
//检查是否为NT标志
PIMAGE_NT_HEADERS pNtHeader=(PIMAGE_NT_HEADERS)((DWORD)pDosHeader
+(DWORD)(pDosHeader->e_lfanew));
if(pNtHeader->Signature != IMAGE_NT_SIGNATURE)
{
return NULL;
}
//没有IAT表则返回
if(pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress
== 0)
{
return NULL;
}
//定位第一个IAT位置
PIMAGE_IMPORT_DESCRIPTOR pImportDesc=(PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pDosHeader
+ (DWORD)pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
//根据输入库名称循环检查所有的IAT,如匹配则返回该IAT地址,否则检测下一个IAT
while(pImportDesc->Name)
{
//获取该IAT描述的输入库名称
PSTR szCurMod = (PSTR)((DWORD)pDosHeader + (DWORD)(pImportDesc->Name));
if(0 == stricmp(szCurMod,szImportMod))
{
break;
}
pImportDesc++;
}
if(NULL == pImportDesc->Name)
{
return NULL;
}
return pImportDesc;
}
//定位被拦截API函数的IAT并修改其内容为替代函数地址
extern "C" __declspec(dllexport) HookAPIByName(HMODULE hModule,/*进程模块句柄*/
LPCSTR szImportMod,/*输入库名称*/
LPHOOKAPI pHookApi)/*HOOKAPI结构指针*/
{
//定位szImportMod输入库在输入数据段中的IAT地址
PIMAGE_IMPORT_DESCRIPTOR pImportDesc = LocationIAT(hModule,szImportMod);
if(pImportDesc == NULL)
{
return FALSE;
}
//第一个Thunk地址
PIMAGE_THUNK_DATA pOrigThunk = (PIMAGE_THUNK_DATA)((DWORD)hModule
+ (DWORD)(pImportDesc->OriginalFirstThunk));
//第一个IAT的Thunk地址
PIMAGE_THUNK_DATA pRealThunk = (PIMAGE_THUNK_DATA)((DWORD)hModule
+ (DWORD)(pImportDesc->FirstThunk));
//循环检测被拦截API函数的IAT项,并使用替代函数地址修改其值
while(pOrigThunk->u1.Function)
{
//检测此Thunk是否为IAT项
if((pOrigThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG) != IMAGE_ORDINAL_FLAG)
{
PIMAGE_IMPORT_BY_NAME pByName = (PIMAGE_IMPORT_BY_NAME)((DWORD)hModule
+(DWORD)(pOrigThunk->u1.AddressOfData));
if(pByName->Name[0] == '\0')
{
return FALSE;
}
//检测是否为拦截的函数
if(strcmpi(pHookApi->szFun,(char*)pByName->Name) == 0)
{
MEMORY_BASIC_INFORMATION mbi_thunk;
//查询修改页的信息
VirtualQuery(pRealThunk,&mbi_thunk,sizeof(MEMORY_BASIC_INFORMATION));
//改变修改页保护属性为PAGE_READWRITE
VirtualProtect(mbi_thunk.BaseAddress,mbi_thunk.RegionSize,PAGE_READWRITE,
&mbi_thunk.Protect);
//保存原来的API函数地址
if(pHookApi->pOldProc == NULL)
{
pHookApi->pOldProc = (PROC)pRealThunk->u1.Function;
}
//修改API函数IAT项内容为替代函数地址
pRealThunk->u1.Function = (PDWORD)pHookApi->pNewProc;
//恢复保护属性
DWORD dwOldProtect;
VirtualProtect(mbi_thunk.BaseAddress,mbi_thunk.RegionSize,mbi_thunk.Protect,
&dwOldProtect);
}
pOrigThunk++;
pRealThunk++;
}
SetLastError(ERROR_SUCCESS);
return TRUE;
}
}
//定义替代函数,拦截MessageBoxA函数
int WINAPI MessageBoxA1(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCation,UINT uType)
{
return MessageBox(hWnd,"Hook API OK!","Hook API",uType);
return 1;
}