ImagePcr
The program compares a drawing against a bitmap held in its resources; the flag is the image it expects.
프로그램을 실행해보자! 그림을 그리고 검사를 받는다. 아무렇게나 그림을 그려 넣으면, Wrong! 탈락한것같다.

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


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

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

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 에서 원하는 핵스 부분을 추출한다.

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

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

모자이크 처리함!