책소개
임베디드 시스템, 디버깅, 시스템 보안, 최적화 등각종 기술과 89가지 노하우를 한 권에!현대의 컴퓨터 시스템은 다층 구조로 이루어집니다. 추상화 레이어를 중첩하면서 발전해 왔으며, 무수한 기능이 실제로 구현되었습니다. 이러한 레이어는 매우 정교하게 설계된 만큼, 단순히 기능만 사용하려 한다면 각 레이어의 동작을 자세히 이해할 필요는 없습니다. 하지만 때로는 추상화 레이어를 벗겨내고 시스템 내부를 자세히 들여다봐야 할 때가 있습니다. 기존 도구만으로는 불가능한 무언가를 구현하려 할 때, 고성능 소프트웨어를 만들려 할 때, 보안 관련 프로그래밍을 할 때 등이 대표적인 예입니다. 추상화 메커니즘 그 자체 또는 추상화에 의해 은폐된 기능을 활용해야 하는 경우가 있기 때문입니다.무엇보다도, 추상화 레이어와 그 하부 구조를 엿보는 과정은 매우 흥미롭습니다. 지금까지 개발자들이 쌓아온 하나하나의 구성 요소와 그 구조를 탐색해나가다 보면 우리가 몰랐던 무언가를 새롭게 발견할 수 있습니다. 게다가 현재는 많은 소프트웨어의 소스 코드가 대중에 공개되어 있는 만큼, 원한다면 언제든 구성 요소를 교체하거나 수정할 수 있습니다. 이 책은 그러한 저수준 프로그래밍의 세계를 탐색하고 이해하는 데 필요한 다양한 기법, 즉 핵(Hack)을 89가지 엄선해 제공합니다.
목차
01장 인트로덕션_#01 미지의 바이너리 읽기_#02 어셈블리 입문_#03 다시 Hello, World!02장 ELF Hack_#04 ELF 파일의 세그먼트_#05 ld-linux.so의 환경 변수 이용하기_#06 공유 라이브러리를 검색할 디렉터리_#07 dlopen에 의한 라이브러리 실행 시 로드와 응용 테크닉_#08 IFUNC를 사용하여 실행 시 구현 전환하기_#09 ELF의 해시 테이블 구조_#10 TLS의 구조 이해하기_#11 코어 파일 읽기_#12 보조 벡터를 사용하여 프로세스에 정보 넘기기_#13 정적 링크와 ASLR의 관계_#14 sold를 사용하여 의존하는 공유 라이브러리 나중에 링크하기_#15 glibc를 Hack하기_#16 patchelf로 ELF 바이너리의 필드 수정하기_#17 LIEF를 사용하여 ELF 바이너리 수정하기_#18 PT_NOTE를 이용한 바이너리 패치_#19 DWARF Expression 실행하기: DWARF I_#20 DWARF로 수식 평가하기: DWARF II_#21 DWARF에서 표준 출력으로 출력하기: DWARF III03장 OS Hack_#22 실행 가능 파일과 그 실행 방법_#23 리눅스에서 Huge Page 사용하기_#24 CRIU를 사용하여 프로세스 저장 및 재개하기_#25 procfs/sysfs의 기본 파악하기_#26 용도에 맞는 파일 시스템 선택하기_#27 특정 프로세스에서 보이는 파일 교체하기_#28 FUSE를 사용하여 파일 시스템 직접 만들기_#29 특수한 메모리 영역 vsyscall과 vDSO_#30 KVM을 사용하여 하이퍼바이저 생성하기_#31 리눅스 커널 Hack 입문_#32 UniKernel: 애플리케이션을 OS로 구동하기_#33 UEFI와 Secure Boot_#34 GNU 툴체인으로 기계어 파일 출력하기_#35 _#30 QEMU에서 동작하는 펌웨어 만들기_#36 크롬북에서 직접 만든 펌웨어 실행하기04장 컨테이너 Hack_#37 리눅스 네임스페이스로 프로세스 분리하기_#38 cgroup으로 프로세스의 리소스 관리하기_#39 chroot/pivot_root로 루트 디렉터리 전환하기_#40 일반 유저가 root처럼 행동하는 방법 3가지_#41 rootless 컨테이너 사용법과 구조_#42 유저 네임스페이스 내에서 각종 네임스페이스 생성하기_#43 /proc/PID/root에서 컨테이너 내의 파일에 직접 접근하기05장 디버거, 트레이서 Hack_#44 gdb Tips_#45 rr을 사용하여 Record and Replay 디버깅하기_#46 새니타이저로 저수준 버그 발견하기: 새니타이저 I_#47 Address Sanitizer의 구조: 새니타이저 II_#48 리눅스 퍼포먼스 분석 입문_#49 ftrace를 사용하여 커널 내에서 발생하는 일 트레이스하기_#50 eBPF를 사용한 트레이싱 입문_#51 DBI로 실행 명령을 트레이스 및 변경하기_#52 Intel PT를 사용하여 고속으로 트레이스 얻기06장 보안 Hack_#53 seccomp로 프로세스에서 사용할 수 있는 시스템 콜 제한하기_#54 Landlock으로 비특권 프로세스 샌드박스 만들기_#55 ASLR: 잘못된 메모리 접근에 대한 보안 메커니즘_#56 ROP: 메모리 손상을 악용하는 표준적인 공격 기법_#57 Intel CET: ROP에 대한 보안 메커니즘_#58 Clang CFI를 이용하여 잘못된 제어 흐름 감지하기_#59 스택 프레임의 변화 관찰하기_#60 퍼징의 개요와 분류_#61 그레이박스 퍼징으로 버그 및 취약성 찾기_#62 LibAFL로 퍼저 구현하기_#63 LibAFL로 구현한 퍼저 개선하기_#64 angr로 심벌릭 실행하기_#65 BadUSB: 사용자를 속이는 USB 디바이스_#66 Row Hammer: DRAM의 취약성에 대한 공격 기법_#67 Meltdown과 Spectre: CPU의 취약성에 대한 공격 기법07장 수치 표현과 데이터 처리 Hack_#68 정수 표현의 기초 지식_#69 다양한 정수 표현_#70 부동소수점 수의 비트열 표현 이해하기_#71 부동소수점 예외_#72 부동소수점 수의 반올림 방식 변경하기_#73 부동소수점 환경을 다루는 코드에 대한 컴파일러 최적화와의 싸움_#74 NaN 깊이 파헤치기_#75 부동소수점 수의 아키텍처별 차이 다루기_#76 SIMD 명령 세트의 기초 지식_#77 SIMD 병렬화 코드 작성하기_#78 SIMD 명령을 사용한 여러 가지 테크닉08장 언어 처리계 Hack_#79 NaN을 활용하여 64비트 값에 태그 붙인 값 저장하기_#80 ucontext.h로 코루틴 구현하기_#81 Profile Guided Optimization_#82 LD_PRELOAD를 사용하여 메모리 할당자 교체하기_#83 ABI와 호출 규약 이해하기_#84 libffi로 실행 시까지 시그니처를 알 수 없는 함수 호출하기_#85 실행 시 기계어 생성하기_#86 GCC/Clang의 내장 함수 이용하기09장 그 밖의 Hack_#87 용어집_#88 Binary Hacks에 필요한 도구_#89 문헌 안내