如何让“安卓解锁”应用更安全地抵御破解?
Posted
技术标签:
【中文标题】如何让“安卓解锁”应用更安全地抵御破解?【英文标题】:How to make an 'android unlocker' app safer against crackers? 【发布时间】:2012-05-19 08:24:13 【问题描述】:对于我的应用程序的付费版本,我选择解锁器应用程序路线,因为它易于实施,允许在开发者控制台中进行个人统计,但主要是因为我不需要维护 2 个代码库(一个用于免费版和另一个付费版)。即使我使用了 CVS(我确实这样做了),继续合并功能和错误修复仍然会让人头疼。解锁器应用总体上更容易实现...
但这有一个严重的缺点,很容易超过安全检查;除非我在这里遗漏了什么。
无论我做什么,这样的实现总是会导致一个简单的if
,像这样:
if(Program.isPremiumVersion())
// Remove ads...
isPremiumVersion()
方法负责检查付费解锁应用程序安装的所有工作,如果证书匹配等等。是的,解锁器应用程序受 LVL 保护(虽然我读过一些文章提到 LVL 是多么不安全,但这不是现在的重点)。但最终,无论isPremiumVersion()
内部的代码多么复杂,它总是返回一个true
或false
值。
重写此类安全功能只是对代码进行逆向工程并使其始终返回true
。不是吗?我们如何保护我们的 android 应用免受这种情况的影响?是的,代码被 ProGuard 混淆了。不过,对于足够熟练的人来说应该不会太难。
请注意,我并不是要与饼干打架,我们根本无法取胜。我不会为此失眠,在“完美解决方案”上浪费无数时间。我只是在寻找一种让它更安全的方法。至少在理论上,这似乎很容易破解。我错了吗?
有什么想法可以提高此类功能的安全性吗?
【问题讨论】:
如果IFDEF
使用java 等效项,或者将isPremiumVersion
设为常量,然后依赖编译器对其进行优化。
不是破解问题的解决方案,但是如果您使用 android 库项目(不可启动),则应该可以缓解重复代码的问题。它或多或少是一个可以从可启动应用程序调用的类/布局/可绘制的共享库。创建您的应用程序的两个版本(免费、付费)并创建一个包含所有通用代码的库。在您的免费/付费版本中,您可以覆盖 layouts/strings/drawables/etc,如果它们需要与共享库中的不同。应该满足您的需求:developer.android.com/guide/developing/projects/…
@Gophermofur 是的,我知道图书馆的方法,但我不喜欢它,它伴随着其他“问题”。不过,无需深入探讨,它与问题无关。我很久以前就决定使用“解锁”方法,那里没有讨论。不过我很感谢你的建议:)
您只能从脚本 Kiddo 中阻止它。创建一个网络服务并隐藏它背后的高级功能。
@lukas 这不会导致同样的问题吗?我的意思是,无论我做什么,服务器检查将始终返回“许可”或“未许可”,然后我要么启用或不启用高级功能。到头来都是一样的……还是我遗漏了什么?
【参考方案1】:
没有简单的方法解决这个问题。
您必须尝试掩盖它。以下是一些提示:
提示 1: 返回布尔值太明显了。尝试返回一个值(例如 int)。然后,使用比较来查看这是否是一个有效的已知返回值。
例如:获取包含某些内容的字符串的 md5,您可以从中判断它是否是优质的。假设您在每个应用程序上都有一个静态的最终字符串。也许一个的 md5 以 9 开头,另一个以 1 开头。在这种情况下,计算 md5 并查看它是否大于您知道它位于其他两个数字之间的“随机”数字。假设“premium”的md5是987,“free”的md5是123。你可以计算md5和456比较。
提示 2 - 更好的是:复制一些代码并每次使用不同的值(而不是 456)!希望这将使混淆代码的解码变得更加困难。
我知道所有这些检查最终都会映射到一个布尔值(if(1 > 2)
将被评估为 if(true)
),但是对您的应用进行逆向工程应该会更加困难。
提示 3:不要在最明显的地方检查“isPremium”。例如,不要在启动应用程序时进行检查,因为这是最明显的地方。如果您想根据应用程序的版本使用条件逻辑,可能很难避免某些明显的地方,但请在这里尽力而为!
提示 4: 构建和混淆您的应用。针对您的 apk 运行逆向工程工具。阅读它,看看它的外观。
最后,每天早餐时观看这个 Google IO 演示:Evading Pirates and Stopping Vampires using License Verification Library, In-App Billing, and App Engine
[编辑 - 更多提示]
提示 6: 尝试使用您使用的代码检查完全有效的位置。这可能会掩盖你在那里真正做的事情。这可能包括调用代码来检查这是哪个版本的应用程序,但没有做任何有意义的事情。或者,在我之前的示例中,将 md5 与 012 或 999 进行比较,只是为了稀释这些变量的实际用途。
提示 7: 与其依赖单个字符串,不如考虑在运行时构造字符串。决赛和静态也可能会引起太多关注,因此避免这些可能是一件好事。
提示 8:不要永远使用 google 教程中提供的 LVL 代码。修改它。很多!
注意:我不确定这些技巧中的任何一个是否真的会产生很大的不同,但你应该有很好的机会至少让饼干的生活变得更艰难。
【讨论】:
我想我的代码需要变得凌乱...我讨厌凌乱的代码,这是我的问题:(【参考方案2】:你可能已经看过了,但这里有一些代码可以用来实现你所说的:
http://groups.google.com/group/android-developers/browse_thread/thread/4ad3d67f735f16d7/948b4f9eee2490a3?pli=1
它会检查免费应用和解锁应用上的签名是否相同。因此,某人不可能人为地创建具有正确名称的应用程序,因为签名会有所不同。但是,人们仍然有可能从手机上撕下 apk 并分发它。解决这个问题的唯一方法是使用某种服务器身份验证,但这会增加成本和复杂性。
【讨论】:
以上是关于如何让“安卓解锁”应用更安全地抵御破解?的主要内容,如果未能解决你的问题,请参考以下文章