HelloWorld.cpp
-> HelloWorld.exe
실행파일 생성개발 도구를 이용해서 소스코드(.cpp) -> 기계어(.exe)
디버거에 탑재된 디스어셈블러 모듈을 사용해서 기계어 -> 어셈블리 언어
어떤 프로그래밍 언어로 생성되더라도 실행파일을 빌드하면 모두 기계어로 변환됨
main()
함수 찾기화면 구성 | 설명 |
---|---|
Code Window | 기본적으로 disassembly code를 표시하여 각종 comment, label을 보여주며, 코드를 분석하여 loop, jump 위치 등의 정보를 표시 |
Register Window | CPU register 값을 실시간으로 표시하며 특정 register들은 수정도 가능 |
Dump Window | 프로세스에서 원하는 memory 주소 위치를 Hex와 ASCII/유니코드 값으로 표시하고 수정도 가능 |
Stack Window | ESP register가 가리키는 프로세스 stack memory를 실시간으로 표시하고 수정도 가능 |
EP(Entry Point)
EP란 Windows 실행 파일(EXE, DLL, SYS 등)의 코드 시작점을 의미.
프로그램이 실행될 때 CPU에 의해 가장 먼저 실행되는 코드 시작 위치
HelloWorld.exe
파일을 OllyDbg로 열어보면 디버거가 해당 파일의 EP인 4011A0
에 멈춘 것을 볼 수 있음40270
C 주소의 함수를 호출(CALL)한 후 40104F
주소로 점프(JUMP)하라"명령어 | 단축키 | 설명 |
---|---|---|
Restart | [Ctrl+F2] | 다시 처음부터 디버깅 시작(디버깅을 당하는 프로세스를 종료하고 재실행) |
Step Into | [F7] | 하나의 OP code실행(CALL 명령을 만나면, 그 함수 코드 내부로 따라 들어감) |
Step Over | [F8] | 하나의 OP code실행(CALL 명령을 만나면, 따라 들어가지 않고 그냥 함수 자체를 실행) |
Execute till Return | [Ctrl+9] | 함수 코드 내에서 RETN 명령어까지 실행(함수 탈출 목적) |
4011A0
에서 [F7]를 눌러 40270C
함수 안으로 들어가면 다음과 같음
오른쪽의 주석에서 빨간색 글씨는 코드에서 호출되는 API 함수 이름인데, 원본 소스코드에서 사용된 적 없는 API들임.
-> 해당 함수는 우리가 찾던 main()
함수가 아님!
사실 Visual C++에서 프로그램 실행을 위해서 추가한 Visual C++ Stub Code
임.
[F8] 또는 [Ctrl+F9]를 사용해서 RETN 명령어가 있는 4027A1
까지 가기
-> RETN 명령어 실행하면 이 함수 안으로 들어오기 전에 봤던 4011A5
로 감
4011A5
주소에서 JMP 0040104F
를 실행main()
가 있을 것임!!0040104F
부터 CALL 함수 다 들어가보고 main() 함수 찾기40105B
)4010E4
주소의 CALL Kernel32.GetCommandLineW
명령어는 Win32 API 호출 코드임(여기서는 필요없음. 참고하기)401144
주소에서 CALL 00401000
실행하여 해당 함수로 들어감401000
함수 = 우리가 찾던 main() 함수!!40104F
)를 기억해 두었다가 [Ctrl+G] 명령어로 이동Packer/Protextor를 사용해서 실행 파일을 압축(/보호)해버리면 파일 구조가 변경되어 OllyDbg에서 API 호출 목록 조회 불가능할 경우 있음
- Packer(Run Time Packer): 실행 압축 유틸리지. 실행 파일의 코드, 데이터, 리소스 등을 압축시킴. 일반 압축 파일과 다른 점은 실행 압축된 파일 그 자체도 실행 파일이라는 것
- Protector: 실행 압축 기능 외에 파일과 그 프로세스를 보호하려는 목적으로 anti-debugging, anti-emulating, anti-dump 등의 기능을 추가한 유틸리티. Protector를 상세 분석하려면 높은 수준의 리버싱 지식 요구됨
- 장점: 사용하기에 가장 간단함
- 단점: 기존 문자열 버퍼 크기 이상의 문자 입력하기 어려움(제약 조건) -> 권장하지 않는 방법
덤프 창에서 [Ctrl+G] 단축키 이용해서 4092A0
주로로 이동
[Ctrl+E] 단축키 이용해서 "Hello World!" 유니코드 문자열이 차지하는 영역을 새로운 문자열로 덮어씀
다시 main() 함수(401000
)로 들어가서 보면 명령어나 파라미터 주소는 그대로지만 전달되는 파라미터 내용이 바뀐 것을 확인할 수 있음
[F9]를 눌러서 실행해보면 메시지 박스에 패치된 문자열("Hello Reversing")이 잘 출력되고 있음
[파일로 저장하기]
4092A0
주소에 저장된 문자열을 파라미터로 전달하고 있음MessageBox()
함수는 파라미터로 입력된 주소의 문자열을 출력하고 있음MessageBox()
에 넘겨주는 주소를 변경하면 됨(지금은 간단한 실습이므로) 임의로 프로그램에서 사용되지 않는 NULL padding 영역에 새로운 문자 패치
[Space] 단축키 이용해서 main() 함수의 401007
주소에서 MessageBox()
함수에 넘겨줄 새로운 버퍼 주소 입력
[F9]로 실행해보면 변경된 문자열이 출력되는 것을 확인 가능