【问题标题】:DLL monitoring动态链接库监控
【发布时间】:2010-10-25 20:09:30
【问题描述】:

是否有一个应用程序可以让我查看从进程发送到 DLL 的内容?

我有一个进程和一个 DLL,我想监控发送给函数的参数,以便我自己使用 DLL。

DLL 的 EXPORT 是。

??0CCPCompressor@@AAE@XZ
??0CCPExpandor@@AAE@XZ
??1CCPCompressor@@AAE@XZ
??1CCPExpandor@@AAE@XZ
?清除@CCPCompressor@@QAEHXZ
?清除@CCPExpandor@@QAEHXZ
..Compress@CCPCompressor..
..删除@CCPCompressor..
..删除@CCPExpandor..
..Expand@CCPExpandor..
..Free@CCPCompressor..
..Free@CCPExpandor..
..Init@CCPCompressor..
..Init@CCPExpandor..
..New@CCPCompressor..
..New@CCPExpandor..

【问题讨论】:

  • 查看您的 DLL 导出引发了一个严重的危险信号 - 您正在从 DLL 中导出 C++ 修饰名称。这意味着您的 DLL 不会在不同的 C++ 编译器之间互操作(它们都有自己的名称修饰算法),甚至在不同版本的 C++ 编译器之间(名称修饰算法因版本而异)。
  • 我相信这个技术被一个 Sysinternal 工具使用了,或者我看到了一篇关于这种注入的文章 Sysinternal 的一个人。不记得了。无论如何,愉快的编码。
  • 一些帮助:Monitoring Tools

标签: c++ windows dll


【解决方案1】:

一般来说,这是一个坏主意。即使您有一些捕获的参数集,如果不深入分析 DLL 代码,您也不知道如何处理这些参数以及某些方法接受的参数范围。例子:如果我调用一个方法 DoMathOperation(Add, 1, 2),你可以模仿这个调用,但是你不能做 DoMathOperation(Multiply, 2, 2) 因为你不知道这是可能的。

