作为代码执行数据?

时间:2010-08-14 21:41:22

标签: c++ windows assembly loader

我的客户要求我编写自定义加密可执行文件,以防止许可系统轻易破解。现在,我明白这是一种虚假的安全感,但尽管如此,他坚持这一点。

所以,我挖掘了我对可移植可执行文件的了解,并提出了这个想法:

  • 加密可执行文件
  • 将此标记添加到加载程序可执行文件的末尾及其大小
  • 加载程序解密数据
  • 它将代码复制到使用具有可执行权限的VirtualAlloc分配的页面
  • 找到应用程序的入口点
  • 跳到那里,我们都准备好了。

跳到那里我有一个问题。我怎样才能做到这一点?如果我要设置一个函数指针,那么签名是什么?加载的可执行文件的main()函数的签名?或者我需要求助于组装?

我知道加载代码后可能需要更正绝对地址。如何检查是否需要,以及如何实际执行此操作?

编辑:在Windows上工作并使用GCC进行编译。如有必要,我可以切换Microsoft编译器。

Edit2:澄清一下:我知道这一点毫无意义。我认为这代表任何类型的DRM。这取决于我的客户决定,尽管我警告他,但他仍然想要它。

提前致谢。

8 个答案:

答案 0 :(得分:11)

不幸的是,跳到代码的入口点是您最不担心的问题。 Portable Executable(PE)文件(用于Windows上的EXE和DLL文件的文件格式)不是您可以加载到单个内存块然后运行的东西。您的自定义PE加载器必须处理以下工作:

  • 将PE文件中的各种代码和数据部分加载到单独的内存块中。

  • 从导入表中解析依赖关系以加载EXE所依赖的DLL。

  • 执行重新安置。

获得正确的所有细节可能是一项非常复杂的工作。我建议您寻找可以购买的工具来进行这种EXE加密。

修改:谷歌快速建议您可能需要查看以下内容:

  • EXECryptor(专有)

  • RLPack(专有)

  • UPX(GPL)这个只根据我的理解进行压缩,但您可以使用The Source添加加密(如果GPL与您的需求兼容)。

    < / LI>

必然会有更多这样的工具 - 这只是快速搜索的结果。

另一个编辑:

<> MSDN杂志刊登了Matt Pietrek撰写的一篇文章,名为“深入研究Win32可移植可执行文件格式”(Part 1Part 2)。它包含有关PE文件格式的大量信息,对您有用。一个有趣的信息:默认情况下,最新版本的Microsoft链接器似乎省略了EXE的基本重定位。您可能希望指示链接器将这些重新放入,因为您的包装EXE可能已经加载到您的有效负载EXE的首选加载地址。或者,您可以尝试为您的包装器EXE提供一个特殊的首选加载地址,希望它不会干扰有效负载EXE。

我还找到了page that discusses a rudimentary PE file compressor。虽然看起来并不完全一般,但在使用它之前可能还需要一些额外的工作。

答案 1 :(得分:4)

除了正确加载PE图像的所有麻烦和麻烦之外,您还需要担心Data Execution Protection这是为了防止这样做。

不要忘记,对于某些抗病毒和反恶意软件工具,这也会像恶意软件行为一样。

答案 2 :(得分:4)

正如其他人所提到的,只需将整个EXE加载到数据部分并在运行时链接它是一项艰巨的任务;但是,这是另一种选择。

输入EXE;找到它的代码和初始化数据(包括常量)部分。重命名这些部分并将它们全部转换为读写初始化数据部分;加密内容。现在添加一个包含解密存根的新代码段,并在那里更改入口点。此存根应该就地解密段,然后将其保护更改为适合其类型的任何内容,并跳转到原始入口点。

这避免了必须实现完整PE加载器的所有功能,因为导入表未加密,因此普通的Windows加载器将为您处理它们。

当然,应该注意的是,这种天真的方法在任何时候都无法在协同攻击中存活 - 攻击者可以简单地转储进程的内存以获取原始的解密代码。为了避免这种情况,我们可能需要不断加密和解密代码,此时PE处理是您最不关心的问题。

答案 3 :(得分:1)

在我的观点中你的打字解决方案是小错误,你的功能正在做什么跳转到其他功能?他们修复了其他地址,我看到这个解决方案有很多问题,比如加密代码的静态链接库。

我认为您可以执行以下操作:

  1. 使用您的秘密程序集传输加密的dll文件
  2. 在tmp目录中加密她
  3. 在此
  4. 上执行LoadLibrary
  5. 解锁DLL文件并从系统中删除?

答案 4 :(得分:1)

  

加载程序解密数据

这说明了一切。

为了使加载程序能够解密数据,它还必须包含(或至少知道)解密密钥。

因此,如果您将此加载器物理地分发给您的用户,他们将可以完全访问加载程序代码和使用的密钥。

也许这就是“虚假安全感”的含义?

由于您的客户似乎要么顽固或者只是无知,为什么不建立一个简单的小解密演示,清楚地显示他们思维中的缺陷?

答案 5 :(得分:1)

另请参阅What is your favourite anti-debugging trick的已接受答案,以获得更好的解决方案,以便更难破解可执行文件。

答案 6 :(得分:0)

您应该能够将地址转换为函数指针,并调用它:

typedef void (*MyPtr)();

MyPtr p = (MyPtr)1234;
p();

答案 7 :(得分:-3)

由于gdt是一个从代码中划分数据的全局描述符表,因此无法在大多数操作系统中执行代码等数据。如果您尝试执行数据,则处理器会给出异常。