본문 바로가기

Reverse Engineering

dreamhack : patch write-up

728x90

⭐⭐실습을 통해 개념 정리하기 ⭐⭐ 

https://dreamhack.io/wargame/challenges/49/

 

patch

flag를 그리는 루틴을 분석하고 가려진 flag를 보이게 해주세요. Reference GDI+ - Win32 apps | Microsoft Docs Graphics Functions - Win32 apps | Microsoft Docs File — x64dbg documentation

dreamhack.io

 

압축파일 안에는 실행파일(patch.exe)가 있는데 이것을 실행하면?

다음과 같이 나온다.

 

이것을 IDA에서 실행

 

정적 분석

step1. WinMain 함수 찾기

patch.exe는 WinAPI를 이용해 만들어진 GUI 프로그램이기 때문에 WinMain함수를 찾아야함..

 

메인함수 직접 찾아보기 -> Import 탭에서 CreateWindowExW 함수 이름 더블클릭해서 함수가 임포트되는 곳으로 이동

-> 단축키 x를 이용해 CreateWindowExW 함수가 사용되는 곳을 보면 WinMain함수에서 사용하고 있음을 파악할 수 있다!

 

step2. WinMain 함수 분석

위에서 f5(디컴파일 단축키)를 누르면

WinMain 함수를 볼 수 있음. 

RegisterClassExW 함수는 윈도우 클래스를 등록하는 함수이며, 인자로 v11 변수가 들어감을 확인가능

중요 point는 윈도우의 메시지 콜백을 설정하는 부분인 14라인임.

 

메시지 콜백함수에서 윈도우의 동작이 정의되어 있음 -> sub_1400032F0함수 분석

 

switch case 구문 내에 총 세개의 case(2u, 0xFu, 0x202u)가 존재

case 0xFu:

  - Paint와 관련된 역할


출처: Microsoft > learn > Windows > 앱 > Win32 > API > Windows GDI > Winuser.h(PaintStruct 구조체)  

💡Paint? 

      PaintStruct 구조체에는 애플리케이션에 대한 정보가 포함되어있는데, 이 정보는 해당 애플리케이션이 소유한 창의 클        라이언트 영역을 그리는데 사용가능.

 * 구문 *  

typedef struct tagPAINTSTRUCT {
  HDC  hdc;
  BOOL fErase;
  RECT rcPaint;
  BOOL fRestore;
  BOOL fIncUpdate;
  BYTE rgbReserved[32];
} PAINTSTRUCT, *PPAINTSTRUCT, *NPPAINTSTRUCT, *LPPAINTSTRUCT;

 * 멤버 *

  1. hdc = 그리는 데 사용할 디스플레이 DC에 대한 핸들.
  2. fErase = 배경을 지워야 하는지 여부를 나타냄. 애플리케이션이 배경을 지워야 하는 경우 0이 아닌 값이 된다. 애플리케이션은 백그라운드 브러시 없이 창 클래스를 만드는 경우 배경을 지워짐.
  3. rcPaint = 그리기를 요청하는 사각형의 왼쪽 위와 오른쪽 위 모서리를 클라이언트 영역의 왼쪽 위 모서리를 기준으로 하는 디바이스 단위로 지정하는 RECT 구조체
  4. fRestore = 예약; 시스템에서 내부적으로 사용됨
  5. fIncUpdate = 예약; 시스템에서 내부적으로 사용됨.
  6. rgbReserved[32] = 예약; 시스템에서 내부적으로 사용됨.

 

   - BeginPaint 함수와 EndPaint 함수 사이에서 플래그를 출력해 줄 것이기 때문에 가운데 있는 sub_140002C40 함수 분석해야함.

 

디컴파일된 sub_140002C40 함수 일부

51번째 줄 ~ 75번째 줄은 sub_140002B80함수 호출

나머지는 각기 다른 함수를 호출

 

추측해보자면! 

sub_140002B80함수는 같은 함수가 연속적으로 호출되는 것으로 보아 무언가 반복적인 형태를 그리는 것으로 추측가능

GdipCreatePen1 함수 -> 펜 생성

GdipDrawLine1 함수 -> 선을 하나 그림

 

sub_140002B80함수에서 그 밑에 나머지 호출되는 함수 중 sub_1400017A0 함수와 비교해보면

sub_1400017A0함수에서는 펜을 생성 후 여러 개의 선을 그리는 것으로 추측가능

 

동적분석

메시지 콜백 함수 디버깅

왼쪽 사진은 메시지 콜백 함수에 브레이크 포인트 건 상태(F2 사용)

오른쪽 사진은 프로그램 실행(F9)

 

F8(Step Over) 단축키를 눌려 함수를 실행 후 프로그램에 어떤 변화가 있는지 확인하는 과정

디버깅 중일때는 프로그램의 모든 동작이 멈춰있는 상태이기 때문에 프로그램 윈도우 창을 띄울 수 없음

이럴 때에는 Alt+Tab을 누른 상태로 윈도우에 어떤 변화가 생겼는지 확인하는 방식으로 프로그램의 변화를 확인할 것!!

1.

 따라서 sub_140002B80 함수는 플래그를 가리는 선을 그리는 함수으로 볼 수 있다.

 선을 그리는 함수가 실행되지 않도록 바이너리를 직접 패치해야할 것!!

 

Step3. 바이너리 패치 - 함수 패치

함수 패치 방법 : Edit - Patch Program 메뉴에서 Assemble 기능을 이용 (bp 걸고 실행중에 해야 클릭이 됨!)

이 함수가 선을 그리지 않고 그대로 반환하도록 ret 인스트럭션을 입력하고 OK하면 위에 사진처럼 나옴

패치한 내용을 실제 바이너리에 적용하기 위해 Edit - Patch Program - APply patches to input file... 메뉴 클릭

적용 창에서 아무것도 변경하지 않고 ok 누르면 바이너리 패치가 실제 파일에 적용됨

 

오류생겨 잠시 중단

하,,,,;;;ㅅ...

 

아아 문제 해결쓰

여기서 Tab키를 누른다

그러면 위와 같은 박스가 나오는데 거기서 저기 위에 나온 함수 패치 사용법 하면 assemble을 이용할 수 있음!

해주면?

ret으로 인스트럭션

 

apply 뭐시기하고 디버깅 실행하면?

해결! 플래그 얻기 성공

휴,,, 이틀만에 함수 패치때문에 고생쓰ㅠ

 

 

쓸모있는 단축키⭐

Ctrl + F2 : 디버깅 종료

'Reverse Engineering' 카테고리의 다른 글

dreamhack : simple-operation write-up  (0) 2024.05.13
dreamhack : rev-basic-3 write-up  (0) 2024.05.13
dreamhack : rev-basic-1 write-up  (0) 2024.05.03
Windows Memory Layout  (0) 2024.05.02
Computer Architecture(컴퓨터 구조)  (0) 2024.04.29