前幾天ㄚ琪才剛借了笑談軟體工程 : 敏捷開發法的逆襲重讀,隔沒幾天就又拿了Binary Hacks:駭客秘傳技巧一百招來看,可能不太像是我應該讀的一本書,不過總是有些時候會碰到一些神秘錯誤,但總不能一直靠琪倒來解決吧,追根究底的使用底層的開發技術或許可以解決這樣的問題。
本書的主題是底層的程式開發技術。
底層指的是接近「赤裸」的電腦硬體。
軟體的世界是藉著不斷堆疊「抽象化」而進步的。組合語言是機械語言的抽象化、C 語言是組合語言的抽象化。而在 C 語言之上,還有許多以 C 實作的各種 script 語言。抽象化可將底層的複雜部份隱藏起來,為開發者提供更具生產力、安全性更高的程式開發手段。
但是,也不能因為這樣就認為把底層的技術完全忘光也能開發程式。若想追求性能極限、盡可能提高可靠度、想解決偶爾發生的「神秘錯誤」,就不得不面對底層細節了。可惜的是,抽象化並非萬全的解決之道。
比如說,Ruby 與 Perl 寫的 script 若是發生 segmentation fault 異常結束的話,就需要下到 C 語言這層尋找原因。有時也會遇到特殊的問題,需要發揮「在執行的時候改寫程式自己的機械碼」這種棘手的技巧。如果不知道底層技術的話,就沒辦法面對這些問題了。
本書的目標,就是介紹這些場面之中能夠發揮威力的眾多訣竅,也就是「Binary Hacks」。Binary Hack 的名稱是來自 0 與 1,也就是程式開發時位於最底層的 binary 觀念。本書把 Binary Hacks 定義為「運用底層軟體技術的程式設計訣竅」,廣泛涵蓋了基本工具的使用方式、安全議題、以及運用 OS 與處理器功能等進階議題。
以往,這類訣竅都沒有整理起來,像是「知道的人就會知道」的東西。本書就是嘗試把這些訣竅集合起來,使它們成為誰都可以運用的工具。本書主要是收集在實際情形下幫得上忙的 hacks,但也提到不少沒什麼用、卻很有趣的 hacks。希望您能透過本書學到有用的訣竅、體會底層技術的趣味。
目錄
推薦序
執筆群
寫在前面
Chapter 1 概論
1. Binary Hack 入門
2. Binary Hack 用語的基礎知識
3. 以 file 檢查檔案種類
4. 以 od 傾印 binary 檔
Chapter 2 Object File Hacks
5. ELF 入門
6. 靜態函式庫與共享函式庫
7. 以 ldd 檢查共享函式庫的依存關係
8. 以 readelf 顯示 ELF 檔案的資訊
9. 以 objdump 傾印 object file 內容
10. 以 objdump 反組譯 object file
11. objcopy 對執行檔嵌入資料
12. 以 nm 檢查 object file 內含的 symbols
13. 以 strings 抽出 binary 檔案內的字串
14. 以 c++filt 將 C++ 的符號 demangle
15. 以 addr2line 把位址轉換成檔名與行號
16. 以 strip 移除 object file 的 symbols
17. 以 ar 操作靜態函式庫
18. 將 C 與 C++ 程式互相連結時的注意事項
19. 注意連結時的 symbol 衝突
20. 為何在製作 GNU/Linux 共享函式庫的時候要以 PIC 編譯
21. 以 statifier 為動態連結的執行檔模擬靜態連結
Chapter 3 GNU Programming Hacks
22. GCC 的 GNU 擴充功能入門
23. 使用 GCC 的行內組譯功能
24. 透過 GCC 內建函式活用最佳化
25. 在不使用 glibc 的前提下寫 Hello World
26. 使用 TLS (thread local storage)
27. 以 glibc 根據系統類型切換要載入的函式庫
28. 根據連結的函式庫改變程式運作
29. 限制函式庫對外公開的 symbols
30. 為函式庫對外公開的symbols 加上版本以控制運作
31. 在 main() 之前呼叫函式
32. 以 GCC 產生的程式碼在執行時產生程式碼
33. 許可或禁止 stack 上的程式碼
34. 執行 heap 上的程式碼
35. 建立 PIE ( 位置獨立執行格式)
36. 以 C++ 寫 synchronized method
37. 以 C++ 寫 singleton
38. 理解 g++ 的例外處理機制 (throw 篇)
39. 理解 g++ 的例外處理機制 (SjLj 篇)
40. 理解 g++ 的例外處理機制 (DWARF2 篇)
41. 理解 g++ 處理例外的成本
Chapter 4 Secure Programming Hacks
42. GCC 安全程式設計入門
43. 以 -ftrapv 偵測整數運算溢位
44. 以 Mudflap 偵測緩衝區溢位
45. 以 -D_FORTIFY_SOURCE 偵測緩衝區溢位
46. 以 -fstack-protector 保護 stack
47. 以無號整數定義 bitmask 常數
48. 注意太大的 shift 移位
49. 注意 64-bit 環境下 0 與 NULL 的不同
50. POSIX 的 thread-safe 函式
51. 如何撰寫安全的 signal handler
52. 以 sigwait 同步處理異步 signal
53. 以 sigsafe 安全地處理 signal
54. 以 Valgrind 偵測記憶體洩漏
55. 以 Valgrind 偵測記憶體操作失誤
56. 以 Helgrind 偵測 multi-thread 程式的臭蟲
57. 以 fakeroot 模擬 root 權限執行程式
Chapter 5 Runtime Hacks
58. 程式如何執行到 main()
59. 系統函式的呼叫過程
60. 以 LD_PRELOAD 抽換共享函式庫
61. 以 LD_PRELOAD 包裝現有函式
62. 以 dlopen 在執行時動態連結
63. 顯示 C 的 backtrace
64. 檢查執行中的 process 的路徑
65. 檢查目前載入的共享函式庫
66. 掌握 process 與動態函式庫映射的記憶體
67. 以 libbfd 取得 symbol 一覽
68. 執行時將 C++ symbol 進行 demangle
69. 以 ffcall 動態決定函式 signature 進行呼叫
70. 以 libdwarf 取得 debug 資訊
71. 以 dumper 將結構內容以更容易看懂的方式顯示
72. 自力載入 object file
73. 以 libunwind 控制呼叫串列
74. 以 GNU lightning 可攜地在執行時產生程式碼
75. 取得 stack 範圍的位址
76. 以 sigaltstack 處理 stack overflow 的狀況
77. 附掛在函式的 enter/exit
78. 從 signal handler 改寫程式的執行環境
79. 取得 program counter 的值
80. 改寫自身程式碼以改變程式行為
81. 以 SIGSEGV 檢查位址是否有效
82. 以 strace 追蹤系統呼叫
83. 以 ltrace 追蹤共享函式庫呼叫
84. 以 Jockey 紀錄、重現 Linux 程式執行狀況
85. 以 prelink 加速程式啟動
86. 以 livepatch 改寫執行中的 process
Chapter 6 Pro_ler.Debugger Hacks
87. 以 gprof 量測執行效能
88. 以 sysprof 輕鬆量測系統效能
89. 以 oprofile 詳細量測系統效能
90. 以 GDB 操作執行中的 process
91. 使用硬體的除錯功能
92. 在 C 程式中設定中斷點
Chapter 7 其他 Hacks
93. Boehm GC 的機制
94. 注意 process 的 memory ordering
95. 以 Portable Coroutine Library (PCL) 進行輕量的平行處理
96. 計算 CPU 的 clock 數
97. 浮點數的 bit 表示法
98. x86 擁有的浮點數運算指令的特殊之處
99. 運算結果等於無限大或 NaN 的時候引發 signal
100. 文獻介紹
索引
↑↑↑↑↑↑↑
這本書真的不是一般人能看的,在寫前面裡就提到了所需的知識,像是要讀Unix的基本操作,可以讀Unix程式開發環境之類的書,還有C語言程式設計的書、跟C++程式語言、或參考我們在程式語言教學 – C、C++、OpenGL、STL的介紹。對象平台是UNIX,焦點集中在GNU/Linux,所以使用Windows的人就不太適合了,不過有使用Cygwin的GNU開發環境的應該也可以運用。嗯有空讀一讀。