2011-07-06 15 views
6

EDITAR:¿Cómo distinguir las funciones definidas por el usuario/biblioteca de un archivo compilado?

Lo que quiero es distinguir enlazados estáticamente funciones de biblioteca y de usuario auto-escrita funciones dentro un archivo compilado (por ejemplo archivo PE).

¿Cómo lograr eso? (Estoy pensando en la comparación de bases de datos, pero no sé ninguna base de datos.)

Por cierto, (ya he sabido mucho antes de hacer esta pregunta) para las funciones de biblioteca vinculadas dinámicamente, son solo una entrada en la importación mesa (de PE).


Por funciones de la biblioteca, me refiero a los definidos en las bibliotecas, tales como STL (sé que esto es un mal nombre).

Por funciones definidas por el usuario, quiero decir aquellas escritas por programadores individuales.

¿Hay alguna forma programática para lograr este objetivo?

En este momento estoy pensando en comparar binarios con una base de datos, pero no conozco ninguna base de datos hasta el momento.

Por favor, recomiende una base de datos o una respuesta diferente. Gracias.

+0

solo a modo de información: IDA disassembler tiene archivos de "firma FLIRT" que utiliza para tratar de determinar este tipo de información, y es moderadamente exitoso. entonces, como ha sido programado antes, sí, es posible. Sin embargo, estoy seguro de que es un esfuerzo enorme hacer esto, y necesitarás generar el tuyo o usar las firmas de otra persona. además, no es una tasa de éxito del 100%, * especialmente para archivos optimizados *. si el archivo ha sido optimizado, es casi imposible (incluso a mano usando una buena herramienta como IDA) averiguar exactamente qué funciones son las que provienen de las bibliotecas. – shelleybutterfly

+0

para compilaciones de depuración, podría ser más factible. pero diría que si una herramienta que ha existido tanto tiempo como IDA todavía no puede hacerlo, tendrá un largo camino por recorrer si intenta implementar su propia solución aquí, y es probable que siga siendo así. bastante imperfecto y no llega ni cerca del 100% en archivos altamente optimizados. enlace a ida si desea verificarlo: http://www.hex-rays.com/idapro/ (no estoy seguro de cuánta funcionalidad tiene la versión demo, pero al menos debería darle una idea, creo, de lo que estoy describiendo) – shelleybutterfly

+0

@shelleybutterfly en realidad, mi propósito de esta pregunta es preguntar cómo IDA logra esto .... –

Respuesta

1

Esta respuesta supone que desea analizar un ejecutable estándar de Windows que está vinculado dinámicamente con otras bibliotecas de importación (.lib y archivos .dll asociados que no están vinculados estáticamente), y si este es el caso, desea interperet la estructura de archivos PE (Portable Executable).

Aquí hay un good article para comenzar, con un código de muestra para volcar el encabezado PE.

Deseará centrarse en la tabla Importar (sección .idata) para llamadas a bibliotecas externas y la tabla Exportar (sección .edata) para llamadas definidas dentro del ejecutable y marcadas como exportables (normalmente esto solo existe en .dll archivos).

Para bibliotecas estáticas, su formato se llama COFF, y existe la utilidad DUMPBIN que se incluye con Visual Studio que puede usar para buscar rápidamente sus archivos lib e incluso deshacer el desensamblaje del código si lo desea.

La utilidad DUMPBIN, que se proporciona con la versión de 32 bits de Microsoft Visual C++, combina las capacidades del enlace, LIB, y utilidades EXEHDR. La combinación de estas herramientas presenta la capacidad para proporcionar información sobre el formato y los símbolos proporcionados en ejecutable, biblioteca y archivos DLL.

Para obtener información sobre la estructura de los archivos COFF, consulte este article.

Determinar si una llamada de función es de una lib o no sería complicado, pero por lo que recuerdo, la mayoría de las llamadas de lib estáticas en código son en realidad llamadas thunk (llamadas jmp simples al código de objeto real copiado desde la lib) y son de pequeño tamaño (por lo general, alrededor de 5 bytes), mientras que los "definidos por el usuario" no son nada y son llamadas enmarcadas basadas en bp.

+0

Mi pregunta es: ¿cómo distinguirlos? Tu criterio no parece estar claro. –

+0

¿Puedes aclarar qué es lo que estás buscando? En la primera parte de mi respuesta, si está utilizando una biblioteca de importación vinculada dinámicamente, sus "funciones de biblioteca" aparecerán todas en la tabla Importar del archivo PE. – GalacticJello

+0

¿Cómo distinguir las funciones vinculadas estáticas con la función autodidacta del usuario? –

1

Cuando su programa está vinculado, las funciones estáticas y las funciones definidas por el usuario son incluyen archivo por archivo.

Así que si vuelca el encabezado de un archivo PE, y mirar a los símbolos plantilla (usando objdump -x si se ejecuta con mingw32, o cualquier otra cosa) verá el nombre de un archivo y luego todas las funciones importar desde este, después de otro nombre de archivo y sus funciones ...
O si tiene información de depuración, puede ser que esto sea más fácil.

Así que después de vincular las funciones con un archivo puede ordenar las funciones mediante el análisis de su nombre de archivo. En busca de extensión (.c/.lib/.a) o consultar en una lista de archivos que tiene somwhere. Tenga cuidado de eliminar archivos crt0 ...

Sin embargo, esta es una solución difícil y no estoy seguro de que esto funcione para todos los programas.

+0

Lo que dijiste es un enlace dinámico. –

+0

No, para el enlace dinámico solo tiene que leer un indicador y no tendrá el código para la función. Aquí tiene una función y su código está en la sección .text. Entonces no hay diferencia con el código definido por el usuario. Pero puede leer desde qué archivo fuente proviene ... – AxFab

+0

¿Debo mantener una base de datos de "fuente"? –

Cuestiones relacionadas