I'm a little confused on the __LINKEDIT
section.
Let me set the background:
__LINKEDIT
In theory (http://www.newosxbook.com/articles/DYLD.html) the first "section" will be LC_DYLD_INFO
.
If I check mach-o/loader.h
I get:
#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) */
...
If I check a mach-o file with otool
I get:
$ 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
If I check the hex using xxd
$ xxd -s 229376 -l 4 MyBinary
00038000: 1122 9002 ."..
I know that the endiannes of my binary is 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
I can corroborate that the first section in __LINKEDIT
is LC_DYLD_INFO
by getting it's offset form 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
If we check the offset of __LINKEDIT
and from LC_DYLD_INFO
we get the same: 229376
Everything fine at the moment, kinda make sense.
Now when I'm in lldb
and want to make sense of the memory.
I can read the memory at the offset:
(lldb) image dump sections MyBinary
...
0x00000400 container [0x0000000100ca0000-0x0000000100ce0000) r-- 0x00038000 0x0003e300 0x00000000 MyBinary.__LINKEDIT
Ok, let's read that memory:
(lldb) x/x 0x00000100ca0000
0x100ca0000: 0x02902211
So this is my problem:
0x02902211
Let's assume I don't know if it's Little or Big Endian. I should find 0x22
at the begining or at the end of the bytes. but it's in the middle? (This confuses me)
the 0x11
I guess is the size 17
(in decimal) which might corresponds to what I can see from the structure in loader.h
(12bytes + 5bytes of padding?) :
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.) Why is the 0x22
not in the end(or beginnig)? or am I reading the offset incorrectly?
2.) otool
says that the command size is 48
(that's 0x30
in hex) but I can't get it from the bytes next to 0x22
. Where do I get the size from?
Thanks for taking the time to read all the way here, and thanks for any help.
User contributions licensed under CC BY-SA 3.0