方法一:暴力破解
文件名:KeygenMe#1.apk
工具:ApktoolGui v2.0 Final
主界面:
点击Activate按钮后出来注册提示框:
开工了,先用ApktoolGui v2.0 Final反编译成java
通过查看AndroidManifest.xml文件,找到主Activity:Com.zAWS.KeygenMe.main,查看主Activity处的代码,找到_check_code()函数
光看函数名称就能猜到是判断注册码正确性了。
其对应的smali代码为
将if-eqz改为if-nez重新编译,安装运行。OK
方法二:分析算法,写注册机
文件名:crackme0a.apk
工具:ApktoolGui v2.0 Final
破解前:
先用ApktoolGui v2.0 Final反编译成java源代码
就一个main文件,很简单。查看代码中的点击按钮事件
发现判断语句,找到validateSerial()方法
顺藤摸瓜,发现核心算法在这里
其中getMobileID()方法是获取手机的DeviceId即IMEI号
注册码的生成就是通过获取手机的IMEI号经MD5加密等一系列处理得来的。好了,根据上面的核心算法编写注册代码(由于我用的模拟器实验的,所以IMEI为15个0):
package com.zm.hxb.lover;
import java.security.MessageDigest;
import java.math.BigInteger;
public class KeyTest {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
KeyTest kTest= new KeyTest();
kTest.testResult();
}
public String testResult(){
String str = "000000000000000";
MessageDigest localMessageDigest=null;
try {
localMessageDigest = MessageDigest.getInstance("MD5");
} catch (Exception e) {
System.out.println(e.toString());
e.printStackTrace();
}
byte[] arrayOfByte1 = str.getBytes();
int i = str.length();
localMessageDigest.update(arrayOfByte1, 0, i);
byte[] arrayOfByte2 = localMessageDigest.digest();
byte[] arrayOfByte3 = new byte[arrayOfByte2.length];
int digestPos = 0;
int transformPos = 0;
int m = arrayOfByte2.length;
//int n = arrayOfByte2.length -1;
while (true) {
if (digestPos >= m)
{
BigInteger bInteger = new BigInteger(1, arrayOfByte3);
System.out.println(bInteger.toString(16).substring(0, 15));
return bInteger.toString(16).substring(0, 15);
}
m = arrayOfByte2.length-1;
int v5;
if(digestPos >= m){
v5 = 0;
}else{
v5 = digestPos + 1;
}
int v9 = arrayOfByte2[digestPos];
int v10 = arrayOfByte2[v5];
int i4 = (byte)(v9 ^ v10);
arrayOfByte3[transformPos] = (byte)i4;
digestPos += 2;
transformPos += 1;
}
}
}
得到注册码d67bb44ac8fe21a,输入文本框,OK,破解成功。