본문 바로가기
Study Log/정보 보안

[정보 보안] 6. 어셈블리 언어 Part.1

by LOGER 2023. 9. 19.

어셈블리 개요

CPU 아키텍쳐

- 내부 동작 방식 & 구성 요소 정의의 설계 개념

- 아키텍쳐에 따라서 명령어, 레지스터 구조 등이 다름

ex) x86, arm 등

 

x86

- 원래 32 bit 아키텍쳐이다

- 64 bit 버전은 x64 (amd64, x86_64)

- Window, Linux, Mac OS 등에서 사용

 

arm

- 원래 32 bit

- 64 bit 버전은 arm64

- 모바일 기기 및 임베디드 시스템에서 사용

 

 

어셈블리어: 기계어와 일대일 대응 (저급 언어)

기계어: 0과 1로 이루어진 컴퓨터가 이해하는 언어 (2진수, 16진수 변환 됨)

 

저급언어: 컴퓨터가 이해하는 언어 (어셈블리어, 기계어)

고급언어: 사람이 이해하는 언어 (C, Java, Python 등)

 

고급언어 ---- (컴파일러) ----> 기계어

기계어 ---- (디컴파일러) ----> 고급언어

 

디컴파일러 - 완벽하게 고급언어로 변환 불가. (컴파일 되는 과정에서 고급언어가 많이 변형 됨)

- 디컴파일러의 성능에 많이 의존 됨

- 잘못된 변환이 나오는 경우가 많음

 

 

어셈블리어 ---- (어셈블러) ----> 기계어

기계어 ---- (디스어셉블러) ----> 어셈블리어

-> 완벽하게 변환 가능

 

 

레지스터: X32

범용 레지스터: 주소나 값을 저장하는 공간

- EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP

EAX: 산수연산, 함수의 리턴값 저장

EBP: 현재 스택 프레임의 베이스 주소 저장

ESP: 스택의 최상단의 주소 저장

 

레지스터는 기본 4바이트!

하위 2바이트, 하위 1바이트에 접근 가능

EAX -> 4바이트

AX -> 2바이트

AH(상위), AL(하위) -> 1바이트

 

ESI -> 4바이트

SI -> 2바이트

SIL -> 1바이트

 

 

레지스터: X64

범용 레지스터: 주소나 값을 저장하는 공간

- RAX, RBX, RCX, RDX, RSI, RDI, RBP, RSP, R8~R15

RAX: 산수연산, 함수의 리턴값 저장

RBP: 현재 스택 프레임의 베이스 주소 저장

RSP: 스택의 최상단의 주소 저장

 

레지스터는 기본 4바이트!

하위 2바이트, 하위 1바이트에 접근 가능

RAX -> 8바이트

EAX -> 4바이트

AX -> 2바이트

AH(상위), AL(하위) -> 1바이트

 

RSI -> 8바이트

ESI -> 4바이트

SI -> 2바이트

SIL -> 1바이트

 

R8 -> 8바이트

R8D -> 4바이트

R8W -> 2바이트

R8B -> 1바이트

 

Ex) 

RAX: 0xAABBCCDD12345678

EAX: 0x12345678

AX: 0x5678

AH(상위): 0x56

AL(하위): 0x78

 

명령 포인터 - 다음에 실행할 명령의 주소를 저장함 (레지스터)

32 bit -> EIP

64 bit -> RIP

시스템 해킹의 목표는 이 명령 포인터 조작!

 

 

데이터 이동

문법 종류 (Intel vs AT&T)

- Intel이 더 가독성이 좋고 대중적임 (AT&T를 Intel로 바꿔서 볼 수 있음)

- AT&T가 더 많은 정보를 담을 수 있다 (레지스터 앞에 기호를 붙임)

 

문법 구조

명령어 & 피연산자

MOV(명령어) EAX(피연산자) 1(피연산자)

피연산자에는 상수, 레지스터, 메모리(포인터) 등이 올 수 있음

메모리

- TYPE PTR [레지스터 or 상수] 형태

- TYPE: BYTE, WORD, DWORD, QWORD (1,2,4,8바이트)

ex> QWORD PTR [0x401245]

 

mov [피연산자 1] [피연산자 2] 

- 데이터 이동 명령어 (값을 가져온다)

- 피연산자 2를 피연산자 1로 이동한다. 

- 피연산자 1: 레지스터, 메모리 (상수 안됨, 이동할 수 있는 공간이 없음)

- 피연산자 2: 상수, 레지스터, 메모리

- 두 피연산자 크기가 일치해야 함

- 두 피연산자가 동시에 메모리이면 안됨

 

** 피연산자 2가 상수일 경우에 피연산자 1은 상수 크기보다 크면 됨

 

lea [피연산자 1] [피연산자 2] 

- load effective address

- 주소 이동 명령어 (주소 자체를 가져오는 것! 값 가져오는거 아님)

- 피연산자 2의 주소를 피연산자 1로 이동

- 피연산자 1은 레지스터

- 피연산자 2는 메모리

 

** mov는 주소 연산이 불가능하지만, lea는 주소 연산이 가능함