我的问题很简单:您是一个输出“授予访问权限”或“拒绝访问”的可执行文件,邪恶的人试图理解您的算法或修补您的内部结构,以使您始终说“授予访问权限”。

听完这个介绍后,您可能会非常想知道我在做什么。暗黑破坏神3发布后他会破解它吗?我可以消除你的忧虑,我不是那些傻瓜之一。我的目标是裂纹。

Crackmes 可以在例如 www.crackmes.de 上找到。Crackme 是一个小型可执行文件,(大多数情况下)包含一个小型算法来验证序列号并根据序列号输出“授予访问权限”或“拒绝访问”。目标是使该可执行输出始终“授予访问权限”。您可以使用的方法可能受到作者的限制 - 不能打补丁,不能反汇编 - 或者涉及您可以使用二进制、objdump 和十六进制编辑器执行的任何操作。破解裂纹无疑是乐趣的一部分,但是,作为一名程序员,我想知道如何创建困难的裂纹。

基本上,我认为crackme由两个主要部分组成:一定的序列验证和周围的代码。

仅使用汇编使串行验证难以跟踪是很有可能的,例如,我有想法将串行作为模拟微处理器的输入,该微处理器必须最终处于某种状态才能使串行被接受。另一方面,人们可能会变得便宜并了解更多有关保护这部分的加密方式的强大方法。因此,使这足以使攻击者试图修补可执行文件不应很难。

然而,更困难的部分是保护二进制文件。让我们假设一个完全安全的序列验证,无法以某种方式逆转(当然我知道它可以逆转,有疑问,你从尝试破解的二进制文件中撕下部分,并向其抛出随机序列,直到它接受为止)。我们如何防止攻击者覆盖二进制文件中的跳转以使我们的二进制文件接受任何内容?

我一直在这个主题上进行一些搜索,但大多数关于二进制安全性、自验证二进制文件等的结果最终都出现在试图防止使用受损二进制文件对操作系统进行攻击的文章中。通过签署某些二进制文件并使用内核验证这些签名。

我目前的想法包括:

  • 检查二进制文件中要跳转的显式位置。
  • 对二进制文件的校验和部分进行比较,并将运行时计算的校验和与这些部分进行比较。
  • 对代码中的函数进行积极和消极的运行时检查。对串行验证有副作用。:)

您能想出更多方法来让可能的攻击者烦恼更长时间吗?(当然,你不能永远让他远离,总有一天,所有检查都会被破坏,除非你能够通过在程序本身中嵌入程序的正确校验和来破坏校验和生成器,呵呵)

有帮助吗?

解决方案

您正在进入“防逆向技术”。这基本上是一门艺术。更糟糕的是,即使你踩死新手,olly和IDA Pro都有“防反倒车插件”,他们可以下载并绕过你的很多反制措施。

对策包括通过陷阱调试器 API 进行调试器检测,或检测“单步执行”。您可以插入代码,在检测到调试器中断后,该代码会继续运行,但在程序中稍后会在随机时间开始运行。这确实是一场猫捉老鼠的游戏,破解者占据了显着的上风。

查看...http://www.openrce.org/reference_library/anti_reversing - 一些外面的东西。

http://www.amazon.com/Reversing-Secrets-Engineering-Eldad-Eilam/dp/0764574817/ - 这本书提供了非常好的防逆向信息并逐步介绍了这些技术。如果您正在了解一般的倒车,那么这是一个很好的起点。

其他提示

我相信这些事情通常带来的麻烦大于其价值。

您花费了大量精力编写代码来保护您的二进制文件。坏人花费更少的精力来破解它(他们通常比你更有经验),然后释放破解,这样每个人都可以绕过你的保护。你唯一会惹恼的人是那些因你的保护而感到不便的诚实人。

只需将盗版视为业务成本 - 如果您确保仅为付费客户提供所有支持,则盗版软件的增量成本为零。

有TPM技术: 维基百科上的 TPM

它允许您将二进制的加密校验和存储在特殊芯片上,这可以充当单向验证。

笔记:TPM 的名声不太好,因为它可以用于 DRM。但对于该领域的专家来说,这有点不公平,甚至有一个 开放式TPM 该组允许 Linux 用户准确控制其 TPM 芯片的使用方式。

这个问题最有力的解决方案之一是 可信计算. 。基本上,您将加密应用程序并将解密密钥传输到特殊芯片( 可信平台模块),芯片只有在验证计算机处于“可信”状态后才会解密应用程序:没有内存查看器/编辑器,没有调试器等。基本上,您需要特殊的硬件才能查看解密的程序代码。

因此,您想要编写一个程序,该程序在开始时接受密钥并将其存储在内存中,然后从磁盘中检索它。如果密钥正确,软件就可以运行。如果密钥错误,软件就会崩溃。目标是盗版者很难生成工作密钥,并且很难修补程序以使用未经许可的密钥。

这实际上可以在没有特殊硬件的情况下实现。考虑一下我们的遗传密码。它的工作原理基于这个宇宙的物理学。我们试图破解它、制造药物等,但我们惨败,通常会产生大量不良副作用,因为我们还没有完全逆向工程遗传“密码”进化运行的复杂“世界” 。基本上,如果您在每个人都可以访问的公共处理器(公共“世界”)上运行所有内容,那么几乎不可能编写这样的安全代码,正如当前软件很容易被破解所证明的那样。

为了实现软件的安全性,您本质上必须编写自己的足够复杂的平台,其他人必须对其进行完全彻底的逆向工程,以便修改代码的行为而不会产生不可预测的副作用。然而,一旦你的平台被逆向工程,你就会回到原点。

问题是,您的平台可能会在通用硬件上运行,这使得您的平台更容易进行逆向工程,这反过来又使您的代码更容易进行逆向工程。当然,这可能只是意味着平台所需的复杂性水平提高了一点,使其难以进行逆向工程。

一个足够复杂的软件平台会是什么样子?例如,也许在每 6 次加法运算之后,第 7 次加法返回乘以 PI 除以自系统初始化以来执行的减法和乘法运算总数的差的模 5 的对数的平方根的结果。该平台必须独立跟踪这些数字,就像代码本身一样,以便解码正确的结果。因此,您的代码将基于对您设计的平台的复杂底层行为的了解来编写。是的,它会消耗处理器周期,但是有人必须对这种令人惊讶的行为进行逆向工程,并将其重新设计到任何新代码中才能使其正常运行。此外,您自己的代码一旦编写就很难更改,因为它会陷入不可简化的复杂性,每一行都取决于之前发生的所有事情。当然,在一个足够安全的平台中,复杂性会更高,但关键是,有人会在逆向工程和修改您的代码之前对您的平台进行逆向工程,而不会产生严重的副作用。

关于版权保护和保护的好文章 将海盗拒之门外:为 Spyro 实施破解保护:龙年

其中提到的最有趣但尚未提及的想法是级联故障 - 您的校验和会修改单个字节,从而导致另一个校验和失败。最终,其中一个校验和会导致系统崩溃或出现奇怪的情况。这使得盗版您的程序的尝试看起来不稳定,并使原因发生在距离崩溃很远的地方。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top