일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- leetcode 238
- airflow docker
- 배열
- Python
- 머신러닝
- leetcode 5
- leetcode 561
- leetcode 344
- leetcode 819
- leetcode125
- leetcode 234
- 블로그 이전했어요
- Hortonworks Sandbox
- docker로 airflow 설치하기
- leetcode 15
- leetcode
- 컴퓨터구조
- MapReduce 실습
- leetcode 49
- ctf-d
- Hadoop
- 빅데이터를 지탱하는 기술
- 문자열 조작
- 올바른 변수명 짓기
- 데이터레이크와 데이터웨어하우스
- wargame.kr
- webcrawler
- leetcode 121
- leetcode 937
- 스파크 완벽 가이드
- Today
- Total
HyeM
[0]32bit Register 본문
#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 종류
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개
- 용도 : 주로 상수/주소 저장할 때, 또는 특정 레지스터를 조작할 때 사용, 특수한 용도로 사용하기도 함.
++ 위에서 레지스터 이름에 E가 붙으면 16bit의 레지스터가 확장됨을 의미한다고 하였다. 위에서 EAX를 예로 들면 16bit였던 AX가 레지스터가 확장됨을 알 수 있다. 각 레지스터는 16bit 하위 호환을 위하여 몇 개의 구획으로 나누어 지는데, EAX를 예로 들어보자. |
- 종류 :
(산술연산 명령어(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차 기억장치로 부터 데이터를 저장하고 검색하는 메모리 관리 기법
페이지는 일정한 크기를 가진 블록으로, 페이징은 프로세스를 페이지로 잘라서 메모리에 적재하는 방식이다.
위의 그림에서, 세그먼트 레지스터가 가리키는 세그먼트 디스크립터와 가상 메모리가 조합되면,
선형주소(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번 비트는 예약되어 있어 소프트웨어에 의해 조작될 수 없다.
( 상태 플래그 )
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 |