본문 바로가기

Reverse Engineering/Wargame

Dreamhack : patch

문제 링크

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

 

풀이

 

기존의 exe 파일을 실행하면 아래와 같다. 

 

그림 1

 

검은색의 박스가 정답 flag를 가리고 있다는 생각이 든다. 그렇다면 해당 검정 박스를 그리는 로직이 코드 내에 있을 것이고, 아래에서 살펴보도록 한다. 

 

그림 2

 

0FF000000h 는 ARGB 형식으로 완전 불투명한 검정을 의미한다. 

 

참고 (ARGB)

 

그림 3

 

해당 Hex 값을 00 00 FF FF 로 변경한다면, 위 검정 사각형의 선이 아래와 같이 빨간색으로 변경된다. 

 

그림 4

 

이제 flag를 가리는 사각형의 색깔을 변경할 수 있다는 것을 알았으니, 투명하게 00 00 00 00으로 변경해 준다. 아래 그림 5를 보면, 점점 flag가 보이는 것을 볼 수 있다. 

 

 

그림 5

 

단, sub_140002B80 함수가 검정 사각형을 그리는 함수이므로, 해당 부분에 해당하는 검정 값만 투명하게 변경해 준다. 아래 그림 6을 보면, 각각 알파벳을 그리는 함수가 존재함을 색깔을 바꿈으로써 알 수 있었다. 

 

 

그림 6

 

 

다른 방법 (풀이)

 

더보기

IDA 디버깅 과정에서 Ctrl + n을 통해 함수를 건너뛰는 방법이 있다는 것을 알게되었고, 아래와 같이 활용이 가능하다. 

 

 

원래는 검정 사각형을 그리는 ( 더 정확히는 검정 선을 그리는 ) sub_7FF623712B80 함수를 실행해야지만, Flag 문자를 그리는 함수에 해당하는 부분으로 건너뛰어 준다.  

 

 

 

 

 

 

 

 

 

 

 

 

 

참고

 

Window API 아직은 무엇인지 잘 모르지만, 아래에 정리해보았다.

 

더보기

https://learn.microsoft.com/ko-kr/windows/win32/api/winuser/nf-winuser-loadstringw 

 

LoadStringW 함수(winuser.h) - Win32 apps

지정된 모듈과 연결된 실행 파일에서 문자열 리소스를 로드하고, 문자열을 버퍼에 복사하고, 종료 null 문자를 추가합니다. (유니코드)

learn.microsoft.com

 

LoadStringW 함수

 

지정된 모듈과 연결된 실행 파일에서 문자열 리소스를 로드하고 문자열을 종료 null 문자가 있는 버퍼에 복사하거나 문자열 리소스 자체에 대한 읽기 전용 포인터를 반환

 

 LoadIconW 함수 (해당 함수는 LoadImage 함수로 대체되었다고 한다.)

 

애플리케이션 인스턴스와 연결된 실행 파일(.exe) 파일에서 지정된 아이콘 리소스를 로드

 

LoadCursorW 함수

애플리케이션 인스턴스와 연결된 실행 파일(.exe) 파일에서 지정된 커서 리소스를 로드

 

CUSOR 리소스

디스플레이 화면의 커서 모양 또는 애니메이션 커서를 정의하는 비트맵을 정의

 

RegisterClassExW 함수

CreateWindow 또는 CreateWindowEx 함수에 대한 호출에서 후속 사용을 위해 창 클래스를 등록

 

창 클래스

창 클래스는 시스템에서 창을 만들기 위해 템플릿으로 사용하는 특성 집합

 

CreateWindowA 매크로

겹치는 팝업 또는 자식 창을 만든다. 창 클래스, 창 제목, 창 스타일 및 창의 초기 위치 및 크기를 지정(선택 사항). 또한 이 함수는 창의 부모 또는 소유자(있는 경우)와 창 메뉴를 지정.

 

CreateWindow 지원하는 스타일 외에도 확장 창 스타일을 사용하려면 CreateWindowEx 함수를 사용.

 

CreateWindowExA 함수

확장 창 스타일을 사용하여 겹치는, 팝업 또는 자식 창을 만든다.

 

CreateWindowExW 함수

확장 창 스타일을 사용하여 겹치는, 팝업 또는 자식 창을 만든다.

 

CreateWindowExA 함수 와 CreateWindowExA 의 차이

두 함수는 서로 기능은 거의 동일하지만, 문자 인코딩 방식의 차이가 있어 서로 다른 함수이다. 

 

함수 이름 문자 인코딩 설명
CreateWindowExA ANSI 구버전/레거시. 멀티바이트 문자열 사용 (char*)
CreateWindowExW Wide (UTF-16) 유니코드 지원. wchar_t* 타입 사용

 

GdiplusStartup 함수

