본문 바로가기

Reversing

[리버스 엔지니어링] 80x86 CPU의 레지스터 종류와 뜻

레지스터(Register)
처리 중인 데이터나 처리 결과를 임시적으로 보관하는 CPU안의 기억장치이다.
레지스터에는 종류가 있고 종류마다 각각 기능이 따로 분류 되어있는데,
범용 레지스터, 세그먼트 레지스터, 포인터 레지스터, 인덱스 레지스터, 플래그 레지스터로 나뉘어 진다.

레지스터들 중에 앞에 E가 붙는것들이 있는데 이때 E는 Extended(확장된)을 의미한다.

범용 레지스터(General Register)

-연산 장치가 수행한 계산 결과의 임시 저장, 산술 및 논리 연산, 주소 색인등에 사용되는 레지스터이다.

  • EAX(Extended Accumulator Register)
    • 함수의 리턴 값 저장이나 산술 연산(+, -, *, /)에 이용된다.
    • Win32 API 함수들은 모두 리턴값을 EAX에 저장한 후에 리턴한다.
  • EBX(Extended Base Register)
    • 메모리 주소를 저장하기 위한 용도로 사용된다.
    • DS 세그먼트의 포인터를 주로 저장, ESI나 EDI 와 결합하여 인덱스에 사용하기도 한다.
  • ECX(Extended Count Register)
    • 반복적으로 실행되는 특정 명령에 사용된다.(루프, 반복문)
    • 좌우 시프트 연산자에도 사용된다.
  • EDX(Extended Data Register)
    • 일반적인 자료를 저장할 때 사용된다.
    • 입출력 연산에도 사용된다.
    • 큰 수의 곱셈과 나눗셈 연산에서 EAX와 함께 사용된다.

x32dbg 사진의 붉은 원이 범용 레지스터 부분이다.

 


세그먼트 레지스터(Segment Register)

-프로그램에 정의한 메모리상의 특정 영역으로 코드, 데이터, 스택 등을 포함하는 레지스터이다.

  • CS(Code Segment Register)
    • 실행할 기계 명령어가 저장된 메모리 주소를 지정한다.(코드 세그먼트의 시작 주소를 가리킴)
    • 일반 프로그래밍에서는 이 레지스터를 직접 참조할 필요가 없다.
  • DS(Data Segment Register)
    • 프로그램에서 정의된 데이터, 상수, 작업 영역 메모리 주소를 지정한다.(데이터 세그먼트의 시작 주소를 가리킴)
    • 프로그램은 참조하려는 데이터의 오프셋을 DS 레지스터에 저장된 주소 값에 더해 데이터 세그먼트 안의 데이터를 참조한다.
  • SS(Stack Segment Register)
    • 프로그램 스택 세그먼트(프로그램을 실행할 때 실행 과정에서 필요한 데이터나 연산 결과 등을 임시 저장 및 삭제 목적으로 사용됨)의 시작 주소를 가리킴.
    • 메모리상에 스택 구현을 가능하게 한다.
  • ES, FS, GS(Extra Segment Register)
    • 문자 연산과 추가 메모리를 지정하는 데 사용하는 여분의 레지스터이다. 
    • ES 레지스터는 추가로 사용된 데이터 세그먼트의 주소를 가리킨다.
    • 스트링(String, 문자 데이터) 연산에 사용되는데 이때 EDI 레지스터와 함께 사용된다.
    • FS, GS 레지스터도 목적은 거의 비슷하나 실제로 거의 사용되지는 않는다.

x32dbg 사진의 붉은 원이 세그먼트 레지스터 부분이다.


포인터 레지스터(Pointer Register)

-프로그램 실행 과정에서 사용하는 주요 메모리 주소 값을 저장하는 레지스터이다.

  • EBP(Extended Base Pointer)
    • SS 레지스터와 함께 사용하여 함수의 시작 주소 값(스택 프레임의 시작 주소)을 저장한다.
    • 함수로 전달되는 지역 변수등을 참조할 때 기준이 된다.
    • ESP 레지스터와 함께 써서 스택 프레임을 형성하기도 한다.
  • ESP(Extended Stack Pointer)
    • SS 레지스터와 함께 사용되며, 스택의 가징 끝 주소(하위 주소)를 가리킨다.
    • 스택에 값을 PUSH/POP 할때마다 ESP의 값이 4바이트씩 감소/증가한다.
 

