clean code
This commit is contained in:
parent
a2bee75ef9
commit
7880e647f5
@ -37,17 +37,10 @@ void set_cwd(const char *const *envp) {
|
|||||||
const uint32_t magic64 = 0xfeedfacf;
|
const uint32_t magic64 = 0xfeedfacf;
|
||||||
const uint32_t magic32 = 0xfeedface;
|
const uint32_t magic32 = 0xfeedface;
|
||||||
|
|
||||||
struct ProgramVars {
|
|
||||||
void *mh; // mach_header or mach_header64
|
|
||||||
int *NXArgcPtr;
|
|
||||||
const char ***NXArgvPtr;
|
|
||||||
const char ***environPtr;
|
|
||||||
const char **__prognamePtr;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct libcache_item {
|
struct libcache_item {
|
||||||
void *header;
|
void *header;
|
||||||
void *trie;
|
void *trie;
|
||||||
|
uint32_t trie_size;
|
||||||
uint32_t hash;
|
uint32_t hash;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -79,7 +72,14 @@ uint32_t fnv_hash(const char *str) {
|
|||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t calculate_libname_hash(const char *name) {
|
// calculate the hash to search
|
||||||
|
// _dyld_get_image_name returns the full path to the library
|
||||||
|
// while the static path in LC_DYLIB (and such) could be relative
|
||||||
|
// we should expand the path to fullpath to correctly compute the hash
|
||||||
|
//
|
||||||
|
// the hardest part is the @rpath, because there can be many LC_RPATH
|
||||||
|
// and @rpath can also reference @loader_path
|
||||||
|
uint32_t calculate_libname_hash(const libcache *cache, const char *name) {
|
||||||
uint32_t hash;
|
uint32_t hash;
|
||||||
uint32_t (*hash_func)(const char *) = fnv_hash;
|
uint32_t (*hash_func)(const char *) = fnv_hash;
|
||||||
if (name[0] == '.') {
|
if (name[0] == '.') {
|
||||||
@ -101,7 +101,12 @@ uint32_t calculate_libname_hash(const char *name) {
|
|||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// dummy no sus function to look for dyld header
|
||||||
|
// i don't know if dyld_stub_binder should be better
|
||||||
|
// because if they are not familiar with dyld
|
||||||
|
// they would not suspect dyld_stub_binder inside modern macho
|
||||||
extern "C" uint32_t dyld_get_sdk_version(const mach_header *mh);
|
extern "C" uint32_t dyld_get_sdk_version(const mach_header *mh);
|
||||||
|
void exported_from_c();
|
||||||
|
|
||||||
void decode_uleb128(char *&addr, uint32_t *ret) {
|
void decode_uleb128(char *&addr, uint32_t *ret) {
|
||||||
uint32_t result = 0;
|
uint32_t result = 0;
|
||||||
@ -377,7 +382,7 @@ void *find_in_reexport(struct libcache *cache, struct libcache_item *lib,
|
|||||||
}
|
}
|
||||||
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;
|
||||||
uint32_t hash = calculate_libname_hash(name);
|
uint32_t hash = calculate_libname_hash(cache, name);
|
||||||
for (int j = 0; j < cache->size; j++) {
|
for (int j = 0; j < cache->size; j++) {
|
||||||
struct libcache_item reexport = cache->libs[j];
|
struct libcache_item reexport = cache->libs[j];
|
||||||
if (reexport.hash != hash) {
|
if (reexport.hash != hash) {
|
||||||
@ -397,14 +402,13 @@ void *find_in_lib(struct libcache *cache, struct libcache_item *lib,
|
|||||||
void *direct = find_in_export_trie(lib->header, lib->trie, symbol);
|
void *direct = find_in_export_trie(lib->header, lib->trie, symbol);
|
||||||
if (direct)
|
if (direct)
|
||||||
return direct;
|
return direct;
|
||||||
// we cannot find in directly exported trie, so we loop through all reexport
|
// cannot find in directly exported trie, loop through all reexport libs
|
||||||
// libs
|
|
||||||
return find_in_reexport(cache, lib, symbol);
|
return find_in_reexport(cache, lib, symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *custom_dlsym(struct libcache *cache, const char *libname,
|
void *custom_dlsym(struct libcache *cache, const char *libname,
|
||||||
const char *symbol) {
|
const char *symbol) {
|
||||||
uint32_t hash = calculate_libname_hash(libname);
|
uint32_t hash = calculate_libname_hash(cache, libname);
|
||||||
for (int i = 0; i < cache->size; i++) {
|
for (int i = 0; i < cache->size; i++) {
|
||||||
struct libcache_item cache_lib = cache->libs[i];
|
struct libcache_item cache_lib = cache->libs[i];
|
||||||
if (cache_lib.hash == hash) {
|
if (cache_lib.hash == hash) {
|
||||||
@ -453,6 +457,14 @@ int hook_printf(const char *format, ...) {
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ProgramVars {
|
||||||
|
void *mh; // mach_header or mach_header64
|
||||||
|
int *NXArgcPtr;
|
||||||
|
const char ***NXArgvPtr;
|
||||||
|
const char ***environPtr;
|
||||||
|
const char **__prognamePtr;
|
||||||
|
};
|
||||||
|
|
||||||
__attribute__((constructor)) static void
|
__attribute__((constructor)) static void
|
||||||
bruh(int argc, const char *const argv[], const char *const envp[],
|
bruh(int argc, const char *const argv[], const char *const envp[],
|
||||||
const char *const apple[], const struct ProgramVars *vars) {
|
const char *const apple[], const struct ProgramVars *vars) {
|
||||||
@ -465,10 +477,11 @@ bruh(int argc, const char *const argv[], const char *const envp[],
|
|||||||
const void *thislib = find_header((void *)bruh);
|
const void *thislib = find_header((void *)bruh);
|
||||||
// Find dyld lib (mapped) file using a no-sus function
|
// Find dyld lib (mapped) file using a no-sus function
|
||||||
const void *libdyld = find_header((void *)dyld_get_sdk_version);
|
const void *libdyld = find_header((void *)dyld_get_sdk_version);
|
||||||
uint32_t libsystem_hash =
|
|
||||||
calculate_libname_hash("/usr/lib/libSystem.B.dylib");
|
|
||||||
|
|
||||||
struct libcache cache = {0, nlib, main, thislib, libdyld};
|
struct libcache cache = {0, 0, (void *)main, (void *)thislib,
|
||||||
|
(void *)libdyld};
|
||||||
|
uint32_t libsystem_hash =
|
||||||
|
calculate_libname_hash(&cache, "/usr/lib/libSystem.B.dylib");
|
||||||
|
|
||||||
// From libdyld header, we can list exports table
|
// From libdyld header, we can list exports table
|
||||||
// to find all function we want to use
|
// to find all function we want to use
|
||||||
@ -511,41 +524,54 @@ bruh(int argc, const char *const argv[], const char *const envp[],
|
|||||||
(dyld_get_image_name_t)find_in_export_trie(libdyld, libdyld_export_trie,
|
(dyld_get_image_name_t)find_in_export_trie(libdyld, libdyld_export_trie,
|
||||||
"__dyld_get_image_name");
|
"__dyld_get_image_name");
|
||||||
|
|
||||||
uint32_t nlib = dyld_image_count_func();
|
cache.size = dyld_image_count_func();
|
||||||
struct libcache_item *liblist =
|
cache.libs =
|
||||||
(struct libcache_item *)malloc(sizeof(struct libcache_item) * nlib);
|
(struct libcache_item *)malloc(sizeof(struct libcache_item) * cache.size);
|
||||||
cache->libs = liblist;
|
|
||||||
for (int i = 0; i < cache.size; i++) {
|
for (int i = 0; i < cache.size; i++) {
|
||||||
void *header = dyld_get_image_header_func(i);
|
void *header = dyld_get_image_header_func(i);
|
||||||
char *name = dyld_get_image_name_func(i);
|
char *name = dyld_get_image_name_func(i);
|
||||||
cache.libs[i].header = header;
|
cache.libs[i].header = header;
|
||||||
cache.libs[i].trie = get_export_trie(header, trie_size);
|
cache.libs[i].trie = get_export_trie(header, trie_size);
|
||||||
cache.libs[i].hash = calculate_libname_hash(name);
|
cache.libs[i].trie_size = trie_size;
|
||||||
printf("%s %x\n", name, cache.libs[i].hash);
|
cache.libs[i].hash = calculate_libname_hash(&cache, name);
|
||||||
|
printf("%p %s\n", header, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// { // test search using name
|
|
||||||
// void* printf_func = custom_dlsym(&cache, "/usr/lib/libSystem.B.dylib",
|
|
||||||
// "_printf"); printf("Indirect search: Found=%p Expected=%p\n",
|
|
||||||
// printf_func, printf);
|
|
||||||
// dump_export_trie_of("/usr/lib/system/libsystem_c.dylib", &cache, "../scripts/libsystem_c_export_trie.bin");
|
// dump_export_trie_of("/usr/lib/system/libsystem_c.dylib", &cache, "../scripts/libsystem_c_export_trie.bin");
|
||||||
|
|
||||||
// void* vm_protect_func = custom_dlsym(&cache,
|
if (false) { // test search using name
|
||||||
// "/usr/lib/libSystem.B.dylib", "_vm_protect"); printf("Indirect search:
|
void *printf_func =
|
||||||
// Found=%p Expected=%p\n", vm_protect_func, vm_protect);
|
custom_dlsym(&cache, "/usr/lib/libSystem.B.dylib", "_printf");
|
||||||
// }
|
printf("Indirect search: Found=%p Expected=%p\n", printf_func, printf);
|
||||||
|
|
||||||
{ // test search using hash of name
|
void *vm_protect_func =
|
||||||
// void* printf_func = custom_dlsym(&cache, libsystem_hash, "_printf");
|
custom_dlsym(&cache, "/usr/lib/libSystem.B.dylib", "_vm_protect");
|
||||||
// printf("Indirect search: Found=%p Expected=%p\n", printf_func, printf);
|
printf("Indirect search: Found=%p Expected=%p\n", vm_protect_func,
|
||||||
|
vm_protect);
|
||||||
|
|
||||||
// void* vm_protect_func = custom_dlsym(&cache, libsystem_hash,
|
// using relative path
|
||||||
// "_vm_protect"); printf("Indirect search: Found=%p Expected=%p\n",
|
void *func_c_1 =
|
||||||
// vm_protect_func, vm_protect);
|
|
||||||
|
|
||||||
void *func_c =
|
|
||||||
custom_dlsym(&cache, "./out/libb.dylib", "__Z15exported_from_cv");
|
custom_dlsym(&cache, "./out/libb.dylib", "__Z15exported_from_cv");
|
||||||
printf("Indirect search: Found=%p Expected=%p\n", func_c, 0);
|
printf("Indirect search: Found=%p Expected=%p\n", func_c_1,
|
||||||
|
exported_from_c);
|
||||||
|
|
||||||
|
// using rpath
|
||||||
|
void *func_c_2 =
|
||||||
|
custom_dlsym(&cache, "@rpath/libb.dylib", "__Z15exported_from_cv");
|
||||||
|
printf("Indirect search: Found=%p Expected=%p\n", func_c_2,
|
||||||
|
exported_from_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (false) { // test search using hash of name
|
||||||
|
void *printf_func = custom_dlsym(&cache, libsystem_hash, "_printf");
|
||||||
|
printf("Indirect search: Found=%p Expected=%p\n", printf_func, printf);
|
||||||
|
|
||||||
|
void *vm_protect_func = custom_dlsym(&cache, libsystem_hash, "_vm_protect");
|
||||||
|
printf("Indirect search: Found=%p Expected=%p\n", vm_protect_func,
|
||||||
|
vm_protect);
|
||||||
|
|
||||||
|
void *realpath_func = custom_dlsym(&cache, libsystem_hash, "_realpath$DARWIN_EXTSN");
|
||||||
|
printf("Indirect search: Found=%p Expected=%p\n", realpath_func, realpath);
|
||||||
}
|
}
|
||||||
|
|
||||||
// now we have function to find exported symbols
|
// now we have function to find exported symbols
|
||||||
@ -642,5 +668,5 @@ bruh(int argc, const char *const argv[], const char *const envp[],
|
|||||||
vm_protect_func(mach_task_self_func(), start_page, 0x4000, 0, VM_PROT_READ);
|
vm_protect_func(mach_task_self_func(), start_page, 0x4000, 0, VM_PROT_READ);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(liblist);
|
free(cache.libs);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user