카테고리 없음

abex - crackme 5

melonbbang-ruffy 2024. 9. 11. 12:23

일단 dbg로 분석하기 전에 die로 파일 분석해보기

더보기

- 32비트 프로그램

- 델파이로 작성됨

- 프로그램에 압축, 암호화 같은 별도의 안전장치 x 

x32 dbg로 실행시켜보자

아무거나 입력해보면 알겠지만

올바른 serial number를 입력해야 될 듯 싶다.

아마 스택이나 메모리에서 값을 알아낼 수 있을듯하다.

ida랑 x32 디버거로 해당 프로그램을 까보도록 하자.

Well Done! 이 부분으로 가면 아마 cmp를 보면서 어떤 값과 비교하는지 알수 있을 듯 하다

 

함수명에서 힌트를 얻을 수 있는건 딱히 없어보인다.

프로그램을 시작하면,

일단 dbg로 분석하기 전에 die로 파일 분석해보기

더보기

- 32비트 프로그램

 

- 델파이로 작성됨

 

- 프로그램에 압축, 암호화 같은 별도의 안전장치 x 

 

함수 목록

https://learn.microsoft.com/ko-kr/windows/win32/api/winbase/nf-winbase-lstrcata

 

lstrcatA 함수(winbase.h) - Win32 apps

한 문자열을 다른 문자열에 추가합니다. 경고 사용하지 마세요. (ANSI)

learn.microsoft.com

lstrcatA 함수

- 한 문자열을 다른 문자열에 추가

https://learn.microsoft.com/ko-kr/windows/win32/api/winbase/nf-winbase-lstrcmpia

 

lstrcmpiA 함수(winbase.h) - Win32 apps

두 문자 문자열을 비교합니다. 대/소문자를 구분하지 않고 비교합니다. (ANSI)

learn.microsoft.com

lstrcmpiA 함수

- 두 문자열 비교, 대/소문자를 구분하지 않고 비교하는 함수

x32 dbg로 실행시켜보자

eax의 레지스터에 담긴 값이 0이 되어야만 문제가 풀립니다.

그리고 직전에 문자열 비교 함수를 호출하는 것으로 보아, 스택에 어떤 값이 저장되어 있고, 그 값과 비교할 때 올바르면 "Well Done"을 출력하는 것으로 보입니다.

일단 cmp eax, 0에서 bp를 걸어주고 프로그램을 실행해 보았습니다.

입력한 문자열과 뭐를 비교하는지 확인해야하는데 현재 상황에서는 확인하기 힘들어보임...

그러면 cat 함수를 살펴보도록 합시다.

아까 말했듯이 lstrcat 함수는 문자열을 가져오는 함수이므로 분명 비교할 문자열을 이 친구를 통해 가져올 것....!

이 함수에 bp를 걸어놓고 다시 프로그램을 실행시켜 보도록 하자

stdcall에 대한 설명을 보면 알겠지만

https://learn.microsoft.com/ko-kr/cpp/cpp/stdcall?view=msvc-170

 

__stdcall

자세히 알아보기: __stdcall

learn.microsoft.com

edx, ecx에 각각 enter your serial, L2C-57816784-ABEX 문자열이 들어갑니다.

그리고 아래에서 CompareStringA 서브루틴이 실행되는데요, 이 함수로 들어가보면

계속 내가 입력한 값과 L2C-57816784-ABEX문자열을 하나씩 비교하는걸 볼 수 있습니다.

아마 올바른 시리얼 번호는 L2C-57816784-ABEX라고 추측해 볼 수 있겠습니다...!

프로그램을 실행하고, 입력창에 L2C-57816784-ABEX을 입력해보면

올바르게 입력했다고 뜨는 걸 확인하실 수 있습니다...!

여기는 함수의 스택 프레임을 보여주는 칸이라고 보면 된다...!

 

 

 

더보기

EIP 레지스터 : 다음 명령어를 실행할 주소를 담고 있는 레지스터

 

dword란 해당 메모리 주소에서 4바이트 만큼 데이터를 가져온다는 의미

 

♥ ida로 해당 프로그램을 c언어로 디컴파일한 코드

#include <windows.h>
#include <defs.h>

CHAR byte_402000[200] =
{
  '\0', ....
}; // idb
DWORD FileSystemFlags = 0u; // idb
DWORD MaximumComponentLength = 0u; // idb
DWORD VolumeSerialNumber = 0u; // idb
CHAR VolumeNameBuffer[] = { '\0', '\0', '\0', '\0' }; // idb
CHAR String[200] =
{
  '\0', ....
}; // idb
HINSTANCE hInstance = NULL; // idb
CHAR String2[] = "4562-ABEX"; // idb
CHAR aL2c5781[] = "L2C-5781"; // idb
CHAR aWellDone[] = "Well Done!"; // idb
CHAR aYepYouEnteredA[] = "Yep, you entered a correct serial!"; // idb
CHAR Caption[] = "Error!"; // idb
CHAR Text[] = "The serial you entered is not correct!"; // idb


void __stdcall __noreturn start(int a1, int a2, int a3, int a4)
{
  hInstance = GetModuleHandleA(0);
  DialogBoxParamA(hInstance, (LPCSTR)1, 0, DialogFunc, 0);
  ExitProcess(0);
}

INT_PTR __stdcall DialogFunc(HWND a1, UINT a2, WPARAM a3, LPARAM a4)
{
  int v4; // ebp
  int v6; // [esp-Ch] [ebp-Ch]
  int v7; // [esp-8h] [ebp-8h]
  int v8; // [esp-4h] [ebp-4h]
  int savedregs; // [esp+0h] [ebp+0h]

  if ( a2 == 273 )
  {
    sub_401056(v4, v6, v7, v8, savedregs);
  }
  else
  {
    if ( a2 != 2 )
      return 0;
    sub_40112D(v4, v6, v7, v8, savedregs);
  }
  return 0;
}

BOOL __userpurge sub_401056@<eax>(int a1@<ebp>, int a2, int a3, int a4, int a5)
{
  char v6; // dl

  if ( *(_DWORD *)(a1 + 16) == 101 )
  {
    GetDlgItemTextA(*(HWND *)(a1 + 8), 104, String, 37);
    GetVolumeInformationA(
      0,
      VolumeNameBuffer,
      0x32u,
      &VolumeSerialNumber,
      &MaximumComponentLength,
      &FileSystemFlags,
      0,
      0);
    lstrcatA(VolumeNameBuffer, String2);
    v6 = 2;
    do
    {
      ++*(_DWORD *)VolumeNameBuffer;
      ++*(_DWORD *)&VolumeNameBuffer[1];
      ++*(_DWORD *)&VolumeNameBuffer[2];
      ++*(_DWORD *)&VolumeNameBuffer[3];
      --v6;
    }
    while ( v6 );
    lstrcatA(byte_402000, aL2c5781);
    lstrcatA(byte_402000, VolumeNameBuffer);
    if ( lstrcmpiA(byte_402000, String) )
      MessageBoxA(*(HWND *)(a1 + 8), Text, Caption, 0);
    else
      MessageBoxA(*(HWND *)(a1 + 8), aYepYouEnteredA, aWellDone, 0);
  }
  else if ( *(_DWORD *)(a1 + 16) != 2 )
  {
    return 0;
  }
  return sub_40112D(a1, a2, a3, a4, a5);
}
BOOL __userpurge sub_40112D@<eax>(int a1@<ebp>, int a2, int a3, int a4, int a5)
{
  return EndDialog(*(HWND *)(a1 + 8), 0);
}