HyeM

[0]32bit Register 본문

Study/Reversing

[0]32bit Register

Hailey_HyeM207 2020. 9. 5. 19:54

 

#1. Register

- 레지스터 : CPU 내부에 존재하는 저장공간으로, 고속으로 데이터를 처리할 수 있다.

 

IA-32 레지스터에는 Basic program execution register,  x87 FPU registers, Control registers, Memory management registers 등 종류가 다양한데, 그 중  가장 기초적인 Basic program execution 레지스터에 대해 알아본다.

 

 

#2. Basic program execution register 종류

출처 : https://smile2x.tistory.com/entry/IA32-%EB%A0%88%EC%A7%80%EC%8A%A4%ED%84%B0%EC%97%90-%EA%B4%80%ED%95%9C-%EA%B8%801

1. 범용(General) 레지스터 (32bit -8개)

2. 세그먼트(Segment) 레지스터 (16bit -6개)

3. 플래그(Flag) 레지스터 (32bit -1개)

4.  인스트럭션(Instruction) 포인터 (32bit -1개)

 

레지스터 이름에 E가 붙은 경우는 예전에 16bit였던 레지스터가 32bit로 확장됨을 의미한다.

 

 

#2-01 . 범용 레지스터 (General Purpose Register)

- 크기 : 32bit(4Byte)

- 개수 : 8개

- 용도 : 주로 상수/주소 저장할 때, 또는 특정 레지스터를 조작할 때 사용, 특수한 용도로 사용하기도 함.

 

https://seednote.tistory.com/10

++  위에서 레지스터 이름에 E가 붙으면 16bit의 레지스터가 확장됨을 의미한다고 하였다. 위에서 EAX를 예로 들면 16bit였던 AX가 레지스터가 확장됨을 알 수 있다.  각 레지스터는 16bit 하위 호환을 위하여 몇 개의 구획으로 나누어 지는데, EAX를 예로 들어보자.

EAX(0~31) : 32bit     #32비트 모두 다 사용하고 싶을 때 사용
AX(0~15)  : EAX의 하위 16bit    #16bit만 사용할 땐 AX 사용
AH(8~15) : AX의 상위 8bit         #8bit만 사용할 땐 AH사용
AL(0~7) : AX의 상위 8bit           #8bit만 사용할 땐 AH사용

=>이렇게 나눠진 레지스터는 상황에 맞게 8,16, 32bit 로 사용할 수 있다.

 

- 종류 : 

 

(산술연산 명령어(ADD, SUB, XOR, OR등) 에서 상수/변수값의 저장 용도로 많이 사용됨)

EAX : 피연산자와연산 결과의 저장소, 

            함수 return 값 저장(모든 Win32 API 함수들은 리턴값을 EAX에 저장하고 리턴한다.)

EBX : DS Segment 안의 데이터를 가리키는 포인터(메모리 주소 저장)

            산수/변수 저장

ECX : 문자열 처리나 루프를 위한 카운터    ( 루프를 돌 때 마다 ECX는 1씩 감소됨)

EDX : I/O 포인터입출력 연산에서 반드시 간접 주소 지정에 의한 데이터 레지스터를 사용함.

          보통 EAX와 함께 연동해서 사용하고,  큰 수의 곱셈 또는 나눗셈 연산시 사용됨.  (나누기 진행시, 몫은 EAX, 나머지는 EDX에 저장됨.)

            부호 확장 명령에 사용

 

(메모리 복사에 이용)

ESI : DS레지스터가 가리키는 데이터 세그먼트  내의 어느 데이터를 가리키고 있는 포인터,

         문자열 처리(데이터 조작, 복사등)에서 source(출발지 주소)를 가리킴

EDI : ES레지스터가 가리키고 있는 데이터 세그먼트 내의 어느 데이터를 가리키고 있는 포인터,

         문자열 처리(데이터 조작, 복사등)에서 destination(목적지 주소)을 가리킴

          stos, movs 사용할 때 마다 1씩 증가한다.

 

(스택관련)

ESP : SS 레지스터가 가리키는 스택 세그먼트의 맨 꼭대기 ( Stack의 끝주소)를 가리킨다. 스택 쌓일때 마다 ESP 값 1씩 증가

