关于HOOK API拦截不到想要拦截的函数问题

haobi704486377 2009-09-26 08:45:32
希望能够帮帮小弟
程序源代码:
void CTestAPIDlg::OnHook()
{
// TODO: Add your control notification handler code here
HMODULE m_hdl = GetModuleHandle(NULL);
HMODULE m_hdldll=LoadLibrary("User32.dll");
FARPROC m_ProAdd = GetProcAddress(m_hdldll,"MessageBoxA");

//pf*m_pf=MessageBoxQ;
//fp=MessageBox;
ReplaceIATEntryInOneMod("User32.dll" , m_ProAdd , (PROC)MessageBoxQ , m_hdl);
}

void CTestAPIDlg::ReplaceIATEntryInOneMod(PCSTR pszCalleeModName, PROC pfnCurrent, PROC pfnNew, HMODULE hmodCaller)
{
ULONG ulSize;

PIMAGE_IMPORT_DESCRIPTOR pImportDesc = NULL;
__try {
pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR) ImageDirectoryEntryToData(
hmodCaller, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &ulSize);
}
__except (InvalidReadExceptionFilter(GetExceptionInformation())) {

}

if (pImportDesc == NULL)
return; // This module has no import section or is no longer loaded

for (; pImportDesc->Name; pImportDesc++)
{
PSTR pszModName = (PSTR) ((PBYTE) hmodCaller + pImportDesc->Name);
if (lstrcmpiA(pszModName, pszCalleeModName) == 0)
{

PIMAGE_THUNK_DATA pThunk = (PIMAGE_THUNK_DATA)
((PBYTE) hmodCaller + pImportDesc->FirstThunk);

// Replace current function address with new function address
for (; pThunk->u1.Function; pThunk++)
{

// Get the address of the function address
PROC* ppfn = (PROC*) &pThunk->u1.Function;

// Is this the function we're looking for?
BOOL bFound = (*ppfn == pfnCurrent);
if (bFound)
{
if (!WriteProcessMemory(GetCurrentProcess(), ppfn, &pfnNew, sizeof(pfnNew), NULL) && (ERROR_NOACCESS == GetLastError()))
{
DWORD dwOldProtect;
if (VirtualProtect(ppfn, sizeof(pfnNew), PAGE_WRITECOPY, &dwOldProtect))
{
WriteProcessMemory(GetCurrentProcess(), ppfn, &pfnNew, sizeof(pfnNew), NULL);
VirtualProtect(ppfn, sizeof(pfnNew), dwOldProtect, &dwOldProtect);
}
}
return; // We did it, get out
}
}
} // Each import section is parsed until the right entry is found and patched
}
}

void CTestAPIDlg::OnMsgbox()
{
// TODO: Add your control notification handler code here
MessageBoxA("没有被截取到!");
}
...全文
204 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
WuXinyang 2009-09-26
  • 打赏
  • 举报
回复
4楼,就是那么回事.
Johnny_Lx 2009-09-26
  • 打赏
  • 举报
回复
对了,楼主想研究HOOK的话windows核心编程对API重定位有详细的解说,可以看一下
xwsn007 2009-09-26
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 zison_sun 的回复:]
找到一个解释

我来解释一下,这种现象是正常的

你的hook是导入表hook

说白了只能hook到程序静态引入的函数

如果你在程序中使用::MessageBox则最终程序中确实引入了user32.dll中的MessageBoxA函数,这样可以hook到

如果你用CWnd::MessageBox来调用就不行了

或许你也知道CWnd::MessageBox最终也是调用了::MessageBox

但是你的程序没有直接导入::MessageBox

因为CWnd::MessageBox也是一个导出函数,具体名字大约是msvc60.dll之类的

是一个MFC的支持库

因此你hook导入表的时候根本找不到::MessageBox的引入

而只能找到CWnd::MessageBox的引入(这个引入的名字很复杂,是变形过的)

所以你的hook无法成功

///////////////////////////////////////////////////////////////
你所提到的问题恰恰是导入表式hook的局限性

只有改变hook的形式才能根本上解决这个问题

新的hook方式就是inline hook

[/Quote]

同意这个说
  • 打赏
  • 举报
