Static Link vs Dynamic Link

2024. 9. 5. 10:08·CS/Computer Architecture
728x90
반응형

Compile | 컴파일

컴파일은 인간이 이해할 수 있는 언어로 작성된 소스코드를 CPU가 이해할 수 있는 언어로 변환하는 작업

즉, 바이너리 형태로 변환하는 작업이다. (기계어)

컴파일 과정

  • Pre-Processing : 전처리기 (Pre-processor)을 통해 소스 파일을 수정된 소스 파일 (전처리된 소스 파일)로 변환
  • Compilation : 컴파일러 (Compiler)을 통해 수정된 소스 파일을 어셈블리 파일로 변환
  • Assembly : 어셈블러 (Assembler)을 통해 어셈블리어 파일을 오브젝트 파일로 변환 - 오브젝트 파일부터 바이너리 형태
  • Linking : 링커 (Linker)을 통해 오브젝트 파일들과 라이브러리, 헤더 파일들을 하나로 묶어 실행 파일로 변환

이때 Linking 과정에서 Static Linking (정적 링킹)과 Dynamic Linking (동적 링킹)으로 구분한다.

 

Static Link  | 정적 링크

obj 파일에 정적 라이브러리 파일 (.a or .lib) 등을 합쳐 하나의 실행 파일을 만듦
  • 실행 파일 내부에 라이브러리가 포함되어 있음
  • 라이브러리 파일이 따로 없어도 독립적으로 동작 가능
  • 정적 링크된 함수를 호출 할 때 소스파일 자체의 함수를 호출하는 것과 같이 호출할 수 있음
  • 라이브러리에서 원하는 함수를 찾지 않아도 되어 탐색 비용이 절감됨
  • 여러 바이너리에서 사용하면 복제가 이루어짐
  • 실행 파일의 용량이 정적링크된 파일만큼 늘어남

Dynamic Link | 동적 링크

obj 파일에 동적 라이브러리 파일 (.a or .lib) 등을  따로 메모리에 올려, 실행파일을 실행시킬 때 불러옴
  • 프로그램 실행 시 동적 링크된 곳에서 파일을 불러옴
  • 바이너리 실행 시 동적 링크된 파일이 프로세스 메모리에 매핑됨
  • 바이너리 실행 중 함수를 호출하면, 매핑된 곳에서 해당 함수의 주소를 찾음
  • 윈도우의 경우 dll 파일 등으로 표현되어 있는 곳에서 exe 파일이 실행시 dll을 불러오는 형식

라이브러리 파일만 링크 되는 것은 아니다. 헤더파일 등도 동적 링크, 정적 링크 될 수 있음

 

더보기

[ 라이브러리란? ]

라이브러리는 컴퓨터 시스템에서 프로그램들이 함수나 변수를 공유해서 사용할 수 있게 해주는 것이다. 

자주 사용되는 함수드의 정의를 묶어, 하나의 라이브러리 파일로 만들고, 여러 프로그램들이 공유해서 사용할 수 있도록 함

 

C언어의 표준 라이브러리 : libc

libc에는 printf, scanf, strlen, memcpy 등을 확인할 수 있음

 

Dynamic Link vs Statkc Link

#include <stdio.h>

int main() {
  puts("Hello, world!");
  return 0;
}

Hello, world!를 출력하는 프로그램을 동적링크, 정적링크 시켜서 비교해보겠다.

gcc -o static hello.c -static  
gcc -o dynamic hello.c

정적, 동적으로 컴파일한다.

용량

ls -lh ./static ./dynamic 
-rwxr-xr-x 1 parallels parallels  69K Sep  5 09:17 ./dynamic
-rwxr-xr-x 1 parallels parallels 621K Sep  5 09:17 ./static

약 10배 정도의 용량 차이가 난다. 

정적 링크된 실행 파일의 용량 >> 동적 링크된 실행 파일의 용량

 

호출 방법

Static

