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;
}