Hacking/DreamHack 시스템 해킹 강의
[ Dreamhack ] 어셈블리어와 x86-64(1)
미역줄기줄기
2024. 2. 5. 11:17
728x90
어셈블리 언어
컴퓨터의 기계어와 치환되는 언어이다. 기계어의 종류만큼 어셈블리어의 종류도 존재한다.
x64 어셈블리 언어
기본구조
동사에 해당하는 명령어와 목적어에 해당하는 피연산자로 구성된다.
mov r4, r0
해석: r4에 r0를 대입해라! ( r4,r0는 레지스터이다 )
그럼 여기서 명령어는 뭘까? 바로 mov이다. 피연산자는? r4, r0이다~
명령어
명령코드 | |
데이터 이동 | mov, lea |
산술 연산 | inc, dec, add, sub |
논리 연산 | and, or, xor, not |
비교 | cmp, test |
분기 | jmp, je, jp |
스택 | push, pop |
프로시져 | call, ret, leave |
시스템 콜 | syscall |
피연산자
- 상수
- 레지스터
- 메모리
이렇게 세 가지의 종류가 있다. ( 좀 전의 예시에도 레지스터가 피연산자로 나왔다. )
메모리 피현산자는 []으로 둘러싸인 것으로 표현되며, 앞에 크기 지정자 TYPE PTR이 추가될 수 있다. 여기엔 BYTE(1byte), WORD(2byte) , DWORD(4byte) , QWORD(8byte) 가 올 수 있다.
QWORD PTR [0x8048000] //0x8048000의 데이터를 8바이트만큼 참조
DWORD PTR [0x8048000] //0x8048000의 데이터를 4바이트만큼 참조
WORD PTR [rax] //rax가 가리키는 주소에서 데이터를 2바이트 만큼 참조
데이터 이동
mov rdi, rsi //rsi의 값을 rdi에 대입
mov QWORD PTR[rdi], rsi //rsi의 값을 rdi가 가리키는 주소에 대입
mov QWORD PTR[rdi+8*rcx], rsi // rsi의 값을 rdi+8*rcx가 가리키는 주소에 대입
lea rsi, [rbx+8*rcx] //rbx+8*rcx를 rsi에 대입
산술 연산
#add dst, src : dst에 src의 값을 더합니다.
add eax, 3 //eax += 3
add ax, WORD PTR[rdi] //ax += *(WORD *)rdi
#sub dst, src: dst에서 src의 값을 뺍니다.
sub eax, 3 //eax -= 3
sub ax, WORD PTR[rdi] //ax -= *(WORD *)rdi
#inc op: op의 값을 1 증가시킴
inc eax //eax += 1
#dec op: op의 값을 1 감소 시킴
dec eax //eax -= 1
논리 연산
비트 단위로 이루어진다.
and dst, src: dst와 src의 비트가 모두 1이면 1 아니면 0
or dst, src: dst와 src의 비트 중 하나라도 1이면 1 아니면 0
xor dst, src: dst와 src의 비트가 서로 다르면 1, 아니면 0
not op: op의 비트 전부 반전
cmp op1, op2: op1과 op2를 비교
분기
분기 명령어는 rip를 이동시켜 실행 흐름을 바꾼다.
jmp addr | addr로 rip를 이동시킨다 |
je addr | 직전에 비교한 두 피연산자가 같으면 점프 |
jg addr | 직전에 비교한 두 연산자 중 전자가 더 크면 점프 |