Overlong
[FlareOn6]Overlong
- 首先查壳,发现无壳,且程序为32位程序
- 使用IDA打开
int __stdcall start(int a1, int a2, int a3, int a4)
{
CHAR Text[128]; // [esp+0h] [ebp-84h] BYREF
int v6; // [esp+80h] [ebp-4h]
v6 = sub_401160(Text, &unk_402008, 28);
Text[v6] = 0;
MessageBoxA(0, Text, Caption, 0);
return 0;
}
首先定义了Text这个char数组和int数值v6
- 进入sub_401160函数
unsigned int __cdecl sub_401160(char *a1, int a2, unsigned int a3)
{
unsigned int i; // [esp+4h] [ebp-4h]
for ( i = 0; i < a3; ++i )
{
a2 += sub_401000(a1, a2);
if ( !*a1++ )
break;
}
return i;
}
其中a3为28
- 进入sub_401000
int __cdecl sub_401000(_BYTE *a1, char *a2)
{
int v3; // [esp+0h] [ebp-8h]
char v4; // [esp+4h] [ebp-4h]
if ( (int)(unsigned __int8)*a2 >> 3 == 30 )
{
v4 = a2[3] & 0x3F | ((a2[2] & 0x3F) << 6);
v3 = 4;
}
else if ( (int)(unsigned __int8)*a2 >> 4 == 14 )
{
v4 = a2[2] & 0x3F | ((a2[1] & 0x3F) << 6);
v3 = 3;
}
else if ( (int)(unsigned __int8)*a2 >> 5 == 6 )
{
v4 = a2[1] & 0x3F | ((*a2 & 0x1F) << 6);
v3 = 2;
}
else
{
v4 = *a2;
v3 = 1;
}
*a1 = v4;
return v3;
}
这个函数应该是对数值a1,a2做计算然后赋值给a2
结合这道题的提示,观察unk_402008,可以发现
.rdata:00402008 unk_402008 db 0E0h ; DATA XREF: start+B↑o
.rdata:00402009 db 81h
一直到
.rdata:004020B6 db 0ADh
.rdata:004020B7 db 0
计算一下B7-08=AF,即十进制的175,长度不仅只有28,所有这里需要修改这个长度
; Attributes: bp-based frame
public start
start proc near
Text= byte ptr -84h
var_4= dword ptr -4
push ebp
mov ebp, esp
sub esp, 84h
push 1Ch //1c即28
push offset unk_402008
lea eax, [ebp+Text]
push eax
call sub_401160
add esp, 0Ch
mov [ebp+var_4], eax
mov ecx, [ebp+var_4]
mov [ebp+ecx+Text], 0
push 0 ; uType
push offset Caption ; "Output"
lea edx, [ebp+Text]
push edx ; lpText
push 0 ; hWnd
call ds:MessageBoxA
xor eax, eax
mov esp, ebp
pop ebp
retn 10h
start endp
这里使用od进行修改
将1c改为AF

允许程序得到flag
flag
[WUSTCTF2020]Cr0ssfun
- 首先查壳,无壳,是elf64位程序
- 拖入IDA,main函数反汇编
int __cdecl main(int argc, const char **argv, const char **envp)
{
char v4[48]; // [rsp+0h] [rbp-30h] BYREF
puts(" _ _ _ _ _____ _____ _____ ");
puts("| | | | | | / ___|_ _| / ___| ");
puts("| | | | | | \\ `--. | | \\ `--. ___ ___ ");
puts("| |/\\| | | | |`--. \\ | | `--. \\/ _ \\/ __|");
puts("\\ /\\ / |_| /\\__/ / | | /\\__/ / __/ (__ ");
puts(" \\/ \\/ \\___/\\____/ \\_/ \\____/ \\___|\\___|");
while ( 1 )
{
puts("Input the flag");
__isoc99_scanf("%s", v4);
if ( (unsigned int)check(v4) == 1 )
break;
puts("0ops, your flag seems fake.");
puts("==============================");
rewind(_bss_start);
}
puts("Your flag is correct, go and submit it!");
return 0;
}
这里注意到check函数是关键,点入该函数,出现了连续的函数
__int64 __fastcall check(__int64 a1)
{
return iven_is_handsome(a1);
}
BOOL8 __fastcall iven_is_handsome(_BYTE *a1)
{
return a1[10] == 112
&& a1[13] == 64
&& a1[3] == 102
&& a1[26] == 114
&& a1[20] == 101
&& (unsigned int)iven_is_c0ol(a1);
}
BOOL8 __fastcall iven_is_c0ol(_BYTE *a1)
{
return a1[7] == 48
&& a1[16] == 95
&& a1[11] == 112
&& a1[23] == 101
&& a1[30] == 117
&& (unsigned int)iven_1s_educated(a1);
}
_BOOL8 __fastcall iven_1s_educated(_BYTE *a1)
{
return *a1 == 119 && a1[6] == 50 && a1[22] == 115 && a1[31] == 110 && a1[12] == 95 && (unsigned int)iven_1s_brave(a1);
}
BOOL8 __fastcall iven_1s_brave(_BYTE *a1)
{
return a1[15] == 100
&& a1[8] == 123
&& a1[18] == 51
&& a1[28] == 95
&& a1[21] == 114
&& (unsigned int)iven_1s_great(a1);
}
_BOOL8 __fastcall iven_1s_great(_BYTE *a1)
{
return a1[2] == 116
&& a1[9] == 99
&& a1[32] == 125
&& a1[19] == 118
&& a1[5] == 48
&& a1[14] == 110
&& (unsigned int)iven_and_grace(a1);
}
BOOL8 __fastcall iven_and_grace(_BYTE *a1)
{
return a1[4] == 50 && a1[17] == 114 && a1[29] == 102 && a1[17] == 114 && a1[24] == 95 && (unsigned int)finally_fun(a1);
}
BOOL8 __fastcall finally_fun(_BYTE *a1)
{
return a1[1] == 99 && a1[25] == 64 && a1[27] == 101;
}
emm,这个题就是将这些组合起来
flag
firmware
路由器固件逆向初探:https://www.cnblogs.com/Lamboy/p/3378111.html
firmware-mod-kit工具安装和使用说明:https://blog.csdn.net/ldwj2016/article/details/80712566
BUUCTF--firmware:https://blog.csdn.net/qq_39542714/article/details/106834889


浙公网安备 33010602011771号