chon

Helloworld.exe 분석 및 바이너리 패치 실습 본문

Reversing

Helloworld.exe 분석 및 바이너리 패치 실습

chon29 2025. 11. 22. 18:00

리버싱을 시작하기 전, 프로그램이 메모리에 적재될 때의 구조와 컴파일러별 특징을 이해해야 한다.

 

[ 실습 파일 ] Helloworld.exe

HelloWorld.exe
0.10MB

 

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)

프로그램이 실행 중인 상태(메모리)에서 데이터를 바꾸는 실습이다.

  1. 덤프 창에서 문자열이 위치한 주소(404000)로 이동한다. (Ctrl+G 또는 덤프에서 따라가기)
  2. 바꾸고 싶은 문자열 영역을 드래그한다.
  3. 바이너리 편집(Binary Edit) 기능을 이용해 원하는 문자열로 덮어쓴다.
    • 주의: 원본 문자열 길이보다 길게 쓰면 뒤의 데이터를 침범할 수 있으므로 주의!
  4. 프로그램을 계속 실행(F9)하면 바뀐 메시지 박스가 출력된다.

MessageBox()

 

(이미지: 덤프 창에서 문자열 편집하는 화면)

3) 파일 영구 변조 (File Patch) 메모리만 바꾸면 재실행 시 원상 복구된다. 실행 파일 자체를 변경하려면 추가 작업이 필요하다.

  1. 수정한 코드나 데이터 영역에서 우클릭 > 파일 패치 > 모든 수정 내용 선택
  2. 나타나는 창에서 파일 패치(Patch File) 버튼을 눌러 .exe 파일로 저장한다.
  3. 이제 파일을 새로 실행해도 변경된 내용이 적용된다.

(이미지: 파일 패치 저장 화면)


리버싱 분석 프로세스 정리

리버싱을 진행할 때 다음과 같은 순서를 따르면 효율적이다.

  1. 일단 실행 (Run): 프로그램의 표면적인 동작 확인 (악성코드라면 가상머신/샌드박스 + Wireshark 활용).
  2. 정보 수집 (Info Gathering):
    • 문자열 검색 (String Search)
    • API 호출 검색 (Import Functions, IAT)
  3. 정적/동적 분석:
    • 의심가는 문자열이나 API 호출 지점으로 이동.
    • 스택(Stack)을 확인하여 함수에 전달되는 인자 파악.
    • 제어 흐름 분석 및 디버깅.
  4. 패치 및 검증:
    • 원하는 로직이나 데이터를 덤프(Dump) 또는 어셈블리 창에서 수정
    • 파일 패치로 저장하여 결과 확인

'Reversing' 카테고리의 다른 글

컴퓨터 명령어 처리구조  (0) 2025.11.21
X64DBG 디버거 설치 및 사용 방법  (0) 2025.11.20