동적, 정적 라이브러리 차이점에 대해서 알아 보기로 하자.
정적 라이브러리는 프로그램과 같이 컴파일 & 링크 되어 실제 오브젝트 파일 내에 포함 되어서 실행 되는 라이브러리이다. 라이브러리와 프로그램이 합체(?) 되기 때문에 정적 라이브러리와 링크 하면 프로그램 용량이 늘어나는 현상을 볼 수 있다.
프로그램과 합체가 되면 단점도 생기는데 라이브러리가 업데이트 되었을 때 그 라이브러리를 사용한 프로그램의 업데이트 버전을 어떻게 배포 하느냐 이거다-_-.. 업데이트가 쉽지 않다.(반면에 속도는 빠르겠지) 이래서 DLL이라고 불리우는 동적 라이브러리가 탄생하게 되었는데 프로그램에 합체 된 정적 라이브러리를 밖으로 꺼내 놓기 시작했다. 이게 바로 동적 라이브러리이다. 이러면 아주 편하게 수정 & 배포를 할 수 있으리라 생각 했겠지만 다른 문제점이 있으니.. 속도가 느려지는 단점이 있다. 동적 로더에게 질의를 날려서 라이브러리 찾고 메모리에 올리고 콜하고블라블라 아무튼 복잡해 진다.(이 과정은 다음에 포스팅)
그럼 어떻게 동작하는지 메모좀 해볼까..
아래 프로그램으로 동적 라이브러리를 들여다 보자. 어래 동적 라이브러리가 어딧어? 하시는 분들도 있겠지만 printf는 glibc에 포함된 동적 라이브러리라는 사실. 파일 분석의 흥미진진함을 더해주기 위해 전역변수도 몇개 추가 했다.

main.c 소스!

숫자 알파벳 심볼명
으로 이루어진 것을 볼 수 있다.
앞의 16진수는 대략 가상 주소 겠고.. 알파벳은 찾아봐야겠고;; 마지막은 심볼명을 의미한다.
T : Text 영역(code)
U : 정의 안된 심볼
B : 초기화 안된 데이터(BSS)
D : 초기화 된 데이터
R : Read only data
자 여기서 중요한건 U로 표시된 undefined 심볼이다. 즉 좌측 캡춰 화면에 printf@@GLIBC_2.0 으로 되어있는.. 뭔지 모르겠지만 가상 주소도 안붙어 있네-_-; 이거이 동적 라이브러리와 관련좀 있는 것으로 추정된다.
그외에 전역 변수로 지정한 gVal~~~ 변수들은 B로 되어있는 것을 볼 수 있다. 여기서 아~ gValInit은 0으로 초기화 되어있는데 왜 초기화 안된 데이터 영역에 있나? 하실 수도 있겠지만 0으로 초기화 된 것들도 BSS 영역으로 갑니다. 만약 gValInit 변수에 100을 넣었으면 D라고 표시 됩니다.
readelf 명령어를 사용해 더 자세히 들여다 보자.
0x00000001 (NEEDED) Shared library: [libc.so.6]

readelf -a main
음.. Entry point address는 0x8048310 이군.. gdb로 분석할 때 이곳에서 부터 시작하면 되겠다. 중요한건 이 부분이 아니고 Dynamic section 쪽에 보면 이 프로그램을 실행 시키기 위해 필요한 동적 라이브러리 목록을 볼 수 있다. NEEDEED가 보일때까지 스크롤 해보자. 슉슉
0x00000001 (NEEDED) Shared library: [libc.so.6]
자 이 부분 중요하다. 정적 라이브러리와 다르게 동적 라이브러리는 실행 프로그램에 포함 되는 것이 아니라고 했다. 그러면 정적 라이브러리 같이 합체(?) 되는 것도 아닌데 어떻게 이 프로그램이 동적 라이브러리와 연관이 지어지느냐 답은 요기 있다. 컴파일러가 이 프로그램은 이런이런 라이브러리를 사용 합니다. 라고 NEEDED 로 실행 파일에 적어 놓는다. 로더가 아~~ 얘는 이런 라이브러리를 사용하는군.. 이라고 생각하게 되고 이 정보를 어떻게 든 참고해서 프로그램 런타임시에 사용 될 것이라고 생각 된다.
.. 다 적을려고 했는데 너무 피곤하다. 너무 바쁘고 ㅠㅠ To be continue 해야겠다... 다음엔 gdb로 런타임상에서 동적 라이브러리가 어떻게 동작하는지 알아보겠따~~ GOT, PLT 기대하시라

