Fix Mach-O symbol parsing in dyldcache ##bin

This change correctly computes the offset to reach the symbol info from
each actual binary in the mutiple sub-caches scenario.
This commit is contained in:
Francesco Tamagni 2023-03-23 18:41:09 +01:00 committed by GitHub
parent 44cb7d98e3
commit 60aad9b0b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -469,7 +469,9 @@ static struct MACH0_(obj_t) *bin_to_mach0(RBinFile *bf, RDyldBinImage *bin) {
struct MACH0_(opts_t) opts;
MACH0_(opts_set_default) (&opts, bf);
opts.header_at = bin->header_at - bin->hdr_offset;
opts.symbols_off = bin->symbols_off;
if (bin->symbols_off) {
opts.symbols_off = bin->symbols_off - bin->hdr_offset;
}
struct MACH0_(obj_t) *mach0 = MACH0_(new_buf) (buf, &opts);
if (mach0) {
@ -1113,17 +1115,21 @@ static ut64 resolve_symbols_off(RDyldCache *cache, ut64 pa) {
if (vmaddr == UT64_MAX) {
return 0;
}
ut64 original_off = r_buf_read_le64_at (cache->buf, cursor + 2 * sizeof (ut32) + 16 + 16);
if (original_off == UT64_MAX) {
return 0;
}
ut32 i,j;
for (i = 0; i < cache->n_hdr; i++) {
cache_hdr_t *hdr = &cache->hdr[i];
ut64 hdr_offset = cache->hdr_offset[i];
ut32 maps_index = cache->maps_index[i];
for (j = 0; j < hdr->mappingCount; j++) {
ut64 map_start = cache->maps[maps_index + j].address;
ut64 map_end = map_start + cache->maps[maps_index + j].size;
if (vmaddr >= map_start && vmaddr < map_end) {
return hdr_offset;
ut64 map_off = vmaddr - map_start + cache->maps[maps_index + j].fileOffset;
return map_off - original_off;
}
}
}