GDB를 이용한 ELF파일 리버싱

ELF 파일을 리버싱할 일이 생겨 ida pro로 분석하려 했다가 remote debugger 설정하는게 갑자기 귀찮아졌다. 

가상머신에 파일을 옮기고 막 바꿔주고 해야 하는데 ㅋㅋ 그게 생각보다 귀찮아서 그냥 gdb로 리버싱해보면

어떨까 하는 생각이 들었다.


리눅스는 기본적으로 유닉스에서 파생되어 왔기때문에 유닉스 환경의 CPU인 AT&T계열의 어셈블리어가 gdb의 기본 언어로 설정되어 있다. 현재 사용되는 PC의 CPU로 사용되는 어셈블리어는 INTEL과 AT&T가 주로 사용되는데 아래 표에서 그 차이가 표시해두었다. 가장 큰 차이라고 볼 수 있는 것이 operand의 위치이다. 

예를 들어 범용레지스터 ebx의 저장된 값을 eax로 옮겨라는 명령을 내리고 싶을 때

Intel에서는 mov eax, ebx이고

AT&T에서는 movl ebx, eax이다.

그리고 나머지 약간의 표기법의 차이도 아래 그림과 같이 존재한다.

아까전에도 말했듯이 gdb의 기본 언어가 AT&T계열이라고 설명하였다. 많은 사용자를 가진 window는 intel계열이고 우리는 window의 PE파일을 리버싱할 기회가 많을텐데, 약간의 차이가 있는 AT&T를 보면 헷갈릴 수 있다. 그러므로 set disassembly-flavor intel 이라는 명령어로 AT&T계열의 어셈블리어를 INTEL로 바꿀 수 있다. 아래 그림을 참고 하면 AT&T에서 INTEL로 어셈블리어가 바뀐 것을 볼 수 있다.

기본적으로 gdb를 사용할 때 봐야 하는 부분은 아래와 같다. B(break)break 포인트 걸기, R(run)으로 실행시켜 b로 설정한 부분으로 가서 그 부분 확인하기, disas(disassem)으로 해당 함수 어셈블리어 보기, I(info)명령을 통해 현재 프로그램의 상태( 레지스터, 스택 등) 보기가 있다

그리고 현재 특정 주소의 메모리의 값을 알기 위해서 아래와 같이 x/(숫자)(영문자)를 이용한다. 예를 들어 아래 명령은 0x8048510부터 6word(4Byte)에 저장된 값을 본다는 것을 의미한다

그 다음으로는 nisi이다. ninext, sistep의 의미를 각각 가지며 둘 다 하나의 명령어를 실행시킨다. 함수를 호출하는 명령어가 있다면 ni는 그 함수를 실행하고 나온 리턴값을 받아 그 다음 명령어를 가리키고, si는 그 함수 내부로 들어가서 첫 명령어를 가리킨다.

추가적으로 몇 개의 명령어를 더 사용해서 리버싱을 진행하였는데 ignoreset 명령어 이다. 8번 도는 for문에 b를 이용하여 break point를 설정하였을 때 ignore (bp 번호) (횟수)를 통해 루프를 (횟수)만큼 무시한다. 그리고 set 명령어는 특정 메모리의 주소 값을 바꿔서 내가 원하는 명령어주소로 갈 때 사용할 수 있다. set {int}0x7fffffffe34c = 8처럼 사용한다.

아래 그림을 참조하여 ignore 명령어의 사용법을 알아보도록 하겠다.

빨간색 박스로 표시되어 있는 부분을 보면 rbp-0x44부분에 0x1을 더하면서 이 부분이 0x7인지를 비교해서 작거나 같으면 main+146으로 점프하는 부분이다. 현재 rbp-0x44에 저장된 값은 2이다

그래서 main+146으로 점프하는 부분인 main+188에 break point를 걸었다. 아래 그림의 첫부분은 i b 명령어를 이용하여 현재 설정된 break point를 보는 부분이다. 이미 이 break point를 세번 hit했다고 한다.  

ignore 1 4를 통해 1번 break point가 가리키는 명령어가 실행될 때 4번 무시한다는 말이다. 그래서 s를 통해 계속 진행을 한 후에 rbp-0x44의 저장된 값을 보면 1씩 4번 증가하여 값이 7이 되어 있는 것을 알 수 있다. 그림에는 안나왔지만 테스트를 하면서 기존의 rbp-0x44부분이 3이엇다.

아래 그림은 set 명령어를 이용하여 특정 메모리에 값을 설정하는 부분이다. 위에서 ignore를 하지 않고 set 명령어를 이용했으면 점프부분을 간단하게 우회를 할 수도 있지만, 점프를 하기전까지 실행되는 루프가 모두 실행되지 않으므로 기존 프로그램이 가지는 상태와 다르게 될 수도 있다. 그러므로 set을 사용할 때는 충분한 고려가 필요하다고 생각한다.

 


