【问题标题】:C or C++: how do loaders/wrappers work?C 或 C++:加载器/包装器如何工作?
【发布时间】:2010-06-09 10:31:01
【问题描述】:

这是我的意思的一个例子......

  • 用户运行 LOADER.EXE 程序
  • LOADER.EXE 下载另一个 EXE,但将其全部保存在内存中而不保存到磁盘中
  • 像从磁盘执行下载的 EXE 一样运行下载的 EXE,但直接从内存执行

我见过一些这样的应用程序,但我从未见过一个例子或解释它是如何工作的。

有人知道吗?

另一个例子是将加密的 EXE 嵌入到另一个文件中。它在内存中被提取和解密,在执行之前从未保存到磁盘。

我已经看到在某些应用程序中使用它来防止盗版。

编辑:附带说明一下,像 UPX 这样的程序会这样工作吗?我查看了代码,但对我来说很难破译,我主要是出于好奇而问,我不需要它。

【问题讨论】:

    标签: c++ windows loader


    【解决方案1】:

    执行此操作的许多程序只是解压缩到 %TEMP%(我知道我会这样做),但大佬们基本上重新实现了 OS 可执行加载器,它必须:

    • 将可执行文件映射到内存中。这并不像听起来那么简单,因为 .exe 包含多个“部分”,它们必须以页面对齐方式加载(它们必须从 4K 的倍数的地址开始)并且它们每个都有特定的请求 - 只读,复制写入、零初始化等......
    • 通过更新导入表部分来满足静态导入,通常使用 LoadLibrary() 和 GetProcAddress()。
    • 对于 dll(实际上几乎相同,重要的区别在于它们有导出和导入),如果编译加载的内存地址是已经在使用(这很常见)。但是,这对于 exe 来说通常是不可能的,因为它们不包括列出加载代码中需要更新的位置的重定位部分,因为通常它们是加载到进程中的第一件事,因此不能被阻止通过某事。这意味着加载器必须为其自己的 exe 提供一个不寻常的加载地址,这不会阻止加载的 exe。

    总之:这是很多工作。如果您有兴趣,请查看 PE 格式规范,其中描述了 .exe 和 .dll 文件,以及 VirtualAlloc() 函数。

    【讨论】:

    • 哇,这听起来比我想象的要复杂得多。你有使用 UPX 的经验吗?它甚至像这样工作吗? (我对包装工了解不多)。我希望能够遇到一些演示这一点的源代码,这将有点容易理解。
    • @guitar:我只是快速浏览了一下代码。加载程序存根是非常宏大的程序集,但如果这个工作,看起来打包程序正在预处理很多,所以存根可以将已经对齐的文件解压缩到内存中,然后获取导入。对于您的第二个和第三个示例,这显然是不够的。 upx.hg.sourceforge.net/hgweb/upx/upx/file/c3853d205747/src/… 中的打包程序更接近,但我敢肯定其他地方的特殊情况较少。
    • 这似乎是一个好的开始,尽管它的商业质量并不高。 code.google.com/p/egodust/source/browse/trunk/pe.c
    【解决方案2】:

    如果你知道可执行文件入口点的偏移量在哪里,并且知道它需要什么参数,那么你需要做的就是使用函数指针在地址“exeBase + entryPointOffset”处调用函数。

    值得注意的是,至少在 x86 系统上,操作系统往往不允许您执行标记为数据的内存。例如,在 windows 下,可以使用“Virtual ProtectEx”函数将内存标记为可执行。

    事实上,在过去的美好时光里,这是一种节省内存的常用系统。您将拥有“overlays”,这样您就可以通过根据需要交换代码来节省内存。

    【讨论】:

    • 真的有用吗?如何确定可执行代码中没有跳转到绝对地址(在加载时会解析)?
    • 绝对地址修正在 EXE 数据中。这就是 Vista 的 ASLR 功能的工作原理。尽管如此,加载程序可能会将其引导代码移开,以便 EXE 在其正常的基地址处加载。
    • @Hans:我很确定 exe 不(尽管它们可以)包含重定位部分,因为 exe 是在地址空间中分配的第一件事,并且因此永远不必重新定位(ASLR 仅适用于 .dll)。 @Goz:这不起作用,因为原始文件数据中的部分没有页面对齐:请参阅 PE 规范关于文件偏移量和 RVA 之间的差异。
    • 请注意,当包装器被创建时,它会知道它包装的是什么EXE。因此它可以选择另一个基地址。
    猜你喜欢
    • 1970-01-01
    • 2014-08-28
    • 2011-05-11
    • 2020-11-03
    • 1970-01-01
    • 2010-11-08
    • 2011-06-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多