EBP : SS레지스터가 가리키는 스택상의 한 데이터 (스택의 첫 시작 주소)를 가리키는 포인터, 

            함수가 호출되었을 때, 그 순간의 EBP를 저장하고 있다가, 함수 리턴 직전에 ESP 값을 되돌려 줘야 함.( Stack Frame 기법) 

 

 

 

 

#2-02. 세그먼트 레지스터 (Segment Register)

- 세그먼트 : 메모리를 조각 내어 각 조각마다 시작주소, 범위, 접근 권한 등을 부여해서 메모리를 보호하는 기법이다. 

                   *페이징(paging)기법으로 가상 메모리를 실제 물리 메모리로 변경할 때 사용됨.

- 세그먼트 레지스터 : 프로세스의 특정 세그먼트를 가리키는 포인터 역할

 

 

*페이징 기법 : 컴퓨터가 메인 메모리에서 사용하기 위해 2차 기억장치로 부터 데이터를 저장하고 검색하는 메모리 관리 기법

                        페이지일정한 크기를 가진 블록으로, 페이징은 프로세스를 페이지로 잘라서 메모리에 적재하는 방식이다. 

 

출처 : https://koreanfoodie.me/22

위의 그림에서, 세그먼트 레지스터가 가리키는 세그먼트 디스크립터와 가상 메모리가 조합되면,

선형주소(Linear Address)가 되고, 이는 페이징 기법에 의해 최종적으로 물리주소(Physical Address)가 된다.

 

 

- 종류 : 

CS : Code Segment    // 코드 세그먼트의 시작번지를 가리키는 포인터

        (코드 세그먼트에는 함수나 제어문 같은 명령어들이 저장되어 있다.)

        Instruction Pointer 레지스터가 가진 offset 값과 합쳐서 실행을 위한 명령어 주소를 참조하게 된다. 

SS : Stack Segment  // 스택 세그먼트의 시작번지를 가리키는 포인터

        (스택 세그먼트는 주소와 데이터를 일시적으로 저장하기 위한 곳이다.)

         SP와 BP가 참조한다. 

DS : Data Segment   // 데이터 세그먼트의 시작번지를 가리키는 포인터

        (데이터 세그먼트에는 주로 전역, 정적 변수 데이터가 들어가 있다.)

        AX, CX, DX, SI, DI 레지스터와 합쳐서 데이터 영역의 주소를 참조하게 된다.

 

ES : Extra(Data) Segment   //추가 레지스터로 주로 문자 데이터의 주소를 지정하는데 사용됨

FS : Data Segment  //추가로 도입된 여분의 세그먼트 레지스터

GS : Data Segment  //추가로 도입된 여분의 세그먼트 레지스터

 

ES, FS, GS 세그먼트는 추가적인 데이터 세그먼트이다.

 

 

=> 세그먼트 레지스터를 통해, 원하는 segment 안의 특정 데이터, 명령어들을 정확하게 가져올 수 있다.

 

 

 

#02-3.  플래그 레지스터(EFLAGS)

EFLAGS(Extended Flags Register)는  32bit로, 각각의 비트마다 의미를 갖고 있고, 각 비트는 On/Off를 의미하는 1과 0 (True/False)의 값을 가진다.

일부 비트는 시스템에서 직접 세팅하고, 일부 비트는 프로그램에서 사용된 명령의 수행 결과에 따라 세팅된다.

플래그 레지스터는 상태 플래그, 컨트롤 플래그, 시스템 플래그들로 이루어졌다.

 

시스템이 초기화 되면 이 레지스터는 0x00000002의 값을 가진다. 그리고 1,3,5,15,22~31번 비트는 예약되어 있어 소프트웨어에 의해 조작될 수 없다.

 

https://kimhyun2017.tistory.com/124

( 상태 플래그 )

CF(Carry Flag) : 연산 수행하면서 자리올림(carry), 자리내림(borrow) 발생하면 1이 된다.

unsigned 변수의 오퍼플로우 발생시 1로 세팅됨.

     carry와 borrow는 덧셈 연산시 bit bound(비트범위)를 넘어가거나, 뺄셈하는데 빌려오는 경우

