Я опишу ситуацию с текущей iOS, она несколько отличается в старых версиях.
Заглушки символов действительно загружают в ПК указатель на функцию.Для стандартного импорта «ленивый» (по требованию) указатель находится в разделе __lazy_symbol
и первоначально указывает на вспомогательную процедуру в разделе __stub_helper
, например:
__symbolstub1 _AudioServicesAddSystemSoundCompletion
__symbolstub1 LDR PC, _AudioServicesAddSystemSoundCompletion$lazy_ptr
__symbolstub1 ; End of function _AudioServicesAddSystemSoundCompletion
__lazy_symbol _AudioServicesAddSystemSoundCompletion$lazy_ptr DCD _AudioServicesAddSystemSoundCompletion$stubHelper
__stub_helper _AudioServicesAddSystemSoundCompletion$stubHelper
__stub_helper LDR R12, =nnn ; symbol info offset in the lazy bind table
__stub_helper B dyld_stub_binding_helper
Функция dyld_stub_binding_helper
является первым в разделе __stub_helper
и, по сути, является просто батутом к функции dyld_stub_binder
в dyld, передавая ей то, что я называю значением "символа информации смещения".Это значение является смещением в потоке информации о отложенном связывании (на который указывает команда загрузки LC_DYLD_INFO или LC_DYLD_INFO_ONLY), которое является своего рода потоком байт-кода с командами для dyld.Типичная последовательность для отложенного импорта выглядит следующим образом:
72: BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB(M, 0xYYYYY)
19: BIND_OPCODE_SET_DYLIB_ORDINAL_IMM(NNNN)
40: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM(0x00, '_AudioServicesAddSystemSoundCompletion')
90: BIND_OPCODE_DO_BIND()
здесь dyld будет делать следующее:
- искать функцию с именем '_AudioServicesAddSystemSoundCompletion' из числа Dylib NNNN в спискедилибов, перечисленных в командах загрузки.
- поиск номера сегмента исполняемого файла M (скорее всего, __DATA)
- запись указателя функции со смещением YYYYY.
- переход к адресу поиска, чтобы фактическая функциявыполняет свою работу
Адрес, на который написано, это слот _AudioServicesAddSystemSoundCompletion$lazy_ptr
.Таким образом, в следующий раз, когда вызывается _AudioServicesAddSystemSoundCompletion
, он сразу перейдет к импортированной функции, не используя dyld.
NB : вы не должны сразу смотреть на смещение 05fc0 в файле.Поле addr
- это виртуальный адрес, вам нужно найти команду содержащего сегмента и посмотреть, с какой виртуальной машины она запускается и каково ее смещение файла, а затем выполнить математику.Обычно сегмент __TEXT начинается с 1000.
Однако фактические заглушки символов действительно выглядят так, как вы вставили, возможно, у вас толстая машина с жирным заголовком, занимающим первые 1000 байтов, поэтому смещения выстраиваются в линию.