Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | |||||
| 3 | 4 | 5 | 6 | 7 | 8 | 9 |
| 10 | 11 | 12 | 13 | 14 | 15 | 16 |
| 17 | 18 | 19 | 20 | 21 | 22 | 23 |
| 24 | 25 | 26 | 27 | 28 | 29 | 30 |
| 31 |
Tags
- Juice Shop
- OpenClaw
- ADsP합격
- rev-basic-3
- 시나공ADsP
- 운영체제
- 세그먼테이션
- adsp독학
- OS
- user pool
- ADsP교재
- AWS
- randzzz
- ADsP
- HRRN
- 26년 1회
- 교체 정책
- rev-basic-4
- id pool
- writeup
- Simple Crack Me
- Pacu
- dreamhack
- cloudgoat
- wargame
- ADsP책추천
- OWASP TOP 10
- ADsP시험
- 병행성
- 라운드로빈
Archives
- Today
- Total
chon
Helloworld.exe 분석 및 바이너리 패치 실습 본문
리버싱을 시작하기 전, 프로그램이 메모리에 적재될 때의 구조와 컴파일러별 특징을 이해해야 한다.
[ 실습 파일 ] Helloworld.exe
1. 사전 지식: 메모리 구조와 컴파일러 특성
[ 컴파일러별 스택 프레임 처리 차이 ]
- Visual C++ 계열: 주로 EBP를 베이스 포인터로 사용하여 스택 프레임을 형성 (push ebp, mov ebp, esp)
- GCC / Dev-C++ 계열: 최적화 옵션에 따라 ESP를 직접 조작하여 변수에 접근하는 방식을 많이 사용 (mov dword ptr [esp+4], 값)
- 이번 실습 파일은 Dev-C++ 형태의 구조(ESP 활용)를 가짐
[ 프로세스 메모리 세그먼트 구조 ]
메모리의 높은 주소(High Address)에서 낮은 주소(Low Address)로의 구조는 다음과 같다.
(표 삽입)
2. 정보 수집 (Static Analysis)
리버싱의 첫 단계는 실행하지 않고 파일의 정보를 캐내는 것이다.
1) 문자열 검색 (String Search)


- 디버거 기능: 우클릭 > 다음을 찾기 > 현재 모듈
- 데이터 세그먼트(.data, .rdata)에 존재하는 문자열들을 확인할 수 있다.
- 실습 확인: 404000 번지 근처에서 "Welcome Message", "Hello World!!" 등의 문자열 발견
2) API 호출 검색 (Inter-modular Calls)


- 디버거 기능: 우클릭 > 다음을 찾기 > 현재 모듈 > 모듈 간 호출
- 프로그램이 운영체제 기능을 빌려 쓰는 API(MessageBox 등)를 확인하여 동작을 유추한다.
- 주의: printf 등은 MSVCRT에 있지만, MessageBox 계열 함수는 User32.dll 라이브러리에 있다.
3. 코드 분석 (Code Analysis)
진입점(Entry Point) 근처의 메인 로직을 분석한다.
[ 어셈블리 코드 분석 ]

00401520 | 55 | push ebp
00401521 | 89 | mov ebp,esp
00401523 | 83 | sub esp,18 | 스택 공간 0x18(24 byte) 확보
00401526 | C7 | mov dword ptr ss:[esp+C], 0 | 변수 초기화
0040152E | C7 | mov dword ptr ss:[esp+8], helloworld.404000 | [Arg3] Title: "Welcome Message"
00401536 | C7 | mov dword ptr ss:[esp+4], helloworld.404010 | [Arg2] Text: "Hello World!!"
0040153E | C7 | mov dword ptr ss:[esp], 0 | [Arg1] hWnd: NULL
00401545 | A1 | mov eax, dword ptr ds:[<MessageBoxA>] | MessageBoxA 주소 가져오기
0040154A | FF | call eax | 함수 호출
0040154C | 83 | sub esp, 10
0040154F | B8 | mov eax, 0
00401554 | C9 | leave
00401555 | C2 | ret 10
- 함수 호출 규약: push 명령어로 파라미터를 넣는 대신, [esp+Offset] 위치에 값을 직접 넣고 함수를 호출하는 GCC 스타일을 볼 수 있다.
- MessageBoxA 파라미터: 총 4개의 인자(NULL, Text, Title, Type)가 들어간다.

4. 디버깅 및 바이너리 패치 (Dynamic Analysis & Patching)
1) 디버거 단축키 사용법
- F2: 중단점(Break Point) 설정/해제
- F4: 커서가 위치한 곳까지 실행 (Run to cursor)
2) 메모리 내 데이터 변조 (Memory Patch)
프로그램이 실행 중인 상태(메모리)에서 데이터를 바꾸는 실습이다.
- 덤프 창에서 문자열이 위치한 주소(404000)로 이동한다. (Ctrl+G 또는 덤프에서 따라가기)
- 바꾸고 싶은 문자열 영역을 드래그한다.
- 바이너리 편집(Binary Edit) 기능을 이용해 원하는 문자열로 덮어쓴다.
- 주의: 원본 문자열 길이보다 길게 쓰면 뒤의 데이터를 침범할 수 있으므로 주의!
- 프로그램을 계속 실행(F9)하면 바뀐 메시지 박스가 출력된다.

(이미지: 덤프 창에서 문자열 편집하는 화면)
3) 파일 영구 변조 (File Patch) 메모리만 바꾸면 재실행 시 원상 복구된다. 실행 파일 자체를 변경하려면 추가 작업이 필요하다.
- 수정한 코드나 데이터 영역에서 우클릭 > 파일 패치 > 모든 수정 내용 선택
- 나타나는 창에서 파일 패치(Patch File) 버튼을 눌러 .exe 파일로 저장한다.
- 이제 파일을 새로 실행해도 변경된 내용이 적용된다.
(이미지: 파일 패치 저장 화면)
리버싱 분석 프로세스 정리
리버싱을 진행할 때 다음과 같은 순서를 따르면 효율적이다.
- 일단 실행 (Run): 프로그램의 표면적인 동작 확인 (악성코드라면 가상머신/샌드박스 + Wireshark 활용).
- 정보 수집 (Info Gathering):
- 문자열 검색 (String Search)
- API 호출 검색 (Import Functions, IAT)
- 정적/동적 분석:
- 의심가는 문자열이나 API 호출 지점으로 이동.
- 스택(Stack)을 확인하여 함수에 전달되는 인자 파악.
- 제어 흐름 분석 및 디버깅.
- 패치 및 검증:
- 원하는 로직이나 데이터를 덤프(Dump) 또는 어셈블리 창에서 수정
- 파일 패치로 저장하여 결과 확인
'Reversing' 카테고리의 다른 글
| 컴퓨터 명령어 처리구조 (0) | 2025.11.21 |
|---|---|
| X64DBG 디버거 설치 및 사용 방법 (0) | 2025.11.20 |