[리버스 엔지니어링] 스택, 스택프레임

Stack(스택) 메모리의 영역중 하나로써 후입 선출(Last In First Out)의 구조를 가지고 있다. 함수의 호출과 관련있는 지역 변수(Local Variable), 매개변수(Parameter), 복귀 주소(Return address)가 저장되는 영..

ludeno-studying.tistory.com

  • EIP(Extended Instruction Pointer)
    • 다음 명령어의 오프셋(Offset, 상대 위치 주소)을 저장한다.
    • 현재 실행 중인 코드 세그먼트에 속한 현재 명령을 가리킨다.
    • 실제 메모리상의 주소를 참조할 때 CS 레지스터와 함께 사용된다.

x32dbg 사진의 붉은 원이 포인터 레지스터 부분이다.


인덱스 레지스터(Index Register)

-데이터를 복사할 때 출발지와 목적지 주소를 각각 가리키는 레지스터이다.

  • EDI(Extended Destination Index)
    • 목적지 주소 값을 저장한다.
  • ESI(Extended Source Index)
    • 출발지 주소 값을 저장한다.

인덱스 레지스터는 메모리의 한 영역(Source)에서 다른 영역(Destination)으로 데이터를 연속적으로 복사할 때 사용된다.

C언어의 strcpy함수를 사용할 때(이때 s1,s2는 각각 선언과 동시에 초기화된 배열과 선언만된 배열이다), strcpy(s2, s1); 형식으로 사용되는데 이때 s2의 주소 값이 저장되는 곳이 EDI이고 s1의 주소 값이 저장되는 곳이 ESI이다.

ex) strcpy
#include <stdio.h>
#include <string.h>
int main()
{
	char s1[20] = "Luden0 Blog";
	char s2[20];

	strcpy(s2, s1);

	printf("%s\n", s2);
	return 0;
}

(실행결과)

s1의 문자열이 s2로 복사됨
x32dbg 사진의 붉은 원이 인덱스 레지스터 부분이다.


플래그 레지스터(Flag Register)

-크기가 32비트로, 컴퓨터의 다양한 상태를 나타내는 비트를 포함한 레지스터이다.

  • EFLAGS
    • 연산 결과 및 시스템 상태와 관련된 여러가지 플래그 값을 저장한다.

플래그 종류

  • CF(Carry Flag): 산술 연산에 의한 자리 올림이나 자리내림이 발생할때 1이된다(세트).
  • ZF(Zero Flag): 산술 연산 결과가 0이면 1이되고(세트) 0이외에는 0이된다(클리어).
  • OF(Overflow Flag): 부호가 있는 수의 오버플로우가 발생하거나 MSB(2진수의 최상위 비트, 부호를 결정한다)를 변경했을 때 1이된다(세트).
  • PF(Parity Flag): 산술 연산 결과가 짝수이면 1이된다(세트).
  • AF(Adjust Flag): 8비트 피연산자를 사용한 산술 연산에서 비트 3 을 비트 4로 자리올림하면 1이된다(세트).
  • SF(Sign Flag): 산술 및 논리 연산 결과가 음수이면 1이된다(세트).
  • DF(Direction Flag): 스트링 명령을 제어해서 DF가 1이면 스트링을 높은 주소에서 낮은 주소로 처리하고 DF가 0이면 스트링을 낮은 주소에서 높은 주소로 처리한다.
  • TF(Trap Flag): 디버깅을 할 때 Single Step Mode(한번에 하나의 명령어만 실행되는 모드)를 활성화 하면 1이되고(세트) 비활성화 하면 0이된다(클리어).
  • IF(Interrupt enable Flag): 프로세서의 인터럽트 처리 여부를 제어한다. IF가 1이면(세트) 시스템의 인터럽트를 처리하고, 0이면(클리어) 시스템의 인터럽트를 무시한다.

x32dbg 사진의 붉은 원이 플래그 레지스터 부분이다.