核心编程关于hookAPI的代码,有些地方不明白,有劳高手释疑

zy1691 2009-11-03 07:44:42
第22章最后的那个例子,关于hookAPI的。


///////////////////////////////////////////////////////////////////////////////


// When an application runs on Windows 98 under a debugger, the debugger
// makes the module's import section point to a stub that calls the desired
// function. To account for this, the code in this module must do some crazy
// stuff. These variables are needed to help with the crazy stuff.


// The highest private memory address (used for Windows 98 only)
PVOID CAPIHook::sm_pvMaxAppAddr = NULL;
const BYTE cPushOpCode = 0x68; // The PUSH opcode on x86 platforms


///////////////////////////////////////////////////////////////////////////////


// The head of the linked-list of CAPIHook objects
CAPIHook* CAPIHook::sm_pHead = NULL;


///////////////////////////////////////////////////////////////////////////////

CAPIHook::CAPIHook(PSTR pszCalleeModName, PSTR pszFuncName, PROC pfnHook,
BOOL fExcludeAPIHookMod) {

if (sm_pvMaxAppAddr == NULL) {
// Functions with address above lpMaximumApplicationAddress require
// special processing (Windows 98 only)
SYSTEM_INFO si;
GetSystemInfo(&si);
sm_pvMaxAppAddr = si.lpMaximumApplicationAddress;
}

m_pNext = sm_pHead; // The next node was at the head
sm_pHead = this; // This node is now at the head

// Save information about this hooked function
m_pszCalleeModName = pszCalleeModName;
m_pszFuncName = pszFuncName;
m_pfnHook = pfnHook;
m_fExcludeAPIHookMod = fExcludeAPIHookMod;
m_pfnOrig = GetProcAddressRaw(
GetModuleHandleA(pszCalleeModName), m_pszFuncName);
chASSERT(m_pfnOrig != NULL); // Function doesn't exist

if (m_pfnOrig > sm_pvMaxAppAddr) {
// The address is in a shared DLL; the address needs fixing up
PBYTE pb = (PBYTE) m_pfnOrig;
if (pb[0] == cPushOpCode) {
// Skip over the PUSH op code and grab the real address
PVOID pv = * (PVOID*) &pb[1];
m_pfnOrig = (PROC) pv;
}
}

// Hook this function in all currently loaded modules
ReplaceIATEntryInAllMods(m_pszCalleeModName, m_pfnOrig, m_pfnHook,
m_fExcludeAPIHookMod);
}




就是这个CAPIHook的构造函数,ReplaceIATEntryInAllMods前面的部分不太明白什么意思,希望哪位高手来给解释一下。
...全文
157 9 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
llaaddoo 2009-11-04
  • 打赏
  • 举报
回复
系统Dll都是在共享内存区域

如果IAT指向的API不在 共享内存区域 , 那么他就有可能被调试器更改过

调试器更改的方法类似
Push API
call debug Fun
ret

他先调用调试器的函数, 然后ret到原来的API函数

所以判断第一个push 再取后面的API地址

if (m_pfnOrig > sm_pvMaxAppAddr) {
// The address is in a shared DLL; the address needs fixing up
//如果m_pfnOrig > sm_pvMaxAppAddr,那就证明这是个98系统
//因为98下2GB的高位内存地址(大于0x80000000)是可以访问的,而2000或xp是不能的。
PBYTE pb = (PBYTE) m_pfnOrig;
if (pb[0] == cPushOpCode) {
// Skip over the PUSH op code and grab the real address
//在98下,如果是在x86平台下,得到的函数地址的首字节为0x68位标志
//而真正的函数基地址为pb+1
PVOID pv = * (PVOID*) &pb[1];
m_pfnOrig = (PROC) pv;
}
stjay 2009-11-04
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 zy1691 的回复:]
C/C++ codeif (m_pfnOrig> sm_pvMaxAppAddr) {// The address is in a shared DLL; the address needs fixing up PBYTE pb= (PBYTE) m_pfnOrig;if (pb[0]== cPushOpCode) {// Skip over the PUSH op code and grab the real address PVOID pv=* (PVOID*)&pb[1];
m_pfnOrig= (PROC) pv;
}
}
主要是这个不明白,可否详细解释下这个判断
cPushOpCode是什么?
[/Quote]

看这句
// Functions with address above lpMaximumApplicationAddress require
// special processing (Windows 98 only)

上面的判断时针对Win98的特殊处理
因为win98的同一系统DLL的内存空间(也即共享内存区),对每个进程都是共用的
而win2000以上,系统DLL是映射到每个进程的内存空间,是互不影响的

看定义
const BYTE cPushOpCode = 0x68; // The PUSH opcode on x86 platforms
汇编码形式如: PUSH 0x00654321 -> 68 21436500

对win98的底层不熟悉,具体为什么这样处理,不太清楚
dirdirdir3 2009-11-03
  • 打赏
  • 举报
回复
push是堆栈入栈命令,一般用于参数的传递.........
dirdirdir3 2009-11-03
  • 打赏
  • 举报
回复
CPushOpCode就是push这个汇编命令的机器码............
zy1691 2009-11-03
  • 打赏
  • 举报
回复

if (m_pfnOrig > sm_pvMaxAppAddr) {
// The address is in a shared DLL; the address needs fixing up
PBYTE pb = (PBYTE) m_pfnOrig;
if (pb[0] == cPushOpCode) {
// Skip over the PUSH op code and grab the real address
PVOID pv = * (PVOID*) &pb[1];
m_pfnOrig = (PROC) pv;
}
}

主要是这个不明白,可否详细解释下这个判断
cPushOpCode是什么?
feilinhe 2009-11-03
  • 打赏
  • 举报
回复
在CAPIHook类的头文件不是已经对这些变量有说明了,英文注释得很清楚,就是保存被Hook的函数的名称地址什么的
dirdirdir3 2009-11-03
  • 打赏
  • 举报
回复
哪里不明白?已经注释的那么详细了..................
fishion 2009-11-03
  • 打赏
  • 举报
回复
只有看英文注释
MoXiaoRab 2009-11-03
  • 打赏
  • 举报
回复

if (sm_pvMaxAppAddr == NULL) {
// Functions with address above lpMaximumApplicationAddress require
// special processing (Windows 98 only)
SYSTEM_INFO si;
GetSystemInfo(&si);
sm_pvMaxAppAddr = si.lpMaximumApplicationAddress;
}

m_pNext = sm_pHead; // The next node was at the head
sm_pHead = this; // This node is now at the head

// Save information about this hooked function
m_pszCalleeModName = pszCalleeModName;
m_pszFuncName = pszFuncName;
m_pfnHook = pfnHook;
m_fExcludeAPIHookMod = fExcludeAPIHookMod;
m_pfnOrig = GetProcAddressRaw(
GetModuleHandleA(pszCalleeModName), m_pszFuncName);
chASSERT(m_pfnOrig != NULL); // Function doesn't exist

if (m_pfnOrig > sm_pvMaxAppAddr) {
// The address is in a shared DLL; the address needs fixing up
PBYTE pb = (PBYTE) m_pfnOrig;
if (pb[0] == cPushOpCode) {
// Skip over the PUSH op code and grab the real address
PVOID pv = * (PVOID*) &pb[1];
m_pfnOrig = (PROC) pv;
}
}



这段吗?英文注释不是写的好好的么

15,473

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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