https://www.ctfiot.com/213409.html#:~:text=3.%20Reverse-,3.1%20mips,-%E5%85%88%E9%80%86mips_bin

https://blog.xmcve.com/2024/11/04/%E5%BC%BA%E7%BD%91%E6%9D%AF2024-Writeup/#title-13

还是要断舍离,相信自己的能力才行(盯 bin 盯了老半天,还以为没看到东西,没想到是 emu 出问题了

have a emulator to run the bin

./emu ./mips_bin

cipher1 = "sxrujtv`labiVzbp`vpg|"
opcode = [0x814226, 0x3C080201, 0x35283A03, 0x240B0216, 0x240A0203,
          0x11610205, 0x10203, 0x21280202, 0x21090202, 0x214BFDFC,
          0x11410209, 0x10203, 0x18D6225, 0x1AC6A25, 0x812D0203,
          0x810C0203, 0x18B6225, 0x1AD6A25, 0x11A1FDF7, 0x10203,
          0x240A0202, 0x1611226, 0x3E1020B, 0x10203]

using fork to calc the data

try to patch the opcode:

from idaapi import *
 
base = 0x00430010
i = 0
while (True):
    addr = base+i
    byte = get_bytes(addr, 1)  
    byte = i & 3 ^ ord(byte)
    patch_byte(addr, byte) 
    i += 1
    if addr == 0x00430070:
        break
 
int __fastcall opcodes(char *a1)//input
{
  int v2; // $t1
  int v3; // $t2
  int v4; // $t3
 
  v2 = 145408;
  v3 = 21;
  v4 = 0;
  while ( !(*a1 ^ *(char *)v2 ^ v3) )
  {
    ++v2;
    ++a1;
    if ( !--v3 )
      return v4;
  }
  return 1;
}
cipher1 = "sxrujtv`labiVzbp`vpg|"
 
for i in range(len(cipher1)):
    print(chr(ord(cipher1[i])^(21-i)), end='')
// flag{dynamic_reverse}
 

发现是假 flag

用 qemu 跑发现能输出 correct 说明 emu 里面藏东西了

有两个思路,第一个 bindiff 看看

syscall:

用 bindiff 能跟踪到 syscall

或者 mmap 直接在固定位置分配内存,很诡异,所以直接在 emu 里搜常量 0x23000,直接锁定函数 0x33D8E0

__int64 __fastcall sub_7F41017F18E4(__int64 a1)
{
  __int64 result; // rax
  int v2; // [rsp+10h] [rbp-20h]
  int i; // [rsp+14h] [rbp-1Ch]
  int j; // [rsp+18h] [rbp-18h]
  __int64 v5; // [rsp+20h] [rbp-10h]
  __int64 v6; // [rsp+28h] [rbp-8h]
 
  v5 = *(_QWORD *)(a1 + 528);
  v2 = 0;
  result = *(unsigned int *)(v5 + 128);
  if ( *(_DWORD *)(v5 + 128) == (_DWORD)&unk_23000 )
  {
    result = (unsigned int)dword_7F41020E6318;
    if ( dword_7F41020E6318 )
    {
      v6 = sub_7F41017F148E((__int64)&unk_7F41020E7280);
      for ( i = 0; i <= 21; ++i )
        *(_BYTE *)(i + v6) ^= dword_7F41020E6324;
      sub_7F41017F1886(v6, 7, 11);
      result = sub_7F41017F1886(v6, 12, 16);
      for ( j = 0; j <= 21; ++j )
      {
        result = (unsigned int)dword_7F4102050A80[j];
        if ( *(unsigned __int8 *)(j + v6) != (_DWORD)result )
        {
          v2 = 1;
          break;
        }
      }
      if ( !v2 && j == 22 )
        dword_7F41020E631C = 1;
    }
  }
  return result;
}
 
//xref to dword_7F41020E6318
 
case 4003u:
      if ( *((_QWORD *)&v387 + 1) )
      {
        v521 = (_BYTE *)sub_3EB0C9(3LL, HIDWORD(v387), SDWORD2(v387), 0LL);
        if ( v521 )
        {
          v13 = sub_3C9EA1((unsigned int)which_clock, v521, SDWORD2(v387));
          rlim_cur = sub_3C9E33(v13);
          if ( (rlim_cur & 0x80000000) == 0 && sub_3C8B51((unsigned int)which_clock) )
          {
            v14 = (__int64 (__fastcall *)(_BYTE *, _QWORD))sub_3C8B51((unsigned int)which_clock);
            rlim_cur = v14(v521, (int)rlim_cur);
          }
          v683 = v521;
          if ( rlim_cur == 28
            && *v683 == 'f'
            && v683[1] == 'l'
            && v683[2] == 'a'
            && v683[3] == 'g'
            && v683[4] == '{'
            && v683[26] == '}' )
          {
            dword_C32318 = 1;
            sub_22E140(&unk_C33280, 0LL, 32LL);
            sub_22E0F0(&unk_C33280, v683, 27LL);
          }
          sub_3C8389(v521, HIDWORD(v387), (int)rlim_cur);
          result = rlim_cur;
        }
        else
        {
          result = 4294967282LL;
        }
      }
      else
      {
        v12 = sub_3C9EA1((unsigned int)which_clock, 0LL, 0LL);
        result = sub_3C9E33(v12);
      }
      goto LABEL_1534;

动调一直断不了,把 bin 的反调试关了也不行,只能硬看了

__int64 __fastcall rc4init(__int64 input)
{
  // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]
 
  v5 = input;
  v17 = __readfsqword(0x28u);
  memset(v13, 0, sizeof(v13));
  v14 = 0;
  memset(sbox, 0, sizeof(sbox));
  v16 = 0;
  for ( i = 0; i <= 255; ++i )
    sbox[i] = i;
  v9 = 0;
  v7 = 0;
  v10 = 0;
  i_1 = 0;
  key = "6105t3";
  do
  {
    v9 = (unsigned __int8)sbox[i_1];
    v11 = 2 * (i_1 / 6 - (((2863311531u * (unsigned __int64)i_1) >> 32) & 0xFFFFFFFC));
    v10 = (unsigned __int8)(key++)[v11];
    v7 += v9 + v10;
    v1 = i_1++;
    sbox[v1] = sbox[(unsigned __int8)v7];
    v2 = (unsigned __int8)v7;
    sbox[(unsigned __int8)v7] = v9;
  }
  while ( i_1 != 256 );
  v4[0] = 3397240LL;
  return _InterlockedExchange64(v4, _InterlockedExchange64(v4, v2) + 13);
}

有栈上的花指令,nop 掉

const char *__fastcall rc4(char *input)
{
  int v1; // edx
  const char *result; // rax
  unsigned __int8 v3; // [rsp+15h] [rbp-17Bh]
  int i; // [rsp+18h] [rbp-178h]
  int v5; // [rsp+1Ch] [rbp-174h]
  unsigned int i_1; // [rsp+20h] [rbp-170h]
  int v7; // [rsp+24h] [rbp-16Ch]
  int v8; // [rsp+28h] [rbp-168h]
  int j; // [rsp+2Ch] [rbp-164h]
  int v10; // [rsp+30h] [rbp-160h]
  int v11; // [rsp+34h] [rbp-15Ch]
  int v12; // [rsp+3Ch] [rbp-154h]
  const char *key; // [rsp+40h] [rbp-150h]
  const char *res; // [rsp+48h] [rbp-148h]
  char sbox[128]; // [rsp+80h] [rbp-110h] BYREF
  __int16 v16; // [rsp+180h] [rbp-10h]
  unsigned __int64 v17; // [rsp+188h] [rbp-8h]
 
  v17 = __readfsqword(0x28u);
  *(_QWORD *)sbox = 0LL;
  *(_QWORD *)&sbox[8] = 0LL;
  memset(&sbox[16], 0, 0xF0uLL);
  v16 = 0;
  for ( i = 0; i <= 255; ++i )
    sbox[i] = i;
  v5 = 0;
  i_1 = 0;
  key = "6105t3";
  do
  {
    v10 = (unsigned __int8)sbox[i_1];
    v11 = (unsigned __int8)(key++)[(int)(2 * (i_1 / 6 - (((2863311531u * (unsigned __int64)i_1) >> 32) & 0xFFFFFFFC)))];
    v5 += v10 + v11;
    v1 = i_1++;
    sbox[v1] = sbox[(unsigned __int8)v5];
    sbox[(unsigned __int8)v5] = v10;
  }
  while ( i_1 != 256 );
  v7 = 0;
  v8 = 0;
  res = (const char *)malloc(256LL);
  for ( j = 0; j != 22; ++j )
  {
    v12 = (unsigned __int8)sbox[(unsigned __int8)++v7];
    v8 += v12;
    sbox[(unsigned __int8)v7] = sbox[(unsigned __int8)v8];
    sbox[(unsigned __int8)v8] = v12;
    v3 = ((((unsigned __int8)(input[j + 5] << 7) | ((unsigned __int8)input[j + 5] >> 1)) << 6) ^ 0xC0 | ((unsigned __int8)((input[j + 5] << 7) | ((unsigned __int8)input[j + 5] >> 1)) >> 2) ^ 0x3B) ^ 0xBE;
    res[j] = sbox[(unsigned __int8)(sbox[(unsigned __int8)v7] + v12)] ^ byte_B9CA60[j & 3] ^ (((unsigned __int8)(((16 * (((32 * v3) | (v3 >> 3)) ^ 0xAD)) | ((unsigned __int8)(((32 * v3) | (v3 >> 3)) ^ 0xAD) >> 4)) ^ 0xDE) >> 5) | (8 * (((16 * (((32 * v3) | (v3 >> 3)) ^ 0xAD)) | ((unsigned __int8)(((32 * v3) | (v3 >> 3)) ^ 0xAD) >> 4)) ^ 0xDE)));
  }
  result = res;
  if ( v17 != __readfsqword(0x28u) )
    sub_616930();
  return result;
}