02. Hello World! 리버싱
1. Hello World! 프로그램
1.1. HelloWorld.exe
1) HelloWorld.exe 실행 화면파일
2) HelloWorld.exe 소스 코드(HelloWorld.cpp)
1.2. 디버거와 어셈블리 언어
1.2.1. 프로그램 처리 과정
전처리기 -> 컴파일러 ->어셈블러 -> 링커
1) 전처리기 : #으로 시작하는 지시자의 지시에 따라 소스코드를 변경하는 작업 수행
2) 컴파일러 : 소스코드를 어셈블리 코드로 번역하는 작업수행
3) 어셈블러 : 어셈블리 코드를 이진 코드(Binary Code)로 변경하는 작업 수행
4) 링커 : 프로그램 내에서 참조하는 함수, 라이브러리들을 연결시켜주는 작업을 수행
1.2.2. 프로그램 실행 과정
Fetch -> Decode -> Execution
1) Fetch : 실행 할 명령어를 레지스터로 옮김 -> I/O Bus로 Register에 저장
2) Decode : 실행 할 명령어를 해석 -> Control Unit
3) Execution : 명령어 실행 -> ALU
1.2.3. 디버거와 어셈블리 언어
1) 디버거(Debugger) : 소프트웨어 개발자가 실행중인 프로그램을 관찰할 수 있게 하는 프로그램 (디스어셈블러 + 디버그로 구성)
ex) Ollydbg, IDA, WinDbg (http://www.reversecore.com/91 참고)
2) 어셈블리 언어(Assembly Code) : 소프트웨어 체인에서 가장 낮은 레벨의 언어
~ 어셈블리어 구성?
OPCODE 목적지 OPERAND, 출발지 OPERAND
- OPCODE(=Operation Code) : 명령의 이름
- OPERAND : 명령에 전달되는 인자
2. Hello World.exe 디버깅
2.1. 디버깅 목표
HelloWorld.exe 실행 파일을 디버깅(Debugging)하여 어셈블리 언어로 변환된 main() 함수 찾기
2.2. OllyDbg
직관적인 인터페이스와 강력한 확장 기능으로 무장한 Win32 디버거 (http://www.ollydbg.de)
설치 방법 : http://t0x1c07.tistory.com/entry/올리디버거OllyDBG-설치-및-기본-설정
1) Code Window
기본적으로 디스어셈블리 코드를 표시하여 각종 comment, label을 보여주며 코드를 분석하여 loop, jump위치 등의 정보를 표시
2) Register Window
CPU register 값을 실시간으로 표시하여 특정 register들은 수정도 가능
3) Dump Window
프로세스에서 원하는 memory 주소 위치를 Hex와 ASCII/유니코드 값으로 표시하고 수정 가능
4) Stack Window
ESP register가 가리키는 프로세스 stack memory를 실시간으로 표시하고 수정도 가능
2.2.0. OllyDbg의 Code Window 구성
1) Address : 프로세서의 가상 메모리(Virtual Address:VA) 내의 주소
2) Instruction : IA32(또는 x86) CPU 명령어
3) Disassembled code : OP code를 보기 쉽게 어셈블리로 변환한 코드
4) comment : 디버거에서 추가한 주석(옵션에 따라 약간 다르게 보일 수도 있다!)
2.2.1. OllyDbg의 기본 명령어(Code Window에서 동작)
명령어 | 단축키 | 설명 |
Restart | [Ctrl+F2] | 다시 처음부터 디버깅 시작 (디버깅을 당하는 프로세스를 종료하고 재실행) |
Step Into | [F7] | 하나의 OP code 실행 (CALL 명령을 만나면, 그 함수 코드 내부로 따라 들어감) |
Step Over | [F8] | 하나의 OP code 실행 (CALL 명령을 만나면, 따라 들어가지 않고 그냥 함수 자체를 실행) |
Execute till Return | [Ctrl+F9] | 함수 코드 내에서 RETN 명령어까지 실행 (함수 탈출 목적) |
2.3. EP(EntryPotin)
Windows 실행 파일(EXE, DLL, SYS 등)의 코드 시작점을 의미한다.
-> 프로그램이 실행될 때 CPU에 의해 가장 먼저 실행되는 코드 시작위치
2.4. 디버깅 시작
1) HelloWorld.exe 파일을 OllyDbg로 연다.
2) 디버거가 멈춘 곳은 EP코드로 HelloWorld.exe의 실행 시작 주소이다.
CALL HelloWor.0040270C : 40200C 주소의 함수를 호출
JMP HelloWor.0040104F : 40104F 주소로 점프
=> 40270C 주소의 함수를 호출(CALL)한 후 40104F 주소로 점프(JMP)하라
3) 40270C 함수 따라가기 = 40110A0 주소에서 Step Into[F7] 명령어를 사용해서 40207C 함수안으로 들어간다.
4) 40270C 함수 안 분석
-> 이 코드는 프로그램 실행을 위해 Visual C++에서 추가한 Visual C++ Stub Code (각 컴파일러 종류와 버전별로 Stub Code 모양은 달라진다)
+ 빨간 글씨는 코드에서 호출되는 API함수 이름
5) 4027A1 주소에 있는 RETN 명령어까지 Step over[F8] 또는 Execute till Return[Ctrl+F9] 명령을 이용하여 실행
6) 40115A5 점프문 따라가기 [F7]
6) 40104F 주소부터 [F7] 명령을 실행한다.
(실행 하다보면 401056의 CALL HelloWor.00402524 명령어을 만날 수 있다.)
7) 402524 함수 안으로 들어간다.
(위의 코드를 보면 MessageBox() API 호출 코드가 보이지 않는다. 즉, 여긴 main()함수라고 보기 어렵다.)
8) 402568 주소의 RETN까지 디버깅을 진행한다.
9) 402568 주소의 RETN을 실행하여 40105B주소로 돌아간다. 그 후 다시 [F7] 명령을 통해 디버깅을 진행한다.
10) 디버깅을 진해하다보면 CALL 00401000 명령어를 만나게 된다.
11) CALL 00401000로 따라 들어간다. [F7]
MessageBoxW() API를 호출하는 코드를 볼 수 있다. MessageBOXW() API의 파라미터가 "Hello World!", "www.reversecore.com" 문자열이다.
-> 여기가 main()함수이다.
'Learning Again > Reversecore' 카테고리의 다른 글
[리버싱 핵심 원리] 5장 : 스택 (0) | 2016.03.19 |
---|---|
[리버싱 핵심 원리] 4장 : IA-32 Register 기본 설명 (0) | 2016.03.19 |
[리버싱 핵심 원리] 3장 : 리틀 엔디언 표기법 (0) | 2016.03.19 |
[리버싱 핵심 원리] 1장 : 리버싱 스토리 (0) | 2015.07.18 |