一个apk的包,用jd打开看原码,它先是行成一个码表用两个序列s和k生成,然后调用libnative_lib.so中的checkflag(s,flag)进行校验
1,每点一次button1会执行一次交换共99999次(所以说屏幕裂开了)
this.btn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
MainActivity mainActivity = MainActivity.this;
mainActivity.hit_count++;
char j = 0;
for (char i = 0; i < 256; i = (char) (i + 1)) {
j = (char) (((MainActivity.this.s[i] + j) + MainActivity.this.k[i]) % 256);
char tmp = MainActivity.this.s[i];
MainActivity.this.s[i] = MainActivity.this.s[j];
MainActivity.this.s[j] = tmp;
}
MainActivity.this.btn.setText(String.valueOf(MainActivity.this.hit_count));
if (MainActivity.this.hit_count >= 99999) {
MainActivity.this.btn2.setEnabled(true);
}
}
2,在lib.so里由s通过63交换次交换每次的结果与输入flag值异或与check比较
__int64 __fastcall Java_com_zxc_ClickStorm_MainActivity_checkflag(__int64 a1, __int64 a2, __int64 a3, __int64 a4)
{
int j; // [rsp+10h] [rbp-180h]
int i; // [rsp+14h] [rbp-17Ch]
__int64 v7; // [rsp+18h] [rbp-178h]
const char *v8; // [rsp+20h] [rbp-170h]
char v9; // [rsp+2Bh] [rbp-165h]
int v10; // [rsp+30h] [rbp-160h]
int v11; // [rsp+34h] [rbp-15Ch]
char v14[264]; // [rsp+80h] [rbp-110h]
unsigned __int64 v15; // [rsp+188h] [rbp-8h]
v15 = __readfsqword(0x28u);
LOBYTE(v11) = 0;
LOBYTE(v10) = 0;
v8 = (const char *)_JNIEnv::GetStringUTFChars(a1, a4, 0LL);// 读入的flag
if ( strlen(v8) != 63 )
return 0;
v7 = _JNIEnv::GetCharArrayElements(a1, a3, 0LL);// 传入的码表
for ( i = 0; i < 256; ++i )
v14[i] = *(_WORD *)(v7 + 2LL * i); // 没用,仅尾1字节有效
for ( j = 0; j < 63; ++j )
{
v11 = (unsigned __int8)(v11 + 1);
v10 = (unsigned __int8)(v14[v11] + v10);
v9 = v14[v11];
v14[v11] = v14[v10];
v14[v10] = v9;
if ( ((unsigned __int8)v14[((unsigned __int8)v14[v10] + (unsigned __int8)v14[v11]) % 256] ^ v8[j]) != answer[j] )
return 0;
}
return 1;
}
根据大意写逆向程序
#tab_s
s = [i for i in range(256)]
k = (b"InfinityLoop"*22) [0:256]
for hit_count in range(99999):
j = 0
for i in range(256):
j = (s[i]+j+k[i])%256
s[i],s[j] = s[j],s[i]
answer = [0xA6,0x3D,0x54,0x0B0,0x74,0xCC,0xBD,0x2A,0x4A,0x0DE,0x0BD,0x35,0x0D1,0x1D,0x80,0x32,0x5F,0x64,0x2F,0x0C5,0x0DD,0x11,0x3E,0x95,0x0CC,0x17,0x13,0x0E5,0x5E,0x65,0x0CE,0x42,0x9E,0x47,0x0C8,0x0F3,0x4D,0x8A,0x0A6,0x1F,0x0F0,0x50,0x27,0x0A2,0x28,0x81,0x24,0x0A7,0x0B4,0x90,0x0FC,0x93,0x8A,0x0C1,0x77,0x0D5,0x16,0x1E,0x0FD,0x87,0x0C7,0x0BB,0x0B3,0x0]
v10,v11 = 0,0
v14 = s
tab = [0]*63
for j in range(63):
v11 = v11+1
v10 = (v14[v11] + v10)& 0xff
v14[v11],v14[v10] = v14[v10],v14[v11]
tab[j] = v14[(v14[v10]+ v14[v11]) %256]
flag = [answer[i]^tab[i] for i in range(63)]
print(bytes(flag))
#flag{i_hope_you_didnt_click_the_button_99999__justRE_in_Static}