作者:代码疯子
博客:Http://Www.ProgramLife.Net/ 求关注,求勾搭!
这是在crackmes.de上找到的一个Android CrackMe,也属于比较简单的类型,当然如果从学习的角度玩,可以尝试通过阅读smali代码并手动将其翻译成Java代码,最终写出一个Keygen出来。
分析之前先把apk装到模拟器上看一下,有两个Activity,提示了两个Hardware ID,需要输入用户名和注册码进行注册。
使用Apktool GUI将apk解包,查看AndroidManifest.xml文件,看到了两个Activity,分别为com.example.helloandroid.HelloAndroid和com.example.helloandroid.prueba2,其中前者是MainActivity。现在提取出APK包中的classes.dex并将其转换为jar包,使用JD-GUI查看代码。总共看到有5个类,下面一个一个进行分析。
1. 类HelloAndroid代码分析
这个类就是MainActivity了,在onCreate方法中计算了两个Hardware ID并显示到了界面上,这里具体的算法暂时可以忽略,因为在另一段代码中有相同的逻辑。之后给两个Button设置监听器,之前我们在界面中看到有两个按钮,一个是“注册”按钮,一个是“关于”按钮。
2. 类HelloAndroid$1代码分析
这是“关于”按钮的监听器类,在onClick方法中通过Intent启动“关于”界面的Activity,也就是prueba2这个类。
3. 类prueba2代码分析
“关于”界面的Activity,有一个按钮,用于返回注册界面,这个类的代码很简单。
4. 类prueba2$1代码分析
“关于”界面中“返回”按钮的监听器类,在onClick方法中通过Intent返回到注册界面。
5. 类HelloAndroid$2代码分析
这是“注册”按钮的监听器类,整个注册算法也在这里,所以这是要重点分析的代码。其实如果只是写出注册机的话,稍微整理下JD-GUI中的代码也就可以了,不过JD-GUI反编译出来的代码有时候可阅读性不是很好,这里从学习的角度出发,通过阅读smali代码还原Java高级代码。
HelloAndroid$2这个类的smali代码中,个人感觉除了try catch结构比较混乱外,其他的都还算很清晰,在我尝试还原的过程中,也只有try catch的位置无法确定放在哪里。还原后的Java代码如下:
class MyOnClickListener implements OnClickListener { public void onClick(View v) { EditText editName = (EditText)findViewById(0x7F050004); EditText editSerial = (EditText)findViewById(0x7F050006); String strName = editName.getText().toString(); String strSerial = editSerial.getText().toString(); String strTemp1 = ""; if (strName.length() < 4) { Toast.makeText( getApplicationContext(), "Min 4 chars", Toast.LENGTH_LONG ).show(); return ; } int i = 0; int len = strName.length(); while (i < len) { char ch = strName.charAt(i); int nVal = (int)ch; String strTemp = String.valueOf(strTemp1); StringBuilder strBuilder = new StringBuilder(strTemp); strBuilder.append(nVal); strTemp1 = strBuilder.toString(); i += 1; } strTemp1 = strTemp1.substring(0, 5); int nName = Integer.parseInt(strTemp1); nName = nName ^ 0x6B016; strTemp1 = String.valueOf(nName); TelephonyManager telMgr = (TelephonyManager)getSystemService("phone"); String strDevId = telMgr.getDeviceId(); String strSimNo = telMgr.getSimSerialNumber(); String strSubDevId = strDevId.substring(0, 6); String strSubSimNo = strSimNo.substring(0, 6); int nSubDevId = Integer.parseInt(strSubDevId); int nSubSimNo = Integer.parseInt(strSubSimNo); long nTemp = nSubDevId ^ nSubSimNo; StringBuilder strBuilder = new StringBuilder(strTemp1); strBuilder.append("-"); strBuilder.append(String.valueOf(nTemp)); strBuilder.append("-"); strBuilder.append(strSubDevId); String strTemp2 = strBuilder.toString(); if (strTemp2.equals(strSerial)) { Toast.makeText( getApplicationContext(), "God boy", Toast.LENGTH_LONG ).show(); } else { Toast.makeText( getApplicationContext(), "Bad boy", Toast.LENGTH_LONG ).show(); } } } |
具体的过程就是耐心的阅读smali代码。整个算法的过程是:
首先用户名的长度至少为4,之后将用户名的每个字符的ASCII值连接成字符串,取字符串的前5个字符转换为整型,然后与0x6B016进行异或运算,所得的结果转换为字符串,这是注册码的第一部分;
其次通过TelephonyManager获取DeviceId和SimSerialNumber,并分别取两个字符串的前6个字符转换为整型,然后将两个整型数值进行异或运算,将结果转换为字符串,得到注册码的第二部分;
最后是获取DeviceId的前6个字符这一个子串,这是注册码的第三部分。
将这三个字符串用连字符“-”连接起来就是注册码了。
6. 编写Keygen
KeyGen参考注册算法的代码。效果截图如下:
CrackMe / Keygen下载:
http://pan.baidu.com/share/link?shareid=2854465072&uk=369321854
在线阅读本PDF:
http://www.programlife.net/doc/Android_CrackMe_2.pdf
(全文完)
本博客很少转载他人文章,如未特别标明,均为原创,转载请注明出处:
本文出自程序人生 >> 简单Android CrackMe分析3
作者:代码疯子