본문 바로가기
IT 보안

리버스 엔지니어링 레지스터 종류 및 설명

by 떠도리c 2024. 9. 22.
반응형

레지스터

레지스터의 기억 용량은 메모리에 비해 적지만 고속으로 접근할 수 있습니다.

주요 레지스터에는 범용레지스터, 상태레지스터, 명령포인터, 세그먼트레지스터가 있습니다.

 

 

범용 레지스터

리버스 엔지니어링(Reverse Engineering)에서 프로그램의 동작 원리를 파악하기 위해 바이너리 코드를 분석하는 과정입니다. 범용 레지스터는 연산이나 포인터 저장 등 범용적으로 사용되는 레지스터 입니다.

EAX, EBX, ECX, EDX, ESP, EBP, ESI, EDI와 같은 레지스터들은 중요한 역할을 수행합니다. 이번에는 리버싱에서 사용되는 각 레지스터의 의미와 주요 용도에 대해 알아보도록 하겠습니다.

  • EAX (Extended Accumulator): EAX 레지스터는 계산 결과나 함수의 반환 값 등을 저장하는 데에 주로 사용됩니다. 리버싱 과정에서는 EAX를 통해 함수의 반환 값을 확인하거나 중요한 데이터를 추적하는 데에 활용됩니다.
  • EBX (Extended Base Register): EBX 레지스터는 데이터에 대한 포인터로 사용됩니다. 리버싱에서는 EBX를 통해 메모리 참조를 분석하고, 데이터 구조나 알고리즘의 흐름을 이해하는 데에 활용됩니다.
  • ECX (Extended Counter): ECX 레지스터는 반복 횟수를 카운트하는 데에 주로 사용됩니다. 리버싱에서는 ECX를 통해 반복문의 동작을 추적하고, 반복되는 코드 블록의 분석에 활용됩니다.
  • EDX (Extended Data Register): EDX 레지스터는 데이터 연산에 사용됩니다. 리버싱에서는 EDX를 통해 중간 연산 결과나 데이터의 흐름을 추적하고, 알고리즘의 동작을 이해하는 데에 활용됩니다.
  • ESP (Extended Stack Pointer): ESP 레지스터는 스택의 최상단을 가리키는 포인터 역할을 합니다. 리버싱에서는 ESP를 통해 스택의 사용 방식을 파악하고, 함수 호출과 관련된 정보를 추적하는 데에 활용됩니다.
  • EBP (Extended Base Pointer): EBP 레지스터는 스택 프레임의 베이스 주소를 가리키는 포인터 역할을 합니다. 리버싱에서는 EBP를 통해 함수의 로컬 변수나 매개변수, 스택 구조를 분석하고 디버깅에 활용됩니다.
  • ESI (Extended Source Index): ESI 레지스터는 데이터 블록의 소스 인덱스를 가리키는 데에 사용됩니다. 리버싱에서는 ESI를 통해 데이터의 흐름을 추적하고, 데이터 처리 알고리즘의 이해에 활용됩니다.
  • EDI (Extended Destination Index): EDI 레지스터는 데이터 블록의 대상 인덱스를 가리키는 데에 사용됩니다. 리버싱에서는 EDI를 통해 데이터의 이동이나 변형과 관련된 작업을 추적하고, 알고리즘의 동작을 이해하는 데에 활용됩니다.

범용 레지스터는 32비트이지만 E(Extended)를 제외하고 AX, BX, CX와 같이 하위 16비트만 사용 가능합니다.

또한 EAX, EBX, ECX, EDX 는 2바이트(16비트)를 AH, BH, CH, DH(상위), AL, BL, CL, DL(하위) 이름으로 참조할 수 있습니다.

리버싱에서 EAX, EBX, ECX, EDX, ESP, EBP, ESI, EDI와 같은 레지스터들은 프로그램의 동작 원리를 이해하고 분석하는 데에 중요한 역할을 합니다.

각 레지스터는 함수 호출, 데이터 처리, 메모리 참조, 반복문 분석 등 다양한 용도로 활용되며 이러한 레지스터들의 용도를 알고 있다면 코드 분석과정에서 많은 도움이 될 것 입니다.

 

 

 

상태 레지스터 (플래그 레지스터)

리버스 엔지니어링(Reverse Engineering)에서 상태 레지스터 32비트 크기를 가지며, 프로세서의 현재 상태를 나타내는 레지스터입니다.

이러한 레지스터들은 프로그램의 실행 중에 프로세서의 상태 변화를 체크하는 데 중요한 역할을 합니다.

  • 플래그 레지스터 (Flag Register)
    • 대표적인 플래그
      • ZF (Zero Flag): 연산 결과가 0이면 ZF는 1(참)로 설정됩니다.
      • SF (Sign Flag): 연산 결과의 최상위 비트(부호 비트)를 나타냅니다. 음수일 경우 1(참)로 설정됩니다.
      • OF (Overflow Flag): 부호 있는 숫자의 연산 결과가 비트 범위를 넘었을 때 1(참)로 설정됩니다.(오버 플로)
      • CF (Carry Flag): 부호 없는 숫자의 연산 결과가 비트 범위를 넘었을 때 1(참)나타냅니다. (오버 플로)
      • PF (Parity Flag): 연산 결과의 1 비트 수가 짝수인 경우 1(참)로 설정됩니다.

상태 레지스터는 CPU가 어떤 상태에 있는지를 나타내며, 프로그램의 실행 흐름을 제어하는 데 중요한 역할을 합니다. 리버싱 과정에서 이러한 레지스터의 값을 이해하고 해석하는 것은 소프트웨어의 내부 작동 원리를 파악하는 데 매우 중요합니다.

 

 

 

