배경지식
📌 내 컴퓨터의 환경은 x64아케텍처를 대상으로 하므로 x64만 어셈블리어를 다룬다
mov eax, 3
; opcode operand1 operand2
; 대입해라 eax에 3을
;데이터 이동
mov
lea
;산술 연산
inc
dec
add
sub
;논리 연산
and
or
xor
not
;비교
cmp
test
;분기
jmp, je, jg
;스택
push
pop
;프로시저(Prosedure)
call
ret
leave
;시스템 콜
syscall
; 강교수님 : 기타 등등 많으나 이것만 알아둬도 돼!
; 알아둬야 해
BYTE
WORD 워드, 2byte
DWORD 더블 워드, 4byte
QWORD 쿼터 워드, 8byte
QWORD PTR [0x80488000] ; 0x80488000의 데이터를 8byte만큼 참조
DWRD PTR [0x80488000] ; 0x80488000의 데이터를 4byte만큼 참조
WORD PTR [rax] ; rax가 가리키는 주소에서 데이터를 2byte 만큼 참조
어떤 값을 레지스터나 메모리에 옮기도록 지시
src에 들어있는 값을 dst에 대입
mov dst, src ; src에 들어있는 값을 dst에 대입
; 순서 헷갈리지 말자! 도착지부터 적는거다.
mov rdi, rsi ; rsi의 값을 rdi에 대입
mov QWORD PTR[rdi], rsi ; rsi의 값을 rdi가 가리키는 주소에 대입
mov QWROD PTR[rdi+8*rcx], rsi ; rsi의 값을 rdi+8*rcx가 가리키는 주소에 대입
src의 유효주소(Effective Address, EA)를 dst에 저장
lea dst, src ; src의 유효주소를 dst에 저장
lea rsi, [rbx+8*rcx] ; rbx+8*rcx를 rsi에 대입
dst에 src의 값을 더함
add dst, src ; dst에 src의 값을 더함
add eax, 3 ; eax += 3
add ax, WORD PTR[rdi] ; ax += *(WORD *)rdi
dst에서 src의 값을 뺌
sub dst, src ; dst에서 src의 값을 뺌
sub eax, 3 ; eax -= 3
sub ax, WORD PTR[rdi] ; ax -= *(WORD *)rdi
op의 값을 1 증가시킴
inc op ; op의 값을 1 증가시킴
inc eax ; eax += 1
op의 값을 1 감소 시킴
dec op ; op의 값을 1 감소 시킴
dec eax ; eax -= 1
⚠️ 비트단위로 계산하는 거니까 16진수 → 2진수로 변환하여 계산해야함 귀찮음
dst와 src의 비트가 모두 1이면 1, 아니면 0
and dst, src ; **dst와 src의 비트가 모두 1이면 1, 아니면 0
;[Register]
eax = 0xffff0000
ebx = 0xcafebabe
;[Code]
and eax, ebx
;[Result]
eax = 0xcafe0000**
dst와 src의 비트 중 하나라도 1이면 1, 아니면 0
or dst, src ; **dst와 src의 비트 중 하나라도 1이면 1, 아니면 0
;[Register]
eax = 0xffff0000
ebx = 0xcafebabe
;[Code]
or eax, ebx
;[Result]
eax = 0xffffbabe ; 계산은 시간날때 해보세요**
dst와 src의 비트가 서로 다르면 1, 같으면 0
xor dst src ; **dst와 src의 비트가 서로 다르면 1, 같으면 0
;[Register]
eax = 0xffffffff
ebx = 0xcafebabe
;[Code]
xor eax, ebx
;[Result]
eax = 0x35014541**
op의 비트 전부 반전
not op ; op의 비트 전부 반전
;[Register]
eax = 0xffffffff
;[Code]
not eax
;[Result]
eax = 0x00000000
두 피연산자의 값을 비교하고 플래그를 설
op1과 op2를 비교
cmp op1, op2 ; op1과 op2를 비교
; 대소를 비교하고 플래그만 세울뿐, 결과를 op1에 저장하지는 않음
;[Code]
1: mov rax, 0xA
2: mov rbx, 0xA
3: cmp rax, rbx ; ZF=1
op1과 op2를 비교
test op1, op2 ; op1과 op2를 비교
; AND연산 취함 결과는 op1에 대입 안함
;[Code]
1: xor rax, rax
2: test rax, rax ; ZF=1
; ZF플래그를 보고 rax가 0이였는지 판단
rip를 이동시켜 실행 흐름을 바꿈
⚠️ 분기문은 엄청 많지만 여백이 좁아 정리할 수 없다 고로 앞으로 알아가도록
addr로 rip를 이동시킴
📌 rip란?
프로세서가 읽고 있는 현재 명령의 위치를 가리키는 명령 포인터
jmp addr ; addr로 rip를 이동시킴
;[Code]
1: xor rax, rax
2: jmp 1 ; jump to 1
직전에 비교한 두 피연산자가 같으면 점프 (jump if equal)
je addr ; **직전에 비교한 두 피연산자가 같으면 점프 (jump if equal)**
;[Code]
1: mov rax, 0xcafebabe
2: mov rbx, 0xcafebabe
3: cmp rax, rbx ; rax == rbx
4: je 1 ; jump to 1
직전에 비교한 두 연산자 중 전자가 더 크면 점프 (jump if greater)
jg addr ; **직전에 비교한 두 연산자 중 전자가 더 크면 점프 (jump if greater)
;[Code]
1: mov rax, 0x31337
2: mov rbx, 0x13337
3: cmp rax, rbx ; rax > rbx
4: jg 1 ; jump to 1**