
IDA를 사용해 main 함수를 디컴파일 해보겠습니다.
int __fastcall main(int argc, const char **argv, const char **envp)
{
char v4[256]; // [rsp+20h] [rbp-118h] BYREF
memset(v4, 0, sizeof(v4));
sub_1400011B0("Input : ", argv, envp);
sub_140001210("%256s", v4);
if ( (unsigned int)sub_140001000(v4) )
puts("Correct");
else
puts("Wrong");
return 0;
}
memset 이후에 printf 함수와 scanf 함수가 실행됩니다.
if문의 조건인 sub_140001000 함수를 살펴보겠습니다.
__int64 __fastcall sub_140001000(__int64 a1)
{
int i; // [rsp+0h] [rbp-18h]
for ( i = 0; (unsigned __int64)i < 0x12; ++i )
{
if ( *(_DWORD *)&aC[4 * i] != *(unsigned __int8 *)(a1 + i) )
return 0LL;
}
return 1LL;
}
for문을 살펴보면 aC[4 * i]와 a1[i]를 11바이트만큼 비교하여 같으면 1을 리턴합니다. aC의 데이터를 확인하기 위해 IDA에서 aC를 더블 클릭해서 확인해 보겠습니다.
.data:0000000140003000 aC db 'C',0 ; DATA XREF: sub_140001000+28↑o
.data:0000000140003002 align 4
.data:0000000140003004 aO db 'o',0
.data:0000000140003006 align 8
.data:0000000140003008 aM db 'm',0
.data:000000014000300A align 4
.data:000000014000300C aP db 'p',0
.data:000000014000300E align 10h
.data:0000000140003010 a4 db '4',0
.data:0000000140003012 align 4
.data:0000000140003014 aR db 'r',0
.data:0000000140003016 align 8
.data:0000000140003018 aE db 'e',0
.data:000000014000301A align 4
.data:000000014000301C db '_',0
.data:000000014000301E align 20h
.data:0000000140003020 aT db 't',0
.data:0000000140003022 align 4
.data:0000000140003024 db 'h',0
.data:0000000140003026 align 8
.data:0000000140003028 aE_0 db 'e',0
.data:000000014000302A align 4
.data:000000014000302C db '_',0
.data:000000014000302E align 10h
.data:0000000140003030 aA db 'a',0
.data:0000000140003032 align 4
.data:0000000140003034 aR_0 db 'r',0
.data:0000000140003036 align 8
.data:0000000140003038 aR_1 db 'r',0
.data:000000014000303A align 4
.data:000000014000303C a4_0 db '4',0
.data:000000014000303E align 20h
.data:0000000140003040 aY db 'y',0
.data:0000000140003042 align 10h
살펴보면 4 * i 위치에 데이터가 저장되어 있고 이를 다 연결한 값이 플래그입니다. 플래그는 Comp4re_the_arr4y 입니다.