Reverse Engineering Chap1-2
1. .cpp vs. .exe
1.1 cpp 파일
•소스파일
•C언어로작성됨
•인간이 이해하기 쉬운 수준
1.2 exe 파일
•바이너리파일
•명령어(instruction)들로 이루어져 있음(기계어)
•인간이 이해하기 매우 어려움
2. 디버거(Debugger)
2.1 디스어셈블러(Disassembler)
•바이너리파일의 기계어를 어셈블리(Assembly)언어로 번역하여 보여주는 도구
•어셈블리언어는 아키텍쳐(Architecture)에의 존적인 언어로, 기계어와 1:1로 대응되지만 인간이 이해 가능한 수준의 언어임
2.2 디버거(Debugger)
•바이너리파일을 디버깅하는 도구
•기본적으로 디스어셈블러모듈등이 포함되어 있음
•디버깅대상이 되는 프로그램(Debuggee)에 대한 제어권을 가지며, 실행제어 및 데이터 처리 전반에 대한 권한을 가짐
•주로버그가 있는지 확인하거나, 원하는 기능을 수행하도록 프로그램 실행과정을 조작할때 이용
•OllyDbg, IDA Pro, ...
2.3 OllyDbg
•http://www.ollydbg.de
•대표적인 무료 디버거
•실습에서는 1.1 버전을 권장
•버전마다 환경이 조금씩 다르므로 유의
•화면구성
•Code Window : 기본적으로 disassembly code를 표시하여 각종 comment,label을 보여주며,코드를 분석하여 loop,jump 위치 등의 정보를 표시합니다
•Register Window : CPU register 값을 실시간으로 표시하며 특정 register들은 수정도 가능합니다
•Dump Window : 프로세스에서 원하는 memory 주소 위치를 Hex와 ASCII/유니코드 값으로 표시하고 수정도 가능합니다
•Stack Window : ESP register가 가리키는 프로세스 stack memory를 실시간으로 표시하고 수졍도 가능합니다
3. HelloWorld.exe
•“Hello World!” 라는문자열을메시지창에출력하는프로그램
•HelloWorld.exe 실행화면
4. 실습#1: main 함수내의 MessageBox 위치찾기
4.1 실습목표
•main() 함수의 위치 및 메세지박스를 표시하는 코드 찾기
•OllyDbg의 기본적인 사용법 익혀보기
4.2 디버깅실습
4.2.1 단순무식하게!
(1) Entry Point(EP)
•바이너리파일의코드시작점
•디버거가멈춘곳
•[F7]을눌러0040270C 함수내부로진입(Step Into)
(2) Comment
•API 호출시 이름이 나타남
•main 함수에서 사용한 적 없는 API들이 있음
(3) main() 함수
•(개발자가작성한) 코드상의 시작부분
(4) Stub Code
•실제 바이너리 코드상의 시작부분
•컴파일러가 프로그램실행을 위해 추가한 코드
•컴파일러마다 달라짐
•리턴부분으로 이동하여 함수탈출([Ctrl+F9]: Execute till Return 단축키)
(5) 디버깅 진행 방법
•Step Into와 Execute till Return을 반복하며 진행
(6) main() 함수를 찾아서
•함수중API 이름이 주석으로 달린 줄은 스킵([F8]: Step Over 단축키)
•다른 함수 호출(call) 시 함수 내부로 들어가 살펴보기([F7]: Step Into 단축키)
•main() 함수가 아닌 경우 리턴문으로 이동하여 탈출([Ctrl+F9]: Execute till Return 단축키)
•처음부터 다시 시작하고 싶다면?([Ctrl+F2]: Restart 단축키)
(7) main() 함수는 어디에?
•0040104F(stub code)
이 부분에 main() 함수가 나타남
•MessageBoxW() API를 호출하는 함수
•CALL 00401000
이 명령어 수행시 메세지박스 출력
Step Into 명령으로 함수 내부 진입
(8) 00401000 위치의 코드
•MessageBoxW() API 호출코드
•PUSH 명령어를 이용하여 스택에인수를 넣음
“www.reversecore.com”
“Hello World!”
•CALL 명령어로 MessageBoxW() 호출
0040100E
4.2.2스마트하게!
(1) 베이스 캠프 설정
•Goto 명령([Ctrl+G])
특정주소로 곧 바로 커서를 이동
커서까지 실행(Execute till cursor[F4] 명령이용)
•Break Point([F2])
execute[F9] 로 BP까지 진행 가능
View -Search for -Breakpoints를눌러BP 목록확인가능
•주석([;])
우 클릭-user-defined comments 선택
(2) 원하는 코드를 빠르게 찾는 방법
•프로그램의 기능에 주목하기
메세지박스를 출력
메세지창의 제목과 내용 확인
이러한 ‘기능’에 해당하는 API의 위치를 우선 탐색
•코드 실행
Step Over 명령으로 한 줄씩 코드를 실행
메세지창이 출력되는 순간의 코드를 확인(CALL 00401000)
해당 코드가 바로 main() 함수의 위치
•문자열 검색
우 클릭-Search for -All referenced text Strings
문자열 “www.reversecore.com” 더블 클릭,MessageBoxW() 호출코드로이동가능
•API 검색(API 이름이 명확한 경우)
i.API 호출 부분에 BP 설정
우 클릭-Search For -All intermodular calls
ii.API 코드에 BP 설정
우 클릭-Search For -Name in all modules
로딩된.dll 파일의 API 목록을 나타내는 것
5. 실습#2: “Hello World!” 문자열 패치
5.1 패치(patch)
•파일또는메모리를수정하여, 프로그램의코드와데이터를수정하는것
•버그수정또는기능추가를위함
5.2 실습 목표
•메세지박스의 “Hello World!” 문자열 변경
5.3 패치 준비
main 함수 시작 주소까지 실행하기(00401000 까지 실행)
5.4 패치 방법
5.4.1 문자열 버퍼 수정
•“Hello World”가 저장된 위치의 값을 직접 수정
•Dump 창에서 Goto -> 004092A0
•“Hello World!” 유니코드 저장 공간(4092A0 ~ 4092B9)
유니코드 크기: 글자당 2바이트
•드래그한 뒤 수정([Ctrl+E])
•수정 결과
•장단점
간단하지만, 문자열버퍼크기이상입력이어려움
버퍼를넘기는경우버퍼오버플로우
5.4.2 다른 메모리 영역에 문자열 생성
•MessageBoxW() API의 문자열 파라미터
특정 메모리 주소에 저장된 값을 전달(스택에 PUSH)
이 주소 값을 변경한다면, 원하는 문자열을 전달가능
•데이터가 저장되는 영역
실제 데이터 값이 저장되는 영역
사용되지 않고 비어있는 영역-> NULL padding 영역
•새로운 문자열 생성
NULL padding 영역에 새로운 문자열 공간 할당 가능
적당한 위치에 새로운 문자열 값 입력([Ctrl+E])
•MessageBoxW() 파라미터 주소 변경
Assemble 기능을 이용하여 코드 패치
패치하고자 하는 코드를 더블 클릭 또는[space]
새로 만든 문자열의 주소로 변경
•실행 결과
5.4.3 패치 결과의 적용
•패치 결과는 메모리에 존재하는 코드를 수정한 것
•실제 파일에는 반영되지 않음-> 파일로 따로 저장 필요
•파일로 저장하는 방법
Dump 창에서 변경된 내용을 선택
우 클릭-Copy to executable file
아래와 같은 창에서 우 클릭후 Save file 메뉴 선택
'리버싱핵심원리' 카테고리의 다른 글
Reverse Engineering Chap 23 (0) | 2016.01.17 |
---|---|
Reverse Engineering Chap 14~15 (0) | 2016.01.14 |
Reverse Engineering Chap 16-17 (0) | 2016.01.14 |
Reverse Engineering Chap 13 (0) | 2016.01.12 |
Reverse Engineering Chap7-12 (0) | 2016.01.10 |