状態: | 開発中 |
位置: | https://github.com/bdcht/ccrawl |
バージョン: | 1.x |
ドクター: | http://ccrawl.readthedocs.io/en/latest/index.html |
Ccrawl は、clang を使用して、さまざまな C/C++ データ構造 (構造体、共用体、クラス、列挙型、typedef、プロトタイプ、マクロ) に関連するデータベースを構築します。これにより、このデータベースにプロパティなどの特定のプロパティをクエリすることで、データ型と定数/マクロを識別できます。構造体/クラスのメモリ レイアウトに関連します。
基本的には、たとえば次のことが可能になります
Ccrawl を使用すると、見つかった構造をさまざまな形式 (C/C++ はもちろん、ctypes や amoco など) で出力できます。 C++ クラスの ctypes 出力は、複数の親 (仮想) クラスの可能性から生じるすべての仮想テーブル ポインター (または VTT) を含む、メモリ内のインスタンス (オブジェクト) レイアウトに対応します。
最後に、Ccrawl を使用すると、ライブラリ API に関するさまざまな統計を計算でき、たとえば、次のような任意のタイプの依存関係グラフを計算できます (tests/samples/xxx/graph.h を参照)。
ユーザー ドキュメントと API は http://ccrawl.readthedocs.io/en/latest/index.html にあります。
ファイルsamples/simple.hの次のC構造体を考えてみましょう。
構造体 S { 文字c; int n; 結合 { unsigned char x[2]; unsigned short s; } う; char (*PtrCharArrayOf3[2])[3]; void (*pfunc)(int, int); };
まず、ローカル データベースに構造定義を収集します。
$ ccrawl -l test.db -g 'test0' サンプル/simple.h を収集 [100%] シンプル.h [2] -------------------------------------------------- ------------------ データベースを保存しています... [ 2]
次に、完全な構造を ctypes に変換できます。
$ ccrawl -l test.db show -r -f ctypes 'struct S' struct_S = type('struct_S',(構造体,),{}) Union_b0eccf67 = type('union_b0eccf67',(Union,),{}) Union_b0eccf67._fields_ = [("x", c_ubyte*2), (「s」、c_ushort)] struct_S._anonymous_ = ("u",) struct_S._fields_ = [("c", c_byte), ("n", c_int), ("u"、union_b0eccf67)、 ("PtrCharArrayOf3", POINTER(c_byte*3)*2), ("pfunc", POINTER(CFUNCTYPE(None, c_int, c_int)))]
または単にフィールドのオフセットを計算するため
$ ccrawl -l test.db 情報 '構造体 S' 識別子: 構造体 S クラス : cStruct ソース: simple.h タグ : テスト0 サイズ:40 オフセット: [(0, 1), (4, 4), (8, 2), (16, 16), (32, 8)]
ここで、よりトリッキーな C++ の例を扱ってみましょう。
$ ccrawl -l test.dbcollect -a --cxx サンプル/shahar.cpp [100%] シャハール.cpp [ 18] -------------------------------------------------- ------------------ データベースを保存しています... [ 18]
クラスの完全な(再帰的) 定義を表示できます。
$ ccrawl -l test.db show -r 'クラスの子' クラス 祖父母 { 公共: 仮想 void grandparent_foo(); int 祖父母データ; }; class Parent1 : virtual public Grandparent { 公共: 仮想 voidparent1_foo(); int 親 1_データ; }; class Parent2 : virtual public Grandparent { 公共: 仮想 voidparent2_foo(); int 親 2_データ; }; クラス子 : public Parent1, public Parent2 { 公共: 仮想 void child_foo(); int child_data; };
そして、その ctypes メモリ レイアウトは次のとおりです。
$ ccrawl -l test.db show -f ctypes 'class Child' struct___layout$Child = type('struct___layout$Child',(構造,),{}) struct___layout$Child._fields_ = [("__vptr$Parent1", c_void_p), ("parent1_data", c_int), ("__vptr$Parent2", c_void_p), ("parent2_data", c_int), ("child_data", c_int), ("__vptr$祖父母", c_void_p), ("祖父母データ", c_int)]
その他の例については、ドキュメントを参照してください。