PF(Parity Flag) : 패리티체크하는데 사용됨.

                                  연산결과 최하위 바이트의 값이 짝수일 경우에 1이 된다.

AF(Adjust Flag) : 연산결과 carry나 borrow가 3bit 이상 발생할 경우 1이 됨.

ZF(Zero Flag) : 연산결과가 0이면 1로 세팅됨. if문 같은 조건문 만족시 세팅된다.

SF(Sign Flag) : 연산 결과 최상위 비트값과 같다. Signed 변수일 경우, 양수이면 0, 음수이면 1이다.

OF(Overflow Flag) : Signed(부호있는)변수의 오버플로우가 발생했을때, 1로 세팅된다. MSB(최상위비트)가 변경될 때, 1로 세팅됨

DF(Direction Flag) : 문자열 처리할때, 1일 경우 문자열 처리 instruction이 자동으로 감소, 0일 경우 자동으로 증가한다.

 

 

( 시스템 플래그 )

IF(Interruo enable flag) : 프로세서가 마스크한 인터럽트에 응답하게 하기 위해선 1로 설정해야 한다.

            마스크한 인터럽트는 요청된 인터럽트에 대해 꼭 응답하지 않아도 되는 인터럽트를 말한다. 반대로 항상 응답해야 되는 인터럽트를 마스크 불가능 인터럽트라고 한다. 

TF(Trap flag) : 디버깅 할 때 single-step을 가능하게 하기 위해선 1로 설정한다.

IOPL(I/O privilege level field) :현재 수행중인 프로세스나 작업의 권한 레벨을 가리킨다.

       현재 수행중인 프로세스를 가리키는 CPL이 I/O address 영역에 접근하기 위해선 IOPL보다 작거나 같아야 한다. 

NT(Nested task flag) : 인터럽트의 체인을 제어한다.

          이전 실행 작업(task)과 현재 작업(task)이 연결되어 있으면 1로 설정된다. 

RF(Resume flag) : 예외 디버깅을 하기 위해서 프로세서의 응답을 제어한다. 

VM(Virtual-8086 mode flag) : Virtual-8086모드를 사용하려면 1로 설정한다.

        Virtual-8086은 IA-32의 동작모드의 하나로, CPU가 보호모드로 작동하여 태스크 관리가 이루어질 때, 8086의 코드가 실행되는 가상머신의 구현을 하드웨어로 지원해준다.

AC(Alignment check flag) : 이 비트와 CR0 레지스터의 AM 비트가 설정되어 있으면, 메모리 주소의  alignment(정렬) checking이 가능하다.

VIF(Virtual interrupt flag)  : IF flag의 가상이미지로,  VIP와 결합시켜 사용한다. 

VIP(Virtual interrupt pending flag) : 인터럽트가 pending(경쟁상태)가 되었음을 나타낸다.

ID (Identification flag) : CPUID instruction을 지원하는 CPU 인지를 나타낸다. 

        CPUID는 x86 아키텍처를 위한 프로세서 기계 명령어이다. 

 

 

 

 

#02-4. instruction 포인터 (EIP)

EIP : Instruction Pointer

cpu가 처리할 명령어의 주소를 나타내는 레지스터이다. 

다음에 실행해야 할 명령어가 존재하는 메모리 주소가 저장된다.

현재 명령어를 실행 완료한 후에, EIP 레지스터에 저장되어있는 주소에 위치한 명령어를 실행한다.

(실행전 EIP에는 다음 실행해야 할 명령어가 존재하는 주소값이 저장된다. (자동으로 다음 명령어 길이만큼 EIP를 증가시킨다.))

※ 범용레지스터와 달리 EIP는 그 값을 직접 변경못하고, 특정명령어(JMP,Jcc,CALL,RET)를 사용하거나 인터럽트, 예외를 발생시켜 간접적으로 변경해야 한다. 

'Study > Reversing' 카테고리의 다른 글

[2]PE구조&wow64 fs redirection + a  (0) 2020.09.20
[1]호출규약 + wargame 정리 + a  (0) 2020.09.14
[1]Dreamhack_Rev 0번 문제  (0) 2020.09.12
[1]abex' crackme #1  (0) 2020.09.12
[0]Stack & StackFrame  (0) 2020.09.05
Comments