x86-64 register shortcut

우리가 흔히 gdb에서 i r 명령어를 쳐보면

Shell
pwndbg> i r
rax            0x0                 0
rbx            0x138d0             80080
rcx            0x0                 0
rdx            0x0                 0
rsi            0xffff888000020800  -131391639386112
rdi            0x138d0             80080
rbp            0xffffffff81c03f30  0xffffffff81c03f30
rsp            0xffffffff81c03f28  0xffffffff81c03f28
r8             0xffffffff81da3000  -2116407296
r9             0xffffffffffff      281474976710655
r10            0xffffffff81c03ef0  -2118107408
r11            0xffffffff0000ffff  -4294901761
r12            0x0                 0
r13            0x0                 0
r14            0x0                 0
r15            0x0                 0
rip            0xffffffff81cf9ec6  0xffffffff81cf9ec6 <start_kernel>
eflags         0x46                [ IOPL=0 ZF PF ]
cs             0x10                16
ss             0x0                 0
ds             0x0                 0
es             0x0                 0
fs             0x0                 0
gs             0x0                 0
fs_base        0x0                 0
gs_base        0xffffffff81cd7000  -2117242880
k_gs_base      0x0                 0
cr0            0x80050033          [ PG AM WP NE ET MP PE ]
cr2            0xffff8880000138d0  -131391639439152
cr3            0x1d2e000           [ PDBR=7470 PCID=0 ]
cr4            0xa0                [ PGE PAE ]
cr8            0x0                 0
efer           0xd01               [ NXE LMA LME SCE ]

다음과 같이 수많은 레지스터가 존재한다. r15까지는 흔히 아니깐 pass를 하고 나머지 특수 레지스터에 대해 분석하는 글들을 위한 shortcut글이다.

항목이게 “무엇”Linux x86-64에서 보통 의미값이 꼬이면 자주 나는 증상shortcut( 추가적으로 분석한 글)
eflags (rflags)CPU 상태 플래그(조건/제어 비트 묶음)IF(인터럽트 허용), ZF/PF/CF/SF/OF(연산 결과 플래그), IOPL(I/O 권한 레벨) 등IF=0이면 인터럽트가 막혀서 시스템이 멈춘 듯 보이거나 타이밍이 달라짐. iretq 복귀 시 “이상한 RFLAGS”면 fault 유발 가능
cs코드 세그먼트 선택자(현재 CPL=권한레벨도 여기로 결정)보통 커널=0x10, 유저=0x33 같은 식(GDT 구성에 따라)CPL/세그 선택자가 부적절하면 #GP/#SS/#PF 등
ss스택 세그먼트 선택자롱모드에선 베이스는 무시되지만 권한/검증에는 여전히 관여iretq로 CPL 바꾸며 복귀할 때 스택 관련이 틀리면 #SS/#GP
ds, es데이터 세그 선택자롱모드에선 거의 의미 없음(베이스/리밋 무시). 보통 0으로 둬도 크게 상관 없는 경우 많음대개 문제 원인 아닐 때가 많음
fs, gs세그 선택자(“selector”) 그 자체selector 값 자체보다 fs_base/gs_base가 핵심selector보다 base가 중요
fs_baseFS 세그먼트 베이스 주소**유저 TLS(Thread-Local Storage)**에 거의 항상 사용됨. glibc는 fs_base를 TCB(스레드 제어블록) 시작점으로 둬서 fs:[offset]로 errno, thread pointer, canary 등 접근TLS 깨지면 유저랜드에서 이상한 segfault/스택카나리 문제/스레드 관련 크래시
gs_baseGS 세그먼트 베이스 주소리눅스 커널은 흔히 gs_base를 per-CPU 영역(CPU별 데이터)이나 현재 태스크 포인터 등에 쓰는 패턴이 많음(설정/커널버전에 따라 다름)잘못된 값이면 커널 진입/복귀 흐름에서 즉시 폭발(#GP/#PF)하기 쉬움
k_gs_base“커널용 GS 베이스”로 쓰이는 값(디버거가 별도로 보여주는 경우)개념적으로는 “커널이 쓰고 싶어하는 GS base”가 따로 있고, 유저/커널 전환 때 SWAPGS로 서로 바꿔 쓰는 모델과 연결됨swapgs 타이밍이 틀리거나 엇갈리면 per-CPU 참조가 틀어져 바로 fault
cr0시스템 제어 레지스터 0PG(페이징 on), WP(커널도 read-only 페이지에 write 금지), PE(보호모드) 등 핵심 제어비트PG 등 핵심 비트가 이상하면 아예 시스템이 제대로 실행 불가
cr2페이지 폴트가 난 선형 주소#PF 발생 시 “어느 주소 접근하다가” 터졌는지 여기에 남음크래시 분석에서 제일 먼저 보는 값
cr3페이지 테이블 기준 주소(PML4) + PCID 등프로세스/주소공간이 바뀔 때 CR3가 바뀜. “유저 주소공간이 context switch마다 바뀌나?”의 핵심이 이거CR3/페이지테이블이 틀리면 즉시 #PF 연쇄what is CR3 register
cr4시스템 제어 레지스터 4PAE, PGE, SMEP/SMAP(설정 시) 등 메모리 보호/페이징 확장 기능SMEP/SMAP 같은 보호기능이 켜져 있으면 특정 종류의 잘못된 접근이 곧바로 fault
cr8Task Priority Register(TPR)APIC 인터럽트 우선순위/마스킹에 관여(주로 커널이 인터럽트 제어에 사용)보통 유저가 직접 신경쓸 일은 적지만 커널 디버깅 땐 의미 있음
eferExtended Feature Enable Register(MSR)LME/LMA(64비트 모드), NXE(NX 비트), SCE(SYSCALL/SYSRET) 등NXE/LMA 등 핵심이 꺼져 있으면 64비트 운영 자체가 불가/불안정