본문 바로가기
Reversing/드림핵

[Dreamhack] rev-basic-4

by L3m0n S0ju 2021. 3. 30.

 

 

 


 

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char v4[256]; // [rsp+20h] [rbp-118h] BYREF

  memset(v4, 0, sizeof(v4));
  sub_1400011C0("Input : ", argv, envp);
  sub_140001220("%256s", v4);
  if ( (unsigned int)sub_140001000((__int64)v4) )
    puts("Correct");
  else
    puts("Wrong");
  return 0;
}

 

 

 

IDA Pro7.5를 이용해 디스어셈블하면 위와 같은 코드를 볼 수 있다. Correct 바로 위의 if 조건문이 참이면 Correct를 출력한다.

 

 


 

__int64 __fastcall sub_140001000(__int64 a1)
{
  int i; // [rsp+0h] [rbp-18h]

  for ( i = 0; (unsigned __int64)i < 28; ++i )
  {
    if ( ((unsigned __int8)(16 * *(_BYTE *)(a1 + i)) | ((int)*(unsigned __int8 *)(a1 + i) >> 4)) != word_140003000[i] )
      return 0i64;
  }
  return 1i64;
}

 

 

위 코드는 if 조건문에 있던 sub_140001000 함수이다. 입력할 문자열을 buf라고 가정하면 (16 * buf[i]) | (buf[i] >> 4) 가 140003000에 있는 문자열과 같으면 if문에 걸리지 않고 결국 return 1을 반환하게 된다.16 * buf[i]는 buf[i]<<4와 같다고 볼 수 있다. 그리고 buf[i] << 4 와 buf[i] >> 4는 서로 비트가 겹치지 않으므로 or 연산자를 계산하면 서로 덧셈을 해주면 된다.

 

 


 

#include <stdio.h>
#include <string.h>

void main()
{
    char buf[] = { 0x24, 0x27 ,0x13 ,0xC6 ,0xC6 ,0x13 ,0x16 ,0xE6 ,0x47 ,0xF5 ,0x26 ,0x96 ,0x47 ,0xF5 ,0x46 ,0x27,
        0x13, 0x26 ,0x26 ,0xC6 ,0x56 ,0xF5 ,0xC3 ,0xC3 ,0xF5 ,0xE3 ,0xE3 ,0x00 };
    for (int j = 0; j < 28; j++) 
    {
        for (int i = 0; i < 256; i++)
        {
            if ((char)((i<<4)|(i>>4)) == buf[j])
                printf("%c\n", i);
        }
    }
}

 


 

 

위 코드와 같이 i를 하나씩 출력하여 입력할 문자열이 출력된다. 해당 문자열을 입력하면 Correct가 출력된다.

 


플래그: DH{Br1ll1ant_bit_dr1bble_<<_>>}

'Reversing > 드림핵' 카테고리의 다른 글

[Dreamhack] rev-basic-8  (0) 2021.04.12
[Dreamhack] rev-basic-7  (0) 2021.03.30
[Dreamhack] rev-basic-5  (0) 2021.03.30
[Dreamhack] rev-basic-3  (0) 2021.03.30
[Dreamhack] rev-basic-0  (0) 2021.03.24

댓글