이쯤하면 gdb에서 리버싱할 때 필요한 부분들을 봤고 추가적으로 알고 싶은 부분은 아래 링크를 참조하면 되겠다잘 설명되어 있다.


참고 

http://korea.gnu.org/manual/release/gdb/gdb.html#SEC92

https://kldp.org/node/71806

http://korea.gnu.org/manual/release/gdb/gdb.html#SEC47






'시스템 > 리버싱' 카테고리의 다른 글

gdb로 elf 리버싱  (0) 2014.06.27
리버싱 바이블 정리[1]  (0) 2014.05.28
심플스 crackme 9번 문제  (0) 2013.10.15
Reversing.kr - Easy Keygen  (1) 2013.09.02
심플스 CrackMe01 풀기  (2) 2012.01.03
Ollydbg 설정 프로그램 Olly_ini_editor  (0) 2012.01.03
ollydbg 설치 및 기본 설정  (3) 2011.12.23



※ 본 내용은 필자가 리버싱바이블을 정리하여 내용적인 측면에서 다소 차이가 있을 수 있습니다.

또한 문제가 되면 바로 삭제하도록 하겠습니다.

리버싱 바이블 정리

kcats

들어가기에 앞서

나는 어떤 책을 볼 때 항상 먼저 목차를 본다. 당연히 이유가 있지. 그 책을 쓴 작가는 독자들이 이해하기 쉽도록 내용을 배치하려고 생각했을 것이다. 처음부터 생뚱맞게 어려운 내용을 넣지 않았을 것이란 말이다. 그러므로 이 책의 목차를 보고 어떤 개념들이 나오고 우리가 어느 부분을 공부하는 지들 대략적으로 감을 잡아가면서 가도록 하자. 




[01부] 리버스 엔지니어링 기본

        1. 리버스 엔지니어링만을 위한 어셈블리

        2. C문법과 디스어셈블링

        3. C++ 클래스와 리버스 엔지니어링

        4. DLL 분석

[02부] 리버스 엔지니어링 중급

        5. PE헤더

        6. 흔히 사용하는 패턴

        7. MFC 리버싱

[03부] 연산 루틴 리버싱

        8. 시리얼 추출 방법

        9. 코드 속이기

[04부] 안티 리버스 엔지니어링

        10. 교과서적인 안티 디버깅

        11. 한 단계 높은 안티 디버깅

        12. 패커가 사용하는 기술

        13. 우회 방법

[05부] OllyDBG 플러그인

        14. OllyDBG 플러그인 SDK

        15. 리버싱 보조 플러그인

        16. 메모리 스캔 플러그인 개발

[06부] 보안 모듈 우회

        17. 바이러스 감지 회피

        18. 백신을 공격하는 악성코드

        19. 실시간 감시 기능 취약점

        20. 키보드 보안 솔루션 우회

[07부] 한 차원 높은 바이너리 창조

        21. 코드 후킹

        22. 코드 패칭

        23. 난독화와 더미코드

 

어셈블리의 기본구조

냉장고에서 물을 꺼내 마시는 것을 가정

C/C++의 경우

void 물마심()

{

        BOOL bOpen = 냉장고문오픈();

        if(bOpen)

        {

                물을꺼냄();

                마심();

        }

}


어셈블리의 경우

__asm{

        냉장고앞으로간다.

        냉장고문을잡는다.

        냉장고문을연다.

   오픈성공:

        냉장고안을본다

        손을든다

        냉장고안에넣는다.

        물병을잡는다

        물병을꺼낸다.

뚜껑을연다.

물을컵에따른다.

컵을손에든다.

컵에든것을마신다.

}


여기서 C/C++과 어셈블리의 가장 결정적인 차이는 한 번의 동작에 몇 가지 액션을 할 수 있느냐이다. 어셈블리가 단순하다는 맹점 때문에 세세하게 다 지정해야한다.

그러므로 코드 한 두 줄만 봐서는 해당 프로시저가 무슨 목적으로 만들어졌는지 알 수 없다. 즉, 전체적인 흐름을 봐야한다.


어셈블리의 기본포맷

요즘 어셈블리를 배우는 것이 x86 CPU의 기본 구조은 IA-32를 익힌다는 것과 동일한 표현이다. AMD의 경우 intel Processor와 호환이 되기 때문이다.

IA-32의 기본 형태는 매우 단순하다. 한 줄을 ᄍᆞᆯ 때 단지 하나 또는 두 개의 코드가 있을뿐이다.

“명령어 + 인자”의 형식이 되며 명령어 + 인자 1 or 인자 2개가 된다. 여기서 중요한 것은 뒤에 있는 인자가 soucre이고 앞에 있는 인자가 destination이다. 밑에 mov 명령어에서 예를 설명하겠다. 인자가 2개까지 밖에 지원하지 않는 탓에 간단한 처리를 위해서도 많은 양의 코드가 필요하다.

1)push 332

push가 명령어(opcode)가 되고 332가 인자가 된다. 현재 스택에 332라는 값을 넣는다.

