본문 바로가기

Reversing/Dreamhack : Reverse Engineering

[Dreamhack] patch

patch

flag를 그리는 루틴을 분석하고 가려진 flag를 보이게 해주세요.

  • 함수/주소 이동 (g): 입력한 함수, 주소로 이동합니다.
  • 상호참조 (x): 함수, 변수를 사용하는 곳을 찾을 수 있습니다.
  • 브레이크 포인트 (F2): 디버깅 시 중단점을 설정할 수 있습니다.
  • Step Over (F8): 디버깅 시 인스트럭션 하나를 실행합니다. 이 때 함수를 만날 시 해당 함수는 바로 실행합니다.
  • 실행 (F9): 바이너리를 실행합니다. 이 때 실행 도중 중단점을 만나면 멈추게 됩니다.
  • Edit - Patch Program: 바이너리 패치와 관련된 메뉴가 존재합니다.

 

실행

 

 

정적 분석

 

WinMain 함수 찾기

  • WinAPI를 이용해 만들어진 GUI 프로그램이기 때문에 WinMain함수를 찾아야함.
  • WinMain 함수에서는 보편적으로 윈도우를 생성하고 관련된 초기화 작업을 진행

WinMain 함수 분석

 

1. 주요 변수

HCURSOR CursorW;  // 커서 핸들
HWND Window;  // 창 핸들
HWND v8;  // 창 핸들의 복사본
HACCEL AcceleratorsW;  // 단축키(가속기) 핸들
WNDCLASSEXW v11;  // 윈도우 클래스 구조체
struct tagMSG Msg;  // 메시지 구조체

 

 

2. 리소스 로딩

LoadStringW(hInstance, 0x67u, &WindowName, 100);
LoadStringW(hInstance, 0x6Du, &ClassName, 100);
  • LoadStringW을 사용해 WindowName과 ClassName을 로드함.

 

3. 윈도우 클래스 등록

v11.cbSize = 80;  // 구조체 크기 설정
v11.style = 3;  // 윈도우 스타일 (CS_HREDRAW | CS_VREDRAW)
v11.lpfnWndProc = (WNDPROC)sub_1400032F0;  // 윈도우 프로시저 설정
*(_QWORD *)&v11.cbClsExtra = 0LL;  // 추가 메모리 없음
v11.hInstance = hInstance;  // 인스턴스 핸들
v11.hIcon = LoadIconW(hInstance, (LPCWSTR)0x6B);  // 큰 아이콘 로드
CursorW = LoadCursorW(0LL, (LPCWSTR)0x7F00);  // 기본 화살표 커서 로드
  • 보편적으로 메시지 콜백함수에서 윈도우의 동작이 정의되어 있기 때문에 sub_1400032F0 함수를 분석해 어떤 동작을 수행하는지 알아야한다.

4. 윈도우 생성

Window = CreateWindowExW(0, &ClassName, &WindowName, 0xC80000u,
    0x80000000, 0, 600, 200, 0LL, 0LL, hInstance, 0LL);
  • CreateWindowExW를 사용하여 창을 생성합니다.
  • 0xC80000u → WS_VISIBLE | WS_OVERLAPPEDWINDOW 스타일 (표준 창 + 표시됨)
  • 0x80000000 → CW_USEDEFAULT를 의미하는 값 (위치를 기본값으로 설정)
  • 600, 200 → 창의 너비와 높이
  • 0LL, 0LL → 부모 윈도우와 메뉴 없음
  • 성공하면 Window에 창 핸들이 저장된다.
v8 = Window;
if ( Window )
  • 창이 정상적으로 생성되었는지 확인

 

5. GDI+ 초기화

hWnd = Window;
dword_140007920 = 600;
dword_140007924 = 200;
GdiplusStartup(&unk_1400078A0, &dword_1400078A8, 0LL);

 

6. 창 표시 및 메시지 루프

ShowWindow(v8, nShowCmd);
UpdateWindow(v8);

 

sub_1400032F0 분석

  • switch case 구문 내에 총 세 개의 case가 존재함
  • 0xFu에 해당하는 case에서 BeginPaint와 EndPaint함수를 볼 수 있음 → 이 사이에서 플래그를 출력할 것임.
  • BeginPaint와 EndPaint 사이에 있는 sub_140002C40함수를 분석해보자.

 

sub_140002C40 분석

  • 반복적으로 무언갈 그리는 것으로 추측됨.

 

sub_14002870

  • 펜을 생성하고 선을 그리는 함수임을 알 수 있음.

 

동적 분석

F2 → 브레이크 포인트 설정

F9 → 디버깅 시작

F8 → Step Over

  • sub_140002B80 함수가 플래그를 가리는 선을 그리는 함수임을 확신할 수 있음.

 

바이너리 패치

 

Edit - Patch Program - Assemble

 

→ 함수가 선을 그리지 않고 그대로 반환하도록 패치해야 하기 때문에 인스트럭션 입력 칸에 함수를 바로 리턴하도록 ret 인스트럭션을 입력

 

Edit - Patch Program - Apply patches to input file… : 패치한 내용을 실제 바이너리에 적용



'Reversing > Dreamhack : Reverse Engineering' 카테고리의 다른 글

[Dreamhack] rev-basic-1  (0) 2025.04.21
[Dreamhack] rev-basic-0  (0) 2025.04.21
IDA  (0) 2025.04.16
Quiz: x86 Assembly 2-3  (0) 2025.04.16
Quiz: x86 Assembly 1  (0) 2025.04.16