오브젝트 파일 분석과 실행 흐름 마무리
이제까지 우리는 C 프로그램이 어떻게 컴파일되고 링크되며 실행되는지에 대한 전 과정을 학습해 보았는데요. 이번 마지막 파트에서는 CSAPP 7.14~15절의 내용을 바탕으로 지금까지의 흐름을 직접 눈으로 확인하고 실습할 수 있는 도구들에 대해 정리해 봅니다.
또한 지금까지 배운 개념을 실제 오브젝트 파일과 실행 파일의 구조를 통해 정리하고 마무리할 예정입니다.
7.14 오브젝트 파일 조작 및 분석 도구
CSAPP에서는 다양한 ELF 분석 도구들을 소개하는데요. 아래는 그 중 핵심 도구들과, 그것들이 어떤 목적에 쓰이는지 정리한 것입니다.
nm(심볼 테이블 보기)
nm main.o
- 오브젝트 파일 내부의 심볼(변수, 함수 등)의 목록을 보여준다
- 각 심볼의 이름, 타입, 섹션 위치 등을 확인할 수 있다
심볼 타입 | 의미 |
T | .text (함수 정의) |
U | undefined (외부 참조) |
D | .data (전역 초기화 변수) |
B | .bss (전역 초기화되지 않은 변수) |
objdump(디스어셈블리 & 실행 흐름 확인)
objdump는 실행 가능한 명령어 레벨에서 바이너리 코드를 들여다보는 도구입니다.
objdump -d prog
- ELF 실행 파일이나 .o 파일을 어셈블리 코드로 보여준다
- PLT, GOT 구조 확인이나 함수 호출 흐름 추적에 매우 유용하다
readelf(ELF 구조 정밀 분석)
readelf -h prog # ELF 헤더
readelf -S prog # 섹션 목록
readelf -s prog # 정적 심볼 테이블 (.symtab)
readelf --dyn-syms prog # 동적 심볼 테이블 (.dynsym)
readelf -r prog # 재배치 정보
- ELF 파일의 전체 구조를 확인할 수 있게 해주는 저수준 해석 도구
- .got, .plt, .bss, .data, .text 등 ELF 섹션들을 직접 확인할 수 있다
- -s와 --dyn-syms의 차이도 중요하다
- -s는 정적 링크(컴파일 타임), --dyn-syms는 동적 링크(실행 타임) 시 사용되는 심볼들을 보여준다
ldd(동적 라이브러리 의존성 확인)
ldd prog
- 실행 파일이 실행 시 참조하게 될 공유 라이브러리(.so)들을 확인할 수 있다.
- 실무에서 libc, libm, libpthread 등의 연결 여부를 체크할 때 자주 사용된다.
- 다만, ldd는 실행을 시도하는 방식이기 때문에 신뢰할 수 없는 실행 파일에는 보안상 위험이 있다.
- 안전한 대안으로는 readelf -d, objdump -p 등이 있다
그 외 도구들
도구 | 설명 | 예시 |
ar | 정적 라이브러리 .a 파일 생성 및 관리 | ar rcs libfoo.a foo.o |
strings | 바이너리 내 출력 가능한 문자열 추출 | strings a.out |
strip | 디버깅 정보를 제거해 크기를 축소 | strip prog |
size | 각 섹션의 크기 및 총 크기 확인 | size a.out |
7.15 실행 흐름 정리 및 마무리
그러면 지금까지 배운 내용을 토대로 컴파일 단계 → 링커 처리 → 실행 시 구조로 다시 한 번 전체 흐름을 정리해 보겠습니다.
전체 실행 과정 요약
- 컴파일 -> .o 생성 (gcc -c)
- 링커(ld) -> 여러 .o를 묶어 실행 파일 생성 (gcc -o prog a.o b.o)
- ELF 파일 로딩 -> OS가 실행 시 .text, .data, .bss 등을 메모리에 적재
- 동적 링커(ld-linux.so) -> .so 파일 로딩, GOT/PLT 구성
- GOT/PLT를 통해 외부 심볼 연결 완료 -> 실행 시작
도구와 실행 흐름의 대응 정리
실행 단계 | 관련 도구 | 설명 |
컴파일 -> .o 생성 | nm, readelf -s | 심볼 테이블 확인 |
링커 -> 실행 파일 생성 | readelf -h/-S/-r, objdump -d | ELF 구조와 함수 흐름 확인 |
런타임 동적 연결 | ldd, readelf -d, objdump -p | 동적 링크 의존성 확인 |
핵심 요약
개념 | 핵심 도구 | 역할 |
ELF 헤더/섹션 | readelf -h, -S | 전체 구조 |
심볼 테이블 | nm, readelf -s, --dyn-syms | 심볼 확인 |
함수 흐름 분석 | objdump -d | 어셈블리 확인 |
라이브러리 의존성 | ldd, readelf -d | 동적 링크 확인 |
최적화/크기 | strip, size | 바이너리 크기 및 정보 확인 |
'크래프톤 정글 > 컴퓨터구조(CSAPP)' 카테고리의 다른 글
[CSAPP 8장 완전 정복] 8.4 프로세스를 만들고 제어하는 기술들 - fork, exec, wait 완전 정복 (0) | 2025.04.19 |
---|---|
[CSAPP 8장 완전 정복] 8.1~8.3 예외와 프로세스, 시스템의 흐름을 바꾸는 힘 (0) | 2025.04.19 |
[CSAPP 7장 완전 정복] 7.13 라이브러리 삽입 완전 이해하기 (0) | 2025.04.18 |
[CSAPP 7장 완전 정복] 7.12 공유 라이브러리의 핵심 기술 - PIC, GOT, PLT (0) | 2025.04.18 |
[CSAPP 7장 완전 정복] 7.10~7.11 정적 링크 vs 동적 링크, 라이브러리 연결의 두 방식 (0) | 2025.04.18 |