Ответ 1
Его можно загрузить файл символов в gdb с помощью команды add-symbol-file
. Самая сложная задача - создать этот файл символов.
С помощью libMachObjC (который является частью class-dump), очень легко сбрасывать все адреса и их соответствующие Objective-C методы. Я написал небольшой инструмент objc-symbols, который делает именно это.
Использует Calendar.app в качестве примера. Если вы попытаетесь перечислить символы с помощью инструмента nm
, вы заметите, что приложение "Календарь" было удалено:
$ nm -U /Applications/Calendar.app/Contents/MacOS/Calendar
0000000100000000 T __mh_execute_header
0000000005614542 - 00 0000 OPT radr://5614542
Но с помощью objc-symbols
вы можете легко получить адреса всех отсутствующих методов Objective-C:
$ objc-symbols /Applications/Calendar.app
00000001000c774c +[CALCanvasAttributedText textWithPosition:size:text:]
00000001000c8936 -[CALCanvasAttributedText createTextureIfNeeded]
00000001000c8886 -[CALCanvasAttributedText bounds]
00000001000c883b -[CALCanvasAttributedText updateBezierRepresentation]
...
00000001000309eb -[CALApplication applicationDidFinishLaunching:]
...
Затем с SymTabCreator вы можете создать файл символа, который на самом деле является пустым dylib со всеми символами.
Использование objc-symbols
и SymTabCreator
вместе просто:
$ objc-symbols /Applications/Calendar.app | SymTabCreator -o Calendar.stabs
Вы можете проверить, что Calendar.stabs
содержит все символы:
$ 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:]
...
Теперь посмотрим, что произойдет в gdb:
$ gdb --silent /Applications/Calendar.app
Reading symbols for shared libraries ................................. done
Без символьного файла:
(gdb) b -[CALApplication applicationDidFinishLaunching:]
Function "-[CALApplication applicationDidFinishLaunching:]" not defined.
Make breakpoint pending on future shared library load? (y or [n]) n
И после загрузки файла символа:
(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
Вы заметите, что адрес точки останова точно не соответствует адресу символа (0x1000309f2 vs 0x1000309eb, 7 байтов разницы), это связано с тем, что gdb автоматически распознает пролог функции и сразу устанавливает точку останова.
GDB script
Вы можете использовать этот GDB script, чтобы автоматизировать это, учитывая, что лишенный исполняемый файл является текущей целью.
Добавьте script снизу к вашему .gdbinit
, настройте удаленный исполняемый файл и запустите команду objc_symbols
в 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