Replace

Patching the compare instruction so any input is accepted, which reveals the stored password.

2026.08.18 Reversing original post

프로그램을 키고 확인해보면, 입력을 받고 Check 버튼을 누르면 맞는지 아닌지를 확인을 하는 프로그램인걸 알 수 있습니 다. 이러한 방식에 문제는 그 패스워드가 플래그 일것이라는걸 암시합니다. 일단 메인 함수와 문자열 찾기 방법을 통해 메 인 코드에 진입합니다.

Figure 1

처음에는 00401071의 점프문을 무조건적으로 참으로 만들어서 correct 문구를 띄어봅니다. 하지만, 그 방식으로는 플래 그를 알아낼수없다는걸 깨닫을수있습니다. 프로그램을 일단 실행시켜보고, 12345 를 넣습니다. 실행을 시켜보면 다음과 같이 eax 값을 004084d0에 저장하는데 이 값은 16진수로 3039입니다.

eax = 0x004084d0 = 0x3039

Figure 2

그 후 해당 함수로 이동하고 (40466F), 그곳에서 4084D0의 값을 두 번 증가시킵니다.

eax = 0x3039(12345) / 0x004084d0 = 0x3039+2 = 0x303B

계속 실행을 시켜보면 해당 부분에서 또 연산이 있습니다 (ret 때문에). eax는 1 증가시키고 004084d0의 값은 601605c7만큼 증가시킵니다.

eax = 0x3039 + 1 = 0x303a / 0x004084d0 = 0x3039 + 2 + 0x601605c7 =

또 순서대로 해당 부분을 다시 거치면서 다시 한번 4084D0의 값을 증가시킵니다.

eax = 0x303a, 0x004084d0 / 0x3039 + 2 + 0x601605c7 + 1

Figure 3

이후 eax 값을 초기화하고 404690으로 점프(분기)가 된다.

Figure 4

404690 주소에서는 4084D0의 값을 DWORD 크기만큼 eax에 저장한다 (60163604 임). 이후 404689를 호출하여 INC를 통해 2를 더해서 ‘60165CA’로 만들어 4084D0에 저장한다. 호출된 주소는 처음의 오류가 발생했던 지점이다. 40466F에서 발생하는 오류는 결국 eax에 정상적인 주소가 들어가지 못하였기에 생긴 오류이다. 따라서 정상적으로 작동 을 한다면, eax에 nop이 들어갈 것이다.

Figure 5

오류가 발생한 이후, 스택 상태를 확인하였다. 스택 상태를 보니, 404672에서 return이 될 때 리턴할 주소는 4046AE주 소였다. 4046AE 주소로 정상적으로 복귀했을 경우, 해당 위치 이후의 코드가 실행되면서 eax 값이 1만큼 증가하게 된 다.

이후 다시 40466F 주소를 호출하게 되는데, 이 부분은 eax에 들어 있는 값을 주소처럼 사용하여 특정 값을 메모리에 저장 하는 루틴으로 보인다. 앞서 발생했던 오류의 원인은 eax에 정상적인 주소가 들어가지 못한 상태에서 해당 루틴이 실행되 었기 때문이며, 정상적으로 동작하는 경우 eax에는 유효한 주소가 들어가게 된다. 이때 해당 주소에 NOP(0x90)이 저장 되도록 설계된 것으로 보이며, 이러한 NOP 저장이 정상적으로 수행되면 함수는 ret을 통해 다시 호출 지점으로 복귀하게 된다.

이후 실행 흐름을 따라가다 보면 4046BE 주소에서 pop eax 명령이 실행되는 것을 확인할 수 있는데, 이 명령은 eax 값을 사용하기 위한 목적이라기보다는 스택에 남아 있는 값을 정리하기 위한 용도로 사용된 것으로 보인다. 실제로 스택을 확인 해보면 이전 단계에서 남아 있던 40469F 주소가 스택에 존재하고 있었고, 이 값이 pop eax를 통해 제거되면서 스택 상태 가 정상화된다. 스택 정리가 완료된 이후에는 4046C4 주소에 위치한 점프문을 통해 실행 흐름이 401071 주소로 분기된다. 이 401071 주소는 처음에 강제로 분기시켜 Correct 문구를 출력했던 위치로, 정상적인 조건을 만족했을 경우에만 도달할 수 있는 루 틴이다.

즉, 앞선 연산과 스택 정리 과정이 모두 정상적으로 수행되었을 때에만 최종적으로 Correct가 출력되는 구조임을 알 수 있 다.

내부 연산 과정을 추적해보면 입력값에 2를 더하고, 0x601605C7을 더한 뒤 다시 1과 1을 더하는 과정을 거치며, 이 최 종 결과가 0x00401071이 되어야만 분기 조건을 만족하게 된다. 이거 밑에 처럼 표현되는데:

x + 2 + 0x601605C7 + 1 + 1 = 0x00401071 -->

x = 0xA02A0AA6 —> 10진수로 변환 —> 2687109798

실제로 해당 값을 입력하면 Correct 문구가 출력되는 것을 확인할 수 있었고, 결과적으로 이 값이 플래그다

Figure 6