CS/소프트웨어보안

4-3. 어셈블리 실습

arsenic-dev 2025. 10. 17. 00:21

경희대학교 장대희 교수님의 소프트웨어보안 수업을 기반으로 정리한 글입니다.

 

Main 함수 분석

pwndbg 실행

  • CMD 열고 wsl -d khu-sw-sec
  • cd ~: home directory로 이동
  • id / pw: user / user
  • pwndbg ./gdb_lab 실행

 

Main 함수 어셈블리 출력

 

push rbp        # 이전 함수의 rbp 저장 -> 이전 함수로 돌아가기 위한 정보
mov rbp, rsp    # 현재 스택 포인터(rsp)를 기준으로 새 프레임 설정

 

※ rbp: 현재 함수의 스택 프레임의 기준 주소(base address)를 담는 레지스터이다.

 

Main 함수 시작 주소 breakpoint 설정 및 실행

stack frame이 할당되는 "push rbp"부터 분석 진행

 

함수 프롤로그 (Prologue, 시작)

함수 시작 시 스택프레임을 세팅하는 단계이다. (stack 하나 내리고 rbp 쌓음: 이전 함수의 rbp 스택에 저장하는 과정)

-> main 함수의 영역 구분

run -> break point 전까지 실행 (화살표로 가리키는 부분: ni 명령 시 실행 시작 부분)

 

변수 공간 할당

Main 함수 분석

DWORD PTR: Double World = 4 bytes -> 데이터 크기 명시

 

※ 데이터 크기 단위

  • PTR
    • byte ptr: 1 바이트 단위 접근
    • word ptr: 2 바이트 단위 접근
    • dword ptr: 4바이트 단위 접근
    • qword ptr: 8바이트 단위 접근
  • 메모리 덤프
    • x/bx: 1바이트만큼 16진수로 출력 (byte)
    • x/hx: 2바이트만큼 16진수로 출력 (halfword)
    • x/wx: 4바이트만큼 16진수로 출력 (word)
    • x/gx: 8바이트만큼 16진수로 술력 (giant word)

 

rdi: 64 비트 환경 체제 / edi: 32 비트 환경 체제

 

레지스터 6개로 인자 먼저 받고, 그 이후엔 스택에 인자를 받는다.

이렇게 rdi, rsi 등의 레지스터들이 순차적으로 쭉 나오면, 함수를 호출하기 직전이라는 것을 알 수 있다.

rax: 범용 레지스터이긴 하지만, 보통 리턴 값을 저장해 반환함

 

※ malloc은 할당 받은 주소, 즉 힙 영역의 주소를 레지스터에 저장하여 return 한다. (보통 $rax 사용)

 

rax에 있던 값을 RBP-0x10에 저장한 뒤, 똑같은 동작을 반대로 수행하는 이유는

힙에서 받은 데이터 주소를 변수에 저장하고, 변수를 사용하기 위해 다시 rax로 불러오기 위함이다.

 

rax가 현재 갖고 있는 값은 rbp - 0x10으로, 힙에 대한 주소임
x/s $rax+8 -> "a" 출력
rip + 0xe0c: "input: " 문자열이 들어있는 주소

 

rip: instruction pointer로, 현재 실행 중인 명령어 다음에 실행할 명령어의 주소를 저장하고 있는 레지스터이다.

 

 

rdi에 값을 저장하는 등, 함수 호출 전 레지스터에 값을 세팅하는 것음 매개 변수를 던지기 위함이다.

  • 매개 변수: 함수에 전달될 값을 임시로 받아서 쓰는 변수

 

가변 인자(매개 변수)는 xmm 레지스터에 들어가고, 이때 몇 개의 xmm 레지스터를 사용했는지 정보를 전달(-> eax)해야 한다.

  • 가변 인자 e.g., printf("%d\n", sum(3, 2));

 

'CS > 소프트웨어보안' 카테고리의 다른 글

5-2. 리눅스 사용  (0) 2025.10.17
5-1. 소프트웨어 보안을 위한 리눅스 기초  (0) 2025.10.17
4-2. GDB 실습  (0) 2025.10.15
4-1. 메모리 구조  (0) 2025.10.15
3. IDA 활용 및 리버싱 방법  (0) 2025.10.13