
Un outil pour extraire les informations RTTI des exécutables Delphi, écrit en Python pur.
Cet outil analyse un fichier exécutable à la recherche de données Delphi, notamment les RTTI et les tables de fonctions virtuelles. Il génère un fichier JSON contenant des informations sur les classes et fonctions identifiées, pouvant être utilisé pour des analyses supplémentaires, par exemple :
Un script IDAPython capable de charger la sortie dans IDA est fourni.
Ce script a été écrit pour compléter d'autres outils de rétro-ingénierie Delphi.
Publié en open source par NCC Group Plc - http://www.nccgroup.com/
Développé par David Cannings (@edeca) [email protected]
http://www.github.com/nccgroup/pythia
Ce projet est publié sous licence AGPL. Veuillez consulter le fichier LICENSE pour plus d'informations.
Le flux de haut niveau est le suivant :
Les vftables Delphi sont bien documentées. Les informations pour la dernière version sont disponibles auprès d'Embarcadero. Une documentation non officielle est disponible pour Delphi 2005 (voir ici).
Le code source de Free Pascal est également utile (miroir Github).
Le premier élément d'une vftable est vmtSelfPtr, qui pointe vers le début de la table de fonctions virtuelles. Le script parcourt chaque segment de code du fichier PE à la recherche de tout emplacement pointant vers l'avant de +0x4C octets. Notez que le compilateur Delphi aligne les vftables sur une limite de 4 octets (par souci d'optimisation).
Par exemple, l'adresse virtuelle (VA) 0x0046E1C8 contient l'offset 0x0046E214, qui est 0x4C en avant de l'emplacement actuel. Comme le montre IDA :
.text:0046E1C8 ; Classes::TComponent *vftable_TDCP_misty1
.text:0046E1C8 14 E2 46 00 vftable_TDCP_misty1 dd offset off_46E214
Cette approche peut générer des faux positifs ; par conséquent, les autres champs de la vftable sont vérifiés pour des valeurs plausibles. Par exemple, le vmtInstanceSize est vérifié pour s'assurer qu'il n'est pas excessif, et les pointeurs de fonctions sont vérifiés pour s'assurer qu'ils se trouvent dans une section exécutable. Lors des tests, le taux de faux positifs était très faible, malgré la méthode de recherche par force brute.
Chaque fonction trouvée dans une vftable est vérifiée pour déterminer si elle est héritée du parent ou surchargée. Delphi ne prend pas en charge l'héritage multiple, ce qui permet de déterminer cela en comparant le pointeur dans la vftable parente au même offset.
Si les deux pointeurs référencent la même fonction, elle est héritée. Si l'enfant a un pointeur différent, alors elle a été surchargée.
La sortie principale de l'outil est un fichier JSON qui peut être injecté dans des traitements ou outils ultérieurs. Cependant, quelques autres formats de sortie sont inclus.
Utilisez l'option --save-tree pour générer un fichier comme :
TObject (at 0x0040112c)
|-- Exception (at 0x004081f8)
| |-- EAbort (at 0x00408260)
| |-- EAbstractError (at 0x00408ad4)
| |-- EAssertionFailed (at 0x00408a74)
| |-- EBcdException (at 0x004bd110)
| | +-- EBcdOverflowException (at 0x004bd16c)
| |-- EBitsError (at 0x0041ab04)
| |-- EComponentError (at 0x0041abbc)
| |-- EConvertError (at 0x00408850)
| |-- EDCP_cipher (at 0x0046a0ac)
| | +-- EDCP_blockcipher (at 0x0046a29c)
| |-- EDCP_hash (at 0x00469f20)
.. etc ..
PACKAGEINFO ou DVCLAL) et ajuster l'analyse en fonction des différentes dispositions de vftable.vmtTypeInfo dans la vftable).call [ecx+3Fh] à une méthode d'instance).TComparer<System.Bindings.EvalProtocol.TPair<System.IInterface,System.Pointer>> qui sont assez indéchiffrables dans IDA.Veuillez m'envoyer des exemples de binaires sur lesquels cet outil ne fonctionne pas, afin qu'il puisse être amélioré.