objective c - Importar información de volcado de clase en GDB
objective-c debug-symbols (3)
Es posible cargar un archivo de símbolos en gdb con el comando add-symbol-file
. La parte más difícil es producir este archivo de símbolos.
Con la ayuda de libMachObjC (que es parte de class-dump de class-dump ), es muy fácil volcar todas las direcciones y sus correspondientes métodos Objective-C. He escrito una pequeña herramienta, objc-symbols que hace exactamente esto.
Usemos Calendar.app como ejemplo. Si intenta enumerar los símbolos con la herramienta nm
, notará que la aplicación Calendario se ha eliminado:
$ nm -U /Applications/Calendar.app/Contents/MacOS/Calendar
0000000100000000 T __mh_execute_header
0000000005614542 - 00 0000 OPT radr://5614542
Pero con objc-symbols
puede recuperar fácilmente las direcciones de todos los métodos faltados de Objective-C:
$ objc-symbols /Applications/Calendar.app
00000001000c774c +[CALCanvasAttributedText textWithPosition:size:text:]
00000001000c8936 -[CALCanvasAttributedText createTextureIfNeeded]
00000001000c8886 -[CALCanvasAttributedText bounds]
00000001000c883b -[CALCanvasAttributedText updateBezierRepresentation]
...
00000001000309eb -[CALApplication applicationDidFinishLaunching:]
...
Luego, con SymTabCreator puede crear un archivo de símbolos, que en realidad es un dylib vacío con todos los símbolos.
Usar objc-symbols
y SymTabCreator
juntos es sencillo:
$ objc-symbols /Applications/Calendar.app | SymTabCreator -o Calendar.stabs
Puedes comprobar que Calendar.stabs
contiene todos los símbolos:
$ nm Calendar.stabs
000000010014a58b T +[APLCALSource printingCachedTextSize]
000000010013e7c5 T +[APLColorSource alternateGenerator]
000000010013e780 T +[APLColorSource defaultColorSource]
000000010013e7bd T +[APLColorSource defaultGenerator]
000000010011eb12 T +[APLConstraint constraintOfClass:withProperties:]
...
00000001000309eb T -[CALApplication applicationDidFinishLaunching:]
...
Ahora veamos que pasa en gdb:
$ gdb --silent /Applications/Calendar.app
Reading symbols for shared libraries ................................. done
Sin el archivo de símbolos:
(gdb) b -[CALApplication applicationDidFinishLaunching:]
Function "-[CALApplication applicationDidFinishLaunching:]" not defined.
Make breakpoint pending on future shared library load? (y or [n]) n
Y después de cargar el archivo de símbolos:
(gdb) add-symbol-file Calendar.stabs
add symbol table from file "Calendar.stabs"? (y or n) y
Reading symbols from /Users/0xced/Calendar.stabs...done.
(gdb) b -[CALApplication applicationDidFinishLaunching:]
Breakpoint 1 at 0x1000309f2
Notará que la dirección del punto de interrupción no coincide exactamente con la dirección del símbolo (0x1000309f2 frente a 0x1000309eb, 7 bytes de diferencia), esto se debe a que gdb reconoce automáticamente el prólogo de la función y establece el punto de interrupción justo después.
Script GDB
Puede usar este script GDB para automatizar esto, dado que el ejecutable eliminado es el objetivo actual.
Agregue la secuencia de comandos de abajo a su .gdbinit
, apunte al ejecutable eliminado y ejecute el comando objc_symbols
en gdb:
$ gdb test
...
(gdb) b +[TestClass randomNum]
Function "+[TestClass randomNum]" not defined.
(gdb) objc_symbols
(gdb) b +[TestClass randomNum]
Breakpoint 1 at 0x100000ee1
(gdb) ^D
define objc_symbols
shell rm -f /tmp/gdb-objc_symbols
set logging redirect on
set logging file /tmp/gdb-objc_symbols
set logging on
info target
set logging off
shell target="$(head -1 /tmp/gdb-objc_symbols | head -1 | awk -F ''"'' ''{ print $2 }'')"; objc-symbols "$target" | SymTabCreator -o /tmp/gdb-symtab
set logging on
add-symbol-file /tmp/gdb-symtab
set logging off
end
¿Hay una manera de importar la salida de class-dump
de class-dump
a GDB?
Código de ejemplo:
$ cat > test.m
#include <stdio.h>
#import <Foundation/Foundation.h>
@interface TestClass : NSObject
+ (int)randomNum;
@end
@implementation TestClass
+ (int)randomNum {
return 4; // chosen by fair dice roll.
// guaranteed to be random.
}
@end
int main(void) {
printf("num: %d/n", [TestClass randomNum]);
return 0;
}
^D
$ gcc test.m -lobjc -o test
$ ./test
num: 4
$ gdb test
...
(gdb) b +[TestClass randomNum]
Breakpoint 1 at 0x100000e5c
(gdb) ^D
$ strip test
$ gdb test
...
(gdb) b +[TestClass randomNum]
Function "+[TestClass randomNum]" not defined.
(gdb) ^D
$ class-dump -A test
...
@interface TestClass : NSObject
{
}
+ (int)randomNum; // IMP=0x0000000100000e50
@end
Sé que ahora puedo usar b *0x0000000100000e50
en gdb
, pero ¿hay alguna forma de modificar la tabla de símbolos de GDB para que acepte b +[TestClass randomNum]
?
Edición: sería preferible si funcionara con GDB v6 y no solo GDB v7, ya que GDB v6 es la última versión con los parches de Apple.
Puedes usar DSYMCreator .
Con DSYMCreator, puede crear un archivo de símbolos a partir de un binario ejecutable de iOS.
Es una cadena de herramientas, así que puedes usarla así.
$ ./main.py --only-objc /path/to/binary/xxx
Luego se
/path/to/binary/xxx.symbol
un archivo/path/to/binary/xxx.symbol
, que es un símbolo de formato DWARF. Puedes importarlo alldb
por ti mismo.Aparte de eso,
DSYMCreator
también admite la exportación de símbolos desde IDA Pro, puede usarlo así.$ ./main.py /path/to/binary/xxx
SÍ, simplemente ignora
--only-objc
flag. Luego, el IDA Pro se ejecutará automáticamente, y luego se/path/to/binary/xxx.symbol
un archivo/path/to/binary/xxx.symbol
, que es el archivo de símbolos.
Gracias por crear objc-symbols
, que forma parte de la cadena de herramientas DSYMCreator.
Por cierto, https://github.com/tobefuturer/restore-symbol es otra opción.
No hay una forma directa de hacer esto (que yo sepa), pero parece una gran idea.
Y ahora hay una manera de hacerlo ... buena respuesta, ¡0xced!
El formato de archivo DWARF está bien documentado , IIRC y, como la fuente lldb está disponible, tiene un ejemplo funcional de un analizador.
Dado que la class-dump también está disponible, no debería ser demasiado difícil modificarla para generar la salida DWARF que luego podría cargarse en el depurador.
Obviamente, no podrías volcar símbolos con total fidelidad, pero esto probablemente sería muy útil.