1
0
mirror of https://github.com/0O0o0oOoO00/Alas.git synced 2026-05-14 19:59:25 +08:00
Files
Alas/blcrack/cracker/Dobby/builtin-plugin/SymbolResolver/macho/shared_cache_ctx.cpp
2025-11-01 00:23:46 +08:00

183 lines
6.2 KiB
C++

#include "shared_cache_ctx.h"
#include <mach/mach.h>
#include <mach/task.h>
#include <mach-o/dyld_images.h>
#include "logging/logging.h"
#include "mmap_file_util.h"
typedef uintptr_t addr_t;
extern "C" {
extern const char *dyld_shared_cache_file_path();
extern int __shared_region_check_np(uint64_t *startaddress);
}
const char *shared_cache_get_file_path() {
return dyld_shared_cache_file_path();
}
struct dyld_cache_header *shared_cache_get_load_addr() {
addr_t shared_cache_base = 0;
if (__shared_region_check_np((uint64_t *)&shared_cache_base) != 0) {
WARN_LOG("__shared_region_check_np failed");
}
if (shared_cache_base)
return (struct dyld_cache_header *)shared_cache_base;
// task info
task_dyld_info_data_t task_dyld_info;
mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT;
kern_return_t ret = task_info(mach_task_self(), TASK_DYLD_INFO, (task_info_t)&task_dyld_info, &count);
if (ret != KERN_SUCCESS) {
ERROR_LOG("task_info failed, ret: %d", ret);
return NULL;
}
// get dyld load address
auto *infos = (struct dyld_all_image_infos *)(uintptr_t)task_dyld_info.all_image_info_addr;
auto *shared_cache = (struct dyld_cache_header *)infos->sharedCacheBaseAddress;
return shared_cache;
}
int shared_cache_load_symbols(shared_cache_ctx_t *ctx) {
uint64_t localSymbolsOffset = 0;
bool latest_shared_cache_format = true;
const char *shared_cache_path = shared_cache_get_file_path();
char shared_cache_symbols_path[4096] = {0};
{
strcat(shared_cache_symbols_path, shared_cache_path);
strcat(shared_cache_symbols_path, ".symbols");
}
auto mmapSharedCacheSymbolsMng = new MmapFileManager(shared_cache_symbols_path);
auto mmap_buffer = mmapSharedCacheSymbolsMng->map();
if (mmap_buffer) { // iphoneos >= 15.0, which has .symbols file
ctx->mmap_shared_cache = (struct dyld_cache_header *)mmap_buffer;
localSymbolsOffset = ctx->mmap_shared_cache->localSymbolsOffset;
} else {
// iphoneos < 15.0, which has no .symbols file
auto mmapSharedCacheMng = new MmapFileManager(shared_cache_symbols_path);
auto runtime_shared_cache = ctx->runtime_shared_cache;
uint64_t mmap_length = runtime_shared_cache->localSymbolsSize;
uint64_t mmap_offset = runtime_shared_cache->localSymbolsOffset;
if (mmap_length == 0)
return -1;
auto mmap_buffer = mmapSharedCacheMng->map_options(mmap_length, mmap_offset);
if (!mmap_buffer) {
return -1;
}
// fake shared cache header
auto mmap_shared_cache =
(struct dyld_cache_header *)((addr_t)mmap_buffer - runtime_shared_cache->localSymbolsOffset);
ctx->mmap_shared_cache = mmap_shared_cache;
localSymbolsOffset = runtime_shared_cache->localSymbolsOffset;
latest_shared_cache_format = false;
}
ctx->latest_shared_cache_format = latest_shared_cache_format;
{
auto mmap_shared_cache = ctx->mmap_shared_cache;
auto localInfo = (struct dyld_cache_local_symbols_info *)((char *)mmap_shared_cache + localSymbolsOffset);
ctx->local_symbols_info = localInfo;
if (ctx->latest_shared_cache_format) {
auto localEntries_64 = (struct dyld_cache_local_symbols_entry_64 *)((char *)localInfo + localInfo->entriesOffset);
ctx->local_symbols_entries_64 = localEntries_64;
} else {
auto localEntries = (struct dyld_cache_local_symbols_entry *)((char *)localInfo + localInfo->entriesOffset);
ctx->local_symbols_entries = localEntries;
}
ctx->symtab = (nlist_t *)((char *)localInfo + localInfo->nlistOffset);
ctx->strtab = ((char *)localInfo) + localInfo->stringsOffset;
}
return 0;
}
int shared_cache_ctx_init(shared_cache_ctx_t *ctx) {
memset(ctx, 0, sizeof(shared_cache_ctx_t));
auto runtime_shared_cache = shared_cache_get_load_addr();
if (!runtime_shared_cache) {
return -1;
}
ctx->runtime_shared_cache = runtime_shared_cache;
// shared cache slide
auto mappings =
(struct dyld_cache_mapping_info *)((char *)runtime_shared_cache + runtime_shared_cache->mappingOffset);
uintptr_t slide = (uintptr_t)runtime_shared_cache - (uintptr_t)(mappings[0].address);
ctx->runtime_slide = slide;
return 0;
}
// refer: dyld
bool shared_cache_is_contain(shared_cache_ctx_t *ctx, addr_t addr, size_t length) {
struct dyld_cache_header *runtime_shared_cache;
if (ctx) {
runtime_shared_cache = ctx->runtime_shared_cache;
} else {
runtime_shared_cache = shared_cache_get_load_addr();
}
addr_t region_start = runtime_shared_cache->sharedRegionStart + ctx->runtime_slide;
addr_t region_end = region_start + runtime_shared_cache->sharedRegionSize;
if (addr >= region_start && addr < region_end)
return true;
return false;
}
int shared_cache_get_symbol_table(shared_cache_ctx_t *ctx, mach_header_t *image_header, nlist_t **out_symtab,
uint32_t *out_symtab_count, char **out_strtab) {
uint64_t textOffsetInCache = (uint64_t)image_header - (uint64_t)ctx->runtime_shared_cache;
nlist_t *localNlists = NULL;
uint32_t localNlistCount = 0;
const char *localStrings = NULL;
const uint32_t entriesCount = ctx->local_symbols_info->entriesCount;
for (uint32_t i = 0; i < entriesCount; ++i) {
if (ctx->latest_shared_cache_format) {
if (ctx->local_symbols_entries_64[i].dylibOffset == textOffsetInCache) {
uint32_t localNlistStart = ctx->local_symbols_entries_64[i].nlistStartIndex;
localNlistCount = ctx->local_symbols_entries_64[i].nlistCount;
localNlists = &ctx->symtab[localNlistStart];
break;
}
} else {
if (ctx->local_symbols_entries[i].dylibOffset == textOffsetInCache) {
uint32_t localNlistStart = ctx->local_symbols_entries[i].nlistStartIndex;
localNlistCount = ctx->local_symbols_entries[i].nlistCount;
localNlists = &ctx->symtab[localNlistStart];
break;
}
}
#if 0
static struct dyld_cache_image_info *imageInfos = NULL;
imageInfos = (struct dyld_cache_image_info *)((addr_t)g_mmap_shared_cache + g_mmap_shared_cache->imagesOffset);
char *image_name = (char *)g_mmap_shared_cache + imageInfos[i].pathFileOffset;
INFO_LOG("dyld image: %s", image_name);
#endif
}
*out_symtab = localNlists;
*out_symtab_count = (uint32_t)localNlistCount;
*out_strtab = (char *)ctx->strtab;
return 0;
}