15 if (bin->options.verbose) \
18 if (mo->options.verbose) \
39 #define mach0_endian 1
42 switch (
bin->main_cmd.cmd) {
44 return bin->entry +
bin->baddr;
56 for (
i = 0;
i <
bin->nsegs;
i++) {
59 if (
addr >= segment_base &&
addr < segment_base + segment_size) {
60 return bin->segs[
i].fileoff + (
addr - segment_base);
70 for (
i = 0;
i <
bin->nsegs;
i++) {
73 if (
offset >= segment_base &&
offset < segment_base + segment_size) {
74 return bin->segs[
i].vmaddr + (
offset - segment_base);
96 sdb_set(
bin->kv,
"mach0_build_platform.cparse",
97 "enum mach0_build_platform"
98 "{MACOS=1, IOS=2, TVOS=3, WATCHOS=4, BRIDGEOS=5, IOSMAC=6, IOSSIMULATOR=7, TVOSSIMULATOR=8, WATCHOSSIMULATOR=9};",
101 "enum mach0_build_tool"
102 "{CLANG=1, SWIFT=2, LD=3};",
104 sdb_set(
bin->kv,
"mach0_load_command_type.cparse",
105 "enum mach0_load_command_type"
106 "{ LC_SEGMENT=0x00000001ULL, LC_SYMTAB=0x00000002ULL, LC_SYMSEG=0x00000003ULL, LC_THREAD=0x00000004ULL, LC_UNIXTHREAD=0x00000005ULL, LC_LOADFVMLIB=0x00000006ULL, LC_IDFVMLIB=0x00000007ULL, LC_IDENT=0x00000008ULL, LC_FVMFILE=0x00000009ULL, LC_PREPAGE=0x0000000aULL, LC_DYSYMTAB=0x0000000bULL, LC_LOAD_DYLIB=0x0000000cULL, LC_ID_DYLIB=0x0000000dULL, LC_LOAD_DYLINKER=0x0000000eULL, LC_ID_DYLINKER=0x0000000fULL, LC_PREBOUND_DYLIB=0x00000010ULL, LC_ROUTINES=0x00000011ULL, LC_SUB_FRAMEWORK=0x00000012ULL, LC_SUB_UMBRELLA=0x00000013ULL, LC_SUB_CLIENT=0x00000014ULL, LC_SUB_LIBRARY=0x00000015ULL, LC_TWOLEVEL_HINTS=0x00000016ULL, LC_PREBIND_CKSUM=0x00000017ULL, LC_LOAD_WEAK_DYLIB=0x80000018ULL, LC_SEGMENT_64=0x00000019ULL, LC_ROUTINES_64=0x0000001aULL, LC_UUID=0x0000001bULL, LC_RPATH=0x8000001cULL, LC_CODE_SIGNATURE=0x0000001dULL, LC_SEGMENT_SPLIT_INFO=0x0000001eULL, LC_REEXPORT_DYLIB=0x8000001fULL, LC_LAZY_LOAD_DYLIB=0x00000020ULL, LC_ENCRYPTION_INFO=0x00000021ULL, LC_DYLD_INFO=0x00000022ULL, LC_DYLD_INFO_ONLY=0x80000022ULL, LC_LOAD_UPWARD_DYLIB=0x80000023ULL, LC_VERSION_MIN_MACOSX=0x00000024ULL, LC_VERSION_MIN_IPHONEOS=0x00000025ULL, LC_FUNCTION_STARTS=0x00000026ULL, LC_DYLD_ENVIRONMENT=0x00000027ULL, LC_MAIN=0x80000028ULL, LC_DATA_IN_CODE=0x00000029ULL, LC_SOURCE_VERSION=0x0000002aULL, LC_DYLIB_CODE_SIGN_DRS=0x0000002bULL, LC_ENCRYPTION_INFO_64=0x0000002cULL, LC_LINKER_OPTION=0x0000002dULL, LC_LINKER_OPTIMIZATION_HINT=0x0000002eULL, LC_VERSION_MIN_TVOS=0x0000002fULL, LC_VERSION_MIN_WATCHOS=0x00000030ULL, LC_NOTE=0x00000031ULL, LC_BUILD_VERSION=0x00000032ULL };",
108 sdb_set(
bin->kv,
"mach0_header_filetype.cparse",
109 "enum mach0_header_filetype"
110 "{MH_OBJECT=1, MH_EXECUTE=2, MH_FVMLIB=3, MH_CORE=4, MH_PRELOAD=5, MH_DYLIB=6, MH_DYLINKER=7, MH_BUNDLE=8, MH_DYLIB_STUB=9, MH_DSYM=10, MH_KEXT_BUNDLE=11};",
113 "enum mach0_header_flags"
114 "{MH_NOUNDEFS=1, MH_INCRLINK=2,MH_DYLDLINK=4,MH_BINDATLOAD=8,MH_PREBOUND=0x10, MH_SPLIT_SEGS=0x20,MH_LAZY_INIT=0x40,MH_TWOLEVEL=0x80, MH_FORCE_FLAT=0x100,MH_NOMULTIDEFS=0x200,MH_NOFIXPREBINDING=0x400, MH_PREBINDABLE=0x800, MH_ALLMODSBOUND=0x1000, MH_SUBSECTIONS_VIA_SYMBOLS=0x2000, MH_CANONICAL=0x4000,MH_WEAK_DEFINES=0x8000, MH_BINDS_TO_WEAK=0x10000,MH_ALLOW_STACK_EXECUTION=0x20000, MH_ROOT_SAFE=0x40000,MH_SETUID_SAFE=0x80000, MH_NO_REEXPORTED_DYLIBS=0x100000,MH_PIE=0x200000, MH_DEAD_STRIPPABLE_DYLIB=0x400000, MH_HAS_TLV_DESCRIPTORS=0x800000, MH_NO_HEAP_EXECUTION=0x1000000};",
116 sdb_set(
bin->kv,
"mach0_section_types.cparse",
117 "enum mach0_section_types"
118 "{S_REGULAR=0, S_ZEROFILL=1, S_CSTRING_LITERALS=2, S_4BYTE_LITERALS=3, S_8BYTE_LITERALS=4, S_LITERAL_POINTERS=5, S_NON_LAZY_SYMBOL_POINTERS=6, S_LAZY_SYMBOL_POINTERS=7, S_SYMBOL_STUBS=8, S_MOD_INIT_FUNC_POINTERS=9, S_MOD_TERM_FUNC_POINTERS=0xa, S_COALESCED=0xb, S_GB_ZEROFILL=0xc, S_INTERPOSING=0xd, S_16BYTE_LITERALS=0xe, S_DTRACE_DOF=0xf, S_LAZY_DYLIB_SYMBOL_POINTERS=0x10, S_THREAD_LOCAL_REGULAR=0x11, S_THREAD_LOCAL_ZEROFILL=0x12, S_THREAD_LOCAL_VARIABLES=0x13, S_THREAD_LOCAL_VARIABLE_POINTERS=0x14, S_THREAD_LOCAL_INIT_FUNCTION_POINTERS=0x15, S_INIT_FUNC_OFFSETS=0x16};",
120 sdb_set(
bin->kv,
"mach0_section_attrs.cparse",
121 "enum mach0_section_attrs"
122 "{S_ATTR_PURE_INSTRUCTIONS=0x800000ULL, S_ATTR_NO_TOC=0x400000ULL, S_ATTR_STRIP_STATIC_SYMS=0x200000ULL, S_ATTR_NO_DEAD_STRIP=0x100000ULL, S_ATTR_LIVE_SUPPORT=0x080000ULL, S_ATTR_SELF_MODIFYING_CODE=0x040000ULL, S_ATTR_DEBUG=0x020000ULL, S_ATTR_SOME_INSTRUCTIONS=0x000004ULL, S_ATTR_EXT_RELOC=0x000002ULL, S_ATTR_LOC_RELOC=0x000001ULL};",
126 "magic cputype cpusubtype (mach0_header_filetype)filetype ncmds sizeofcmds (mach0_header_flags)flags",
129 "[4]Ed[16]zxxxxoodx "
130 "(mach0_load_command_type)cmd cmdsize segname vmaddr vmsize fileoff filesize maxprot initprot nsects flags",
133 "[4]Ed[16]zqqqqoodx "
134 "(mach0_load_command_type)cmd cmdsize segname vmaddr vmsize fileoff filesize maxprot initprot nsects flags",
136 sdb_set(
bin->kv,
"mach0_symtab_command.format",
138 "(mach0_load_command_type)cmd cmdsize symoff nsyms stroff strsize",
140 sdb_set(
bin->kv,
"mach0_dysymtab_command.format",
141 "[4]Edddddddddddxdxdxxxd "
142 "(mach0_load_command_type)cmd cmdsize ilocalsym nlocalsym iextdefsym nextdefsym iundefsym nundefsym tocoff ntoc moddtaboff nmodtab extrefsymoff nextrefsyms inddirectsymoff nindirectsyms extreloff nextrel locreloff nlocrel",
145 "[16]z[16]zxxxxxx[1]E[3]Bxx "
146 "sectname segname addr size offset align reloff nreloc (mach0_section_types)flags_type (mach0_section_attrs)flags_attr reserved1 reserved2",
149 "[16]z[16]zqqxxxx[1]E[3]Bxxx "
150 "sectname segname addr size offset align reloff nreloc (mach0_section_types)flags_type (mach0_section_attrs)flags_attr reserved1 reserved2 reserved3",
154 "name_offset timestamp current_version compatibility_version name",
156 sdb_set(
bin->kv,
"mach0_dylib_command.format",
158 "(mach0_load_command_type)cmd cmdsize (mach0_dylib)dylib",
160 sdb_set(
bin->kv,
"mach0_id_dylib_command.format",
162 "(mach0_load_command_type)cmd cmdsize (mach0_dylib)dylib",
166 "(mach0_load_command_type)cmd cmdsize uuid",
168 sdb_set(
bin->kv,
"mach0_rpath_command.format",
170 "(mach0_load_command_type)cmd cmdsize path_offset path",
172 sdb_set(
bin->kv,
"mach0_entry_point_command.format",
174 "(mach0_load_command_type)cmd cmdsize entryoff stacksize",
176 sdb_set(
bin->kv,
"mach0_encryption_info64_command.format",
178 "(mach0_load_command_type)cmd cmdsize offset size id padding",
180 sdb_set(
bin->kv,
"mach0_encryption_info_command.format",
182 "(mach0_load_command_type)cmd cmdsize offset size id",
184 sdb_set(
bin->kv,
"mach0_code_signature_command.format",
186 "(mach0_load_command_type)cmd cmdsize offset size",
188 sdb_set(
bin->kv,
"mach0_dyld_info_only_command.format",
190 "(mach0_load_command_type)cmd cmdsize rebase_off rebase_size bind_off bind_size weak_bind_off weak_bind_size lazy_bind_off lazy_bind_size export_off export_size",
192 sdb_set(
bin->kv,
"mach0_load_dylinker_command.format",
194 "(mach0_load_command_type)cmd cmdsize name_offset name",
196 sdb_set(
bin->kv,
"mach0_id_dylinker_command.format",
198 "(mach0_load_command_type)cmd cmdsize name_offset name",
200 sdb_set(
bin->kv,
"mach0_build_version_command.format",
202 "(mach0_load_command_type)cmd cmdsize (mach0_build_platform)platform minos sdk ntools",
204 sdb_set(
bin->kv,
"mach0_build_version_tool.format",
206 "(mach0_build_tool)tool version",
208 sdb_set(
bin->kv,
"mach0_source_version_command.format",
210 "(mach0_load_command_type)cmd cmdsize version",
212 sdb_set(
bin->kv,
"mach0_function_starts_command.format",
214 "(mach0_load_command_type)cmd cmdsize offset size",
216 sdb_set(
bin->kv,
"mach0_data_in_code_command.format",
218 "(mach0_load_command_type)cmd cmdsize offset size",
220 sdb_set(
bin->kv,
"mach0_version_min_command.format",
222 "(mach0_load_command_type)cmd cmdsize version reserved",
224 sdb_set(
bin->kv,
"mach0_segment_split_info_command.format",
226 "(mach0_load_command_type)cmd cmdsize offset size",
228 sdb_set(
bin->kv,
"mach0_unixthread_command.format",
230 "(mach0_load_command_type)cmd cmdsize flavor count",
235 ut8 magicbytes[4] = { 0 };
236 ut8 machohdrbytes[
sizeof(
struct MACH0_(mach_header))] = { 0 };
243 bin->big_endian =
false;
245 bin->big_endian =
true;
247 bin->big_endian =
false;
249 bin->big_endian =
true;
251 bin->big_endian =
false;
253 bin->big_endian =
true;
258 if (
len !=
sizeof(machohdrbytes)) {
259 bprintf(
"Error: read (hdr)\n");
278 size_t i, j,
k, sect,
len;
280 ut8 segcom[
sizeof(
struct MACH0_(segment_command))] = { 0 };
281 ut8 sec[
sizeof(
struct MACH0_(section))] = { 0 };
286 if (!size_sects || size_sects >
bin->size) {
293 perror(
"realloc (seg)");
299 bprintf(
"Error: read (seg)\n");
307 memcpy(&
bin->segs[j].segname, &segcom[
i], 16);
344 if (
bin->segs[j].nsects > 0) {
346 bin->nsects +=
bin->segs[j].nsects;
347 if (
bin->nsects > 128) {
348 int new_nsects =
bin->nsects & 0xf;
349 bprintf(
"WARNING: mach0 header contains too many sections (%d). Wrapping to %d\n",
350 bin->nsects, new_nsects);
351 bin->nsects = new_nsects;
353 if ((
int)
bin->nsects < 1) {
354 bprintf(
"Warning: Invalid number of sections\n");
362 if (!size_sects || size_sects >
bin->size) {
379 perror(
"realloc (sects)");
384 for (
k = sect, j = 0;
k <
bin->nsects;
k++, j++) {
385 ut64 offset =
off +
sizeof(
struct MACH0_(segment_command)) + j *
sizeof(
struct MACH0_(section));
388 bprintf(
"Error: read (sects)\n");
401 sdb_set(
bin->kv,
sdb_fmt(
"mach0_section_%.16s_%.16s.format",
bin->sects[
k].segname,
bin->sects[
k].sectname),
"mach0_section64", 0);
403 sdb_set(
bin->kv,
sdb_fmt(
"mach0_section_%.16s_%.16s.format",
bin->sects[
k].segname,
bin->sects[
k].sectname),
"mach0_section", 0);
446 const char *error_message =
"";
448 ut8 nlst[
sizeof(
struct MACH0_(nlist))] = { 0 };
449 const bool be = mo->big_endian;
456 Eprintf(
"Error: read (symtab)\n");
469 mo->nsymtab = st.
nsyms;
477 Error(
"symbol size is zero");
479 if (st.
symoff > mo->size || st.
symoff + size_sym > mo->size) {
480 Error(
"symoff is out of bounds");
483 Error(
"symoff is out of bounds");
488 Error(
"Error: read (symstr)");
493 for (
i = 0;
i < mo->nsymtab;
i++) {
494 ut64 at = st.
symoff + (
i *
sizeof(
struct MACH0_(nlist)));
497 Error(
"read (nlist)");
515 Eprintf(
"%s\n", error_message);
524 ut8 dymod[
sizeof(
struct MACH0_(dylib_module))] = { 0 };
525 ut8 idsyms[
sizeof(
ut32)] = { 0 };
533 bprintf(
"Error: read (dysymtab)\n");
558 bin->ntoc =
bin->dysymtab.ntoc;
561 perror(
"calloc (toc)");
572 if (
bin->dysymtab.tocoff >
bin->size ||
bin->dysymtab.tocoff + size_tab >
bin->size) {
576 for (
i = 0;
i <
bin->ntoc;
i++) {
580 bprintf(
"Error: read (toc)\n");
588 bin->nmodtab =
bin->dysymtab.nmodtab;
589 if (
bin->nmodtab > 0) {
591 perror(
"calloc (modtab)");
602 if (
bin->dysymtab.modtaboff >
bin->size ||
603 bin->dysymtab.modtaboff + size_tab >
bin->size) {
607 for (
i = 0;
i <
bin->nmodtab;
i++) {
611 bprintf(
"Error: read (modtab)\n");
636 bin->nindirectsyms =
bin->dysymtab.nindirectsyms;
637 if (
bin->nindirectsyms > 0) {
639 perror(
"calloc (indirectsyms)");
650 if (
bin->dysymtab.indirectsymoff >
bin->size ||
651 bin->dysymtab.indirectsymoff + size_tab >
bin->size) {
655 for (
i = 0;
i <
bin->nindirectsyms;
i++) {
658 bprintf(
"Error: read (indirect syms)\n");
670 if (off < 0 || off >=
len) {
677 typedef struct __CodeDirectory {
702 int psize = datasize;
709 CS_CodeDirectory cscd = { 0 };
710 #define READFIELD(x) cscd.x = rz_read_ble32(p + rz_offsetof(CS_CodeDirectory, x), 1)
711 #define READFIELD8(x) cscd.x = p[rz_offsetof(CS_CodeDirectory, x)]
724 eprintf(
"Version: %x\n", cscd.version);
725 eprintf(
"Flags: %x\n", cscd.flags);
726 eprintf(
"Length: %d\n", cscd.length);
727 eprintf(
"PageSize: %d\n", cscd.pageSize);
728 eprintf(
"hashOffset: %d\n", cscd.hashOffset);
729 eprintf(
"codeLimit: %d\n", cscd.codeLimit);
730 eprintf(
"hashSize: %d\n", cscd.hashSize);
731 eprintf(
"hashType: %d\n", cscd.hashType);
732 char *identity =
readString(
p, cscd.identOffset, psize);
733 eprintf(
"Identity: %s\n", identity);
734 char *teamId =
readString(
p, cscd.teamIDOffset, psize);
735 eprintf(
"TeamID: %s\n", teamId);
736 eprintf(
"CodeSlots: %d\n", cscd.nCodeSlots);
740 const char *digest_algo =
"sha1";
741 switch (cscd.hashType) {
744 digest_algo =
"sha1";
747 digest_algo =
"sha256";
755 int fofsz = cscd.length;
760 eprintf(
"Invalid cdhash offset/length values\n");
761 goto parseCodeDirectory_end;
766 goto parseCodeDirectory_end;
771 for (
i = 0;
i < digest_size;
i++) {
779 ut8 *hash =
p + cscd.hashOffset;
783 for (j = 0; j < cscd.nCodeSlots; j++) {
785 int idx = j * digest_size;
787 for (
k = 0;
k < digest_size;
k++) {
791 int fofsz =
RZ_MIN(
sizeof(fofbuf), cscd.codeLimit - fof);
796 goto parseCodeDirectory_end;
799 if (memcmp(hash +
idx, digest, digest_size)) {
802 for (
i = 0;
i < digest_size;
i++) {
812 parseCodeDirectory_end:
831 bprintf(
"Failed to get data while parsing LC_CODE_SIGNATURE command\n");
841 bin->signature = (
ut8 *)
strdup(
"Malformed entitlement");
852 bool isVerbose =
false;
863 if (data +
i >
bin->size) {
864 bin->signature = (
ut8 *)
strdup(
"Malformed entitlement");
876 if (
true || isVerbose) {
879 bin->signature = (
ut8 *)
strdup(
"Malformed entitlement");
888 if (len <= bin->
size &&
len > 1) {
890 if (!
bin->signature) {
896 bin->signature[
len] =
'\0';
899 bin->signature = (
ut8 *)
strdup(
"Malformed entitlement");
902 bin->signature = (
ut8 *)
strdup(
"Malformed entitlement");
923 eprintf(
"Magic: %x\n", words[0]);
925 (
int)data +
idx.offset + 8, (
int)
length);
926 eprintf(
"openssl pkcs7 -print_certs -text -inform der -in DUMP\n");
927 eprintf(
"openssl asn1parse -offset %d -length %d -inform der -in /bin/ls\n",
928 (
int)data +
idx.offset + 8, (
int)
length);
930 (
int)data +
idx.offset + 8, (
int)
length);
939 p[
sizeof(
p) - 1] = 0;
941 if (slot_size <
sizeof(
p)) {
943 char *ident =
rz_str_ndup((
const char *)
p + 28, ident_size);
949 if (
bin->options.verbose) {
950 eprintf(
"Invalid code slot size\n");
958 if (
bin->options.verbose) {
959 eprintf(
"TODO: Some codesign slots are not yet supported\n");
963 if (
bin->options.verbose) {
964 eprintf(
"Unknown Code signature slot %d\n",
idx.type);
969 if (!
bin->signature) {
1009 if (ptr_thread >
bin->size) {
1013 switch (
bin->hdr.cputype) {
1022 (
ut8 *)&
bin->thread_state.x86_32,
"16i", 1) == -1) {
1023 bprintf(
"Error: read (thread state x86_32)\n");
1026 pc =
bin->thread_state.x86_32.eip;
1028 arw_ptr = (
ut8 *)&
bin->thread_state.x86_32;
1036 (
ut8 *)&
bin->thread_state.x86_64,
"32l", 1) == -1) {
1037 bprintf(
"Error: read (thread state x86_64)\n");
1040 pc =
bin->thread_state.x86_64.rip;
1042 arw_ptr = (
ut8 *)&
bin->thread_state.x86_64;
1055 (
ut8 *)&
bin->thread_state.ppc_32,
bin->big_endian ?
"40I" :
"40i", 1) == -1) {
1056 bprintf(
"Error: read (thread state ppc_32)\n");
1059 pc =
bin->thread_state.ppc_32.srr0;
1061 arw_ptr = (
ut8 *)&
bin->thread_state.ppc_32;
1068 (
ut8 *)&
bin->thread_state.ppc_64,
bin->big_endian ?
"34LI3LI" :
"34li3li", 1) == -1) {
1069 bprintf(
"Error: read (thread state ppc_64)\n");
1072 pc =
bin->thread_state.ppc_64.srr0;
1074 arw_ptr = (
ut8 *)&
bin->thread_state.ppc_64;
1083 (
ut8 *)&
bin->thread_state.arm_32,
bin->big_endian ?
"17I" :
"17i", 1) == -1) {
1084 bprintf(
"Error: read (thread state arm)\n");
1087 pc =
bin->thread_state.arm_32.r15;
1089 arw_ptr = (
ut8 *)&
bin->thread_state.arm_32;
1097 (
ut8 *)&
bin->thread_state.arm_64,
bin->big_endian ?
"34LI1I" :
"34Li1i", 1) == -1) {
1098 bprintf(
"Error: read (thread state arm)\n");
1103 arw_ptr = (
ut8 *)&
bin->thread_state.arm_64;
1107 bprintf(
"Error: read (unknown thread state structure)\n");
1112 if (arw_ptr && arw_sz > 0) {
1116 for (
i = 0;
i < arw_sz;
i++) {
1122 if (is_first_thread) {
1123 bin->main_cmd = *lc;
1134 bprintf(
"Error: read (thread)\n");
1144 bprintf(
"Likely overflow while parsing"
1145 " LC_FUNCTION_STARTS command\n");
1150 bprintf(
"Failed to get data while parsing"
1151 " LC_FUNCTION_STARTS command\n");
1161 bprintf(
"Failed to allocate buffer\n");
1167 bprintf(
"Likely overflow while parsing "
1168 "LC_FUNCTION_STARTS command\n");
1174 bprintf(
"Failed to get data while parsing"
1175 " LC_FUNCTION_STARTS\n");
1194 lib =
bin->nlibs - 1;
1198 perror(
"realloc (libs)");
1204 bprintf(
"Error: read (dylib)\n");
1224 bprintf(
"Error: read (dylib str)");
1233 return "LC_DATA_IN_CODE";
1235 return "LC_CODE_SIGNATURE";
1239 return "LC_TWOLEVEL_HINTS";
1241 return "LC_PREBIND_CKSUM";
1243 return "LC_SEGMENT";
1245 return "LC_SEGMENT_64";
1251 return "LC_DYSYMTAB";
1253 return "LC_PREBOUND_DYLIB";
1255 return "LC_ROUTINES";
1257 return "LC_ROUTINES_64";
1259 return "LC_SUB_FRAMEWORK";
1261 return "LC_SUB_UMBRELLA";
1263 return "LC_SUB_CLIENT";
1265 return "LC_SUB_LIBRARY";
1267 return "LC_FUNCTION_STARTS";
1269 return "LC_DYLIB_CODE_SIGN_DRS";
1273 return "LC_BUILD_VERSION";
1275 return "LC_VERSION_MIN_MACOSX";
1277 return "LC_VERSION_MIN_IPHONEOS";
1279 return "LC_VERSION_MIN_TVOS";
1281 return "LC_VERSION_MIN_WATCHOS";
1283 return "LC_DYLD_INFO";
1285 return "LC_DYLD_INFO_ONLY";
1287 return "LC_DYLD_ENVIRONMENT";
1289 return "LC_SOURCE_VERSION";
1295 return "LC_ID_DYLIB";
1297 return "LC_ID_DYLINKER";
1299 return "LC_LAZY_LOAD_DYLIB";
1301 return "LC_ENCRYPTION_INFO";
1303 return "LC_ENCRYPTION_INFO_64";
1305 return "LC_SEGMENT_SPLIT_INFO";
1307 return "LC_REEXPORT_DYLIB";
1309 return "LC_LINKER_OPTION";
1311 return "LC_LINKER_OPTIMIZATION_HINT";
1313 return "LC_LOAD_DYLINKER";
1315 return "LC_LOAD_DYLIB";
1317 return "LC_LOAD_WEAK_DYLIB";
1321 return "LC_UNIXTHREAD";
1323 return "LC_LOADFVMLIB";
1325 return "LC_IDFVMLIB";
1329 return "LC_FVMFILE";
1331 return "LC_PREPAGE";
1339 return "mach0_build_version_command";
1341 return "mach0_code_signature_command";
1343 return "mach0_data_in_code_command";
1346 return "mach0_dyld_info_only_command";
1352 return "mach0_dysymtab_command";
1354 return "mach0_encryption_info_command";
1356 return "mach0_encryption_info64_command";
1358 return "mach0_function_starts_command";
1362 return "mach0_id_dylib_command";
1364 return "mach0_id_dylinker_command";
1374 return "mach0_load_dylinker_command";
1378 return "mach0_dylib_command";
1382 return "mach0_entry_point_command";
1398 return "mach0_rpath_command";
1400 return "mach0_segment";
1402 return "mach0_segment64";
1404 return "mach0_segment_split_info_command";
1406 return "mach0_source_version_command";
1416 return "mach0_symtab_command";
1422 return "mach0_uuid_command";
1427 return "mach0_version_min_command";
1431 return "mach0_unixthread_command";
1451 return "iOS Simulator";
1453 return "tvOS Simulator";
1455 return "watchOS Simulator";
1482 if (
header.fixups_version > 0) {
1483 eprintf(
"Unsupported fixups version: %u\n",
header.fixups_version);
1494 if (!
bin->chained_starts) {
1498 ut64 cursor = starts_at +
sizeof(
ut32);
1499 for (
i = 0;
i <
bin->nchained_starts;
i++) {
1502 cursor +=
sizeof(
ut32);
1505 if (
i >=
bin->nsegs) {
1512 bin->chained_starts[
i] = cur_seg;
1526 cursor +=
sizeof(
ut32);
1533 if (!
bin->dyld_info) {
1539 bin->nchained_starts =
bin->nsegs;
1541 if (!
bin->chained_starts) {
1544 size_t wordsize = get_word_size(
bin);
1549 bind_size =
bin->dyld_info->bind_size;
1550 if (!bind_size || bind_size < 1) {
1553 if (
bin->dyld_info->bind_off >
bin->size) {
1556 if (
bin->dyld_info->bind_off + bind_size >
bin->size) {
1564 bprintf(
"Error: read (dyld_info bind) at 0x%08" PFMT64x "\n", (
ut64)(
size_t)
bin->dyld_info->bind_off);
1569 size_t cur_seg_idx = 0;
1582 read_uleb128(&
p,
end);
1586 const size_t ps = 0x1000;
1587 if (!cur_seg || cur_seg_idx != seg_idx) {
1588 cur_seg_idx = seg_idx;
1589 cur_seg =
bin->chained_starts[seg_idx];
1595 bin->chained_starts[seg_idx] = cur_seg;
1598 cur_seg->
page_count = ((
bin->segs[seg_idx].vmsize + (ps - 1)) & ~(ps - 1)) / ps;
1618 bprintf(
"Error: Unexpected BIND_OPCODE_THREADED sub-opcode: 0x%x\n",
imm);
1627 read_uleb128(&
p,
end);
1630 while (*
p++ &&
p <
end) {
1639 if (seg_idx >=
bin->nsegs) {
1640 bprintf(
"Error: BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB"
1641 " has unexistent segment %d\n",
1646 seg_off = read_uleb128(&
p,
end);
1650 seg_off += read_uleb128(&
p,
end);
1655 seg_off += read_uleb128(&
p,
end) + wordsize;
1663 for (j = 0; j <
count; j++) {
1664 seg_off +=
skip + wordsize;
1668 bprintf(
"Error: unknown bind opcode 0x%02x in dyld_info\n", *
p);
1681 bool is_first_thread =
true;
1687 bin->has_crypto = 0;
1688 if (
bin->hdr.sizeofcmds >
bin->size) {
1689 bprintf(
"Warning: chopping hdr.sizeofcmds\n");
1690 bin->hdr.sizeofcmds =
bin->size - 128;
1697 bprintf(
"mach0: out of bounds command\n");
1709 bprintf(
"Warning: mach0_header %d = cmdsize<1. (0x%llx vs 0x%llx)\n",
i,
1719 sdb_set(
bin->kv,
sdb_fmt(
"mach0_cmd_%d.format",
i),
"[4]Ed (mach_load_command_type)cmd size", 0);
1735 bprintf(
"error parsing segment\n");
1743 bprintf(
"error parsing symtab\n");
1750 bprintf(
"error parsing dysymtab\n");
1783 bprintf(
"UUID out of bounds\n");
1801 struct MACH0_(encryption_info_command) eic = { 0 };
1802 ut8 seic[
sizeof(
struct MACH0_(encryption_info_command))] = { 0 };
1804 bprintf(
"encryption info out of bounds\n");
1814 bin->has_crypto = eic.cryptid;
1830 bprintf(
"Warning: Cannot parse dylinker command\n");
1856 ut8 sep[2 *
sizeof(
ut64)] = { 0 };
1859 if (!is_first_thread) {
1860 bprintf(
"Error: LC_MAIN with other threads\n");
1863 if (
off + 8 >
bin->size ||
off +
sizeof(ep) >
bin->size) {
1864 bprintf(
"invalid command size for main\n");
1877 is_first_thread =
false;
1881 if (!is_first_thread) {
1882 bprintf(
"Error: LC_UNIXTHREAD with other threads\n");
1889 bprintf(
"Cannot parse thread\n");
1892 is_first_thread =
false;
1899 bprintf(
"Cannot parse dylib\n");
1909 if (
bin->dyld_info) {
1911 bprintf(
"Cannot parse dyldinfo\n");
1953 bprintf(
"Cannot parse LC_FUNCTION_STARTS\n");
1965 bool has_chained_fixups =
false;
1977 bprintf(
"Warning: mach0_header %d = cmdsize<1. (0x%llx vs 0x%llx)\n",
i,
1987 sdb_set(
bin->kv,
sdb_fmt(
"mach0_cmd_%d.format",
i),
"[4]Ed (mach_load_command_type)cmd size", 0);
1993 if (
bin->options.verbose) {
1998 eprintf(
"data-in-code at 0x%x size %d\n", dataoff, datasize);
2004 for (j = 0; j < datasize; j += 8) {
2017 if (
bin->options.verbose) {
2022 eprintf(
"exports trie at 0x%x size %d\n", dataoff, datasize);
2030 if (
bin->options.verbose) {
2031 eprintf(
"chained fixups at 0x%x size %d\n", dataoff, datasize);
2051 Eprintf(
"Warning: Cannot initialize items\n");
2064 for (
i = 0; !mo->symbols[
i].last;
i++) {
2065 free(mo->symbols[
i].name);
2073 free(mo->indirectsyms);
2074 free(mo->imports_by_ord);
2075 if (mo->imports_by_name) {
2076 ht_pp_free(mo->imports_by_name);
2078 free(mo->dyld_info);
2082 free(mo->func_start);
2083 free(mo->signature);
2086 if (mo->chained_starts) {
2087 for (
i = 0;
i < mo->nchained_starts;
i++) {
2088 if (mo->chained_starts[
i]) {
2089 free(mo->chained_starts[
i]->page_start);
2090 free(mo->chained_starts[
i]);
2093 free(mo->chained_starts);
2107 options->verbose = bf->rbin->verbose;
2147 if (strstr(sect->
name,
"_cstring")) {
2150 if (strstr(sect->
name,
"_objc_methname")) {
2153 if (strstr(sect->
name,
"_objc_classname")) {
2156 if (strstr(sect->
name,
"_objc_methtype")) {
2170 struct MACH0_(obj_t) *obj = bf->o->bin_obj;
2204 if (obj->buf_patched) {
2209 vf->
buf = obj->buf_patched;
2219 struct MACH0_(obj_t) *
bin = bf->o->bin_obj;
2224 for (
size_t i = 0;
i <
bin->nsegs;
i++) {
2225 struct MACH0_(segment_command) *seg = &
bin->segs[
i];
2226 if (!seg->initprot) {
2233 map->psize = seg->vmsize;
2234 map->vaddr = seg->vmaddr;
2235 map->vsize = seg->vmsize;
2241 map->paddr = seg->fileoff;
2245 map->paddr = seg->fileoff + bf->o->boffset;
2257 struct MACH0_(obj_t) *obj = bf->o->bin_obj;
2268 struct MACH0_(obj_t) *
bin = bf->o->bin_obj;
2269 if (
bin->sections_cache) {
2270 return bin->sections_cache;
2275 if (
bin->nsegs > 0) {
2276 struct MACH0_(segment_command) * seg;
2277 for (
i = 0;
i <
bin->nsegs;
i++) {
2278 seg = &
bin->segs[
i];
2279 if (!seg->initprot) {
2286 s->vaddr = seg->vmaddr;
2287 s->vsize = seg->vmsize;
2288 s->size = seg->vmsize;
2289 s->paddr = seg->fileoff;
2290 s->paddr += bf->o->boffset;
2293 s->is_segment =
true;
2299 if (
bin->nsects > 0) {
2300 int last_section =
RZ_MIN(
bin->nsects, 128);
2301 for (
i = 0;
i < last_section;
i++) {
2308 s->align = (
ut64)(1ULL << (
bin->sects[
i].align & 63));
2309 s->is_segment =
false;
2312 s->type =
bin->sects[
i].flags & 0xFF;
2313 s->flags =
bin->sects[
i].flags & 0xFFFFFF00;
2316 int segment_index = 0;
2318 for (j = 0; j <
bin->nsegs; j++) {
2319 if (
s->vaddr >=
bin->segs[j].vmaddr &&
2320 s->vaddr < (
bin->segs[j].vmaddr +
bin->segs[j].vmsize)) {
2327 char *segment_name =
rz_str_newf(
"%zu.%s",
i,
bin->segs[segment_index].segname);
2328 s->name =
rz_str_newf(
"%s.%s", segment_name, section_name);
2330 if (strstr(section_name,
"interpos") || strstr(section_name,
"__mod_")) {
2360 return rz_str_new(
"NON_LAZY_SYMBOL_POINTERS");
2414 char sectname[64], raw_segname[17];
2418 if (
bin->nsects < 1 &&
bin->nsegs > 0) {
2419 struct MACH0_(segment_command) * seg;
2423 for (
i = 0;
i <
bin->nsegs;
i++) {
2424 seg = &
bin->segs[
i];
2431 rz_strf(sectname,
"%.16s", seg->segname);
2452 for (
i = 0;
i <
to;
i++) {
2459 rz_strf(sectname,
"%.16s",
bin->sects[
i].sectname);
2461 rz_strf(raw_segname,
"%.16s",
bin->sects[
i].segname);
2462 for (j = 0; j <
bin->nsegs; j++) {
2470 "%d.%s.%s", (
int)
i, raw_segname, sectname);
2478 size_t i, j, nsyms, stridx;
2488 if (!
bin || !
bin->sects) {
2491 for (
i = 0;
i <
bin->nsects;
i++) {
2493 ut64 sect_size =
bin->sects[
i].size;
2494 ut32 sect_fragment =
bin->sects[
i].reserved2;
2495 if (
bin->sects[
i].offset >
bin->size) {
2496 bprintf(
"mach0: section offset starts way beyond the end of the file\n");
2499 if (sect_size >
bin->size) {
2500 bprintf(
"mach0: Invalid symbol table size\n");
2501 sect_size =
bin->size -
bin->sects[
i].offset;
2503 nsyms = (
int)(sect_size / sect_fragment);
2504 for (j = 0; j < nsyms; j++) {
2506 if (
bin->sects[
i].reserved1 + j >=
bin->nindirectsyms) {
2510 if (
bin->indirectsyms) {
2511 if (
idx !=
bin->indirectsyms[
bin->sects[
i].reserved1 + j]) {
2515 if (
idx >
bin->nsymtab) {
2519 int delta = j *
bin->sects[
i].reserved2;
2521 bprintf(
"mach0: corrupted reserved2 value leads to int overflow.\n");
2527 stridx =
bin->symtab[
idx].n_strx;
2528 if (stridx < bin->symstrlen) {
2529 symstr = (
char *)
bin->symstr + stridx;
2534 if (*symstr ==
'_') {
2553 ht_pp_insert(hash,
key,
"1");
2565 if (!mo->symstr || stridx >= mo->symstrlen) {
2568 int len = mo->symstrlen - stridx;
2569 const char *symstr = (
const char *)mo->symstr + stridx;
2570 for (
i = 0;
i <
len;
i++) {
2571 if ((
ut8)(symstr[
i] & 0xff) == 0xff || !symstr[
i]) {
2588 if (!
bin->dyld_info) {
2648 resolver = res +
bin->options.header_at;
2649 }
else if (isReexport) {
2650 p += strlen((
char *)
p) + 1;
2687 ut64 child_count = read_uleb128(&
p,
end);
2691 if (
state->i == child_count) {
2695 if (!
state->next_child) {
2705 p += strlen(next->
label) + 1;
2726 rz_list_foreach (
states, it,
s) {
2727 if (
s->node == next->
node) {
2764 size_t j,
s, symbols_size, symbols_count;
2775 HtPP *hash = ht_pp_new0();
2784 rz_list_foreach (
list, it,
s) {
2789 if (!
bin->symtab || !
bin->symstr) {
2794 symbols_count = (
bin->dysymtab.nextdefsym +
2795 bin->dysymtab.nlocalsym +
2796 bin->dysymtab.nundefsym);
2797 symbols_count +=
bin->nsymtab;
2798 symbols_size = (symbols_count + 1) * 2 *
sizeof(
struct symbol_t);
2800 if (symbols_size < 1) {
2809 for (
s = 0;
s < 2;
s++) {
2812 from =
bin->dysymtab.iextdefsym;
2816 from =
bin->dysymtab.ilocalsym;
2821 from =
bin->dysymtab.iundefsym;
2833 ut32 maxsymbols = symbols_size /
sizeof(
struct symbol_t);
2834 if (symbols_count >= maxsymbols) {
2835 symbols_count = maxsymbols - 1;
2836 eprintf(
"macho warning: Symbol table truncated\n");
2838 for (
i =
from;
i <
to && j < symbols_count;
i++, j++) {
2848 sym->
type =
"LOCAL";
2850 int stridx =
bin->symtab[
i].n_strx;
2853 sym->
name = sym_name;
2856 if (!strcmp(
name,
"__Dmain")) {
2858 }
else if (strstr(
name,
"4main") && !strstr(
name,
"STATIC")) {
2860 }
else if (!strcmp(
name,
"_main")) {
2862 }
else if (!strcmp(
name,
"main")) {
2877 for (
i =
bin->dysymtab.iundefsym;
i <
to;
i++) {
2879 if (j > symbols_count) {
2880 bprintf(
"mach0-get-symbols: error\n");
2897 for (
i = 0;
i <
bin->nsymtab;
i++) {
2898 struct MACH0_(nlist) *st = &
bin->symtab[
i];
2903 if (
section == 1 && j < symbols_count) {
2906 sym->
vaddr = st->n_value;
2909 if (st->n_type &
N_EXT) {
2912 sym->
type =
"LOCAL";
2916 sym->
name = sym_name;
2923 if (!strcmp(
name,
"__Dmain")) {
2925 }
else if (strstr(
name,
"4main") && !strstr(
name,
"STATIC")) {
2946 if (j < sym_ctx->symbols_count) {
2961 int j,
s, stridx, symbols_size, symbols_count;
2965 return bin->symbols;
2968 HtPP *hash = ht_pp_new0();
2976 symbols_count = n_exports;
2980 if (
bin->symtab &&
bin->symstr) {
2982 symbols_count = (
bin->dysymtab.nextdefsym +
2983 bin->dysymtab.nlocalsym +
2984 bin->dysymtab.nundefsym);
2985 symbols_count +=
bin->nsymtab;
2986 if (symbols_count < 0 || ((
st64)symbols_count * 2) >
ST32_MAX) {
2987 eprintf(
"Symbols count overflow\n");
2991 symbols_size = (symbols_count + 1) * 2 *
sizeof(
struct symbol_t);
2993 if (symbols_size < 1) {
3002 for (
s = 0;
s < 2;
s++) {
3005 from =
bin->dysymtab.iextdefsym;
3009 from =
bin->dysymtab.ilocalsym;
3014 from =
bin->dysymtab.iundefsym;
3026 ut32 maxsymbols = symbols_size /
sizeof(
struct symbol_t);
3027 if (symbols_count >= maxsymbols) {
3028 symbols_count = maxsymbols - 1;
3029 eprintf(
"macho warning: Symbol table truncated\n");
3031 for (
i =
from;
i <
to && j < symbols_count;
i++, j++) {
3036 symbols[j].is_imported =
false;
3040 stridx =
bin->symtab[
i].n_strx;
3045 if (
bin->main_addr == 0 &&
name) {
3046 if (!strcmp(
name,
"__Dmain")) {
3048 }
else if (strstr(
name,
"4main") && !strstr(
name,
"STATIC")) {
3050 }
else if (!strcmp(
name,
"_main")) {
3052 }
else if (!strcmp(
name,
"main")) {
3064 for (
i =
bin->dysymtab.iundefsym;
i <
to;
i++) {
3065 if (j > symbols_count) {
3066 bprintf(
"mach0-get-symbols: error\n");
3074 for (
i = 0;
i <
bin->nsymtab &&
i < symbols_count;
i++) {
3075 struct MACH0_(nlist) *st = &
bin->symtab[
i];
3076 if (st->n_type &
N_STAB) {
3083 if (
section == 1 && j < symbols_count) {
3086 symbols[j].addr = st->n_value;
3106 if (
bin->main_addr == 0 &&
name) {
3107 if (
name && !strcmp(
name,
"__Dmain")) {
3109 }
else if (
name && strstr(
name,
"4main") && !strstr(
name,
"STATIC")) {
3117 }
else if (!n_exports) {
3121 symbols_size = (symbols_count + 1) *
sizeof(
struct symbol_t);
3122 if (symbols_size < 1) {
3131 if (n_exports && (symbols_count - j) >= n_exports) {
3136 sym_ctx.
hash = hash;
3149 int i, j,
idx, stridx;
3150 if (!
bin->sects || !
bin->symtab || !
bin->symstr || !
bin->indirectsyms) {
3154 if (
bin->dysymtab.nundefsym < 1 ||
bin->dysymtab.nundefsym > 0xfffff) {
3162 for (
i = j = 0;
i <
bin->dysymtab.nundefsym;
i++) {
3163 idx =
bin->dysymtab.iundefsym +
i;
3164 if (idx < 0 || idx >=
bin->nsymtab) {
3165 bprintf(
"WARNING: Imports index out of bounds. Ignoring relocs\n");
3169 stridx =
bin->symtab[
idx].n_strx;
3183 if (!
bin->imports_by_ord_size) {
3185 bin->imports_by_ord_size = j;
3188 bin->imports_by_ord_size = 0;
3213 if (
entry->offset == 0 && !
bin->sects) {
3215 for (
i = 0;
i <
bin->nsects;
i++) {
3217 if (!strncmp(
bin->sects[
i].sectname,
"__text", 6)) {
3222 eprintf(
"entrypoint is 0...\n");
3237 for (
i = 0;
i <
bin->nlibs;
i++) {
3252 for (
i = 0;
i <
bin->nlibs;
i++) {
3269 for (
i = 0;
i <
bin->nsegs;
i++) {
3270 if (
bin->segs[
i].fileoff == 0 &&
bin->segs[
i].filesize != 0) {
3271 return bin->segs[
i].vmaddr;
3314 const int cpu =
bin->hdr.cputype;
3327 case 1:
return "macos";
3328 case 2:
return "ios";
3329 case 3:
return "watchos";
3330 case 4:
return "tvos";
3337 const char *archstr =
"unknown";
3338 switch (hdr->cputype) {
3343 archstr =
"mc680x0";
3350 archstr =
"mc88000";
3353 archstr =
"mc98000";
3377 eprintf(
"Unknown arch %d\n", hdr->cputype);
3390 switch (cpusubtype) {
3404 default:
return "Unknown vax subtype";
3407 switch (cpusubtype) {
3411 default:
return "Unknown mc680x0 subtype";
3414 switch (cpusubtype) {
3434 default:
return "Unknown i386 subtype";
3437 switch (cpusubtype & 0xff) {
3440 default:
return "Unknown x86 subtype";
3443 switch (cpusubtype & 0xff) {
3447 default:
return "Unknown mc88000 subtype";
3450 switch (cpusubtype & 0xff) {
3453 default:
return "Unknown mc98000 subtype";
3456 switch (cpusubtype & 0xff) {
3459 default:
return "Unknown hppa subtype";
3462 switch (cpusubtype & 0xff) {
3466 default:
return "Unknown arm64 subtype";
3469 switch (cpusubtype & 0xff) {
3493 eprintf(
"Unknown arm subtype %d\n", cpusubtype & 0xff);
3494 return "unknown arm subtype";
3497 switch (cpusubtype & 0xff) {
3499 default:
return "Unknown sparc subtype";
3502 switch (cpusubtype & 0xff) {
3511 default:
return "Unknown mips subtype";
3514 switch (cpusubtype & 0xff) {
3517 default:
return "Unknown i860 subtype";
3521 switch (cpusubtype & 0xff) {
3535 default:
return "Unknown ppc subtype";
3538 return "Unknown cputype";
3560 const char *mhtype =
"Unknown";
3561 switch (hdr->filetype) {
3562 case MH_OBJECT: mhtype =
"Relocatable object";
break;
3563 case MH_EXECUTE: mhtype =
"Executable file";
break;
3564 case MH_FVMLIB: mhtype =
"Fixed VM shared library";
break;
3565 case MH_CORE: mhtype =
"Core file";
break;
3566 case MH_PRELOAD: mhtype =
"Preloaded executable file";
break;
3567 case MH_DYLIB: mhtype =
"Dynamically bound shared library";
break;
3568 case MH_DYLINKER: mhtype =
"Dynamic link editor";
break;
3569 case MH_BUNDLE: mhtype =
"Dynamically bound bundle file";
break;
3570 case MH_DYLIB_STUB: mhtype =
"Shared library stub for static linking (no sections)";
break;
3571 case MH_DSYM: mhtype =
"Companion file with only debug sections";
break;
3572 case MH_KEXT_BUNDLE: mhtype =
"Kernel extension bundle file";
break;
3573 case MH_FILESET: mhtype =
"Kernel cache file";
break;
3597 return bin->main_addr;
3619 for (
i = 0;
i < 64;
i++) {
3620 if (
b[
i] == 0xe8 && !
b[
i + 3] && !
b[
i + 4]) {
3621 int delta =
b[
i + 1] | (
b[
i + 2] << 8) | (
b[
i + 3] << 16) | (
b[
i + 4] << 24);
3641 struct MACH0_(mach_header) *mh =
MACH0_(get_hdr)(
buf);
3646 cb_printf(
"pf.mach0_header @ 0x%08" PFMT64x "\n", pvaddr);
3647 cb_printf(
"0x%08" PFMT64x " Magic 0x%x\n", pvaddr, mh->magic);
3649 cb_printf(
"0x%08" PFMT64x " CpuType 0x%x\n", pvaddr, mh->cputype);
3651 cb_printf(
"0x%08" PFMT64x " CpuSubType 0x%x\n", pvaddr, mh->cpusubtype);
3653 cb_printf(
"0x%08" PFMT64x " FileType 0x%x\n", pvaddr, mh->filetype);
3655 cb_printf(
"0x%08" PFMT64x " nCmds %d\n", pvaddr, mh->ncmds);
3657 cb_printf(
"0x%08" PFMT64x " sizeOfCmds %d\n", pvaddr, mh->sizeofcmds);
3659 cb_printf(
"0x%08" PFMT64x " Flags 0x%x\n", pvaddr, mh->flags);
3661 bool is64 = mh->cputype >> 16;
3665 ut8 wordbuf[
sizeof(word)];
3667 switch (mh->cputype) {
3673 #define READWORD() \
3674 if (rz_buf_read_at(buf, addr, (ut8 *)wordbuf, 4) != 4) { \
3675 eprintf("Invalid address in buffer."); \
3680 word = isBe ? rz_read_be32(wordbuf) : rz_read_le32(wordbuf);
3685 for (
n = 0;
n < mh->ncmds;
n++) {
3689 if (pf_definition) {
3690 cb_printf(
"pf.%s @ 0x%08" PFMT64x "\n", pf_definition, pvaddr - 4);
3692 cb_printf(
"0x%08" PFMT64x " cmd %7d 0x%x %s\n",
3700 cb_printf(
"0x%08" PFMT64x " cmdsize %d\n", pvaddr - 4, word);
3702 eprintf(
"Invalid size for a load command\n");
3725 cb_printf(
"0x%08" PFMT64x " minos %d.%d.%d\n", pvaddr + 4, minos1, minos2, minos3);
3739 cb_printf(
"0x%08" PFMT64x " sdk %d.%d.%d\n", pvaddr + 8, sdk1, sdk2, sdk3);
3745 cb_printf(
"0x%08" PFMT64x " ntools %d\n", pvaddr + 12, ntools);
3748 while (
off < (lcSize - 8) && ntools--) {
3749 cb_printf(
"pf.mach0_build_version_tool @ 0x%08" PFMT64x "\n", pvaddr +
off);
3758 if (
off >= (lcSize - 8)) {
3774 cb_printf(
"0x%08" PFMT64x " version %d.%d.%d\n", pvaddr +
off, version1, version2, version3);
3781 ut8 data[64] = { 0 };
3785 cb_printf(
"0x%08" PFMT64x " entry0 0x%" PFMT64x "\n", pvaddr, ep);
3787 cb_printf(
"0x%08" PFMT64x " stacksize 0x%" PFMT64x "\n", pvaddr + 8, ss);
3799 cb_printf (
"0x%08"PFMT64x" id 0x%x\n",
addr + 20,
id?
id:
"");
3800 cb_printf (
"0x%08"PFMT64x" symooff 0x%x\n",
addr + 20,
id?
id:
"");
3801 cb_printf (
"0x%08"PFMT64x" nsyms %d\n",
addr + 20,
id?
id:
"");
3802 cb_printf (
"0x%08"PFMT64x" stroff 0x%x\n",
addr + 20,
id?
id:
"");
3803 cb_printf (
"0x%08"PFMT64x" strsize 0x%x\n",
addr + 20,
id?
id:
"");
3810 if (!rz_buf_read_ble32_at(
buf,
addr, &str_off, isBe)) {
3831 cb_printf(
"0x%08" PFMT64x " current %d.%d.%d\n", pvaddr + 8, current1, current2, current3);
3848 cb_printf(
"0x%08" PFMT64x " compat %d.%d.%d\n", pvaddr + 12, compat1, compat2, compat3);
3850 cb_printf(
"0x%08" PFMT64x " id %s\n",
3851 pvaddr + str_off - 8,
id ?
id :
"");
3858 cb_printf(
"0x%08" PFMT64x " uuid ", pvaddr);
3859 for (
i = 0;
i <
sizeof(uuid);
i++) {
3860 cb_printf(
"%02x", uuid[
i]);
3868 cb_printf(
"0x%08" PFMT64x " name %s\n", pvaddr,
name);
3874 while (
off < lcSize && nsects--) {
3876 cb_printf(
"pf.mach0_section64 @ 0x%08" PFMT64x "\n", pvaddr - 8 +
off);
3879 cb_printf(
"pf.mach0_section @ 0x%08" PFMT64x "\n", pvaddr - 8 +
off);
3887 if (!rz_buf_read_ble32_at(
buf,
addr, &str_off, isBe)) {
3906 cb_printf(
"0x%08" PFMT64x " current %d.%d.%d\n", pvaddr + 8, current1, current2, current3);
3922 cb_printf(
"0x%08" PFMT64x " compat %d.%d.%d\n", pvaddr + 12, compat1, compat2, compat3);
3923 cb_printf(
"0x%08" PFMT64x " load_dylib %s\n",
3924 pvaddr + str_off - 8, load_dylib ? load_dylib :
"");
3930 cb_printf(
"0x%08" PFMT64x " rpath %s\n",
3931 pvaddr + 4, rpath ? rpath :
"");
3941 cb_printf(
"0x%08" PFMT64x " cryptoff 0x%08x\n", pvaddr, word);
3946 cb_printf(
"0x%08" PFMT64x " cryptsize %d\n", pvaddr + 4, word);
3951 cb_printf(
"0x%08" PFMT64x " cryptid %d\n", pvaddr + 8, word);
3957 cb_printf(
"0x%08" PFMT64x " dataoff 0x%08x\n", pvaddr, words[0]);
3958 cb_printf(
"0x%08" PFMT64x " datasize %d\n", pvaddr + 4, words[1]);
3959 cb_printf(
"# wtf mach0.sign %d @ 0x%x\n", words[1], words[0]);
3972 struct MACH0_(mach_header) *mh =
MACH0_(get_hdr)(
buf);
3987 bool is64 = mh->cputype >> 16;
3994 switch (mh->cputype) {
4002 for (
n = 0;
n < mh->ncmds;
n++) {
4004 if (!rz_buf_read_ble32_at(
buf, paddr, &lcType, isBe)) {
4008 if (!rz_buf_read_ble32_at(
buf, paddr + 4, &word, isBe)) {
4011 if (paddr + 8 >
length) {
4017 eprintf(
"Invalid size for a load command\n");
4024 if (pf_definition) {
4035 while (
off < lcSize && ntools--) {
4050 const char *sname = is64 ?
"mach0_section64" :
"mach0_section";
4052 sdb_fmt(
"section_%zu", j++), sname, sname,
true);
4054 off += is64 ? 80 : 68;
4070 ut8 magicbytes[
sizeof(
ut32)] = { 0 };
4071 ut8 machohdrbytes[
sizeof(
struct MACH0_(mach_header))] = { 0 };
4074 bool big_endian =
false;
4107 macho_hdr->magic =
rz_read_ble(&machohdrbytes[0], big_endian, 32);
4108 macho_hdr->cputype =
rz_read_ble(&machohdrbytes[4], big_endian, 32);
4109 macho_hdr->cpusubtype =
rz_read_ble(&machohdrbytes[8], big_endian, 32);
4110 macho_hdr->filetype =
rz_read_ble(&machohdrbytes[12], big_endian, 32);
4111 macho_hdr->ncmds =
rz_read_ble(&machohdrbytes[16], big_endian, 32);
4112 macho_hdr->sizeofcmds =
rz_read_ble(&machohdrbytes[20], big_endian, 32);
4113 macho_hdr->flags =
rz_read_ble(&machohdrbytes[24], big_endian, 32);
4115 macho_hdr->reserved =
rz_read_ble(&machohdrbytes[28], big_endian, 32);
const MCPhysReg * iterator
RZ_API RzBinSection * rz_bin_section_new(const char *name)
RZ_API void rz_bin_symbol_free(RzBinSymbol *sym)
RZ_API void rz_bin_map_free(RzBinMap *map)
RZ_API void rz_bin_field_free(RzBinField *field)
RZ_API void rz_bin_section_free(RzBinSection *bs)
RZ_API RzBinField * rz_bin_field_new(ut64 paddr, ut64 vaddr, int size, const char *name, const char *comment, const char *format, bool format_named)
RZ_API void rz_bin_virtual_file_free(RzBinVirtualFile *vfile)
static RzList * libs(RzBinFile *bf)
static char * entitlements(RzBinFile *bf, bool json)
RzList * symbols(RzBinFile *bf)
RzList * imports(RzBinFile *bf)
RzList * sections(RzBinFile *bf)
int bits(struct state *s, int need)
void rip(char *fname, off_t offset, unsigned int length)
_Use_decl_annotations_ int __cdecl printf(const char *const _Format,...)
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 count
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
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 static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void length
static static fork const void static count static fd link
size_t map(int syms, int left, int len)
RZ_API char * sdb_fmt(const char *fmt,...)
void skip(file *in, unsigned n)
RZ_API void rz_hash_free(RzHash *rh)
RZ_API RzHash * rz_hash_new(void)
RZ_API RZ_OWN ut8 * rz_hash_cfg_calculate_small_block(RZ_NONNULL RzHash *rh, RZ_NONNULL const char *name, RZ_NONNULL const ut8 *buffer, ut64 bsize, RZ_NONNULL RzHashSize *osize)
Returns the digest size of the requested algorithm name.
RZ_API void Ht_() free(HtName_(Ht) *ht)
RZ_API const KEY_TYPE bool * found
return memset(p, 0, total)
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
static const char * page_index
static void list(RzEgg *egg)
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 void * rz_list_get_top(RZ_NONNULL const RzList *list)
Returns the last element of the list.
RZ_API RZ_OWN void * rz_list_pop(RZ_NONNULL RzList *list)
Removes and returns the last element of the list.
RZ_API RZ_OWN RzList * rz_list_new(void)
Returns a new initialized RzList pointer (free method is not initialized)
RZ_API RZ_BORROW RzListIter * rz_list_push(RZ_NONNULL RzList *list, void *item)
Alias for rz_list_append.
RZ_API ut32 rz_list_length(RZ_NONNULL const RzList *list)
Returns the length of the list.
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 * realloc(void *ptr, size_t size)
void * malloc(size_t size)
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")
static const char struct stat static buf struct stat static buf static vhangup int options
#define header(is_bt, len_min, ret_op)
RzList *MACH0_() mach_fields(RzBinFile *bf)
RzList *MACH0_() get_maps_unpatched(RzBinFile *bf)
static const char * build_version_platform_to_string(ut32 platform)
static int walk_exports(struct MACH0_(obj_t) *bin, RExportsIterator iterator, void *ctx)
const char *MACH0_() get_intrp(struct MACH0_(obj_t) *bin)
void(* RExportsIterator)(struct MACH0_(obj_t) *bin, const char *name, ut64 flags, ut64 offset, void *ctx)
RzList *MACH0_() get_maps(RzBinFile *bf)
static int parse_thread(struct MACH0_(obj_t) *bin, struct load_command *lc, ut64 off, bool is_first_thread)
static ut64 pa2va(RzBinFile *bf, ut64 offset)
static bool init(struct MACH0_(obj_t) *mo)
RzList *MACH0_() get_segments(RzBinFile *bf)
static const char * build_version_tool_to_string(ut32 tool)
char *MACH0_() section_type_to_string(ut64 type)
const RzList *MACH0_() get_symbols_list(struct MACH0_(obj_t) *bin)
static bool parse_chained_fixups(struct MACH0_(obj_t) *bin, ut32 offset, ut32 size)
static bool parse_segments(struct MACH0_(obj_t) *bin, ut64 off)
char *MACH0_() get_class(struct MACH0_(obj_t) *bin)
RZ_API RZ_OWN char *MACH0_() get_name(struct MACH0_(obj_t) *mo, ut32 stridx, bool filter)
Get a string from the string table referenced by the LC_SYMTAB command.
static bool __isDataSection(RzBinSection *sect)
static const char * cpusubtype_tostring(ut32 cputype, ut32 cpusubtype)
static bool parse_import_stub(struct MACH0_(obj_t) *bin, struct symbol_t *symbol, int idx)
static bool parse_dysymtab(struct MACH0_(obj_t) *bin, ut64 off)
RzList *MACH0_() section_flag_to_rzlist(ut64 flag)
void MACH0_() mach_headerfields(RzBinFile *bf)
char *MACH0_() get_filetype(struct MACH0_(obj_t) *bin)
static ut64 entry_to_vaddr(struct MACH0_(obj_t) *bin)
void MACH0_() kv_loadlibs(struct MACH0_(obj_t) *bin)
static bool reconstruct_chained_fixup(struct MACH0_(obj_t) *bin)
char *MACH0_() get_filetype_from_hdr(struct MACH0_(mach_header) *hdr)
static bool parse_signature(struct MACH0_(obj_t) *bin, ut64 off)
static void init_sdb_formats(struct MACH0_(obj_t) *bin)
static bool parse_symtab(struct MACH0_(obj_t) *mo, ut64 off)
RZ_API ut64 MACH0_() paddr_to_vaddr(struct MACH0_(obj_t) *bin, ut64 offset)
struct section_t *MACH0_() get_sections(struct MACH0_(obj_t) *bin)
struct lib_t *MACH0_() get_libs(struct MACH0_(obj_t) *bin)
static bool init_hdr(struct MACH0_(obj_t) *bin)
static void parseCodeDirectory(struct MACH0_(obj_t) *mo, RzBuffer *b, int offset, int datasize)
int MACH0_() get_bits_from_hdr(struct MACH0_(mach_header) *hdr)
static int parse_dylib(struct MACH0_(obj_t) *bin, ut64 off)
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)
static int parse_function_starts(struct MACH0_(obj_t) *bin, ut64 off)
static int init_items(struct MACH0_(obj_t) *bin)
static int prot2perm(int x)
static char * readString(ut8 *p, int off, int len)
bool MACH0_() is_big_endian(struct MACH0_(obj_t) *bin)
static void fill_exports_list(struct MACH0_(obj_t) *bin, const char *name, ut64 flags, ut64 offset, void *ctx)
ut64 MACH0_() get_baddr(struct MACH0_(obj_t) *bin)
static const char * cmd_to_pf_definition(ut32 cmd)
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)
RZ_API ut64 MACH0_() vaddr_to_paddr(struct MACH0_(obj_t) *bin, ut64 addr)
struct import_t *MACH0_() get_imports(struct MACH0_(obj_t) *bin)
int MACH0_() get_bits(struct MACH0_(obj_t) *bin)
static const char * cmd_to_string(ut32 cmd)
const char *MACH0_() get_cputype_from_hdr(struct MACH0_(mach_header) *hdr)
char *MACH0_() get_cpusubtype_from_hdr(struct MACH0_(mach_header) *hdr)
const char *MACH0_() get_os(struct MACH0_(obj_t) *bin)
void MACH0_() opts_set_default(struct MACH0_(opts_t) *options, RzBinFile *bf)
static int inSymtab(HtPP *hash, const char *name, ut64 addr)
struct addr_t *MACH0_() get_entrypoint(struct MACH0_(obj_t) *bin)
static void assign_export_symbol_t(struct MACH0_(obj_t) *bin, const char *name, ut64 flags, ut64 offset, void *ctx)
RZ_API ut64 MACH0_() reloc_targets_map_base(RzBinFile *bf, struct MACH0_(obj_t) *obj)
base vaddr where to map the artificial reloc target vfile
#define MACH0_VFILE_NAME_PATCHED
#define CSSLOT_CMS_SIGNATURE
#define CSSLOT_CODEDIRECTORY
RZ_API ut64 MACH0_() reloc_targets_vfile_size(struct MACH0_(obj_t) *obj)
size of the artificial reloc target vfile
#define RZ_BIN_MACH0_STRING_LENGTH
#define CSSLOT_RESOURCEDIR
#define MACH0_VFILE_NAME_REBASED_STRIPPED
#define MACH0_VFILE_NAME_RELOC_TARGETS
#define CSSLOT_APPLICATION
RZ_API RzBuffer *MACH0_() new_rebasing_and_stripping_buf(struct MACH0_(obj_t) *obj)
RZ_API bool MACH0_() needs_rebasing_and_stripping(struct MACH0_(obj_t) *obj)
#define CSSLOT_REQUIREMENTS
RZ_API bool MACH0_() segment_needs_rebasing_and_stripping(struct MACH0_(obj_t) *obj, size_t seg_index)
RZ_API void MACH0_() patch_relocs(RzBinFile *bf, struct MACH0_(obj_t) *obj)
Patching of external relocs in a sparse overlay buffer.
#define CSSLOT_ENTITLEMENTS
@ LC_VERSION_MIN_IPHONEOS
@ LC_LINKER_OPTIMIZATION_HINT
@ S_LITERAL_POINTERS
S_LITERAL_POINTERS - Section with pointers to literals.
@ S_MOD_INIT_FUNC_POINTERS
@ S_CSTRING_LITERALS
S_CSTRING_LITERALS - Section with literal C strings.
@ S_4BYTE_LITERALS
S_4BYTE_LITERALS - Section with 4 byte literals.
@ S_ZEROFILL
S_ZEROFILL - Zero fill on demand section.
@ S_NON_LAZY_SYMBOL_POINTERS
S_NON_LAZY_SYMBOL_POINTERS - Section with non-lazy symbol pointers.
@ S_COALESCED
S_COALESCED - Section contains symbols that are to be coalesced.
@ S_MOD_TERM_FUNC_POINTERS
@ S_LAZY_SYMBOL_POINTERS
S_LAZY_SYMBOL_POINTERS - Section with lazy symbol pointers.
@ S_REGULAR
S_REGULAR - Regular section.
@ CPU_SUBTYPE_MC68030_ONLY
@ S_ATTR_SOME_INSTRUCTIONS
S_ATTR_SOME_INSTRUCTIONS - Section contains some machine instructions.
@ S_ATTR_STRIP_STATIC_SYMS
@ S_ATTR_EXT_RELOC
S_ATTR_EXT_RELOC - Section has external relocation entries.
@ S_ATTR_DEBUG
S_ATTR_DEBUG - A debug section.
@ S_ATTR_LIVE_SUPPORT
S_ATTR_LIVE_SUPPORT - Blocks are live if they reference live blocks.
@ S_ATTR_NO_DEAD_STRIP
S_ATTR_NO_DEAD_STRIP - No dead stripping.
@ S_ATTR_PURE_INSTRUCTIONS
@ S_ATTR_SELF_MODIFYING_CODE
@ EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER
@ EXPORT_SYMBOL_FLAGS_REEXPORT
@ CPU_SUBTYPE_HPPA_7100LC
@ BIND_SUBOPCODE_THREADED_SET_BIND_ORDINAL_TABLE_SIZE_ULEB
@ BIND_SUBOPCODE_THREADED_APPLY
@ BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB
@ BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED
@ BIND_OPCODE_SET_DYLIB_SPECIAL_IMM
@ BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB
@ BIND_OPCODE_ADD_ADDR_ULEB
@ BIND_OPCODE_SET_TYPE_IMM
@ BIND_OPCODE_SET_DYLIB_ORDINAL_IMM
@ BIND_OPCODE_SET_ADDEND_SLEB
@ BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB
@ BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM
@ BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB
@ CPU_SUBTYPE_MC88000_ALL
@ CPU_SUBTYPE_PENTIUM_3_XEON
@ CPU_SUBTYPE_PENTIUM_3_M
@ CPU_SUBTYPE_PENTIUM_4_M
@ CPU_SUBTYPE_CELERON_MOBILE
@ DYLD_CHAINED_PTR_ARM64E
@ CPU_SUBTYPE_POWERPC_604e
@ CPU_SUBTYPE_POWERPC_601
@ CPU_SUBTYPE_POWERPC_ALL
@ CPU_SUBTYPE_POWERPC_603e
@ CPU_SUBTYPE_POWERPC_970
@ CPU_SUBTYPE_POWERPC_603ev
@ CPU_SUBTYPE_POWERPC_7400
@ CPU_SUBTYPE_POWERPC_620
@ CPU_SUBTYPE_POWERPC_7450
@ CPU_SUBTYPE_POWERPC_603
@ CPU_SUBTYPE_POWERPC_602
@ CPU_SUBTYPE_POWERPC_604
@ CPU_SUBTYPE_MC98000_ALL
@ CPU_SUBTYPE_POWERPC_750
@ CPU_SUBTYPE_MIPS_R2000a
@ CPU_SUBTYPE_MIPS_R3000a
#define RZ_BIN_MACH0_SYMBOL_TYPE_EXT
#define RZ_BIN_MACH0_SYMBOL_TYPE_LOCAL
#define X86_THREAD_STATE64
#define X86_THREAD_STATE32
RZ_API int sdb_num_set(Sdb *s, const char *key, ut64 v, ut32 cas)
RZ_API ut64 sdb_num_get(Sdb *s, const char *key, ut32 *cas)
static bool filter(RzParse *p, ut64 addr, RzFlag *f, RzAnalysisHint *hint, char *data, char *str, int len, bool big_endian)
RZ_API void rz_bin_relocs_patch_maps(RZ_NONNULL RzList *maps, RZ_NULLABLE RzBuffer *buf_patched, ut64 buf_patched_offset, ut64 target_vfile_base, ut64 target_vfile_size, RZ_NONNULL const char *vfile_name_patched, RZ_NONNULL const char *vfile_name_reloc_targets)
Change file-mapped maps to the patched vfile if covered by the buffer and add the reloc target map.
#define rz_return_if_fail(expr)
#define rz_return_val_if_fail(expr, val)
#define RZ_BIN_BIND_GLOBAL_STR
#define rz_buf_read_le16_at(b, addr, result)
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 bool rz_buf_read8_at(RzBuffer *b, ut64 addr, RZ_NONNULL RZ_OUT ut8 *result)
Read a byte at the specified address in 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.
RZ_API RZ_OWN RzBuffer * rz_buf_new_empty(ut64 len)
Creates a new empty buffer with a predefined size;.
RZ_API ut64 rz_buf_size(RZ_NONNULL RzBuffer *b)
Return the size of the buffer.
static ut64 rz_read_ble64(const void *src, bool big_endian)
static ut8 rz_read_ble8(const void *src)
static ut64 rz_read_be64(const void *src)
static ut32 rz_read_le32(const void *src)
static ut32 rz_read_ble32(const void *src, bool big_endian)
static ut16 rz_read_ble16(const void *src, bool big_endian)
static ut64 rz_read_ble(const void *src, bool big_endian, int size)
static ut32 rz_read_be32(const void *src)
static int UT32_MUL(ut32 *r, ut32 a, ut32 b)
RZ_API int rz_hex_bin2str(const ut8 *in, int len, char *out)
void(* RzListFree)(void *ptr)
#define RZ_LOG_ERROR(fmtstr,...)
RZ_API void rz_skiplist_free(RzSkipList *list)
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
RZ_API char * rz_str_append(char *ptr, const char *string)
RZ_API char * rz_str_ndup(RZ_NULLABLE const char *ptr, int len)
Create new copy of string ptr limited to size len.
RZ_API char * rz_str_new(const char *str)
RZ_API size_t rz_str_ncpy(char *dst, const char *src, size_t n)
Secure string copy with null terminator.
RZ_API void rz_str_filter(char *str)
Convert all non-printable characters in str with '.'.
#define rz_strf(buf,...)
Convenience macro for local temporary strings.
RZ_API char * rz_sys_getenv(const char *key)
Get the value of an environment variable named key or NULL if none exists.
int(* PrintfCallback)(const char *str,...) RZ_PRINTF_CHECK(1
#define rz_offsetof(type, member)
RZ_API st64 rz_sleb128(const ut8 **data, const ut8 *end)
RZ_API void rz_pvector_free(RzPVector *vec)
RZ_API Sdb * sdb_new(const char *path, const char *name, int lock)
RZ_API int sdb_set(Sdb *s, const char *key, const char *val, ut32 cas)
static struct sockaddr static addrlen static backlog const void static flags void struct sockaddr from
static struct sockaddr static addrlen static backlog const void static flags void struct sockaddr socklen_t static fromlen const void const struct sockaddr to
static struct sockaddr static addrlen static backlog const void static flags void flags
#define tr(opcode, mask, lose, flags)
struct symbol_t * symbols
uint32_t compatibility_version
XX curplugin == o->plugin.
Description of a single memory mapping into virtual memory from a binary.
RZ_NONNULL RzBuffer * buf
bool buf_owned
whether buf is owned and freed by this RzBinVirtualFile
RZ_OWN RZ_NONNULL char * name
void error(const char *msg)
if(dbg->bits==RZ_SYS_BITS_64)
ut64(WINAPI *w32_GetEnabledXStateFeatures)()