harness-writing は何をしますか?
効果的なファジングハーネスをさまざまな言語で記述するためのテクニック。新しいファズターゲットを作成する場合や既存のハーネスコードを改善する場合に使用します。
はじめに
ファジングハーネスは、テスト対象のプログラムにデータを供給し、その動作を監視するためのインターフェースです。適切に設計されたハーネスは、ファジングの効率と有効性を大幅に向上させます。このスキルでは、複数の言語におけるハーネス記述のベストプラクティス、よくある落とし穴、および最適化手法を学びます。
サポート言語
- C/C++
- Python
- Rust
- Go
- Java
主なトピック
1. ハーネスの基本構造
ハーネスは通常、以下のコンポーネントから構成されます:
- 入力データの準備
- API/関数の呼び出し
- エラーハンドリング
- クリーンアップ
2. 入力生成パターン
ファザーから受け取ったバイト列を適切なデータ構造に変換する方法:
- 固定長バッファ
- 可変長データ(プロトコルバッファなど)
- ファイルベースの入力
3. エラー処理と異常検出
- アサーションの活用
- メモリエラーの検出(AddressSanitizer など)
- 未定義動作の検出
4. ツール連携
- libFuzzer:
LLVMFuzzerTestOneInput関数の実装 - AFL:
__AFL_FUZZ_INITと__AFL_FUZZ_TESTCASE_BUFの使用法 - Honggfuzz:
HF_ITERマクロの活用 - Jazzer (Java):
FuzzerTestOneInputメソッドの実装
実践例
以下に、C言語でのシンプルなハーネス例を示します:
#include <stdint.h>
#include <stddef.h>
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
if (size < 3) return 0;
uint8_t command = data[0];
uint16_t value = (data[1] << 8) | data[2];
// 対象関数の呼び出し
process_command(command, value);
return 0;
}
リソース
コントリビューション
このスキルの改善提案は、GitHub リポジトリ にて受け付けています。バグレポートやプルリクエストをお待ちしています。