728x90
1. 문제
1) 문제 확인
그림을 그리고 누르면 틀렸다고 한다. 어떤 그림을 맞추는건가 싶다.
2) 코드흐름 파악
int __stdcall sub_401130(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
HDC v4; // eax
int result; // eax
HGDIOBJ v6; // eax
HDC v7; // esi
void *v8; // esi
HRSRC v9; // eax
HGLOBAL v10; // eax
_BYTE *v11; // eax
signed int v12; // edi
_BYTE *v13; // ecx
int v14; // eax
char pv; // [esp+8h] [ebp-80h]
LONG v16; // [esp+Ch] [ebp-7Ch]
UINT cLines; // [esp+10h] [ebp-78h]
struct tagBITMAPINFO bmi; // [esp+20h] [ebp-68h]
if ( Msg <= 0x111 )
{
if ( Msg != 0x111 )
{
switch ( Msg )
{
case 1u:
v7 = GetDC(hWnd);
hbm = CreateCompatibleBitmap(v7, 200, 150);
hdc = CreateCompatibleDC(v7);
h = SelectObject(hdc, hbm);
Rectangle(hdc, -5, -5, 205, 205);
ReleaseDC(hWnd, v7);
....
case 0xFu:
v4 = BeginPaint(hWnd, (LPPAINTSTRUCT)bmi.bmiColors);
BitBlt(v4, 0, 0, 200, 150, hdc, 0, 0, 0xCC0020u);
EndPaint(hWnd, (const PAINTSTRUCT *)bmi.bmiColors);
return 0;
}
return DefWindowProcA(hWnd, Msg, wParam, lParam);
}
if ( wParam == 100 )
{
GetObjectA(hbm, 24, &pv);
memset(&bmi, 0, 0x28u);
bmi.bmiHeader.biHeight = cLines;
bmi.bmiHeader.biWidth = v16;
bmi.bmiHeader.biSize = 40;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 24;
bmi.bmiHeader.biCompression = 0;
GetDIBits(hdc, (HBITMAP)hbm, 0, cLines, 0, &bmi, 0);
v8 = operator new(bmi.bmiHeader.biSizeImage);
GetDIBits(hdc, (HBITMAP)hbm, 0, cLines, v8, &bmi, 0);
v9 = FindResourceA(0, (LPCSTR)0x65, (LPCSTR)0x18);
v10 = LoadResource(0, v9);
v11 = LockResource(v10);
v12 = 0;
v13 = v8;
v14 = v11 - (_BYTE *)v8;
while ( *v13 == v13[v14] )
{
++v12;
++v13;
if ( v12 >= 90000 )
{
sub_401500(v8);
return 0;
}
}
MessageBoxA(hWnd, Text, Caption, 0x30u); //wrong 출력
sub_401500(v8);
return 0;
}
return 0;
}
...
return result;
}
wrong 문자열을 타고 가보면 어디서 호출되는지 찾을 수 있다. v13==v13[v14]를 루프를 돌면서 확인하는데, 어셈으로 보면 다음과 같다
.text:004013A3 mov dl, [ecx]
.text:004013A5 mov bl, [eax+ecx]
.text:004013A8 cmp dl, bl
.text:004013AA jnz short loc_4013CD
.text:004013AC inc edi
.text:004013AD inc ecx
.text:004013AE cmp edi, 15F90h
.text:004013B4 jl short loc_4013A3
.text:004013B6 push esi ; lpMem
.text:004013B7 call sub_401500
.text:004013BC add esp, 4
.text:004013BF xor eax, eax
.text:004013C1 pop ebx
.text:004013C2 pop edi
.text:004013C3 pop esi
.text:004013C4 add esp, 80h
.text:004013CA retn 10h
ecx와 ecx+eax를 비교하고, edi가 0x15f90인지 비교하는 루프를 돈다. ecx에 어떤값이 들어가는 지 확인하면서 진행하면 될듯싶다.
2. 접근방법
FindResource, LoadResource, LockResource 를 거쳐 esi에 0x4b80048 주소가 저장된다. esi가 곧 ecx에 들어가므로 뭐가 들어있는지 확인해보자
0x4b80048 부터 0x15f90 까지 괴상한 값이 들어가 있다. 이거를 한바이트씩 90000바이트 비교한다. 이는 pe 구조중 리소스 영역에 들어 있는 값이다
3. 풀이
덤프 창에서 shift+C로 0x4b80048 + 90000 까지 복사한다음 bmp 파일로 만들어준다.
또한 비트맵 이미지를 만들때
switch ( Msg )
{
case 1u:
v7 = GetDC(hWnd);
hbm = CreateCompatibleBitmap(v7, 200, 150);
hdc = CreateCompatibleDC(v7);
h = SelectObject(hdc, hbm);
Rectangle(hdc, -5, -5, 205, 205);
ReleaseDC(hWnd, v7);
::wParam = (WPARAM)CreateFontA(12, 0, 0, 0, 400, 0, 0, 0, 0x81u, 0, 0, 0, 0x12u, pszFaceName);
dword_4084E0 = (int)CreateWindowExA(
0,
ClassName,
WindowName,
0x50000000u,
60,
.........
if ( wParam == 100 )
{
GetObjectA(hbm, 24, &pv);
memset(&bmi, 0, 0x28u);
bmi.bmiHeader.biHeight = cLines;
bmi.bmiHeader.biWidth = v16;
bmi.bmiHeader.biSize = 40;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 24;
bmi.bmiHeader.biCompression = 0;
GetDIBits(hdc, (HBITMAP)hbm, 0, cLines, 0, &bmi, 0);
v8 = operator new(bmi.bmiHeader.biSizeImage);
GetDIBits(hdc, (HBITMAP)hbm, 0, cLines, v8, &bmi, 0);
v9 = FindResourceA(0, (LPCSTR)0x65, (LPCSTR)0x18);
v10 = LoadResource(0, v9);
v11 = LockResource(v10);
v12 = 0;
.....
가로 200, 세로 150인 것을 알수 있고 정답이미지는 24bit bmp 파일인 것을 알수있다.
따라서 200X150 bmp 파일을 만들고 리소스로 아까 복사한것을 넣어서 bmp를 만들면된다.
- 42 4D : 시그니처
- C6 5F 01 00 : 파일 전체 사이즈
- 00 00 : 예약 필드
- 00 00
- 36 00 00 00 : 실제 리소스 오프셋
4. 몰랐던 개념
- CreateCompatibleBitmap
- CreateCompatibleDC
728x90
'워게임 > reversing.kr' 카테고리의 다른 글
[reversing.kr] Direct 3D FPS (0) | 2020.12.21 |
---|---|
[reversing.kr] Position (0) | 2020.12.16 |
[reversing.kr] Replace (0) | 2020.12.14 |
[reversing.kr] Music Player.exe (0) | 2020.12.11 |
[reversing.kr] easy elf (0) | 2020.12.10 |
Uploaded by Notion2Tistory v1.1.0