Statut: | En développement |
Emplacement: | https://github.com/bdcht/ccrawl |
Version: | 1.x |
Doc : | http://ccrawl.readthedocs.io/en/latest/index.html |
Ccrawl utilise clang pour construire une base de données liée à diverses structures de données C/C++ (struct, union, classe, enum, typedef, prototypes et macros) qui permet d'identifier les types de données et les constantes/macros en interrogeant cette base de données pour des propriétés spécifiques, y compris les propriétés. lié à la disposition de la mémoire structure/classe.
En gros cela permet par exemple de
Ccrawl permet alors de sortir les structures trouvées dans de nombreux formats : C/C++ bien sûr, mais aussi ctypes, ou amoco. La sortie ctypes d'une classe C++ correspond à une disposition d'instance (objet) en mémoire, y compris tous les pointeurs de table virtuelle (ou VTT) résultant d'éventuellement plusieurs classes parentes (éventuellement virtuelles).
Enfin, Ccrawl permet de calculer diverses statistiques sur une API de bibliothèque, et permet de calculer le graphe de dépendances d'un type donné comme par exemple (voir tests/samples/xxx/graph.h) :
La documentation utilisateur et l'API sont disponibles sur http://ccrawl.readthedocs.io/en/latest/index.html
Considérez la structure C suivante du fichier samples/simple.h
structure S { char c; entier n; syndicat { caractère non signé x[2] ; courts métrages non signés ; } toi; char (*PtrCharArrayOf3[2])[3]; void (*pfunc)(int, int); } ;
Tout d’abord, collectez la définition de la structure dans une base de données locale :
$ ccrawl -l test.db -g 'test0' collecter des échantillons/simple.h [100%] simple.h [ 2] -------------------------------------------------- ------------------- sauvegarde de la base de données... [ 2]
Ensuite, il est possible de traduire la structure complète en ctypes
$ ccrawl -l test.db show -r -f ctypes 'struct S' struct_S = type('struct_S',(Structure,),{}) 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(Aucun, c_int, c_int)))]
Ou simplement pour calculer les décalages des champs
$ ccrawl -l test.db info 'struct S' identifiant : struct S classe : cStruct source : simple.h mot-clé : test0 taille : 40 décalages : [(0, 1), (4, 4), (8, 2), (16, 16), (32, 8)]
Passons maintenant à un exemple C++ plus délicat :
$ ccrawl -l test.db collect -a --cxx samples/shahar.cpp [100%] shahar.cpp [ 18] -------------------------------------------------- ------------------- sauvegarde de la base de données... [ 18]
Nous pouvons montrer une définition complète (récursive) d'une classe :
$ ccrawl -l test.db show -r 'classe Enfant' classe Grand-parent { publique: vide virtuel grandparent_foo(); int grandparent_data; } ; classe Parent1 : grand-parent public virtuel { publique: vide virtuel parent1_foo(); int parent1_data; } ; classe Parent2 : grand-parent public virtuel { publique: vide virtuel parent2_foo(); int parent2_data; } ; classe Enfant : public Parent1, public Parent2 { publique: vide virtuel child_foo(); int enfant_données ; } ;
Et sa disposition de la mémoire ctypes :
$ ccrawl -l test.db show -f ctypes 'class Child' struct___layout$Child = type('struct___layout$Child',(Structure,),{}) 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$Grandparent", c_void_p), ("grandparent_data", c_int)]
Voir la documentation pour plus d'exemples.