【讨论】:

    【解决方案2】:

    最简单的方法是简单地重新定位原始 dll,然后使用相同的导出创建一个您自己制作的新 dll。此 dll 将从备用位置加载旧 dll。

    这在这里不太适用 - dll 正在导出 c++ 类成员,这有两个后果:c++ 类必须静态加载,因为没有 c++ 机制将 c++ 函数指针(通过 GetProcAddress 获得)“粘合”到类实例。

    这意味着您的 shim dll 将处于不得不导入和导出以及相同符号集的不幸位置。

    解决此问题的唯一方法是将您的 shim dll 分为两部分:

    垫片1:

    其中一部分会获取原始 dll 的名称,并会导出与原始 dll 导出的相同的类定义:

     class __decldpec(dllexport) CCPCompressor {
      ...
    

    Depends可以破解名字装饰,或者Undname.exe随Visual Studio一起分发。

    这部分将 LoadLibrary() 使用位于其他文件夹中的 shimdll2.dll 的显式路径以及原始 dll。需要 GetProcAddress() 来导入由 shimdll2.dll 导出的函数

    垫片2:

    另一个 shim dll 将位于您尝试拦截的 dll 所在的文件夹中。这个 dll 必须从原始压缩器 dll 中导入类:

    class __declspec(dllimport) CCPCompressor {
      ...
    

    您可以使用第一个 dll 制作的 dll 导入库来实际链接符号。 然后是从 shim2.dll 导出函数的情况,每当调用 CCPCompressor 方法时,shim1.dll 都会调用该函数。

    注意。其他事情:您的 CCPCompressor 类的版本至少需要有一个大的虚拟数组,因为您无法从 dll 导出中知道应用程序期望该类有多大(除非您碰巧有一个实际的头文件描述类)。


    分解导出的名称以构建类定义: 从开始 > 程序 > Visual Studio 20XX -> 工具菜单打开 Visual Studio 20XX 命令提示符。

    c:\...\VC>undname ?Clear@CCPCompressor@@QAEHXZ
    Microsoft (R) C++ Name Undecorator
    
    Undecoration of :- "?Clear@CCPCompressor@@QAEHXZ"
    is :- "public: int __thiscall CCPCompressor:Clear(void)"
    
    c:\...\VC>_
    

    对从原始 dll 导出的每个函数执行此操作(undname 接受某种文本文件以加快此过程)以了解如何声明匹配的类 def。

    【讨论】:

    • 如何找到与原始 dll 导出的相同的类定义?
    • 如果你没有,那么你需要发明它:使用depends.exe映射出每个函数原型,并将它们全部添加到你自己的类声明中。
    • 我整理了以下内容,但 ::New 我不确定。 class __decldpec(dllexport) CCPCompressor
      {
      private:
      CCPCompressor(void);
      ~CCPCompressor(void);
      public:
      int Clear(void);
      无符号短压缩(unsigned char* const, unsigned short, unsigned char* const, unsigned short, int);
      void Delete(void);
      void Free(void);
      int Init(void);}
      static class CCPCompressor * __cdecl CCPCompressor::New(void);

      你有什么值得一读的真正好的URL吗?
    • 该类定义看起来适合类 shim dll。不幸的是,我想不出任何涵盖此内容的好网站,坦率地说,在这篇文章之前,我从未考虑过如何从 dll 中挂钩 c++ 类。
    【解决方案3】:

    使用detours 是否符合您的要求?

    来自网站:

    概览

    创新系统研究取决于轻松检测和扩展现有操作系统和应用程序功能的能力。通过访问适当的源代码,通过重建操作系统或应用程序插入新的工具或扩展通常是微不足道的。然而,在当今世界,系统研究人员很少能够访问所有相关的源代码。

    Detours 是一个库,用于在 x86、x64 和 IA64 机器上检测任意 Win32 函数。 Detours 通过重写目标函数的内存代码来拦截 Win32 函数。 Detours 包还包含用于将任意 DLL 和数据段(称为有效负载)附加到任何 Win32 二进制文件的实用程序。

    Detours 将未插桩的目标函数(可通过蹦床调用)保留为子例程以供插桩使用。我们的蹦床设计支持对现有二进制软件进行大量创新扩展。

    我们使用 Detours 创建了一个自动分布式分区系统,检测和分析 DCOM 协议栈,并为基于 COM 的 OS API 创建了一个thunking layer。 Detours 在 Microsoft 和行业内被广泛使用。

    【讨论】:

    • 我可以尝试,但从另一篇文章看来我无法使用它来监视带有类的 DLL。如果你能告诉我我可以,我会试试的。谢谢。
    • 没有为 c++ 类方法指针定义应用程序二进制接口。结果是方法指针不能通过 void* 封送,因为它们的大小可能变化很大。 Detours 需要一个函数的地址,该函数的调用约定与被挂钩的函数匹配,我只是看不出如何提供。
    • 好吧,从你的角度来看,类只是方法的集合——如果你捕获方法并用参数记录它们的调用,你会有所收获。
    • @Chris:他没有提到他要监控对象实例吗?也许如果他只想要参数,而忽略'this',这可能是可行的?
    • 1.他想使用 dll,所以无论如何他都需要对类定义进行逆向工程。 2. 拦截已有exe对dll的调用时,不清楚如何使用代码将Detours注入到进程中。 3. 即使跨越了这个障碍,在注射之前拨打的电话也会被错过。 4. 我可以想到两种使用 Detours 的潜在方法:1. 创建一个本地 shim 类,并尝试将类方法指针转换为纯内存地址以传递给 DetourAttach,2. 使用一些自定义 asm 绕行到 c 方法处理 __fastcall 参数打包。
    【解决方案4】:

    唯一可靠的方法是调试您的程序(使用任何调试器,如 OllyDBG)并在所需的导出函数上设置断点。然后您可以简单地跟踪发送到调用函数的堆栈参数。这只是开始,您需要在调试器或反汇编器中全面分析函数指令,以了解每个参数的作用及其类型。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-13
      • 1970-01-01
      • 2015-08-25
      • 1970-01-01
      • 2013-07-16
      相关资源
      最近更新 更多