频道栏目
读书频道 > 安全 > Android软件安全与逆向分析
5.6.3 定位关键代码——使用IDA Pro进行破解的实例
2012-12-27 15:46:26     我来说两句
收藏   我要投稿

本文所属图书 > Android软件安全与逆向分析

Android软件安全一直是广大开发者与软件用户讨论的话题,但市场上却没有发现类似选题的书籍。本书主要从以下几个方面对Android安全展开探讨:首先是Android程序的反汇编,这一部分是绝大多数开发人员所关心,但大...  立即去当当网订购

使用IDA Pro 定位关键代码的方法整体上与定位 smali 关键代码差不多。
 
第一种方法是搜索特征字符串。首先按下快捷键 CTRL+S 打开段选择对话框,双击STRINGS段跳转到字符串段,然后点击菜单项“Search →text ”,或者按下快捷键 ALT+T,打开文本搜索对话框,在 String 旁边的文本框中输入要搜索的字符串后点击 OK按钮,稍等片刻就会定位到搜索结果。不过目前 IDA Pro 对中文字符串的显示与搜索都不支持,如果字符串中的中文字符显示为乱码,需要编写相关的字符串处理插件来解决,这个工作就交给读者去完成了。

第二种方法是搜索关键API。首先按下快捷键CTRL+S 打开段选择对话框,双击第一个CODE 段跳转到数据起始段,然后点击菜单项“Search →text ”,或者按下快捷键 ALT+T,打开文本搜索对话框,在String 旁边的文本框中输入要搜索的API 名称后点击OK按钮,稍等片刻就会定位到搜索结果。如果API 被调用多次,可以按下快捷键CTRL+T 来搜索下一项。

第三种方法是通过方法名来判断方法的功能。这种办法比较笨拙,对于混淆过的代码,定位关键代码比较困难。比如,我们知道crackme0502.apk 程序的主Activity 类为MainActivity,于是在 Exports选项卡页面上输入 Main,代码会自动定位到以 Main开头的所在行,如图5-9 所示,可粗略判断出每个方法的作用。


 

下面我们来尝试破解一下crackme0502.apk。首先安装运行 apk 程序,程序运行后有两个按钮,点击“获取注解”按钮会Toast弹出3 条信息。在文本框中输入任何字符串后,点击“检测注册码”按钮,程序弹出注册码错误的提示信息。这里我们以按钮事件响应为突破口来查找关键代码,通过图5-9 我们可以发现有两个名为OnClick()的方法,那具体是哪一个呢?我们分别进去看看。前者调用了MainActivity.access$0()方法,在IDA Pro 的反汇编界面双击MainActivity_access可以看到它其实调用了MainActivity的getAnnotations()方法,看到这里应该可以明白,MainActivity$1.onClick()方法是前面按钮的事件响应代码。接下来查看MainActivity$2.onClick()方法,双击代码行,来到相应的反汇编代码处,按下空格键切换到IDA Pro 的流程视图,如图5-10 所示,代码的“分水岭”就是“if-eqz v2,loc_2D0DC ”。图中左边红色箭头表示条件不满足时执行的路线,右边的绿色箭头是条件满足时执行的路线。


 

虽然不知道这堆乱码字符串分别是什么,但通过最后调用的Toast来看,直接修改 if-eqz即可将程序破解。将鼠标定位到指令“if-eqz v2, loc_2D0DCD ”所在行,然后点击IDA Pro主界面的“Hex View-A”选项卡,可看到这条指令所在的文件偏移为0x2D0BE,相应的字节码为“38 02 0f 00 ”,通过前面的学习,我们知道只需将 if-eqz 的OpCode值38 改成if-nez的OpCode值39即可。说干说干,使用C32asm打开classes.dex 文件,将 0x2D0BE的38改为39,然后保存退出。接着按照本书 4.6 小节的介绍,将dex 文件进行Hash修复后导入apk 文件,对 apk 重新签名后安装测试发现程序已经破解成功了。

为了让读者看到一种常见的Android程序的保护手段,这里更换一下破解思路。通过图5-10 可发现,MainActivity$SNChecker.isRegistered()方法实际上返回一个Boolean 值,通过判断它的返回值来确定注册码是否正确。现在的问题是,如果该程序是一个大型的Android软件,而且调用注册码判断的地方可能不止一处,这种情况时,通常有两种解决方法:第一种是使用IDA Pro 的交叉引用功能查找到所有方法被调用的地方,然后修改所有的判断结果;第二种方法是直接给isRegistered() 方法“动手术”,让它的结果永远返回为真。很显然,第二种方法解决问题更利落,而且一劳永逸。

下面尝试使用这种方法进行破解,首先按下空格键切换到反汇编视图,发现直接修改方法的第二条指令为“return v9  ”即可完成破解,对应机器码为“0F 09”,将其修改完成后重新修复与签名,安装测试发现程序启动后就立即退出了。这时最先怀疑的是程序是否修改正确,使用 IDA Pro 重新导入修改过的classes.dex 文件,发现修改的地方没错,看来是程序采取了某种保护措施!回想一下前面提到的两种程序退出方法: Context 的finish() 方法与android.os.Process 的killProcess()方法,按下快捷键CTRL+S 并双击 CODE 回到代码段,接着按下快捷键ALT+T搜索 finish 与killProcess,最后在 MyApp类的onCreate()方法中找到了相应的调用,查看相应的反汇编代码,发现这段代码使用Java 的反射机制,手工调用isRegistered() 方法检查字符串“11111”是否为合法注册码,如果是或者调用 isRegistered() 失败都说明程序被修改过,从而调用killProcess()来杀死进程。明白了保护手段,解决方法就简单多了,直接将两处killProcess()的调用直接nop 掉(修改相应地方的指令为0 )就可以了。

您对本文章有什么意见或着疑问吗?请到论坛讨论您的关注和建议是我们前行的参考和动力  
上一篇:5.6.2 如何操作
下一篇:5.7.1 Androguard的安装与配置
相关文章
图文推荐
排行
热门
最新书评
特别推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站