9 #include "../i/private.h"
23 struct MACH0_(obj_t) *
bin = (
struct MACH0_(obj_t) *)o->
bin_obj;
30 if (!
bin->signature) {
35 pj_s(pj, (
const char *)
bin->signature);
44 struct MACH0_(opts_t) opts;
47 struct MACH0_(obj_t) *res =
MACH0_(new_buf)(
buf, &opts);
101 rz_list_foreach (secs,
iter, sec) {
103 if (strstr(sec->
name,
"_mod_fini_func")) {
105 }
else if (strstr(sec->
name,
"_mod_init_func")) {
114 if (read < sec->
size) {
115 RZ_LOG_ERROR(
"process_constructors: cannot process section %s\n", sec->
name);
119 for (
i = 0;
i + 3 < sec->
size;
i += 4) {
127 for (
i = 0;
i + 7 < sec->
size;
i += 8) {
162 if (ptr->
vaddr & 1) {
179 if (ptr->
paddr & 1) {
194 struct MACH0_(obj_t) *
bin;
201 const char *lang =
"c";
211 bool isStripped =
false;
220 for (
i = 0; !syms[
i].
last;
i++) {
233 char *
p = strchr(dn,
'.');
259 bin->dbg_info = strncmp(ptr->
name,
"radr://", 7) ? 0 : 1;
262 if (!strncmp (ptr->
name,
"__Z", 3)) {
265 if (!strncmp (ptr->
name,
"type.", 5)) {
267 }
else if (!strcmp (ptr->
name,
"_rust_oom")) {
274 if (
bin->func_start) {
276 const ut8 *temp =
bin->func_start;
277 const ut8 *temp_end =
bin->func_start +
bin->func_size;
278 while (temp + 3 < temp_end && *temp) {
286 ptr->
paddr = address;
307 if (
bin->has_blocks_ext) {
308 lang = !strcmp (lang,
"c++") ?
"c++ blocks ext." :
"c blocks ext.";
321 if (imports_by_name) {
334 char *
name = (
char *)orig_name;
335 const char *_objc_class =
"_OBJC_CLASS_$";
336 const int _objc_class_len = strlen(_objc_class);
337 const char *_objc_metaclass =
"_OBJC_METACLASS_$";
338 const int _objc_metaclass_len = strlen(_objc_metaclass);
341 if (!strncmp(
name, _objc_class, _objc_class_len)) {
342 name += _objc_class_len;
344 }
else if (!strncmp(
name, _objc_metaclass, _objc_metaclass_len)) {
345 name += _objc_metaclass_len;
346 type =
"OBJC_METACLASS";
357 if (imports_by_name) {
358 ht_pp_insert(imports_by_name, orig_name, ptr);
381 bin->has_canary =
false;
382 bin->has_retguard = -1;
383 bin->has_sanitizers =
false;
384 bin->has_blocks_ext =
false;
391 if (
bin->imports_by_ord && ptr->
ordinal <
bin->imports_by_ord_size) {
394 if (!strcmp(
name,
"__stack_chk_fail")) {
395 bin->has_canary =
true;
397 if (!strcmp(
name,
"__asan_init") ||
398 !strcmp(
name,
"__tsan_init")) {
399 bin->has_sanitizers =
true;
401 if (!strcmp(
name,
"_NSConcreteGlobalBlock")) {
402 bin->has_blocks_ext =
true;
412 struct MACH0_(obj_t) *
bin =
NULL;
436 if (reloc->
name[0]) {
443 }
else if (reloc->
ord >= 0 &&
bin->imports_by_ord && reloc->
ord <
bin->imports_by_ord_size) {
469 for (
i = 0; !
libs[
i].last;
i++) {
479 struct MACH0_(obj_t) *
bin =
NULL;
535 if (!memcmp(
buf,
"\xce\xfa\xed\xfe", 4) ||
536 !memcmp(
buf,
"\xfe\xed\xfa\xce", 4)) {
545 const bool use_pagezero =
true;
546 const bool use_main =
true;
547 const bool use_dylinker =
true;
548 const bool use_libsystem =
true;
549 const bool use_linkedit =
true;
550 ut32 filesize, codeva, datava;
551 ut32 ncmds, cmdsize, magiclen;
552 ut32 p_codefsz = 0, p_codeva = 0, p_codesz = 0, p_codepa = 0;
553 ut32 p_datafsz = 0, p_datava = 0, p_datasz = 0, p_datapa = 0;
554 ut32 p_cmdsize = 0, p_entry = 0, p_tmp = 0;
561 #ifndef RZ_BIN_MACH064
562 if (opt->
bits == 64) {
569 #define B(x, y) rz_buf_append_bytes(buf, (const ut8 *)(x), y)
570 #define D(x) rz_buf_append_ut32(buf, x)
571 #define Z(x) rz_buf_append_nbytes(buf, x)
572 #define W(x, y, z) rz_buf_write_at(buf, x, (const ut8 *)(y), z)
574 p_tmp = rz_buf_size(buf); \
576 W(p_tmp, y, strlen(y))
579 B(
"\xce\xfa\xed\xfe", 4);
592 if (data && dlen > 0) {
624 WZ(16,
"__PAGEZERO");
663 if (data && dlen > 0) {
669 W(p_tmp,
"__TEXT", 6);
702 WZ(16,
"__LINKEDIT");
723 Z(18 *
sizeof(
ut32));
726 const char *dyld =
"/usr/lib/dyld";
727 const int dyld_len = strlen(dyld) + 1;
729 D((4 * 3) + dyld_len);
735 const char *lib =
"/usr/lib/libSystem.B.dylib";
736 const int lib_len = strlen(lib) + 1;
764 Z(17 *
sizeof(
ut32));
771 Z(16 *
sizeof(
ut32));
783 W(p_entry, &codeva, 4);
787 W(p_cmdsize, &cmdsize, 4);
788 filesize = magiclen + cmdsize + clen + dlen;
790 W(p_codefsz, &filesize, 4);
791 W(p_codefsz - 8, &filesize, 4);
792 W(p_codeva, &codeva, 4);
794 W(p_codesz, &clen, 4);
795 p_tmp = codeva -
baddr;
796 W(p_codepa, &p_tmp, 4);
800 if (data && dlen > 0) {
802 W(p_datafsz, &filesize, 4);
803 W(p_datava, &datava, 4);
804 W(p_datasz, &dlen, 4);
805 p_tmp = datava -
baddr;
806 W(p_datapa, &p_tmp, 4);
857 .desc =
"mach0 bin plugin",
885 #ifndef RZ_PLUGIN_INCORE
RZ_API RZ_OWN RzList * rz_bin_file_strings(RZ_NONNULL RzBinFile *bf, size_t min_length, bool raw_strings)
Generates a RzList struct containing RzBinString from a given RzBinFile.
RZ_API void rz_bin_symbol_free(RzBinSymbol *sym)
RZ_API void rz_bin_import_free(RzBinImport *imp)
RZ_API RZ_OWN char * rz_bin_demangle(RZ_NULLABLE RzBinFile *bf, RZ_NULLABLE const char *language, RZ_NULLABLE const char *symbol, ut64 vaddr, bool libs)
Demangles a symbol based on the language or the RzBinFile data.
static RzBinAddr * binsym(RzBinFile *bf, RzBinSpecialSymbol sym)
static void _handle_arm_thumb(struct MACH0_(obj_t) *bin, RzBinSymbol **p)
static void process_constructors(RzBinFile *bf, RzList *ret, int bits)
static Sdb * get_sdb(RzBinFile *bf)
static RzList * classes(RzBinFile *bf)
RzBinPlugin rz_bin_plugin_mach0
static bool load_buffer(RzBinFile *bf, RzBinObject *obj, RzBuffer *buf, Sdb *sdb)
static RzList * symbols(RzBinFile *bf)
static ut64 size(RzBinFile *bf)
static RzList * libs(RzBinFile *bf)
static RzList * strings(RzBinFile *bf)
static void destroy(RzBinFile *bf)
RZ_API RzLibStruct rizin_plugin
static bool check_buffer(RzBuffer *b)
static RzBinAddr * newEntry(ut64 hpaddr, ut64 paddr, int type, int bits)
static RzList * virtual_files(RzBinFile *bf)
static ut64 baddr(RzBinFile *bf)
static RzList * entries(RzBinFile *bf)
static RzList * maps(RzBinFile *bf)
static char * entitlements(RzBinFile *bf, bool json)
static RzBuffer * create(RzBin *bin, const ut8 *code, int clen, const ut8 *data, int dlen, RzBinArchOptions *opt)
static RzBinInfo * info(RzBinFile *bf)
static RzBinImport * import_from_name(RzBin *rbin, const char *orig_name, HtPP *imports_by_name)
static RzList * sections(RzBinFile *bf)
static RzList * imports(RzBinFile *bf)
static RzList * relocs(RzBinFile *bf)
int bits(struct state *s, int need)
RZ_API void Ht_() free(HtName_(Ht) *ht)
RZ_API const KEY_TYPE bool * found
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 * calloc(size_t number, 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")
RzList *MACH0_() mach_fields(RzBinFile *bf)
const char *MACH0_() get_intrp(struct MACH0_(obj_t) *bin)
RzList *MACH0_() get_maps(RzBinFile *bf)
RzList *MACH0_() get_segments(RzBinFile *bf)
char *MACH0_() section_type_to_string(ut64 type)
const RzList *MACH0_() get_symbols_list(struct MACH0_(obj_t) *bin)
char *MACH0_() get_class(struct MACH0_(obj_t) *bin)
RzList *MACH0_() section_flag_to_rzlist(ut64 flag)
void MACH0_() mach_headerfields(RzBinFile *bf)
char *MACH0_() get_filetype(struct MACH0_(obj_t) *bin)
struct lib_t *MACH0_() get_libs(struct MACH0_(obj_t) *bin)
char *MACH0_() get_cpusubtype(struct MACH0_(obj_t) *bin)
const struct symbol_t *MACH0_() get_symbols(struct MACH0_(obj_t) *bin)
ut64 MACH0_() get_main(struct MACH0_(obj_t) *bin)
bool MACH0_() is_big_endian(struct MACH0_(obj_t) *bin)
ut64 MACH0_() get_baddr(struct MACH0_(obj_t) *bin)
void *MACH0_() mach0_free(struct MACH0_(obj_t) *mo)
bool MACH0_() has_nx(struct MACH0_(obj_t) *bin)
bool MACH0_() is_pie(struct MACH0_(obj_t) *bin)
RzList *MACH0_() get_virtual_files(RzBinFile *bf)
const char *MACH0_() get_cputype(struct MACH0_(obj_t) *bin)
struct import_t *MACH0_() get_imports(struct MACH0_(obj_t) *bin)
const char *MACH0_() get_os(struct MACH0_(obj_t) *bin)
void MACH0_() opts_set_default(struct MACH0_(opts_t) *options, RzBinFile *bf)
struct addr_t *MACH0_() get_entrypoint(struct MACH0_(obj_t) *bin)
RZ_BORROW RzSkipList *MACH0_() get_relocs(struct MACH0_(obj_t) *bin)
RZ_API RzList *MACH0_() parse_classes(RzBinFile *bf, objc_cache_opt_info *oi)
#define RZ_BIN_MACH0_SYMBOL_TYPE_LOCAL
RZ_API int sdb_ns_set(Sdb *s, const char *name, Sdb *r)
static int is_arm(RzBinPEObj *bin)
#define rz_return_val_if_fail(expr, val)
#define RZ_BIN_DBG_STRIPPED
#define RZ_BIN_ENTRY_TYPE_FINI
@ RZ_BIN_SPECIAL_SYMBOL_MAIN
#define RZ_BIN_ENTRY_TYPE_INIT
#define RZ_BIN_BIND_LOCAL_STR
#define RZ_BIN_BIND_GLOBAL_STR
#define RZ_BIN_TYPE_FUNC_STR
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 RZ_OWN RzBuffer * rz_buf_new_with_bytes(RZ_NULLABLE RZ_BORROW const ut8 *bytes, ut64 len)
Creates a new buffer with a bytes array.
RZ_API ut64 rz_buf_size(RZ_NONNULL RzBuffer *b)
Return the size of the buffer.
static ut32 rz_read_le32(const void *src)
static ut64 rz_read_le64(const void *src)
void(* RzListFree)(void *ptr)
#define RZ_LOG_ERROR(fmtstr,...)
RZ_API char * pj_drain(PJ *j)
RZ_API PJ * pj_s(PJ *j, const char *k)
#define rz_skiplist_foreach(list, it, pos)
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
RZ_API char * rz_str_dup(char *ptr, const char *string)
RZ_API const char * rz_str_constpool_get(RzStrConstPool *pool, const char *str)
RZ_API const ut8 * rz_uleb128_decode(const ut8 *data, int *datalen, ut64 *v)
RZ_API SetU * set_u_new(void)
RZ_API void set_u_free(SetU *s)
RZ_API void set_u_add(SetU *s, ut64 u)
RZ_API bool set_u_contains(SetU *s, ut64 u)
XX curplugin == o->plugin.
ut64 paddr
the paddr where the value should be patched into
ut64 vaddr
the vaddr where the value should be patched into
ut64 target_vaddr
the target address that the patched reloc points to
#define get_bits(av, af, an)
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
int read(izstream &zs, T *x, Items items)