如何使'android unlocker'应用程序更安全地抵御饼干?

问题描述:

对于我的应用程序的付费版本,我选择了解锁器应用程序路由,因为它很容易实现,允许开发人员控制台中的各个统计信息,但主要是因为我不需要维护2个代码库(一个用于免费版本和付费版本的另一个版本)。即使我使用了CVS(我也这样做),继续合并功能和错误修复仍然是一件痛苦的事情。解锁应用程序总体上实施起来要容易得多...如何使'android unlocker'应用程序更安全地抵御饼干?

但是这带来了一个严重的缺点,它很容易超出安全检查;除非我在这里错过了一些东西。

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

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

isPremiumVersion()方法是一个负责检查的付费解锁应用程序安装了所有的工作,如果证书匹配和所有的东西。是的,解锁应用程序受LVL保护(尽管我已阅读了几篇文章,提及LVL是多么不安全,但这不是重点)。但最终,无论isPremiumVersion()中的代码有多复杂,它总会导致返回truefalse值。

覆盖此类安全功能只是对代码进行反向工程,并始终返回true。不是吗?我们如何保护我们的Android应用程序免受此影响?是的,代码被ProGuard混淆了。尽管如此,对于有足够熟练的人来说不应该太难。

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

任何想法,以提高这种功能的安全性?

+0

只要使用'IFDEF'或者使'isPremiumVersion'为常量的java等价物,并且依靠编译器优化它。 – CodesInChaos

+3

不解决您的破解问题,但如果您使用Android库项目(不可启动),则应该减轻重复代码问题。它或多或少是可以从可启动应用程序中调用的类/布局/可绘制的共享库。创建两个版本的应用程序(免费,付费)并创建一个包含所有常用代码的库。在免费/付费版本中,如果需要与共享库中的内容不同,则可以覆盖布局/字符串/绘图/等。应该满足您的需求:http://developer.android.com/guide/developing/projects/projects-eclipse.html – Gophermofur

+0

@Gophermofur是的,我知道图书馆的方法,但我不喜欢它,它带有其他事宜”。不需要更深入,它与问题无关。我很久以前就决定,我正在用“解锁器”的方法,并没有在那里讨论。我赞赏你的建议,但:) –

您可能已经看到了这一点,但这里是执行一些代码,你在说什么:

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

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

+0

这与我的问题有什么关系?它不回答任何问题... –

有没有简单的解决方法。

你必须尝试掩盖它。以下是一些提示:

提示1:返回布尔值太明显。尝试返回一个值(例如int)。然后,使用比较来查看这是否是有效的已知返回值。

例如:获取一个字符串的md5,其中包含可以判断是否溢价的东西。假设你在每个应用上都有一个静态的最终字符串。也许一个人的md5以9开头,另一个以1开头。在这种情况下,计算md5,看看它是否大于一个“随机”数字,你知道它在另外两个数字之间。假设“高级”的md5是987,“free”的md5是123.您可以计算md5并将其与456进行比较。

提示2 - 更好:重复一些代码,每次使用不同的值(而不是456)!希望这会使解码混淆代码变得更加困难。

我知道所有这些检查最终都会映射到一个布尔值(if(1 > 2)将被评估为if(true)),但是对应用程序进行逆向工程应该更加困难。

提示3:不要在最明显的地方运行“isPremium”检查。例如,不要在启动应用程序时进行检查,因为这是最明显的地方。如果您想要取决于应用程序版本的条件逻辑,则可能难以避免某些明显的斑点,但请尽力而为!

提示4:构建和混淆你的应用程序。针对您的apk运行逆向工程工具。阅读并看看它看起来如何。

最后,这个谷歌IO呈现每天吃早饭时看:Evading Pirates and Stopping Vampires using License Verification Library, In-App Billing, and App Engine

[编辑 - 几个技巧]

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

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

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

注:我不知道如果这些建议实际上会带来很大的区别,但你应该有至少制作饼干的生活有点困难,很好的机会。

+2

我想我的代码需要弄乱...我讨厌凌乱的代码,这是我的问题:( –