逆向攻防世界CTF系列57-babymips

32位无壳,IDA8.3打开不能反编译,使用7.5打开

int __fastcall main(int a1, char **a2, char **a3){
  setbuf((FILE *)stdout, 0);
  setbuf((FILE *)stdin, 0);
  printf("Give me your flag:");
  scanf("%32s", v5);
  for ( i = 0; i < 32; ++i ) *((_BYTE *)&i + i + 4) ^= 32 - (_BYTE)i;
  if ( !strncmp(v5, fdata, 5u) ) result = sub_4007F0(v5);
  else result = puts("Wrong");
  return result;
}

跟进变量i和v5发现地址差4,这里就是将32位逐位异或32- i

image-20241212093710184

下面把前五位取比较

image-20241212093839663

跟进sub_4007F0

int __fastcall sub_4007F0(const char *a1){
  for ( i = 5; i < strlen(a1); ++i ){
    if ( (i & 1) != 0 )
      v1 = (a1[i] >> 2) | (a1[i] << 6);
    else
      v1 = (4 * a1[i]) | (a1[i] >> 6);
    a1[i] = v1;
  }
  if (!strncmp(a1 + 5, (const char *)off_410D04, 0x1Bu) ) result = puts("Right!");
  else result = puts("Wrong!");
  return result;
}

对其进行处理,再比较

enc = [
  0,0,0,0,0,0x52, 0xFD, 0x16, 0xA4, 0x89, 0xBD, 0x92, 0x80, 0x13, 0x41,
  0x54, 0xA0, 0x8D, 0x45, 0x18, 0x81, 0xDE, 0xFC, 0x95, 0xF0,
  0x16, 0x79, 0x1A, 0x15, 0x5B, 0x75, 0x1F
]

flag = 'Q|j{g'
for i in range(len(flag)):
    print(chr(ord(flag[i]) ^ (32 - i)), end='')

for i in range(5,len(enc)):
    if ((i & 1) != 0):
        v1 = ((enc[i] << 2) | (enc[i] >> 6)) &0xFF
    else:
        v1 = ((enc[i] >> 2) | (enc[i] << 6)) &0xFF

    print(chr(v1 ^ (32-i)),end='')