Ph0en1x-100
雷电模拟器打开,随便输入会提示信息Failed
在这里插入图片描述
MainActivity中找到关键词Failed发现调用了三种函数getSecret getFlag以及encrypt

getSecret函数:Java层函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public String getSecret(String arg12) {
String v7 = "KE3TLNE6M43EK4GM34LKMLETG";
try {
byte[] v3 = MessageDigest.getInstance(this.encrypt(v7).substring(5, 8)).digest(arg12.getBytes("UTF-8"));
if(v3 == null) {
return null;
}

StringBuilder v4 = new StringBuilder(v3.length * 2);
byte[] v0 = v3;
int v6 = v0.length;
int v5;
for(v5 = 0; v5 < v6; ++v5) {
int v1 = v0[v5];
if((v1 & 0xFF) < 16) {
v4.append("0");
}

v4.append(Integer.toHexString(v1 & 0xFF));
}

String v8 = v4.toString();
return v8;
}
catch(UnsupportedEncodingException v2) {
v2.printStackTrace();
}
catch(NoSuchAlgorithmException v2_1) {
v2_1.printStackTrace();
}

return null;
}

getFlag以及encrypt函数:so层

1
2
3
4
5
public native String encrypt(String arg1) {
}

public native String getFlag() {
}

根据if判断语句,将getFlag加密值经过getsecret加密与encrypt函数处理后(我们输入的字符串)getSecret加密进行比对。两者都需要进行getSecret加密,我们只需要保证两者加密前相等,就能找到正确的flag。

1
2
3
4
5
6
7
8
public void onGoClick(View arg5) {
if(this.getSecret(this.getFlag()).equals(this.getSecret(this.encrypt(this.etFlag.getText().toString())))) {
Toast.makeText(((Context)this), "Success", 1).show();
}
else {
Toast.makeText(((Context)this), "`Failed`", 1).show();
}
}

so层分析encrypt函数,只要将ASCII码值减一

1
2
3
4
5
6
7
8
9
10
11
12
13
int __fastcall Java_com_ph0en1x_android_1crackme_MainActivity_encrypt(int a1, int a2, int a3)
{
size_t v4; // r4
const char *i; // r5

v4 = 0;
for ( i = (const char *)(*(int (__fastcall **)(int, int, _DWORD))(*(_DWORD *)a1 + '\x02\xA4'))(a1, a3, 0);
v4 < j_strlen(i);
--i[v4++] )
{
;
}
return (*(int (__fastcall **)(int, const char *))(*(_DWORD *)a1 + 668))(a1, i);

然后分析getFlag只有return输出最后的v9没有输入
可以用Fridahook直接得到输出结果(放着吧,我还不会!)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
int __fastcall Java_com_ph0en1x_android_1crackme_MainActivity_getFlag(int a1)
{
signed int i; // r0
char v3; // r3
int v4; // r1
signed int v6; // [sp+0h] [bp-68h]
char *v7; // [sp+4h] [bp-64h]
char v8[16]; // [sp+14h] [bp-54h] BYREF
char v9[40]; // [sp+24h] [bp-44h] BYREF

j_memcpy(v9, &unk_2784, sizeof(v9));
strcpy(v8, "Hello Ph0en1x");
v6 = j_strlen(v8);
for ( i = j_strlen(v9) - 1; i > 0; --i )
{
v3 = v9[i] + 1;
v9[i] = v3;
v7 = &v9[i - 1];
v4 = i % v6;
v7[1] = (v8[v4] ^ (v3 - *v7)) - 1;
}
v9[0] = (v9[0] ^ 0x48) - 1;
return (*(int (__fastcall **)(int, char *))(*(_DWORD *)a1 + 668))(a1, v9);
}

也可以修改smail代码,执行getFlag得到最终结果
首先找到MainActivity中执行getFlag的地方,复制
在这里插入图片描述
粘贴到Failed的地方
在这里插入图片描述
编译生成APK,运行,得到中间值
在这里插入图片描述
写python脚本,将ASCII码值+1

1
2
3
4
5
6
pre='ek`fz@q2^x/t^fn0mF^6/^rb`qanqntfg^E`hq|'
flag=''
for i in pre:
flag+=chr(ord(i)+1)
print(flag)

运行

1
flag{Ar3_y0u_go1nG_70_scarborough_Fair}

修改smail代码的时候,不能把maketext一起覆盖掉,要通过它进行输出
还有修改完代码不能直接进行编译生成APK,要记得先保存。。。