19 return !strcmp(magic,
"dyld_v1 arm64") || !strcmp(magic,
"dyld_v1 arm64e") || !strcmp(magic,
"dyld_v1 x86_64") || !strcmp(magic,
"dyld_v1 x86_64h");
28 for (
i = 0;
i < n_maps;
i++) {
99 ut64 size =
h->codeSignatureOffset +
h->codeSignatureSize;
101 #define SHIFT_MAYBE(x) \
140 rz_list_foreach (hdrs,
iter, item) {
157 for (
i = 0;
i < cache->
n_hdr;
i++) {
180 ut64 max_address = 0;
181 for (
i = 0;
i < cache->
n_hdr;
i++) {
196 map->fileOffset += hdr_offset;
197 if (
map->address > max_address) {
199 max_address =
map->address;
252 if (strcmp(
bin->file,
"lib/libobjc.A.dylib")) {
256 struct MACH0_(opts_t) opts = { 0 };
258 opts.header_at =
bin->header_at;
260 struct MACH0_(obj_t) *mach0 =
MACH0_(new_buf)(cache->
buf, &opts);
273 ut64 scoffs_offset = 0;
274 ut64 scoffs_size = 0;
291 if (!scoffs_offset || scoffs_size < 40) {
298 ut64 sel_string_base;
303 if (!
rz_buf_read_le64_at(cache->
buf, scoffs_offset + 16, &sel_string_end) || sel_string_end == sel_string_base) {
317 if (!cache_buf || !hdr) {
357 bool has_large_entries = cache->
n_hdr > 1;
370 if (has_large_entries) {
372 bin->nlist_start_index =
e->nlistStartIndex;
373 bin->nlist_count =
e->nlistCount;
376 bin->nlist_start_index =
e->nlistStartIndex;
377 bin->nlist_count =
e->nlistCount;
407 char *lib_name =
file;
416 return !strstr((
const char *)
a, (
const char *)
b);
420 HtPU *path_to_idx = ht_pu_new0();
430 ht_pu_insert(path_to_idx,
file, (
ut64)
i);
441 struct MACH0_(mach_header) mh;
445 if (mh.magic !=
MH_MAGIC_64 || mh.sizeofcmds == 0) {
448 ut64 cmds_at = pa +
sizeof(
struct MACH0_(mach_header));
450 if (!cmds ||
rz_buf_read_at(cache->
buf, cmds_at, cmds, mh.sizeofcmds) != mh.sizeofcmds) {
453 cmds[mh.sizeofcmds] = 0;
455 ut8 *
end = cmds + mh.sizeofcmds;
456 while (cursor <
end) {
464 if (cursor + 24 >=
end) {
467 const char *
key = (
const char *)cursor + 24;
491 char *target_libs =
NULL;
497 if (!target_lib_names) {
510 for (
i = 0;
i < cache->
n_hdr;
i++) {
524 HtPU *path_to_idx =
NULL;
544 bool printing = !deps[j];
549 if (strstr(lib_name,
"libobjc.A.dylib")) {
562 if (extras && depArray) {
564 for (
k = extras[j].dependentsStartArrayIndex; depArray[
k] != 0xffff;
k++) {
565 ut16 dep_index = depArray[
k] & 0x7fff;
577 }
else if (path_to_idx) {
582 ht_pu_free(path_to_idx);
588 if (deps && !deps[j]) {
606 bin->hdr_offset = hdr_offset;
607 bin->symbols_off = symbols_off;
611 char *last_slash = strrchr(
file,
'/');
612 if (last_slash && *last_slash) {
613 if (last_slash >
file) {
614 char *scan = last_slash - 1;
615 while (scan >
file && *scan !=
'/') {
643 if (rz_list_empty(
bins)) {
656 for (
i = 0;
i < 64;
i += 8) {
657 ut8 byte = (
x >>
i) & 0xff;
661 for (j = 0; j < 8; j++) {
662 if (!((
byte >> j) & 1)) {
676 if (cache->
n_hdr > 1) {
687 bool found_sample =
false;
689 struct MACH0_(opts_t) opts = { 0 };
690 opts.header_at =
bin->header_at;
692 struct MACH0_(obj_t) *mach0 =
MACH0_(new_buf)(cache->
buf, &opts);
706 int classlist_idx = 0, data_idx = 0;
707 for (
i = 0; !
sections[
i].last && incomplete;
i++) {
728 int n_classes = classlist_sample_size / 8;
731 if (
rz_buf_fread_at(cache->
buf, sect_offset, (
ut8 *)classlist,
"l", n_classes) < classlist_sample_size) {
736 ut64 data_tail = data_addr & 0xfff;
737 ut64 data_tail_end = (data_addr +
sections[data_idx].size) & 0xfff;
738 for (
i = 0;
i < n_classes;
i++) {
739 ut64 cl_addr = (classlist[
i] & value_mask) + value_add;
740 ut64 cl_tail = cl_addr & 0xfff;
741 if (cl_tail >= data_tail && cl_tail < data_tail_end) {
742 ut64 off = cl_tail - data_tail;
743 slide = ((cl_addr -
off) & value_mask) - (data_addr & value_mask);
771 ut32 slide_info_version = 0;
776 if (slide_info_version == 3) {
786 if (page_starts_size +
size > slideInfoSize) {
790 if (page_starts_size > 0) {
791 tmp_buf_1 =
malloc(page_starts_size);
813 rebase_info->
delta_mask = 0x3ff8000000000000ULL;
823 if (rebase_info->
slide) {
827 rebase_info->
slide = slide;
831 }
else if (slide_info_version == 2 || slide_info_version == 4) {
886 rebase_info->
version = slide_info_version;
900 if (rebase_info->
slide) {
904 rebase_info->
slide = slide;
908 }
else if (slide_info_version == 1) {
951 one_page_buf =
malloc(4096);
965 rebase_info->
toc = (
ut16 *)tmp_buf_1;
967 rebase_info->
entries = tmp_buf_2;
971 if (rebase_info->
slide) {
975 rebase_info->
slide = slide;
980 RZ_LOG_ERROR(
"Unsupported slide info version %d\n", slide_info_version);
998 ut32 total_slide_infos = 0;
1007 total_slide_infos += n_slide_infos[
i];
1010 if (!total_slide_infos) {
1022 if (!n_slide_infos[
i]) {
1029 ut64 slide_infos_offset = sio;
1030 if (!slide_infos_offset) {
1033 slide_infos_offset += hdr_offset;
1037 for (j = 0; j < n_slide_infos[
i]; j++) {
1044 if (
entry.slideInfoOffset &&
entry.slideInfoSize) {
1049 prev_info = infos[
k].
info;
1060 if (
k < total_slide_infos) {
1062 if (!pruned_infos) {
1069 infos = pruned_infos;
1121 RZ_LOG_ERROR(
"dyldcache: malformed local symbol entry\n");
1125 ut64 nlists_size =
sizeof(
struct MACH0_(nlist)) *
bin->nlist_count;
1131 bin->nlist_start_index *
sizeof(
struct MACH0_(nlist));
1138 for (j = 0; j !=
bin->nlist_count; j++) {
1139 struct MACH0_(nlist) *
nlist = &nlists[j];
1151 sym->
type =
"LOCAL";
1248 for (
i = 0;
i < cache->
n_hdr;
i++) {
1263 RZ_LOG_ERROR(
"Cannot read cache_locsym_info_t from header\n");
1267 RZ_LOG_ERROR(
"The number of entries count differs from cache header image count\n");
1271 bool has_large_entries = cache->
n_hdr > 1;
1272 if (has_large_entries) {
1275 if (!large_entries) {
1279 info->entriesCount) != entries_size) {
1280 RZ_LOG_ERROR(
"Cannot read cache_locsym_entry_large_t\n");
1287 if (!regular_entries) {
1291 info->entriesCount) != entries_size) {
1319 RZ_LOG_ERROR(
"dyldcache: malformed local symbols metadata\n");
static RzList * maps(RzBinFile *bf)
RzList * entries(RzBinFile *bf)
RzBinInfo * info(RzBinFile *bf)
RzList * symbols(RzBinFile *bf)
RzList * sections(RzBinFile *bf)
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags cmd
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len key
RZ_API ut64 rz_dyldcache_get_slide(RzDyldCache *cache)
static RzDyldLocSym * rz_dyld_locsym_new(RzDyldCache *cache)
RZ_API bool rz_dyldcache_check_magic(const char *magic)
static void rebase_info2_free(RzDyldRebaseInfo2 *rebase_info)
RZ_API void rz_dyldcache_symbols_from_locsym(RzDyldCache *cache, RzDyldBinImage *bin, RzList *symbols, SetU *hash)
static cache_imgxtr_t * read_cache_imgextra(RzBuffer *cache_buf, cache_hdr_t *hdr, cache_accel_t *accel)
static void rebase_info_free(RzDyldRebaseInfo *rebase_info)
static ut64 estimate_slide(RzDyldCache *cache, ut64 value_mask, ut64 value_add)
RZ_API void rz_dyldcache_free(RzDyldCache *cache)
static cache_hdr_t * read_cache_header(RzBuffer *cache_buf, ut64 offset)
static void populate_cache_headers(RzDyldCache *cache)
RZ_API RzDyldCache * rz_dyldcache_new_buf(RzBuffer *buf)
static RzList * create_cache_bins(RzDyldCache *cache)
static cache_accel_t * read_cache_accel(RzBuffer *cache_buf, cache_hdr_t *hdr, cache_map_t *maps)
static ut32 dumb_ctzll(ut64 x)
static char * get_lib_name(RzBuffer *cache_buf, cache_img_t *img)
static cache_img_t * read_cache_images(RzBuffer *cache_buf, cache_hdr_t *hdr, ut64 hdr_offset)
static RzDyldRebaseInfo * get_rebase_info(RzDyldCache *cache, ut64 slideInfoOffset, ut64 slideInfoSize, ut64 start_of_data, ut64 slide)
static void free_bin(RzDyldBinImage *bin)
RZ_API ut64 rz_dyldcache_va2pa(RzDyldCache *cache, uint64_t vaddr, ut32 *offset, ut32 *left)
static void rebase_info3_free(RzDyldRebaseInfo3 *rebase_info)
static ut64 va2pa(uint64_t addr, ut32 n_maps, cache_map_t *maps, RzBuffer *cache_buf, ut64 slide, ut32 *offset, ut32 *left)
static RzDyldRebaseInfos * get_rebase_infos(RzDyldCache *cache)
static void match_bin_entries(RzDyldCache *cache, void *entries)
RZ_API objc_cache_opt_info * rz_dyldcache_get_objc_opt_info(RzBinFile *bf, RzDyldCache *cache)
static HtPU * create_path_to_index(RzBuffer *cache_buf, cache_img_t *img, cache_hdr_t *hdr)
static void carve_deps_at_address(RzDyldCache *cache, cache_img_t *img, HtPU *path_to_idx, ut64 address, int *deps, bool printing)
static void populate_cache_maps(RzDyldCache *cache)
static int string_contains(const void *a, const void *b)
static void rebase_info1_free(RzDyldRebaseInfo1 *rebase_info)
size_t map(int syms, int left, int len)
RZ_API void Ht_() free(HtName_(Ht) *ht)
RZ_API const KEY_TYPE bool * found
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
RZ_API RZ_BORROW RzListIter * rz_list_find(RZ_NONNULL const RzList *list, const void *p, RZ_NONNULL RzListComparator cmp)
Returns RzListIter element which matches via the RzListComparator.
RZ_API RZ_BORROW RzListIter * rz_list_iterator(const RzList *list)
returns the first RzList iterator int the list
RZ_API RZ_OWN RzList * rz_list_newf(RzListFree f)
Returns a new initialized RzList pointer and sets the free method.
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
void * malloc(size_t size)
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
struct section_t *MACH0_() get_sections(struct MACH0_(obj_t) *bin)
void *MACH0_() mach0_free(struct MACH0_(obj_t) *mo)
#define rz_return_if_fail(expr)
#define rz_return_val_if_fail(expr, val)
RZ_API RZ_OWN char * rz_buf_get_string(RZ_NONNULL RzBuffer *b, ut64 addr)
Get a string from the buffer.
RZ_API RzBuffer * rz_buf_ref(RzBuffer *b)
Increment the reference count of the buffer.
RZ_API st64 rz_buf_read_at(RZ_NONNULL RzBuffer *b, ut64 addr, RZ_NONNULL RZ_OUT ut8 *buf, ut64 len)
Read len bytes of the buffer at the specified address.
RZ_API st64 rz_buf_fread_at(RZ_NONNULL RzBuffer *b, ut64 addr, RZ_NONNULL ut8 *buf, RZ_NONNULL const char *fmt, int n)
...
#define rz_buf_read_le32_at(b, addr, result)
RZ_API void rz_buf_free(RzBuffer *b)
Free all internal data hold by the buffer and the buffer.
#define rz_buf_read_le64_at(b, addr, result)
static ut32 rz_read_le32(const void *src)
void(* RzListFree)(void *ptr)
#define RZ_LOG_INFO(fmtstr,...)
#define RZ_LOG_WARN(fmtstr,...)
#define RZ_LOG_ERROR(fmtstr,...)
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
RZ_API RzList * rz_str_split_list(char *str, const char *c, int n)
Split the string str according to the substring c and returns a RzList with the result.
RZ_API char * rz_sys_getenv(const char *key)
Get the value of an environment variable named key or NULL if none exists.
RZ_API void set_u_add(SetU *s, ut64 u)
RZ_API bool set_u_contains(SetU *s, ut64 u)
uint32_t bottomUpListOffset
uint32_t dofSectionsOffset
uint32_t imageExtrasCount
uint32_t reExportListOffset
uint32_t initializersOffset
uint32_t rangeTableOffset
uint32_t imagesExtrasOffset
uint64_t accelerateInfoAddr
uint64_t localSymbolsOffset
uint64_t localSymbolsSize
uint64_t accelerateInfoSize
uint32_t page_extras_count
uint32_t page_extras_offset
uint32_t page_starts_offset
uint32_t page_starts_count
uint32_t page_starts_count
XX curplugin == o->plugin.
ut64 local_symbols_offset
RzDyldRebaseInfosEntry * entries
RzDyldRebaseInfos * rebase_infos
struct rz_list_iter_t * n
if(dbg->bits==RZ_SYS_BITS_64)
ut64(WINAPI *w32_GetEnabledXStateFeatures)()