2)mov eax,1

eax라는 레지스터에 1이라는 값을 넣는다. eax에 source가 되고 1이 destination이 된다.


레지스터

8개의 레지스터가 쓰이며, 쉽게 말하면 CPU가 사용하는 변수라고 생각하면 된다.

EAX

산술 계산에 사용되며, 가장 많이 사용되는 레지스터이다. 또한 함수의 리턴값이 저장되는 레지스터이다.

EDX

이 또한 각종 연산에 쓰이며, 더하고 빼고 곱하는 용도로 이용됨.

ECX

ECX의 C는 count의 약자로 루프문을 수행할 때 카운팅을 하는 역할을 함. for문에서 사용되는 I라고 보면 되겠다.

EBX

이 것은 그냥 여분으로 사용되는 레지스터라고 보면 되겠다.

ESI, EDI

ESI는 문자열이나 각종 반복 데이터를 처리 또는 메모리를 옮기는데 사용

복사할 메모리 크기가 아주 크지 않은 경우 굳이 ESI,EDI를 쓰지 않는다.

EBP, ESP

EBP(Extended Base Point)는 현재 함수에서 사용하는 스택의 첫 주소를 잡아주는 기준 역할을 한다고 보면 된다.  EBP보다 낮은 주소 예를 들어 EBP-4, EBP-8 등은 지역변수가 담기고, EBP+4,EBP+8 등은 이전함수에서 준 매개변수들이 담길 수 있다.

ESP(Extended Stack Pointer)는 현재 스택의 가장 윗 부분을 가리키고 있다. push나 pop을 통해 스택의 주소가 변할 수 있으므로, ESP가 이에 대해 계속 가리키고 있어 계산 없이 빠르게 접근 가능하다.

레지스터의 크기

EAX등의 레지스터는 32비트, 즉 4바이트의 크기이다. AX는 16비트, 즉 2바이트이며 AH 와 AL은 각각 8비트, 즉 1바이트의 크기이다. 아래 그림을 보면서 확인하도록 하자.



리틀엔디언

바이트 저장 순서는 엔디언이라고 한다. 우리가 흔히 사용하는 순서의 숫자는 빅엔디언이다.

예를 들어 0x12345678은 1바이트씩 총 4바이트 값을 저장하며 빅엔디언으로

12 34 56 78 으로 4바이트가 저장된다. 하지만 리틀엔디언은 78 56 34 12가 된다.

오른쪽부터 읽으면 리틀엔디언, 왼쪽부터 읽으면 빅엔디언이라고 알면 된다.


어셈블리 명령어

모든 어셈블리 명령어를 다 보는 것보다 꼭 필요한 것만 알아두고 모르는 것이 나올 때마다 보는 것이 낫다. 그리고 여기에 나온 명령어만 알아도 대부분의 어셈블리 명령어를 이해 할 수 있다.


PUSH, POP

스택에 값을 넣는 것을 PUSH, 스택에 있는 값을 가져오는 것을 POP이다.

또한 PUSHAD, POPAD는 모든 레지스터를 PUSH하고 POP하라는 명령어이다. x64에서는 이 PUSHAD와 POPAD가 없어졌다고 한다.

push 3

push eax

pop eax(스택에 있는 값을 가져와서 eax에 넣어라는 말)

MOV

단순히 값을 넣는 역할을 한다.

mov eax,1

mov eax,ebx

LEA

주소를 가져오는 것

가령 esi에 0x401000이 들어있고 *esi 에 5640EC83이 있다면

lea eax, dword ptr ds:[esi]는 eax에 0x401000이 들어가는 것

mov eax , dwword ptr ds:[esi]는 5640EC83

ADD, SUB

ADD는 src에서 dst로 값을 더하라는 명령, SUB는 src에서 dst로 값을 빼라는 명령이다.

INT 

인터럽트 명령이다. MS-DOS에서는 어플리케이션에서 즉시 인터럽트를 일으킬 수 있었지만, 32비트에서는 어플리케이션 레벨에서의 인터럽트가 한계가 있고, ring0 레벨로 내려가기 전까진 거의 사용할 일이 없는 명령어가 됨. 제일 많이 만나는 것이 INT 3인데 옵코드가 0xCC인 DebugBreak()임

CALL

함수를 호출하는 명령어

INC, DEC

INC는 i++, DEC는 I—이다.

AND, OR, XOR

dest와 src를 연산한다. XOR은 XOR eax,eax라는 식으로 사용되는데 같은 값을 XOR하면 0이 되므로 초기화하는 용도로 사용된다.

NOP

아무것도 하지말라고 함

CMP, JMP

비교, 점프하는 명령어



스택

LIFO(Last in First Out)으로 먼저 넣은 것이 나중에 나오고, 나중에 넣은 것이 먼저 나오는 구조다. 리버스 엔지니어링을 위해 스택에 대해서 알아야 하는 것은 아래와 같다. 함수

