假设我们在一程序Msg.exe内调用这三个函数,
那么,当我们调用::MessageBox时,会先在Msg.exe的输入表中找到::MessageBox对应的地址,再进行调用。
因此,如果我们想进行::MessageBox这个API函数的拦截时,我们可以通过修改程序的输入表(Import Table)来实现。
然而, 对于AfxMessageBox和CWnd::MessageBox这两个函数,或许你曾经听高人说过,实际上这两个函数内部也是通过调
用::MessageBox这个API函数来实现的。那么, 这样一来,很多新手就会有这样一个疑问了,为什么我拦截::MessageBox这个函数后(直
接调用该函数可以转入预定义的中转函数),再调用AfxMessageBox和CWnd::MessageBox这两个函数中任意一个的时候为什么不能跳转
到预定义的中转函数中呢 ?
首先, 我们得从PE文件的结构说起。在EXE程序被加载到内存的过程中,事实上, 在其背后(我们看不过的过程)还进行着一些我们不
知道的事。这里我指的不知道的事,即隐式加载一些程序运行所依赖的模块(大多数情况下是DLL)。举个例子,MFC程序在加载过程中也加入
以下一些DLL:
ntdll.dll
kernel32.dll
user32.dll
gdi32.dll
MFC42D.DLL
MFCO42D.DLL
MSVCRTD.DLL
...
...
你可以通过Module32First、Module32Next去具体看看。在观察过程中, 你可能会发现一个类似Msg.exe的模块,这是程序在内存中的
映像。我们所说的输入表就存在于这个映射文件的结构中(PE结构),我们所做的修改也在这个文件内,但这不是我要谈的重点。事实上,
在调用AfxMessageBox和CWnd::MessageBox这两个函数的时候,程序调用的是位于MFC42D.DLL和MFCO42D.DLL中相应的函数。
因此,若想要拦截AfxMessageBox或者CWnd::MessageBox,就必须修改MFC42D.DLL和MFCO42D.DLL的输入表(DLL也属于PE文
件结构)。
另外,若要进行彻底些的拦截,最好还要修改下DLL模块导出表相应函数的地址。