回复
找到一个解释

我来解释一下,这种现象是正常的

你的hook是导入表hook

说白了只能hook到程序静态引入的函数

如果你在程序中使用::MessageBox则最终程序中确实引入了user32.dll中的MessageBoxA函数,这样可以hook到

如果你用CWnd::MessageBox来调用就不行了

或许你也知道CWnd::MessageBox最终也是调用了::MessageBox

但是你的程序没有直接导入::MessageBox

因为CWnd::MessageBox也是一个导出函数,具体名字大约是msvc60.dll之类的

是一个MFC的支持库

因此你hook导入表的时候根本找不到::MessageBox的引入

而只能找到CWnd::MessageBox的引入(这个引入的名字很复杂,是变形过的)

所以你的hook无法成功

///////////////////////////////////////////////////////////////
你所提到的问题恰恰是导入表式hook的局限性

只有改变hook的形式才能根本上解决这个问题

新的hook方式就是inline hook
  • 打赏
  • 举报
回复
是做了封装,不过归根到底还是用的那个全局的MessageBox,因为动态链接时根据IAT里调用的还是USER32.DLL里面的MessagBoxA,W而已。
WuXinyang 2009-09-26
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 zison_sun 的回复:]
听我说,你写一个基于WIN32的程序A,程序A里调用MessageBox,用这个程序做测试,因为MFC里调用的MessageBox不能捕获,理论上调用的都是那个全局的MessageBox,但却不捕获。不知道为啥。
[/Quote]

MFC对MessageBox做了封装了的吧.
  • 打赏
  • 举报
回复
听我说,你写一个基于WIN32的程序A,程序A里调用MessageBox,用这个程序做测试,因为MFC里调用的MessageBox不能捕获,理论上调用的都是那个全局的MessageBox,但却不捕获。不知道为啥。
  • 打赏
  • 举报
回复
我经过测试,成功HOOK到了MFC里的CWnd::MessageBox(),CWnd的实际是调用了SDK里面的MessageBox,你可以查看MFC提供的源码,它的实现在WINCORE.CPP,可以清楚的看到它调用了sdk的,由于一般写MFC程序时,appwizard最后一步是都用动态链接,如果改成静态链接就可以HOOK到!
为什么动态链接就HOOK不到,还不清楚!或许可以只是方法不对,还待研究
fishion 2009-09-26
  • 打赏
  • 举报
回复
还有就是,要做成动态链接库形式
fishion 2009-09-26
  • 打赏
  • 举报
回复
怎么会是这样的,一样是可以的吧?在MFC中的MessageBoxA不就是经过封装了而已,但是在里面还是调用win32 MessageBoxA这个API吧,我刚刚测试过就没问题,你可以去下载个<windows 核心编程>的源码看下他是怎么拦截API的
野男孩 2009-09-26
  • 打赏
  • 举报
回复
void CTestAPIDlg::OnMsgbox1()
{
// TODO: Add your control notification handler code here
MessageBox("谢谢!");
}

这个MessageBox调用的是CWnd::MessageBoxA,可不是User32里面的MessageBoxA。IAT里面自然没有这个函数。MFC32.dll中的导出函数没有名字,所以只能用数字,这里MessageBox对应的是4224(我是VC6, Win2k3 SP1)。 强制hack的方法如下:

OnHook:
HMODULE m_hdl = GetModuleHandle(NULL);
//去MFC42.dll中找(我调试的是Release版本,所以不是MFC42D.dll)CWnd::MessageBoxA
FARPROC m_ProAdd = GetProcAddress(LoadLibrary("MFC42.dll"),(LPCSTR)4224);
//然后以MessageBoxQ函数hook之
ReplaceIATEntryInOneMod("MFC42.dll" , m_ProAdd , (PROC)MessageBoxQ , m_hdl);

MessageBoxQ函数要注意,没有四个参数了,因为hook的是CWnd类成员函数,所以有个this指针在ECX寄存器。我是这么写的:
int WINAPI MessageBoxQ(LPCTSTR lpText,LPCTSTR lpCaption,UINT uType)
{
//break in debugger
__asm int 3;
return 0;
}

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