반응형

우리가 기존에 배우던 C, C++, Java 같은 언어들은 고급 언어이고,
어셈블리어는 기계어(0과 1로만 이루어진 언어)에 매우 가까운 저급 언어입니다.

프로그래밍 언어는 기계어에 가까울수록 작성과 이해는 어렵지만 실행 속도는 빠릅니다.
예를 들어 Python으로 문제를 실행해보면 메모리를 많이 사용하고, 실행 속도도 C보다 느린 것을 확인할 수 있습니다.


개발 환경 준비 (Linux 기준)

Linux 환경에서 진행할 것이므로, 우분투와 가상머신을 설치합니다.
(설치 과정은 생략)

NASM 설치

sudo apt-get install nasm

어셈블리어로 Hello World 출력하기

파일 생성

nano helloworld.s

nano는 메모장처럼 텍스트를 작성할 수 있는 에디터입니다.
.s 확장자는 어셈블리 소스 파일을 의미합니다.


코드 구조 설명

  • section .data
    프로그램에서 사용하는 문자열 같은 데이터를 저장하는 공간
  • section .text
    실제 실행되는 코드 영역
  • _start
    C 언어의 main 함수보다 먼저 실행되는 시작 지점

주요 명령어 설명

  • mov
    레지스터에 값을 대입하는 명령어
    • mov rax, 1 → rax 레지스터에 1을 저장

파일 저장 및 종료

  • Ctrl + X → Y → Enter

파일 내용 확인

cat helloworld.s

컴파일 및 실행

nasm -f elf64 -o helloworld.o helloworld.s
ld -o helloworld helloworld.o
ls
./helloworld
  • Linux에서는 실행 가능한 파일이 연두색으로 표시됩니다.

세그멘테이션 오류가 날 경우

section.data

처럼 붙여 썼을 가능성이 큽니다.
반드시 아래처럼 작성해야 합니다.

section .data

vi / vim 편집기 사용법

파일 열기

vi helloworld.s
  • i : 입력 모드
  • ESC : 명령 모드
  • :q : 종료
  • :w : 저장
  • :wq : 저장 후 종료

vim 설치:

sudo apt-get install vim

레지스터와 시스템 콜 이해하기

레지스터 크기

  • 64bit : RAX, RBX, RCX …
  • 32bit : EAX, EBX …
  • 16bit : AX, BX …
  • 8bit : AL, BL …

예:

  • RDX → EDX → DX → DL

주요 레지스터 용도

데이터 레지스터

  • RAX
    시스템 콜 번호 / 함수 반환값
  • RBX
    메모리 주소 저장
  • RCX
    반복문에서 카운터 역할
  • RDX
    데이터 처리용

포인터 레지스터

  • RSI
    출발지 주소
  • RDI
    목적지 주소
  • RBP
    스택 기준 주소
  • RSP
    현재 스택 최상단 주소
  • r8 ~ r15 : 함수 인자 전달용

시스템 콜(System Call)

64bit Linux에서는 syscall 명령어를 사용합니다.

  • rax : 시스템 콜 번호
  • rdi, rsi, rdx : 매개변수

예시:

  • sys_write
    • rax = 1
    • rdi = 1 (stdout)
    • rsi = 문자열 주소
    • rdx = 문자열 길이
  • sys_exit
    • rax = 60
    • rdi = 종료 코드

어셈블리 주요 명령어 정리

명령어설명

mov x, y x ← y
and x, y x ← x and y
or x, y x ← x or y
xor x, y x ← x xor y
add x, y x ← x + y
sub x, y x ← x - y
inc x x ← x + 1
dec x x ← x - 1
syscall 시스템 콜 호출
db 메모리 데이터 선언

메모리 구조 이해하기

  • Stack
    LIFO 구조, 취약점이 많이 발생
  • Heap
    동적 메모리 영역 (malloc)
  • BSS
    초기화되지 않은 전역 변수
  • Data
    초기화된 전역 변수
  • Text
    실행 코드 영역

스택 프레임(Stack Frame)

C 코드 작성

nano sum.c

어셈블리 코드로 변환

gcc -S sum.c
vi sum.s

함수 호출 과정

  • push rbp
  • mov rsp, rbp
  • sub rsp, 16
  • 인자 전달
  • call sum
  • leave
  • ret

오퍼랜드 크기 접미사

  • movl : 32bit
  • movw : 16bit
  • movb : 8bit

에코(Echo) 프로그램 만들기

입력한 문자열을 그대로 출력하는 프로그램

nano echo.s
  • xor rax, rax : rax를 0으로 초기화
  • sub rsp, 64 : 입력 버퍼 공간 확보
  • sys_read → 입력 받기
  • sys_write → 출력
  • sys_exit → 종료

반복문 구현하기

nano loop.s

주요 흐름

  • cmp : 비교
  • je : 같으면 점프
  • jmp : 무조건 점프
  • inc : 증가
  • syscall : 출력
반응형

'Hacking > Assembly' 카테고리의 다른 글

Nasm을 이용한 Assembly 배우기-0  (0) 2026.02.15

+ Recent posts