brunch

새로운 루트 확보에 앞서 기본기

CPU 레지스터 어셈블리어 표기법 정리

by Younggi Seo

새로운 공격 루트를 확보하기 위한 공격에 대한 원리를 캐는 섹션에 앞서 gdb(GNU 디버거) 명령을 통해 확인할 수 있었던 어셈블리 언어 표기법에 대해 정리하는 시간을 가지겠다.



gdb$ 명령단에서 x 명령을 통해 메모리 내용을 확인할 수 있었다.

gdb$ x/ (명령 수) i (선두 주소)


gdb에서는 기본적으로 AT&T 표기법이 사용된다. 인텔 표기법/AT&T 표기법은 다음과 같이 변경할 수 있다.


인텔 표기법

mov eax, 5


AT&T 표기법

mov $5, %eax


인텔 명령은 두 번째 오퍼랜드(피연산자)의 값을 첫 번째 오퍼랜드에 저장하지만 AT&T 표기법에서는 첫 번째 오퍼랜드를 두 번째 오퍼랜드에 저장한다. 그리고 위의 예에서도 알 수 있듯이 접두사 또한 다르다. 인텔 표기법에서는 레지스터 이름이나 정수에 접두사가 붙지 않지만 AT&T 표기법에서는 레지스터 이름에는 %를, 정수에는 $를 붙이는 것을 알 수 있다(이걸 구글링 해서도 못 찾았는데).


어느 서적에서는 AT&T 표기법을 이용하고 다른 서적에서는 인텔 표기법이 이용되어 어셈블리 명령에서 오퍼랜드(Operand, 피연산자)의 순서가 뒤바뀌기기도 하는데, gdb 명령단에서 'set disassembly-flavor intel' 명령어로 변경하여 인텔 표기법으로 통일시킬 수 있다.


앞서 우분투 리눅스를 통해 버퍼오버플로우 공격을 실습한 섹션들에서는 AT&T 표기법이었다. 레지스터 값과 관련하여 gdb 단에서의 명령어이다.


1) 레지스터 값을 로딩하려면 p 명령을 사용함.

gdb$ p (레지스터명)


2) i 명령을 통해 일부 레지스터를 제외한 모든 레지스터의 값을 표시할 수도 있다.

gdb$ i r

원래 명령어: info registers


[메모리 덤프 관련]

b: BYTE(1 byte)

h: HALFWORD(2 bytes)

w: WORD(4 bytes)

g: GIANTWORD(8 bytes)


표시 형식은 다음과 같은 것이 있다.

s: 문자열

i: 명령

x: 16진수


만약 x/100wx *0x4010000이라고 쓴다면 메모리 주소 0x4010000부터 4 바이트 단위로 100개분의 메모리값을 16진수로 읽어온다.


gdb$ x/(읽어오고 싶은 크기)(메모리 크기)(표시 형식)(읽어올 메모리의 시작 주소)




참조

우스이 토시노리 외 7인. 양현 역. (2016). CTF 정보보안 콘테스트 챌린저 북: Capture The Flag 문제 풀이로 배우는 해킹 테크닉, 서울: 위키북스.

keyword
매거진의 이전글Section 7-3: RCE testing