DDDDigtal 4ensics

레나 튜토리얼 - 01 풀이 본문

Reversing

레나 튜토리얼 - 01 풀이

Dx4 2024. 2. 12. 17:01

레나 튜토리얼은 리버싱 기초를 배우기 좋은 기초 문제 모음이다. 이를 인지하고 꼭 한 번 씩 풀어봤음 하는 마음으로

풀이를 진행 해봄.

 

 가장 먼저 파일을 열면 [이미지 1]과 같이 Evaluation period out of date. purchase new license 즉, 라이센스가 없다고 창이 뜬다.

 

[이미지 1] 프로그램 실행

 

 우리는 문제를 해결하기 위하여, 일단 [이미지2]와 같이 문제를 기드라로 불러온다. 코드 브라우저를 통하여 코드를 확인한다면, 다음과 같이 해설할 수 있다.

[이미지 2] 기드라로 문제를 불러온 화면

 

 아래의 코드가 문제 파일의 전체 코드이다. 우리는 이 코드에서 정답을 찾아야 함으로 이 코드를 분석하면서 문제가 원하는 행위를 찾아보자.

/* WARNING: Globals starting with '_' overlap smaller symbols at the same address */

void entry(void)

{
  HANDLE hFile;
  BOOL BVar1;
  int iVar2;
  int iVar3;
  UINT in_stack_00000000;
  
  DAT_00402177 = GetModuleHandleA((LPCSTR)0x0);
  _DAT_00402197 = 0x4003;
  _DAT_0040219b = &DAT_004011a6;
  _DAT_0040219f = 0;
  _DAT_004021a3 = 0;
  _DAT_004021a7 = DAT_00402177;
  _DAT_004021ab = LoadIconA(DAT_00402177,(LPCSTR)0x4);
  _DAT_004021af = LoadCursorA((HINSTANCE)0x0,(LPCSTR)0x7f00);
  hFile = CreateFileA(s__Keyfile.dat_00402078 + 1,0xc0000000,3,(LPSECURITY_ATTRIBUTES)0x0,3,0x40216f
                      ,(HANDLE)0x0);
  if (hFile == (HANDLE)0xffffffff) {
    MessageBoxA((HWND)0x0,s__Evaluation_period_out_of_date._P_00402016 + 1,
                s__Key_File_ReverseMe_00402000,0);
                    /* WARNING: Subroutine does not return */
    ExitProcess(in_stack_00000000);
  }
  BVar1 = ReadFile(hFile,&DAT_0040211a,0x46,(LPDWORD)&DAT_00402173,(LPOVERLAPPED)0x0);
  if (BVar1 != 0) {
    iVar2 = 0;
    iVar3 = 0;
    if (0xf < DAT_00402173) {
      for (; (&DAT_0040211a)[iVar2] != '\0'; iVar2 = iVar2 + 1) {
        if ((&DAT_0040211a)[iVar2] == 'G') {
          iVar3 = iVar3 + 1;
        }
      }
      if (7 < iVar3) {
        MessageBoxA((HWND)0x0,s__You_really_did_it!_Congratz_!!!_004020dd + 1,
                    s__Key_File_ReverseMe_00402000,0);
                    /* WARNING: Subroutine does not return */
        ExitProcess(in_stack_00000000);
      }
    }
  }
  MessageBoxA((HWND)0x0,s__Keyfile_is_not_valid._Sorry._00402085 + 1,s__Key_File_ReverseMe_00402000,
              0);
                    /* WARNING: Subroutine does not return */
  ExitProcess(in_stack_00000000);
}

 

 

 가장 먼저 [이미지 3]의 코드는 CreateFileA를 통하여 Keyfile.dat파일의 유무와 함께 파일이 있다면 열기를 시도한다. 만약 파일을 열 수 없다면(존재하지 않는다면) MessageBoxA를 이용하여 메세지 박스를 띄우고 프로그램을 종료한다.로 해석할 수 있다. 이 때 [이미지 1]과 같은 화면이 나올 것 이다.

[이미지 3] 파일 유무 확인

 

 

 그 후 [이미지4]와 같이 ReadFile을 통하여 Keyfile.dat의 데이터를 읽어온다. 

처음에 마주하는 if는 파일을 성공적으로 읽었냐를 확인하는 if이며,

2번 째 if는 파일의 존재하는 데이터가 0xf 즉, 15바이트를 넘냐를 확인하는 if문이다.

그 후 반복문에 마주하게 되는데 파일의 데이터를 읽어오며 값이 존재하지 않을 때 ('\0' = null이다.)까지 반복문을 계속한다. 만약 읽어 온 데이터가 'G'라면 iVar3에 +1 한다.

마지막 반복문에 G가 7개 이상 존재한다면 [이미지 5]와 같이 우리가 원하던 결과를 얻을 수 있다.

[이미지 4] 문제가 원하는 플레그

 

[이미지 5] 원하던 결과

이 문제에서 요구하던 행위는 다음과 같다.

1. Keyfile.dat가 존재하는가?

2. 파일의 데이터가 15byte를 초과하는가 ?

3. 파일의 데이터에 'G'가 7개 이상 존재하는가 ?

이를 모두 충족하였을 때, 플레그를 얻을 수 있다.