ssongk
ssongk
ssongk
전체 방문자
오늘
어제

공지사항

  • resources
  • 분류 전체보기 (626)
    • CTF (24)
    • background (79)
      • fuzzing (5)
      • linux (29)
      • linux kernel (15)
      • windows (2)
      • web assembly (1)
      • embedded (0)
      • web (13)
      • crypto (9)
      • mobile (1)
      • AI (1)
      • etc.. (3)
    • write-up(pwn) (171)
      • dreamhack (102)
      • pwn.college (4)
      • pwnable.xyz (51)
      • pwnable.tw (3)
      • pwnable.kr (5)
      • G04T (6)
    • write-up(rev) (32)
      • dreamhack (24)
      • reversing.kr (8)
    • write-up(web) (195)
      • dreamhack (63)
      • LOS (40)
      • webhacking.kr (69)
      • websec.fr (3)
      • wargame.kr (6)
      • webgoat (1)
      • G04T (7)
      • suninatas (6)
    • write-up(crypto) (19)
      • dreamhack (16)
      • G04T (1)
      • suninatas (2)
    • write-up(forensic) (53)
      • dreamhack (5)
      • ctf-d (47)
      • suninatas (1)
    • write-up(misc) (13)
      • dreamhack (12)
      • suninatas (1)
    • development (31)
      • Linux (14)
      • Java (13)
      • Python (1)
      • C (2)
      • TroubleShooting (1)
    • 자격증 (8)
    • 이산수학 (1)
    • 정보보안 (0)
hELLO · Designed By 정상우.
ssongk

ssongk

[reversing.kr] ImagePrc write-up
write-up(rev)/reversing.kr

[reversing.kr] ImagePrc write-up

2024. 6. 6. 00:44

이번 문제는 라업을 참고해가면서 진행했다.

 


 

마우스로 그림을 그리고 check 버튼을 눌러 검사할 수 있는 기능이 존재한다.

 

int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
  int SystemMetrics; // eax
  HWND Window; // eax
  int v7; // [esp-1Ch] [ebp-64h]
  struct tagMSG Msg; // [esp+4h] [ebp-44h] BYREF
  WNDCLASSA WndClass; // [esp+20h] [ebp-28h] BYREF

  ::hInstance = hInstance;
  WndClass.cbClsExtra = 0;
  WndClass.cbWndExtra = 0;
  WndClass.hbrBackground = (HBRUSH)GetStockObject(0);
  WndClass.hCursor = LoadCursorA(0, (LPCSTR)0x7F00);
  WndClass.hInstance = hInstance;
  WndClass.hIcon = LoadIconA(0, (LPCSTR)0x7F00);
  WndClass.lpfnWndProc = (WNDPROC)sub_401130;
  WndClass.lpszClassName = lpWindowName;
  WndClass.lpszMenuName = 0;
  WndClass.style = 3;
  RegisterClassA(&WndClass);
  v7 = GetSystemMetrics(1) / 2 - 0x4B;
  SystemMetrics = GetSystemMetrics(0);
  Window = CreateWindowExA(
             0,
             lpWindowName,
             lpWindowName,
             0xCA0000u,
             SystemMetrics / 2 - 0x64,
             v7,
             0xC8,
             0x96,
             0,
             0,
             hInstance,
             0);
  ShowWindow(Window, 5);
  if ( !GetMessageA(&Msg, 0, 0, 0) )
    return Msg.wParam;
  do
  {
    TranslateMessage(&Msg);
    DispatchMessageA(&Msg);
  }
  while ( GetMessageA(&Msg, 0, 0, 0) );
  return Msg.wParam;
}
LRESULT __stdcall sub_401130(HWND hWnd, UINT Msg, WPARAM wParam, unsigned int lParam)
{
  HDC v4; // eax
  HGDIOBJ v6; // eax
  HDC DC; // esi
  void *v8; // esi
  HRSRC ResourceA; // eax
  HGLOBAL Resource; // eax
  _BYTE *v11; // eax
  int v12; // edi
  _BYTE *v13; // ecx
  int v14; // eax
  char pv[4]; // [esp+8h] [ebp-80h] BYREF
  LONG v16; // [esp+Ch] [ebp-7Ch]
  UINT cLines; // [esp+10h] [ebp-78h]
  struct tagBITMAPINFO bmi; // [esp+20h] [ebp-68h] BYREF

  if ( Msg <= 0x111 )
  {
    if ( Msg != 0x111 )
    {
      switch ( Msg )
      {
        case 1u:
          DC = GetDC(hWnd);
          hbm = CreateCompatibleBitmap(DC, 0xC8, 0x96);
          hdc = CreateCompatibleDC(DC);
          h = SelectObject(hdc, hbm);
          Rectangle(hdc, 0xFFFFFFFB, 0xFFFFFFFB, 0xCD, 0xCD);
          ReleaseDC(hWnd, DC);
          ::wParam = (WPARAM)CreateFontA(0xC, 0, 0, 0, 0x190, 0, 0, 0, 0x81u, 0, 0, 0, 0x12u, pszFaceName);
          dword_4084E0 = (int)CreateWindowExA(
                                0,
                                ClassName,
                                WindowName,
                                0x50000000u,
                                0x3C,
                                0x55,
                                0x50,
                                0x1C,
                                hWnd,
                                (HMENU)0x64,
                                hInstance,
                                0);
          SendMessageA((HWND)dword_4084E0, 0x30u, ::wParam, 0);
          return 0;
        case 2u:
          v6 = SelectObject(hdc, h);
          DeleteObject(v6);
          DeleteDC(hdc);
          PostQuitMessage(0);
          return 0;
        case 0xFu:
          v4 = BeginPaint(hWnd, (LPPAINTSTRUCT)bmi.bmiColors);
          BitBlt(v4, 0, 0, 0xC8, 0x96, hdc, 0, 0, 0xCC0020u);
          EndPaint(hWnd, (const PAINTSTRUCT *)bmi.bmiColors);
          return 0;
      }
      return DefWindowProcA(hWnd, Msg, wParam, lParam);
    }
    if ( wParam == 0x64 )
    {
      GetObjectA(hbm, 0x18, pv);
      memset(&bmi, 0, 0x28u);
      bmi.bmiHeader.biHeight = cLines;
      bmi.bmiHeader.biWidth = v16;
      bmi.bmiHeader.biSize = 0x28;
      bmi.bmiHeader.biPlanes = 1;
      bmi.bmiHeader.biBitCount = 0x18;
      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);
      ResourceA = FindResourceA(0, (LPCSTR)0x65, (LPCSTR)0x18);
      Resource = LoadResource(0, ResourceA);
      v11 = LockResource(Resource);
      v12 = 0;
      v13 = v8;
      v14 = v11 - (_BYTE *)v8;
      while ( *v13 == v13[v14] )
      {
        ++v12;
        ++v13;
        if ( v12 >= 0x15F90 )
        {
          sub_401500(v8);
          return 0;
        }
      }
      MessageBoxA(hWnd, Text, Caption, 0x30u);  // wrong
      sub_401500(v8);
      return 0;
    }
    return 0;
  }
  switch ( Msg )
  {
    case 0x200u:
      if ( dword_47D7F8 )
      {
        MoveToEx(hdc, x, y, 0);
        LineTo(hdc, (unsigned __int16)lParam, HIWORD(lParam));
        x = (unsigned __int16)lParam;
        y = HIWORD(lParam);
        InvalidateRect(hWnd, 0, 0);
      }
      return 0;
    case 0x201u:
      dword_47D7F8 = 1;
      y = HIWORD(lParam);
      x = (unsigned __int16)lParam;
      return 0;
    case 0x202u:
      dword_47D7F8 = 0;
      return 0;
    default:
      return DefWindowProcA(hWnd, Msg, wParam, lParam);
  }
}

 

