2014. 1. 23. 15:45 :: 리버싱

드디어 처음으로 하는 실습입니다ㅎㅎ

제목처럼 해당 파일을 크랙해보라고 도발(?)하는 이름이네요...

크랙미는 크랙 연습을 목적으로 작성되어 공개된 프로그램입니다. 그리고 매우 간단해서 초보자에게 알맞습니다. (저같은..)

그럼 이제 그 도발에 넘어가서 크랙을 해보도록 하겠습니다.

 

 

1. abex' crackme #1

 

   크랙을 하기전에 디버깅을 하기전에 어떤 프로그램인지 알아보록하겠습니다.

 

위 사진이 실행되며 확인 버튼을 눌러보면 아래와 같은 문구가 나옵니다.

 

에러메시지가 뜨네요. 저희가 크랙해야될 내용이 보입니다. HD(하드디스크)가 CD-ROM으로 인식되게 하면 되겠네요.

디버깅을 해보도록 하겠습니다.

 

실행시켜보니 이제까지 디버깅해왔던 HelloWorld.exe와는 코드길이 엄청나게 차이가 나네요. 이유는 지금 하고있는 abex crackme는 어셈블리언어로 만들어진파일이라 코드 길이가 짧습니다. HelloWorld는 C언어등의 언어로 작성된것을 어셈블리로 변환된것이라 긴것입니다.(잘안보이시면 사진을 클릭하여 크게 보세요~)

 

 

본론으로 돌아와서 코드분석을 해보겠습니다. (아래 사진 잘 안보이시면 클릭하여 크게 보세요~)

위 사진처럼 분석해보았습니다.

 

 

참고. abex' crackme #1에서 사용된 어셈블리 명령어 

 명령어

 설명 

PUSH 

스택에 값을 입력 

CALL 

지정된 주소의 함수를 호출 

INC 

값을 1 증가 

DEC 

값을 1 감소 

JMP 

지정된 주소로 점프 

CMP 

주어진 두 개의 값을 비교

(SUB 명령어와 동일하나 값이 변경되지 않고 EFLAGS 레지스터만 변경됨,

두 값이 동일하다면 SUB 결과는 0이고 ZF = 1 로 세팅됨) 

JE 

조건 분기(Jump if Equal)

(ZF = 1 이면 점프) 

 

 

2. 크랙

 

   이제 코드를 패치해서 크랙을 해보도록 하겠습니다. 위에서 말씀드렸듯이 HD를 CD-ROM으로 인식하게 하면 되겠네요.

 

 

위 조건분기 코드를 보시면 CMP EAX, ESI를 비교를 먼저 합니다. 그 다음 JE 명령어에서 위에서 비교된 결과값을 가지고 해당 주소 40103D로 점프하라고 되어있습니다.(명령어의 설명을 위쪽 크랙미1에서 사용된 어셈블리 명령어 표를 보시면 됩니다.)

 

코드분석을 해놓은 그림을 보시면 아시겠지만 EAX, ESI는 같지 않습니다. 그러므로 CMP에서도 불일치하다는 결과값을 출력하기 때문에 JE명령어에서 일치할때 점프하라고 되어있는 주소로 점프하지 못하고 바로 다음줄로 이동하게 됩니다.

 

바로 다음줄은 조건 불일치 시 라고 명시를 해둔 곳인데 결과적으로 HD를 CD-ROM으로 인식하지 못했다는 메시지박스를 출력하게 되는겁니다.

 

저희는 이제 조건분기 부분에서 JE명령어 부분을 크랙해서 CMP에서 비교한 값이 어느값이 나오든지 바로 HD를 CD-ROM으로 인식했다는 결과가 출력되도록 해보겠습니다.

 

"JE SHOR 0040103D" 라는 명령어를 "JMP SHORT 0040103D"로 바꾸시면 되겠습니다. 바꾸시는 방법은 JE명령어 코드를 선택하시고 [Space]버튼 또는 더블클릭해서 바꾸시면 되겠습니다. 그다음 바뀐 프로그램을 새롭게 저장해야되는데요. 먼저 코드를 바꾸신 다음에 작은 팝업창을 닫으시고(JE명령어 코드만 바꾸세요...) 아무코드에서나 마우스 우클릭후에 'Copy to executable' 메뉴에서 'All modifications' 선택하세요. 그 다음 'Copy all'을 누르시면 새로운 코드파일이 생성됩니다. 거기서 마우스 우클릭 후에 'save file'를 선택하여 새롭게 저장하시고 생성되는 exe 프로그램을 실해보시면 HD를 CD-ROM으로 인식했다는 메시지박스를 보실수 있을것입니다.

 

JE 명령어 코드를 바꾸는것 이외에도 다른 부분을 패치해서 하는 방법도 있습니다. 참고하시면 되겠습니다.

 

 

3. 스택에 변수를 전달하는 방법

 

   크랙미#1을 마무리하면서 스택에 변수를 전달하는 방법에 대해 알아보고 마무리하겠습니다.

 

 

1번에서 크랙미#1 코드분석을 보시면 MessageBoxA() 함수가 3개 나옵니다. 그리고 바로 위 코드를 보시면 MessageBoxA() 함수가 실행되기전에 4번의 PUSH 명령어를 사용하여 필요한 변수를 역순으로 입력하고 있습니다.

 

위 코드를 C언어로 변형하면

[ MessageBox(NULL, "Make me think your HD is a CD-ROM.", "abex' 1st crackme", MB_OK:MB_APPLMODAL); ]

이렇게 됩니다. C언어에서는 함수에 넘기는 변수의 순서가 어셈블리 언어에서는 역순으로 넘어가는 것을 알고계세요. 이유는 스택은 FILO(First In Last Out) 구조이기 때문입니다.

 

디버거를 EIP=0040100E 시점까지 f4 키를 통해 진행한 다음 해당 스택을 보시면 위 사진처럼 보실수 있습니다.

예전에 공부했던 스택부분으로 기억하시면서 보시면 거꾸로 저장되는것을 확인할수 있습니다. 그렇게 저장을 다하고 맨마지막에 MessageBoxA()가 실행되면서 스택에 있는 변수를 꺼내게 되는데 스택의 구조는 FILO, LIFO(Last In First Out)으로 마지막에 들어간것이 처음으로 나오게 되면서 MessageBoxA()입장에서는 변수들이 순서대로 꺼내는 입장이 되게 됩니다.

 

 

이상으로 크랙미#1에 대한 공부를 마치도록 하겠습니다. 이처럼 크랙에 대해 자세히 분석해보았고 실제 실습을 해보면서 공부하며 핵심 원리를 파악하시고 많이 연습하시면 좋을거 같습니다.

 

참고서적 : 리버싱 핵심 원리 / 저자 : 이승원

 

 

':: 리버싱' 카테고리의 다른 글

[정보 보안 개론] Chapter 06 악성코드  (0) 2016.11.07
Red_Seek :: 스택 프레임  (0) 2014.01.29
[Red_Seek] 스택  (0) 2014.01.22
[Red_Seek] IA-32 Register  (0) 2014.01.14
[Red_Seek] 엔디언 표기법  (0) 2014.01.09
posted by Red_Seek