ImagePcr

The program compares a drawing against a bitmap held in its resources; the flag is the image it expects.

2026.08.18 Reversing original post

프로그램을 실행해보자! 그림을 그리고 검사를 받는다. 아무렇게나 그림을 그려 넣으면, Wrong! 탈락한것같다.

Figure 1

X32dbg 로 먼저 열어 본다. 문자열 찾기에서 Wrong을 사용하는 주소로 가본다. 일단 GetDIBits 로 비트맵이미지를 가 져온다. 아마 내가 그린 그림이다! 그리고 FindResourceA, LoadResource 로 비교할 파일을 가져온다. 비트하나씩 비교 해서, 틀리면 바로 Wrong 을 출력하는것같다. 그렇다면, 그 파일에 정답이 있을거다!

Figure 2

Figure 3

PE Viewer 로 열어봤는데, rsrc 섹션에, 리소스데이터가있다. 정답 이미지의 파일을 위에 정보들로 알아낼수있다.

Figure 4

0960 (f 가 시작하는곳)~ (0960 + 15FF0)

비트맵이미지파일이다. 밑으로 쭉 내려보니까 중간에 00 도 있다는걸 확인했다. 그러기위해선, 높이와 너비를 알아야한 다. 다시 코드를 분석해보자. 주변 위에를 찾아보니까 GetDIBits 가있다. GetDIBits는 비트맵(Bitmap)의 실제 픽셀 데이터를 메모리 버퍼로 가져오는 Windows GDI API이다.

Figure 5

push edx, getDiBits 주소의 hex 값을 (첫번째 줄) 보면 데이터들을 볼수있다 BITMAPINFOHEADER 구조체 (정석) typedef struct tagBITMAPINFOHEADER { DWORD biSize; // 0x00 LONG

biWidth; // 0x04 LONG biHeight; // 0x08 WORD biPlanes; // 0x0C WORD biBitCount; // 0x0E }
BITMAPINFOHEADER;

이걸 정리하면:

Offset HEX Size 필드 의미 값

+0x00 28 00 00 00 4B (DWORD) biSize 구조체 크기 0x28 = 40 bytes

+0x04 c8 00 00 00 4B (LONG) biWidth 가로 픽셀 0xC8 = 200 px

+0x08 96 00 00 00 4B (LONG) biHeight 세로 픽셀 0x96 = 150 px

+0x0C 01 00 2B (WORD) biPlanes 플레인 수 1 (고정값)

+0x0E 18 00 2B (WORD) biBitCount 색 깊이 0x18 = 24 bit

이 정보들을 가지고 그림판에서 비트맵을 만든다. (24 비트 맵으로 저장해야함; 픽셀 사이즈도 맞추고). 이제 비트 맵의 내 용을 채워 플래그 (답 이미지) 를 볼 차례다. 헥스 에디터에 ImagePcr.exe 파일과 그리고 bmp 파일을 열어준다. 아까 구 한 오프셋으로 ImagePcr.exe 에서 원하는 핵스 부분을 추출한다.

Figure 6

카피엔 페이스트한 다음에 헤더가 끝나고 바디가 시작하는 주소인 0x36 에 클릭후 페이스트 해준다. (딱맞는다)

Figure 7

이렇게 저장 후 bmp 파일을 열어주면 플래그를 볼수있다.

Figure 8

모자이크 처리함!