Chapter2——如何分析Android程序

前几天买了《Android软件安全与逆向分析》这本书,决定在这里记一些笔记。

第一章介绍了如何搭建环境,此处略去;第二章开始讲分析Android程序。

下面按顺序记录关键内容。

--------------------------------------

2.1.编写一个需要填写注册码的APK


要破解要现有「试验品」,作者编写了一个叫做crackme02的APP,

主要代码有:

MessageDigest digest = MessageDigest.getInstance("MD5");
digest.result();
digest.update(userName.getBytes());//采用MD5对用户名进行Hash
byte [] bytes = digest.digest();//将计算结果转换为长度32位的16进制字符串
StringBuilder sb = new StringBuilder();
for (int i = 0 ; i <hexStr.length() ; i += 2)//取字符串的奇数位重组为新的字符串,which is SN
	sb.append(hexStr.charAt(i));
StringuserSN = sb.toString();
if(!userSN.equalsIgnoreCase(sn))
	return false ; 

题外话,介绍一下Hash:

Hash,一般翻译做“散列”,也有直接音译为"哈希"的,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,而不可能从散列值来唯一的确定输入值。
MD5可以说是目前应用最广泛的Hash算法。

上面那段代码使用MD5算法计算用户名字符串的Hash,将计算所得的结果转换成长度32位的16进制字符串,然后取字符串的奇数位重新组合成新的字符串,也就成了注册码。然后就是一个判断语句。

接下来他写了一个简单的界面,要求填入用户名和注册码,然后点击注册按钮。

2.2破解第一个程序

破解2.1中写的那个程序。作者用Apktool反编译了apk,得到smali格式的反汇编代码,以及res文件夹中的资源。

突破口是之前编写的程序中的strings.xml中的错误提示。

打开strings.xml,定位到这一行:

<string name = "unsucceeded">无效的用户名或注册码</string>

strings.xml所有的字符串资源都在"gen/<package name>/R.java"文件的String类中被标示,如图:

Chapter2——如何分析Android程序

每个字符串都有唯一的int类型的索引值。用Apktool反编译之后,所有的索引值都保存在strings.xml文件同名目录下的public.xml中,如下图:

Chapter2——如何分析Android程序

(注意这两张图的app_name不是同一个应用的所以才不同。因为只有用apktool反编译之后才会产生res/public.xml,而得不到gen中的R.java。我没有特意去反编译这个应用而是随便找了个反编译好的apk。)

作者在public.xml中找到了unsucceeded对应的id:

<public type="string" name="unsucceeded"  />

然后在smali目录中搜索含有内容为0x7f070024的文件,发现只有MainActivity$1.smali文件一处调用。打开这个文件,代码一大堆,

找到关键的一段:

invoke-static {v0,v1,v2},Lcom/droider/crackme0201/MainActivity;->access$2.....;Ljava/lang/String;)Z #检测注册码是否合法
move-result v0
if-nez v0, :cond_0 #如果结果不为0,就跳转到cond_0:处
....
cond_0
....

把一个Boolean值保存到v0,如果条件为真则跳转到cond_0,否则顺序执行。

显然,把if-nez调成if-eqz就可以了。

然后用apktool b命令重新编译打包成apk。

接下来用signapk.jar对apk签名signapk是源码中的一个签名工具。可以用Android源码中的签名文件testkey.pk8,testkay.x509.pem作为签名文件。具体签名步骤就不介绍了,在书的26页。

然后是安装。他用了adb install signed.apk把这个安装到了AVD里面。然后只要在在注册码中输入任意的东西就可以了。

----------

这篇文章重要的点在于:

通过strings.xml中的文字来定位到unsucceeded,

然后在public.xml中找到它的id,

再在smali文件中找对应的smali文件

这三个步骤。

跟这个差不多:http://bbs.pediy.com/showthread.php?t=153295