mirror of
https://github.com/rizinorg/rizin
synced 2026-08-22 20:26:16 -04:00
Fix SPARC/MC680x0 Mach-O fat binary issues (#5338)
* Add thread_state register layouts for Mac-O Sparc and MC680x0 binaries. * Prevent hitting assert by passing NULL in some cases. If name is not a valid arch identifier, it should complain later. * Switch to m68k name, to match the asm.arch plugin name. * Don't ignore endianess of fat Mach-O binaries. And if it isn't ignored check for actual endianess, not for being a PPC binary. * Add `obs` command to select the different versions of fat binaries. * Fix import tests of mach-o * Properly rest xtr_data->loaded * Update doxygen and remove RZ_DEPRECATED flag
This commit is contained in:
parent
eefb34bcd5
commit
cb3e09aa4e
26 changed files with 738 additions and 241 deletions
|
|
@ -728,52 +728,52 @@ static char *get_reg_profile(RzAnalysis *analysis) {
|
|||
"=A1 a1\n"
|
||||
"=A2 a2\n"
|
||||
"=A3 a3\n"
|
||||
"gpr d0 .32 0 0\n"
|
||||
"gpr d1 .32 4 0\n"
|
||||
"gpr d2 .32 8 0\n"
|
||||
"gpr d3 .32 12 0\n"
|
||||
"gpr d4 .32 16 0\n"
|
||||
"gpr d5 .32 20 0\n"
|
||||
"gpr d6 .32 24 0\n"
|
||||
"gpr d7 .32 28 0\n"
|
||||
"gpr a0 .32 32 0\n"
|
||||
"gpr a1 .32 36 0\n"
|
||||
"gpr a2 .32 40 0\n"
|
||||
"gpr a3 .32 44 0\n"
|
||||
"gpr a4 .32 48 0\n"
|
||||
"gpr a5 .32 52 0\n"
|
||||
"gpr a6 .32 56 0\n"
|
||||
"gpr a7 .32 60 0\n"
|
||||
"gpr fp0 .32 64 0\n" // FPU register 0, 96bits to write and read max
|
||||
"gpr fp1 .32 68 0\n" // FPU register 1, 96bits to write and read max
|
||||
"gpr fp2 .32 72 0\n" // FPU register 2, 96bits to write and read max
|
||||
"gpr fp3 .32 76 0\n" // FPU register 3, 96bits to write and read max
|
||||
"gpr fp4 .32 80 0\n" // FPU register 4, 96bits to write and read max
|
||||
"gpr fp5 .32 84 0\n" // FPU register 5, 96bits to write and read max
|
||||
"gpr fp6 .32 88 0\n" // FPU register 6, 96bits to write and read max
|
||||
"gpr fp7 .32 92 0\n" // FPU register 7, 96bits to write and read max
|
||||
"gpr pc .32 96 0\n"
|
||||
"gpr sr .32 100 0\n" // only available for read and write access during supervisor mode 16bit
|
||||
"gpr ccr .32 104 0\n" // subset of the SR, available from any mode
|
||||
"gpr sfc .32 108 0\n" // source function code register
|
||||
"gpr dfc .32 112 0\n" // destination function code register
|
||||
"gpr usp .32 116 0\n" // user stack point this is an shadow register of A7 user mode, SR bit 0xD is 0
|
||||
"gpr vbr .32 120 0\n" // vector base register, this is a Address pointer
|
||||
"gpr cacr .32 124 0\n" // cache control register, implementation specific
|
||||
"gpr caar .32 128 0\n" // cache address register, 68020, 68EC020, 68030 and 68EC030 only.
|
||||
"gpr msp .32 132 0\n" // master stack pointer, this is an shadow register of A7 supervisor mode, SR bits 0xD && 0xC are set
|
||||
"gpr isp .32 136 0\n" // interrupt stack pointer, this is an shadow register of A7 supervisor mode, SR bit 0xD is set, 0xC is not.
|
||||
"gpr tc .32 140 0\n"
|
||||
"gpr itt0 .32 144 0\n" // in 68EC040 this is IACR0
|
||||
"gpr itt1 .32 148 0\n" // in 68EC040 this is IACR1
|
||||
"gpr dtt0 .32 156 0\n" // in 68EC040 this is DACR0
|
||||
"gpr dtt1 .32 160 0\n" // in 68EC040 this is DACR1
|
||||
"gpr mmusr .32 164 0\n"
|
||||
"gpr urp .32 168 0\n"
|
||||
"gpr srp .32 172 0\n"
|
||||
"gpr fpcr .32 176 0\n"
|
||||
"gpr fpsr .32 180 0\n"
|
||||
"gpr fpiar .32 184 0\n";
|
||||
"gpr d0 .32 0 0\n"
|
||||
"gpr d1 .32 4 0\n"
|
||||
"gpr d2 .32 8 0\n"
|
||||
"gpr d3 .32 12 0\n"
|
||||
"gpr d4 .32 16 0\n"
|
||||
"gpr d5 .32 20 0\n"
|
||||
"gpr d6 .32 24 0\n"
|
||||
"gpr d7 .32 28 0\n"
|
||||
"gpr a0 .32 32 0\n"
|
||||
"gpr a1 .32 36 0\n"
|
||||
"gpr a2 .32 40 0\n"
|
||||
"gpr a3 .32 44 0\n"
|
||||
"gpr a4 .32 48 0\n"
|
||||
"gpr a5 .32 52 0\n"
|
||||
"gpr a6 .32 56 0\n"
|
||||
"gpr a7 .32 60 0\n"
|
||||
"gpr pc .32 64 0\n"
|
||||
"gpr ccr .8 68 0\n" // subset of the SR, available from any mode
|
||||
"gpr fp0 .32 69 0\n" // FPU register 0, 96bits to write and read max
|
||||
"gpr fp1 .32 73 0\n" // FPU register 1, 96bits to write and read max
|
||||
"gpr fp2 .32 77 0\n" // FPU register 2, 96bits to write and read max
|
||||
"gpr fp3 .32 81 0\n" // FPU register 3, 96bits to write and read max
|
||||
"gpr fp4 .32 85 0\n" // FPU register 4, 96bits to write and read max
|
||||
"gpr fp5 .32 89 0\n" // FPU register 5, 96bits to write and read max
|
||||
"gpr fp6 .32 93 0\n" // FPU register 6, 96bits to write and read max
|
||||
"gpr fp7 .32 97 0\n" // FPU register 7, 96bits to write and read max
|
||||
"gpr fpcr .32 101 0\n"
|
||||
"gpr fpsr .32 105 0\n"
|
||||
"gpr fpiar .32 109 0\n"
|
||||
"gpr sr .32 113 0\n" // only available for read and write access during supervisor mode 16bit
|
||||
"gpr sfc .32 117 0\n" // source function code register
|
||||
"gpr dfc .32 121 0\n" // destination function code register
|
||||
"gpr usp .32 125 0\n" // user stack point this is an shadow register of A7 user mode, SR bit 0xD is 0
|
||||
"gpr vbr .32 129 0\n" // vector base register, this is a Address pointer
|
||||
"gpr cacr .32 133 0\n" // cache control register, implementation specific
|
||||
"gpr caar .32 137 0\n" // cache address register, 68020, 68EC020, 68030 and 68EC030 only.
|
||||
"gpr msp .32 141 0\n" // master stack pointer, this is an shadow register of A7 supervisor mode, SR bits 0xD && 0xC are set
|
||||
"gpr isp .32 145 0\n" // interrupt stack pointer, this is an shadow register of A7 supervisor mode, SR bit 0xD is set, 0xC is not.
|
||||
"gpr tc .32 149 0\n"
|
||||
"gpr itt0 .32 153 0\n" // in 68EC040 this is IACR0
|
||||
"gpr itt1 .32 157 0\n" // in 68EC040 this is IACR1
|
||||
"gpr dtt0 .32 161 0\n" // in 68EC040 this is DACR0
|
||||
"gpr dtt1 .32 165 0\n" // in 68EC040 this is DACR1
|
||||
"gpr mmusr .32 169 0\n"
|
||||
"gpr urp .32 173 0\n"
|
||||
"gpr srp .32 177 0\n";
|
||||
return rz_str_dup(p);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -80,8 +80,48 @@ static RzBinPlugin *get_plugin_from_buffer(RzBin *bin, const char *pluginname, R
|
|||
return rz_bin_get_binplugin_by_name(bin, "any");
|
||||
}
|
||||
|
||||
RZ_API bool rz_bin_file_object_new_from_xtr_data(RzBin *bin, RzBinFile *bf, RzBinObjectLoadOptions *opts, RzBinXtrData *data) {
|
||||
rz_return_val_if_fail(bin && bf && data, false);
|
||||
static inline void mark_all_xtr_as_unloaded(RzBin *bin) {
|
||||
RzListIter *iter;
|
||||
RzBinFile *binfile = NULL;
|
||||
rz_list_foreach (bin->binfiles, iter, binfile) {
|
||||
if (!binfile->xtr_data) {
|
||||
continue;
|
||||
}
|
||||
RzBinXtrData *xtr_data;
|
||||
RzListIter *iter_xtr;
|
||||
rz_list_foreach (binfile->xtr_data, iter_xtr, xtr_data) {
|
||||
xtr_data->loaded = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Updates the current active object of the binfile \p bf
|
||||
* with the RzBinXtrData \p data.
|
||||
* It creates a new RzBinObj instance according to \p data
|
||||
* and loads it as current object.
|
||||
*
|
||||
* NOTE: It will mark all other RzBinXtrData insances in all RzBinFiles
|
||||
* as unloaded. This is a required side effect of Rizin only supporting
|
||||
* one active object at a time.
|
||||
* NOTE: \p data must be an element from the bf->xtr_data list.
|
||||
* Otherwise the result is undefined.
|
||||
*
|
||||
* \param bin The current RzBin isntance.
|
||||
* \param bf The RzBinFile to update.
|
||||
* \param opts Loading options for the new object.
|
||||
* \param data The RzBinXtrData to load.
|
||||
*
|
||||
* \return True if the loading was successful. False otherwise.
|
||||
*/
|
||||
RZ_API bool rz_bin_file_set_xtr_data_as_current_obj(
|
||||
RZ_BORROW RZ_NONNULL RzBin *bin,
|
||||
RZ_BORROW RZ_NONNULL RzBinFile *bf,
|
||||
RZ_BORROW RZ_NONNULL RzBinObjectLoadOptions *opts,
|
||||
RZ_BORROW RZ_NONNULL RzBinXtrData *data) {
|
||||
rz_return_val_if_fail(bin && bf && data && opts, false);
|
||||
|
||||
mark_all_xtr_as_unloaded(bin);
|
||||
|
||||
ut64 offset = data->offset;
|
||||
ut64 sz = data->size;
|
||||
|
|
@ -111,18 +151,19 @@ RZ_API bool rz_bin_file_object_new_from_xtr_data(RzBin *bin, RzBinFile *bf, RzBi
|
|||
o->info->machine = rz_str_dup(data->metadata->machine);
|
||||
o->info->type = rz_str_dup(data->metadata->type);
|
||||
o->info->bits = data->metadata->bits;
|
||||
o->info->big_endian = data->metadata->big_endian;
|
||||
o->info->has_crypto = bf->o->info->has_crypto;
|
||||
data->loaded = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool xtr_metadata_match(RzBinXtrData *xtr_data, const char *arch, int bits) {
|
||||
static bool xtr_metadata_match(RzBinXtrData *xtr_data, const char *arch, int bits, RZ_NULLABLE const char *machine) {
|
||||
if (!xtr_data->metadata || !xtr_data->metadata->arch) {
|
||||
return false;
|
||||
}
|
||||
const char *iter_arch = xtr_data->metadata->arch;
|
||||
int iter_bits = xtr_data->metadata->bits;
|
||||
return bits == iter_bits && !strcmp(iter_arch, arch) && !xtr_data->loaded;
|
||||
return bits == iter_bits && !strcmp(iter_arch, arch) && (!machine || RZ_STR_EQ(machine, xtr_data->metadata->machine)) && !xtr_data->loaded;
|
||||
}
|
||||
|
||||
RZ_IPI RzBinFile *rz_bin_file_new_from_buffer(RzBin *bin, const char *file, RzBuffer *buf, RzBinObjectLoadOptions *opts, int fd, const char *pluginname) {
|
||||
|
|
@ -149,7 +190,17 @@ RZ_IPI RzBinFile *rz_bin_file_new_from_buffer(RzBin *bin, const char *file, RzBu
|
|||
return bf;
|
||||
}
|
||||
|
||||
RZ_API RzBinFile *rz_bin_file_find_by_arch_bits(RzBin *bin, const char *arch, int bits) {
|
||||
/**
|
||||
* \brief Search the matching binary file for \p arch \p bits and \p machine (optional).
|
||||
*
|
||||
* \param bin The current RzBin instance.
|
||||
* \param arch The architecture of the binary file.
|
||||
* \param bits The architecture bits of the binary file.
|
||||
* \param machine (Optional) The machine the binary file is for.
|
||||
*
|
||||
* \return The binary file or NULL if no matching exists.
|
||||
*/
|
||||
RZ_API RZ_BORROW RzBinFile *rz_bin_file_find_by_arch_bits(RzBin *bin, const char *arch, int bits, RZ_NULLABLE const char *machine, RZ_NULLABLE const char *filename) {
|
||||
RzListIter *iter;
|
||||
RzBinFile *binfile = NULL;
|
||||
RzBinXtrData *xtr_data;
|
||||
|
|
@ -163,8 +214,8 @@ RZ_API RzBinFile *rz_bin_file_find_by_arch_bits(RzBin *bin, const char *arch, in
|
|||
}
|
||||
// look for sub-bins in Xtr Data and Load if we need to
|
||||
rz_list_foreach (binfile->xtr_data, iter_xtr, xtr_data) {
|
||||
if (xtr_metadata_match(xtr_data, arch, bits)) {
|
||||
if (!rz_bin_file_object_new_from_xtr_data(bin, binfile, &xtr_data->obj_opts, xtr_data)) {
|
||||
if (xtr_metadata_match(xtr_data, arch, bits, machine)) {
|
||||
if (!rz_bin_file_set_xtr_data_as_current_obj(bin, binfile, &xtr_data->obj_opts, xtr_data)) {
|
||||
return NULL;
|
||||
}
|
||||
return binfile;
|
||||
|
|
|
|||
|
|
@ -822,16 +822,27 @@ trashbin:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
RZ_API bool rz_bin_use_arch(RzBin *bin, const char *arch, int bits, const char *name) {
|
||||
/**
|
||||
* \brief Sets the object file matching the \p arch, \p bits and optionally the \p machine and \p filename.
|
||||
*
|
||||
* \param bin The current RzBin instance.
|
||||
* \param arch The architecture of the binary file.
|
||||
* \param bits The architecture bits of the binary file.
|
||||
* \param machine (Optional) The machine of the binary file.
|
||||
* \param filename (Optional) The filename of the RzBinFile to load. Can be NULL.
|
||||
*
|
||||
* \return True if the binary file was successfully set according to the parameters. False otherwise.
|
||||
*/
|
||||
RZ_API bool rz_bin_use_arch(RzBin *bin, const char *arch, int bits, RZ_NULLABLE const char *machine, RZ_NULLABLE const char *filename) {
|
||||
rz_return_val_if_fail(bin && arch, false);
|
||||
|
||||
RzBinFile *binfile = rz_bin_file_find_by_arch_bits(bin, arch, bits);
|
||||
RzBinFile *binfile = rz_bin_file_find_by_arch_bits(bin, arch, bits, machine, filename);
|
||||
if (!binfile) {
|
||||
RZ_LOG_WARN("Cannot find binfile with arch/bits %s/%d\n", arch, bits);
|
||||
return false;
|
||||
}
|
||||
|
||||
RzBinObject *obj = rz_bin_object_find_by_arch_bits(binfile, arch, bits, name);
|
||||
RzBinObject *obj = rz_bin_object_find_by_arch_bits(binfile, arch, bits, machine, filename);
|
||||
if (!obj && binfile->xtr_data) {
|
||||
RzBinXtrData *xtr_data = rz_list_get_n(binfile->xtr_data, 0);
|
||||
if (xtr_data && !xtr_data->loaded) {
|
||||
|
|
@ -839,7 +850,7 @@ RZ_API bool rz_bin_use_arch(RzBin *bin, const char *arch, int bits, const char *
|
|||
.baseaddr = UT64_MAX,
|
||||
.loadaddr = rz_bin_get_laddr(bin)
|
||||
};
|
||||
if (!rz_bin_file_object_new_from_xtr_data(bin, binfile, &obj_opts, xtr_data)) {
|
||||
if (!rz_bin_file_set_xtr_data_as_current_obj(bin, binfile, &obj_opts, xtr_data)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -851,15 +862,25 @@ RZ_API bool rz_bin_use_arch(RzBin *bin, const char *arch, int bits, const char *
|
|||
return rz_bin_set_cur_binfile(bin, binfile);
|
||||
}
|
||||
|
||||
RZ_API bool rz_bin_select(RzBin *bin, const char *arch, int bits, const char *name) {
|
||||
rz_return_val_if_fail(bin, false);
|
||||
/**
|
||||
* \brief Selects the binfile matching \p arch, \p bits and optionally \p machine
|
||||
* and \p filename and sets it as current binfile in RzBin.
|
||||
*
|
||||
* \param bin The current RzBin instance.
|
||||
* \param arch The architecture of the binary file.
|
||||
* \param bits The architecture bits of the binary file.
|
||||
* \param machine (Optional) The machine of the binary file.
|
||||
* \param filename (Optional) The filename of RzBinFile to load.
|
||||
*
|
||||
* \return True if the binary file was successfully set according to the parameters. False otherwise.
|
||||
*/
|
||||
RZ_API bool rz_bin_select(RzBin *bin, RZ_NONNULL const char *arch, int bits, RZ_NULLABLE const char *machine, RZ_NULLABLE const char *filename) {
|
||||
rz_return_val_if_fail(bin && arch, false);
|
||||
|
||||
RzBinFile *cur = rz_bin_cur(bin);
|
||||
RzBinObject *obj = NULL;
|
||||
name = !name && cur ? cur->file : name;
|
||||
RzBinFile *binfile = rz_bin_file_find_by_arch_bits(bin, arch, bits);
|
||||
if (binfile && name) {
|
||||
obj = rz_bin_object_find_by_arch_bits(binfile, arch, bits, name);
|
||||
RzBinFile *binfile = rz_bin_file_find_by_arch_bits(bin, arch, bits, machine, filename);
|
||||
if (binfile) {
|
||||
obj = rz_bin_object_find_by_arch_bits(binfile, arch, bits, machine, filename);
|
||||
}
|
||||
if (!rz_bin_file_set_obj(binfile, obj)) {
|
||||
return NULL;
|
||||
|
|
|
|||
|
|
@ -598,14 +598,15 @@ RZ_IPI RzBinObject *rz_bin_object_get_cur(RzBin *bin) {
|
|||
return bin->cur->o;
|
||||
}
|
||||
|
||||
RZ_IPI RzBinObject *rz_bin_object_find_by_arch_bits(RzBinFile *bf, const char *arch, int bits, const char *name) {
|
||||
rz_return_val_if_fail(bf && arch && name, NULL);
|
||||
RZ_IPI RzBinObject *rz_bin_object_find_by_arch_bits(RzBinFile *bf, RZ_NONNULL const char *arch, int bits, RZ_NULLABLE const char *machine, RZ_NULLABLE const char *filename) {
|
||||
rz_return_val_if_fail(bf && arch, NULL);
|
||||
if (bf->o) {
|
||||
RzBinInfo *info = bf->o->info;
|
||||
if (info && info->arch && info->file &&
|
||||
(bits == info->bits) &&
|
||||
!strcmp(info->arch, arch) &&
|
||||
!strcmp(info->file, name)) {
|
||||
(!filename || RZ_STR_EQ(info->file, filename)) &&
|
||||
(!machine || RZ_STR_EQ(info->machine, machine))) {
|
||||
return bf->o;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1070,8 +1070,36 @@ static int parse_thread(struct MACH0_(obj_t) * bin, struct load_command *lc, ut6
|
|||
arw_ptr = (ut8 *)&bin->thread_state.arm_64;
|
||||
arw_sz = sizeof(struct arm_thread_state64);
|
||||
break;
|
||||
case CPU_TYPE_MC680x0:
|
||||
if (ptr_thread + sizeof(struct mc680x0_thread_state) > bin->size) {
|
||||
return false;
|
||||
}
|
||||
if (rz_buf_fread_at(bin->b, ptr_thread,
|
||||
(ut8 *)&bin->thread_state.mc680x0, bin->big_endian ? "17I1c" : "17i1c", 1) == -1) {
|
||||
RZ_LOG_ERROR("read thread state mc680x064\n");
|
||||
return false;
|
||||
}
|
||||
pc = bin->thread_state.mc680x0.pc;
|
||||
pc_offset = ptr_thread + rz_offsetof(struct mc680x0_thread_state, pc);
|
||||
arw_ptr = (ut8 *)&bin->thread_state.mc680x0;
|
||||
arw_sz = sizeof(struct mc680x0_thread_state);
|
||||
break;
|
||||
case CPU_TYPE_SPARC:
|
||||
if (ptr_thread + sizeof(struct sparc_thread_state64) > bin->size) {
|
||||
return false;
|
||||
}
|
||||
if (rz_buf_fread_at(bin->b, ptr_thread,
|
||||
(ut8 *)&bin->thread_state.sparc_64, bin->big_endian ? "36L" : "36l", 1) == -1) {
|
||||
RZ_LOG_ERROR("read thread state sparc64\n");
|
||||
return false;
|
||||
}
|
||||
pc = bin->thread_state.sparc_64.tpc;
|
||||
pc_offset = ptr_thread + rz_offsetof(struct sparc_thread_state64, tpc);
|
||||
arw_ptr = (ut8 *)&bin->thread_state.sparc_64;
|
||||
arw_sz = sizeof(struct sparc_thread_state64);
|
||||
break;
|
||||
default:
|
||||
RZ_LOG_ERROR("unknown thread state structure\n");
|
||||
RZ_LOG_ERROR("unknown thread state structure %" PFMT32u "\n", bin->hdr.cputype);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -2845,12 +2873,11 @@ int MACH0_(get_bits_from_hdr)(struct MACH0_(mach_header) * hdr) {
|
|||
return 32;
|
||||
}
|
||||
|
||||
bool MACH0_(is_big_endian)(struct MACH0_(obj_t) * bin) {
|
||||
if (bin) {
|
||||
const int cpu = bin->hdr.cputype;
|
||||
return cpu == CPU_TYPE_POWERPC || cpu == CPU_TYPE_POWERPC64;
|
||||
}
|
||||
return false;
|
||||
bool MACH0_(is_big_endian)(RZ_NONNULL RzBuffer *buf) {
|
||||
rz_return_val_if_fail(buf, false);
|
||||
bool big_endian;
|
||||
free(MACH0_(get_hdr)(buf, &big_endian));
|
||||
return big_endian;
|
||||
}
|
||||
|
||||
const char *MACH0_(get_intrp)(struct MACH0_(obj_t) * bin) {
|
||||
|
|
@ -2967,7 +2994,8 @@ void MACH0_(mach_headerfields)(RzBinFile *bf) {
|
|||
RzBuffer *buf = bf->buf;
|
||||
ut64 length = rz_buf_size(buf);
|
||||
int n = 0;
|
||||
struct MACH0_(mach_header) *mh = MACH0_(get_hdr)(buf);
|
||||
bool big_endian;
|
||||
struct MACH0_(mach_header) *mh = MACH0_(get_hdr)(buf, &big_endian);
|
||||
if (!mh) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -2992,13 +3020,6 @@ void MACH0_(mach_headerfields)(RzBinFile *bf) {
|
|||
ut64 addr = 0x20 - 4;
|
||||
ut32 word = 0;
|
||||
ut8 wordbuf[sizeof(word)];
|
||||
bool isBe = false;
|
||||
switch (mh->cputype) {
|
||||
case CPU_TYPE_POWERPC:
|
||||
case CPU_TYPE_POWERPC64:
|
||||
isBe = true;
|
||||
break;
|
||||
}
|
||||
#define READWORD() \
|
||||
if (rz_buf_read_at(buf, addr, (ut8 *)wordbuf, 4) != 4) { \
|
||||
eprintf("Invalid address in buffer."); \
|
||||
|
|
@ -3006,7 +3027,7 @@ void MACH0_(mach_headerfields)(RzBinFile *bf) {
|
|||
} \
|
||||
addr += 4; \
|
||||
pvaddr += 4; \
|
||||
word = isBe ? rz_read_be32(wordbuf) : rz_read_le32(wordbuf);
|
||||
word = rz_read_ble32(wordbuf, big_endian);
|
||||
|
||||
if (is64) {
|
||||
addr += 4;
|
||||
|
|
@ -3035,13 +3056,13 @@ void MACH0_(mach_headerfields)(RzBinFile *bf) {
|
|||
switch (lcType) {
|
||||
case LC_BUILD_VERSION: {
|
||||
ut32 platform;
|
||||
if (!rz_buf_read_le32_at(buf, addr, &platform)) {
|
||||
if (!rz_buf_read_ble32_at(buf, addr, &platform, big_endian)) {
|
||||
break;
|
||||
}
|
||||
cb_printf("0x%08" PFMT64x " platform %s\n", pvaddr, rz_mach0_platform_to_string(platform));
|
||||
|
||||
ut16 minos1;
|
||||
if (!rz_buf_read_le16_at(buf, addr + 6, &minos1)) {
|
||||
if (!rz_buf_read_ble16_at(buf, addr + 6, &minos1, big_endian)) {
|
||||
break;
|
||||
}
|
||||
ut8 minos2;
|
||||
|
|
@ -3055,7 +3076,7 @@ void MACH0_(mach_headerfields)(RzBinFile *bf) {
|
|||
cb_printf("0x%08" PFMT64x " minos %d.%d.%d\n", pvaddr + 4, minos1, minos2, minos3);
|
||||
|
||||
ut16 sdk1;
|
||||
if (!rz_buf_read_le16_at(buf, addr + 10, &sdk1)) {
|
||||
if (!rz_buf_read_ble16_at(buf, addr + 10, &sdk1, big_endian)) {
|
||||
break;
|
||||
}
|
||||
ut8 sdk2;
|
||||
|
|
@ -3069,7 +3090,7 @@ void MACH0_(mach_headerfields)(RzBinFile *bf) {
|
|||
cb_printf("0x%08" PFMT64x " sdk %d.%d.%d\n", pvaddr + 8, sdk1, sdk2, sdk3);
|
||||
|
||||
ut32 ntools;
|
||||
if (!rz_buf_read_le32_at(buf, addr + 12, &ntools)) {
|
||||
if (!rz_buf_read_ble32_at(buf, addr + 12, &ntools, big_endian)) {
|
||||
break;
|
||||
}
|
||||
cb_printf("0x%08" PFMT64x " ntools %d\n", pvaddr + 12, ntools);
|
||||
|
|
@ -3079,7 +3100,7 @@ void MACH0_(mach_headerfields)(RzBinFile *bf) {
|
|||
cb_printf("pf.mach0_build_version_tool @ 0x%08" PFMT64x "\n", pvaddr + off);
|
||||
|
||||
ut32 tool;
|
||||
if (!rz_buf_read_le32_at(buf, addr + off, &tool)) {
|
||||
if (!rz_buf_read_ble32_at(buf, addr + off, &tool, big_endian)) {
|
||||
break;
|
||||
}
|
||||
cb_printf("0x%08" PFMT64x " tool %s\n", pvaddr + off, rz_mach0_build_version_tool_to_string(tool));
|
||||
|
|
@ -3090,7 +3111,7 @@ void MACH0_(mach_headerfields)(RzBinFile *bf) {
|
|||
}
|
||||
|
||||
ut16 version1;
|
||||
if (!rz_buf_read_le16_at(buf, addr + off + 2, &version1)) {
|
||||
if (!rz_buf_read_ble16_at(buf, addr + off + 2, &version1, big_endian)) {
|
||||
break;
|
||||
}
|
||||
ut8 version2;
|
||||
|
|
@ -3111,14 +3132,14 @@ void MACH0_(mach_headerfields)(RzBinFile *bf) {
|
|||
ut8 data[64] = { 0 };
|
||||
rz_buf_read_at(buf, addr, data, sizeof(data));
|
||||
#if RZ_BIN_MACH064
|
||||
ut64 ep = rz_read_ble64(&data, false); // bin->big_endian);
|
||||
ut64 ep = rz_read_ble64(&data, big_endian);
|
||||
cb_printf("0x%08" PFMT64x " entry0 0x%" PFMT64x "\n", pvaddr, ep);
|
||||
ut64 ss = rz_read_ble64(&data[8], false); // bin->big_endian);
|
||||
ut64 ss = rz_read_ble64(&data[8], big_endian);
|
||||
cb_printf("0x%08" PFMT64x " stacksize 0x%" PFMT64x "\n", pvaddr + 8, ss);
|
||||
#else
|
||||
ut32 ep = rz_read_ble32(&data, false); // bin->big_endian);
|
||||
ut32 ep = rz_read_ble32(&data, big_endian);
|
||||
cb_printf("0x%08" PFMT32x " entry0 0x%" PFMT32x "\n", (ut32)pvaddr, ep);
|
||||
ut32 ss = rz_read_ble32(&data[4], false); // bin->big_endian);
|
||||
ut32 ss = rz_read_ble32(&data[4], big_endian);
|
||||
cb_printf("0x%08" PFMT32x " stacksize 0x%" PFMT32x "\n", (ut32)pvaddr + 4, ss);
|
||||
#endif
|
||||
} break;
|
||||
|
|
@ -3126,14 +3147,14 @@ void MACH0_(mach_headerfields)(RzBinFile *bf) {
|
|||
break;
|
||||
case LC_ID_DYLIB: { // install_name_tool
|
||||
ut32 str_off;
|
||||
if (!rz_buf_read_ble32_at(buf, addr, &str_off, isBe)) {
|
||||
if (!rz_buf_read_ble32_at(buf, addr, &str_off, big_endian)) {
|
||||
break;
|
||||
}
|
||||
|
||||
char *id = rz_buf_get_string(buf, addr + str_off - 8);
|
||||
|
||||
ut16 current1;
|
||||
if (!rz_buf_read_le16_at(buf, addr + 10, ¤t1)) {
|
||||
if (!rz_buf_read_ble16_at(buf, addr + 10, ¤t1, big_endian)) {
|
||||
free(id);
|
||||
break;
|
||||
}
|
||||
|
|
@ -3150,7 +3171,7 @@ void MACH0_(mach_headerfields)(RzBinFile *bf) {
|
|||
cb_printf("0x%08" PFMT64x " current %d.%d.%d\n", pvaddr + 8, current1, current2, current3);
|
||||
|
||||
ut16 compat1;
|
||||
if (!rz_buf_read_le16_at(buf, addr + 14, &compat1)) {
|
||||
if (!rz_buf_read_ble16_at(buf, addr + 14, &compat1, big_endian)) {
|
||||
free(id);
|
||||
break;
|
||||
}
|
||||
|
|
@ -3186,7 +3207,7 @@ void MACH0_(mach_headerfields)(RzBinFile *bf) {
|
|||
rz_buf_read_at(buf, addr, name, sizeof(name) - 1);
|
||||
cb_printf("0x%08" PFMT64x " name %s\n", pvaddr, name);
|
||||
ut32 nsects;
|
||||
if (!rz_buf_read_le32_at(buf, addr - 8 + (is64 ? 64 : 48), &nsects)) {
|
||||
if (!rz_buf_read_ble32_at(buf, addr - 8 + (is64 ? 64 : 48), &nsects, big_endian)) {
|
||||
break;
|
||||
}
|
||||
ut64 off = is64 ? 72 : 56;
|
||||
|
|
@ -3203,12 +3224,12 @@ void MACH0_(mach_headerfields)(RzBinFile *bf) {
|
|||
case LC_LOAD_DYLIB:
|
||||
case LC_LOAD_WEAK_DYLIB: {
|
||||
ut32 str_off;
|
||||
if (!rz_buf_read_ble32_at(buf, addr, &str_off, isBe)) {
|
||||
if (!rz_buf_read_ble32_at(buf, addr, &str_off, big_endian)) {
|
||||
break;
|
||||
}
|
||||
char *load_dylib = rz_buf_get_string(buf, addr + str_off - 8);
|
||||
ut16 current1;
|
||||
if (!rz_buf_read_le16_at(buf, addr + 10, ¤t1)) {
|
||||
if (!rz_buf_read_ble16_at(buf, addr + 10, ¤t1, big_endian)) {
|
||||
free(load_dylib);
|
||||
break;
|
||||
}
|
||||
|
|
@ -3224,7 +3245,7 @@ void MACH0_(mach_headerfields)(RzBinFile *bf) {
|
|||
}
|
||||
cb_printf("0x%08" PFMT64x " current %d.%d.%d\n", pvaddr + 8, current1, current2, current3);
|
||||
ut16 compat1;
|
||||
if (!rz_buf_read_le16_at(buf, addr + 14, &compat1)) {
|
||||
if (!rz_buf_read_ble16_at(buf, addr + 14, &compat1, big_endian)) {
|
||||
free(load_dylib);
|
||||
break;
|
||||
}
|
||||
|
|
@ -3254,17 +3275,17 @@ void MACH0_(mach_headerfields)(RzBinFile *bf) {
|
|||
case LC_ENCRYPTION_INFO:
|
||||
case LC_ENCRYPTION_INFO_64: {
|
||||
ut32 word;
|
||||
if (!rz_buf_read_le32_at(buf, addr, &word)) {
|
||||
if (!rz_buf_read_ble32_at(buf, addr, &word, big_endian)) {
|
||||
break;
|
||||
}
|
||||
cb_printf("0x%08" PFMT64x " cryptoff 0x%08x\n", pvaddr, word);
|
||||
|
||||
if (!rz_buf_read_le32_at(buf, addr + 4, &word)) {
|
||||
if (!rz_buf_read_ble32_at(buf, addr + 4, &word, big_endian)) {
|
||||
break;
|
||||
}
|
||||
cb_printf("0x%08" PFMT64x " cryptsize %d\n", pvaddr + 4, word);
|
||||
|
||||
if (!rz_buf_read_le32_at(buf, addr + 8, &word)) {
|
||||
if (!rz_buf_read_ble32_at(buf, addr + 8, &word, big_endian)) {
|
||||
break;
|
||||
}
|
||||
cb_printf("0x%08" PFMT64x " cryptid %d\n", pvaddr + 8, word);
|
||||
|
|
@ -3290,8 +3311,9 @@ RzStructuredData *MACH0_(mach_structure)(RzBinFile *bf) {
|
|||
|
||||
RzBuffer *buf = bf->buf;
|
||||
ut64 length = rz_buf_size(buf);
|
||||
bool big_endian;
|
||||
|
||||
struct MACH0_(mach_header) *mh = MACH0_(get_hdr)(buf);
|
||||
struct MACH0_(mach_header) *mh = MACH0_(get_hdr)(buf, &big_endian);
|
||||
if (!mh) {
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -3300,7 +3322,6 @@ RzStructuredData *MACH0_(mach_structure)(RzBinFile *bf) {
|
|||
ut32 word = 0;
|
||||
char tmp[256] = { 0 };
|
||||
|
||||
bool big_endian = (mh->cputype & CPU_TYPE_POWERPC) != 0;
|
||||
bool is_64bit = mh->cputype >> 16;
|
||||
|
||||
RzStructuredData *info = rz_structured_data_new_map();
|
||||
|
|
@ -3324,7 +3345,7 @@ RzStructuredData *MACH0_(mach_structure)(RzBinFile *bf) {
|
|||
rz_structured_data_map_add_string(mach0, "CpuType", "vax");
|
||||
break;
|
||||
case CPU_TYPE_MC680x0:
|
||||
rz_structured_data_map_add_string(mach0, "CpuType", "mc680x0");
|
||||
rz_structured_data_map_add_string(mach0, "CpuType", "m68k");
|
||||
break;
|
||||
case CPU_TYPE_X86:
|
||||
rz_structured_data_map_add_string(mach0, "CpuType", "x86");
|
||||
|
|
@ -3432,13 +3453,13 @@ RzStructuredData *MACH0_(mach_structure)(RzBinFile *bf) {
|
|||
switch (lcType) {
|
||||
case LC_BUILD_VERSION: {
|
||||
ut32 platform;
|
||||
if (!rz_buf_read_le32_at(buf, addr, &platform)) {
|
||||
if (!rz_buf_read_ble32_at(buf, addr, &platform, big_endian)) {
|
||||
break;
|
||||
}
|
||||
rz_structured_data_map_add_string(lc_info, "Platform", rz_mach0_platform_to_string(platform));
|
||||
|
||||
ut16 minos1;
|
||||
if (!rz_buf_read_le16_at(buf, addr + 6, &minos1)) {
|
||||
if (!rz_buf_read_ble16_at(buf, addr + 6, &minos1, big_endian)) {
|
||||
break;
|
||||
}
|
||||
ut8 minos2;
|
||||
|
|
@ -3453,7 +3474,7 @@ RzStructuredData *MACH0_(mach_structure)(RzBinFile *bf) {
|
|||
rz_structured_data_map_add_string(lc_info, "MinOS", tmp);
|
||||
|
||||
ut16 sdk1;
|
||||
if (!rz_buf_read_le16_at(buf, addr + 10, &sdk1)) {
|
||||
if (!rz_buf_read_ble16_at(buf, addr + 10, &sdk1, big_endian)) {
|
||||
break;
|
||||
}
|
||||
ut8 sdk2;
|
||||
|
|
@ -3468,7 +3489,7 @@ RzStructuredData *MACH0_(mach_structure)(RzBinFile *bf) {
|
|||
rz_structured_data_map_add_string(lc_info, "SDK", tmp);
|
||||
|
||||
ut32 ntools;
|
||||
if (!rz_buf_read_le32_at(buf, addr + 12, &ntools)) {
|
||||
if (!rz_buf_read_ble32_at(buf, addr + 12, &ntools, big_endian)) {
|
||||
break;
|
||||
}
|
||||
rz_structured_data_map_add_unsigned(lc_info, "nTools", ntools, false);
|
||||
|
|
@ -3490,7 +3511,7 @@ RzStructuredData *MACH0_(mach_structure)(RzBinFile *bf) {
|
|||
}
|
||||
|
||||
ut32 tool;
|
||||
if (!rz_buf_read_le32_at(buf, addr + off, &tool)) {
|
||||
if (!rz_buf_read_ble32_at(buf, addr + off, &tool, big_endian)) {
|
||||
break;
|
||||
}
|
||||
rz_structured_data_map_add_string(build, "Tool", rz_mach0_build_version_tool_to_string(tool));
|
||||
|
|
@ -3501,7 +3522,7 @@ RzStructuredData *MACH0_(mach_structure)(RzBinFile *bf) {
|
|||
}
|
||||
|
||||
ut16 version1;
|
||||
if (!rz_buf_read_le16_at(buf, addr + off + 2, &version1)) {
|
||||
if (!rz_buf_read_ble16_at(buf, addr + off + 2, &version1, big_endian)) {
|
||||
break;
|
||||
}
|
||||
ut8 version2;
|
||||
|
|
@ -3524,11 +3545,11 @@ RzStructuredData *MACH0_(mach_structure)(RzBinFile *bf) {
|
|||
ut8 data[64] = { 0 };
|
||||
rz_buf_read_at(buf, addr, data, sizeof(data));
|
||||
#if RZ_BIN_MACH064
|
||||
ut64 ep = rz_read_ble64(&data, false); // bin->big_endian);
|
||||
ut64 ss = rz_read_ble64(&data[8], false); // bin->big_endian);
|
||||
ut64 ep = rz_read_ble64(&data, big_endian);
|
||||
ut64 ss = rz_read_ble64(&data[8], big_endian);
|
||||
#else
|
||||
ut32 ep = rz_read_ble32(&data, false); // bin->big_endian);
|
||||
ut32 ss = rz_read_ble32(&data[4], false); // bin->big_endian);
|
||||
ut32 ep = rz_read_ble32(&data, big_endian);
|
||||
ut32 ss = rz_read_ble32(&data[4], big_endian);
|
||||
#endif
|
||||
rz_structured_data_map_add_unsigned(lc_info, "Entry", ep, true);
|
||||
rz_structured_data_map_add_unsigned(lc_info, "StackSize", ss, false);
|
||||
|
|
@ -3548,7 +3569,7 @@ RzStructuredData *MACH0_(mach_structure)(RzBinFile *bf) {
|
|||
free(id);
|
||||
|
||||
ut16 current1;
|
||||
if (!rz_buf_read_le16_at(buf, addr + 10, ¤t1)) {
|
||||
if (!rz_buf_read_ble16_at(buf, addr + 10, ¤t1, big_endian)) {
|
||||
break;
|
||||
}
|
||||
ut8 current2;
|
||||
|
|
@ -3563,7 +3584,7 @@ RzStructuredData *MACH0_(mach_structure)(RzBinFile *bf) {
|
|||
rz_structured_data_map_add_string(lc_info, "Current", tmp);
|
||||
|
||||
ut16 compat1;
|
||||
if (!rz_buf_read_le16_at(buf, addr + 14, &compat1)) {
|
||||
if (!rz_buf_read_ble16_at(buf, addr + 14, &compat1, big_endian)) {
|
||||
break;
|
||||
}
|
||||
ut8 compat2;
|
||||
|
|
@ -3596,7 +3617,7 @@ RzStructuredData *MACH0_(mach_structure)(RzBinFile *bf) {
|
|||
rz_structured_data_map_add_string(lc_info, "Name", name);
|
||||
|
||||
ut32 nsects;
|
||||
if (!rz_buf_read_le32_at(buf, addr - 8 + (is_64bit ? 64 : 48), &nsects)) {
|
||||
if (!rz_buf_read_ble32_at(buf, addr - 8 + (is_64bit ? 64 : 48), &nsects, big_endian)) {
|
||||
break;
|
||||
}
|
||||
rz_structured_data_map_add_unsigned(lc_info, "nSects", nsects, false);
|
||||
|
|
@ -3615,7 +3636,7 @@ RzStructuredData *MACH0_(mach_structure)(RzBinFile *bf) {
|
|||
free(load_dylib);
|
||||
|
||||
ut16 current1;
|
||||
if (!rz_buf_read_le16_at(buf, addr + 10, ¤t1)) {
|
||||
if (!rz_buf_read_ble16_at(buf, addr + 10, ¤t1, big_endian)) {
|
||||
break;
|
||||
}
|
||||
ut8 current2;
|
||||
|
|
@ -3630,7 +3651,7 @@ RzStructuredData *MACH0_(mach_structure)(RzBinFile *bf) {
|
|||
rz_structured_data_map_add_string(lc_info, "Current", tmp);
|
||||
|
||||
ut16 compat1;
|
||||
if (!rz_buf_read_le16_at(buf, addr + 14, &compat1)) {
|
||||
if (!rz_buf_read_ble16_at(buf, addr + 14, &compat1, big_endian)) {
|
||||
break;
|
||||
}
|
||||
ut8 compat2;
|
||||
|
|
@ -3656,17 +3677,17 @@ RzStructuredData *MACH0_(mach_structure)(RzBinFile *bf) {
|
|||
case LC_ENCRYPTION_INFO:
|
||||
case LC_ENCRYPTION_INFO_64: {
|
||||
ut32 word;
|
||||
if (!rz_buf_read_le32_at(buf, addr, &word)) {
|
||||
if (!rz_buf_read_ble32_at(buf, addr, &word, big_endian)) {
|
||||
break;
|
||||
}
|
||||
rz_structured_data_map_add_unsigned(lc_info, "CryptOffset", word, true);
|
||||
|
||||
if (!rz_buf_read_le32_at(buf, addr + 4, &word)) {
|
||||
if (!rz_buf_read_ble32_at(buf, addr + 4, &word, big_endian)) {
|
||||
break;
|
||||
}
|
||||
rz_structured_data_map_add_unsigned(lc_info, "CryptSize", word, false);
|
||||
|
||||
if (!rz_buf_read_le32_at(buf, addr + 8, &word)) {
|
||||
if (!rz_buf_read_ble32_at(buf, addr + 8, &word, big_endian)) {
|
||||
break;
|
||||
}
|
||||
rz_structured_data_map_add_unsigned(lc_info, "CryptId", word, false);
|
||||
|
|
@ -3693,7 +3714,8 @@ RzStructuredData *MACH0_(mach_structure)(RzBinFile *bf) {
|
|||
RzPVector /*<RzBinField *>*/ *MACH0_(mach_fields)(RzBinFile *bf) {
|
||||
RzBuffer *buf = bf->buf;
|
||||
ut64 length = rz_buf_size(buf);
|
||||
struct MACH0_(mach_header) *mh = MACH0_(get_hdr)(buf);
|
||||
bool big_endian;
|
||||
struct MACH0_(mach_header) *mh = MACH0_(get_hdr)(buf, &big_endian);
|
||||
if (!mh) {
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -3714,23 +3736,15 @@ RzPVector /*<RzBinField *>*/ *MACH0_(mach_fields)(RzBinFile *bf) {
|
|||
paddr += 4;
|
||||
}
|
||||
|
||||
bool isBe = false;
|
||||
switch (mh->cputype) {
|
||||
case CPU_TYPE_POWERPC:
|
||||
case CPU_TYPE_POWERPC64:
|
||||
isBe = true;
|
||||
break;
|
||||
}
|
||||
|
||||
int n;
|
||||
char tmpbuf[128];
|
||||
for (n = 0; n < mh->ncmds; n++) {
|
||||
ut32 lcType;
|
||||
if (!rz_buf_read_ble32_at(buf, paddr, &lcType, isBe)) {
|
||||
if (!rz_buf_read_ble32_at(buf, paddr, &lcType, big_endian)) {
|
||||
break;
|
||||
}
|
||||
ut32 word;
|
||||
if (!rz_buf_read_ble32_at(buf, paddr + 4, &word, isBe)) {
|
||||
if (!rz_buf_read_ble32_at(buf, paddr + 4, &word, big_endian)) {
|
||||
break;
|
||||
}
|
||||
if (paddr + 8 > length) {
|
||||
|
|
@ -3752,7 +3766,7 @@ RzPVector /*<RzBinField *>*/ *MACH0_(mach_fields)(RzBinFile *bf) {
|
|||
switch (lcType) {
|
||||
case LC_BUILD_VERSION: {
|
||||
ut32 ntools;
|
||||
if (!rz_buf_read_le32_at(buf, paddr + 20, &ntools)) {
|
||||
if (!rz_buf_read_ble32_at(buf, paddr + 20, &ntools, big_endian)) {
|
||||
break;
|
||||
}
|
||||
ut64 off = 24;
|
||||
|
|
@ -3766,7 +3780,7 @@ RzPVector /*<RzBinField *>*/ *MACH0_(mach_fields)(RzBinFile *bf) {
|
|||
case LC_SEGMENT:
|
||||
case LC_SEGMENT_64: {
|
||||
ut32 nsects;
|
||||
if (!rz_buf_read_le32_at(buf, addr + (is64 ? 64 : 48), &nsects)) {
|
||||
if (!rz_buf_read_ble32_at(buf, addr + (is64 ? 64 : 48), &nsects, big_endian)) {
|
||||
break;
|
||||
}
|
||||
ut64 off = is64 ? 72 : 56;
|
||||
|
|
@ -3791,7 +3805,7 @@ RzPVector /*<RzBinField *>*/ *MACH0_(mach_fields)(RzBinFile *bf) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
struct MACH0_(mach_header) * MACH0_(get_hdr)(RzBuffer *buf) {
|
||||
struct MACH0_(mach_header) * MACH0_(get_hdr)(RzBuffer *buf, RZ_NULLABLE RZ_OUT bool *is_big_endian) {
|
||||
ut8 magicbytes[sizeof(ut32)] = { 0 };
|
||||
ut8 machohdrbytes[sizeof(struct MACH0_(mach_header))] = { 0 };
|
||||
int len;
|
||||
|
|
@ -3818,6 +3832,9 @@ struct MACH0_(mach_header) * MACH0_(get_hdr)(RzBuffer *buf) {
|
|||
} else if (rz_read_be32(magicbytes) == 0xfeedfacf) {
|
||||
big_endian = true;
|
||||
}
|
||||
if (is_big_endian) {
|
||||
*is_big_endian = big_endian;
|
||||
}
|
||||
len = rz_buf_read_at(buf, 0, machohdrbytes, sizeof(machohdrbytes));
|
||||
if (len != sizeof(struct MACH0_(mach_header))) {
|
||||
free(macho_hdr);
|
||||
|
|
|
|||
|
|
@ -188,6 +188,8 @@ struct MACH0_(obj_t) {
|
|||
struct ppc_thread_state64 ppc_64;
|
||||
struct arm_thread_state32 arm_32;
|
||||
struct arm_thread_state64 arm_64;
|
||||
struct sparc_thread_state64 sparc_64;
|
||||
struct mc680x0_thread_state mc680x0;
|
||||
} thread_state;
|
||||
char (*libs)[RZ_BIN_MACH0_STRING_LENGTH];
|
||||
int nlibs;
|
||||
|
|
@ -247,7 +249,7 @@ struct lib_t *MACH0_(get_libs)(struct MACH0_(obj_t) * bin);
|
|||
ut64 MACH0_(get_baddr)(struct MACH0_(obj_t) * bin);
|
||||
char *MACH0_(get_class)(struct MACH0_(obj_t) * bin);
|
||||
int MACH0_(get_bits)(struct MACH0_(obj_t) * bin);
|
||||
bool MACH0_(is_big_endian)(struct MACH0_(obj_t) * bin);
|
||||
bool MACH0_(is_big_endian)(RZ_NONNULL RzBuffer *buf);
|
||||
bool MACH0_(is_pie)(struct MACH0_(obj_t) * bin);
|
||||
bool MACH0_(has_nx)(struct MACH0_(obj_t) * bin);
|
||||
const char *MACH0_(get_intrp)(struct MACH0_(obj_t) * bin);
|
||||
|
|
@ -260,7 +262,7 @@ char *MACH0_(get_filetype_from_hdr)(struct MACH0_(mach_header) * hdr);
|
|||
ut64 MACH0_(get_main)(struct MACH0_(obj_t) * bin);
|
||||
const char *MACH0_(get_cputype_from_hdr)(struct MACH0_(mach_header) * hdr);
|
||||
int MACH0_(get_bits_from_hdr)(struct MACH0_(mach_header) * hdr);
|
||||
struct MACH0_(mach_header) * MACH0_(get_hdr)(RzBuffer *buf);
|
||||
struct MACH0_(mach_header) * MACH0_(get_hdr)(RzBuffer *buf, RZ_NULLABLE RZ_OUT bool *is_big_endian);
|
||||
RzStructuredData *MACH0_(mach_structure)(RzBinFile *bf);
|
||||
RzPVector /*<RzBinField *>*/ *MACH0_(mach_fields)(RzBinFile *bf);
|
||||
RZ_API RZ_OWN char *MACH0_(get_name)(struct MACH0_(obj_t) * mo, ut32 stridx, bool filter);
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ RZ_API RZ_NONNULL const char *rz_mach0_cputype_to_string(ut32 cputype) {
|
|||
case CPU_TYPE_VAX:
|
||||
return "vax";
|
||||
case CPU_TYPE_MC680x0:
|
||||
return "mc680x0";
|
||||
return "m68k";
|
||||
case CPU_TYPE_I386:
|
||||
case CPU_TYPE_X86_64:
|
||||
return "x86";
|
||||
|
|
|
|||
|
|
@ -190,6 +190,38 @@ struct arm_thread_state64 {
|
|||
ut32 flags;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief This layout is guessed. I couldn't find a reference online
|
||||
* implementing linking of Mach-O Sparc binaries and has the layout of the thread state.
|
||||
* The layout below is the one used for the registers in the ELF core dumps.
|
||||
* I use this in the hope the Mach-O and ELF devs had some
|
||||
* commen documentation they were refering to.
|
||||
*/
|
||||
struct sparc_thread_state64 {
|
||||
ut64 g[8];
|
||||
ut64 o[8];
|
||||
ut64 l[8];
|
||||
ut64 i[8];
|
||||
ut64 tstate;
|
||||
ut64 tpc;
|
||||
ut64 tnpc;
|
||||
ut64 y;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Assume layout of register file from the ISA:
|
||||
*
|
||||
* Figure 2-1:
|
||||
* https://www.nxp.com/docs/en/reference-manual/MC68000UM.pdf
|
||||
* https://web.archive.org/web/20250716224705/https://www.nxp.com/docs/en/reference-manual/MC68000UM.pdf
|
||||
*/
|
||||
struct mc680x0_thread_state {
|
||||
ut32 d[8];
|
||||
ut32 a[8];
|
||||
ut32 pc;
|
||||
ut8 ccr;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
uint8_t uuid[16];
|
||||
uint64_t loadAddress;
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ RZ_IPI void rz_bin_object_free(RzBinObject *o);
|
|||
RZ_IPI ut64 rz_bin_object_get_baddr(RzBinObject *o);
|
||||
RZ_IPI RzBinObject *rz_bin_object_new(RzBinFile *binfile, RzBinPlugin *plugin, RzBinObjectLoadOptions *opts, ut64 offset, ut64 sz);
|
||||
RZ_IPI RzBinObject *rz_bin_object_get_cur(RzBin *bin);
|
||||
RZ_IPI RzBinObject *rz_bin_object_find_by_arch_bits(RzBinFile *binfile, const char *arch, int bits, const char *name);
|
||||
RZ_IPI RzBinObject *rz_bin_object_find_by_arch_bits(RzBinFile *bf, RZ_NONNULL const char *arch, int bits, RZ_NULLABLE const char *machine, RZ_NULLABLE const char *filename);
|
||||
|
||||
RZ_IPI RzBinFile *rz_bin_file_xtr_load_buffer(RzBin *bin, RzBinXtrPlugin *xtr, const char *filename, RzBuffer *buf, RzBinObjectLoadOptions *obj_opts, int idx, int fd);
|
||||
RZ_IPI RzBinFile *rz_bin_file_new_from_buffer(RzBin *bin, const char *file, RzBuffer *buf, RzBinObjectLoadOptions *opts, int fd, const char *pluginname);
|
||||
|
|
|
|||
|
|
@ -474,7 +474,7 @@ static RzBinInfo *mach0_info(RzBinFile *bf) {
|
|||
ret->cpu = MACH0_(get_cpusubtype)(bf->o->bin_obj);
|
||||
ret->machine = MACH0_(get_cpusubtype)(bf->o->bin_obj);
|
||||
ret->type = MACH0_(get_filetype)(bf->o->bin_obj);
|
||||
ret->big_endian = MACH0_(is_big_endian)(bf->o->bin_obj);
|
||||
ret->big_endian = MACH0_(is_big_endian)(bf->buf);
|
||||
ret->bits = 32;
|
||||
if (bf && bf->o && bf->o->bin_obj) {
|
||||
ret->has_crypto = ((struct MACH0_(obj_t) *)
|
||||
|
|
|
|||
|
|
@ -59,11 +59,12 @@ static int size(RzBin *bin) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline void fill_metadata_info_from_hdr(RzBinXtrMetadata *meta, struct MACH0_(mach_header) * hdr) {
|
||||
static inline void fill_metadata_info_from_hdr(RzBinXtrMetadata *meta, struct MACH0_(mach_header) * hdr, bool is_big_endian) {
|
||||
meta->arch = rz_str_dup(MACH0_(get_cputype_from_hdr)(hdr));
|
||||
meta->bits = MACH0_(get_bits_from_hdr)(hdr);
|
||||
meta->machine = MACH0_(get_cpusubtype_from_hdr)(hdr);
|
||||
meta->type = MACH0_(get_filetype_from_hdr)(hdr);
|
||||
meta->big_endian = is_big_endian;
|
||||
meta->libname = NULL;
|
||||
meta->xtr_type = "fat";
|
||||
}
|
||||
|
|
@ -82,14 +83,15 @@ static RzBinXtrData *extract(RzBin *bin, int idx) {
|
|||
free(arch);
|
||||
return NULL;
|
||||
}
|
||||
struct MACH0_(mach_header) *hdr = MACH0_(get_hdr)(arch->b);
|
||||
bool big_endian;
|
||||
struct MACH0_(mach_header) *hdr = MACH0_(get_hdr)(arch->b, &big_endian);
|
||||
if (!hdr) {
|
||||
free(metadata);
|
||||
free(arch);
|
||||
free(hdr);
|
||||
return NULL;
|
||||
}
|
||||
fill_metadata_info_from_hdr(metadata, hdr);
|
||||
fill_metadata_info_from_hdr(metadata, hdr, big_endian);
|
||||
RzBinXtrData *res = rz_bin_xtrdata_new(arch->b, arch->offset, arch->size, narch, metadata);
|
||||
rz_buf_free(arch->b);
|
||||
free(arch);
|
||||
|
|
@ -106,23 +108,27 @@ static RzBinXtrData *oneshot_buffer(RzBin *bin, RzBuffer *b, int idx) {
|
|||
int narch;
|
||||
struct rz_bin_fatmach0_obj_t *fb = bin->cur->xtr_obj;
|
||||
struct rz_bin_fatmach0_arch_t *arch = rz_bin_fatmach0_extract(fb, idx, &narch);
|
||||
if (arch) {
|
||||
RzBinXtrMetadata *metadata = RZ_NEW0(RzBinXtrMetadata);
|
||||
if (metadata) {
|
||||
struct MACH0_(mach_header) *hdr = MACH0_(get_hdr)(arch->b);
|
||||
if (hdr) {
|
||||
fill_metadata_info_from_hdr(metadata, hdr);
|
||||
RzBinXtrData *res = rz_bin_xtrdata_new(arch->b, arch->offset, arch->size, narch, metadata);
|
||||
rz_buf_free(arch->b);
|
||||
free(arch);
|
||||
free(hdr);
|
||||
return res;
|
||||
}
|
||||
free(metadata);
|
||||
}
|
||||
free(arch);
|
||||
if (!arch) {
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
RzBinXtrMetadata *metadata = RZ_NEW0(RzBinXtrMetadata);
|
||||
if (!metadata) {
|
||||
free(arch);
|
||||
return NULL;
|
||||
}
|
||||
bool big_endian;
|
||||
struct MACH0_(mach_header) *hdr = MACH0_(get_hdr)(arch->b, &big_endian);
|
||||
if (!hdr) {
|
||||
free(metadata);
|
||||
free(arch);
|
||||
return NULL;
|
||||
}
|
||||
fill_metadata_info_from_hdr(metadata, hdr, big_endian);
|
||||
RzBinXtrData *res = rz_bin_xtrdata_new(arch->b, arch->offset, arch->size, narch, metadata);
|
||||
rz_buf_free(arch->b);
|
||||
free(arch);
|
||||
free(hdr);
|
||||
return res;
|
||||
}
|
||||
|
||||
static RzList /*<RzBinXtrData *>*/ *oneshotall_buffer(RzBin *bin, RzBuffer *b) {
|
||||
|
|
|
|||
|
|
@ -301,6 +301,9 @@ RZ_API bool rz_core_bin_apply_all_info(RzCore *r, RzBinFile *binfile) {
|
|||
r->dbg->bp->baddr = baseaddr;
|
||||
rz_config_set(r->config, "asm.arch", arch);
|
||||
rz_config_set_i(r->config, "asm.bits", bits);
|
||||
if (info->cpu) {
|
||||
rz_config_set(r->config, "asm.cpu", info->cpu);
|
||||
}
|
||||
rz_config_set(r->config, "analysis.arch", arch);
|
||||
if (RZ_STR_ISNOTEMPTY(info->cpu)) {
|
||||
rz_config_set(r->config, "analysis.cpu", info->cpu);
|
||||
|
|
@ -4649,37 +4652,37 @@ static int bin_versioninfo(RzCore *r, PJ *pj, int mode) {
|
|||
return true;
|
||||
}
|
||||
|
||||
RZ_API int rz_core_bin_set_arch_bits(RzCore *r, const char *name, const char *arch, ut16 bits) {
|
||||
int fd = rz_io_fd_get_current(r->io);
|
||||
RzIODesc *desc = rz_io_desc_get(r->io, fd);
|
||||
/**
|
||||
* \brief Sets the current architecture and bits to the given values.
|
||||
* If there is a RzBinFile with \p filename, and/or an object for \p arch and \p bits,
|
||||
* it will load it and set it as main object file.
|
||||
*
|
||||
* \param r The current RzCore isntance to update.
|
||||
* \param filename (Optional) The filename of the RzBinFile to load.
|
||||
* \param arch The architecture name.
|
||||
* \param bits The architecture bits.
|
||||
*
|
||||
* \return True if loading the binary file was successful. False otherwise.
|
||||
*/
|
||||
RZ_API bool rz_core_bin_set_arch_bits(RZ_NONNULL RzCore *r, RZ_NULLABLE const char *filename, RZ_NULLABLE const char *arch, ut16 bits) {
|
||||
rz_return_val_if_fail(r, false);
|
||||
RzBinFile *curfile, *binfile = NULL;
|
||||
if (!name) {
|
||||
if (!desc || !desc->name) {
|
||||
return false;
|
||||
}
|
||||
name = desc->name;
|
||||
}
|
||||
/* Check if the arch name is a valid name */
|
||||
if (!rz_asm_is_valid(r->rasm, arch)) {
|
||||
return false;
|
||||
}
|
||||
/* Find a file with the requested name/arch/bits */
|
||||
binfile = rz_bin_file_find_by_arch_bits(r->bin, arch, bits);
|
||||
binfile = rz_bin_file_find_by_arch_bits(r->bin, arch, bits, NULL, filename);
|
||||
if (!binfile) {
|
||||
return false;
|
||||
}
|
||||
if (!rz_bin_use_arch(r->bin, arch, bits, name)) {
|
||||
if (!rz_bin_use_arch(r->bin, arch, bits, NULL, filename)) {
|
||||
return false;
|
||||
}
|
||||
curfile = rz_bin_cur(r->bin);
|
||||
// set env if the binfile changed or we are dealing with xtr
|
||||
if (curfile != binfile || binfile->curxtr) {
|
||||
rz_core_bin_set_cur(r, binfile);
|
||||
if (binfile->o && binfile->o->info) {
|
||||
free(binfile->o->info->arch);
|
||||
binfile->o->info->arch = rz_str_dup(arch);
|
||||
binfile->o->info->bits = bits;
|
||||
}
|
||||
return rz_core_bin_apply_all_info(r, binfile);
|
||||
}
|
||||
return true;
|
||||
|
|
@ -5394,12 +5397,13 @@ struct arch_ctx {
|
|||
ut64 size;
|
||||
const char *arch;
|
||||
int bits;
|
||||
bool big_endian;
|
||||
const char *machine;
|
||||
};
|
||||
|
||||
static void print_arch(RzBin *bin, RzCmdStateOutput *state, struct arch_ctx *ctx, const char *flag, RzBinInfo *info) {
|
||||
char str_fmt[30];
|
||||
const char *fmt = "Xnss";
|
||||
const char *fmt = "Xnsisb";
|
||||
|
||||
switch (state->mode) {
|
||||
case RZ_OUTPUT_MODE_QUIET:
|
||||
|
|
@ -5409,6 +5413,7 @@ static void print_arch(RzBin *bin, RzCmdStateOutput *state, struct arch_ctx *ctx
|
|||
pj_o(state->d.pj);
|
||||
pj_ks(state->d.pj, "arch", ctx->arch);
|
||||
pj_ki(state->d.pj, "bits", ctx->bits);
|
||||
pj_kb(state->d.pj, "big_endian", ctx->big_endian);
|
||||
pj_kn(state->d.pj, "offset", ctx->offset);
|
||||
pj_kn(state->d.pj, "size", ctx->size);
|
||||
if (info) {
|
||||
|
|
@ -5422,11 +5427,11 @@ static void print_arch(RzBin *bin, RzCmdStateOutput *state, struct arch_ctx *ctx
|
|||
break;
|
||||
case RZ_OUTPUT_MODE_TABLE:
|
||||
if (flag && strcmp(flag, "unknown_flag")) {
|
||||
rz_strf(str_fmt, "%s_%i %s", ctx->arch, ctx->bits, flag);
|
||||
rz_strf(str_fmt, "%s %s", ctx->arch, flag);
|
||||
} else {
|
||||
rz_strf(str_fmt, "%s_%i", ctx->arch, ctx->bits);
|
||||
rz_strf(str_fmt, "%s", ctx->arch);
|
||||
}
|
||||
rz_table_add_rowf(state->d.t, fmt, ctx->offset, ctx->size, str_fmt, ctx->machine);
|
||||
rz_table_add_rowf(state->d.t, fmt, ctx->offset, ctx->size, str_fmt, ctx->bits, ctx->machine, ctx->big_endian);
|
||||
break;
|
||||
default:
|
||||
rz_warn_if_reached();
|
||||
|
|
@ -5442,9 +5447,9 @@ RZ_API bool rz_core_bin_archs_print(RZ_NONNULL RzBin *bin, RZ_NONNULL RzCmdState
|
|||
return false;
|
||||
}
|
||||
|
||||
const char *fmt = "Xnss";
|
||||
const char *fmt = "Xnsisb";
|
||||
rz_cmd_state_output_array_start(state);
|
||||
rz_cmd_state_output_set_columnsf(state, fmt, "offset", "size", "arch", "machine", NULL);
|
||||
rz_cmd_state_output_set_columnsf(state, fmt, "offset", "size", "arch", "bits", "machine", "big_endian", NULL);
|
||||
|
||||
if (binfile->curxtr) {
|
||||
RzListIter *iter_xtr;
|
||||
|
|
@ -5459,6 +5464,7 @@ RZ_API bool rz_core_bin_archs_print(RZ_NONNULL RzBin *bin, RZ_NONNULL RzCmdState
|
|||
ctx.size = xtr_data->size;
|
||||
ctx.arch = xtr_data->metadata->arch;
|
||||
ctx.bits = xtr_data->metadata->bits;
|
||||
ctx.big_endian = xtr_data->metadata->big_endian;
|
||||
ctx.machine = xtr_data->metadata->machine;
|
||||
|
||||
print_arch(bin, state, &ctx, NULL, NULL);
|
||||
|
|
@ -5471,6 +5477,7 @@ RZ_API bool rz_core_bin_archs_print(RZ_NONNULL RzBin *bin, RZ_NONNULL RzCmdState
|
|||
ctx.size = obj->obj_size;
|
||||
ctx.arch = (info && info->arch) ? info->arch : "unk_0";
|
||||
ctx.bits = info ? info->bits : 0;
|
||||
ctx.big_endian = info ? info->big_endian : false;
|
||||
ctx.machine = info ? info->machine : "unknown_machine";
|
||||
|
||||
const char *h_flag = info ? info->head_flag : NULL;
|
||||
|
|
|
|||
|
|
@ -757,6 +757,58 @@ RZ_IPI RzCmdStatus rz_open_binary_file_handler(RzCore *core, int argc, const cha
|
|||
return RZ_CMD_STATUS_OK;
|
||||
}
|
||||
|
||||
static inline bool xtr_selection_matches(RzList /*<const char *>*/ *selection, const RzBinXtrMetadata *metadata) {
|
||||
rz_return_val_if_fail(selection && metadata && rz_list_length(selection) >= 2, false);
|
||||
return (RZ_STR_EQ(rz_list_get_n(selection, 0), metadata->arch) &&
|
||||
atoi(rz_list_get_n(selection, 1)) == metadata->bits &&
|
||||
(rz_list_length(selection) < 3 || RZ_STR_ISEMPTY(metadata->machine) || RZ_STR_EQ(rz_list_get_n(selection, 2), metadata->machine)));
|
||||
}
|
||||
|
||||
RZ_IPI RzCmdStatus rz_open_binary_select_handler(RzCore *core, int argc, const char **argv) {
|
||||
RzBin *bin = core->bin;
|
||||
if (!bin) {
|
||||
return RZ_CMD_STATUS_ERROR;
|
||||
}
|
||||
bool list_existing = argc == 1;
|
||||
RzListIter *iter;
|
||||
RzBinFile *binfile = NULL;
|
||||
RzBinXtrData *xtr_data;
|
||||
size_t bits = 0;
|
||||
|
||||
rz_list_foreach (bin->binfiles, iter, binfile) {
|
||||
RzListIter *iter_xtr;
|
||||
if (!binfile->xtr_data) {
|
||||
continue;
|
||||
}
|
||||
rz_list_foreach (binfile->xtr_data, iter_xtr, xtr_data) {
|
||||
if (list_existing) {
|
||||
rz_cons_printf("%s_%i_%s\n", xtr_data->metadata->arch, xtr_data->metadata->bits, xtr_data->metadata->machine);
|
||||
continue;
|
||||
}
|
||||
RzList *selection = rz_str_split_duplist(argv[1], "_", 0);
|
||||
if (rz_list_length(selection) < 2) {
|
||||
RZ_LOG_WARN("Invalid argument.\n");
|
||||
return RZ_CMD_STATUS_ERROR;
|
||||
}
|
||||
if (xtr_selection_matches(selection, xtr_data->metadata)) {
|
||||
bits = xtr_data->metadata->bits;
|
||||
const char *mach = rz_list_length(selection) > 2 ? rz_list_get_n(selection, 2) : NULL;
|
||||
if (!rz_bin_select(bin, rz_list_get_n(selection, 0), bits, mach, NULL)) {
|
||||
rz_list_free(selection);
|
||||
return RZ_CMD_STATUS_ERROR;
|
||||
}
|
||||
if (!rz_core_bin_apply_all_info(core, binfile)) {
|
||||
rz_list_free(selection);
|
||||
return RZ_CMD_STATUS_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
rz_list_free(selection);
|
||||
}
|
||||
}
|
||||
return RZ_CMD_STATUS_OK;
|
||||
}
|
||||
|
||||
RZ_IPI RzCmdStatus rz_open_binary_reload_handler(RzCore *core, int argc, const char **argv) {
|
||||
// XXX: this will reload the bin using the buffer.
|
||||
// An assumption is made that assumes there is an underlying
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ static const RzCmdDescDetail history_list_or_exec_details[2];
|
|||
static const RzCmdDescDetail cmd_info_query_details[2];
|
||||
static const RzCmdDescDetail query_sdb_get_set_details[2];
|
||||
static const RzCmdDescDetail plugins_asm_print_details[2];
|
||||
static const RzCmdDescDetail open_binary_select_details[2];
|
||||
static const RzCmdDescDetail cmd_print_byte_array_details[3];
|
||||
static const RzCmdDescDetail pf_details[3];
|
||||
static const RzCmdDescDetail print_string_details[2];
|
||||
|
|
@ -648,6 +649,7 @@ static const RzCmdDescArg open_binary_select_fd_args[2];
|
|||
static const RzCmdDescArg open_binary_del_args[2];
|
||||
static const RzCmdDescArg open_binary_add_args[2];
|
||||
static const RzCmdDescArg open_binary_file_args[2];
|
||||
static const RzCmdDescArg open_binary_select_args[2];
|
||||
static const RzCmdDescArg open_binary_reload_args[2];
|
||||
static const RzCmdDescArg open_use_args[2];
|
||||
static const RzCmdDescArg open_prioritize_args[2];
|
||||
|
|
@ -14224,6 +14226,31 @@ static const RzCmdDescHelp open_binary_file_help = {
|
|||
.args = open_binary_file_args,
|
||||
};
|
||||
|
||||
static const RzCmdDescDetailEntry open_binary_select_Examples_detail_entries[] = {
|
||||
{ .text = "obs", .arg_str = NULL, .comment = "List all architectures the fat binary supports contains." },
|
||||
{ .text = "obs sparc", .arg_str = NULL, .comment = "Select and load the binary for Sparc" },
|
||||
{ 0 },
|
||||
};
|
||||
static const RzCmdDescDetail open_binary_select_details[] = {
|
||||
{ .name = "Examples", .entries = open_binary_select_Examples_detail_entries },
|
||||
{ 0 },
|
||||
};
|
||||
static const RzCmdDescArg open_binary_select_args[] = {
|
||||
{
|
||||
.name = "arch",
|
||||
.type = RZ_CMD_ARG_TYPE_STRING,
|
||||
.flags = RZ_CMD_ARG_FLAG_LAST,
|
||||
.optional = true,
|
||||
|
||||
},
|
||||
{ 0 },
|
||||
};
|
||||
static const RzCmdDescHelp open_binary_select_help = {
|
||||
.summary = "Select the binary version for the specified architecture from the fat binary.",
|
||||
.details = open_binary_select_details,
|
||||
.args = open_binary_select_args,
|
||||
};
|
||||
|
||||
static const RzCmdDescArg open_binary_reload_args[] = {
|
||||
{
|
||||
.name = "baddr",
|
||||
|
|
@ -24050,6 +24077,9 @@ RZ_IPI void rzshell_cmddescs_init(RzCore *core) {
|
|||
RzCmdDesc *open_binary_file_cd = rz_cmd_desc_argv_new(core->rcmd, ob_cd, "obf", rz_open_binary_file_handler, &open_binary_file_help);
|
||||
rz_warn_if_fail(open_binary_file_cd);
|
||||
|
||||
RzCmdDesc *open_binary_select_cd = rz_cmd_desc_argv_new(core->rcmd, ob_cd, "obs", rz_open_binary_select_handler, &open_binary_select_help);
|
||||
rz_warn_if_fail(open_binary_select_cd);
|
||||
|
||||
RzCmdDesc *open_binary_reload_cd = rz_cmd_desc_argv_new(core->rcmd, ob_cd, "obR", rz_open_binary_reload_handler, &open_binary_reload_help);
|
||||
rz_warn_if_fail(open_binary_reload_cd);
|
||||
|
||||
|
|
|
|||
|
|
@ -1870,6 +1870,8 @@ RZ_IPI RzCmdStatus rz_open_binary_show_handler(RzCore *core, int argc, const cha
|
|||
RZ_IPI RzCmdStatus rz_open_binary_add_handler(RzCore *core, int argc, const char **argv);
|
||||
// "obf"
|
||||
RZ_IPI RzCmdStatus rz_open_binary_file_handler(RzCore *core, int argc, const char **argv);
|
||||
// "obs"
|
||||
RZ_IPI RzCmdStatus rz_open_binary_select_handler(RzCore *core, int argc, const char **argv);
|
||||
// "obR"
|
||||
RZ_IPI RzCmdStatus rz_open_binary_reload_handler(RzCore *core, int argc, const char **argv);
|
||||
// "ou"
|
||||
|
|
|
|||
|
|
@ -256,6 +256,20 @@ commands:
|
|||
- name: file
|
||||
type: RZ_CMD_ARG_TYPE_FILE
|
||||
optional: true
|
||||
- name: obs
|
||||
cname: open_binary_select
|
||||
summary: Select the binary version for the specified architecture from the fat binary.
|
||||
args:
|
||||
- name: arch
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
optional: true
|
||||
details:
|
||||
- name: Examples
|
||||
entries:
|
||||
- text: "obs"
|
||||
comment: "List all architectures the fat binary supports contains."
|
||||
- text: "obs sparc"
|
||||
comment: "Select and load the binary for Sparc"
|
||||
- name: obR
|
||||
cname: open_binary_reload
|
||||
summary: Reload the current buffer for setting of the bin (use once only)
|
||||
|
|
|
|||
|
|
@ -425,6 +425,7 @@ typedef struct rz_bin_xtr_metadata_t {
|
|||
char *libname;
|
||||
char *machine;
|
||||
char *type;
|
||||
bool big_endian;
|
||||
const char *xtr_type;
|
||||
} RzBinXtrMetadata;
|
||||
|
||||
|
|
@ -998,21 +999,25 @@ RZ_API RzBinFile *rz_bin_cur(RzBin *bin);
|
|||
RZ_API RzBinObject *rz_bin_cur_object(RzBin *bin);
|
||||
|
||||
// select/list binfiles functions
|
||||
RZ_API bool rz_bin_select(RzBin *bin, const char *arch, int bits, const char *name);
|
||||
RZ_API bool rz_bin_select(RzBin *bin, RZ_NONNULL const char *arch, int bits, RZ_NULLABLE const char *machine, RZ_NULLABLE const char *filename);
|
||||
RZ_API bool rz_bin_select_bfid(RzBin *bin, ut32 bf_id);
|
||||
RZ_API bool rz_bin_use_arch(RzBin *bin, const char *arch, int bits, const char *name);
|
||||
RZ_API bool rz_bin_use_arch(RzBin *bin, const char *arch, int bits, RZ_NULLABLE const char *machine, RZ_NULLABLE const char *filename);
|
||||
RZ_API RzBuffer *rz_bin_create(RzBin *bin, const char *plugin_name, const ut8 *code, int codelen, const ut8 *data, int datalen, RzBinArchOptions *opt);
|
||||
|
||||
RZ_API const char *rz_bin_entry_type_string(int etype);
|
||||
RZ_API ut64 rz_bin_get_first_entrypoint(RZ_NULLABLE RzBinObject *obj);
|
||||
|
||||
RZ_API bool rz_bin_file_object_new_from_xtr_data(RzBin *bin, RzBinFile *bf, RzBinObjectLoadOptions *opts, RzBinXtrData *data);
|
||||
RZ_API bool rz_bin_file_set_xtr_data_as_current_obj(
|
||||
RZ_BORROW RZ_NONNULL RzBin *bin,
|
||||
RZ_BORROW RZ_NONNULL RzBinFile *bf,
|
||||
RZ_BORROW RZ_NONNULL RzBinObjectLoadOptions *opts,
|
||||
RZ_BORROW RZ_NONNULL RzBinXtrData *data);
|
||||
|
||||
// RzBinFile.get
|
||||
RZ_API RzBinFile *rz_bin_file_at(RzBin *bin, ut64 addr);
|
||||
RZ_API RzPVector /*<RzBinSymbol *>*/ *rz_bin_file_get_symbols(RzBinFile *bf);
|
||||
// RzBinFile.find
|
||||
RZ_API RzBinFile *rz_bin_file_find_by_arch_bits(RzBin *bin, const char *arch, int bits);
|
||||
RZ_API RZ_BORROW RzBinFile *rz_bin_file_find_by_arch_bits(RzBin *bin, const char *arch, int bits, RZ_NULLABLE const char *machine, RZ_NULLABLE const char *filename);
|
||||
RZ_API RzBinFile *rz_bin_file_find_by_id(RzBin *bin, ut32 bin_id);
|
||||
RZ_API RzBinFile *rz_bin_file_find_by_fd(RzBin *bin, ut32 bin_fd);
|
||||
RZ_API RzBinFile *rz_bin_file_find_by_name(RzBin *bin, const char *name);
|
||||
|
|
|
|||
|
|
@ -993,7 +993,7 @@ typedef struct rz_core_bin_filter_t {
|
|||
const char *name;
|
||||
} RzCoreBinFilter;
|
||||
|
||||
RZ_API int rz_core_bin_set_arch_bits(RzCore *r, const char *name, const char *arch, ut16 bits);
|
||||
RZ_API bool rz_core_bin_set_arch_bits(RZ_NONNULL RzCore *r, RZ_NULLABLE const char *filename, RZ_NULLABLE const char *arch, ut16 bits);
|
||||
RZ_API int rz_core_bin_update_arch_bits(RzCore *r);
|
||||
RZ_API RZ_OWN char *rz_core_bin_class_build_flag_name(RZ_NONNULL RzBinClass *cls);
|
||||
RZ_API RZ_OWN char *rz_core_bin_super_build_flag_name(RZ_NONNULL RzBinClass *cls);
|
||||
|
|
|
|||
|
|
@ -172,7 +172,7 @@ static int rzbin_show_help(int v) {
|
|||
"-e", "", "Entrypoint",
|
||||
"-ee", "", "Constructor/destructor entrypoints",
|
||||
"-E", "", "Globally exportable symbols",
|
||||
"-f", "[str]", "Select sub-bin named str",
|
||||
"-f", "[mach]", "Select sub-binary for the machine [mach].",
|
||||
"-F", "[binfmt]", "Force to use that bin plugin (ignore header check)",
|
||||
"-g", "", "Same as -SMZIHVResizcld -SS -SSS -ee (show all info)",
|
||||
"-G", "[addr]", "Load address . offset to header",
|
||||
|
|
@ -554,7 +554,7 @@ static int rzbin_do_operation(RzBin *bin, const char *op, int rad, const char *o
|
|||
.baseaddr = UT64_MAX,
|
||||
.loadaddr = rz_bin_get_laddr(bin)
|
||||
};
|
||||
if (xtr_data && !xtr_data->loaded && !rz_bin_file_object_new_from_xtr_data(bin, cur, &obj_opts, xtr_data)) {
|
||||
if (xtr_data && !xtr_data->loaded && !rz_bin_file_set_xtr_data_as_current_obj(bin, cur, &obj_opts, xtr_data)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -717,7 +717,7 @@ RZ_API int rz_main_rz_bin(int argc, const char **argv) {
|
|||
int c, bits = 0, actions = 0;
|
||||
char *create = NULL;
|
||||
ut64 action = RZ_BIN_REQ_UNK;
|
||||
char *tmp, *ptr, *arch_name = NULL;
|
||||
char *tmp, *ptr, *machine = NULL;
|
||||
const char *arch = NULL;
|
||||
const char *forcebin = NULL;
|
||||
const char *chksum = NULL;
|
||||
|
|
@ -858,7 +858,7 @@ RZ_API int rz_main_rz_bin(int argc, const char **argv) {
|
|||
set_action(RZ_BIN_REQ_CLASSES);
|
||||
}
|
||||
break;
|
||||
case 'f': arch_name = rz_str_dup(opt.arg); break;
|
||||
case 'f': machine = rz_str_dup(opt.arg); break;
|
||||
case 'F': forcebin = opt.arg; break;
|
||||
case 'b': bits = rz_num_math(NULL, opt.arg); break;
|
||||
case 'm':
|
||||
|
|
@ -1004,6 +1004,10 @@ RZ_API int rz_main_rz_bin(int argc, const char **argv) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (machine && !(arch && bits)) {
|
||||
RZ_LOG_ERROR("Selecting a machine requires [arch] and [bits].")
|
||||
RZ_FREE(machine);
|
||||
}
|
||||
|
||||
if (is_active(RZ_BIN_REQ_LISTPLUGINS)) {
|
||||
const char *plugin_name = NULL;
|
||||
|
|
@ -1297,12 +1301,12 @@ RZ_API int rz_main_rz_bin(int argc, const char **argv) {
|
|||
start_state(&state);
|
||||
|
||||
// List fatmach0 sub-binaries, etc
|
||||
if (action & RZ_BIN_REQ_LISTARCHS || ((arch || bits || arch_name) && !rz_bin_select(bin, arch, bits, arch_name))) {
|
||||
if (action & RZ_BIN_REQ_LISTARCHS || (arch && bits && !rz_bin_select(bin, arch, bits, machine, NULL))) {
|
||||
RzCmdStateOutput *st = add_header(&state, mode == RZ_OUTPUT_MODE_STANDARD ? RZ_OUTPUT_MODE_TABLE : mode, "archs");
|
||||
rz_core_bin_archs_print(bin, st);
|
||||
add_footer(&state, st);
|
||||
free(arch_name);
|
||||
}
|
||||
free(machine);
|
||||
if (action & RZ_BIN_REQ_PDB_DWNLD) {
|
||||
SPDBOptions pdbopts;
|
||||
pdbopts.symbol_server = (char *)rz_config_get(core.config, "pdb.server");
|
||||
|
|
@ -1339,7 +1343,7 @@ RZ_API int rz_main_rz_bin(int argc, const char **argv) {
|
|||
}
|
||||
if (action & RZ_BIN_REQ_EXTRACT) {
|
||||
if (bf->xtr_data) {
|
||||
rzbin_extract(bin, (!arch && !arch_name && !bits));
|
||||
rzbin_extract(bin, (!arch && !machine && !bits));
|
||||
} else {
|
||||
eprintf(
|
||||
"Cannot extract bins from '%s'. No supported "
|
||||
|
|
|
|||
|
|
@ -105,6 +105,8 @@ a4 = 0x00000000
|
|||
a5 = 0x00000000
|
||||
a6 = 0x00000000
|
||||
a7 = 0x00000000
|
||||
pc = 0x00000000
|
||||
ccr = 0x00
|
||||
fp0 = 0x00000000
|
||||
fp1 = 0x00000000
|
||||
fp2 = 0x00000000
|
||||
|
|
@ -113,9 +115,10 @@ fp4 = 0x00000000
|
|||
fp5 = 0x00000000
|
||||
fp6 = 0x00000000
|
||||
fp7 = 0x00000000
|
||||
pc = 0x00000000
|
||||
fpcr = 0x00000000
|
||||
fpsr = 0x00000000
|
||||
fpiar = 0x00000000
|
||||
sr = 0x00000000
|
||||
ccr = 0x00000000
|
||||
sfc = 0x00000000
|
||||
dfc = 0x00000000
|
||||
usp = 0x00000000
|
||||
|
|
@ -132,8 +135,5 @@ dtt1 = 0x00000000
|
|||
mmusr = 0x00000000
|
||||
urp = 0x00000000
|
||||
srp = 0x00000000
|
||||
fpcr = 0x00000000
|
||||
fpsr = 0x00000000
|
||||
fpiar = 0x00000000
|
||||
EOF
|
||||
RUN
|
||||
|
|
|
|||
|
|
@ -319,10 +319,10 @@ iA
|
|||
iAj
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
offset size arch machine
|
||||
----------------------------------------------------------------------
|
||||
0x00000000 266108 mips_32 mips32 noreorder pic MIPS R3000 big-endian
|
||||
[{"arch":"mips","bits":32,"offset":0,"size":266108,"cpu":"mips32","features":"noreorder pic cpic o32 n32","machine":"MIPS R3000 big-endian"}]
|
||||
offset size arch bits machine big_endian
|
||||
--------------------------------------------------------------------------------------
|
||||
0x00000000 266108 mips mips32 noreorder pic cpi 32 MIPS R3000 big-endian true
|
||||
[{"arch":"mips","bits":32,"big_endian":true,"offset":0,"size":266108,"cpu":"mips32","features":"noreorder pic cpic o32 n32","machine":"MIPS R3000 big-endian"}]
|
||||
EOF
|
||||
RUN
|
||||
|
||||
|
|
@ -333,10 +333,10 @@ iA
|
|||
iAj
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
offset size arch machine
|
||||
-----------------------------------------------------------------------
|
||||
0x00000000 1039368 mips_64 mips64r2 noreorder pi MIPS R3000 big-endian
|
||||
[{"arch":"mips","bits":64,"offset":0,"size":1039368,"cpu":"mips64r2","features":"noreorder pic cpic n64","machine":"MIPS R3000 big-endian"}]
|
||||
offset size arch bits machine big_endian
|
||||
---------------------------------------------------------------------------------------
|
||||
0x00000000 1039368 mips mips64r2 noreorder pic c 64 MIPS R3000 big-endian false
|
||||
[{"arch":"mips","bits":64,"big_endian":false,"offset":0,"size":1039368,"cpu":"mips64r2","features":"noreorder pic cpic n64","machine":"MIPS R3000 big-endian"}]
|
||||
EOF
|
||||
RUN
|
||||
|
||||
|
|
@ -344,9 +344,9 @@ NAME=iA (file x86)
|
|||
FILE=bins/elf/analysis/x86-helloworld-gcc
|
||||
CMDS=iA
|
||||
EXPECT=<<EOF
|
||||
offset size arch machine
|
||||
-----------------------------------
|
||||
0x00000000 4899 x86_32 Intel 80386
|
||||
offset size arch bits machine big_endian
|
||||
-------------------------------------------------
|
||||
0x00000000 4899 x86 32 Intel 80386 false
|
||||
EOF
|
||||
RUN
|
||||
|
||||
|
|
@ -3350,9 +3350,9 @@ NAME=iA (file x86_64)
|
|||
FILE=bins/elf/analysis/hello-linux-x86_64
|
||||
CMDS=iA
|
||||
EXPECT=<<EOF
|
||||
offset size arch machine
|
||||
-----------------------------------------------
|
||||
0x00000000 6710 x86_64 AMD x86-64 architecture
|
||||
offset size arch bits machine big_endian
|
||||
-------------------------------------------------------------
|
||||
0x00000000 6710 x86 64 AMD x86-64 architecture false
|
||||
EOF
|
||||
RUN
|
||||
|
||||
|
|
|
|||
|
|
@ -707,3 +707,183 @@ EXPECT=<<EOF
|
|||
1 fd: 3 +0x00000000 0x00000000 * 0x000001ff rwx
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=M68k, HPPA, Sparc, x86
|
||||
FILE=bins/mach0/2048-NeXTSTEP
|
||||
CMDS=<<EOF
|
||||
iA
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
offset size arch bits machine big_endian
|
||||
------------------------------------------------
|
||||
0x00002000 49152 m68k 32 mc68030 true
|
||||
0x0000e000 40960 x86 32 386 false
|
||||
0x00018000 49152 hppa 32 hppa7100 true
|
||||
0x00024000 49152 sparc 32 all true
|
||||
EOF
|
||||
EXPECT_ERR=
|
||||
RUN
|
||||
|
||||
NAME=M68k, HPPA, Sparc, x86
|
||||
FILE=bins/mach0/2048-NeXTSTEP
|
||||
CMDS=<<EOF
|
||||
|
||||
# Test if sane defaults were selected
|
||||
echo default (m68k)
|
||||
e asm.arch
|
||||
e asm.cpu
|
||||
e asm.bits
|
||||
e cfg.bigendian
|
||||
pd 10 @ section.0.__TEXT.__text
|
||||
|
||||
obs hppa_32_hppa7100
|
||||
e asm.arch
|
||||
e asm.cpu
|
||||
e asm.bits
|
||||
e cfg.bigendian
|
||||
pd 10 @ section.0.__TEXT.__text
|
||||
|
||||
obs sparc_32_all
|
||||
e asm.arch
|
||||
e asm.cpu
|
||||
e asm.bits
|
||||
e cfg.bigendian
|
||||
pd 10 @ section.0.__TEXT.__text
|
||||
|
||||
obs x86_32_386
|
||||
e asm.arch
|
||||
e asm.cpu
|
||||
e asm.bits
|
||||
e cfg.bigendian
|
||||
pd 10 @ section.0.__TEXT.__text
|
||||
|
||||
obs m68k_32_mc68030
|
||||
e asm.arch
|
||||
e asm.cpu
|
||||
e asm.bits
|
||||
e cfg.bigendian
|
||||
pd 10 @ section.0.__TEXT.__text
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
default (m68k)
|
||||
m68k
|
||||
mc68030
|
||||
32
|
||||
true
|
||||
;-- section.0.__TEXT.__text:
|
||||
0x000049c0 movea.l a7, a0 ; [00] -r-x section size 6638 named 0.__TEXT.__text
|
||||
0x000049c2 suba.w 0xc, a7
|
||||
0x000049c6 move.l (a0)+, d0
|
||||
0x000049c8 move.l d0, (a7)
|
||||
0x000049ca move.l d0, 0x8004.l
|
||||
0x000049d0 move.l a0, 0x4(a7)
|
||||
0x000049d4 move.l a0, 0x8008.l
|
||||
0x000049da addq.l 0x1, d0
|
||||
0x000049dc asl.l 0x2, d0
|
||||
0x000049de adda.l d0, a0
|
||||
hppa
|
||||
hppa7100
|
||||
32
|
||||
true
|
||||
;-- section.0.__TEXT.__text:
|
||||
0x000039e8 ldw 0(sp),r26 ; [00] -r-x section size 10588 named 0.__TEXT.__text
|
||||
0x000039ec ldo 7f(sp),sp
|
||||
0x000039f0 ldil L%3800,r1
|
||||
0x000039f4 be 1fc(sr4,r1)
|
||||
0x000039f8 depwi 0,31,6,sp
|
||||
0x000039fc stw rp,-14(sp)
|
||||
0x00003a00 stw,ma r5,80(sp)
|
||||
0x00003a04 stw r4,-7c(sp)
|
||||
0x00003a08 stw r3,-78(sp)
|
||||
0x00003a0c copy r26,r4
|
||||
sparc
|
||||
all
|
||||
32
|
||||
true
|
||||
;-- section.0.__TEXT.__text:
|
||||
0x0000441c mov sp, o0 ; [00] -r-x section size 7912 named 0.__TEXT.__text
|
||||
0x00004420 sethi 0x11, o5
|
||||
0x00004424 or o5, 0x30, o5
|
||||
0x00004428 jmp o5
|
||||
0x0000442c nop
|
||||
0x00004430 save sp, -0x70, sp
|
||||
0x00004434 add i0, 0x44, o1
|
||||
0x00004438 sethi 0x20, o2
|
||||
0x0000443c st o1, [o2+8]
|
||||
0x00004440 ld [i0+0x40], o0
|
||||
x86
|
||||
386
|
||||
32
|
||||
false
|
||||
;-- section.0.__TEXT.__text:
|
||||
0x00002a24 push ebp ; [00] -r-x section size 6524 named 0.__TEXT.__text
|
||||
0x00002a25 mov ebp, esp
|
||||
0x00002a27 push edi
|
||||
0x00002a28 push esi
|
||||
0x00002a29 push ebx
|
||||
0x00002a2a lea esi, dword [ebp+0x04]
|
||||
0x00002a2d mov edx, dword [esi]
|
||||
0x00002a2f mov dword [0x6004], edx
|
||||
0x00002a35 lea eax, dword [esi+0x04]
|
||||
0x00002a38 mov dword [0x6008], eax
|
||||
m68k
|
||||
mc68030
|
||||
32
|
||||
true
|
||||
;-- section.0.__TEXT.__text:
|
||||
0x000049c0 movea.l a7, a0 ; [00] -r-x section size 6638 named 0.__TEXT.__text
|
||||
0x000049c2 suba.w 0xc, a7
|
||||
0x000049c6 move.l (a0)+, d0
|
||||
0x000049c8 move.l d0, (a7)
|
||||
0x000049ca move.l d0, 0x8004.l
|
||||
0x000049d0 move.l a0, 0x4(a7)
|
||||
0x000049d4 move.l a0, 0x8008.l
|
||||
0x000049da addq.l 0x1, d0
|
||||
0x000049dc asl.l 0x2, d0
|
||||
0x000049de adda.l d0, a0
|
||||
EOF
|
||||
EXPECT_ERR=<<EOF
|
||||
ERROR: unknown thread state structure 11
|
||||
ERROR: mach0: Cannot parse thread
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=Switch between same archs, with different bits and machine
|
||||
FILE=bins/mach0/AppIOSEntitlements.ios
|
||||
CMDS=<<EOF
|
||||
obs
|
||||
echo "# default"
|
||||
e asm.arch
|
||||
e asm.bits
|
||||
e asm.cpu
|
||||
|
||||
obs arm_64_all
|
||||
echo "# arm_64_all"
|
||||
e asm.arch
|
||||
e asm.bits
|
||||
e asm.cpu
|
||||
|
||||
obs arm_32_v7
|
||||
echo "# arm_32_v7"
|
||||
e asm.arch
|
||||
e asm.bits
|
||||
e asm.cpu
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
arm_32_v7
|
||||
arm_64_all
|
||||
# default
|
||||
arm
|
||||
32
|
||||
v7
|
||||
# arm_64_all
|
||||
arm
|
||||
64
|
||||
all
|
||||
# arm_32_v7
|
||||
arm
|
||||
32
|
||||
v7
|
||||
EOF
|
||||
EXPECT_ERR=
|
||||
RUN
|
||||
|
|
|
|||
|
|
@ -181,12 +181,12 @@ iA
|
|||
iAj
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
offset size arch machine
|
||||
-----------------------------------
|
||||
0x00001000 13792 x86_64 x86 64 all
|
||||
0x00005000 13760 x86_32 386
|
||||
0x00009000 13616 ppc_32 7400
|
||||
[{"arch":"x86","bits":64,"offset":4096,"size":13792,"machine":"x86 64 all"},{"arch":"x86","bits":32,"offset":20480,"size":13760,"machine":"386"},{"arch":"ppc","bits":32,"offset":36864,"size":13616,"machine":"7400"}]
|
||||
offset size arch bits machine big_endian
|
||||
-------------------------------------------------
|
||||
0x00001000 13792 x86 64 x86 64 all false
|
||||
0x00005000 13760 x86 32 386 false
|
||||
0x00009000 13616 ppc 32 7400 true
|
||||
[{"arch":"x86","bits":64,"big_endian":false,"offset":4096,"size":13792,"machine":"x86 64 all"},{"arch":"x86","bits":32,"big_endian":false,"offset":20480,"size":13760,"machine":"386"},{"arch":"ppc","bits":32,"big_endian":true,"offset":36864,"size":13616,"machine":"7400"}]
|
||||
EOF
|
||||
RUN
|
||||
|
||||
|
|
@ -198,13 +198,13 @@ CMDS=<<EOF
|
|||
EOF
|
||||
EXPECT=<<EOF
|
||||
[Archs]
|
||||
offset size arch machine
|
||||
-----------------------------------
|
||||
0x00001000 13792 x86_64 x86 64 all
|
||||
0x00005000 13760 x86_32 386
|
||||
0x00009000 13616 ppc_32 7400
|
||||
offset size arch bits machine big_endian
|
||||
-------------------------------------------------
|
||||
0x00001000 13792 x86 64 x86 64 all false
|
||||
0x00005000 13760 x86 32 386 false
|
||||
0x00009000 13616 ppc 32 7400 true
|
||||
|
||||
{"archs":[{"arch":"x86","bits":64,"offset":4096,"size":13792,"machine":"x86 64 all"},{"arch":"x86","bits":32,"offset":20480,"size":13760,"machine":"386"},{"arch":"ppc","bits":32,"offset":36864,"size":13616,"machine":"7400"}]}
|
||||
{"archs":[{"arch":"x86","bits":64,"big_endian":false,"offset":4096,"size":13792,"machine":"x86 64 all"},{"arch":"x86","bits":32,"big_endian":false,"offset":20480,"size":13760,"machine":"386"},{"arch":"ppc","bits":32,"big_endian":true,"offset":36864,"size":13616,"machine":"7400"}]}
|
||||
EOF
|
||||
RUN
|
||||
|
||||
|
|
@ -309,3 +309,19 @@ EXPECT=<<EOF
|
|||
0x100004090 0x0000000100009338 8....... 4295004984 18.__DATA.__objc_data class SceneDelegate R 0x100009310
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=M68k, HPPA, Sparc, x86
|
||||
FILE=bins/mach0/2048-NeXTSTEP
|
||||
CMDS=<<EOF
|
||||
iA
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
offset size arch bits machine big_endian
|
||||
------------------------------------------------
|
||||
0x00002000 49152 m68k 32 mc68030 true
|
||||
0x0000e000 40960 x86 32 386 false
|
||||
0x00018000 49152 hppa 32 hppa7100 true
|
||||
0x00024000 49152 sparc 32 all true
|
||||
EOF
|
||||
EXPECT_ERR=
|
||||
RUN
|
||||
|
|
|
|||
|
|
@ -112,12 +112,12 @@ RUN
|
|||
|
||||
NAME=mach0 arm64e legacy chained imports (BIND_OPCODE_THREADED)
|
||||
FILE=bins/mach0/imports-arm64e-threaded
|
||||
ARGS=-a arm -b 64
|
||||
CMDS=<<EOF
|
||||
obs arm_64_arm64e
|
||||
ii
|
||||
ir
|
||||
pxr 0x10 @ section.13.__DATA.__objc_classrefs
|
||||
pD 0x10 @ section.13.__DATA.__objc_classrefs
|
||||
pxr 0x10 @ section.15.__DATA.__objc_classrefs
|
||||
pD 0x10 @ section.15.__DATA.__objc_classrefs
|
||||
ic
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
|
|
@ -157,12 +157,14 @@ nth vaddr bind type lib name
|
|||
0x100008108 0x00008108 0x100010048 SET_64 NSObject
|
||||
0x100008110 0x00008110 0x100010040 SET_64 _objc_empty_cache
|
||||
0x100008120 0x00008120 0x00000000 SET_64
|
||||
0x1000080c0 0x0000000100008100 ........ @ section.13.__DATA.__objc_classrefs 4295000320 15.__DATA.__objc_data class Stub R 0x1000080d8
|
||||
0x1000080c8 0x0000000100010030 0....... @ reloc.NSString 4295032880 NSString R 0x0
|
||||
;-- section.13.__DATA.__objc_classrefs:
|
||||
0x1000080c0 .qword 0x0000000100008100 ; sym.class_Stub; RELOC 64 ; [13] -rw- section size 16 named 13.__DATA.__objc_classrefs
|
||||
0x1000080e0 0x0000000100010038 8....... @ reloc.NSObject.1000080e0 4295032888 NSObject R 0x0
|
||||
0x1000080e8 0x0000000100010040 @....... @ reloc._objc_empty_cache.1000080e8 4295032896 _objc_empty_cache R 0x0
|
||||
;-- section.15.__DATA.__objc_classrefs:
|
||||
;-- NSObject:
|
||||
0x1000080e0 .qword 0x0000000100010038 ; reloc.target.NSObject; RELOC 64 NSObject ; [15] -rw- section size 16 named 15.__DATA.__objc_classrefs
|
||||
;-- NSString:
|
||||
0x1000080c8 .qword 0x0000000100010030 ; reloc.target.NSString; RELOC 64 NSString
|
||||
;-- _objc_empty_cache:
|
||||
0x1000080e8 .qword 0x0000000100010040 ; reloc.target._objc_empty_cache; RELOC 64 _objc_empty_cache
|
||||
address min max name super
|
||||
--------------------------------------------------
|
||||
0x1000080d8 0x1000080d8 0x1000080d8 Stub NSObject
|
||||
|
|
@ -171,9 +173,9 @@ RUN
|
|||
|
||||
NAME=mach0 arm64e chained imports
|
||||
FILE=bins/mach0/imports-arm64e-chained
|
||||
ARGS=-a arm -b 64
|
||||
CMDS=<<EOF
|
||||
ii
|
||||
pd 3 @ 0x100003f48
|
||||
ir
|
||||
pxr 0x10 @ section.13.__DATA.__objc_classrefs
|
||||
pD 0x10 @ section.13.__DATA.__objc_classrefs
|
||||
|
|
@ -182,15 +184,19 @@ EOF
|
|||
EXPECT=<<EOF
|
||||
nth vaddr bind type lib name
|
||||
-----------------------------------------------------------------
|
||||
0 0x100003f20 NONE FUNC objc_alloc
|
||||
1 0x100003f30 NONE FUNC objc_alloc_init
|
||||
2 0x100003f40 NONE FUNC objc_autoreleasePoolPop
|
||||
3 0x100003f50 NONE FUNC objc_autoreleasePoolPush
|
||||
0 0x100003f30 NONE FUNC objc_alloc
|
||||
1 0x100003f3c NONE FUNC objc_alloc_init
|
||||
2 0x100003f48 NONE FUNC objc_autoreleasePoolPop
|
||||
3 0x100003f54 NONE FUNC objc_autoreleasePoolPush
|
||||
4 ---------- NONE FUNC objc_msgSend
|
||||
5 ---------- NONE OBJC_CLASS NSString
|
||||
6 ---------- NONE FUNC _objc_empty_cache
|
||||
7 ---------- NONE OBJC_METACLASS NSObject
|
||||
8 ---------- NONE OBJC_CLASS NSObject
|
||||
;-- objc_autoreleasePoolPop:
|
||||
0x100003f48 adrp x16, reloc.objc_alloc ; 0x100004000
|
||||
0x100003f4c ldr x16, [x16, 0x10] ; [0x10:4]=0x400000
|
||||
0x100003f50 br x16
|
||||
vaddr paddr target type name
|
||||
-------------------------------------------------------------------
|
||||
0x100004000 0x00004000 0x100010008 SET_64 objc_alloc
|
||||
|
|
|
|||
|
|
@ -5,6 +5,5 @@ EOF
|
|||
EXPECT_ERR=<<EOF
|
||||
ERROR: malformed uleb128
|
||||
ERROR: malformed uleb128
|
||||
ERROR: Invalid size for a load command
|
||||
EOF
|
||||
RUN
|
||||
|
|
|
|||
|
|
@ -1272,3 +1272,55 @@ paddr vaddr len size section type string
|
|||
EOF
|
||||
EXPECT_ERR=
|
||||
RUN
|
||||
|
||||
NAME=fat binary - endianness
|
||||
FILE=bins/mach0/2048-NeXTSTEP
|
||||
CMDS=!rz-bin -I -A ${RZ_FILE}
|
||||
EXPECT=<<EOF
|
||||
[Archs]
|
||||
offset size arch bits machine big_endian
|
||||
------------------------------------------------
|
||||
0x00002000 49152 m68k 32 mc68030 true
|
||||
0x0000e000 40960 x86 32 386 false
|
||||
0x00018000 49152 hppa 32 hppa7100 true
|
||||
0x00024000 49152 sparc 32 all true
|
||||
|
||||
[Info]
|
||||
arch m68k
|
||||
cpu mc68030
|
||||
features N/A
|
||||
baddr 0x00002000
|
||||
binsz 0x0000e000
|
||||
bintype mach0
|
||||
bits 32
|
||||
class MACH0
|
||||
compiler N/A
|
||||
dbg_file N/A
|
||||
endian BE
|
||||
hdr.csum N/A
|
||||
guid N/A
|
||||
intrp N/A
|
||||
laddr 0x00000000
|
||||
lang c
|
||||
machine mc68030
|
||||
minopsz 1
|
||||
os darwin
|
||||
cc N/A
|
||||
rpath N/A
|
||||
subsys unknown
|
||||
stripped false
|
||||
crypto false
|
||||
havecode true
|
||||
va true
|
||||
sanitiz false
|
||||
static true
|
||||
linenum false
|
||||
lsyms false
|
||||
canary false
|
||||
PIE false
|
||||
RELROCS false
|
||||
NX false
|
||||
|
||||
EOF
|
||||
EXPECT_ERR=
|
||||
RUN
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue