核心编程关于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前面的部分不太明白什么意思,希望哪位高手来给解释一下。
...全文
257 9 打赏 收藏 转发到动态 举报
写回复
用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;
}
}



这段吗?英文注释不是写的好好的么
内容概要:本文围绕有限控制集模型预测控制(FCS-MPC)下并网逆变器的运行特性与并网性能展开深入研究,重点基于三相LCL型并网逆变器拓扑结构,通过Simulink仿真实现对其在动态与稳态工况下的控制策略建模与性能分析。研究系统构建了包含dq轴电流内环、同步锁相环(PLL)、数字控制延时及滤波环节的分层控制小信号模型,并深入探讨了PLL引起的频率耦合效应对系统稳定性的影响,进而建立了考虑正负序分量交互的逆变器序阻抗解析模型。结合Nyquist与Bode图频域稳定判据,提出基于阻抗比的稳定性分析方法,并通过仿真扫频辨识技术提取序阻抗,验证理论模型的准确性。文章进一步剖析了弱电网条件下并网系统的耦合失稳机理,对比分析了虚拟同步发电机(VSG)、双闭环控制、模型预测控制等多种先进控制策略的性能差异,旨在提升并网电能质量、动态响应能力与抗扰性。; 适合人群:具备扎实的电力电子、自动控制理论基础,从事新能源并网、微电网、电力系统稳定性分析等相关领域的科研人员及工程技术人员,尤其适合研究生及以上学历或具有1-3年相关工作经验的研发人员。; 使用场景及目标:① 掌握FCS-MPC在并网逆变器中的控制策略设计与Simulink仿真建模方法;② 深入理解基于小信号建模的正负序阻抗建模理论及其在弱电网交互稳定性分析中的应用;③ 学习并实践利用扫频辨识法提取序阻抗及通过Nyquist/Bode判据进行频域稳定性分析的完整流程;④ 为光伏、风电等新能源发电系统的并网控制器设计、优化及振荡问题抑制提供理论依据和技术参考。; 阅读建议:建议读者结合文中提供的Matlab/Simulink仿真模型与代码进行同步实践操作,重点关注控制策略的实现细节、小信号建模的推导过程以及仿真结果与理论分析的对比验证,同时可延伸学习文档中涉及的VSG、谐波线性化、阻抗建模等关键技术,以构建系统化的新能源并网系统分析与设计能力。

15,465

社区成员

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

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