바이너리 실행 파일은 어떻게 구성되어 있을까? 탐구해보자!
- 실행 파일은 이해할 수 없는 것이 아니며, 정규 파일 형식임.
- 리눅스에서 ELF 바이너리를 다루며, C 언어를 사용하지만 다른 컴파일 언어도 가능함.
- 심볼(symbol), 섹션(section), **세그먼트(segment)**에 대해 배움.
- 심볼은 함수 이름과 같고, 섹션에 정리되며, 섹션은 세그먼트로 구성됨.
-
readelf
도구를 사용하여 이들을 살펴봄.
1단계: 텍스트 편집기에서 열기!
- 가장 단순한 방법으로 바이너리를 볼 수 있으며, "Penguin!"과 "ELF"라는 텍스트를 확인할 수 있음.
2단계: readelf
를 사용하여 심볼 테이블 보기
-
readelf --symbols
를 사용하여 심볼을 볼 수 있음. -
main
,puts
,_start
등의 심볼을 확인할 수 있음. - 프로그램은
main
이 아닌_start
에서 시작함.
심볼
- 프로그램 작성 시 함수에 대한 심볼이 생성됨.
- 라이브러리에서 함수를 호출할 때 해당 함수의 코드를 찾기 위해 심볼이 필요함.
- 정적 링킹(static linking)과 동적 링킹(dynamic linking)을 통해 링킹이 이루어짐.
3단계: objdump
를 사용하여 바이너리 보기 및 섹션에 대해 배우기!
-
objdump
는 바이너리를 더 잘 볼 수 있는 방법을 제공함. -
.text
,.rodata
,.interp
등의 섹션을 볼 수 있음. - 섹션은 링크 시간에 사용되고, 세그먼트는 실행 시간에 사용됨.
4단계: 어셈블리 보기!
-
.text
섹션에 어셈블리 코드가 포함되어 있음. -
objdump -d
를 사용하여 어셈블리 코드를 볼 수 있음.
5단계: 세그먼트 보기!
- 프로그램은 세그먼트 또는 프로그램 헤더로 구성됨.
-
readelf --segments
를 사용하여 세그먼트를 볼 수 있음. - 세그먼트는 프로그램의 다른 부분을 메모리에 어떻게 분리할지 결정함.
마법이 아님!
- 실행 파일은 마법이 아니며, ELF는 다른 파일 형식과 같음.
-
readelf
,nm
,objdump
를 사용하여 리눅스 바이너리를 조사할 수 있음.
GN⁺의 의견
- 이 글은 초급 소프트웨어 엔지니어들에게 바이너리 실행 파일의 구조를 이해하는 데 매우 유익함.
- 심볼, 섹션, 세그먼트의 개념과 이들을 조사하는 도구들(
readelf
,objdump
)에 대한 실용적인 정보를 제공함. - 프로그램이 실제로 어떻게 메모리에 로드되고 실행되는지에 대한 기본적인 이해를 돕는 내용이 포함되어 있어, 시스템 프로그래밍에 대한 흥미를 불러일으킬 수 있음.
Hacker News 의견
-
한 사용자는 ELF(Executable and Linkable Format)를 직접 작성해보는 것을 추천하며, 이것이 실행 파일의 기본 부분을 이해하는 데 큰 도움이 된다고 말함. 또한, 이 글은 기존의 상향식 접근이 아닌 하향식 접근을 원하는 사람들에게 유용함.
-
또 다른 사용자는 프로그램이 실행될 때
main
에서 시작하는 것으로 생각할 수 있지만, 실제로는_start
에서 시작한다고 설명함._start
는main
을 호출하는 등 여러 중요한 작업을 수행하는데, 이는 C 언어에 특화된 것이 아니라 언어에 관계없는 바이너리의 진입점임. -
한 사용자는 Julia의 기사가 항상 훌륭하다고 언급하며, 컴파일된 코드가 비밀을 간직하지 않는다는 것을
strings
명령어를 시연함으로써 사람들에게 가르치는 데 좋은 결과를 얻었다고 함. -
한 사용자는 수학에서 컴퓨터 과학으로 학문적 경력을 전환했을 때 이 주제를 처음 공부했다고 말하며, 이러한 깊은 탐구를 후회하지 않았다고 언급함. Julia 역시 수학 배경을 가지고 있으며, 이러한 하향식 추론에 대한 욕구가 수학자들을 이러한 실험으로 이끌었을 수 있다고 생각함.
-
한 사용자는 실행 파일이 플랫폼에 특화되어 있다는 것을 반영하며, "실제로 이식 가능한 실행 파일"이 다양한 플랫폼에서 실행될 수 있음을 증명했을 때의 경험을 공유함. 이는 자바, 크로스플랫폼 라이브러리 등 다양한 방법으로 해결하려 했던 크로스플랫폼 문제의 해결책이 오랫동안 우리 눈앞에 있었다는 것을 의미함.
-
한 사용자는 90년대 초반에 실행 파일의 형식에 매료되어 DOS와 Windows 실행 파일 뷰어를 Modula 2로 작성했다고 말함. 이 프로그램은 VEXE라는 이름으로 공유 소프트웨어로 1991년에 출시되었으며, 크래커들 사이에서 일정한 추종을 얻었고, +ORC 튜토리얼에서 언급되기도 했음.
-
한 사용자는 바이너리 파일을 터미널에 출력하는 것은 슬픔의 원인이라고 말하며, 대신
hexdump -C
를 사용하는 것을 선호함. -
여러 사용자들이 이 주제에 대한 훌륭한 스레드라고 언급함.
-
한 사용자는 이 주제에 관심이 있는 사람들에게 Cosmopolitan과 RedBean, "αcτµαlly pδrταblε εxεcµταblε (2020)"을 읽어보는 것을 추천함.