크기가 작은 ELF 파일의 첫 구현
문서 작성 중에 딴 짓으로 크기가 작은 실행 파일이란 주제에 빠져 보았습니다. ELF(Executable and Linkable Format)는 실행 파일, 라이브러리 등을 위한 표준 파일 형식입니다. 리눅스의 ./include/uapi/linux/elf.h 에서 그 구조를 확인할 수 있는데, 예전에 컴파일러 없이 부팅 이미지를 만들어 보자는 것을 시도한 이후에 다시 한 번 장난 끼가 발동하여 이번에는 리눅스 실행 파일을 만들어 보는 것으로 정하고 문서를 만들어 봅니다. 이 작은 실행 파일의 중요한 포인트는 데이터 등이 담기는 섹션 헤더가 존재하지 않고 프로그램 정보 만을 담는 프로그램 헤더와 ELF 헤더 그리고 프로그램 코드만이 담긴다는 것입니다. 32비트로 작성한 것은 32비트의 ELF 헤더가 더 작기 때문입니다. 아래의 쉘을 실행하시면, printf "\x7f\x45\x4c\x46\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00\x01\x00\x00\x00\x54\x80\x04\x08\x34\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x34\x00\x20\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x80\x04\x08\x00\x80\x04\x08\x6b\x00\x00\x00\x6b\x00\x00\x00\x05\x00\x00\x00\x00\x10\x00\x00\xb0\x04\xb2\x08\xb9\x63\x80\x04\x08\xcd\x80\xb0\x01\xcd\x80\x48\x69\x20\x73\x65\x61\x6e\x0a" > a.out && chmod 755 ./a.out && ./a.out "Hi sean" 이 출력되어져 나오는 것을 보실 수 있습니다. ELF 헤더 7f 45 4c 46 / ELF 매직 넘버 01 / 32 비트 01 / 리틀엔디안 01 / 오리지널 버전의 경우 1 00 / System V 운영체제 00 / Application Binary Interface 버전 00 00 00 00 00 00 00 / 패딩 02 00 / 실행 파일 타입 03 00 / x86 머신 01 00 00 00 / 버전 1 54 80 04 08 / 엔트리 포인트의 메모리 주소 34 00 00 00 / 시작 프로그램의 주소 00 00 00 00 / 섹션 헤더의 시작 위치 00 00 00 00 / 플래그 34 00 / ELF 헤더의 크기 20 00 / 프로그램 헤더의 엔트리 크기 01 00 / 프로그램 헤더의 엔트리 갯수 00 00 / 섹션 헤더의 엔트리 크기 00 00 / 섹션 헤더의 엔트리 갯수 00 00 / 섹션 헤더의 엔트리 인덱스 프로그램 헤더 01 00 00 00 / 프로그램 헤더 타입 '로드', 실행을 위한 파일 00 00 00 00 / 오프셋 00 80 04 08 / 가상 주소 00 80 04 08 / 실제 주소 6b 00 00 00 / 파일 사이즈 6b 00 00 00 / 메모리 사이즈 05 00 00 00 / 읽고 실행하기 00 10 00 00 / 0x1000 얼라인먼트 프로그램 코드 b0 04 / mov $0x4,%al / 파라미터 1 - 인터럽트 80의 4는 write b2 08 / mov $0x8,%dl / 파라미터 2 - 8만큼 기록 b9 63 80 04 08 / mov $0x8048063,%ecx / 파라미터 3 - 0x8048063 위치의 데이터 cd 80 / int $0x80 / interrupt 80 호출 b0 01 / mov $0x1,%al / 파라미터 1 - 인터럽트 80의 1은 exit cd 80 / int $0x80 / interrupt 80 호출 48 69 20 73 65 61 6e 0a / "Hi sean\n" / 섹션이 없는 대신에.... 실제 크기를 더 줄이려면, 시작 프로그램의 주소를 살짝 수정하고 겹치기 방법을 통하여 적은 바이트나마 줄일 수 있는 방법이 있습니다. 너무 많은 고민이 필요하여서, 차근차근 시간이 많이 있을 때, 압축할 수 있는 방법을 고민해보려 합니다. 어떤 분들은 60바이트 미만으로 하시는 분들도 계시더군요. 🤪