Add: rpath resolve

This commit is contained in:
cocay 2023-12-14 10:38:44 +07:00
parent c805fc56b3
commit 26d002cdb1

View File

@ -72,17 +72,18 @@ struct libcache {
void *main;
void *thislib;
void *libdyld;
int nrpath;
char** rpaths;
};
// try these hashes
// https://gist.github.com/sgsfak/9ba382a0049f6ee885f68621ae86079b
uint32_t fnv_hash(const char *str) {
uint32_t fnv_hash_extend(const char *str, uint32_t h) {
unsigned char *s = (unsigned char *)str; /* unsigned string */
/* See the FNV parameters at www.isthe.com/chongo/tech/comp/fnv/#FNV-param */
const uint32_t FNV_32_PRIME = 0x01000193; /* 16777619 */
uint32_t h = 0x811c9dc5; /* 2166136261 */
// uint32_t h = 0x811c9dc5; /* 2166136261 */x
while (*s != 0) {
/* xor the bottom with the current octet */
h ^= *s++;
@ -92,6 +93,12 @@ uint32_t fnv_hash(const char *str) {
return h;
}
uint32_t fnv_hash(const char* str) {
return fnv_hash_extend(str, 0x811c9dc5);
}
// try these hashes
// https://gist.github.com/sgsfak/9ba382a0049f6ee885f68621ae86079b
// calculate the hash to search
// _dyld_get_image_name returns the full path to the library
@ -115,7 +122,20 @@ uint32_t calculate_libname_hash(const libcache *cache, const char *name) {
// then resolve the full path for all rpath
//
// which rpath is correct can be done by checking if the cache has that hash
printf("resolver for @rpath is not supported yet\n");
for (int i = 0; i < cache->nrpath; i++){
char* rpath = cache->rpaths[i];
char* p = realpath(rpath, 0);
hash = hash_func(p);
hash = fnv_hash_extend(&name[6], hash);
for (size_t i = 0; i < cache->size; i++) {
if (cache->libs[i].hash == hash) {
free(p);
return hash;
}
}
free(p);
}
// printf("resolver for @rpath is not supported yet\n");
} else {
hash = hash_func(name);
}
@ -745,6 +765,7 @@ struct ProgramVars {
void build_cache(struct libcache &cache, void *main);
void fix(struct libcache &cache);
void find_all_rpath(struct libcache &cache, void *main);
void test(struct libcache &cache);
@ -832,6 +853,7 @@ void build_cache(struct libcache &cache, void *main) {
printf("lib header at %p\n", thislib);
printf("libdyld header at %p\n", libdyld);
find_all_rpath(cache ,main);
uint32_t trie_size;
void *libdyld_export_trie = get_export_trie(libdyld, trie_size);
@ -863,6 +885,41 @@ void build_cache(struct libcache &cache, void *main) {
}
}
// Function to find all rpath entries of the main executable
void find_all_rpath(struct libcache &cache, void *header) {
const uint32_t magic = *(uint32_t *)header;
char *ptr = (char *)header;
if (magic == magic64) {
ptr += 0x20;
} else {
ptr += 0x20 - 0x4;
}
printf("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n");
const uint32_t ncmds = *((uint32_t *)header + 4);
printf("RPATHS:\n");
cache.nrpath = 0;
for (uint32_t i = 0; i < ncmds; i++) {
const uint32_t cmd = *((uint32_t *)ptr + 0);
const uint32_t cmdsize = *((uint32_t *)ptr + 1);
if (cmd == LC_RPATH) cache.nrpath++;
ptr += cmdsize;
}
uint32_t idx = 0;
ptr = (char *)header;
ptr += (magic == magic64) ? 0x20 : 0x20 - 0x4;
cache.rpaths = (char **)malloc(sizeof(char *) * cache.nrpath);
for (uint32_t i = 0; i < ncmds; i++) {
const uint32_t cmd = *((uint32_t *)ptr + 0);
const uint32_t cmdsize = *((uint32_t *)ptr + 1);
if (cmd == LC_RPATH) {
cache.rpaths[idx++] = (char *)ptr + 12;
printf("%s\n", cache.rpaths[idx - 1]);
}
ptr += cmdsize;
}
printf("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n");
}
void fix_binds(struct libcache_item *libfixing, struct libcache *cache,
int n_ins, uint32_t *instructions, char *libs, char *symbols) {
uint32_t libsystem_hash =