add more utilities to custom_loader lib

This commit is contained in:
nganhkhoa 2023-06-15 10:45:01 +07:00
parent 9f54720e7b
commit ed793b1df6

View File

@ -20,6 +20,22 @@ int custom_strcmp(const char *p1, const char *p2) {
return c1 - c2; return c1 - c2;
} }
int custom_strncmp(const char *s1, const char *s2, register size_t n)
{
register unsigned char u1, u2;
while (n-- > 0)
{
u1 = (unsigned char) *s1++;
u2 = (unsigned char) *s2++;
if (u1 != u2)
return u1 - u2;
if (u1 == '\0')
return 0;
}
return 0;
}
void set_cwd(const char *const *envp) { void set_cwd(const char *const *envp) {
while (*envp) { while (*envp) {
// PWD= // PWD=
@ -208,6 +224,9 @@ void print_macho_summary(const void *header) {
} }
const uint32_t ncmds = *((uint32_t *)header + 4); const uint32_t ncmds = *((uint32_t *)header + 4);
uint64_t linkedit_vmaddr;
uint64_t linkedit_fileoffset;
uint64_t slide;
printf("parsing macho at %p\n", header); printf("parsing macho at %p\n", header);
printf("ncmds %x\n", ncmds); printf("ncmds %x\n", ncmds);
for (int i = 0; i < ncmds; i++) { for (int i = 0; i < ncmds; i++) {
@ -226,8 +245,11 @@ void print_macho_summary(const void *header) {
uint64_t fileoffset = *((uint64_t *)ptr + 5); uint64_t fileoffset = *((uint64_t *)ptr + 5);
uint64_t filesize = *((uint64_t *)ptr + 6); uint64_t filesize = *((uint64_t *)ptr + 6);
if (custom_strcmp(name, "__TEXT") == 0) { if (custom_strcmp(name, "__TEXT") == 0) {
uint64_t slide = (uint64_t)header - vmaddr; slide = (uint64_t)header - vmaddr;
printf(" --- slide=0x%llx ---\n", slide); printf(" --- slide=0x%llx ---\n", slide);
} else if (custom_strcmp(name, "__LINKEDIT") == 0) {
linkedit_vmaddr = vmaddr;
linkedit_fileoffset = fileoffset;
} }
printf(" Segment %s\n", name); printf(" Segment %s\n", name);
printf(" vmaddr=0x%llx fileoffset=0x%llx\n", vmaddr, fileoffset); printf(" vmaddr=0x%llx fileoffset=0x%llx\n", vmaddr, fileoffset);
@ -244,6 +266,31 @@ void print_macho_summary(const void *header) {
printf(" addr=0x%llx size=0x%llx fileoffset=0x%x\n", addr, size, fileoffset); printf(" addr=0x%llx size=0x%llx fileoffset=0x%x\n", addr, size, fileoffset);
} }
} }
if (cmd == LC_SYMTAB) {
uint32_t symoff = *((uint32_t *)ptr + 2);
uint32_t nsym = *((uint32_t *)ptr + 3);
uint32_t stroff = (*((uint32_t *)ptr + 4));
uint32_t strsize = *((uint32_t *)ptr + 5);
struct symbol_t {
uint32_t strx;
uint8_t flags;
uint8_t sect;
uint16_t desc;
uint64_t value;
};
uint64_t symtab_start = (uint64_t)symoff - linkedit_fileoffset + slide + linkedit_vmaddr;
uint64_t stroff_start = (uint64_t)stroff - linkedit_fileoffset + slide + linkedit_vmaddr;
printf(" symtab: offset=0x%x nsym=0x%x\n", symoff, nsym);
for (int j = 0; j < nsym; j++) {
struct symbol_t* symtab = (struct symbol_t*)symtab_start;
struct symbol_t symbol = symtab[j];
char* name = (char*)stroff_start + symbol.strx;
printf(" %s %llx => %p\n", name, symbol.value, (void*)(symbol.value + slide));
}
}
if (cmd == LC_REEXPORT_DYLIB) { if (cmd == LC_REEXPORT_DYLIB) {
uint32_t name_offset = *((uint32_t *)ptr + 2); uint32_t name_offset = *((uint32_t *)ptr + 2);
char *name = (char *)ptr + name_offset; char *name = (char *)ptr + name_offset;
@ -524,6 +571,79 @@ void dump_export_trie_of(const char* libname, const libcache* cache, const char*
} }
} }
void* find_in_symtab(const libcache_item* lib, const char* find) {
void* header = lib->header;
const uint32_t magic = *(uint32_t *)header;
char *ptr = (char *)header;
if (magic == magic64) {
ptr += 0x20;
} else {
ptr += 0x20 - 0x4;
}
const uint32_t ncmds = *((uint32_t *)header + 4);
char* command_ptr = ptr;
uint64_t linkedit_vmaddr;
uint64_t linkedit_fileoffset;
uint64_t slide;
for (int i = 0; i < ncmds; i++) {
const uint32_t cmd = *((uint32_t *)ptr + 0);
const uint32_t cmdsize = *((uint32_t *)ptr + 1);
if (cmd == LC_SYMTAB) {
uint32_t symoff = *((uint32_t *)ptr + 2);
uint32_t nsym = *((uint32_t *)ptr + 3);
uint32_t stroff = (*((uint32_t *)ptr + 4));
uint32_t strsize = *((uint32_t *)ptr + 5);
struct symbol_t {
uint32_t strx;
uint8_t flags;
uint8_t sect;
uint16_t desc;
uint64_t value;
};
uint64_t symtab_start = (uint64_t)symoff - linkedit_fileoffset + slide + linkedit_vmaddr;
uint64_t stroff_start = (uint64_t)stroff - linkedit_fileoffset + slide + linkedit_vmaddr;
for (int j = 0; j < nsym; j++) {
struct symbol_t* symtab = (struct symbol_t*)symtab_start;
struct symbol_t symbol = symtab[j];
char* name = (char*)stroff_start + symbol.strx;
if (custom_strcmp(name, find) == 0) {
return (void*)(symbol.value + slide);
}
}
break;
}
if (cmd == LC_SEGMENT_64) {
char *name = (char *)((uint64_t *)ptr + 1);
uint64_t vmaddr = *((uint64_t *)ptr + 3);
uint64_t fileoffset = *((uint64_t *)ptr + 5);
if (custom_strcmp(name, "__TEXT") == 0) {
slide = (uint64_t)header - vmaddr;
} else if (custom_strcmp(name, "__LINKEDIT") == 0) {
linkedit_vmaddr = vmaddr;
linkedit_fileoffset = fileoffset;
}
}
ptr += cmdsize;
}
return 0;
}
void* find_in_symtab(const char* libname, const libcache* cache, const char* find) {
uint32_t hash = calculate_libname_hash(cache, libname);
struct libcache_item *cache_lib = 0;
for (int i = 0; i < cache->size; i++) {
if (cache->libs[i].hash == hash) {
cache_lib = &(cache->libs[i]);
break;
}
}
return find_in_symtab(cache_lib, find);
}
int hook_printf(const char *format, ...) { int hook_printf(const char *format, ...) {
va_list args; va_list args;
va_start(args, format); va_start(args, format);
@ -561,8 +681,15 @@ bruh(int argc, const char *const argv[], const char *const envp[],
build_cache(cache, (void *)(vars->mh)); build_cache(cache, (void *)(vars->mh));
// dump_export_trie_of( // dump_export_trie_of(
// "/usr/lib/system/libsystem_c.dylib", &cache, // "/usr/lib/libobjc.A.dylib", &cache,
// "../scripts/libsystem_c_export_trie.bin"); // "../scripts/lib_objc_export_trie.bin");
// dump_macho(
// "/usr/lib/libobjc.A.dylib", &cache,
// "../scripts/lib_objc_symtab.bin");
// struct libcache_item* objc = get_libcache_with_name(&cache, "/usr/lib/libobjc.A.dylib");
// print_macho_summary(objc->header);
// test(cache); // test(cache);
@ -621,9 +748,6 @@ void build_cache(struct libcache& cache, void* main) {
printf("lib header at %p\n", thislib); printf("lib header at %p\n", thislib);
printf("libdyld header at %p\n", libdyld); printf("libdyld header at %p\n", libdyld);
// print_macho_summary(main);
// print_macho_summary(thislib);
uint32_t trie_size; uint32_t trie_size;
void *libdyld_export_trie = get_export_trie(libdyld, trie_size); void *libdyld_export_trie = get_export_trie(libdyld, trie_size);