Skip to content

Commit ae2bc09

Browse files
committed
Rebind in all relevant segments, not just the last ones found. Fixes __got rebinds.
1 parent 4c691f9 commit ae2bc09

File tree

1 file changed

+26
-23
lines changed

1 file changed

+26
-23
lines changed

fishhook.c

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -110,54 +110,57 @@ static void rebind_symbols_for_image(struct rebindings_entry *rebindings,
110110
if (dladdr(header, &info) == 0) {
111111
return;
112112
}
113-
uintptr_t cur = (uintptr_t)header + sizeof(mach_header_t);
113+
114114
segment_command_t *cur_seg_cmd;
115115
segment_command_t *linkedit_segment = NULL;
116-
section_t *lazy_symbols = NULL;
117-
section_t *non_lazy_symbols = NULL;
118116
struct symtab_command* symtab_cmd = NULL;
119117
struct dysymtab_command* dysymtab_cmd = NULL;
118+
119+
uintptr_t cur = (uintptr_t)header + sizeof(mach_header_t);
120120
for (uint i = 0; i < header->ncmds; i++, cur += cur_seg_cmd->cmdsize) {
121121
cur_seg_cmd = (segment_command_t *)cur;
122122
if (cur_seg_cmd->cmd == LC_SEGMENT_ARCH_DEPENDENT) {
123123
if (strcmp(cur_seg_cmd->segname, SEG_LINKEDIT) == 0) {
124124
linkedit_segment = cur_seg_cmd;
125-
continue;
126-
}
127-
if (strcmp(cur_seg_cmd->segname, SEG_DATA) != 0) {
128-
continue;
129-
}
130-
for (uint j = 0; j < cur_seg_cmd->nsects; j++) {
131-
section_t *sect =
132-
(section_t *)(cur + sizeof(segment_command_t)) + j;
133-
if ((sect->flags & SECTION_TYPE) == S_LAZY_SYMBOL_POINTERS) {
134-
lazy_symbols = sect;
135-
}
136-
if ((sect->flags & SECTION_TYPE) == S_NON_LAZY_SYMBOL_POINTERS) {
137-
non_lazy_symbols = sect;
138-
}
139125
}
140126
} else if (cur_seg_cmd->cmd == LC_SYMTAB) {
141127
symtab_cmd = (struct symtab_command*)cur_seg_cmd;
142128
} else if (cur_seg_cmd->cmd == LC_DYSYMTAB) {
143129
dysymtab_cmd = (struct dysymtab_command*)cur_seg_cmd;
144130
}
145131
}
132+
146133
if (!symtab_cmd || !dysymtab_cmd || !linkedit_segment ||
147134
!dysymtab_cmd->nindirectsyms) {
148135
return;
149136
}
137+
150138
// Find base symbol/string table addresses
151139
uintptr_t linkedit_base = (uintptr_t)slide + linkedit_segment->vmaddr - linkedit_segment->fileoff;
152140
nlist_t *symtab = (nlist_t *)(linkedit_base + symtab_cmd->symoff);
153141
char *strtab = (char *)(linkedit_base + symtab_cmd->stroff);
142+
154143
// Get indirect symbol table (array of uint32_t indices into symbol table)
155144
uint32_t *indirect_symtab = (uint32_t *)(linkedit_base + dysymtab_cmd->indirectsymoff);
156-
if (lazy_symbols) {
157-
perform_rebinding_with_section(rebindings, lazy_symbols, slide, symtab, strtab, indirect_symtab);
158-
}
159-
if (non_lazy_symbols) {
160-
perform_rebinding_with_section(rebindings, non_lazy_symbols, slide, symtab, strtab, indirect_symtab);
145+
146+
cur = (uintptr_t)header + sizeof(mach_header_t);
147+
for (uint i = 0; i < header->ncmds; i++, cur += cur_seg_cmd->cmdsize) {
148+
cur_seg_cmd = (segment_command_t *)cur;
149+
if (cur_seg_cmd->cmd == LC_SEGMENT_ARCH_DEPENDENT) {
150+
if (strcmp(cur_seg_cmd->segname, SEG_DATA) != 0) {
151+
continue;
152+
}
153+
for (uint j = 0; j < cur_seg_cmd->nsects; j++) {
154+
section_t *sect =
155+
(section_t *)(cur + sizeof(segment_command_t)) + j;
156+
if ((sect->flags & SECTION_TYPE) == S_LAZY_SYMBOL_POINTERS) {
157+
perform_rebinding_with_section(rebindings, sect, slide, symtab, strtab, indirect_symtab);
158+
}
159+
if ((sect->flags & SECTION_TYPE) == S_NON_LAZY_SYMBOL_POINTERS) {
160+
perform_rebinding_with_section(rebindings, sect, slide, symtab, strtab, indirect_symtab);
161+
}
162+
}
163+
}
161164
}
162165
}
163166

@@ -193,4 +196,4 @@ int rebind_symbols(struct rebinding rebindings[], size_t rebindings_nel) {
193196
}
194197
}
195198
return retval;
196-
}
199+
}

0 commit comments

Comments
 (0)