Static Link와 Dynamic Link

2026. 5. 19. 20:23·System Hacking

링크 Link

컴파일의 마지막 단계

프로그램에서 어떤 라이브러리의 함수를 사용한다면, 호출된 함수와 실제 라이브러리의 함수가 링크 과정에서 연결된다

 

C 소스 코드는 리눅스에서 전처리, 컴파일, 어셈블 과정을 거쳐 ELF 형식을 갖춘 오브젝트 파일로 번역된다. 

이렇게 만들어진 오브젝트 파일은 실행가능한 형식을 갖추고는 있지만, 라이브러리 함수들의 정의가 어디있는지 알지 못하므로 실행은 불가능하다. 이 상태에서는 함수가 심볼로는 기록되어있으나, 심볼에 대한 자세한 내용은 기록이 되어있지 않다.

 

동적 링크

동적 링크된 바이너리를 실행하면 동적 라이브러리가 프로세스의 메모리에 매핑된다. 이후 실행 중에 라이브러리의 함수를 호출하면 매핑된 라이브러리에서 호출할 함수의 주소를 찾고, 해당 함수를 실행한다. 

 

정적 링크

바이너리에 정적 라이브러리의 필요한 모든 함수가 포함된다. 즉, 라이브러리를 참조하는 것이 아니라 자신의 함수를 호출하는 것처럼 호출할 수 있다.

여러 바이너리에서 하나의 라이브러리를 사용할 경우 해당 라이브러리의 복제가 여러번 이루어지게 되므로 용량을 낭비하게 된다.

static과 dynamic 파일 크기 비교

static에서는 puts가 위치한 0x404d30을 직접 호출한다.

dynamic에서는 puts의 plt 주소인 0x401040을 호출한다.  

 

동적 링크된 바이너리는 함수의 주소를 라이브러리에서 찾아야하는데, plt는 이 과정에서 사용되는 테이블이다. 

 

PLT (Procedure Linkage Table), GOT(Global Offset Table)

라이브러리에서 동적 링크된 심볼의 주소를 찾을 때 사용하는 테이블

 

바이너리가 실행되면 runtime resolve (ASLR에 의해 라이브러리가 임의 주소에 매핑 -> 라이브러리 함수 호출 시 함수 이름 바탕으로 라이브러리에서 심볼 탐색 -> 해당 주소로 실행 흐름 옮김) 과정을 거친다. 

 

반복적으로 호출되는 함수의 정의를 매번 탐색한다면 굉장한 비효율이다.

ELF는 이를 위해서 resolve된 함수의 주소를 테이블에 저장한다. 이 테이블이 GOT이다.

 


실제 바이너리에서 일어나는 동작을 확인해보자. 사용할 프로그램 소스코드는 다음과 같다.

// Name: got.c
// Compile: gcc -o got got.c -no-pie

#include <stdio.h>

int main() {
  puts("Resolving address of 'puts'.");
  puts("Get address from GOT");
}

 

entry로 진입점으로 간다. GOT의 상태는 got 명령어로 확인할 수 있다. 

 

GOT 엔트리의 존재는 바이너리가 컴파일/링크될 때 슬롯이 확정된다. 엔트리 값(주소)는 runtime resolve 후에 채워진다. 

 

puts의 주소를 찾기 전이므로, puts의 GOT 엔트리인 0x404000에는 .plt 섹션 어딘가의 주소가 적혀있다. 

 

main()에서 puts@plt를 호출하는 지점에 중단점을 설정하고, 안으로 따라가본다. 

PLT에서는 먼저 puts의 GOT엔트리가 가리키는 주소로 실행 흐름을 옮긴다. DISAM 부분은 프로그램에서 명령어가 호출되는 순서(제어 흐름)을 보여주는데, 이를 따라가면_dl_runtime_resolve_xsavec가 호출될 것이다.

안으로 이동

ni 함수를 사용해서 _dl_runtime_resolve_xsavec안으로 진입 후 finish로 함수를 빠져나오면 puts의 GOT엔트리에 libc영역 내 실제 puts 주소가 쓰여있는 것을 확인할 수 있다.

해당 위치에서 finish로 빠져나왔다.

0x7ffff7c87be0가 puts의 값으로 쓰인 것을 확인할 수 있다. puts의 resolve가 완료되었다!

아래쪽에 puts함수가 한 번 더 호출된다. ni를 이용해서 계속 가다가 해당 함수에서 si로 내부로 들어가준다. 

_dl_runtime_resolve_xsavec 함수가 호출되지 않고, 바로 실행되는 것을 확인할 수 있다. 

 

GOT엔트리에 저장된 값을 공격자가 임의로 변경할 수 있다면, 임의의 함수가 호출될 때 공격자가 원하는 코드가 실행되도록 할 수 있을 것이다. 이를 GOT Overwrite라고 한다. 임의의 주소에 임의의 값을 오버라이트 하는 수단을 가지고 있을 때 수행한다. 

 


main+33 에 BP를 설정하고 GOT엔트리 값을 바꾸어준다. 

c로 continue 해주면 "AAAAAAAA"로 실행 흐름이 옮겨지는 것을 확인할 수 있다. 

저작자표시 비영리 변경금지 (새창열림)

'System Hacking' 카테고리의 다른 글

Return to Library (RTL공격. NX우회)  (0) 2026.05.19
NX & ASLR  (0) 2026.05.19
Stack Canary  (0) 2026.05.17
Stack Buffer Overflow 스택 버퍼 오버플로우  (0) 2026.05.16
셸코드 Shellcode  (0) 2026.05.12
'System Hacking' 카테고리의 다른 글
  • Return to Library (RTL공격. NX우회)
  • NX & ASLR
  • Stack Canary
  • Stack Buffer Overflow 스택 버퍼 오버플로우
권 한
권 한
포렌식 같이 하실래요?
  • 권 한
    Kwon5an.log
    권 한
    • 분류 전체보기 (115) N
      • @Xpert (28)
        • 2025 (23)
        • 2026 (5)
      • Forensic (26)
        • Windows (7)
        • Linux (3)
        • Memory (4)
        • Network (0)
      • System Hacking (6)
      • Reversing (0)
      • STUDY (11)
        • 컴퓨터 구조 (2)
        • 운영체제 (0)
        • 알고리즘 자료구조 (0)
        • CS (7)
      • #컴공에서살아남기 (15) N
        • 201 C++ (3)
        • 201 보안기초 (12) N
        • 201 OSS (0)
      • Write-up (15)
        • H4CKING GAME (1)
        • DreamHack (12)
        • bandit (0)
      • PROGRAM (0)
        • K-shield.jr (0)
      • PROJECT (0)
      • 사담.생각.끄적끄적 (7)
  • 공지사항

    • Notice
  • 링크

    • DAILY BLOG
    • Velog
    • NOTION
  • 전체
    오늘
    어제
  • hELLO· Designed By정상우.v4.10.6
권 한
Static Link와 Dynamic Link
상단으로

티스토리툴바