Esta herramienta escanea un archivo ejecutable para los datos de Delphi, incluidas las tablas de funciones RTTI y virtuales. Emite un archivo JSON con información sobre clases y funciones identificadas, que se pueden utilizar para un análisis adicional, por ejemplo:
Se proporciona un script Idapython que puede cargar la salida en IDA.
El script fue escrito para complementar otras herramientas para la ingeniería inversa de Delphi.
Lanzado 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. Consulte la licencia para obtener más información.
El flujo de alto nivel es:
Los vftables de Delphi están bien documentados. La información para la última versión está disponible en Embarcadero. La documentación no oficial está disponible para Delphi 2005 (ver aquí).
El código fuente de Free Pascal también es útil (espejo GitHub).
El primer elemento en un 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 para cualquier ubicación que apunte hacia adelante +0x4C bytes. Tenga en cuenta que el compilador Delphi alinea los vftables con un límite de 4 bytes (para optimización).
Por ejemplo, el siguiente VA 0x0046E1C8 contiene el desplazamiento 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 tanto, otros campos en el Vftable se verifican para obtener valores sensibles. Por ejemplo, el vmtInstanceSize se verifica para asegurarse de que no sea excesivo y los punteros de la función se verifican en una sección ejecutable. Durante las pruebas, la tasa de falsos positivos fue muy baja, a pesar del método de búsqueda de fuerza bruta.
Cada función que se encuentra en un Vftable se verifica para ver si se hereda del padre o sobrecargado. Delphi no admite la herencia múltiple, por lo que esto se puede lograr verificando el puntero en el Vftable principal con el mismo desplazamiento.
Si ambos punteros hacen referencia a la misma función, se hereda. Si el niño tiene un puntero diferente, entonces se ha sobrecargado.
La salida principal de la herramienta es un archivo JSON que puede alimentarse en el procesamiento / herramientas posteriores. Sin embargo, se incluyen algunos otros formatos de salida.
Use 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 recurso DVCLAL ) y ajuste el escaneo para diferentes diseños de Vftable.call [ecx+3Fh] a un método de instancia)TComparer<System.Bindings.EvalProtocol.TPair<System.IInterface,System.Pointer>> que son bastante indescifrables en IDA.Envíeme ejemplos de binarios donde esta herramienta no funciona, por lo que se puede mejorar.