gpt에게 코드 해석을 부탁했더니 bmp 파일을 가져와서 비교하는 루틴을 가지고 있다고 한다.

해당 루틴은 while으로 구성되어 있는데

비교하는 주소를 디버거로 보면 힙에 저장하고 FF가 많이 있는 것을 확인할 수 있다.

 

exe의 리소스 파일들은 .rsrc 섹션에 존재한다.

pe-bear

 

음.. 이건 문제를 많이 풀어보면 감각이 생길 것 같은데

이렇게 리소스의 bmp 파일과 비교하는 루틴이 있다는 것을 알았을 때

bmp 파일이 플래그라는 것을 유추할 수 있다.

 

bmp 파일을 복원하기 위해서 넓이, 높이 등의 정보를 알아야 한다.

ida로 확인해보면 그런 정보들을 설정해주는 것을 확인할 수 있다.

ida

 

cLines와 v16의 값을 알기 위해 xdbg를 사용한다.

xdbg

 

확인해보면 width는 0x96이고 height는 0xc8이다.

이건 라업 보고 알았는데 bitcount도 중요한 필드였다.

bitcount는 ida에서 0x18인 것을 확인할 수 있다.

 

이제 그림판을 열어서 해당 정보들에 맞는 파일을 생성한다.

그림판

 

픽셀 데이터에 해당하는 부분을 .rsrc 섹션에 있는 데이터로 덮어쓰면 복구가 완료된다.

HxD

 

 


 

https://snwo.tistory.com/53

 

[Reversing.kr] (Reversing] ImagePrc 풀이

프로그램을 실행하면 그림을 그리고 검사를 받는다. Wrong! 탈락한것같다. exe32 파일이니, 올리디버거로 열어보자 Wrong을 사용하는 주소로 가보자 일단 GetDIBits 로 비트맵이미지를 가져온다. 내가

snwo.tistory.com

 

'write-up(rev) > reversing.kr' 카테고리의 다른 글

[reversing.kr] Position write-up  (1) 2024.06.15
[reversing.kr] Replace write-up  (0) 2024.06.01
[reversing.kr] Music Player write-up  (0) 2024.05.31
[reversing.kr] Easy ELF write-up  (0) 2023.08.30
[reversing.kr] Easy Unpack write-up  (0) 2023.08.30
    'write-up(rev)/reversing.kr' 카테고리의 다른 글
    • [reversing.kr] Position write-up
    • [reversing.kr] Replace write-up
    • [reversing.kr] Music Player write-up
    • [reversing.kr] Easy ELF write-up
    ssongk
    ssongk
    벌레 사냥꾼이 되고 싶어요

    티스토리툴바