시스템 해킹을 다시 차근차근 정리하면서 공부하기로 했으므로 글도 쓸겸 여기에 쭉 정리해 볼 생각입니다.
레지스터(Register)
레지스터는 CPU가 빠르게 데이터를 저장하고 사용할 때 이용하는 보관소입니다.
산술 연산에 필요한 데이터를 저장하거나 주소를 저장하고 참조하는 등 다양한 용도로 사용되는데, 그냥 변수라고 생각하시면 됩니다.
레지스터는 범용 레지스터, 세그먼트 레지스터, 명령어 포인터 레지스터, 플래그 레지스터가 존재합니다.
범용 레지스터
범용 레지스터는 주용도가 정해져 있긴 하나 다양한 용도로 사용될 수 있습니다.
x64에서는 각각 8바이트를 저장가능하며, 부호 없는 정수를 기준으로 2^64 -1 까지의 수를 나타낼 수 있습니다.
아래는 자주 쓰는 범용 레지스터들과 주용도입니다. 이외에도 x64에는 r8 ~ r15까지의 범용 레지스터가 더 있습니다.
세그먼트 레지스터
x64에는 cs, ss, ds, es, fs, gs 총 6가지 세그먼트 레지스터가 존재하고 각 레지스터의 크기는 16비트입니다.
명령어 포인터 레지스터
rip라는 명령어 포인터 레지스터는 CPU가 수많은 기계어 코드 속에서 어느 부분의 코드를 실행할지 가리켜주는 레지스터입니다. 크기는 8바이트입니다.
플래그 레지스터
플래그 레지스터는 프로세서의 현재 상태를 저장하고 있는 레지스터입니다. x64에는 RFLAGS라는 64비트 크기의 플래그 레지스터가 존재합니다.
플래그 레지스터는 깃발을 올리고, 내리는 행위로 신호를 전달하듯이 자신을 구성하는 비트들로 현재 CPU 상태를 표현합니다.
아래 사진은 자주 사용하는 플래그 레지스터와 그 의미입니다.
레지스터 구성
x64 레지스터는 8바이트 크기를 가지고 있는데 옛날 32비트에서 쓰던 레지스터가 확장된 개념입니다.
32비트에서는 rax가 eax가 되고 크기가 4바이트가 됩니다.
또 그 eax에서 과거 16비트 시절에는 ax라는 2바이트짜리 레지스터를 썼고 그 ax레지스터도 나눠서 상위 1바이트는 ah, 하위 1바이트는 al이라고 합니다.
어셈블리
어셈블리는 기본적인 명령어만 정리하겠습니다.
인텔 문법 기준으로 설명하겠습니다.
push : 스택에 특정 값을 넣고 rsp를 뺀다(64비트일 경우 8, 32비트일 경우 4)
pop : 특정 값에 esp가 현재 가리키고 있는 값을 넣고 rsp를 더한다(64비트일 경우 8, 32비트일 경우 4)
nop : 아무 동작도 하지 않고 다음 명령어로 넘어감
mov a, b : b를 a에 복사한다(a = b라고 생각하면 편함)
lea a, [b] : b의 주소에 있는 값을 a에 복사한다 (a = *b)
cmp a, b : a와 b를 비교한다 (비교 후 위에 설명한 플래그 레지스터가 바뀝니다. 그걸 기준으로 분기나 다른 동작을 함)
add a, b : a와 b를 더해서 a에 결과를 넣는다 (a += b)
sub a, b : a와 b를 빼서 a에 결과를 넣는다 (a -= b)
xor a, b : a와 b를 xor연산 후 a에 결과를 넣는다
inc a : a에 1을 더함
dec a : a에 1을 뺌
je : 비교 값이 같은 경우 점프
jne : 비교 값이 다른 경우 점프
call : 해당 프로시저를 호출
jmp : 해당 주소로 점프
메모리 구조
리눅스에서는 프로세스의 메모리를 세그먼트로 구분합니다.
세그먼트란 적재되는 데이터의 용도별로 메모리를 나눈 공간이라고 보면됩니다.
크게 코드, 데이터, BSS, 힙, 스택으로 나뉩니다.
세그먼트를 나누면 각 용도에 맞게 적절한 권한을 부여할 수 있는 장점이 있습니다. 권한은 읽기, 쓰기, 실행이 존재하며 CPU는 메모리에 대해 권한이 부여된 행위만 할 수 있습니다.
코드 세그먼트
코드 세그먼트는 실행 가능한 코드가 저장된 영역입니다.
일반적으로 읽기, 실행 권한을 가지고 있으며, 예를 들어 main()등의 함수 코드가 위치 합니다.
데이터 세그먼트
데이터 세그먼트는 초기화된 전역변수 또는 상수가 위치하는 영역입니다.
읽기와 쓰기 권한 또는 읽기 전용 권한(상수가 위치한 rodata영역)을 가지고 있습니다.
BSS 세그먼트
BSS 세그먼트는 초기화 되지 않은 데이터가 위치하는 영역입니다.
읽기와 쓰기 권한을 가지고 있으며 주로 초기화되지 않은 전역 변수가 위치 합니다.
스택 세그먼트
스택 세그먼트는 임시 변수가 저장되는 영역입니다.
읽기와 쓰기 권한을 가지고 있으며 주로 지역 변수, 함수의 인자 등이 위치합니다.
힙 세그먼트
힙 세그먼트는 실행 중 동적으로 사용되는 영역으로 읽기와 쓰기 권한을 가지고 있으며,
malloc(), calloc()같은 함수등으로 할당 받은 메모리가 위치합니다.
'Pwn' 카테고리의 다른 글
우분투 세팅(18.04) (5) | 2022.02.13 |
---|---|
gcc -m32 컴파일 오류 (0) | 2022.01.06 |