
Una herramienta para extraer información RTTI de ejecutables de Delphi, escrita en Python puro.
Esta herramienta escanea un archivo ejecutable en busca de datos de Delphi, incluyendo RTTI y tablas de funciones virtuales. Genera un archivo JSON con información sobre las clases y funciones identificadas, que puede utilizarse para análisis adicionales, por ejemplo:
Se incluye un script de IDAPython que puede cargar la salida en IDA.
El script fue escrito para complementar otras herramientas de ingeniería inversa de Delphi.
Publicado como código abierto por NCC Group Plc - http://www.nccgroup.com/
Desarrollado por David Cannings (@edeca) [email protected]
http://www.github.com/nccgroup/pythia
Este proyecto se publica bajo la licencia AGPL. Consulta LICENSE para más información.
El flujo de alto nivel es:
Las vftables de Delphi están bien documentadas. La información para la última versión está disponible en Embarcadero. Documentación no oficial está disponible para Delphi 2005 (ver aquí).
El código fuente de Free Pascal también es útil (espejo de Github).
El primer elemento de una vftable es vmtSelfPtr, que apunta al inicio de la
tabla de funciones virtuales. El script escanea cada segmento de código en el archivo PE en busca de
cualquier ubicación que apunte hacia adelante +0x4C bytes. Ten en cuenta que el compilador de Delphi alinea
las vftables a un límite de 4 bytes (para optimización).
Por ejemplo, la siguiente VA 0x0046E1C8 contiene el offset 0x0046E214, que
está 0x4C por delante de la ubicación actual. Como se muestra en IDA:
.text:0046E1C8 ; Classes::TComponent *vftable_TDCP_misty1
.text:0046E1C8 14 E2 46 00 vftable_TDCP_misty1 dd offset off_46E214
Este enfoque puede generar falsos positivos, por lo que se comprueban otros campos de la
vftable en busca de valores razonables. Por ejemplo, se verifica que vmtInstanceSize
no sea excesivo y que los punteros a función se encuentren
en una sección ejecutable. Durante las pruebas, la tasa de falsos positivos fue
muy baja, a pesar del método de búsqueda por fuerza bruta.
Cada función encontrada en una vftable se comprueba para ver si se hereda del padre o está sobrescrita. Delphi no admite herencia múltiple, por lo que esto se puede lograr comprobando el puntero en la vftable del padre con el mismo offset.
Si ambos punteros hacen referencia a la misma función, se hereda. Si el hijo tiene un puntero diferente, entonces está sobrescrita.
La salida principal de la herramienta es un archivo JSON que puede introducirse en procesos / herramientas posteriores. Sin embargo, se incluyen algunos otros formatos de salida.
Usa la opción --save-tree para generar un archivo como:
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 o DVCLAL) y ajustar el escaneo para diferentes formatos de vftable.vmtTypeInfo en la vftable)call [ecx+3Fh] con un método de instancia)TComparer<System.Bindings.EvalProtocol.TPair<System.IInterface,System.Pointer>> que son bastante indescifrables en IDA.Por favor, envíame ejemplos de binarios donde esta herramienta no funcione, para que pueda mejorarse.