Я немного запутался в разделе __LINKEDIT
.
Позвольте мне установить фон:
Что я понимаю о __LINKEDIT
В теории ( http://www.newosxbook.com/articles/DYLD.html) первая «секция» будет LC_DYLD_INFO
.
Если я проверю mach-o/loader.h
, я получу:
#define LC_DYLD_INFO 0x22
...
struct dyld_info_command {
uint32_t cmd; /* LC_DYLD_INFO or LC_DYLD_INFO_ONLY */
uint32_t cmdsize; /* sizeof(struct dyld_info_command) */
...
Если я проверю мах -o файл с otool
Я получаю:
$ otool -l MyBinary | grep -B3 -A8 LINKEDIT
Load command 3
cmd LC_SEGMENT_64
cmdsize 72
segname __LINKEDIT
vmaddr 0x0000000100038000
vmsize 0x0000000000040000
fileoff 229376
filesize 254720
maxprot 0x00000001
initprot 0x00000001
nsects 0
flags 0x0
Если я проверяю гекс, используя xxd
$ xxd -s 229376 -l 4 MyBinary
00038000: 1122 9002 ."..
Я знаю, что порядковый номер моего двоичного файла равен little
:
$ rabin2 -I MyBinary (03/14 10:21:51)
arch arm
baddr 0x100000000
binsz 484096
bintype mach0
bits 64
canary false
class MACH064
crypto false
endian little
havecode true
intrp /usr/lib/dyld
laddr 0x0
lang swift
linenum false
lsyms false
machine all
maxopsz 16
minopsz 1
nx false
os darwin
pcalign 0
pic true
relocs false
sanitiz false
static false
stripped true
subsys darwin
va true
Я могу подтвердить, что первый раздел в __LINKEDIT
равен LC_DYLD_INFO
, получив его смещение формы otool
:
$ otool -l MyBinary | grep -B1 -A11 LC_DYLD_INFO (03/14 10:25:35)
Load command 4
cmd LC_DYLD_INFO_ONLY
cmdsize 48
rebase_off 229376
rebase_size 976
bind_off 230352
bind_size 3616
weak_bind_off 0
weak_bind_size 0
lazy_bind_off 233968
lazy_bind_size 6568
export_off 240536
export_size 9744
Если мы проверим смещение __LINKEDIT
и из LC_DYLD_INFO
мы получаем то же самое: 229376
В настоящий момент все нормально, вроде как имеет смысл.
Мое замешательство
Теперь, когда я нахожусь в lldb
и хочу разобраться в памяти.
Я могу прочитать память по смещению:
(lldb) image dump sections MyBinary
...
0x00000400 container [0x0000000100ca0000-0x0000000100ce0000) r-- 0x00038000 0x0003e300 0x00000000 MyBinary.__LINKEDIT
Хорошо, давайте прочитаем эту память:
(lldb) x/x 0x00000100ca0000
0x100ca0000: 0x02902211
Так что это моя проблема:
0x02902211
Давайте предположим, что я не знаю, если это ' s Little или Big Endian. Я должен найти 0x22
в начале или в конце байтов. но это посередине? (Это смущает меня)
0x11
Я предполагаю, что это размер 17
(в десятичном формате), который может соответствовать тому, что я могу видеть из структуры в loader.h
(12 байтов + 5 байтов заполнения?) :
struct dyld_info_command {
uint32_t cmd; /* LC_DYLD_INFO or LC_DYLD_INFO_ONLY */
uint32_t cmdsize; /* sizeof(struct dyld_info_command) */
uint32_t rebase_off; /* file offset to rebase info */
uint32_t rebase_size; /* size of rebase info */
uint32_t bind_off; /* file offset to binding info */
uint32_t bind_size; /* size of binding info */
uint32_t weak_bind_off; /* file offset to weak binding info */
uint32_t weak_bind_size; /* size of weak binding info */
uint32_t lazy_bind_off; /* file offset to lazy binding info */
uint32_t lazy_bind_size; /* size of lazy binding infs */
uint32_t export_off; /* file offset to lazy binding info */
uint32_t export_size; /* size of lazy binding infs */
};
Мои вопросы
1.) Почему 0x22
не в конце (или в начале)? или я неправильно читаю смещение? 2.) otool
говорит, что размер команды 48
(это 0x30
в шестнадцатеричном формате), но я не могу получить его из байтов рядом с 0x22
. Откуда я могу получить размер?
Спасибо, что нашли время, чтобы прочитать все здесь, и спасибо за любую помощь.