安卓应用程序是否真的无法保护不被反向工程?

64

众所周知,Android应用程序是用Java编写的。在Java中,无论你做什么,都不可能防止已编译的代码被反编译或逆向工程,正如Stack Overflow问题如何锁定编译的Java类以防止反编译?所建议的那样。

如果一个应用程序包含算法交易秘密,如何保护其免受逆向工程的影响呢?

“如何”不仅指软件技术,还包括其他创意方法。


4
Android应用程序可以使用Java语言编写源代码,但它们不会以Java字节码的形式分发 - 它们以DEX(Dalvik可执行)文件的形式进行分发。有一些针对DEX文件的反汇编器可以生成类似汇编代码的内容,但据我所知,无法将DEX反编译为Java源代码。 - Nate
3
Nate,这是一个很好的评论和非常有用的信息。如果这被证明是正确的解决方案,请将其发布为答案,我将高兴地接受它作为“答案”。与此同时,我找到了以下线程,它表明即使是DEX文件也可以反编译为Java源代码:https://dev59.com/knM_5IYBdhLWcg3wvF3J 这是真的吗? - Android Eve
我偶然发现的另一个相关参考资料:https://dev59.com/R3A75IYBdhLWcg3wv7_A - Android Eve
10个回答

73

我的第一步是使用ProGuard来优化和混淆代码,该工具已知可用于针对Android的Dalvik虚拟机(通过Dex)的字节码。这是一个非常好的工具,可以增加“反转”代码的难度,同时缩小代码的占用空间(在某些情况下甚至可以显著减少:我最近的一个小应用从约600KB减少到了约50KB)。

正如其他人所说,当你的算法实现被分发给客户端时,你永远无法完全保证其细节的安全性。要做到这一点,你需要将代码仅保留在自己的服务器上。试图实现客户端代码的近乎100%的安全性实际上相当于DRM,这可能会使你的客户端代码在网络故障时变得脆弱,并且会让(合法的)用户感到沮丧。

Android开发者博客上有一些关于“防篡改”的Android应用程序的有用 文章(并且他们建议在整体方法中使用ProGuard)。

关于“创意”方法:一些开发人员采用调试器检测技术来防止运行时分析,并将此与部分二进制代码的加密相结合(以防止静态分析),但说实话,足够决心的攻击者可以规避这些措施,同时也会引起合法用户的沮丧,正如Windows KB文章所述游戏:错误消息:检测到调试器:卸载调试器并重试。我的女朋友的“学车”DVD软件因此无法在VirtualBox下运行,但她当然归咎于Linux!

OpenRCE维基百科关于混淆代码的文章可能是进一步了解此内容的好起点。但请注意,过度热衷于使用这些技术会让您失去更多用户而不是通过反向工程失去商业机密。正如Anton S所说,也许最“有创意”的方法在于调整业务模式而不是技术。

最新的Android SDK更新于2010年12月6日发布(与Android 2.3 Gingerbread版本同时发布):

集成ProGuard支持:ProGuard现在已经打包到SDK工具中。开发人员现在可以将代码混淆作为发布构建的一部分来集成。


1
+1。这是我迄今为止收到的最佳答案。谢谢。除非收到更好的答案,否则将接受此答案。 - Android Eve

14
如果可能的话,可以实现远程过程调用到一个受到良好保护的服务器(该服务器拥有你想要保护的代码)。

我的想法!+1!@Android Eve:您可以使用一个秘密的身份验证密码来连接您的服务器。即使有人从您的代码中提取了这个密码,也没有人能够看到您的计算方式。 - jwueller
1
这个想法很好。然而有一个巨大的缺点:放弃分布式处理的好处。如果算法需要为数亿人提供服务,那么你需要在服务器农场上进行严重的投资。 - Android Eve
我会说忘记口令吧,因为总有人会提取出来的。就像你所说的,这是一个黑盒子,人们只能看到结果,但无法看到产生结果的代码。感谢加一! - jcomeau_ictx
1
口令短语是一种额外的混淆层。您不需要它,但也不会有任何损失,而且使用此服务而不使用应用程序会更加困难。 - jwueller
@elusive:如果这是你的偏好,那就没问题。在这些小评论框中很难解释我的哲学,所以我不会尝试。 - jcomeau_ictx

