Reversing.kr Replace

Reversing/리버싱 문제풀이

2015. 10. 6. 18:51



실행을 시키고 입력을 하면 이렇게 문제가 발생해서 종료된다.


올리디버거로 실행시켜보니 40466F에서 접근할 수 없는 메모리에 90이라는 데이터를 써서 예외가 발생하는 것을 알 수 있다.

따라서 이 부분을 해결해야 한다고 생각하고 이제 입력하는 숫자를 기준으로 어떻게 프로그램이 진행 되는지 알아 보았다.


위 함수는 입력한 숫자를 받는 함수이다. 이 함수에 브레이크를 걸었다.


브레이크를 걸고 진행을 하면 위 그림과 같이 40105A에서 멈춘다.


위 과정을 간략히 설명하자면 아래와 같다. 

1. [4084D0]에 EAX저장 (입력한 값)


2. 40466F 함수 호출 


40466F 함수안에서는 

[4084D0] 1증가 -> [4084D0] 1증가 -> [4084D0] 601605C7증가 -> [4084D0] 1증가 -> [4084D0] 1증가 


위 과정이 차례대로 발생한다 .


즉 내가 입력한 숫자에서  (0x601605C7 + 4) 만큼 더해지는 것이다.


3. EAX 0으로 초기화


4. 404690으로 분기





404690으로 이동하면 위와 같은 명령어들이 있다.

이것도 중요한 부분을 간략히 말하면 


1. [4084D0]값을 eax에 넣음


2. 404689함수호출

[4084D0] 1 증가 (필요 x  이미 eax에 값을넣었음)


3. [40466F]에 특정 명령어 덮어씀

이 명령어는 아까 예외를 발생시킨 부분으로 

EAX의 값 1바이트를 0x90(NOP) 으로 덮어쓰는 역할


4. 40466F 호출


5. EAX + 1


6. 40466F 호출


7. 401071로 분기



이 부분으로 다시 오는데 바로 아래 401073 ~ 40107E 까지가 Success!를 출력해주는 명령어이다.

근데 401071에서 JMP를 하기 때문에 지금 이상태로는 절대로 Success!를 출력할 수가 없다.


하지만 생각을 해보면 401071의 OPCODE가 2바이트이고, 

아까 위에서 40466F함수를 두번 호출할 때 EAX의 연속적인 2바이트를 NOP으로 바꿀수 있었다.


따라서 401071 ~ 72의 값이 NOP이 되면 JMP가 없어지며 Success!가 출력되게 할 수 있다.


401071이 NOP이 되려면 

MOV EAX, DWORD [4084D0]

이 명령어가 실행될 때의 [4084D0]가 401071이 되어야 한다.


아까 위에서 계산한 식을 이용하면

x + 601605C7 + 4 = 401071

이러한 식을 세울 수 있다.




계산을 하면 위와 같이 값이 음수이다.

하지만 입력한 값을 대입 할때는 DWORD만큼 사용을 하기 때문에

FFFFFFFF는 필요 없이 A02A 0AA6만 필요하다.

이 값을 10진수로 바꾸면 끝 !