定制调试诊断工具和实用程序(8)
2006-07-20 11:42:17 来源:WEB开发网如果你比较线程函数和 kernel32.dll 输出的 LoadLibrary,你会发现它们的署名相同。两者都带32位值作为参数并返回32位值。根据这种相似性。Jeffrey Richter 在《Programming Applications for Microsoft Windows》(Microsoft Press, 1999)中解释了如何用 InjectLib 将一个 DLL 注入到另一个进程地址空间,然后用 EjectLib 将它卸载(实现细节参见 Inject.cpp )。它在本文中提供的代码有改动,以便通过对应的 CPSAPIWrapper 类动态使用 PSAPI,OpenProcess 已经被 GetProcessHandleWithEnoughRights 替代。
为什么加载这样的 DLL 会如此有趣呢?如果你正在写 DLL,这种方法可以使你的代码轻松运行在其它进程的上下文中。真正有趣的是要在调用进程和远程 DLL 代码之间建立沟通渠道。驱动应用 GrabInfo,以及注入 DLL GrabHook 是作为例子建立的。其目的是获取四个参数,它们对于其它进程应该是未知的。这些参数分别是:命令行(GetCommandLine),环境字符串(GetEnvironmentStrings),是否调试(IsDebuggerPresent)以及在其下运行的窗口站(GetProcessWindowStation 和 GetUserObjectInformation)。
远程调用的每个函数被包装在辅助函数中,由 DLL 中输出,它们全都调用一个通用函数:Ex-ecuteRemoteAction。该函数以目标应用的进程 ID 以及与拟执行行为对应的命令 ID 为参数(参见 GrabHook.cpp 中的 RA_XXX 常量)。它们被保存在变量 s_dwProcessID 和 s_Action 中,执行的结果被保存在 s_bSuccess 中。这三个变量要被两个进程存取,同时两个进程还要共享其相同的值,于是必须把它们声明在 DLL 的共享段中,方法是使用 #pragma data_seg 和 #pragma comment,就像下面这样:
#pragma data_seg(".shared")
DWORD s_Action = 0;
DWORD s_dwProcessID = 0;
BOOL s_bSuccess = FALSE;
#pragma data_seg()
#pragma comment(linker, "-section:.shared,rws")
s_Action 和 s_dwProcessID 的值在调用进程中发生了什么变化?被调用进程又是如何给 s_bSuccess 赋值的呢,Figure 13 例举了远程调用的过程。
- ››调试SQL server 2008功能设置
- ››调试JavaScript错误
- ››定制个性化的对话框窗口类
- ››定制 SWT/RCP 界面:如何编写一个漂亮的 SWT/RCP ...
- ››调试和测试 Swing 代码
- ››定制基于 Visual studio 2005 平台 Windows CE(AR...
- ››定制版黑雨 blackra1n 越狱3.1.2 全系 iPhone
- ››调试集成 Java 和 C/C++ 的代码
- ››定制 Eclipse RCP 应用程序,第 1 部分: 可与 SWT...
- ››调试JavaScript脚本程序(Firefox篇)
- ››调试JavaScript/VB Script脚本程序(ASP.NET篇)
- ››调试JavaScript/VB Script脚本程序(Wscript篇)
更多精彩
赞助商链接