1. 함수 호출 시 파라미터가 들어가는 방향

2. 리턴 주소

3. 지역 변수 사용


그리고 함수 첫부분에 아래와 같은 코드가 생긴다. 이를 함수 프롤로그라고도 한다.

push ebp

mov ebp,esp

sub esp,50h

ebp레지스터를 스택에 넣고 현재 esp의 값을 ebp에 넣는다. 이것은 아래 그림과 같다.

ebp는 extended base point로 스택 프레임의 시작부분을, esp는 extended stack point로 스택 프레임의 끝 부분을 가리킨다. 이 부분에서 따로 언급하지 않았지만 001004부분 그러니까 100C라는 값이 들어간 부분 밑에 함수의 기능이 끝나고 다시 돌아갈 부분의 주소가 저장된다. 일단 염두만 해놓고 넘어가도록 하자



                            ▲push ebp하기전                                                      push ebp한 후                  


                                   mov ebp,esp 한 후                                      sub esp – 50h 한 후



함수의 호출

 DWORD HelloFunction(DWORD dwParam1,DWORD dwParam2)라는 함수가 정의되어 있고 main 함수에서 이 함수를 아래와 같이 부른다고 하자. HelloFunction에서 파라미터로 4,5를 주고 있다. 이 부분에 대해 아래와 첫 번째 매개변수를 먼저 넣는 것이 아니라 스택의  LIFO특성에 따라 두 번째 매개변수인 5를 먼저 넣고, 첫 번째 매겨변수 4를 두 번째로 스택에 넣고 있다. 그리고 00401258에서 HelloFunction을 부른다. 여기서 HelloFunction으로 들어가면서 스택에는 HelloFunction이 종료되고 난 뒤에 처리할 주소를 넣어준다. 여기서는 call주소보다 +4만큼 많은 0040125C라고 하면 된다. 16진수로 C는 12인 것을 참고하도록 하자. 그 후에 함수안에서는 위에서 설명한 함수 프롤로그 push ebpmov ebp,esp를 처리한다.

int main(){

DWORD dwRet = HelloFunction(4,5);

}

위 부분을 리버스 엔지니어링 해보면 다음과 같다.

00401250 push 5

00401254 push 4

00401258 call (HelloFunction의 주소)




























'시스템 > 리버싱' 카테고리의 다른 글

gdb로 elf 리버싱  (0) 2014.06.27
리버싱 바이블 정리[1]  (0) 2014.05.28
심플스 crackme 9번 문제  (0) 2013.10.15
Reversing.kr - Easy Keygen  (1) 2013.09.02
심플스 CrackMe01 풀기  (2) 2012.01.03
Ollydbg 설정 프로그램 Olly_ini_editor  (0) 2012.01.03
ollydbg 설치 및 기본 설정  (3) 2011.12.23



심플스 crackme 9번 문제를 풀어보도록 하겠다.


순서대로 하는것이 좋으나, 일단 9번 문제 풀이를 가지고 있으니 9번문제부터 하도록 하겠다.


Ollydbg로 리버싱하기에 앞서 실행했을 때 어떤 값이 나오는지 알아야 한다.

그리고 어떤 목적으로 리버싱을 할지 꼭 유념하고 해야한다.

이 프로그램이 name에 따른 secure key를 확인하는 구조까지 파악할 것인지

단순이 특정 ID에 따른 secure key값만 구할 것인지 말이다.


본 포스팅은 secure key 값만 구하는 것을 목표로 하겠다.

프로그램을 실행하면 아래 그림과 같이 두개의 입력창과 validate 라는 버튼이 보인다.

아무 값이나 넣고 validate해보면 no no no! Try more!이라는 메세지 창이 뜬다.


▲실행 화면

▲ 틀렸을 경우(name에 따른 Secure Key가 맞지 않을때) 나타나는 메세지 창


기본적으로 all refereced string을 하면 메세지 창에서 사용한 문자열들이 나와야 하는데 그렇지 않아서 당황했다. 하지만 Search for -> Intermodular calls에서 사용한 함수를 보도록 한다.

Search for -> Intermodular calls 

아래 그림과 같이 vbaStrcmp가 있다. 문자열 비교를 통해 name으로 만든 secure key와 사용자가 입력한 secure key를 비교 할 테니  이 부분에 break를 하고 F9로 실행을 시켜보자. 


vbaStrCmp


실행시키면 다음과 같이 멈추는데 이 때 vbaStrcmp이전에 push되는 부분을 보면 스택에 아래 그림과 같이 jkxiig과 내가 입력한 asdf가 있는 것을 볼 수 있다 .그러므로 newbie에 맞는 secure key는 jkxiig이다.

▲Strcmp 전 부분

▲스택 부분





'시스템 > 리버싱' 카테고리의 다른 글

