C++ 以代码形式执行数据?

C++ 以代码形式执行数据?,c++,windows,assembly,loader,C++,Windows,Assembly,Loader,我的客户要求我编写一个自定义加密的可执行文件,以防止许可证系统容易被破解。现在,我明白这是一种虚假的安全感,但尽管如此,他还是坚持这样做 因此,我挖掘了我对可移植可执行文件的知识,并提出了以下想法: 加密可执行文件 将其与大小一起粘贴到加载程序可执行文件的末尾 加载程序解密数据 它将代码复制到分配有可执行权限的VirtualAlloc的页面 它找到应用程序的入口点 跳到那里,我们都准备好了 我对在那里跳有点问题。我该怎么做?如果我设置一个指向它的函数指针,签名是什么?加载的可执行文件的mai

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

因此,我挖掘了我对可移植可执行文件的知识,并提出了以下想法:

  • 加密可执行文件
  • 将其与大小一起粘贴到加载程序可执行文件的末尾
  • 加载程序解密数据
  • 它将代码复制到分配有可执行权限的VirtualAlloc的页面
  • 它找到应用程序的入口点
  • 跳到那里,我们都准备好了
我对在那里跳有点问题。我该怎么做?如果我设置一个指向它的函数指针,签名是什么?加载的可执行文件的main()函数的签名?还是我需要诉诸集会

我理解在加载代码后可能需要更正绝对地址。如何检查是否需要,以及如何实际执行

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

编辑2:澄清一下:我知道这基本上是毫无意义的。我相信它代表任何一种DRM。这取决于我的客户来决定,尽管我警告过他,他还是想要


提前感谢。

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

typedef void (*MyPtr)();

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

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

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

  • 从导入表解析依赖项以加载EXE所依赖的DLL

  • 执行重新定位

把所有的细节都弄对可能是一项相当复杂的工作。我建议你寻找一个工具,你可以买这种EXE加密

编辑:快速浏览谷歌,你可能想看看以下内容:

  • (专有)

  • (专有)

  • (GPL)据我所知,这一个只进行压缩,但您可以使用源代码添加加密(如果GPL与您的需要兼容)

肯定会有更多这样的工具——这只是快速搜索的结果

另一编辑:

MSDN杂志刊登了Matt Pietrek的一篇文章,名为“深入研究Win32可移植可执行文件格式”(,)。它包含了很多关于PE文件格式的信息,这些信息应该对您有用。一个有趣的信息:微软linker的最新版本似乎在默认情况下忽略了前男友的基本重新定位。您可能希望指示链接器将这些文件放回,因为很可能您的包装器EXE已加载到有效负载EXE的首选加载地址。或者,您可以尝试为包装器EXE提供一个奇特的首选加载地址,希望它不会干扰有效负载EXE


我还找到了一个新的方法。不过,它似乎并不完全通用,在使用它之前可能需要一些额外的工作。

除了正确加载PE映像所带来的麻烦之外,您还需要担心哪些是为了阻止这样做


别忘了,对于某些反病毒和反恶意软件工具来说,这也可能看起来像恶意软件行为。

在我看来,你的类型化解决方案有点缺陷,你的函数做什么会跳转到其他函数?它们是固定的其他地址,我看到这个解决方案有很多问题,比如加密代码的静态链接库在哪里

我想你可以做如下事情:

  • 使用机密程序集传输加密的dll文件
  • 在tmp目录中加密她
  • 你在这上面写图书馆吗
  • 解锁DLL文件并从系统中删除

  • 在大多数操作系统中,您无法像代码一样执行数据,这要归功于gdt,它是一个将数据和代码分开的全局描述符表。如果您试图执行数据,处理器会给出一个异常

    加载程序解密数据

    这真的说明了一切

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

    因此,如果您将此加载程序以物理方式分发给用户,他们将拥有对加载程序代码和所用密钥的完全访问权限

    也许这就是你所说的“虚假安全感”


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

    正如其他人所提到的,简单地将整个EXE加载到数据部分并在运行时链接它是一项困难的任务;然而,这里有另一个选择

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

    这避免了必须实现完整PE加载程序的所有功能,因为导入表没有加密,因此普通的windows加载程序将为您处理这些功能

    当然,应该注意的是,这种幼稚的方法在任何时候都无法经受协同攻击——攻击者可以简单地转储