Mach-O - порядковый номер раздела LINKEDIT - PullRequest
0 голосов
/ 14 марта 2020

Я немного запутался в разделе __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. Откуда я могу получить размер?

Спасибо, что нашли время, чтобы прочитать все здесь, и спасибо за любую помощь.

...