드림핵 사이트의 워게임 rev-basic-3 문제 풀이 진행하겠습니다.
https://dreamhack.io/wargame/challenges/17/
문제 유형을 파악하기 위해 Windows의 PowerShell을 이용하여 프로그램을 실행시켜줍니다. 아래와 같이 임의의 문자열을 입력하면 'Wrong'이 출력됩니다.
이를 통해 오답 시 'Wrong', 정답 시 'Correct'가 출력됨을 예측할 수 있습니다.
위 main 함수를 디컴파일합니다. (단축키 F5)
int __cdecl 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((__int64)v4) )
puts("Correct");
else
puts("Wrong");
return 0;
}
sub_140001000 함수를 더블클릭하여 함수의 내용을 확인합니다.
__int64 __fastcall sub_140001000(__int64 a1)
{
int i; // [rsp+0h] [rbp-18h]
for ( i = 0; (unsigned __int64)i < 0x18; ++i )
{
if ( byte_140003000[i] != (i ^ *(unsigned __int8 *)(a1 + i)) + 2 * i )
return 0i64;
}
return 1i64;
}
우리가 구하고자 하는 배열은 a1이고 배열 byte_140003000은 주어졌습니다.
배열 byte_140003000를 더블클릭하여 메모리 주소를 확인한 후
Hex View에서 아래의 정보를 확인할 수 있습니다.
*16진수임을 유의합니다.
sub_140001000 함수를 읽어봅니다.
byte_140003000[i] == (i ^ a1[i]) + (2 * i)
가 모든 i에 대해 성립해야 합니다.
이 식을 a1을 기준으로 방정식을 풀듯 정리합니다.
XOR 연산에 대한 정보를 알면 쉽게 해결할 수 있습니다.
'A ^ B = C 라면 C ^ B = A 와 C ^ A = B 가 성립한다.'
a1[i] = i ^ (byte_140003000[i] - (2 * i))
이를 코드로 작성합니다.
nums = [0x49, 0x60, 0x67, 0x74, 0x63, 0x67, 0x42, 0x66, 0x80, 0x78, 0x69, 0x69, 0x7B, 0x99, 0x6D, 0x88, 0x68, 0x94, 0x9F, 0x8D, 0x4D, 0xA5, 0x9D, 0x45]
for i in range(len(nums)) :
tmp1 = nums[i] - (2 * i)
tmp2 = tmp1 ^ i
print(chr(tmp2), end = '')
위 코드로 출력된 문자열이 정답입니다.
I_am_X0_xo_Xor_eXcit1ng