objdump : GNU 개발 툴 중 컴파일된 바이너리 파일을 볼 수 있다.
-D : 모든 파일을 다 디스어셈블
정규표현식으로 main.:을 사용하고 20줄만 출력되게 파이프로 -A20
첫번째 줄 8048374는 메모리 주소
AT&T와 인텔 문법이 있는데 문법 앞에 %와 $가 있으면 AT&T 문법이다.
a.out의 AT&T문법
a.out의 인텔 문법
0x252 x86 프로세서
프로그래머는 컴파일된 프로그램을 한 단계식 보며 프로그램 메모리를 검사하고 프로세서 레지스터를 보기 위해 디버거를 사용한다.
GDB -
main 함수에 중지점(breakpoint)을 설정돼 코드 실행 직전에 멈춘다.
(누산기eax, 카운터ecx,데이터edx,베이스ebx)는 범용 레지스터
(스택 포인터esp, 베이스 포인터ebp, 근원지 인덱스esi, 목적지 인덱스edi)
ESP, EBP는 32비트 주소를 저장해서 포인터라 불림
ESI, EDI는 불러오기(LOAD명령)과 저장하기 명령에 쓰이지만 대부분 범용 레지스터
EIP레지스터는 프로세서가 읽고 있는 현재 명령의 위치를 가리키는 명령 포인터 레지스터다
eflags는 비교와 메모리 분할을 위한 몇 비트의 플래그로 이뤄져 있다.
0x253 어셈블리 언어
gdb 사용 시 setdisassembly intel -> set dis intel 명령어로 역어셈블 표기를 인텔로 설정할 수 있다.
인텔 문법으로 바뀌었으므로
명령 <목적지>, <근원지>
목적지와 근원지에는 직관적 연상 기호(Mnemonic)이 들어가는데 mov 명령은 값을 이동, cmp는 값을 비교, j로 시작하는 명령은 코드의 다른 부분으로 점프 등이 있다.
gdb컴파일러 사용 시 gdb에서 소스코드를 볼 수 있는 추가 디버그 정보를 포함시키려면 -g 옵션 사용
list 명령으로 소스코드가 출력되고 main() 함수의 역어셈블이 출력된다.
그리고 main에 중지점을 설정하고 실행하고 eip를 출력해서 보면 0x08048394의 메모리 주소를 가지고 있으며 함수 프롤로그라고 한다.
main() 함수의 나머지 전역 변수를 위한 메모리를 할당하려고 컴파일러가 자동으로 생성한 것이다.
examine == x(축약) 명령을 사용해 메모리를 조사
examine은 메모리 위치와 메모리를 어떻게 보여줄지에 대한 두개의 인자가 필요하다.
- o - 8진법으로 보기
- x - 16진법으로 보기
- u - 부호가 없는(unsigned) 표준 10진법으로 보기
- t - 2진법으로 보기
info register eip == i r eip(축약)
$eip는 그 순간에 가지는 값을 의미
메모리의 단일 유닛 기본 크기는 4바이트 워드다.
- b - 단일 바이트
- h - 2바이트의 하프워드
- w - 4바이트의 워드
- g - 8바이트의 자이언트
DWORD = double word = 4바이트
x/8xb와 x/8xh의 값의 차이가 보이는데
0xc7 0x45 ==> 0x45c7 처럼 역바이트 현상을 볼 수 있다.
이는 x86프로세서에서 리틀 엔디언(맨 하위 바이트를 처음에 저장)으로 바이트 순서를 저장해서 그렇다.
- 4개의 단일 바이트(x/4xb)와 1개의 워드(x/1xw) 비교
instruction == i(축약) 문자로 명령 메모리 보기
next instruction == nexti(축약)
해킹 공격의 예술 66~154까지
파이썬 해킹 19~113까지