[ctf.show.reverse] 屏幕裂开了

一个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}

你可能感兴趣的:(CTF,reverse,reverse)