본문 바로가기

리버싱 개인 공부/[리버싱핵심원리]

[리버싱핵심원리] abex' crackme

우선 코드 파악을 위해 Ollydbg에서 코드를 실행해 보았더니 순서대로 창이 뜹니다.

 

Ollydbg 에서 파일의 디스어셈 코드를 살펴보겠습니다.

Entry Point에 main함수가 바로 나타나는 것을 보면 어셈블리 언어로 개발되었다는 것을 알 수 있습니다.

 

본격적으로 코드를 분석하기 전에 기본적인 명령어를 정리해봤습니다.

명령어 설명
PUSH 스택에 값을 입력
CALL 지정된 주소의 함수를 호출
INC 값을 1 증가
DEC 값을 1 감소
JMP 지정된 주소로 점프
CMP 주어진 두개의 operand 비교
JE 조건 분기(Jump if equal)

 

<abex ' crackme 실습>

우선, 디버깅을 시작하기 전에 파일을 실행시켜서 어떤 프로그램인지 살펴봅니다.

첫 번째 팝업 창에서 리버서(사용자)가 무엇을 해야할지 알려주고 있습니다.

, 이번 실습의 목적은 프로그램을 실행했을 때 HD(하드디스크)CD롬으로 인식되도록 변경하는 것입니다. 문제를 해결하는 방법은 다양하지만 저는 프로그램 코드를 변경해서 문제를 해결해봤습니다.

 

Ollydbg에서 파일을 열어서 디스어셈 코드를 살펴보겠습니다.

0041044를 보면 저희가 원하는 메시지 박스 텍스트도 보입니다.(Ok, I really think that your HD is a CD-ROM! :p")

 

EP코드가 매우 짧은 걸 볼 수 있는데, 이를 통해서 abex crackme 파일이 어셈블리 언어로 만들어진 실행 파일이라는 것을 알 수 있습니다. 개발툴을 사용하지 않고 어셈블리 언어로 작성하면 어셈 코드가 곧 디스어셈 코드가 되기 때문입니다.

(개발툴을 사용하면 자신이 작성한 소스코드 외에 컴파일러가 Stub Code를 추가 시키기 때문에 디스어셈을 하면 복잡하게 보임)

*Stub code(스텁 코드)는 프로그램의 소스 코드에서 자동으로 추가되는 작은 코드 조각을 의미합니다. 이러한 스텁 코드는 일반적으로 컴파일러나 개발 도구에 의해 자동으로 생성되며, 주로 소스 코드의 다른 부분과의 인터페이스를 관리하거나, 외부 라이브러리나 함수와의 상호 작용을 도와줍니다.

 

F8(Step Over)로 하나씩 넘기다보면 아까 실행시켰을 때 봤던 처음 메시지 화면이 실행됩니다. 계속 F8넘어가다 보면,,

 

00401036주소에서 두 번 째 메시지가 실행됩니다. 즉 이 두개의 코드 사이를 조작하면 저희가 원하는 결과 메시지 창을 얻을 수 있다는 것을 알 수 있습니다.

 

0041024 주소의 줄을 보면 CMP EAX, ESI라고 써져있습니다.

CMP EAX, ESI 는 EAX와 ESI를 비교(CMP)하여 같으면(제로플래그 = 1) 0040103D로 넘어가고,

다르면 그냥 밑 명령어 (JE SHORT 0040103D) 를 실행시키라는 뜻입니다.

JE는 피연산자들의 값이 같으면(제로플래그 = 1이면) 점프하라고 하는 일종의 조건문입니다.

 

GetDriveTypeA() 함수 실행이 끝난 상태에서 레지스터 정보를 살펴보면 EAX 레지스터에는 3저장되어있고, ESI 레지스터에는 0이 저장되어 있습니다.

레지스터를 변경하는 명령어를 보면 ESI 레지스터는 모두 3만큼 증가시키고. EAX 레지스터는 2만큼 감소시킵니다.

ESI 레지스터를 증가시키는 명령어 2(40101E, 40101F줄에 있는 INC ESI) 2개를 실행하지 않으면 EAXESI 값이 동일해집니다.

 

0040101DJMP 명령어를 아래 두 줄 INC ESIDEC EAX 가 실행되지 않게 수정하면 문제를 해결할 수 있습니다.

 

INC ESIDEC EAX 명령어가 실행되지 않게 하려면 JMP SHORT 00401021 명령어를 JMP SHORT 00401023로 바꾸면 됩니다.

 

코드 수정을 완료하고 F8(스텝 오버)를 눌러서 EAX값과 ESI 값이 1이 되므로 제로 플래그가 둘 다 1이되어서 저희가 원하는 메시지 창을 띄울 수 있습니다.

결과를 확인해 보면 “Ok, I really think that Your HD is a CD-ROM! :p” 라는 메시지를 출력하는 창을 볼 수 있습니다.

여기서 주의할 점은 프로그램 실행 위치가 변경하고자 하는 코드 위에 있어야 한다는 것입니다. 그래야만 코드 변경 후 실행해서 동작을 확인할 수 있습니다.