안 쓰던 블로그

레지스터 본문

CTF/Pwnable

레지스터

proqk 2020. 10. 13. 13:32
반응형

전에 리버싱 공부하면서 레지스터를 정리한 적이 있다 foxtrotin.tistory.com/266

다시 기억할 겸 정리

 

레지스터는 CPU 내부에 존재하는 작고 고속인 다목적 메모리이다

종류로는 범용, 세그먼트, 상태 플래그, 명령 포인터 등등.. 이 있다

 

범용 레지스터는 논리, 수리 연산에 사용되는 피연산자, 주소를 계산하는 사용되는 피연산자, 메모리 포인터가 저장된다

세그먼트 레지스터는 코드 세그먼트, 데이터 세그먼트, 스택 세그먼트를 가리키는 주소가 들어 있다 (세그먼트?: foxtrotin.tistory.com/312)

플래그 레지스터는 프로그램의 현재 상태나 조건 등을 검사하는 데 사용되는 플래그들이 들어 있다

명령 포인터(인스트럭션 포인터)는 다음에 수행해야 하는 명령이 있는 메모리 상의 주소가 들어 있다

 

범용 레지스터

EAX: 입출력, 산술, 논리 연산을 수행하는 누산기 레지스터로 함수의 리턴값을 저장한다(32비트)-AX(하위 16비트)-AH(상위 8비트)/AL(하위 8비트)

EBX: ESI나 EDI와 결합하여 주소 지정을 확장하기 위한 인덱스으로서 사용(32비트)-BX(16비트)-BH/BL(8비트)

ECX: 반복 명령어 사용시 반복 카운터로 사용(32비트)-CX(16비트)-CH/CL(8비트)

EDX: EAX의 보조적인 역할로 쓰이며 큰 수의 산술, 논리 연산 등에서 부호 확장 명령에 사용(32비트)-DX(16비트)-DH/DL(8비트)

ESI: DS레지스터가 가리키는 데이터 세그먼트 내의 어느 데이터를 가리킨다. 문자열에서는 출발지를 가리킨다

EDI: ES레지스터가 가리키는 데이터 세그먼트 내의 어느 데이터를 가리킨다. 문자열에서는 목적지를 가리킨다

ESP: SS레지스터가 가리키는 스택 세그먼트 맨 꼭대기를 가리키는 포인터

EBP: SS레지스터가 가리키는 스택 상의 한 데이터를 가리키는 포인터

 

세그먼트 레지스터

CS: 코드 세그먼트를 가리킨다

DS, ES, FS, GS: 데이터 세그먼트를 가리킨다

SS: 스택 세그먼트를 가리킨다

 

이렇게 세그먼트 레지스터가 가리키는 위치를 바탕으로 우리가 원하는 세그먼트 안의 특정 데이터, 명령어들을 정확하게 끄집어 낼 수가 있다

 

플래그 레지스터

컨트롤 플래그 레지스터는 상태 플래그, 컨트롤 플래그, 시스템 플래그들의 집합이다

 

상태 플래그(Status flags)

CF: carry flag. 연산 수행 중 carry나 borrow가 발생하면 1된다. carry와 borrow는 덧셈 올림수이거나 뺄셈에서 수 빌려오기를 말한다.

PF: parity flag. 연산 결과 1비트들의 개수에 따라 짝수/홀수 패리티를 나타낸다. 패리티 체크에 사용한다

AF: adjust flag. 연산 결과 carry나 borrow가 3bit이상 발생하면 1이다

ZF: zero flag. 연산 결과가 0일 때 세트(1) 된다. 연산 결과가 0이 아니면 해제(0)된다

SF: sign flag. 연산 결과가 음수가 되면 세트(1)된다. 연산 결과가 양수가 되면 해제(0)된다

OF: overflow flag. 오버플로우 플래그, 부호 있는 연산 결과가 용량보다 클 때(=오버플로우) 세트(1)된다

 

DF: direction flag. 문자열을 이동하거나 비교할 때 문자열의 처리 방향에 따라 세트되어 방향을 결정한다

 

시스템 플래그(system flags)

IF: interrupt flag. 키보드 입력같은 외부 인터럽트의 처리를 하며면 1

TF: trap flag. 디버깅 시 single-step 프로세서 연산 사용하려면 1

IOPL: I/O privilege level flag. 현재 수행 중인 프로세스의 권한을 가리키는 CPL이 I/O 주소 영역에 접근하기 위해서는 같거나 작은 값이 있어야 한다

NT: nested task flag. 인터럽트의 체인 제어. 1이면 연결되어 있음을 의미

RF: resume flag. 예외처리 디버깅하기 위해 프로세서의 응답 제어

VM: virtual-8086 mode flag. 버추얼8086 모드를 사용하려면 1

AC: alignment check flag. 이 비트+CR0레지스터에 AM비트가 1이면 메모리 레퍼런스에 alignment 체킹이 가능하다

VIF: virtual interrupt flag. IF flag의 가상 이미지이다. VIP랑 같이 사용

VIP: virtual interrupt pending flag. 인터럽트가 경쟁 상태(pending)이 되었다는 의미

ID: identification flag. CPUID 구조를 지원하는 CPU인지를 의미

 

 

명령 포인터

다음 명령어의 위치를 가리킨다

명령어 뿐만 아니라 JMP, CALL, RET, IRET 구조가 있는 구조값을 가진다

Instruction Pointer 줄여서 IP고, x86에서는 e, x64에서는 r붙여서 eip/rip라고 한다

 

EIP레지스터는 소프트웨어에 의해 직접 엑세스 할 수 없고, JMP, CALL같은 control-transfer instuction이나 interrupt나 exception에 의해서 제어된다

 


 

sfp와 ret 글(foxtrotin.tistory.com/351)에서 ebp, eip라는 것이 등장했다

위에서 다룬 내용을 가지고 정리하면 아래와 같다

 

ebp/rbp는 베이스 포인터로, 스택 프레임의 시작 지점 주소가 저장된다. 현재 사용되는 스택 프레임이 소멸되지 않는 동안은 ebp의 값이 변하지 않는다. 현재 스택 프레임이 소멸되면 이전에 사용되던 스택 프레임을 가리키게 된다 (스택의 시작점)

 

esp/rsp는 스택 포인터로, 스택 프레임의 끝 지점 주소가 저장된다. push나 pop명령에 따라 esp값이 변한다 (스택의 꼭대기)

 

eip/rip는 다음에 실행할 명령이 들어 있는 메모리 주소를 가리킨다

 

 

앞에 e가 붙으면 x86의 레지스터(32비트), r이 붙으면 x64의 레지스터(64비트)이다

그리고 e~는 4바이트, r~은 8바이트이다

x86에서 x64가 되면서 레지스터 이름과 크기가 변화했기 때문인데, 그렇기 때문에 e~가 사용되지 않는 건 아니다. eax라는 건 rax 레지스터의 하위 4바이트를 의미하는 이름이라고 알면 된다

 

반응형

'CTF > Pwnable' 카테고리의 다른 글

32bit ROP  (0) 2020.11.10
32bit와 64bit - x86과 x64 비교  (0) 2020.10.13
스택과 SFP와 RET  (0) 2020.10.13
pwntools을 이용한 문제 풀이-double pistol  (0) 2020.09.15
pwntool을 이용한 문제 풀이  (0) 2020.09.15
Comments