准备环境
工具:jeb + android killer + eclipse + cmder
逆向分析
apk拖入:jeb
1、找到入口代码:
题目很简单,v2 == v4的内容就算破解成功,分析v2 和v4数据来源,发现v4就是目标密码,只不过是加密后的密码。(此题是通过密文比较,判断 成功与否)
突破点,有日志输出:
1、发现有日志输出:Log.i ,第一个想到的就是查看日志输出(从后面的分析结果来看,最好还是用eclipse或者android studio 带DDMS工具查看日志)
于是adb logcat -s “lil’
得到日志信心如下:很可惜显示的全部是乱码!!! 最后发现是cmder的bug,不能显示中文
通过:eclipse输出,发现其实是中文,,,被cmder给坑了!!!
解决方案:
1、在原apk中添加日志,并重新编译(代价更小一些)
2、直接抠出原有的代码,并添加日志代码,不改变原来的apk。(代价更大一些)
这里我想的是代码直接还原,模拟环境,并添加日志输出
突破分析源代码如下:
protected String getTableFromPic() {
String v6;
InputStream v3;
String v5 = "";
try {
v3 = this.getResources().getAssets().open("logo.png");
int v4 = v3.available();
byte[] v0 = new byte[v4];
v3.read(v0, 0, v4);
byte[] v1 = new byte[768];
System.arraycopy(v0, 89473, v1, 0, 768);
v6 = new String(v1, "utf-8");
for(int i = 0; i < 256; ){
Log.i("TTT",v6.substring(i, i+31));
i += 32;
}
Log.i("TTT", v6);//将v6的内容输出,发现就是密文中文字符集
Log.i("TTT", "" + v6.length());
if(v3 == null) {
return v6;
}}catch(Exception e){
e.printStackTrace();
}
return "";
}
protected String getPwdFromPic() {
String v6;
InputStream v3;
String v5 = "";
try {
v3 = this.getResources().getAssets().open("logo.png");
int v4 = v3.available();
byte[] v0 = new byte[v4];
v3.read(v0, 0, v4);
byte[] v1 = new byte[18];
System.arraycopy(v0, 91265, v1, 0, 18);
v6 = new String(v1, "utf-8");//将v6的内容输出,发现就是密文中文字符集密码
Log.i("TTT", "" + v6.length());
Log.i("TTT","" + bn(v6.getBytes("utf-8")));
if(v3 == null) {
return v6;
}
return v6;
}catch(Exception e){
e.printStackTrace();
}
return "";
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String key = "中国";
getTableFromPic();
getPwdFromPic();
try {
Log.i("TTT","" + bn(key.getBytes("utf-8")));
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
分析输出的日志:密码是:义弓么丸广之,,,找到密文数组中对应的所对应的下标,即可换算出用户应该输入的密码
最终用户需要输入密码是:581026
测试效果:
小结
1、java层代码的的日志是一个好的利用点,用好它可以节省很多事
2、cmder在windows比cmd好用,但是在中文字符上支持不足。可以使用ddms作为参看日志输出,或者使用重定位功能将日志重定位到文件当中。