GdiplusStartup 함수는 Windows GDI+를 초기화. 다른 GDI+ 호출을 하기 전에 GdiplusStartup 을 호출하고 GDI+를 사용한 후 GdiplusShutdown 을 호출

 

Windows GDI

Microsoft Windows GDI(그래픽 디바이스 인터페이스)를 사용하면 애플리케이션에서 비디오 디스플레이와 프린터 모두에서 그래픽 및 서식이 지정된 텍스트를 사용할 수 있다. Windows 기반 애플리케이션은 그래픽 하드웨어에 직접 액세스하지 않는다. 대신 GDI는 애플리케이션을 대신하여 디바이스 드라이버와 상호 작용

 

showWindow 함수

지정된 창의 표시 상태를 설정

BOOL ShowWindow(
  [in] HWND hWnd,
  [in] int  nCmdShow
);

 

[in] hWnd : 형식: HWND : 창에 대한 핸들

 

[in] nCmdShow : 형식: int : 창을 표시하는 방법을 제어한다. 애플리케이션을 시작한 프로그램이 STARTUPINFO 구조를 제공하는 경우 이 매개 변수는 애플리케이션이 ShowWindow를 처음 호출할 때 무시된다. 그렇지 않으면 ShowWindow가 처음 호출될 때 값은 해당 nCmdShow 매개 변수에서 WinMain 함수에서 가져온 값이어야한다.

 

UpdateWindow 함수

UpdateWindow 함수는 창의 업데이트 영역이 비어 있지 않은 경우 창에 WM_PAINT 메시지를 보내 지정된 창의 클라이언트 영역을 업데이트한다. 함수는 애플리케이션 큐를 우회하여 지정된 창의 창 프로시저로 직접 WM_PAINT 메시지를 보낸다. 업데이트 지역이 비어 있으면 메시지가 전송되지 않는다.

 

WM_PAINT 메시지

시스템 또는 다른 애플리케이션이 애플리케이션 창의 일부를 그리도록 요청할 때 WM_PAINT 메시지가 전송되어진다. UpdateWindow 또는 RedrawWindow 함수가 호출될 때 또는 애플리케이션이 GetMessage 또는 PeekMessage 함수를 사용하여 WM_PAINT 메시지를 가져올 때 DispatchMessage 함수에 의해 메시지가 전송되어진다. 

 

LoadAcceleratorsW 함수

지정된 엑셀러레이터 테이블을 로드

 

Accelerator Table

특정 키 조합(단축키)이 눌렸을 때, 그것을 특정 명령(MENU 명령 등)으로 자동 매핑해주는 Windows 리소스

(예시) Ctrl + S를 누르면, 자동으로 ID_FILE_SAVE 명령이 전달

 

GetMessageW 함수

호출 스레드의 메시지 큐에서 메시지를 검색. 함수는 게시된 메시지를 검색할 수 있을 때까지 들어오는 보낸 메시지를 디스패치

 

TranslateAcceleratorW 함수

메뉴 명령에 대한 가속기 키를 처리. 이 함수는 WM_KEYDOWN 또는 WM_SYSKEYDOWN 메시지를 WM_COMMAND 또는 WM_SYSCOMMAND 메시지(지정된 액셀러레이터 테이블에 키 항목이 있는 경우)로 변환한 다음 WM_COMMAND 또는 WM_SYSCOMMAND 메시지를 지정된 창 프로시저로 직접 보낸다.

 

TranslateMessage 함수

가상 키 메시지를 문자 메시지로 변환. 문자 메시지는 다음에 스레드가 GetMessage 또는 PeekMessage 함수를 호출할 때 읽을 호출 스레드의 메시지 큐에 게시

 

DispatchMessageW 함수

창 프로시저에 메시지를 디스패치 한다. 일반적으로 GetMessage 함수에서 검색한 메시지를 디스패치하는데 사용.

 

조금 더 쉽게, 메시지 구조체(MSG)에 담긴 메시지를 해당 윈도우의 프로시저 함수(WndProc)에 전달하는 일을 말한다.

 

PostQuitMessage 함수

스레드가 종료를 요청했음을 시스템에 나타낸다. 일반적으로 WM_DESTROY 메시지에 대한 응답으로 사용

 

BeginPaint 함수

해당 함수는 그리기 위해 지정된 창을 준비하고 그림에 대한 정보로 PAINTSTRUCT 구조를 채움.

 

EndPaint 함수

해당 함수는 지정된 창에서 그리기 끝을 표시한다. 이 함수는 BeginPaint 함수를 호출할 때마다 필요하지만 그리기 완료된 후에만 필요.

 

InvalidateRect 함수

InvalidateRect 함수는 지정된 창의 업데이트 영역에 사각형을 추가. 업데이트 지역은 다시 그려야 하는 창의 클라이언트 영역 부분을 나타