gdb로 elf 리버싱  (0) 2014.06.27
리버싱 바이블 정리[1]  (0) 2014.05.28
심플스 crackme 9번 문제  (0) 2013.10.15
Reversing.kr - Easy Keygen  (1) 2013.09.02
심플스 CrackMe01 풀기  (2) 2012.01.03
Ollydbg 설정 프로그램 Olly_ini_editor  (0) 2012.01.03
ollydbg 설치 및 기본 설정  (3) 2011.12.23


오랫만에 포스팅을 한다.


많은 일이 있었지만, 결국 포스팅을 한다는 것은 나를 괴롭히는 것이 아니라 

나를 더욱 성장시키며, 진정 내가 하고 싶은 것을 하나 하나 알아간다는 것이라는 걸 알게 됬다.

스스로 많이 한다고 주변 사람들에게 떠벌리며, 그것에 만족하며, 내가 하지 않는 것이 아니라

못한다고 스스로 변명과 핑계를 만들고 잇엇다.

쨋든 서론은 여기까지 하고 리버싱을 해봅시다.

Reversing.kr에서 2번째로 풀 Easy Keygen이 되겠다.


▲Reversign.kr - Easy Keygen


리버싱을 하기에 앞서 우리는 프로그램으로부터 얻을 수 있는 정보는 모두 얻어야 한다 .그러므로 일단 EasyKeygen을 실행시켜보자. 그러면 다음과 같이 당연히 틀린 시리얼을 입력하여 Wrong이라는 메세지가 나온다.

실행시 나타나는 메세지

이를 토대로 아래와 같이 OllyDbg에서 관련 문자열을 찾도록 한다. 

밑의 그림과 같이 Wrong과 Correct가 있는 것이 보이고, 이 주변에 분기문을 통해 두 문자열을 포함한 위치로 이동될 것이라고 예측해 볼 수 있다.

프로그램이 가지고 있는 문자열 찾는 방법

문자열 목록과 그 문자열을 가지고 있는 주소

위에서 예측해본 것과 같이 00401118에 JNE를 통해 Correct와 Wrong을 구분하는 것을 볼 수 있다.

▲JNE를 통한 분기

여기서 우리는 멈춰서 생각해봐야한다. id에 맞는 Serial이 필요한 것이고, ID를 기준으로 프로그램에서 Serial을만든 후 , 사용자가 입력한 Serial과 비교 할 것이다. 

문제를 풀기 위해서 특정 Serial을 구하거나, 프로그램 안에 남겨진 힌트를 찾아야 할텐데

ReadMe를 보면 ID가 주어진다.


▲ReadMe에 있는 ID

따라서 아래 그림과 같이 Name을 입력 하고 난뒤에 호출한 함수나 그 사이에 있는 부분을 분석하면 어떠한 방식으로 Serial을 만드는지 알 수 있다. 


▲Input Name과 Input Serial 사이


심상치 않은 부분을 하나하나 보도록 하겠다. 현재 실행위치는 00401077이고 이에 대한 레지스터들의 값이 나타난다.


 

CMP ESI, 3

ESI - 3을 한 후에 JL(Jump less)로 음수가 나타난다면 점프를 실행한다. 

즉, 다시말해서 ESI가 3보다 작다면 한 줄 넘어 0040107E로 가고 그렇지 않다면

바로 다음줄로 가서 XOR ESI, ESI로 ESI를 0으로 만든다.

아랫부분에 보면 INC ESI가 있는 것을 보아

3번 증가후 다시 0으로 바꿔주는 반복형태를 가지고 있다.


또한 아래부분에 보면

OR ECX,FFFFFFFF후 하여 ECX를 초기화한 후에

REPNE SCAS BYTE PTR ES:[EDI] name이 저장된 곳으로 계산 후 

NOT ECX  DEC ECX 2의 보수를 취한다.

또 이 반복문을 한번 지나가면서 EBP가 하나 증가하는걸 봐서

CMP EBP, ECX는  EBP(반복문 횟수), ECX(문자열 길이)를 비교하는 것이므로

문자열 길이 만큼 반복이 진행되는 것을 알 수 있다.


오늘 포스팅은 여기까지 하고 내일 이어 진행하도록 하겠다.





'시스템 > 리버싱' 카테고리의 다른 글

gdb로 elf 리버싱  (0) 2014.06.27
리버싱 바이블 정리[1]  (0) 2014.05.28
심플스 crackme 9번 문제  (0) 2013.10.15
Reversing.kr - Easy Keygen  (1) 2013.09.02
심플스 CrackMe01 풀기  (2) 2012.01.03
Ollydbg 설정 프로그램 Olly_ini_editor  (0) 2012.01.03
ollydbg 설치 및 기본 설정  (3) 2011.12.23
  1. juhee 2013.09.02 21:54 신고

    다음 포스팅이 기대되는군요,
    빠른 다음편 기대할게요~^^

문제는 프로그램에서 핵심이 되는 API는 무엇이냐는 것이다.

일단 프로그램을 실행시켜보면 다음과 같은 메세지 박스가 뜨는 것을 확인할 수 있습니다.

 



 

