본문 바로가기

Reversing/reversing.kr

reversing.kr 5번 Replace 문제 풀이. 해석

반응형

reversing.kr 5번 Replace 문제개요.

오늘은 reversing.kr 5번 문제를 풀어보고자 한다. 문제 이름은 Replace고, 바로 시작해보도록 하겠다.

 

 

Replace 개요

먼저 replace.exe 파일을 실행하면, Wrong이 출력된다. 임의의 숫자를 입력해서 Check 버튼을 클릭하면, 오류가

발생하면서 프로그램이 종료된다.  어떤 것 때문에 오류가 발생하고, 어떻게 문제를 해결해야 할지 천천히 알아보도록

하자.

 

 

Replace 문제해결 1

먼저 간단하게 PE분석 먼저 진행해보자. Replace.exe를 보면, C++로 개발되어 있고 패킹이 되어있지 않다. 각설하고 바로 리버싱을 시작해보자.

 

 

Replace 문제해결 2

먼저 x32dbg에 Replace.exe를 붙이고 디버거에서 실행을 해서, 임의의 숫자를 입력하면 40466F 주소로 온다.

이때, eax에 0x90의 값을 저장한다. 0x90은 NOP을 의미한다. 하지만 여기서 오류가 발생하는 것을 보면 저장을 할 때 문제가 발생한다는 것을 알 수 있다. 

 

 

Replace 문제해결 3

위 사진을 보면, EAX에 6016A9D가 저장되어 있고, 해당 주소는 접근이 불가능한 상태이다. 따라서 접근이 불가능한

주소에 0x90을 저장하려고 시도해서 오류가 발생하는 것이다. 

 

 

Replace 문제해결 4

먼저 이 프로그램에서 어떤 함수들이 사용되는지 알아야 한다. Ctrl + N을 눌러서 사용되는 함수 목록을 확인해보자.

보면 'GetDigItemInt'라는 함수가 있다. 이 함수는 컨트롤에 입력되는 문자열에서 정수형 데이터를 얻어오는 함수이다.

그리고 4050A8에서 사용되는 DialogBoxParamA 있다. 이 함수에서 생성된 입력창에서 얻은 문자열을 GetDigltemInt에서 정수로 바꿔서 받아온다는 뜻이다.

 

 

Replace 문제해결 5

먼저 GetDlgItemInt가 사용되는 주소에 브레이크 포인트를 걸고 실행해보자.

 

 

Replace 문제해결 6
Replace 문제해결 7

임의의 값 '12345'를 입력하고 나면 브레이크 포인트에서 멈추고,  16진수로 바꾼 값 0x3039를 eax에 저장한다.

 

 

 

Replace 문제해결 8

이후 입력 값 '12345'를 16진수 0x3039로 변경한 내용을 4084D0 주소에 저장을 한다. 

다음 401065에서 처음의 오류가 발생했던 함수를 호출한다. 호출 과정을 살펴보기 위해 F7을 통해 함수 내부를 살펴보자.

 

 

Replace 문제해결 9

40466 주소의 내부를 오자마자 다시 40467A를 호출하는 모습을 보인다. 다시 F7을 눌러서 40467A의 내부를 살펴보자.

 

 

Replace 문제해결 10

40467A의 내부를 보니 406016 주소에 619060EB 값을 저장하고, 404689를 호출한다. 이때 404689는 inc로 4084D0 내부의 저장된 값 '0x3039'를 1 증가시킨 후 다시 저장하는 기능을 한다. 따라서 404684에서 1을 증가시키고, 404689에서 1을 또 증가시켜서, 총 2가 증가되어 '0x303B'가 4084D0에 저장된다.

 

 

Replace 문제해결 11

Replace 문제 해결 10에서 모든 일이 끝나고, return 되면서 404674로 도착하게 된다. 

404674에서는 4084D0 주소에 60165C7을 저장한다. 즉, 원래 저장되어 있던 값 '0x303B'에 '60165C7'을 더해서 '6019602'가 사용자 값이 위치한 주소가 된다.

 

이후 404684에서 404689를 호출한다. 호출된 함수는 방금 전 INC로 4084D0에 저장된 값에 2를 더하는 함수였기에 '60165C7' + '2'를 해서 '60165C9'가 저장된다.

 

 

Replace 문제해결 12

함수가 종료되면서 return이 되는데 아까와 다르게 40106A 주소로 리턴된다. 이후 eax 값을 초기화하고 404690으로

점프(분기)가 된다.

 

 

Replace 문제해결 13

 404690 주소에서는 4084D0의 값을 DWORD 크기만큼 eax에 저장한다. 이후 404689를 호출하여 INC를 통해 2를 더해서 '60165CA'로 만들어 4084D0에 저장한다. 

 

이후 40466F에 '0x39000C6'값을 넣은 후 40466F를 호출한다.

 

 

Replace 문제해결 14

호출된 주소는 처음의 오류가 발생했던 지점이다. 40466F에서 발생하는 오류는 결국 eax에 정상적인 주소가 들어가지 못하였기에 생긴 오류이다. 따라서 정상적으로 작동을 한다면, eax에 nop이 들어갈 것이다.

 

 

Replace 문제해결 15

오류가 발생한 이후, 스택 상태를 확인하였다. 스택 상태를 보니, 404672에서 return이 될 때 리턴할 주소는

4046AE주소였다.

 

 

Replace 문제해결 16

4046AE주소를 확인해보니 정상적인 주소로 리턴이 되었을 때 eax는 1만큼 증가되어 저장되었을 것이다.

이후 40466F 주소를 호출해서 NOP을 저장하는 코드로 도착하고, NOP을 입력 후 4046B4 주소로 return 하게 된다.

 

그다음, 4046BE 주소에서 POP eax가 실행되어 '문제 해결 15번' 사진에 남아있던  return 주소인 40469F 주소가 정리되고 4046C4 주소의 점프문을 통해 401071 주소로 분기될 것이다.

 

Replace 문제해결 17

분기되면, Correct문이 출력된다.

 

 

결론적으로 401071 주소의 코드를 우회하면 문제를 해결할 수 있다. 따라서 401071 주소 코드가 "EB 11"  2byte 크기의 코드인 것과 0x90(NOP)이 두 번 저장된 것을 통해  0x90 코드가 401071, 401072 주소에 입력되면 분기문 코드가 덮어져서 "Correct!"가  출력될 것이라고 생각했다.

 

Replace 문제해결 18

따라서 주소에 90을 덮어준 후, 입력창에 FFFFFFFF - 601605CB(601605C7  + INC + INC + INC + INC) + 401071의 값인 268710978을 입력하면 "Correct!"가 출력된다.

 

 

Replace 문제해결 19

 

728x90