명령 포인터

명령 포인터는 CPU가 다음에 실행할 명령어의 주소를 가리키는 레지스터입니다. x86 아키텍처에서 이를 'Instruction Pointer (IP)' 또는 'Program Counter (PC)'라고 부르며, 64비트 확장 아키텍처인 x86_64에서는 'RIP'라는 이름으로 확장되었습니다.

리버스 엔지니어링에서 명령 포인터는 현재 실행 흐름을 이해하고 제어하는 데 중요한 요소입니다.

  • 프로그램 실행 제어: 명령 포인터는 프로그램이 실행될 때 CPU가 참조하는 주소를 제공합니다. CPU는 명령 포인터가 가리키는 메모리 위치에서 명령어를 가져와 실행하고, 명령어가 실행된 후에는 명령 포인터를 갱신하여 다음 명령어로 이동합니다.
  • 프로그램 흐름 추적: 리버스 엔지니어링 과정에서 분석가는 명령 포인터의 값을 추적함으로써 프로그램의 실행 흐름을 이해하고, 분기, 루프, 함수 호출 등의 흐름을 분석할 수 있습니다.
  • 디버깅: 디버거를 사용할 때, 명령 포인터는 현재 중단점(breakpoint)의 위치나 단계별 코드 실행(step through) 중 현재 실행 지점을 표시하는 데 사용됩니다.
  • 예외 처리 및 인터럽트 처리: 프로그램이 예외 상황에 직면하거나 인터럽트 요청을 받았을 때, 명령 포인터는 예외 처리기나 인터럽트 서비스 루틴으로 제어를 이동하는 데 사용됩니다.
  • EIP (Extended Instruction Pointer)EIP는 x86 아키텍처에서 사용되는 명령 포인터입니다.
    • EIP 레지스터의 주요 기능과 특징
      • 명령어 위치 지정: EIP는 현재 CPU가 실행하고 있는 명령어의 위치를 메모리 상에서 지정합니다. 이는 프로그램 카운터로서의 기능을 하며, CPU는 EIP가 가리키는 위치에서 명령어를 읽어 실행합니다.
      • 자동 갱신: 명령어가 실행될 때마다 EIP는 자동으로 갱신되어 다음에 실행할 명령어의 위치를 가리킵니다. 이 갱신은 대부분의 명령어가 실행된 후에 명령어 크기만큼 증가하는 방식으로 이루어집니다.
      • 제어 전송 명령어와의 상호작용: 제어 전송 명령어(예: 점프, 호출, 리턴 명령어)는 EIP의 값을 변경함으로써 프로그램의 실행 흐름을 변경합니다. 이를 통해 분기, 함수 호출, 루프 등의 프로그램 구조를 구현할 수 있습니다.
      • 리버스 엔지니어링에서의 중요성: 리버스 엔지니어링 시, EIP 레지스터의 값을 모니터링하고 추적함으로써 실행 흐름을 분석하고, 프로그램의 동작을 이해할 수 있습니다. 또한, 어셈블리 코드 레벨에서 EIP를 조작하여 프로그램의 흐름을 변경하는 기술도 사용됩니다.
      • 보안 측면: 보안 측면에서 EIP는 중요한 요소입니다. 공격자들은 버퍼 오버플로우 같은 취약점을 이용하여 EIP의 값을 조작하고, 원하는 코드를 실행할 수 있는 위치로 변경하여 시스템을 공격할 수 있습니다.

명령 포인터는 프로그램의 실행 상태를 나타내는 가장 기본적인 요소 중 하나이므로, 리버스 엔지니어링을 수행할 때 정확한 실행 흐름을 파악하고, 프로그램의 동작을 이해하기 위해 반드시 주시해야 하는 레지스터입니다.

 

 

 

세그먼트 레지스터

리버스 엔지니어링에서 세그먼트 레지스터는 프로세서가 메모리에 접근할 때 사용하는 레지스터로, 특히 x86 아키텍처에서 중요한 역할을 합니다. 세그먼트 레지스터는 메모리 관리의 일부로서, 메모리를 세그먼트로 나누고 각 세그먼트에 대한 기준 주소를 저장하는 데 사용됩니다. 이는 메모리를 효율적으로 관리하고 보호하는 데 중요한 기능을 합니다.

  • 세그먼트 레지스터의 종류
    • CS (Code Segment): 프로그램 코드가 저장되는 메모리 세그먼트의 기준 주소를 가집니다. CPU가 실행할 명령어의 주소를 결정할 때 CS 레지스터의 값이 사용됩니다.
    • DS (Data Segment): 프로그램의 데이터를 저장하는 세그먼트의 기준 주소를 가집니다. 데이터 세그먼트는 변수, 상수, 정적 데이터 등을 포함합니다.
    • SS (Stack Segment): 프로그램의 스택이 위치하는 메모리 세그먼트의 기준 주소를 가집니다. 함수 호출, 로컬 변수 저장, 호출 상태의 저장 등 스택 관련 연산에 사용됩니다.
    • ES (Extra Segment): 데이터 복사와 같은 특정한 연산에 추가적인 데이터 세그먼트로 사용됩니다. ES는 DS, CS, SS와 별도로 추가적인 데이터 세그먼트를 참조할 때 사용됩니다.
    • FS, GS (General Purpose Segment Registers): 이 두 세그먼트 레지스터는 특별한 용도가 정해져 있지 않고, 운영체제나 응용 프로그램에 의해 다양한 목적으로 사용될 수 있습니다. 예를 들어, FS는 종종 Thread Local Storage (TLS)에 접근하는 데 사용됩니다.

 

반응형