9

对于我的应用程序的付费版本,我选择解锁器应用程序路线,因为它易于实现,允许在开发者控制台中进行单独的统计,但主要是因为我不需要维护 2 个代码库(一个用于免费版本和另一个用于付费版本)。即使我使用了 CVS(我确实这样做了),继续合并功能和错误修复仍然会让人头疼。解锁器应用程序整体上更容易实现......

但这有一个严重的缺点,很容易超过安全检查;除非我在这里遗漏了什么。

无论我做什么,这样的实现总是会导致一个简单的if,像这样:

if(Program.isPremiumVersion()) {
    // Remove ads...
}

isPremiumVersion()方法负责检查付费解锁应用程序安装的所有工作,如果证书匹配等等。是的,解锁器应用程序受 LVL 保护(虽然我读过一些文章提到 LVL 是多么不安全,但这不是现在的重点)。但最终,无论里面的代码isPremiumVersion()变得多么复杂,它总是导致返回一个truefalse值。

覆盖此类安全功能只是对代码进行逆向工程并使其始终返回的问题true。不是吗?我们如何保护我们的 Android 应用免受这种情况的影响?是的,代码被 ProGuard 混淆了。不过,对于足够熟练的人来说应该不会太难。

请注意,我不是想和饼干打架,我们根本就赢不了。我不会为此失眠,在“完美解决方案”上浪费无数时间。我只是在寻找一种让它更安全的方法。至少在理论上,这似乎很容易破解。我错了吗?

有什么想法可以提高此类功能的安全性吗?

4

2 回答 2

7

没有简单的方法可以解决这个问题。

你必须尝试掩盖它。这里有一些提示:

提示 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 演示:使用许可证验证库、应用内计费和 App Engine 逃避海盗和阻止吸血鬼

[编辑-更多提示]

提示 6:尝试使用您使用的代码检查完全有效的位置。这可能会掩盖你在那里真正做的事情。这可能包括调用代码来检查这是哪个版本的应用程序,但没有做任何有意义的事情。或者,在我之前的示例中,将 md5 与 012 或 999 进行比较,只是为了稀释这些变量的实际用途。

提示 7:您可以考虑在运行时构造字符串,而不是依赖单个字符串。决赛和静态也可能会引起太多关注,因此避免这些可能是一件好事。

提示 8:永远不要使用谷歌教程中提供的 LVL 代码。修改它。很多!

注意:我不确定这些技巧中的任何一个是否真的会产生很大的不同,但你应该有很好的机会至少让饼干的生活变得更加艰难。

于 2012-05-10T21:54:15.297 回答
1

您可能已经看到了这一点,但这里有一些代码用于实现您所谈论的内容:

http://groups.google.com/group/android-developers/browse_thread/thread/4ad3d67f735f16d7/948b4f9eee2490a3?pli=1

它检查免费和解锁应用程序上的签名是否相同。因此,某人不可能人为地创建具有正确名称的应用程序,因为签名会有所不同。但是,人们仍然有可能从手机上撕下 apk 并分发它。解决这个问题的唯一方法是使用某种服务器身份验证,但这会增加成本和复杂性。

于 2012-05-10T18:11:14.030 回答