0x00000000004007a0 <+0>:     stp     x29, x30, [sp, #-16]!
0x00000000004007a4 <+4>:     mov     x29, sp
0x00000000004007a8 <+8>:     adrp    x0, 0x454000 <read_encoded_value_with_base+160>
0x00000000004007ac <+12>:    add     x0, x0, #0x518
0x00000000004007b0 <+16>:    bl      0x401660 <puts>
0x00000000004007b4 <+20>:    mov     w0, #0x0                        // #0
0x00000000004007b8 <+24>:    ldp     x29, x30, [sp], #16
0x00000000004007bc <+28>:    ret

puts가 있는 0x401660을 직접 호출함

 

Dynamic

0x0000000000400698 <+0>:     stp     x29, x30, [sp, #-16]!
0x000000000040069c <+4>:     mov     x29, sp
0x00000000004006a0 <+8>:     adrp    x0, 0x400000
0x00000000004006a4 <+12>:    add     x0, x0, #0x6d8
0x00000000004006a8 <+16>:    bl      0x400540 <puts@plt>
0x00000000004006ac <+20>:    mov     w0, #0x0                        // #0
0x00000000004006b0 <+24>:    ldp     x29, x30, [sp], #16

puts의 plt 주소인 0x400540을 호출함

plt는 동적 링크된 바이너리에서 함수의 주소를 라이브러리에서 찾는데 사용되는 테이블

 

PLT & GOT

PLT (Procedure Linkage Table), GOT (Gloabl Offset Table)은 라이브러리에서 동적 링크된 심볼 주소를 찾을 때 사용하는 테이블

PLT

  • 라이브러리의 모든 함수의 주소가 매핑되어있음
  • printf, puts 등등 PLT 테이블이 매핑되어 있음
  • 바이너리는 정확히 사용하려는 함수가 PLT에 어디 위치에 있는지 실행하기 전에는 알 수 없음 => Lazy binding인 경우

GOT

  • ELF (리눅스 바이너리 포맷)은 GOT 테이블을 두고, resolve된 함수의 주소를 해당 테이블에 저장 
  • 함수를 다시 호출할 때 PLT에서 다시 함수를 찾지 않아도 됨
  • 함수의 다시 실행할 때는 PLT에 함수가 어디에 있는지 정확한 주소를 GOT에 이미 저장해둔 상태

 

runtime resolve

해당 과정을 통해 동적 링크된 심볼 주소를 찾음

  1. 라이브러리 함수 호출
  2. 함수의 이름을 바탕으로 라이브러리에서 심볼 탐색
  3. 함수 정의 발견 시, 그 주소로 실행 흐름을 옮김

resolve 전

puts@plt를 호출하는 부분을 중심으로 볼 예정

  1. plt의 주소인 0x400540으로 실행 흐름이 옮겨짐 (puts의 주소가 아님)
  2. _dl_runtime_resolve_fxsave라는 함수가 실행됨
  3. 해당 함수에서 puts의 주소를 구함
  4. GOT 엔트리에 puts의 주소를 적음

해당 GOT 엔트리에는 libc 영역 내 실제 puts 주소가 쓰여짐

resolve 후

두번째로 puts를 실행한다는 가정

  1. puts@plt를 call 함
  2. GOT에서 이미 매핑된 puts의 주소를 받아와 puts가 바로 실행됨

 

Question & Learn

Resolve된 후 함수의 흐름

resolve가 되었다고 하더라도, 바로 GOT를 참고하지는 앟는다. 

puts@plt가 GOT에 저장되어있는 '실제 주소'를 가져오는 것이다.

 

plt -> got 주소

got -> 실제 함수의 주소

이렇게 저장되어 있게 된다. 

GOT Overwrite

취약점 : PLT에서 GOT를 참고하여 실행 흐름을 옮길 때 GOT 값을 검증하지 않음

→ GOT Overwrite 공격 기법 수행 가능

 

앞의 예시를 바탕으로, puts의 GOT 엔트리에 저장된 값을 임의로 변경하면, puts가 호출될 때 실행 흐름을 옮길 수 있음

 

reference 

- Dreamhack SystemHacking > Background: Library - Static Link vs Dynamic Link

728x90
반응형
저작자표시 비영리 변경금지 (새창열림)

'CS > Computer Architecture' 카테고리의 다른 글

[Assembly] 산술 연산  (0) 2024.09.27
[Assembly] 데이터 이동  (0) 2024.09.20
함수의 프롤로그 & 에필로그  (0) 2024.08.22
Register  (1) 2024.08.16
[Assembly] Intel vs AT&T  (3) 2024.08.14
'CS/Computer Architecture' 카테고리의 다른 글
  • [Assembly] 산술 연산
  • [Assembly] 데이터 이동
  • 함수의 프롤로그 & 에필로그
  • Register
min_zu
min_zu
  • min_zu
    민주제도
    min_zu
  • 전체
    오늘
    어제
    • ._. (176)
      • AI (2)
        • DeepLearning (2)
        • CS231n (0)
      • Web (2)
        • ReactJS (0)
      • CS (83)
        • OS (7)
        • Data Structure (23)
        • Computer Architecture (8)
        • Computer Network (20)
        • Algorithm (25)
      • Linux (3)
        • KaliLinux (0)
        • Docker (1)
      • Hacking (83)
        • Write Up (25)
        • Pwnable (13)
        • Reversing (2)
        • Cryptography (12)
        • Web Hacking (4)
        • Window (6)
        • Network (7)
        • Web3 (13)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    DeepLearning
    Sort
    Search
    ComputerArchitecture
    Tree
    AI
    DataStructure
    Linux
    WinAFL
    UTM
    Web
    Mac
    OS
    Graph
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
min_zu
Static Link vs Dynamic Link
상단으로

티스토리툴바