2015移动安全Crackme1
- 拿到这个APK之后,没啥好说的,安装后发现要输入一个什么密码才能通过验证,拖到JEB里看看。
- 看到
MainActivity
里有几个关键的函数,分别是bytesToAliSmsCode(String, [B)String
,getPwdFromPic()String
,getTableFromPic()String
,aliCodeToBytes(String, String)[B
。具体做什么用的等下再分析。 - 找到
onCreate
函数,发现设置了一个监听器。
00000048 invoke-virtual Button->setOnClickListener(View$OnClickListener)V, v0, v2
- 于是我们继续去找
onClick
函数,应该在MAinActivity$1这个类中,
.method public onClick(View)V
.registers 11
.param p1, "v"
.prologue
00000000 iget-object v6, p0, MainActivity$1->val$edit:EditText
00000004 invoke-virtual EditText->getText()Editable, v6
0000000A move-result-object v6
0000000C invoke-interface Editable->toString()String, v6
00000012 move-result-object v3
.local v3, password:Ljava/lang/String;
00000014 iget-object v6, p0, MainActivity$1->this$0:MainActivity
00000018 invoke-virtual MainActivity->getTableFromPic()String, v6
0000001E move-result-object v5
.local v5, table:Ljava/lang/String;
00000020 iget-object v6, p0, MainActivity$1->this$0:MainActivity
00000024 invoke-virtual MainActivity->getPwdFromPic()String, v6
0000002A move-result-object v4
.local v4, pw:Ljava/lang/String;
0000002C const-string v6, "lil"
00000030 new-instance v7, StringBuilder
00000034 const-string v8, "table:"
00000038 invoke-direct StringBuilder-><init>(String)V, v7, v8
0000003E invoke-virtual StringBuilder->append(String)StringBuilder, v7, v5
00000044 move-result-object v7
00000046 invoke-virtual StringBuilder->toString()String, v7
0000004C move-result-object v7
0000004E invoke-static Log->i(String, String)I, v6, v7
00000054 const-string v6, "lil"
00000058 new-instance v7, StringBuilder
0000005C const-string v8, "pw:"
00000060 invoke-direct StringBuilder-><init>(String)V, v7, v8
00000066 invoke-virtual StringBuilder->append(String)StringBuilder, v7, v4
0000006C move-result-object v7
0000006E invoke-virtual StringBuilder->toString()String, v7
00000074 move-result-object v7
00000076 invoke-static Log->i(String, String)I, v6, v7
0000007C const-string v2, ""
:80
.local v2, enPassword:Ljava/lang/String;
00000080 const-string v6, "utf-8"
00000084 invoke-virtual String->getBytes(String)[B, v3, v6
0000008A move-result-object v6
0000008C invoke-static MainActivity->access$0(String, [B)String, v5, v6
00000092 move-result-object v2
00000094 const-string v6, "lil"
00000098 new-instance v7, StringBuilder
0000009C const-string v8, "enPassword:"
000000A0 invoke-direct StringBuilder-><init>(String)V, v7, v8
000000A6 invoke-virtual StringBuilder->append(String)StringBuilder, v7, v2
000000AC move-result-object v7
000000AE invoke-virtual StringBuilder->toString()String, v7
000000B4 move-result-object v7
000000B6 invoke-static Log->i(String, String)I, v6, v7
:BC
000000BC if-eqz v4, :F2
:C0
000000C0 const-string v6, ""
000000C4 invoke-virtual String->equals(Object)Z, v4, v6
000000CA move-result v6
000000CC if-nez v6, :F2
:D0
000000D0 invoke-virtual String->equals(Object)Z, v4, v2
000000D6 move-result v6
000000D8 if-eqz v6, :F2
:DC
000000DC iget-object v6, p0, MainActivity$1->this$0:MainActivity
000000E0 invoke-static MainActivity->access$1(MainActivity)V, v6
:E6
000000E6 return-void
:E8
000000E8 move-exception v1
.local v1, e:Ljava/io/UnsupportedEncodingException;
000000EA invoke-virtual UnsupportedEncodingException->printStackTrace()V, v1
000000F0 goto :BC
:F2
000000F2 new-instance v0, AlertDialog$Builder
000000F6 iget-object v6, p0, MainActivity$1->this$0:MainActivity
000000FA invoke-direct AlertDialog$Builder-><init>(Context)V, v0, v6
.local v0, builder:Landroid/app/AlertDialog$Builder;
00000100 const v6, 0x7F0A0011 # R.string.dialog_error_tips
00000106 invoke-virtual AlertDialog$Builder->setMessage(I)AlertDialog$Builder, v0, v6
0000010C const v6, 0x7F0A0010 # R.string.dialog_title
00000112 invoke-virtual AlertDialog$Builder->setTitle(I)AlertDialog$Builder, v0, v6
00000118 const v6, 0x7F0A0013 # R.string.dialog_ok
0000011E new-instance v7, MainActivity$1$1
00000122 invoke-direct MainActivity$1$1-><init>(MainActivity$1)V, v7, p0
00000128 invoke-virtual AlertDialog$Builder->setPositiveButton(I, DialogInterface$OnClickListener)AlertDialog$Builder, v0, v6, v7
0000012E invoke-virtual AlertDialog$Builder->show()AlertDialog, v0
00000134 goto :E6
.catch UnsupportedEncodingException {:80 .. :BC} :E8
.end method
整个流程还是比较清晰的,先获取EditText中的内容,然后调用getTableFromPic
,getPwdFromPic
,bytesToAliSmsCode
,最后将enPasswd和getPwdFromPic
得到的数据进行比较,如果一致则通过。搞成JAVA代码大概是下面这个样子。
public void onClick(View v) {
String InputString = this.val$edit.getText().toString();
String pic89473 = MainActivity.this.getTableFromPic();
String pic91265 = MainActivity.this.getPwdFromPic();
Log.i("lil", "table:" + pic89473);
Log.i("lil", "pw:" + pic91265);
try {
String enPassword = MainActivity.bytesToAliSmsCode(pic89473, InputString.getBytes("utf-8"));
Log.i("lil", "enPassword:" + enPassword);
}
catch(UnsupportedEncodingException v1) {
v1.printStackTrace();
}
if(pic91265 == null || (pic91265.equals("")) || !pic91265.equals(enPassword)) {
AlertDialog$Builder v0 = new AlertDialog$Builder(MainActivity.this);
v0.setMessage(2131361809);
v0.setTitle(2131361808);
v0.setPositiveButton(2131361811, new DialogInterface$OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
v0.show();
}
else {
MainActivity.this.showDialog();
}
}
接下来去分析getTableFromPic
和getPwdFromPic
函数。
关键部分如下
inputStream = this.getResources().getAssets().open("logo.png");
int picSize = inputStream.available();
byte[] buffer = new byte[picSize];
inputStream.read(buffer, 0, picSize);
byte[] temp = new byte[768];
System.arraycopy(buffer, 89473, temp, 0, 768); // 从第89473偏移量开始复制768个字节
returnResult = new String(temp, "utf-8");
if(inputStream == null) {
return returnResult;
}
其实就是读取了logo.png这张图片,从89473位置开始读取了768个字节。getPwdFromPic
函数类似。
bytesToAliSmsCode
更简单,主要就是
for(v0 = 0; v0 < data.length; ++v0) {
v1.append(table.charAt(data[v0] & 255));
}
最后返回v1
。
- 注意到代码中有
Log.i
,果断祭出ddms,看看log,先随便输入点什么,比如123456
02-18 11:05:41.434: I/lil(25142): table:一乙二十丁厂七卜人入八九几儿了力乃刀又三于干亏士工土才寸下大丈与万上小口巾山千乞川亿个勺久凡及夕丸么广亡门义之尸弓己已子卫也女飞刃习叉马乡丰王井开夫天无元专云扎艺木五支厅不太犬区历尤友匹车巨牙屯比互切瓦止少日中冈贝内水见午牛手毛气升长仁什片仆化仇币仍仅斤爪反介父从今凶分乏公仓月氏勿欠风丹匀乌凤勾文六方火为斗忆订计户认心尺引丑巴孔队办以允予劝双书幻玉刊示末未击打巧正扑扒功扔去甘世古节本术可丙左厉右石布龙平灭轧东卡北占业旧帅归且旦目叶甲申叮电号田由史只央兄叼叫另叨叹四生失禾丘付仗代仙们仪白仔他斥瓜乎丛令用甩印乐
02-18 11:05:41.434: I/lil(25142): pw:义弓么丸广之
02-18 11:05:41.444: I/lil(25142): enPassword:么广亡门义之
哟~这都是嘛东西,经过上面的分析我们已经知道了,只要让pw和enPassword相等就没问题了,可是这一堆汉字都是嘛东西?
仔细看一下,发现enPassword中出现的汉字其实都在table中,好像就是个单表替换嘛~,这样就简单了,把pw拿到table里匹配一下,发现从“丸”这个字开始,分别对应0123456789。也就是:
丸么广亡门义之尸弓己 -> 0123456789
那把pw翻译出来就是581026,破解成功。