Dreamhack 문제 풀이 - rev-basic-5

 

디버깅을 해보면, 연속하는 두개의 입력값의 합이 메모리에 저장된 문자와 일치하는지를 확인하는 코드이다

 

예를 들어서 입력값으로 문자열 abcdef...를 집어넣으면,

 -> a+b 즉 0x61 + 0x62가 0xAD 인지 확인 (다르면 종료)

 -> b+c 즉 0x62 + 0x63이 0xD8 인지 확인 (다르면 종료)

 -> c+d 즉 0x63 + 0x64가 0xCB 인지 확인. (다르면 종료)

 -> 계속 반복된다

 

<비교 값>

00007FF7809E3000  AD D8 CB CB 9D 97 CB C4 92 A1 D2 D7 D2 D6 A8 A5  .ØËË..ËÄ.¡Ò×ÒÖ¨¥  
00007FF7809E3010  DC C7 AD A3 A1 98 4C 00 00 00 00 00 00 00 00 00  ÜÇ.£¡.L.........  

 

 

그렇다면 다음 입력값이 없는 마지막 루프에는 어떻게 될지를 확인하기 위하여 입력값으로 "abcdefghijklmnopqrstuvw" (0x18 바이트)를 넣어보자. 그리고 반복문의 중단 없이 마지막을 보기 위해 분기하는 je문을 jmp로 바꾸어준다.

 

이렇게 고치고 루프를 돌려보면 마지막 루프에서 w다음에 입력값이 없으므로 그냥 w만 가지고 메모리의 값과 비교를 하게 된다

 

다시 설명하자면, 입력값의 연속 두 글자와 메모리에 저장된 값을 비교해야 하나,

 

입력값의 마지막 문자 (여기서는 w) 다음에는 0밖에 없으므로 결국 w가 메모리에 저장되어 있는 마지막 글자인 4C와 일치하는지 비교를 하게 된다. 다시말해 마지막 입력값 w는 4C가 되어야 한다는 뜻이다.

 

 

00007FF7809E3000  AD D8 CB CB 9D 97 CB C4 92 A1 D2 D7 D2 D6 A8 A5  .ØËË..ËÄ.¡Ò×ÒÖ¨¥  
00007FF7809E3010  DC C7 AD A3 A1 98 4C

 

 

이제 마지막 값을 알았으니 단순 계산으로 풀기만 하면 된다.

편의를 위하여 입력값을 "abcdefghijklmnopqrstuvw"로 지칭하겠다.

 

 

위에서 w = 4C라는 사실을 알았다. 

그렇다면 v+w가 그 이전 값인 98이 되어야 하므로 v = 98-w = 98-4C = 4C가 된다

그렇다면 u+v가 그 이전 값인 A1이 되어야 하므로 u = A1-v = A1-4C = 55가 된다.

그렇다면 t+u가 그 이전....

 

 

반복 계산을 파이썬으로 풀면 다음과 같다.

(지면을 아끼기 위하여 결과를 깔끔히 보여주는 코드만 첨부함)

s = "AD D8 CB CB 9D 97 CB C4 92 A1 D2 D7 D2 D6 A8 A5 DC C7 AD A3 A1 98 4C 00".split(" ")
s_int = [ int(a, 16) for a in s]
s_int.reverse()

w = int("4C", 16)
answer = "L"

for i in range(2, len(s_int)):
    w = s_int[i]-w
    answer += chr(w)
print(answer[::-1])

출력 결과

All_l1fe_3nds_w1th_NULL

 

 

댓글

Designed by JB FACTORY