作为代码执行数据?

我的客户要求我编写一个自定义的encryption可执行文件,以防止许可证系统轻易破解。 现在,我明白这是一种错误的安全感,但是尽pipe如此,他还是坚持了这一点。

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

  • encryption可执行文件
  • 将其粘贴到加载器可执行文件的最后,并将其放大
  • 加载器解密数据
  • 它将代码复制到分配有具有可执行权限的VirtualAlloc的页面
  • 它find应用程序的入口点
  • 跳到那里,我们都准备好了。

我有一个问题跳到那里的一部分。 我怎样才能做到这一点? 如果我要为它设置一个函数指针,签名是什么? 加载的可执行文件main()函数的签名? 还是我需要诉诸大会?

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

编辑:在窗口上工作和编译与GCC。 如有必要,我可以切换Microsoft编译器。

编辑2:澄清:我知道它是毫无意义的。 我相信这代表任何一种DRM。 这是由我的客户来决定,他仍然希望尽pipe我警告他这件事。

提前致谢。

Solutions Collecting From Web of "作为代码执行数据?"

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

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

这样可以避免必须实现完整的PE加载器的所有功能,因为导入表没有加密,因此正常的Windows加载器将为您处理它们。

当然,应该指出的是,这种天真的方法在任何时候都不会经受一次一致的攻击 – 攻击者可以简单地转储进程的内存来获取原始的解密代码。 为了避免这种情况,可能需要持续加密和解密代码,在这一点上,PE处理是您最担心的问题。

不幸的是,跳到你的代码的入口点是你最担心的。 一个可移植的可执行文件 (PE)文件(这是用于Windows上的EXE和DLL文件的文件格式)是不是你可以加载到一个单一的内存块,然后运行。 您的自定义PE加载器将不得不照顾以下工作:

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

  • 解决从导入表的依赖关系加载您的EXE依赖的DLL。

  • 执行重定位。

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

编辑:一个快速的谷歌建议你可能想看看下面的内容:

  • EXECryptor (专有)

  • RLPack (专有)

  • UPX (GPL)据我所知,这个只做压缩,但是你可以使用Source来添加加密(如果GPL与你的需求兼容的话)。

这样的工具肯定会有更多的工具 – 这只是一个快速搜索的结果。

另一个编辑:

MSDN杂志刊登了Matt Pietrek的一篇名为“深入研究Win32可移植可执行文件格式”的文章( 第1 部分 , 第2部分 )。 它包含很多关于PE文件格式的信息,这些信息应该对你有用。 一个有趣的信息:微软链接器的最新版本默认情况下,似乎省略了EXE的基址重定位。 你可能要指示链接器把它们放回去,因为你的包装EXE可能已经被加载到你的有效载荷EXE的首选加载地址。 或者,你可以尝试给你的包装EXE一个异国情调的首选加载地址,它希望不会干扰有效载荷EXE。

我还找到了一个讨论基本的PE文件压缩器的页面 。 它似乎并不完全一般,但可能需要一些额外的工作,才可以使用它。

除了正确加载PE映像的所有麻烦和麻烦之外,您还需要担心数据执行保护(Data Execution Protection) ,它旨在防止这样做。

不要忘记,这也可能会出现像一些反病毒和反恶意软件工具的恶意软件行为。

从我的角度来看,你输入的解决方案是小错误,你的函数做了什么跳转到其他函数? 他们是固定的其他地址,我看到这个解决方案很多问题,如加密代码的静态链接库在哪里。

我想你可以做一些事情:

  1. 运行一个加密的DLL文件与您的秘密大会
  2. 在tmp目录中加密她
  3. 在这个上做LoadLibrary
  4. 解锁DLL文件并从系统中删除?

加载器解密数据

这说明了一切。

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

因此,如果您将此加载程序以物理方式分发给用户,则它们将完全访问加载程序代码和所用的密钥。

也许这就是你所说的“错误的安全感”呢?

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

另请参阅接受的答案是什么是您最喜欢的反调试技巧,以便更好地解决可执行文件的破解问题。

你应该可以通过c-style将你的地址转换成一个函数指针,然后调用它:

typedef void (*MyPtr)(); MyPtr p = (MyPtr)1234; p(); 

在大多数操作系统中,不能像代码那样执行数据,这要归功于gdt,这是将代码中的数据分开的全局描述符表。 如果您尝试执行数据,处理器会给出异常。