Skip to content

Commit a9af7b4

Browse files
committed
remove obsoleted comment
1 parent 22f8fe9 commit a9af7b4

File tree

6 files changed

+135
-25
lines changed

6 files changed

+135
-25
lines changed

inject.c

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ struct ppc_thread_state64 {
7070
uint32_t vrsave;
7171
};
7272

73-
// covers multiple flavors - some contain the state but not all
7473
#pragma pack(4)
7574
struct exception_message {
7675
mach_msg_header_t Head;
@@ -133,14 +132,12 @@ static kern_return_t find_symtab_addrs(uint32_t ncmds, mach_vm_size_t sizeofcmds
133132
struct load_command *lc;
134133
uint32_t symoff = 0, stroff = 0;
135134
uint32_t cmdsleft;
136-
mach_vm_size_t accumulated_sizeofcmds = 0;
137135

138136
memset(symtab, 0, sizeof(*symtab));
139137

140138
lc = cmds;
141-
cmdsleft = ncmds;
142-
while(cmdsleft--) {
143-
if((accumulated_sizeofcmds += SWAP(lc->cmdsize)) > sizeofcmds) {
139+
for(cmdsleft = ncmds; cmdsleft--;) {
140+
if((sizeofcmds -= SWAP(lc->cmdsize)) < 0) {
144141
// the mach file is invalid
145142
return KERN_INVALID_ARGUMENT;
146143
}
@@ -161,25 +158,18 @@ static kern_return_t find_symtab_addrs(uint32_t ncmds, mach_vm_size_t sizeofcmds
161158
return KERN_INVALID_ARGUMENT;
162159
}
163160

161+
#define CATCH(SWAP, off, size, addr) if(SWAP(sc->fileoff) <= (off) && (SWAP(sc->fileoff) + SWAP(sc->filesize)) >= ((off) + (size))) (addr) = SWAP(sc->vmaddr) + (off) - SWAP(sc->fileoff);
162+
164163
lc = cmds;
165-
cmdsleft = ncmds;
166-
while(cmdsleft--) {
164+
for(cmdsleft = ncmds; cmdsleft--;) {
167165
if(SWAP(lc->cmd) == LC_SEGMENT) {
168166
struct segment_command *sc = (void *) lc;
169-
if(SWAP(sc->fileoff) < symoff && (SWAP(sc->fileoff) + SWAP(sc->filesize)) >= (symoff + symtab->nsyms * nlist_size)) {
170-
symtab->symaddr = sc->vmaddr + symoff - sc->fileoff;
171-
}
172-
if(SWAP(sc->fileoff) < stroff && (SWAP(sc->fileoff) + SWAP(sc->filesize)) >= (stroff + symtab->strsize)) {
173-
symtab->straddr = sc->vmaddr + stroff - sc->fileoff;
174-
}
167+
CATCH(SWAP, symoff, symtab->nsyms * nlist_size, symtab->symaddr);
168+
CATCH(SWAP, stroff, symtab->strsize, symtab->straddr);
175169
} else if(SWAP(lc->cmd) == LC_SEGMENT_64) {
176170
struct segment_command_64 *sc = (void *) lc;
177-
if(SWAP64(sc->fileoff) < symoff && (SWAP64(sc->fileoff) + SWAP64(sc->filesize)) >= (symoff + symtab->nsyms * nlist_size)) {
178-
symtab->symaddr = sc->vmaddr + symoff - sc->fileoff;
179-
}
180-
if(SWAP64(sc->fileoff) < stroff && (SWAP64(sc->fileoff) + SWAP64(sc->filesize)) >= (stroff + symtab->strsize)) {
181-
symtab->straddr = sc->vmaddr + stroff - sc->fileoff;
182-
}
171+
CATCH(SWAP64, symoff, symtab->nsyms * nlist_size, symtab->symaddr);
172+
CATCH(SWAP64, stroff, symtab->strsize, symtab->straddr);
183173
}
184174
lc = (void *) ((char *) lc + SWAP(lc->cmdsize));
185175
}
@@ -358,6 +348,7 @@ kern_return_t inject(pid_t pid, const char *path) {
358348
break;
359349
case CPU_TYPE_POWERPC:
360350
case CPU_TYPE_POWERPC64:
351+
fprintf(stderr, "yep it's ppc\n");
361352
state.ppc.r[1] = stack_end;
362353
memcpy(&state.ppc.r[3], args_64 + 1, 6*8);
363354
state.ppc.srr0 = addrs.syscall;
@@ -395,7 +386,7 @@ kern_return_t inject(pid_t pid, const char *path) {
395386
while(1) {
396387
struct exception_message msg;
397388
TRY(mach_msg_overwrite(NULL, MACH_RCV_MSG, 0, sizeof(msg), exc, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL, (void *) &msg, sizeof(msg)));
398-
printf("got a message\n");
389+
//fprintf(stderr, "got a message\n");
399390
if(!(msg.Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) ||
400391
(msg.msgh_body.msgh_descriptor_count == 0) ||
401392
(msg.Head.msgh_size < offsetof(struct exception_message, old_state)) ||
@@ -421,6 +412,8 @@ kern_return_t inject(pid_t pid, const char *path) {
421412
}
422413

423414
if(!cond) {
415+
// let the normal crash mechanism handle it
416+
task_set_exception_ports(task, em[0], eh[0], eb[0], ef[0]);
424417
FAIL(KERN_FAILURE);
425418
} else if(started_dlopen) {
426419
TRY(thread_terminate(msg.thread.name));

inject.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#include <unistd.h>
22
#include <mach/kern_return.h>
33

4-
54
kern_return_t inject(pid_t pid, const char *path);
65

76
// The behavior is synchronous: when it returns, constructors have

interpose.c

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
#include <stdint.h>
2+
#include <stdbool.h>
3+
#include <stdlib.h>
4+
#include <stdio.h>
5+
#include <mach-o/loader.h>
6+
#include <mach-o/nlist.h>
7+
#include <string.h>
8+
9+
#ifdef __LP64__
10+
#define nlist_native nlist_64
11+
#define LC_SEGMENT_NATIVE LC_SEGMENT_64
12+
#define segment_command_native segment_command_64
13+
#define mach_header_native mach_header_64
14+
#define section_native section_64
15+
#define PAGEZERO_SIZE 0x100000000;
16+
#else
17+
#define nlist_native nlist
18+
#define LC_SEGMENT_NATIVE LC_SEGMENT
19+
#define segment_command_native segment_command
20+
#define mach_header_native mach_header
21+
#define section_native section
22+
#define PAGEZERO_SIZE 0x1000
23+
#endif
24+
25+
void *find_lazy(uint32_t ncmds, struct load_command *cmds, const char *desired) {
26+
uint32_t symoff = 0, stroff = 0, isymoff = 0, lazy_index = 0, lazy_size = 0;
27+
void **lazy = 0;
28+
struct load_command *lc;
29+
uint32_t cmdsleft;
30+
31+
lc = cmds;
32+
for(cmdsleft = ncmds; cmdsleft--;) {
33+
printf("%p %x\n", &lc->cmd, lc->cmd);
34+
if(lc->cmd == LC_SYMTAB) {
35+
struct symtab_command *sc = (void *) lc;
36+
stroff = sc->stroff;
37+
symoff = sc->symoff;
38+
} else if(lc->cmd == LC_DYSYMTAB) {
39+
struct dysymtab_command *dc = (void *) lc;
40+
isymoff = dc->indirectsymoff;
41+
} else if(lc->cmd == LC_SEGMENT_NATIVE) {
42+
struct segment_command_native *sc = (void *) lc;
43+
struct section_native *sect = (void *) (sc + 1);
44+
uint32_t i;
45+
for(i = 0; i < sc->nsects; i++) {
46+
if((sect->flags & SECTION_TYPE) == S_LAZY_SYMBOL_POINTERS) {
47+
lazy_index = sect->reserved1;
48+
lazy_size = sect->size / sizeof(*lazy);
49+
lazy = (void *) sect->addr;
50+
}
51+
sect++;
52+
}
53+
}
54+
lc = (void *) ((char *) lc + lc->cmdsize);
55+
}
56+
57+
if(!stroff || !symoff || !isymoff || !lazy_index) return 0;
58+
59+
#define CATCH(off, addr) if(sc->fileoff <= (off) && (sc->fileoff + sc->filesize) >= (off)) (addr) = (void *) (sc->vmaddr + (off) - sc->fileoff);
60+
struct nlist_native *syms = 0;
61+
char *strs = 0;
62+
uint32_t *isyms = 0;
63+
64+
lc = cmds;
65+
for(cmdsleft = ncmds; cmdsleft--;) {
66+
if(lc->cmd == LC_SEGMENT_NATIVE) {
67+
struct segment_command_native *sc = (void *) lc;
68+
CATCH(symoff, syms);
69+
CATCH(stroff, strs);
70+
CATCH(isymoff, isyms);
71+
}
72+
lc = (void *) ((char *) lc + lc->cmdsize);
73+
}
74+
75+
if(!syms || !strs || !isyms) return 0;
76+
77+
uint32_t i;
78+
for(i = lazy_index; i < lazy_index + lazy_size; i++) {
79+
struct nlist_native *sym = syms + isyms[i];
80+
if(!strcmp(strs + sym->n_un.n_strx, desired)) {
81+
return lazy;
82+
}
83+
lazy++;
84+
}
85+
86+
return 0;
87+
}
88+
89+
bool interpose(const char *name, void *impl) {
90+
struct mach_header_native *mach_hdr = (void *)PAGEZERO_SIZE;
91+
92+
void **lazy = find_lazy(mach_hdr->ncmds, (void *) (mach_hdr + 1), name);
93+
if(!lazy) return false;
94+
95+
*lazy = impl;
96+
97+
return true;
98+
}

interpose.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#include <stdbool.h>
2+
3+
bool interpose(const char *name, void *impl);

tester/Makefile

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ endif
66

77
all: testlib tester
88

9-
testlib: testlib.c Makefile
10-
$(GCC) $(ARCH) -dynamiclib -o testlib.dylib testlib.c
11-
tester: tester.c ../*.c ../*.h Makefile
12-
$(GCC) -O3 -g3 -o tester -I.. tester.c ../*.c ../*.h -Wall -Wno-parentheses
9+
testlib: testlib.c ../interpose.c ../interpose.h Makefile
10+
$(GCC) $(ARCH) -dynamiclib -I.. -o testlib.dylib testlib.c ../interpose.c -Wall -Wno-parentheses
11+
tester: tester.c ../inject.c ../inject.h Makefile
12+
$(GCC) -O3 -g3 -o tester -I.. tester.c ../inject.c -Wall -Wno-parentheses
1313
clean:
1414
rm -f tester testlib.dylib

tester/testlib.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,23 @@
11
#include <stdio.h>
2+
#include <stdint.h>
3+
#include <interpose.h>
4+
5+
int fake_puts(const char *s) {
6+
printf("whee %s\n", s);
7+
return 0;
8+
}
29

310
__attribute__((constructor))
411
static void hello() {
512
fprintf(stderr, "Someone loaded me\n");
13+
union {
14+
char bytes[4];
15+
uint32_t num;
16+
} u;
17+
u.bytes[0] = 0x12;
18+
u.bytes[1] = 0x34;
19+
u.bytes[2] = 0x56;
20+
u.bytes[3] = 0x78;
21+
fprintf(stderr, "le->78563412 be->12345678 actual=%x\n", u.num);
22+
fprintf(stderr, "%d\n", interpose("_puts", fake_puts));
623
}

0 commit comments

Comments
 (0)