-
2 Hello World! 리버싱(1)리버싱 엔지니어링/리버싱 핵심 원리 2022. 2. 5. 01:41
2.1 Hello World! 프로그램
#include "windows.h" #include "tchar.h" int _tmain(int argc, TCHAR *argv[]) { MessageBox(NULL, L"Hello World!", L"www.reversecore.com", MB_OK); return 0; }
해당 코드 *Release 모드로 빌드해서 실행파일(.exe) 만들기
*Release 모드
: 디버깅 정보를 삽입하지 않고, 코드를 최적화시켜 실행하여 파일의 크기를 줄여준다.
- 코드가 간결해져서 디버깅하기에 편리
- 속도, 크기면에서 유리
- 프로그램 배포시 릴리즈 모드로 배포
2.1.1 디버거와 어셈블리 언어
- 개발도구(Visual C++)를 이용해 C 언어 소스코드(.cpp)를 빌드하면, 실행파일이 (.exe) 생성
- 소스코드를 기계가 이해하기 쉬운 기계어(.exe)로 변환하는 과정
- 디버거 유틸리티
- 기계어를 사람이 알아보기 어렵기 때문에 필요
- 탑재된 디스어셈블러 모듈로 기계어를 어셈블리 언어로 번역하여 보여줌
2.2 HelloWorld.exe 디버깅 : OllyDbg
2.2.1 OllyDbg 실행화면
Code window disassembly code를 표시. 코드를 분석하여 loop, jump 위치 등의 정보를 표시.
Register window CPU register 값을 실시간으로 표시. Dump window 프로세스에서 원하는 memory 주소 위치를 Hex와 ASCII/유니코드 값으로 표시, 수정 Stack window ESP Register가 가리키는 프로세스 stack memory를 실시간으로 표시, 수정 2.2.2 EP(EntryPoint)
: 실행 시작 주소
HelloWorld.exe 디버깅 - HelloWorld.exe 실행 시작 주소 : 0040126F
- 의미 : 401678 주소를 호출(CALL)한 후 4010ED 주소로 점프(JMP)해라
2.2.3 OllyDbg 기본 명령어
명령어 단축키 설명
Restart [Ctrl+F2] 다시 처음부터 디버깅 시작 Step Into [F7] 하나의 OP code 실행(CALL 명령어를 만나면, 그 함수 코드 내부로 따라 들어감) Step Over [F8] 하나의 OP code 실행(CALL 명령어를 만나면, 따라 들어가지 않고 자체 실행) Execute till Return [Ctrl+F9] 함수 코드 내에서 RETN 명령어까지 실행(함수 탈출) Mission : 기본 명령어를 이용한 main() 함수 찾기
main() 함수 기본명령어를 이용해 디버깅하며 메인함수 발견!
2.3 OllyDbg 베이스 캠프
2.3.1 베이스 캠프
: 디버거 재실행 시 처음(EP 코드)부터 새로 시작하는 불편함 때문에, 중요 포인트(주소)를 지정해 놓고 빠르게 갈 수 있는 방법을 기록.
2.3.2 베이스 캠프를 설치하는 4가지 방법
1) Goto 명령
- 단축키 : [Ctrl+G]
- 주소 입력 → OK
- Execute till cursor[F4] 명령으로 해당 주소까지 실행
2) BP 설치
- BP(Break Point)를 설치[F2]하고 실행[F9]
- 가장 편하고 많이 사용되는 방법
- 현재 위치부터 실행하다 BP가 걸린 곳에서 멈춤
- BreakPoints 목록을 통해서도 이동가능
3) 주석
- 단축키 : [;]
- 단축키로 주석을 달고, 해당 주석을 찾아감.
- defined comment 항목에서 확인 가능
4) 레이블
- 원하는 주소에 특정 이름을 붙여주는 기능
- 단축키 : [:]
- 레이블을 붙이면, 해당 주소를 입력한 레이블로 표시
- defined labels 항목에서 확인 가능
2.4 원하는 코드를 빨리 찾아내는 4가지 방법
2.4.1 코드 실행 방법
- Step Over[F8]로 디버깅을 하다보면, “Hello World” 메시지 박스가 출력
- 특정 함수 호출 이후 메시지 박스가 나타남 → 함수는 main() 함수이다.
2.4.2 문자열 검색 방법
- 마우스 우측 → Search for → All referenced text strings 명령어 사용
- 의미 : 401007 주소의 PUSH 411B00 명령어가 있는데, 이 명령어에서 참조되는 411B00 주소는 ‘HelloWorld’ 라는 문자열이다.
- 문자열 클릭 시 main()함수의 MessageBoxW() 호출 코드로 바로 이동(아래 사진 참고)
2.4.3 API 검색 방법(1) - 호출 코드에 BP
- Windows 프로그래밍에서 모니터 화면에 무언가를 출력하기 위해서는 Win32 API를 사용해 OS에 화면출력을 요청해야함. → 화면에 무언가를 출력할 시 Win32 API 사용했다는 뜻.
- 예제의 경우, 메시지 박스를 출력하므로 user32.MessageBoxW() API 사용
- 마우스 우측 → Search for → All intermodular calls 명령어 사용
- API 찾아 클릭하여 이동
단, 모든 실행 파일에서 API 호출 목록을 추출할 수 있는 것은 아니다.
2.4.4 API 검색 방법(2) - API 코드에 직접 BP
- 프로그램이 일을 하려면 OS에서 제공된 API를 사용해 OS에 요청해야 하고, 그 API가 실제 구현된 시스템 DLL 파일들은 우리 프로그램의 프로세스 메모리에 로딩되어야함.
- View - Memory (단축키 : [Ait+M]) 사용하여 프로세스 메모리 확인
- USER32 라이브러리 로딩된 것을 확인
- 마우스 우측 → Search for → Name in all modules 명령어 사용하여 DLL 파일이 제공하는 API 목록 확인
- ‘Name’ 정렬 후 MessageBoxW를 타이핑 하여 검색 후 선택
- 스택 윈도우에서 메인 함수 찾기 가능.
- CALL to MessageBoxW from HelloWor.0040100E : MessageBoxW는 40100E주소에서 호출되었으며, 함수 실행이 종료되면 401014 주소로 리턴한다.
- 리턴 주소 401014는 main 함수 내 MessageBoxW 함수 호출 바로 다음 코드.
'리버싱 엔지니어링 > 리버싱 핵심 원리' 카테고리의 다른 글
5 스택 (0) 2022.02.06 2 Hello World! 리버싱(2) - 문자열 패치 (0) 2022.02.06 4 IA-32 Register 기본 설명 (0) 2022.02.06 3 리틀 엔디언 표기법 (0) 2022.02.06 1 리버싱 엔지니어링 (0) 2022.01.07