System Hacking/Basics

Static Link vs Dynamic Link / PLT vs GOT

hanbunny 2025. 3. 20. 19:46

라이브러리?

컴퓨터 시스템에서, 프로그램들이 함수나 변수를 공유해 사용 가능하게 한다.

라이브러리를 사용하면 같은 함수를 반복적으로 정의해야 하는 수고를 덜 수 있음.

#표준 라이브러리 경로
$ ld --verbose | grep SEARCH_DIR | tr -s ' ;' '\n'

 

링크?

라이브러리 함수를 사용할 때 호출된 함수와 실제 라이브러리의 함수가 링크 과정에서 연결됨.

컴파일의 마지막 단계이다. 심볼과 관련된 정보들을 찾아서 최종 실행 파일에 기록하기도한다.

 

*오브젝트 파일: 실행 가능한 형식을 갖추고 있지만, 라이브러리 함수들의 정의가 어디있는지 알지 못해 실행은 불하능한 파일.

 

$ gcc -c hello-world.c -o hello-world.o]
$ readelf -s hello-world.o | grep puts

심볼로는 기록이 되어 있지만 심볼에 대한 내용이 하나도 없음.

$ gcc -o hello-world hello-world.c
$ readelf -s hello-world | grep puts
$ ldd hello-world


동적 링크 vs 정적 링크

 

동적링크

동적링크를 하면 바이너리를 실행했을때 동적 라이브러리가 프로세스의 메모리에 매핑된다.

실행중에 라이브러리의 함수를 호출하면 매핑된 라이브러리에서 호출할 함수의 주소를 찾아 실행.

 

정적 링크

정적링크를하면 바이너리에 정적 라이브러리의 필요한 모든 함수가 포함됨.

함수를 호출할때 라이브러리를 참조하지 않고 가지고 있는 자신의 함수를 직접 호출 하는 것.

-> 속도는 빠르지만 용량이 낭비될 수 있음

용량 차지 차이

 

#static
main:
  push   rbp
  mov    rbp,rsp
  lea    rax,[rip+0x96880] # 0x498004
  mov    rdi,rax
  call   0x40c140 <puts>
  mov    eax,0x0
  pop    rbp
  ret
  
  #dynamic
  main: 
 push   rbp
 mov    rbp,rsp
 lea    rdi,[rip+0xebf] # 0x402004
 mov    rdi,rax
 call   0x401040 <puts@plt>
 mov    eax,0x0
 pop    rbp
 ret

호출 방법을 보면 static에서는 puts가 있는 0x40c140을 직접 호출하지만

dynamic에서는 plt 주소인 0x401040을 호출함.


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

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

 

반복적으로 호출되는 함수의 정의를 매번 탐색해야하면 비효율적이게 되기 때문에

ELF는 GOT라는 테이블을 두고 resolve된 함수의 주소를 테이블에 저장한다.

다음에 또 호출되면 GOT테이블에서 저장된 주소를 꺼내 사용함.

 

 

시스템 해킹의 관점에서 PLT와 GOT

PLT에서 GOT를 참조해 실행 흐름을 옮길 때 GOT값을 검증하지 않는다.

따라서 GOT엔트리에 저장된 값을 공격자가 임의로 변경하면 공격자가 원하는 코드를 실행 가능.

-> GOT Overwrite라고함.