본문 바로가기

[Dreamhack] x86 Assembly (1) 정리

@rn1p4st2022. 7. 22. 00:29
반응형

어셈블리 언어와 어셈블러가 있다.

어셈블러는 어셈블리어 코드를 컴퓨터가 이해할 수 있는 기계어로 코드를 치환해준다.

소프트웨어를 역분석 하기위해, 기계어를 어셈블리 언어로 번역하는 역어셈블러(Disassembler)를 개발했다.

 

어셈블리 언어는 아키텍처마다 여러 종류가 있다.

 

x64 어셈블리 언어의 기본 구조

구조는 명령어 즉, Operation Code(Opcode)와 피연산자(Operand)로 구성 된다.

mov eax, 3

mov는 opcode로 대입하라. eax와 3은 각각 operand1, operand2를 나타낸다. operand1에 operand2를 대입하라는 문장이다.

 

명령코드

데이터 이동(Data Transfer) mov, lea
산술 연산(Arithmetic) inc, dec, add, sub
논리 연산(Logical) and, or, xor, not
비교(Comparison) cmp, test
분기(Branch) jmp, je, jg
스택(Stack) push, pop
프로시져(Procedure) call, ret, leave
시스템 콜(System call) syscall

 

피연산자

피연산자에는 총 3가지 종류가 올수 있는데, 상수와 레지스터, 메모리가 있다.

메모리 피연산자는 []로 둘러싸인 것으로, 앞에 크기 지정자 TYPE PTR이 추가 될 수 있다. 타입으로는 BYTE, WORD, DWORD, QWORD가 올 수 있으며, 각각 1바이트, 2바이트, 4바이트, 8바이트의 크기를 지정한다.

QWORD PTR [0x8048000] 0x8048000의 데이터를 8바이트만큼 참조
DWORD PTR [0x8048000] 0x8048000의 데이터를 4바이트만큼 참조
WORD PTR [rax] rax가 가르키는 주소에서 데이터를 2바이트 만큼 참조

 

x86-64 어셈블리 명령어


데이터 이동

mov dst, src : src에 들어있는 값을 dst에 대입

mov rdi, rsi rsi의 값을 rdi에 대입
mov QWORD PTR[rdi], rsi rsi의 값을 rdi가 가리키는 주소에 대입
mov QWORD PTR[rdi+8*rcx], rsi rsi의 값을 rdi+8*rcx가 가리키는 주소에 대입

lea dst, src : src의 유효 주소(Effective Address, EA)를 dst에 저장합니다.

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

[Register]
eax = 0xffff0000
ebx = 0xcafebabe

[Code]
and eax, ebx

[Result]
eax = 0xcafe0000

 

or dst, src: dst와 src의 비트 중 하나라도 1이면 1, 아니면 0

[Register]
eax = 0xffff0000
ebx = 0xcafebabe
[Code]
or eax, ebx
[Result]
eax = 0xffffbabe

xor dst, src: dst와 src의 비트가 서로 다르면 1, 같으면 0

[Register]
eax = 0xffffffff
ebx = 0xcafebabe
[Code]
xor eax, ebx
[Result]
eax = 0x35014541

not op: op의 비트 전부 반전

[Register]
eax = 0xffffffff
[Code]
not eax
[Result]
eax = 0x00000000

비교

두 피연산자의 값을 비교하고, 플래그를 설정한다.

cmp op1, op2 : op1과 op2를 비교

두 피연산자를 빼서 대소를 비교한다.

 

test op1, op2 : op1과 op2를 비교

두 피연산자에 AND 비트연산을 취한다.

분기

rip를 이동시켜 실행 흐름을 바꾼다.

jmp addr : addr로 rip를 이동시킨다.

 

je addr: 직전에 비교한 두 피 연산자가 같으면 점프

 

jg addr : 직전에 비교한 두 연산자 중 전자가 더 크면 점프

반응형
rn1p4st
@rn1p4st :: 푸들푸들

RECORD STUDY

목차