본문 바로가기

리버싱

[리버싱] 어셈블리어란





어셈블리어의 구조



어셈블리어는 기본적으로 명령어 (OpCode) 와 오퍼랜드 (Operand) 로 이루어져 있다. Operand 는 명령어 다음에 오는 레지스터 이름이나 값 즉, 명령 대상이 되는 레지스터나 값이다. 명령어를 Operator (연산자) 라고 부르며 이러한 Operator 의 종류에 따라 오퍼랜드의 개수가 다르다.


EX)    MOV       EAX,         val1

operator operand1, operand2





어셈블리어 문법



어셈블리어의 문법에는 크게 Intel 방식과 AT&T 방식이 있는데 그 둘의 차이점은 다음과 같다.



Register 이름


AT&T 문법에서는 모든 레지스터 이름 앞에 %가 붙는다. 이는 레지스터와 다른 심볼을 혼동하지 않게 하는 장점이 있다. 


예를 들어 eax 레지스터를 나타내는 경우


AT&T : %eax 

Intel : eax




Operand 순서


AT&T 문법에서는 원본(source)이 왼쪽, 목적지(destination)가 오른쪽에 위치한다. Intel 문법에서는 이와 반대로 되어있다. 


예를 들어 eax 에서 ebx 레지스터로 데이터를 복사하는 경우


AT&T : movl %eax, %ebx

Intel : mov ebx, eax




Operand 크기 지정


operand 의 크기를 지정할 때 크기에 따라 b (byte), w (word), l (long) 접미사를 명령어에 붙인다.


operand 로 지정된 레지스터를 가지고 크기를 판단할 수 있을 때는 이를 생략할 수 있으며, 판단할 수 없는 경우 32-bit 연산으로 가정하게 된다. 


operand가 레지스터가 아니라 메모리인 경우는 반드시 접미사를 붙이는 게 좋다. 


Intel 에서는 byte ptr, word ptr, dword ptr 같은 지시자 (specifier) 를 사용하여 이를 나타낸다. 


예를 들어 word 크기의 foo 값을 bx 로 복사하는 경우


AT&T : movw foo, %ax

Intel : mov ax, word ptr [foo]




상수 (constant) 와 immediate 값


모든 상수와 immediate 값에는 $가 붙는다. 예를 들어 숫자 5를 나타내려면 $5라고 한다. 


변수의 주소를 나타낼 때에도 앞에 $를 붙인다. 예를 들어 foo 란 변수의 주소는 $foo 이다. 그냥 foo 라고 하면 변수의 값을 나타내게 된다.


foo 변수의 주소를 eax 레지스터로 복사하는 경우


AT&T : lea $foo, %eax

Intel : lea eax, [foo]


숫자 0xd00d 를 eax  레지스터로 복사하는 경우


AT&T : movl $0xd00d, %eax

Intel : mov eax, 0d000h




메모리 참조


AT&T 문법은 소괄호를 이용해 10(%eax) 과 같이 표현하지만 Intel 문법은 대괄호 안에 주소를 넣어 [eax+10] 과 같이 표현한다.


eax 레지스터가 가리키는 주소의 값을 참조하는 경우


AT&T : (%eax)

Intel : [eax]


레지스터에 변수(var)의 옵셋을 합한 주소를 참조하는 경우


AT&T : var(%eax)

Intel : [eax + var]





'리버싱' 카테고리의 다른 글

과제  (0) 2017.08.23
[리버싱] 리틀엔디안 빅엔디안  (0) 2017.08.22
[리버싱] 어셈블리어 명령어  (0) 2017.08.21
[리버싱] 디버거(OllyDbg)  (0) 2017.08.21
[리버싱] 리버싱에 대해 알아보자  (0) 2017.08.21