본문 바로가기

해킹&보안/악성코드 및 치트

Reverse Engineering 4

이번에도 풀이는 다르겠지만 문제는 똑같이 나오네요. 시작해봅시다

Main함수 부분입니다.

입력 값을 받고 특정 값과 비교하여 Correct or Worng을 출력하는 것 같습니다.

자세하게 들여다 보기 위해 디컴파일을 해보겠습니다.

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

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

어셈블리어가 이렇게 C언어로 바뀌었습니다. 요약을 해보면 

입력을 받고, 해당 입력을 처리하여 "Correct" 또는 "Wrong"을 출력. 입력은 argvenvp를 통해 전달되고, memset() 함수를 사용하여 초기화된 로컬 변수 v4에 저장후, 입력된 값이 유효한지를 확인하고, 유효하면 "Correct"를 출력하고, 그렇지 않으면 "Wrong"을 출력하는 코드입니다.

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

  for ( i = 0; (unsigned __int64)i < 0x18; ++i )
  {
    if ( byte_140003000[i] != (i ^ *(unsigned __int8 *)(a1 + i)) + 2 * i )
      return 0i64;
  }
  return 1i64;
}

sub_140001000함수에 진입하여 분석해보겠습니다.

입력 값과 byte_140003000 배열의 값들을 비교하는데, byte_140003000[i] 값과 (i ^ *(unsigned __int8 *)(a1 + i)) + 2 * i 값을 비교합니다. 만약 두 값이 다르면 0을 반환하고, 모든 비교가 일치하면 1을 반환합니다. 여기서 i는 0부터 0x17까지 증가하며, (unsigned __int64)i < 0x18 (16진수 18 = 10진수 24)만큼 반복됩니다.

 

함수로 더 진입하였더니 16진수 값들이 많이 보입니다.

이 값들을 이용해서 위에 있는 코드를 역연산하면 (i ^ (input)) - 2*i) 가 됩니다.

 

c언어 코드로 식을 만들어서 실행하면

나오게 된다

I_am_X0_xo_Xor_eXcit1ng

'해킹&보안 > 악성코드 및 치트' 카테고리의 다른 글

Reverse Engineering 6  (0) 2024.05.10
Reverse Engineering 5  (0) 2024.05.01
Reverse Engineering 3  (1) 2024.03.25
Reverse Engineering 2  (0) 2024.03.25
Reverse Engineering 1  (1) 2024.03.25