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 직전에 비교한 두 연산자 중 전자가 더 크면 점프