리버싱을 하기에 앞서 뚜렷한 목적을 두고 임해야 명확하고 빠르게 결과를 도출 할수 있습니다.


Ollydbg로 프로그램을 열면 짧은 코드가 나오는 프로그램도 있지만

엄청나게 긴 프로그램이나 여러 dll을 import하는 프로그램을 볼 수 있는데

다 하나 하나 마춰보면서 역공학을 펼칠 순 없습니다.

스도쿠를 할때 모든 칸에 모든 수를 넣어보면서 대입을 하지 않는것처럼요

자신이 경험을 통해 아는 부분을 대입하여 내가 원하는 목표를 빠르게 도출 할 수 있도록 합니다.

서론이 길었습니다. 문제를 풀어 보도록 합시다.

첫번째 메시지 박스(abex'1st crackme)를 확인하면 다음 메시지 박스(Error)가 나타나는 것을 알 수 있습니다.

이를 통해 유추 할 수 있는 부분은 모두 알아봅니다.


"HD(Hard Disk)를 CD-Rom처럼 생각하게 만들어줘"라는 메세지에서

"이건 CD-ROM이 아니잖니"라는 메세지를 띄우는 것을 알 수 있습니다.

그다음 Ollydbg로 실행을 시킵니다.

옵션에서

처음 Ollydbg설치시 처음에 멈추는 부분(First pause)를 
 
모듈의 처음 시작부분(entry point of main module)로 두었기 때문에 가장 처음 부분으로 갈 것입니다.

설정 부분에 대한 설명은 (http://kcats.tistory.com/entry/ollydbg설치)에 있습니다.





※TIP 위 그림의 왼쪽 하단 부분에 보이는 부분을 클릭하면

Appearance 와 Debugging Option을 빠르게 이동 할 수 있습니다.

처음 리버싱을 하는 입장에서 다른 사람들의 풀이를 보면 확실하게 짚고 넘어가지 않고

빠르게 넘어가는 석연찮음을 보입니다. 물론 위에서도 말씀드렸지만 CPU의 모든 행위들을 볼 수 없지만요

그래서 이번 Crackme01의 풀이는 하나하나 천천히 풀이해보도록 하겠습니다.

물론 저도 처음 리버싱을 접했을 때 왜 이렇게 대충 짚고 넘어가지? 왜 하나하나 풀이 하지 않지? 라고 했지만

좀더 접해보면서 리버싱이라는 것이 직관적인 부분이 많이 있으며 경험을 통한 예상으로 풀이를 하는 부분이 다수 존재합니다.


위 그림에서 GetDriveTypeA , MessageBoxA 라는 API가 쓰였다는 것을 확인 할 수 있으며

그에 대한 파라미터(인자값)으로 GetDriveType A는 하나 MessageBoxA는 4개가 들어가는 것을 예상을 한 상태로

 Win32API Referrence를 보며 API를 확인해봅시다.


 

 


GetDriveType은 디스크가 (제거가능한 것/고정된 것) 인지 (CD-ROM/RAM disk/network drive)인지 결정해주는 함수입니다.

인자값으로 알고자 하는 드라이브의 경로를 적어주며, 리턴값이 6개가 있다는 것을 알 수 있습니다.

여기서 DRIVE_CDROM으로 나오는 값을 다른 값이 나오도록 바꿔줘야 한다는 것을 예상 할 수 있습니다.

그래서 API부분에 Break Point(F2)를 걸고  실행(F9) 시켜 봅니다.

 



함수가 실행되기전에 멈춰 있는 상태며 이때 CPU Register들의 값이

 


빨간색 부분들이 변화된 값들이고 초록색부분들은 변하지 않는 부분입니다.

인것을 참고 하며 Step Over(F8)시켜줍니다.

 


위 레지스터값의 변화를 통해 EAX(3), ECX(00008CA8), EDX(7C93E514) , ESP(0012FFC4)인것을 확인합니다.

일반적으로 EAX에 리턴값들이 들어가므로 GetDriveType API에서 리턴된 값이 3이라는 걸 예상할 수 있습니다.

 


그후 보면 JE( Jump Equal) 같을 시 Jump구분을 통해

MessagBox API에 다른 인자값이 들어 가는 것을 알 수 있습니다.

MessagBox에 들어 가는 값은 Ollydbg에서 가르쳐주므로

style,title,text hOwner 순으로 Stack에 들어가 역순으로
 
hOwner,text,title,style순으로 나와서 API에 파라미터값으로 들어갑니다.

그럼 이제 예상 할수 있는 부분은 GetDriveTypeA로 나온 값을 JE 구문 전까지 계산을 한 후에

JE에서 검증을 한후 메세지박스를 띄워주는 구조인 것을 알 수 있습니다.

그럼 값이 맞는지 검증하는 부분인 JE와 CALL 사이에 있는 부분을 풀이해 보도록 하겟습니다.

INC ESI

ESI의 값을 1 증가 시킵니다. ESI(FFFFFFFF)에서 1증가 하여 ESI(00000000)이 됩니다.

DEC EAX
 
EAX의 값을 1 감소 시킵니다. EAX(00000003)에서 1감소 하여 EAX(00000002)가 됩니다.

JMP SHORT 00401021

00401021부분으로 JUMP합니다. (바로 밑줄부분 인걸 알수 있습니다.)

INC ESI

ESI 값을 1 증가 시킵니다. ESI(00000000)에서 1증가 하여 ESI(00000001)이 됩니다.

INC ESI

ESI 값을 1 증가 시킵니다. ESI(00000001)에서 1증가 하여 ESI(00000002)가 됩니다.

DEC EAX

EAX의 값을 1 감소 시킵니다. EAX(00000002)에서 1감소 하여 EAX(00000001)이 됩니다.

CMP EAX,ESI

EAX와 ESI를 비교하는데 EAX에 ESI를 빼서 0이 나오면 같다라고 생각합니다.

현재 EAX의 값은 1 ESI의 값은 2이므로 같지 않습니다.

JE구문을 통과하기 위해서는 EAX값이 2가 되어야 하고 그러기 위해서는

GetDriveType에서 나온 값이 4가 되어야 합니다.

여기서 두가지 부분으로 나뉘어서 생각할 수 잇습니다.

1) 계산 부분을 조정하여 인증 되는 부분(JE)에 Equl로 통과한다.

2) 인증 부분을 조정하여 우회하여 JMP로 통과한다.

