C或C ++:加载器/包装器如何工作?

时间:2010-06-09 10:31:01

标签: c++ windows loader

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

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

我见过这样的一些应用程序,我从来没有见过它的工作原理的例子或解释。

有人知道吗?

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

我已经看到在某些应用程序中使用的一种方法可以防止盗版。

编辑:作为旁注,像UPX这样的程序是这样运作的吗?我查看了代码,但很难为我解读,我主要是出于好奇,我不需要它。

2 个答案:

答案 0 :(得分:4)

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

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

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

答案 1 :(得分:1)

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

值得注意的是,OS至少在x86系统上,往往不允许你执行标记为数据的内存。例如,在Windows下,可以使用“Virtual ProtectEx”功能将其更改为将内存标记为可执行文件。

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