Binary Hacks ─ ハッカー秘伝のテクニック100選


目次

本書に寄せて by 川合史朗さん
クレジット
はじめに

1章 イントロダクション

1. Binary Hack入門
2. Binary Hack用語の基礎知識
3. fileでファイルの種類をチェックする
4. odでバイナリファイルをダンプする

2章 オブジェクトファイルHack

5. ELF入門
6. 静的ライブラリと共有ライブラリ
7. lddで共有ライブラリの依存関係をチェックする
8. readelfでELFファイルの情報を表示する
9. objdumpでオブジェクトファイルをダンプする
10. objdumpでオブジェクトファイルを逆アセンブルする
11. objcopyで実行ファイルにデータを埋め込む
12. nmでオブジェクトファイルに含まれるシンボルをチェックする
13. stringsでバイナリファイルから文字列を抽出する
14. c++filtでC++のシンボルをデマングルする
15. addr2lineでアドレスからファイル名と行番号を取得する
16. stripでオブジェクトファイルからシンボルを削除する
17. arで静的ライブラリを操作する
18. CとC++のプログラムをリンクするときの注意点
19. リンク時のシンボルの衝突に注意する
20. GNU/Linuxの共有ライブラリを作るときPICでコンパイルするのはなぜか
21. statifierで動的リンクの実行ファイルを擬似的に静的リンクにする

3章 GNUプログラミングHack

22. GCCのGNU拡張入門
23. GCCでインラインアセンブラを使う
24. GCCのビルトイン関数による最適化を活用する
25. glibcを使わないでHello Worldを書く
26. TLS(スレッドローカルストレージ)を使う
27. glibcでロードするライブラリをシステムに応じて切り替える
28. リンクされているライブラリによってプログラムの動作を変える
29. ライブラリの外に公開するシンボルを制限する
30. ライブラリの外に公開するシンボルにバージョンをつけて動作を制御する
31. main()の前に関数を呼ぶ
32. GCCが生成したコードによる実行時コード生成
33. スタックに置かれたコードの実行を許可/禁止する
34. ヒープ上に置いたコードを実行する
35. PIE(位置独立実行形式)を作成する
36. C++でsynchronized methodを書く
37. C++でシングルトンを生成する
38. g++の例外処理を理解する(throw編)
39. g++の例外処理を理解する(SjLj編)
40. g++の例外処理を理解する(DWARF2編)
41. g++ 例外処理のコストを理解する

4章 セキュアプログラミングHack

42. GCCセキュアプログラミング入門
43. -ftrapvで整数演算のオーバーフローを検出する
44. Mudflap でバッファオーバーフローを検出する
45. -D_FORTIFY_SOURCEでバッファオーバーフローを検出する
46. -fstack-protectorでスタックを保護する
47. bitmaskする定数は符号なしにする
48. 大きすぎるシフトに注意
49. 64ビット環境で0とNULLの違いに気を付ける
50. POSIXのスレッドセーフな関数
51. シグナルハンドラを安全に書く方法
52. sigwaitで非同期シグナルを同期的に処理する
53. sigsafeでシグナル処理を安全にする
54. Valgrindでメモリリークを検出する
55. Valgrindでメモリの不正アクセスを検出する
56. Helgrindでマルチスレッドプログラムのバグを検出する
57. fakerootで擬似的なroot権限でプロセスを実行する

5章 ランタイムHack

58. プログラムがmain()にたどりつくまで
59. システムコールはどのように呼び出されるか
60. LD_PRELOADで共有ライブラリを差し換える
61. LD_PRELOAD で既存の関数をラップする
62. dlopenで実行時に動的リンクする
63. Cでバックトレースを表示する
64. 実行中のプロセスのパス名をチェックする
65. ロードしている共有ライブラリをチェックする
66. プロセスや動的ライブラリがマップされているメモリを把握する
67. libbfdでシンボルの一覧を取得する
68. C++ のシンボルを実行時にデマングルする
69. ffcallでシグネチャを動的に決めて関数を呼ぶ
70. libdwarfでデバッグ情報を取得する
71. dumperで構造体のデータを見やすくダンプする
72. オブジェクトファイルを自力でロードする
73. libunwindでコールチェインを制御する
74. GNU lightningでポータブルに実行時コード生成する
75. スタック領域のアドレスを取得する
76. sigaltstackでスタックオーバーフローに対処する
77. 関数へのenter/exitをフックする
78. シグナルハンドラからプログラムの文脈を書き換える
79. プログラムカウンタの値を取得する
80. 自己書き換えでプログラムの動作を変える
81. SIGSEGVを使ってアドレスの有効性を確認する
82. straceでシステムコールをトレースする
83. ltraceで共有ライブラリの関数呼び出しをトレースする
84. JockeyでLinuxのプログラムの実行を記録、再生する
85. prelinkでプログラムの起動を高速化する
86. livepatchで実行中のプロセスにパッチをあてる

6章 プロファイラ・デバッガHack

87. gprofでプロファイルを調べる
88. sysprofでお手軽にシステムプロファイルを調べる
89. oprofileで詳細なシステムプロファイルを得る
90. GDBで実行中のプロセスを操る
91. ハードウェアのデバッグ機能を使う
92. Cのプログラムの中でブレークポイントを設定する

7章 その他のHack

93. Boehm GCの仕組み
94. プロセッサのメモリオーダリングに注意
95. Portable Coroutine Library(PCL)で軽量な並行処理を行う
96. CPUのクロック数をカウントする
97. 浮動小数点数のビット列表現
98. x86が持つ浮動小数点演算命令の特殊性
99. 結果が無限大やNaNになる演算でシグナルを発生させる
100. 文献案内
索引

Satoru Takabayashi