jeb反编译apk
主要代码是if 那个判断,getFlag取字符串用getSecret加密,和输入字符串encrypt加密后再getSecret加密,进行比较,两边同样都是getSecret加密,那比较可以简化成this.getFlag() == this.encrypt(s) 。
也就是输入字符经过encrypt加密后等于getFlag的字符串即可。
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(0x7F040019); // layout:activity_main
this.etFlag = (EditText)this.findViewById(0x7F0C004F); // id:flag_edit
}
public void onGoClick(View v) {
String s = this.etFlag.getText().toString();
**if(this.getSecret(this.getFlag()).equals(this.getSecret(this.encrypt(s)))) {**
Toast.makeText(this, "Success", 1).show();
return;
}
Toast.makeText(this, "Failed", 1).show();
}
Hook获取getFlag返回值
直接上objection 获取到getFlag的返回值:ekfz@q2^x/t^fn0mF^6/^rb
qanqntfg^E`hq|
(agent) [360023] Return Value: ekfz@q2^x/t^fn0mF^6/^rb
qanqntfg^E`hq|
ida分析so
ida看下encrypt 的实现。
循环遍历字符串。每个字符-1;
jstring __fastcall Java_com_ph0en1x_android_1crackme_MainActivity_encrypt(JNIEnv *a1, jobject a2, jstring a3)
{
const char *v4; // r4
const char *i; // r5
v4 = (*a1)->GetStringUTFChars(a1, a3, 0);
for ( i = v4; i - v4 < strlen(v4); ++i )
--*i;
return (*a1)->NewStringUTF(a1, v4);
}
算法还原
循环遍历字符串ekfz@q2^x/t^fn0mF^6/^rb
qanqntfg^E`hq|,每个字符+1;
public static void main(String[] args) {
String aa = "ek`fz@q2^x/t^fn0mF^6/^rb`qanqntfg^E`hq|";
char[] chars = new char[aa.length()];
for (int i = 0; i < aa.length(); i++) {
chars[i] = (char) (aa.charAt(i) + 1);
}
System.out.println(chars);
}
得到flag: