Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/147.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C或C++;:装载机/包装机如何工作?_C++_Windows_Loader - Fatal编程技术网

C++ C或C++;:装载机/包装机如何工作?

C++ C或C++;:装载机/包装机如何工作?,c++,windows,loader,C++,Windows,Loader,这里有一个例子来说明我的意思 用户运行LOADER.EXE程序 LOADER.EXE下载另一个EXE,但将其全部保存在内存中,而不将其保存到磁盘 运行下载的EXE,就像从磁盘执行一样,但直接从内存执行吗 我见过一些这样的应用程序,但我从未见过一个例子或解释它是如何工作的 有人知道吗 另一个例子是在另一个文件中嵌入加密的EXE。它在内存中被提取和解密,在执行之前从未保存到磁盘 我已经在一些应用程序中看到了用于防止盗版的 编辑:作为旁注,像UPX这样的程序是这样工作的吗?我看了代码,但对我来说很

这里有一个例子来说明我的意思

  • 用户运行LOADER.EXE程序
  • LOADER.EXE下载另一个EXE,但将其全部保存在内存中,而不将其保存到磁盘
  • 运行下载的EXE,就像从磁盘执行一样,但直接从内存执行吗
我见过一些这样的应用程序,但我从未见过一个例子或解释它是如何工作的

有人知道吗

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

我已经在一些应用程序中看到了用于防止盗版的


编辑:作为旁注,像UPX这样的程序是这样工作的吗?我看了代码,但对我来说很难破译,我问的主要是出于好奇,我不需要它。

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

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


事实上,在过去的好日子里,这是一个保存内存的通用系统。您将拥有“”,这样您可以根据需要交换代码以节省内存

很多这样做的程序只是解压缩到%TEMP%(我知道我是这么做的),但是大公司基本上重新实现了OS可执行加载程序,它必须:

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

总之:这是一个很大的工作。如果您感兴趣,请查看描述.exe和.dll文件的PE格式规范,以及
VirtualAlloc()
函数。

这真的有效吗?如何确保在可执行代码中没有跳转到绝对地址(这将在加载时解析)?绝对地址修正在EXE数据中。这就是Vista的ASLR功能的工作原理。不过,加载程序可能会将其引导代码移开,以便EXE在其正常基址处加载。@Hans:我很确定EXE没有(尽管它们可以)包含重新定位部分,因为EXE是在地址空间中分配的第一个内容,因此永远不必重新定位(ASLR仅用于.dll)@Goz:这不起作用,因为原始文件数据中的部分没有页面对齐:请参阅PE规范中关于文件偏移量和RVA之间的差异。请注意,创建包装时,它将知道要包装的EXE。因此它可以选择另一个基址。哇,听起来比我想象的要复杂得多。你有UPX的经验吗?它是这样工作的吗?(我对包装工不太了解)。我希望能够找到一些源代码来演示这一点,这将有点容易理解。@guitar:我只是快速浏览了一下代码。加载器存根是一个非常重宏的程序集,但是如果这项工作正常的话,看起来打包程序正在进行大量的预处理,因此存根可以将一个已经对齐的文件解压缩到内存中,然后获得导入。显然,这对于您的第二个和第三个示例是不够的。包装机的东西更近了,但我相信其他地方的特殊案例较少。这似乎是一个好的开始,尽管它不太符合商业质量。