본문 바로가기

Reversing/Dreamhack : Reverse Engineering

[Dreamhack] rev-basic-4

Reversing Basic Challenge #4

이 문제는 사용자에게 문자열 입력을 받아 정해진 방법으로 입력값을 검증하여 correct 또는 wrong을 출력하는 프로그램이 주어집니다. 해당 바이너리를 분석하여 correct를 출력하는 입력값을 찾으세요! 획득한 입력값은 DH{} 포맷에 넣어서 인증해주세요. 예시) 입력 값이 Apple_Banana일 경우 flag는 DH{Apple_Banana}

 

sub_140001000 함수

  • scanf에서 입력받은 문자열을 인자로 받음
  • 즉, a1은 입력된 문자열
  • 반복문 0x1C = 28번 반복
  • byte_14003000 배열에 들어있는 값 :

 

 

1️⃣ (unsigned __int8)(16 * *(_BYTE *)(a1 + i)) 분석

 

(1) _BYTE *

  • _BYTE *는 1바이트 크기의 데이터(char or unsigned char)을 가리키는 포인터
  • (_BYTE *)(a1 + i)는 a1+i라는 메모리 주소를 _BYTE *로 변환 → 여기까지는 주소값
  • *(_BYTE *)(a1 + i)는 해당 주소에 있는 1바이트 값을 가져옴
  • 여기서 *는 해당 주소의 값을 가져오는 연산자로 사용됨

(2) 16 *

  • 가져온 값에 16을 곱하는 것
  • 즉, << 4 shift 연산

(3) (unsigned __int8)

  • (unsigned __int8)를 씌우는 이유는, 결과를 8비트 정수로 유지하기 위함임.

 

 

2️⃣ ((int)*(unsigned __int8 *)(a1 + i) >> 4) 분석

 

(1) (unsigned __int8 *)(a1 + i)

  • a1 + i 라는 메모리 주소에 있는 1바이트 값을 (unsigned __int8 *)로 캐스팅
    • unsigned __int8는 8비트(1바이트) 크기의 부호 없는 정수. 즉, unsigned char과 같은 개념
    • unsigned __int8 *1바이트 크기의 데이터를 가리키는 포인터
  • 즉, (a1 + i)가 가리키는 곳을 "이건 unsigned __int8 * 타입이야"라고 명시하는 것

(2) *(unsigned __int8 *)(a1 + i)

  • (unsigned __int8 *)(a1 + i)는 메모리 주소를 가리키는 포인터이므로, *를 사용하면 해당 주소에서 1바이트 크기의 값을 가져오는 것

(3) (int) 변환

  • 가져온 1바이트 크기의 값을 int로 변환
  • 즉 8비트 → 32비트
  • unsigned __int8int로 변환하는 경우는 단순히 부호 없는 8비트 값을 부호 있는 32비트로 확장하는 것

(4) >>4 (오른쪽 쉬프트)

  • 가져온 32비트 값을 4비트 오른쪽으로 이동
0xF4 (244) = 1111 0100 (2진수)
(int) 변환 후 32비트: 0000 0000 0000 0000 0000 0000 1111 0100
4비트 오른쪽 시프트:  0000 0000 0000 0000 0000 0000 0000 1111 (15)

 

역연산

  • byte_14003000 에 들어있는 값의 상위 4비트를 하위 4비트로, 하위 4비트를 상위 4비트로 바꾸어 주면 a1을 구할 수 있다.
#include<stdio.h>

int main() {

    int input[28] = {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};  

    int flag[28] = {0};

    for(int i = 0; i < 28; i++) {
        flag[i] = input[i] << 4 | input[i] >> 4;
    }

    printf("flag is DH{");

    for(int i = 0; i < 28; i++) 
    printf("%c", flag[i]);
    
    printf("}");

    return 0;

}



'Reversing > Dreamhack : Reverse Engineering' 카테고리의 다른 글

[Dreamhack] rev-basic-6  (0) 2025.04.21
[Dreamhack] rev-basic-5  (0) 2025.04.21
[Dreamhack] rev-basic-3  (0) 2025.04.21
[Dreamhack] rev-basic-2  (0) 2025.04.21
[Dreamhack] rev-basic-1  (0) 2025.04.21