7

让麻烦变得非常便宜,并且不要建立在客户端执行的秘密之上的业务模型。换句话说,不要分享你的秘密。


6
安东,我的意思不是要对用户进行复制或防盗版保护。该应用程序很可能是免费提供的。我所说的是一些公司可能会进行逆向工程... - Android Eve
同样适用于Root检测。您将尝试控制“控制者的控制者”,包括您依赖的API调用,以了解“谁拥有root访问权限?” - Awi

5

无法防止客户端代码被逆向工程。你只能使用更或者更少有效的混淆代码的方法。而优化的x86汇编语言恰好是一种相当好的混淆方式。

因此,如果你有算法保密,请将其放在服务器端。


Android设备上优化的x86汇编器?如何实现? - Android Eve
3
这只是一般而言 x86 比 Java 字节码更难反编译,但仍有可能。据我所知,可以在 Android 程序中使用原生代码(我猜测是 ARM),但我不确定这是否是一个好主意。 - CodesInChaos
你是在指NDK吗?我不介意在Android上使用我的母语(C ++),但我的理解是,NDK仅限于非常特定的低级系统编程。 - Android Eve

3
如何锁定编译后的Java类以防止反编译
无法做到。 任何方案都可以被具有足够技能、时间和动机的人攻破。
(顺带一提,这也适用于编译成二进制代码的软件。唯一的区别在于反编译所需的努力程度。)
我的问题是,如何保护包含算法商业机密的应用程序免受反向工程?
简单地不要将应用安装在用户手机上。或者(更有用的)在远程(正确安全的)服务器上运行包含商业机密的代码。

1
+1 对于最后一个提示。还有其他不一定是软件技术的想法吗? - Android Eve

2

您无法完全保护您的应用程序,因为总会有人会破解它...

但是,您可以通过使您的应用程序免费或至少价格便宜来阻止他们这样做,以此来阻碍他们。

另一种方法是尽量让您的Android应用程序“愚蠢”,即将所有机密业务逻辑保留在后端服务器上,并只使用某种形式的公开服务显示数据。


第三个点加一分。还有其他的想法,不一定是软件技术吗? - Android Eve

1
无论你做什么,也许至少可以使反编译变得非常困难,但是:如果程序中执行/计算了某些内容,则算法的信息必须存在,并且总会有可能找出如何获取该信息(假设对手具备足够的技能和动机)。始终如此。

0

我将我的算法放在服务器上,并从我的智能手机应用程序中调用该服务。攻击者可以对我的智能手机应用程序进行逆向工程,以查看我与服务器之间的协议。我可以保护我的算法,但无法防止未经授权使用我的服务。我必须接受这个现实而没有解决方案。只要我通过自己的服务赚钱,我就必须接受其他人可能窃取我的服务的潜力。


0

你想寻找一种创新的方法,这里提供一种。

现在手机上尚未被反编译的主程序是什么?无线电固件。为什么?因为它不在手机的ARM芯片组上运行,而是在越来越多出现在智能手机中的高通Hexagon单独芯片上。它不是x86,也不是ARM,它使用了高通专有的架构和指令。

  • Java反编译很容易。

  • ARM反编译更加困难(Hex-Rays反编译器的许可证从1129美元起...并且二进制代码中的Thumb代码和标准ARM代码混合在一起会很麻烦)=>你可以尝试使用Android NDK进行编译。

  • 目前还没有Hexagon反编译器!而且QDSP规格也没有公开的版本,即使是盗版。

问题是,一个独立的软件供应商是否可以使用大众市场手机中包含的Hexagon固件?这似乎是高通所采取的方向。看看他们的网站和SnapDragon产品。

注意:我不是高通或闭源的支持者。但这个帖子呼吁这种解决方案。

1
你不需要反编译来进行逆向工程,只需使用反汇编即可。我发现六边形反汇编非常易读。 - Willem Hengeveld

0

你无法百分之百地保护你的安卓代码免受反向工程。如果你想要保护一些关键信息,那么可以通过集成服务器来获取在调用网络服务时提供给你的加密密钥,并将该密钥用于你的代码中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接