계산부분을 조정하기 위해서 위의 풀이를 한 것이므로 일단은 조정해보도록 하겟습니다.


EAX을 감소 시키는 부분을 NOP처리를 하여 EAX의 값을 줄이지 않도록 하겠습니다.


 

EAX값이 2이며 ZeroFlag가 1로 되어 Jump가 발생되는것을 알 수가 있습니다.

F8(Step Over)로 실행시키면 이제 메세지박스에 "Ok,I really think that your HD is a CD-ROMD! "이 나옵니다.

그림

그럼 이제 JE 구문을 JMP로 바꿔보겠습니다.

그림

어떤값이 오더라도 JMP로 원하는 곳으로 이동시켜서 원하는 메세지 박스를 생성시킵니다.



 

이 문제는 값이 일정하게 나오는 인자에서 값의 조작이나 분기문의 조작하는 CrackMe였습니다.



 

'시스템 > 리버싱' 카테고리의 다른 글

gdb로 elf 리버싱  (0) 2014.06.27
리버싱 바이블 정리[1]  (0) 2014.05.28
심플스 crackme 9번 문제  (0) 2013.10.15
Reversing.kr - Easy Keygen  (1) 2013.09.02
심플스 CrackMe01 풀기  (2) 2012.01.03
Ollydbg 설정 프로그램 Olly_ini_editor  (0) 2012.01.03
ollydbg 설치 및 기본 설정  (3) 2011.12.23
  1. ParkHG 2014.10.08 02:32 신고

    2)인증부분을 조정하여 ... 이부분에 그림이 없는건가요????


OllyIniEditor_2_2.exe


http://www.npteam.net/4에서 다운 받을수 있으며


열기 버튼을 통해 Ollydbg.ini파일의 경로를 설정해주면 간편하게 옵션을 설정할수 있습니다.

Black Skin을 사용한 모습


깔끔한 설정 환경을 볼수 있다. 하지만 필자는 매트릭스형(검정 바탕에 초록글씨)를 선호한다 !!

리버싱의 로망이라규


'시스템 > 리버싱' 카테고리의 다른 글

gdb로 elf 리버싱  (0) 2014.06.27
리버싱 바이블 정리[1]  (0) 2014.05.28
심플스 crackme 9번 문제  (0) 2013.10.15
Reversing.kr - Easy Keygen  (1) 2013.09.02
심플스 CrackMe01 풀기  (2) 2012.01.03
Ollydbg 설정 프로그램 Olly_ini_editor  (0) 2012.01.03
ollydbg 설치 및 기본 설정  (3) 2011.12.23



ollydbg 설치부터 시작하겠습니다.




위 그림의 odbg110.zip을 다운 받습니다.

다운을 받은후 압축을 풀면


UDD 폴더와 plugin 폴더를 만들고 위의 3개의 .dll파일들을 plugin폴더로 옮겨줍니다.

UDD폴더에는 백업파일이 plugin폴더에는 추가기능을 사용자가 직접 다운받아 넣어두는 곳이라고
생각해두면 되겠습니다



