ch@e
article thumbnail

어셈블리어

컴퓨터의 기계어와 치환되는 언어, CPU에서 사용되는 ISA의 종류가 다양한데 이 종류만큼 많은 수의 어셈블리어가 존재한다. 

 

X64 어셈블리 언어 

기본 구조: 명령어(Operation Code, Opcode, 동사에 해당함), 피연산자(Operand, 목적어에 해당함)

어셈블리어 문법 구조 예시

 

피연산자

피연산자에서 올 수 있는 3가지

-상수(lmmediate Value)

-레지스터(Register)

-메모리(Memory): []으로 둘러싸여 표현, 앞에 크기 지정자 TYPE PTR이 추가될 수 있음(TYPE에는 BYTE, WORD, DWORD, QWORD가 올 수 있고 각 1,2,4,8, 바이트의 크기를 지정한다.

-ex)메모리 피연산자의 예

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

 

데이터 이동 명령어

어떤 값을 레지스터나 메모리에 옮기도록 지시한다.

 

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에 대입

 

산술 연산 명령어

덧셈, 뺄셈, 곱셈, 나눗셈 연산을 지시한다 

 

ex) add dst, src : dst에 src의 값을 더한다.

add eax, 3 eax += 3
add ax, WORD PTR[rdi] ax += *(WORD *)rdi

ex) sub dst, src: dst에서 src의 값을 뺀다.

sub eax, 3 eax -= 3
sub ax, WORD PTR[rdi] ax -= *(WORD *)rdi

ex) inc op: op의 값을 1 증가시킴

inc eax eax += 1

ex) dec op: op의 값을 1 감소 시킴

dec eax eax -= 1

 

논리 연산 명령어

and, or, xor, neg 등의 비트 연산을 지시한다.(비트 단위로)

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 & not

 

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를 비교

cmp는 두 피연산자를 빼서 대소를 비교하고 연산의 결과는 op1에 대입하지 않는다.

 

 

명령어 분류

명령 코드
데이터 이동(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

 

요약

데이터 이동 연산자
mov dst, src: src의 값을 dst에 대입
lea dst, src: src의 유효 주소를 dst에 대입

 

산술 연산
add dst, src: src의 값을 dst에 더함
sub dst, src: src의 값을 dst에서 뺌
inc op: op의 값을 1 더함
dec op: op의 값을 1 뺌

 

논리 연산
and dst, src: dst와 src가 모두 1이면 1, 아니면 0
or dst, src: dst와 src스택

push val : rsp를 8만큼 빼고, 스택의 최상단에 val을 쌓습니다.

pop reg: 스택 최상단의 값을 reg에 넣고, rsp를 8만큼 더합니다.



프로시저

call addr: addr의 프로시저를 호출합니다.

leave: 스택 프레임을 정리합니다.

ret: 호출자의 실행 흐름으로 돌아갑니다.



syscall: 커널에게 필요한 동작을 요청합니다.

중 한 쪽이라도 1이면 1, 아니면 0
xor dst, src: dst와 src가 다르면 1, 같으면 0
not op: op의 비트를 모두 반전


비교
cmp op1, op2: op1에서 op2를 빼고 플래그를 설정
test op1, op2: op1과 op2에 AND 연산을 하고, 플래그를 설정


분기
jmp addr: addr로 rip 이동
je addr: 직전 비교에서 두 피연산자의 값이 같을 경우 addr로 rip 이동
jg addr: 직전 비교에서 두 피연산자 중 전자의 값이 더 클 경우 addr로 rip 이동

 

'System & Reversing 필기' 카테고리의 다른 글

[DreamHack] shell_basic 풀이  (0) 2023.05.08
DreamHack Stage2(컴퓨터 구조)  (0) 2023.05.01
DreamHack Stage2( 리눅스 메모리 구조)  (0) 2023.05.01
BoF  (0) 2023.03.18
x86, x64 레지스터  (0) 2023.03.18
profile

ch@e

@ch@e

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!

검색 태그