前几天ㄚ琪才刚借了笑谈软体工程 : 敏捷开发法的逆袭重读,隔没几天就又拿了Binary Hacks:骇客秘传技巧一百招来看,可能不太像是我应该读的一本书,不过总是有些时候会碰到一些神秘错误,但总不能一直靠琪倒来解决吧,追根究底的使用底层的开发技术或许可以解决这样的问题。
[adsense][/adsense]
本书的主题是底层的程式开发技术。
底层指的是接近“赤裸”的电脑硬体。
软体的世界是藉着不断堆叠“抽象化”而进步的。组合语言是机械语言的抽象化、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开发环境的应该也可以运用。嗯有空读一读。