WinApi를 다운 받아 참조할 수 있습니다. 단점은 영어로 되있다는거
(http://tuts4you.com/download.php?view.258)
필자도 영어 울렁증이 있긴하지만..(OTL) 리버싱 공부 하며 영어 공부 하며 겸사겸사 한다 치고

아는만큼 읽어보면 될것 같습니다.



ollydbg 폴더 안에 다운 받아 압축을 푼 후에 밑에 그림처럼 Help-> Select API help file을
선택합니다.

 

 


SelectAPI를 통해 WInAPI의 경로를 지정후 Open API로 레퍼런스에게 도움을 청하여 읽어보면 됩니다



그리고 Option에 들어가 Appearance에 들어가 사용자 환경을 바꿔줍니다.



글씨가 작다면 Fonts 탭에서 Change로 글꼴 스타일과 크기를 조정해줍니다.

Ollydbg를 통해 리버싱을 하면서 분기문들을 유심이 봐야 합니다. 그 부분에서 분기문을 나타내주는

JMP, JE, JNE 등이 있는데 이 부분들이 잘 표시 될수 있도록 하는 설정을 ollydbg폴더에
 ollydbg.ini파일에서
아래 그림과 같이 설정해 줍니다.


 주의 !! 4개 부분을 모두 1로 설정해야 합니다. 예전에 이 부분을 그대로 설정해놓고

왜 안되지 안되지 하는 조금 부족한 행동을 보였을 때가 생각이 나네요

그리고 밑에 부분 Option -> Debuggin Option 에서 CPU 탭에서 jump 옵션 들을 모두 체크 해줍니다.


그라믄 다음과 같이 점프 모냥이 보입니다



그리고 Ollydbg로 파일을 열었을때 Entry Point 부터 시작하도록 하는 설정을 합니다.




제 개인적인 셋팅을 보여 드리겠습니다. 

필자는 남자는 허세다 라고 생각하기 때문에 ( 물론 여자도 허세가 필요합니다)

 꼭 이 환경설정이 필요하다고 생각합니다.

공대생, IT를 하는 사람으로서 매트릭스의 글꼴이 지나가는 모습들은 가장 멋있을뿐더러

비IT인들이 보기에 unix환경에서 까만 배경에 초록 글씨만 나와도 멋지게 봅니다.

그러므로 !!!

아래 그림과 같이 설정합니다.



짜잔 그럼 환경이 다음과 같이 간디나게 건담조종석처럼 바뀝니다.


막상 올리고 나니 별로 허세가 좔좔 흐르지 않는것처럼 보이지만

직접 설정해 보시면 아 역시 연예인들이 실물이 더 예쁘구나 라는 진리를 이 사진을 통해 알게 될것입니다.

그리고 공개된 장소에서 뒤에서 누가 이 환경을 본다면 

지나가는 친분이 있는 사람에게서 97.213%   " 와 정말 멋있다. 너 어떤거 하는거야?" 라는 질문에

"난 리버싱하는 남자라고" 대답 하실수 있을것입니다.

리버싱하는 허세남의 2번째는 미칠듯한 스피드한 단축키를 사용하는 것입니다.

단축키 정리표는 http://www.ollydbg.de/quickst.htm 에서 보시면 되고

필자가 기본적으로 사용하는 부분은

Alt + C ( CPU환경 보기) , Alt + B (Break Point 부분 보기 ) , Alt + E ( Module 보기)

Ctrl + G (입력부분(메모리주소 등) 따라가기) Alt + E 에서 Ctrl + N(함수,변수 등 이름찾기 )

등이 있습니다.


일단 중요한것은 뒤에 사람이 온다? 인기척이 느껴진다 그러면 빠르게 Alt + C , Alt + B를 누르고

고뇌하는 표정을 짓다가 무언가를 감을 잡았다는 표정으로 Ctrl + G 로 입력하시어 보시면 됩니다


헥헥 힘들게 썼네요 첫 포스팅이다 보니 생각나는대로 적다 보니

두서가 없는 부분이 없지만

젤 마지막 부분을 강조 하고 싶다는 말을 밝히지 아니할순 없네요

이만 마치겠습니다.

'시스템 > 리버싱' 카테고리의 다른 글

gdb로 elf 리버싱  (0) 2014.06.27
리버싱 바이블 정리[1]  (0) 2014.05.28
심플스 crackme 9번 문제  (0) 2013.10.15
Reversing.kr - Easy Keygen  (1) 2013.09.02
심플스 CrackMe01 풀기  (2) 2012.01.03
Ollydbg 설정 프로그램 Olly_ini_editor  (0) 2012.01.03
ollydbg 설치 및 기본 설정  (3) 2011.12.23
  1. ParkHG 2014.10.08 01:49 신고

    으아 ㅋㅋㅋㅋㅋ 정말 꿀팁이군요. 정말이지 마지막이 매력터지는 포스팅이네요 ㅋㅋㅋㅋ

  2. 춤추는 공학도 2015.02.12 10:59 신고

    전문적이시면서도... 재미있습니다 ㅋㅋㅋㅋㅋ 좋은 글 잘 봤습니다!


  3. NEO 2016.11.16 21:11 신고

    매트릭스ㅋㅋㅋㅋ 꿀팁 감사합니다!!

+ Recent posts