Change output of iH to support structured data. (#5263)

This commit is contained in:
Giovanni 2025-08-23 22:23:14 +08:00 committed by GitHub
parent 684277d227
commit 9db7089248
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
67 changed files with 4110 additions and 1894 deletions

View file

@ -193,6 +193,7 @@ RZ_IPI void rz_bin_object_free(RzBinObject *o) {
ht_sp_free(o->import_name_symbols);
ht_up_free(o->vaddr_to_class_method);
rz_bin_info_free(o->info);
rz_structured_data_free(o->structured_data);
rz_bin_reloc_storage_free(o->relocs);
rz_bin_source_line_info_free(o->lines);
rz_bin_string_database_free(o->strings);
@ -690,6 +691,11 @@ RZ_API const RzBinInfo *rz_bin_object_get_info(RZ_NONNULL RzBinObject *obj) {
return obj->info;
}
RZ_API const RzStructuredData *rz_bin_object_get_structured_data(RZ_BORROW RZ_NONNULL RzBinObject *obj) {
rz_return_val_if_fail(obj, NULL);
return obj->structured_data;
}
/**
* \brief Get pvector of \p char* representing the libraries used by the binary object.
*/

View file

@ -51,6 +51,11 @@ RZ_IPI void rz_bin_set_and_process_file(RzBinFile *bf, RzBinObject *o) {
o->info = NULL;
}
rz_structured_data_free(o->structured_data);
if (!plugin->bin_structure || !(o->structured_data = plugin->bin_structure(bf))) {
o->structured_data = NULL;
}
rz_bin_source_line_info_free(o->lines);
if (!plugin->lines || !(o->lines = plugin->lines(bf))) {
o->lines = NULL;

View file

@ -269,7 +269,7 @@ RZ_OWN char *Elf_(rz_bin_elf_get_e_shstrndx_as_string)(RZ_NONNULL ELFOBJ *bin);
RZ_OWN char *Elf_(rz_bin_elf_get_e_type_as_string)(RZ_NONNULL ELFOBJ *bin);
RZ_OWN char *Elf_(rz_bin_elf_get_e_version_as_string)(RZ_NONNULL ELFOBJ *bin);
bool Elf_(rz_bin_elf_get_ehdr)(RZ_NONNULL ELFOBJ *bin);
bool Elf_(rz_bin_elf_print_ehdr)(ELFOBJ *bin, RZ_NONNULL PrintfCallback cb);
RzStructuredData *Elf_(rz_bin_elf_ehdr)(ELFOBJ *bin);
// elf_hash.c
bool Elf_(rz_bin_elf_get_gnu_hash_table)(RZ_NONNULL ELFOBJ *bin, RzBinElfGnuHashTable *result);

View file

@ -72,6 +72,10 @@ RzBinInfo *elf64_info(RzBinFile *bf) {
return info(bf);
}
RzStructuredData *elf64_structure(ELFOBJ *bin) {
return Elf_(rz_bin_elf_ehdr)(bin);
}
RzPVector /*<RzBinField *>*/ *elf64_fields(RzBinFile *bf) {
return fields(bf);
}
@ -104,14 +108,6 @@ int elf64_check_buffer_aux(RzBuffer *buf) {
return check_buffer_aux(buf);
}
void elf64_headers(RzBinFile *bf) {
headers(bf);
}
void elf64_headers_obj(ELFOBJ *bin, RZ_NONNULL PrintfCallback cb) {
headers_obj(bin, cb);
}
RzBuffer *elf64_create_elf(RzBin *bin, const ut8 *code, int codelen, const ut8 *data, int datalen, RzBinArchOptions *opt) {
return create_elf(bin, code, codelen, data, datalen, opt);
}

View file

@ -26,6 +26,7 @@ RzPVector /*<RzBinSymbol *>*/ *elf64_symbols_obj(void *elf_obj);
RzPVector /*<RzBinSymbol *>*/ *elf64_symbols(RzBinFile *bf);
RzPVector /*<RzBinImport *>*/ *elf64_imports(RzBinFile *bf);
RzBinInfo *elf64_info(RzBinFile *bf);
RzStructuredData *elf64_structure(ELFOBJ *bin);
RzPVector /*<RzBinField *>*/ *elf64_fields(RzBinFile *bf);
ut64 elf64_size(RzBinFile *bf);
RzPVector /*<char *>*/ *elf64_libs(RzBinFile *bf);
@ -34,8 +35,6 @@ int elf64_get_file_type(RzBinFile *bf);
char *elf64_regstate(RzBinFile *bf);
void elf64_destroy(RzBinFile *bf);
int elf64_check_buffer_aux(RzBuffer *buf);
void elf64_headers(RzBinFile *bf);
void elf64_headers_obj(ELFOBJ *bin, RZ_NONNULL PrintfCallback cb);
RzBuffer *elf64_create_elf(RzBin *bin, const ut8 *code, int codelen, const ut8 *data, int datalen, RzBinArchOptions *opt);
RzPVector /*<RzBinMap *>*/ *elf64_maps_unpatched_obj(void *elf_obj, size_t size);
RzBinAddr *elf64_addr_new_from_paddr(ELFOBJ *bin, ut64 paddr);

View file

@ -67,18 +67,6 @@ static bool is_valid_elf_ident(ut8 *e_ident) {
return !memcmp(e_ident, ELFMAG, SELFMAG) || !memcmp(e_ident, CGCMAG, SCGCMAG);
}
static bool print_ehdr_aux(ELFOBJ *bin, PrintfCallback cb, ut64 offset, const char *name, char *(*get_value)(ELFOBJ *bin)) {
char *tmp = get_value(bin);
if (!tmp) {
return false;
}
cb("0x%08" PFMT64x " %-10s %s\n", offset, name, tmp);
free(tmp);
return true;
}
RZ_OWN char *Elf_(rz_bin_elf_get_e_ehsize_as_string)(RZ_NONNULL ELFOBJ *bin) {
rz_return_val_if_fail(bin, NULL);
@ -199,21 +187,57 @@ bool Elf_(rz_bin_elf_get_ehdr)(RZ_NONNULL ELFOBJ *bin) {
return read_ehdr_other(bin);
}
bool Elf_(rz_bin_elf_print_ehdr)(ELFOBJ *bin, RZ_NONNULL PrintfCallback cb) {
rz_return_val_if_fail(bin && cb, false);
RzStructuredData *Elf_(rz_bin_elf_ehdr)(ELFOBJ *bin) {
rz_return_val_if_fail(bin, NULL);
return print_ehdr_aux(bin, cb, E_IDENT_OFFSET, "MAGIC", Elf_(rz_bin_elf_get_e_indent_as_string)) &&
print_ehdr_aux(bin, cb, E_TYPE_OFFSET, "Type", Elf_(rz_bin_elf_get_e_type_as_string)) &&
print_ehdr_aux(bin, cb, E_MACHINE_OFFSET, "Machine", Elf_(rz_bin_elf_get_e_machine_as_string)) &&
print_ehdr_aux(bin, cb, E_VERSION_OFFSET, "Version", Elf_(rz_bin_elf_get_e_version_as_string)) &&
print_ehdr_aux(bin, cb, E_ENTRYPOINT_OFFSET, "Entrypoint", Elf_(rz_bin_elf_get_e_entry_as_string)) &&
print_ehdr_aux(bin, cb, E_PHOFF_OFFSET, "PhOff", Elf_(rz_bin_elf_get_e_phoff_as_string)) &&
print_ehdr_aux(bin, cb, E_SHOFF_OFFSET, "ShOff", Elf_(rz_bin_elf_get_e_shoff_as_string)) &&
print_ehdr_aux(bin, cb, E_FLAGS_OFFSET, "Flags", Elf_(rz_bin_elf_get_e_flags_as_string)) &&
print_ehdr_aux(bin, cb, E_EHSIZE_OFFSET, "EhSize", Elf_(rz_bin_elf_get_e_ehsize_as_string)) &&
print_ehdr_aux(bin, cb, E_PHENTSIZE_OFFSET, "PhentSize", Elf_(rz_bin_elf_get_e_phentsize_as_string)) &&
print_ehdr_aux(bin, cb, E_PHNUM_OFFSET, "PhNum", Elf_(rz_bin_elf_get_e_phnum_as_string)) &&
print_ehdr_aux(bin, cb, E_SHENTSIZE_OFFSET, "ShentSize", Elf_(rz_bin_elf_get_e_shentsize_as_string)) &&
print_ehdr_aux(bin, cb, E_SHNUM_OFFSET, "ShNum", Elf_(rz_bin_elf_get_e_shnum_as_string)) &&
print_ehdr_aux(bin, cb, E_SHSTRNDX_OFFSET, "ShStrndx", Elf_(rz_bin_elf_get_e_shstrndx_as_string));
RzStructuredData *header = rz_structured_data_new_map();
if (!header) {
return NULL;
}
RzStructuredData *elf = rz_structured_data_map_add_map(header, "elf");
if (!elf) {
goto fail;
}
RzStructuredData *e_ident = rz_structured_data_map_add_map(elf, "e_ident");
if (!e_ident) {
goto fail;
}
char *e_ident_bytes = Elf_(rz_bin_elf_get_e_indent_as_string)(bin);
if (!e_ident_bytes) {
goto fail;
}
if (!(rz_structured_data_map_add_string(e_ident, "bytes", e_ident_bytes) &&
rz_structured_data_map_add_unsigned(e_ident, "ei_class", bin->ehdr.e_ident[EI_CLASS], false) &&
rz_structured_data_map_add_unsigned(e_ident, "ei_data", bin->ehdr.e_ident[EI_DATA], false) &&
rz_structured_data_map_add_unsigned(e_ident, "ei_version", bin->ehdr.e_ident[EI_VERSION], false) &&
rz_structured_data_map_add_unsigned(e_ident, "ei_osabi", bin->ehdr.e_ident[EI_OSABI], false) &&
rz_structured_data_map_add_unsigned(e_ident, "ei_abiversion", bin->ehdr.e_ident[EI_ABIVERSION], false))) {
goto fail;
}
free(e_ident_bytes);
if (!(rz_structured_data_map_add_unsigned(elf, "e_machine", bin->ehdr.e_machine, false) &&
rz_structured_data_map_add_unsigned(elf, "e_version", bin->ehdr.e_version, false) &&
rz_structured_data_map_add_unsigned(elf, "e_entry", bin->ehdr.e_entry, true) &&
rz_structured_data_map_add_unsigned(elf, "e_phoff", bin->ehdr.e_phoff, true) &&
rz_structured_data_map_add_unsigned(elf, "e_shoff", bin->ehdr.e_shoff, true) &&
rz_structured_data_map_add_unsigned(elf, "e_flags", bin->ehdr.e_flags, true) &&
rz_structured_data_map_add_unsigned(elf, "e_ehsize", bin->ehdr.e_ehsize, false) &&
rz_structured_data_map_add_unsigned(elf, "e_phentsize", bin->ehdr.e_phentsize, false) &&
rz_structured_data_map_add_unsigned(elf, "e_phnum", bin->ehdr.e_phnum, false) &&
rz_structured_data_map_add_unsigned(elf, "e_shentsize", bin->ehdr.e_shentsize, false) &&
rz_structured_data_map_add_unsigned(elf, "e_shnum", bin->ehdr.e_shnum, false) &&
rz_structured_data_map_add_unsigned(elf, "e_shstrndx", bin->ehdr.e_shstrndx, false))) {
goto fail;
}
return header;
fail:
rz_structured_data_free(header);
return NULL;
}

View file

@ -148,6 +148,10 @@ RzBinInfo *elf_info(RzBinFile *bf) {
return info(bf);
}
RzStructuredData *elf_structure(ELFOBJ *bin) {
return Elf_(rz_bin_elf_ehdr)(bin);
}
RzPVector /*<RzBinField *>*/ *elf_fields(RzBinFile *bf) {
return fields(bf);
}
@ -180,14 +184,6 @@ int elf_check_buffer_aux(RzBuffer *buf) {
return check_buffer_aux(buf);
}
void elf_headers(RzBinFile *bf) {
headers(bf);
}
void elf_headers_obj(ELFOBJ *bin, RZ_NONNULL PrintfCallback cb) {
headers_obj(bin, cb);
}
RzBuffer *elf_create_elf(RzBin *bin, const ut8 *code, int codelen, const ut8 *data, int datalen, RzBinArchOptions *opt) {
return create_elf(bin, code, codelen, data, datalen, opt);
}

View file

@ -26,6 +26,7 @@ RzPVector /*<RzBinSymbol *>*/ *elf_symbols_obj(void *elf_obj);
RzPVector /*<RzBinSymbol *>*/ *elf_symbols(RzBinFile *bf);
RzPVector /*<RzBinImport *>*/ *elf_imports(RzBinFile *bf);
RzBinInfo *elf_info(RzBinFile *bf);
RzStructuredData *elf_structure(ELFOBJ *bin);
RzPVector /*<RzBinField *>*/ *elf_fields(RzBinFile *bf);
ut64 elf_size(RzBinFile *bf);
RzPVector /*<char *>*/ *elf_libs(RzBinFile *bf);
@ -34,8 +35,6 @@ int elf_get_file_type(RzBinFile *bf);
char *elf_regstate(RzBinFile *bf);
void elf_destroy(RzBinFile *bf);
int elf_check_buffer_aux(RzBuffer *buf);
void elf_headers(RzBinFile *bf);
void elf_headers_obj(ELFOBJ *bin, RZ_NONNULL PrintfCallback cb);
RzBuffer *elf_create_elf(RzBin *bin, const ut8 *code, int codelen, const ut8 *data, int datalen, RzBinArchOptions *opt);
RzPVector /*<RzBinMap *>*/ *elf_maps_unpatched_obj(void *elf_obj, size_t size);
RzBinAddr *elf_addr_new_from_paddr(ELFOBJ *bin, ut64 paddr);

View file

@ -25,16 +25,16 @@ typedef struct {
int j;
int symbols_count;
HtSP *hash;
} RSymCtx;
} SymCtx;
typedef void (*RExportsIterator)(struct MACH0_(obj_t) * bin, const char *name, ut64 flags, ut64 offset, void *ctx);
typedef void (*ExportsIterator)(struct MACH0_(obj_t) * bin, const char *name, ut64 flags, ut64 offset, void *ctx);
typedef struct {
ut8 *node;
char *label;
int i;
ut8 *next_child;
} RTrieState;
} TrieState;
// OMG; THIS SHOULD BE KILLED; this var exposes the local native endian, which is completely unnecessary
// USE THIS: int ws = bf->o->info->big_endian;
@ -2304,7 +2304,7 @@ RZ_API RZ_OWN char *MACH0_(get_name)(struct MACH0_(obj_t) * mo, ut32 stridx, boo
return NULL;
}
static int walk_exports(struct MACH0_(obj_t) * bin, RExportsIterator iterator, void *ctx) {
static int walk_exports(struct MACH0_(obj_t) * bin, ExportsIterator iterator, void *ctx) {
rz_return_val_if_fail(bin, 0);
if (!bin->dyld_info) {
return 0;
@ -2333,7 +2333,7 @@ static int walk_exports(struct MACH0_(obj_t) * bin, RExportsIterator iterator, v
goto beach;
}
RTrieState *root = RZ_NEW0(RTrieState);
TrieState *root = RZ_NEW0(TrieState);
if (!root) {
goto beach;
}
@ -2343,7 +2343,7 @@ static int walk_exports(struct MACH0_(obj_t) * bin, RExportsIterator iterator, v
rz_list_push(states, root);
do {
RTrieState *state = rz_list_last(states);
TrieState *state = rz_list_last(states);
p = state->node;
ut64 len = read_uleb128(&p, end);
if (len == UT64_MAX) {
@ -2377,7 +2377,7 @@ static int walk_exports(struct MACH0_(obj_t) * bin, RExportsIterator iterator, v
if (iterator && !isReexport) {
char *name = NULL;
RzListIter *iter;
RTrieState *s;
TrieState *s;
rz_list_foreach (states, iter, s) {
if (!s->label) {
continue;
@ -2418,7 +2418,7 @@ static int walk_exports(struct MACH0_(obj_t) * bin, RExportsIterator iterator, v
} else {
p = state->next_child;
}
RTrieState *next = RZ_NEW0(RTrieState);
TrieState *next = RZ_NEW0(TrieState);
if (!next) {
goto beach;
}
@ -2443,7 +2443,7 @@ static int walk_exports(struct MACH0_(obj_t) * bin, RExportsIterator iterator, v
{
// avoid loops
RzListIter *it;
RTrieState *s;
TrieState *s;
rz_list_foreach (states, it, s) {
if (s->node == next->node) {
RZ_LOG_ERROR("malformed export trie\n");
@ -2465,7 +2465,7 @@ beach:
}
static void assign_export_symbol_t(struct MACH0_(obj_t) * bin, const char *name, ut64 flags, ut64 offset, void *ctx) {
RSymCtx *sym_ctx = (RSymCtx *)ctx;
SymCtx *sym_ctx = (SymCtx *)ctx;
int j = sym_ctx->j;
if (j < sym_ctx->symbols_count) {
sym_ctx->symbols[j].offset = offset;
@ -2650,7 +2650,7 @@ const struct symbol_t *MACH0_(get_symbols)(struct MACH0_(obj_t) * bin) {
}
}
if (n_exports && (symbols_count - j) >= n_exports) {
RSymCtx sym_ctx;
SymCtx sym_ctx;
sym_ctx.symbols = symbols;
sym_ctx.j = j;
sym_ctx.symbols_count = symbols_count;
@ -3007,6 +3007,7 @@ void MACH0_(mach_headerfields)(RzBinFile *bf) {
addr += 4; \
pvaddr += 4; \
word = isBe ? rz_read_be32(wordbuf) : rz_read_le32(wordbuf);
if (is64) {
addr += 4;
pvaddr += 4;
@ -3284,6 +3285,411 @@ void MACH0_(mach_headerfields)(RzBinFile *bf) {
free(mh);
}
RzStructuredData *MACH0_(mach_structure)(RzBinFile *bf) {
rz_return_val_if_fail(bf && bf->o && bf->o->bin_obj, NULL);
RzBuffer *buf = bf->buf;
ut64 length = rz_buf_size(buf);
struct MACH0_(mach_header) *mh = MACH0_(get_hdr)(buf);
if (!mh) {
return NULL;
}
ut64 addr = 0x20 - 4;
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();
if (!info) {
return NULL;
}
#if RZ_BIN_MACH064
RzStructuredData *mach0 = rz_structured_data_map_add_map(info, "mach0_64");
#else
RzStructuredData *mach0 = rz_structured_data_map_add_map(info, "mach0");
#endif
if (!mach0) {
rz_structured_data_free(info);
return NULL;
}
rz_structured_data_map_add_unsigned(mach0, "Magic", mh->magic, true);
switch (mh->cputype) {
case CPU_TYPE_VAX:
rz_structured_data_map_add_string(mach0, "CpuType", "vax");
break;
case CPU_TYPE_MC680x0:
rz_structured_data_map_add_string(mach0, "CpuType", "mc680x0");
break;
case CPU_TYPE_X86:
rz_structured_data_map_add_string(mach0, "CpuType", "x86");
break;
case CPU_TYPE_X86_64:
rz_structured_data_map_add_string(mach0, "CpuType", "x86_64");
break;
case CPU_TYPE_MIPS:
rz_structured_data_map_add_string(mach0, "CpuType", "mips");
break;
case CPU_TYPE_MC98000:
rz_structured_data_map_add_string(mach0, "CpuType", "mc98000");
break;
case CPU_TYPE_HPPA:
rz_structured_data_map_add_string(mach0, "CpuType", "HPPA");
break;
case CPU_TYPE_ARM:
rz_structured_data_map_add_string(mach0, "CpuType", "arm");
break;
case CPU_TYPE_ARM64:
rz_structured_data_map_add_string(mach0, "CpuType", "arm64");
break;
case CPU_TYPE_ARM64_32:
rz_structured_data_map_add_string(mach0, "CpuType", "arm64_32");
break;
case CPU_TYPE_MC88000:
rz_structured_data_map_add_string(mach0, "CpuType", "mc88000");
break;
case CPU_TYPE_SPARC:
rz_structured_data_map_add_string(mach0, "CpuType", "sparc");
break;
case CPU_TYPE_I860:
rz_structured_data_map_add_string(mach0, "CpuType", "i860");
break;
case CPU_TYPE_POWERPC:
rz_structured_data_map_add_string(mach0, "CpuType", "ppc");
break;
case CPU_TYPE_POWERPC64:
rz_structured_data_map_add_string(mach0, "CpuType", "ppc64");
break;
default:
rz_structured_data_map_add_unsigned(mach0, "CpuType", mh->cputype, true);
break;
}
rz_structured_data_map_add_unsigned(mach0, "CpuSubType", mh->cpusubtype, true);
rz_structured_data_map_add_unsigned(mach0, "FileType", mh->filetype, true);
rz_structured_data_map_add_unsigned(mach0, "nCmds", mh->ncmds, false);
rz_structured_data_map_add_unsigned(mach0, "sizeOfCmds", mh->sizeofcmds, false);
rz_structured_data_map_add_unsigned(mach0, "Flags", mh->flags, true);
#define MACH0_READ_WORD_HERE() \
do { \
if (!rz_buf_read_ble32_offset(buf, &addr, &word, big_endian)) { \
break; \
} \
} while (0)
if (is_64bit) {
addr += 4;
}
if (mh->ncmds < 1) {
free(mh);
return info;
}
RzStructuredData *lcmds = rz_structured_data_map_add_array(mach0, "LoadCommands");
if (!lcmds) {
rz_structured_data_free(info);
return NULL;
}
for (ut32 n = 0; n < mh->ncmds; n++) {
MACH0_READ_WORD_HERE();
ut32 lcType = word;
RzStructuredData *lc_info = rz_structured_data_array_add_map(lcmds);
if (!lc_info) {
rz_warn_if_reached();
rz_structured_data_free(info);
return NULL;
}
const char *lc_name = cmd_to_string(lcType);
if (RZ_STR_ISNOTEMPTY(lc_name)) {
rz_structured_data_map_add_string(lc_info, "LcType", lc_name);
} else {
rz_structured_data_map_add_unsigned(lc_info, "LcType", lcType, true);
}
MACH0_READ_WORD_HERE();
if (addr > length) {
break;
}
int lcSize = word;
word &= 0xFFFFFF;
if (lcSize < 1) {
RZ_LOG_ERROR("Invalid size for a load command\n");
break;
}
rz_structured_data_map_add_unsigned(lc_info, "CmdSize", word, false);
switch (lcType) {
case LC_BUILD_VERSION: {
ut32 platform;
if (!rz_buf_read_le32_at(buf, addr, &platform)) {
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)) {
break;
}
ut8 minos2;
if (!rz_buf_read8_at(buf, addr + 5, &minos2)) {
break;
}
ut8 minos3;
if (!rz_buf_read8_at(buf, addr + 4, &minos3)) {
break;
}
rz_strf(tmp, "%d.%d.%d", minos1, minos2, minos3);
rz_structured_data_map_add_string(lc_info, "MinOS", tmp);
ut16 sdk1;
if (!rz_buf_read_le16_at(buf, addr + 10, &sdk1)) {
break;
}
ut8 sdk2;
if (!rz_buf_read8_at(buf, addr + 9, &sdk2)) {
break;
}
ut8 sdk3;
if (!rz_buf_read8_at(buf, addr + 8, &sdk3)) {
break;
}
rz_strf(tmp, "%d.%d.%d", sdk1, sdk2, sdk3);
rz_structured_data_map_add_string(lc_info, "SDK", tmp);
ut32 ntools;
if (!rz_buf_read_le32_at(buf, addr + 12, &ntools)) {
break;
}
rz_structured_data_map_add_unsigned(lc_info, "nTools", ntools, false);
RzStructuredData *build_vers = rz_structured_data_map_add_array(lc_info, "BuildVersionTool");
if (!build_vers) {
rz_warn_if_reached();
rz_structured_data_free(info);
return NULL;
}
ut64 off = 16;
while (off < (lcSize - 8) && ntools--) {
RzStructuredData *build = rz_structured_data_array_add_map(build_vers);
if (!build) {
rz_warn_if_reached();
rz_structured_data_free(info);
return NULL;
}
ut32 tool;
if (!rz_buf_read_le32_at(buf, addr + off, &tool)) {
break;
}
rz_structured_data_map_add_string(build, "Tool", rz_mach0_build_version_tool_to_string(tool));
off += 4;
if (off >= (lcSize - 8)) {
break;
}
ut16 version1;
if (!rz_buf_read_le16_at(buf, addr + off + 2, &version1)) {
break;
}
ut8 version2;
if (!rz_buf_read8_at(buf, addr + off + 1, &version2)) {
break;
}
ut8 version3;
if (!rz_buf_read8_at(buf, addr + off, &version3)) {
break;
}
rz_strf(tmp, "%d.%d.%d", version1, version2, version3);
rz_structured_data_map_add_string(build, "Version", tmp);
off += 4;
}
break;
}
case LC_MAIN: {
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);
#else
ut32 ep = rz_read_ble32(&data, false); // bin->big_endian);
ut32 ss = rz_read_ble32(&data[4], false); // bin->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);
} break;
case LC_SYMTAB:
break;
case LC_ID_DYLIB: { // install_name_tool
ut32 str_off;
if (!rz_buf_read_ble32_at(buf, addr, &str_off, big_endian)) {
break;
}
char *id = rz_buf_get_string(buf, addr + str_off - 8);
if (RZ_STR_ISNOTEMPTY(id)) {
rz_structured_data_map_add_string(lc_info, "Id", id);
}
free(id);
ut16 current1;
if (!rz_buf_read_le16_at(buf, addr + 10, &current1)) {
break;
}
ut8 current2;
if (!rz_buf_read8_at(buf, addr + 9, &current2)) {
break;
}
ut8 current3;
if (!rz_buf_read8_at(buf, addr + 8, &current3)) {
break;
}
rz_strf(tmp, "%d.%d.%d", current1, current2, current3);
rz_structured_data_map_add_string(lc_info, "Current", tmp);
ut16 compat1;
if (!rz_buf_read_le16_at(buf, addr + 14, &compat1)) {
break;
}
ut8 compat2;
if (!rz_buf_read8_at(buf, addr + 13, &compat2)) {
break;
}
ut8 compat3;
if (!rz_buf_read8_at(buf, addr + 12, &compat3)) {
break;
}
rz_strf(tmp, "%d.%d.%d", compat1, compat2, compat3);
rz_structured_data_map_add_string(lc_info, "Compat", tmp);
break;
}
case LC_UUID: {
ut8 uuid[16];
if (rz_buf_read_at(buf, addr, uuid, sizeof(uuid)) != sizeof(uuid)) {
break;
}
rz_hex_bin2str(uuid, sizeof(uuid), tmp);
rz_structured_data_map_add_string(lc_info, "UUID", tmp);
} break;
case LC_SEGMENT:
case LC_SEGMENT_64: {
char name[17] = { 0 };
rz_buf_read_at(buf, addr, (ut8 *)name, sizeof(name) - 1);
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)) {
break;
}
rz_structured_data_map_add_unsigned(lc_info, "nSects", nsects, false);
} break;
case LC_LOAD_DYLIB:
case LC_LOAD_WEAK_DYLIB: {
ut32 str_off;
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);
if (RZ_STR_ISNOTEMPTY(load_dylib)) {
rz_structured_data_map_add_string(lc_info, "LoadDyLib", load_dylib);
}
free(load_dylib);
ut16 current1;
if (!rz_buf_read_le16_at(buf, addr + 10, &current1)) {
break;
}
ut8 current2;
if (!rz_buf_read8_at(buf, addr + 9, &current2)) {
break;
}
ut8 current3;
if (!rz_buf_read8_at(buf, addr + 8, &current3)) {
break;
}
rz_strf(tmp, "%d.%d.%d", current1, current2, current3);
rz_structured_data_map_add_string(lc_info, "Current", tmp);
ut16 compat1;
if (!rz_buf_read_le16_at(buf, addr + 14, &compat1)) {
break;
}
ut8 compat2;
if (!rz_buf_read8_at(buf, addr + 13, &compat2)) {
break;
}
ut8 compat3;
if (!rz_buf_read8_at(buf, addr + 12, &compat3)) {
break;
}
rz_strf(tmp, "%d.%d.%d", compat1, compat2, compat3);
rz_structured_data_map_add_string(lc_info, "Compat", tmp);
break;
}
case LC_RPATH: {
char *rpath = rz_buf_get_string(buf, addr + 4);
if (RZ_STR_ISNOTEMPTY(rpath)) {
rz_structured_data_map_add_string(lc_info, "rPath", rpath);
}
free(rpath);
break;
}
case LC_ENCRYPTION_INFO:
case LC_ENCRYPTION_INFO_64: {
ut32 word;
if (!rz_buf_read_le32_at(buf, addr, &word)) {
break;
}
rz_structured_data_map_add_unsigned(lc_info, "CryptOffset", word, true);
if (!rz_buf_read_le32_at(buf, addr + 4, &word)) {
break;
}
rz_structured_data_map_add_unsigned(lc_info, "CryptSize", word, false);
if (!rz_buf_read_le32_at(buf, addr + 8, &word)) {
break;
}
rz_structured_data_map_add_unsigned(lc_info, "CryptId", word, false);
break;
}
case LC_CODE_SIGNATURE: {
ut32 words[2];
if (!rz_buf_read_at(buf, addr, (ut8 *)words, sizeof(words))) {
break;
}
rz_structured_data_map_add_unsigned(lc_info, "DataOffset", words[0], true);
rz_structured_data_map_add_unsigned(lc_info, "DataSize", words[1], false);
break;
}
}
addr += word - 8;
}
free(mh);
return info;
}
RzPVector /*<RzBinField *>*/ *MACH0_(mach_fields)(RzBinFile *bf) {
RzBuffer *buf = bf->buf;
ut64 length = rz_buf_size(buf);

View file

@ -261,7 +261,7 @@ 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);
void MACH0_(mach_headerfields)(RzBinFile *bf);
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);
RZ_API ut64 MACH0_(paddr_to_vaddr)(struct MACH0_(obj_t) * bin, ut64 offset);

View file

@ -191,22 +191,40 @@ RzPVector /*<RzBinString *>*/ *mbn_strings(RzBinFile *bf) {
return rz_bin_file_strings(bf, &opt);
}
void mbn_header_obj(SblHeader *sb, RZ_NONNULL PrintfCallback cb) {
rz_return_if_fail(sb && cb);
cb("0x%02" PFMTSZx " image_id: %s (0x%" PFMT32x ")\n", offsetof(SblHeader, image_id), rz_mbn_image_id_str(sb->image_id), sb->image_id);
cb("0x%02" PFMTSZx " version: 0x%" PFMT32x "\n", offsetof(SblHeader, version), sb->version);
cb("0x%02" PFMTSZx " paddr: 0x%" PFMT32x "\n", offsetof(SblHeader, paddr), sb->paddr);
cb("0x%02" PFMTSZx " vaddr: 0x%" PFMT32x "\n", offsetof(SblHeader, vaddr), sb->vaddr);
cb("0x%02" PFMTSZx " psize: 0x%" PFMT32x "\n", offsetof(SblHeader, psize), sb->psize);
cb("0x%02" PFMTSZx " code_pa: 0x%" PFMT32x "\n", offsetof(SblHeader, code_pa), sb->code_pa);
cb("0x%02" PFMTSZx " sign_va: 0x%" PFMT32x "\n", offsetof(SblHeader, sign_va), sb->sign_va);
cb("0x%02" PFMTSZx " sign_sz: 0x%" PFMT32x "\n", offsetof(SblHeader, sign_sz), sb->sign_sz);
cb("0x%02" PFMTSZx " cert_va: 0x%" PFMT32x "\n", offsetof(SblHeader, cert_va), sb->cert_va);
cb("0x%02" PFMTSZx " cert_sz: 0x%" PFMT32x "\n", offsetof(SblHeader, cert_sz), sb->cert_sz);
RzStructuredData *mbn_structure(SblHeader *sb) {
RzStructuredData *info = rz_structured_data_new_map();
if (!info) {
return NULL;
}
RzStructuredData *mbn = rz_structured_data_map_add_map(info, "mbn");
if (!mbn) {
rz_structured_data_free(info);
return NULL;
}
RzStructuredData *image = rz_structured_data_map_add_map(mbn, "image");
if (!image) {
rz_structured_data_free(info);
return NULL;
}
rz_structured_data_map_add_string(image, "name", rz_mbn_image_id_str(sb->image_id));
rz_structured_data_map_add_unsigned(image, "id", sb->image_id, true);
rz_structured_data_map_add_unsigned(mbn, "version", sb->version, true);
rz_structured_data_map_add_unsigned(mbn, "paddr", sb->paddr, true);
rz_structured_data_map_add_unsigned(mbn, "vaddr", sb->vaddr, true);
rz_structured_data_map_add_unsigned(mbn, "psize", sb->psize, true);
rz_structured_data_map_add_unsigned(mbn, "code_pa", sb->code_pa, true);
rz_structured_data_map_add_unsigned(mbn, "sign_va", sb->sign_va, true);
rz_structured_data_map_add_unsigned(mbn, "sign_sz", sb->sign_sz, true);
rz_structured_data_map_add_unsigned(mbn, "cert_va", sb->cert_va, true);
rz_structured_data_map_add_unsigned(mbn, "cert_sz", sb->cert_sz, true);
return info;
}
void mbn_header(RzBinFile *bf) {
rz_return_if_fail(bf && bf->o && bf->o->bin_obj && bf->rbin && bf->rbin->cb_printf);
RzStructuredData *mbn_structure_bin(RzBinFile *bf) {
SblHeader *sb = mbn_file_get_hdr(bf);
mbn_header_obj(sb, bf->rbin->cb_printf);
return mbn_structure(sb);
}

View file

@ -152,5 +152,5 @@ ut64 mbn_size(RzBinFile *bf);
void mbn_destroy_obj(SblHeader *sb);
void mbn_destroy(RzBinFile *bf);
RzPVector /*<RzBinString *>*/ *mbn_strings(RzBinFile *bf);
void mbn_header_obj(SblHeader *sb, RZ_NONNULL PrintfCallback cb);
void mbn_header(RzBinFile *bf);
RzStructuredData *mbn_structure(SblHeader *sb);
RzStructuredData *mbn_structure_bin(RzBinFile *bf);

View file

@ -596,57 +596,67 @@ RZ_IPI RZ_OWN RzPVector /*<RzBinReloc *>*/ *rz_bin_mdt_relocs(RzBinFile *bf) {
return relocs;
}
RZ_IPI void rz_bin_mdt_print_header(RzBinFile *bf) {
rz_return_if_fail(bf && bf->o && bf->o->bin_obj && bf->rbin && bf->rbin->cb_printf);
RZ_IPI RzStructuredData *rz_bin_mdt_structure(RzBinFile *bf) {
rz_return_val_if_fail(bf && bf->o && bf->o->bin_obj, NULL);
const RzBinMdtObj *mdt = bf->o->bin_obj;
char bits[65] = { 0 };
size_t i;
void **it;
RzStructuredData *content = NULL;
RzStructuredData *info = rz_structured_data_new_map();
if (!info) {
return NULL;
}
RzStructuredData *mdt_segments = rz_structured_data_map_add_array(info, "mdt_segments");
if (!mdt_segments) {
rz_structured_data_free(info);
return NULL;
}
size_t i = 0;
void **it = NULL;
char bits[70] = { 0 };
bits[0] = '0';
bits[1] = 'b';
rz_pvector_enumerate (mdt->parts, it, i) {
RzBinMdtPart *part = *it;
rz_str_bits64(bits, qcom_p_flags(part->pflags));
bf->rbin->cb_printf("==== MDT Segment %" PFMTSZu " ====\n", i);
bf->rbin->cb_printf(" priv_p_flags: 0b%s:", bits);
if (part->is_layout) {
bf->rbin->cb_printf(" layout");
}
if (part->relocatable) {
bf->rbin->cb_printf(" reloc");
rz_str_bits64(&bits[2], qcom_p_flags(part->pflags));
RzStructuredData *segment = rz_structured_data_array_add_map(mdt_segments);
if (!segment) {
rz_structured_data_free(info);
return NULL;
}
rz_structured_data_map_add_string(segment, "priv_p_flags", bits);
rz_structured_data_map_add_boolean(segment, "is_layout", part->is_layout);
rz_structured_data_map_add_boolean(segment, "is_relocatable", part->relocatable);
switch (part->format) {
default:
/* fall-thru */
case RZ_BIN_MDT_PART_UNIDENTIFIED:
bf->rbin->cb_printf(" | Unidentified\n");
rz_structured_data_map_add_string(segment, "format", "unidentified");
break;
case RZ_BIN_MDT_PART_ELF:
bf->rbin->cb_printf(" | ELF\n");
if (part->obj.elf) {
bf->rbin->cb_printf(" -- ELF HEADER BEGIN -- \n");
elf_headers_obj((ELFOBJ *)part->obj.elf, bf->rbin->cb_printf);
bf->rbin->cb_printf(" --- ELF HEADER END --- \n\n");
} else {
bf->rbin->cb_printf(" ------- FAILED ------- \n");
}
rz_structured_data_map_add_string(segment, "format", "elf binary");
content = elf_structure(part->obj.elf);
rz_structured_data_map_add(segment, "content", content);
break;
case RZ_BIN_MDT_PART_MBN:
bf->rbin->cb_printf(" | MBN signature segment\n");
if (part->obj.mbn) {
bf->rbin->cb_printf(" -- MBN AUTH HEADER BEGIN -- \n");
mbn_header_obj(part->obj.mbn, bf->rbin->cb_printf);
bf->rbin->cb_printf(" --- MBN AUTH HEADER END --- \n\n");
} else {
bf->rbin->cb_printf(" ------- FAILED ------- \n");
}
rz_structured_data_map_add_string(segment, "format", "mbn signature");
content = mbn_structure(part->obj.mbn);
rz_structured_data_map_add(segment, "content", content);
break;
case RZ_BIN_MDT_PART_COMPRESSED_Q6ZIP:
bf->rbin->cb_printf(" | Q6ZIP compressed\n");
rz_structured_data_map_add_string(segment, "format", "Q6ZIP compressed");
break;
case RZ_BIN_MDT_PART_COMPRESSED_CLADE2:
bf->rbin->cb_printf(" | CLADE2 compressed\n");
rz_structured_data_map_add_string(segment, "format", "CLADE2 compressed");
break;
case RZ_BIN_MDT_PART_COMPRESSED_ZLIB:
bf->rbin->cb_printf(" | ZLIB compressed\n");
rz_structured_data_map_add_string(segment, "format", "ZLIB compressed");
break;
}
}
return info;
}

View file

@ -94,7 +94,7 @@ RZ_IPI RZ_OWN RzPVector /*<RzBinMap *>*/ *rz_bin_mdt_get_maps(RzBinFile *bf);
RZ_IPI RZ_OWN RzPVector /*<RzBinAddr *>*/ *rz_bin_mdt_get_entry_points(RzBinFile *bf);
RZ_IPI RZ_OWN RzPVector /*<RzBinVirtualFile *>*/ *rz_bin_mdt_virtual_files(RzBinFile *bf);
RZ_IPI RZ_OWN RzPVector /*<RzBinSymbol *>*/ *rz_bin_mdt_symbols(RzBinFile *bf);
RZ_IPI void rz_bin_mdt_print_header(RzBinFile *bf);
RZ_IPI RzStructuredData *rz_bin_mdt_structure(RzBinFile *bf);
RZ_IPI RZ_OWN RzPVector /*<RzBinSection *>*/ *rz_bin_mdt_sections(RzBinFile *bf);
RZ_IPI RZ_OWN RzPVector /*<RzBinReloc *>*/ *rz_bin_mdt_relocs(RzBinFile *bf);

View file

@ -9,78 +9,109 @@
#include "dmp/dmp64.h"
static Sdb *get_sdb(RzBinFile *bf) {
static Sdb *dmp64_get_sdb(RzBinFile *bf) {
rz_return_val_if_fail(bf && bf->o, NULL);
struct rz_bin_dmp64_obj_t *obj = (struct rz_bin_dmp64_obj_t *)bf->o->bin_obj;
return (obj && obj->kv) ? obj->kv : NULL;
}
static void destroy(RzBinFile *bf) {
static void dmp64_destroy(RzBinFile *bf) {
rz_bin_dmp64_free((struct rz_bin_dmp64_obj_t *)bf->o->bin_obj);
}
static void header(RzBinFile *bf) {
static RzStructuredData *dmp64_structure(RzBinFile *bf) {
rz_return_val_if_fail(bf && bf->rbin && bf->o && bf->o->bin_obj, NULL);
struct rz_bin_dmp64_obj_t *obj = (struct rz_bin_dmp64_obj_t *)bf->o->bin_obj;
struct rz_bin_t *rbin = bf->rbin;
rbin->cb_printf("DUMP_HEADER64:\n");
rbin->cb_printf(" MajorVersion : 0x%08" PFMT32x "\n", obj->header->MajorVersion);
rbin->cb_printf(" MinorVersion : 0x%08" PFMT32x "\n", obj->header->MinorVersion);
rbin->cb_printf(" DirectoryTableBase : 0x%016" PFMT64x "\n", obj->header->DirectoryTableBase);
rbin->cb_printf(" PfnDataBase : 0x%016" PFMT64x "\n", obj->header->PfnDataBase);
rbin->cb_printf(" PsLoadedModuleList : 0x%016" PFMT64x "\n", obj->header->PsLoadedModuleList);
rbin->cb_printf(" PsActiveProcessHead : 0x%016" PFMT64x "\n", obj->header->PsActiveProcessHead);
rbin->cb_printf(" MachineImageType : 0x%08" PFMT32x "\n", obj->header->MachineImageType);
rbin->cb_printf(" NumberProcessors : 0x%08" PFMT32x "\n", obj->header->NumberProcessors);
rbin->cb_printf(" BugCheckCode : 0x%08" PFMT32x " (%s)\n", obj->header->BugCheckCode, rz_bin_dmp64_bugcheckcode_as_str(obj->header->BugCheckCode));
rbin->cb_printf(" BugCheckParameter1 : 0x%016" PFMT64x "\n", obj->header->BugCheckParameter1);
rbin->cb_printf(" BugCheckParameter2 : 0x%016" PFMT64x "\n", obj->header->BugCheckParameter2);
rbin->cb_printf(" BugCheckParameter3 : 0x%016" PFMT64x "\n", obj->header->BugCheckParameter3);
rbin->cb_printf(" BugCheckParameter4 : 0x%016" PFMT64x "\n", obj->header->BugCheckParameter4);
rbin->cb_printf(" KdDebuggerDataBlock : 0x%016" PFMT64x "\n", obj->header->KdDebuggerDataBlock);
rbin->cb_printf(" SecondaryDataState : 0x%08" PFMT32x "\n", obj->header->SecondaryDataState);
rbin->cb_printf(" ProductType : 0x%08" PFMT32x "\n", obj->header->ProductType);
rbin->cb_printf(" SuiteMask : 0x%08" PFMT32x "\n", obj->header->SuiteMask);
RzStructuredData *info = rz_structured_data_new_map();
if (!info) {
return NULL;
}
RzStructuredData *dmp64 = rz_structured_data_map_add_map(info, "dmp64");
if (!dmp64) {
rz_structured_data_free(info);
return NULL;
}
rz_structured_data_map_add_unsigned(dmp64, "MajorVersion", obj->header->MajorVersion, true);
rz_structured_data_map_add_unsigned(dmp64, "MinorVersion", obj->header->MinorVersion, true);
rz_structured_data_map_add_unsigned(dmp64, "DirectoryTableBase", obj->header->DirectoryTableBase, true);
rz_structured_data_map_add_unsigned(dmp64, "PfnDataBase", obj->header->PfnDataBase, true);
rz_structured_data_map_add_unsigned(dmp64, "PsLoadedModuleList", obj->header->PsLoadedModuleList, true);
rz_structured_data_map_add_unsigned(dmp64, "PsActiveProcessHead", obj->header->PsActiveProcessHead, true);
rz_structured_data_map_add_unsigned(dmp64, "MachineImageType", obj->header->MachineImageType, true);
rz_structured_data_map_add_unsigned(dmp64, "NumberProcessors", obj->header->NumberProcessors, true);
{
RzStructuredData *bug_check_code = rz_structured_data_map_add_map(dmp64, "BugCheckCode");
if (!bug_check_code) {
rz_structured_data_free(info);
return NULL;
}
rz_structured_data_map_add_unsigned(bug_check_code, "Value", obj->header->BugCheckCode, true);
rz_structured_data_map_add_string(bug_check_code, "Meaning", rz_bin_dmp64_bugcheckcode_as_str(obj->header->BugCheckCode));
}
rz_structured_data_map_add_unsigned(dmp64, "BugCheckParameter1", obj->header->BugCheckParameter1, true);
rz_structured_data_map_add_unsigned(dmp64, "BugCheckParameter2", obj->header->BugCheckParameter2, true);
rz_structured_data_map_add_unsigned(dmp64, "BugCheckParameter3", obj->header->BugCheckParameter3, true);
rz_structured_data_map_add_unsigned(dmp64, "BugCheckParameter4", obj->header->BugCheckParameter4, true);
rz_structured_data_map_add_unsigned(dmp64, "KdDebuggerDataBlock", obj->header->KdDebuggerDataBlock, true);
rz_structured_data_map_add_unsigned(dmp64, "SecondaryDataState", obj->header->SecondaryDataState, true);
rz_structured_data_map_add_unsigned(dmp64, "ProductType", obj->header->ProductType, true);
rz_structured_data_map_add_unsigned(dmp64, "SuiteMask", obj->header->SuiteMask, true);
if (obj->bmp_header) {
rbin->cb_printf("\nBITMAP_DUMP:\n");
rbin->cb_printf(" HeaderSize : 0x%08" PFMT64x "\n", obj->bmp_header->FirstPage);
rbin->cb_printf(" BitmapSize : 0x%08" PFMT64x "\n", obj->bmp_header->Pages);
rbin->cb_printf(" Pages : 0x%08" PFMT64x "\n", obj->bmp_header->TotalPresentPages);
} else if (obj->triage64_header) {
rbin->cb_printf("\nTRIAGE_DUMP64:\n");
rbin->cb_printf(" ServicePackBuild : 0x%08" PFMT32x "\n", obj->triage64_header->ServicePackBuild);
rbin->cb_printf(" SizeOfDump : 0x%08" PFMT32x "\n", obj->triage64_header->SizeOfDump);
rbin->cb_printf(" ValidOffset : 0x%08" PFMT32x "\n", obj->triage64_header->ValidOffset);
rbin->cb_printf(" ContextOffset : 0x%08" PFMT32x "\n", obj->triage64_header->ContextOffset);
rbin->cb_printf(" ExceptionOffset : 0x%08" PFMT32x "\n", obj->triage64_header->ExceptionOffset);
rbin->cb_printf(" MmOffset : 0x%08" PFMT32x "\n", obj->triage64_header->MmOffset);
rbin->cb_printf(" UnloadedDriversOffset : 0x%08" PFMT32x "\n", obj->triage64_header->UnloadedDriversOffset);
rbin->cb_printf(" PrcbOffset : 0x%08" PFMT32x "\n", obj->triage64_header->PrcbOffset);
rbin->cb_printf(" ProcessOffset : 0x%08" PFMT32x "\n", obj->triage64_header->ProcessOffset);
rbin->cb_printf(" ThreadOffset : 0x%08" PFMT32x "\n", obj->triage64_header->ThreadOffset);
rbin->cb_printf(" CallStackOffset : 0x%08" PFMT32x "\n", obj->triage64_header->CallStackOffset);
rbin->cb_printf(" SizeOfCallStack : 0x%08" PFMT32x "\n", obj->triage64_header->SizeOfCallStack);
rbin->cb_printf(" DriverListOffset : 0x%08" PFMT32x "\n", obj->triage64_header->DriverListOffset);
rbin->cb_printf(" DriverCount : 0x%08" PFMT32x "\n", obj->triage64_header->DriverCount);
rbin->cb_printf(" StringPoolOffset : 0x%08" PFMT32x "\n", obj->triage64_header->StringPoolOffset);
rbin->cb_printf(" StringPoolSize : 0x%08" PFMT32x "\n", obj->triage64_header->StringPoolSize);
rbin->cb_printf(" BrokenDriverOffset : 0x%08" PFMT32x "\n", obj->triage64_header->BrokenDriverOffset);
rbin->cb_printf(" TriageOptions : 0x%08" PFMT32x "\n", obj->triage64_header->TriageOptions);
rbin->cb_printf(" TopOfStack : 0x%016" PFMT64x "\n", obj->triage64_header->TopOfStack);
rbin->cb_printf(" BStoreOffset : 0x%08" PFMT32x "\n", rz_read_le32(&obj->triage64_header->ArchitectureSpecific.Ia64.BStoreOffset));
rbin->cb_printf(" SizeOfBStore : 0x%08" PFMT32x "\n", rz_read_le32(&obj->triage64_header->ArchitectureSpecific.Ia64.SizeOfBStore));
rbin->cb_printf(" LimitOfBStore : 0x%016" PFMT64x "\n", rz_read_le64(&obj->triage64_header->ArchitectureSpecific.Ia64.LimitOfBStore));
rbin->cb_printf(" DataPageAddress : 0x%016" PFMT64x "\n", obj->triage64_header->DataPageAddress);
rbin->cb_printf(" DataPageOffset : 0x%08" PFMT32x "\n", obj->triage64_header->DataPageOffset);
rbin->cb_printf(" DataPageSize : 0x%08" PFMT32x "\n", obj->triage64_header->DataPageSize);
rbin->cb_printf(" DebuggerDataOffset : 0x%08" PFMT32x "\n", obj->triage64_header->DebuggerDataOffset);
rbin->cb_printf(" DebuggerDataSize : 0x%08" PFMT32x "\n", obj->triage64_header->DebuggerDataSize);
rbin->cb_printf(" DataBlocksOffset : 0x%08" PFMT32x "\n", obj->triage64_header->DataBlocksOffset);
rbin->cb_printf(" DataBlocksCount : 0x%08" PFMT32x "\n", obj->triage64_header->DataBlocksCount);
RzStructuredData *bitmap = rz_structured_data_map_add_map(dmp64, "Bitmap");
if (!bitmap) {
rz_structured_data_free(info);
return NULL;
}
rz_structured_data_map_add_unsigned(bitmap, "HeaderSize", obj->bmp_header->FirstPage, true);
rz_structured_data_map_add_unsigned(bitmap, "BitmapSize", obj->bmp_header->Pages, true);
rz_structured_data_map_add_unsigned(bitmap, "Pages", obj->bmp_header->TotalPresentPages, true);
}
if (obj->triage64_header) {
RzStructuredData *triage64 = rz_structured_data_map_add_map(dmp64, "TriageDump64");
if (!triage64) {
rz_structured_data_free(info);
return NULL;
}
rz_structured_data_map_add_unsigned(triage64, "ServicePackBuild", obj->triage64_header->ServicePackBuild, true);
rz_structured_data_map_add_unsigned(triage64, "SizeOfDump", obj->triage64_header->SizeOfDump, true);
rz_structured_data_map_add_unsigned(triage64, "ValidOffset", obj->triage64_header->ValidOffset, true);
rz_structured_data_map_add_unsigned(triage64, "ContextOffset", obj->triage64_header->ContextOffset, true);
rz_structured_data_map_add_unsigned(triage64, "ExceptionOffset", obj->triage64_header->ExceptionOffset, true);
rz_structured_data_map_add_unsigned(triage64, "MmOffset", obj->triage64_header->MmOffset, true);
rz_structured_data_map_add_unsigned(triage64, "UnloadedDriversOffset", obj->triage64_header->UnloadedDriversOffset, true);
rz_structured_data_map_add_unsigned(triage64, "PrcbOffset", obj->triage64_header->PrcbOffset, true);
rz_structured_data_map_add_unsigned(triage64, "ProcessOffset", obj->triage64_header->ProcessOffset, true);
rz_structured_data_map_add_unsigned(triage64, "ThreadOffset", obj->triage64_header->ThreadOffset, true);
rz_structured_data_map_add_unsigned(triage64, "CallStackOffset", obj->triage64_header->CallStackOffset, true);
rz_structured_data_map_add_unsigned(triage64, "SizeOfCallStack", obj->triage64_header->SizeOfCallStack, true);
rz_structured_data_map_add_unsigned(triage64, "DriverListOffset", obj->triage64_header->DriverListOffset, true);
rz_structured_data_map_add_unsigned(triage64, "DriverCount", obj->triage64_header->DriverCount, true);
rz_structured_data_map_add_unsigned(triage64, "StringPoolOffset", obj->triage64_header->StringPoolOffset, true);
rz_structured_data_map_add_unsigned(triage64, "StringPoolSize", obj->triage64_header->StringPoolSize, true);
rz_structured_data_map_add_unsigned(triage64, "BrokenDriverOffset", obj->triage64_header->BrokenDriverOffset, true);
rz_structured_data_map_add_unsigned(triage64, "TriageOptions", obj->triage64_header->TriageOptions, true);
rz_structured_data_map_add_unsigned(triage64, "TopOfStack", obj->triage64_header->TopOfStack, true);
rz_structured_data_map_add_unsigned(triage64, "BStoreOffset", rz_read_le32(&obj->triage64_header->ArchitectureSpecific.Ia64.BStoreOffset), true);
rz_structured_data_map_add_unsigned(triage64, "SizeOfBStore", rz_read_le32(&obj->triage64_header->ArchitectureSpecific.Ia64.SizeOfBStore), true);
rz_structured_data_map_add_unsigned(triage64, "LimitOfBStore", rz_read_le64(&obj->triage64_header->ArchitectureSpecific.Ia64.LimitOfBStore), true);
rz_structured_data_map_add_unsigned(triage64, "DataPageAddress", obj->triage64_header->DataPageAddress, true);
rz_structured_data_map_add_unsigned(triage64, "DataPageOffset", obj->triage64_header->DataPageOffset, true);
rz_structured_data_map_add_unsigned(triage64, "DataPageSize", obj->triage64_header->DataPageSize, true);
rz_structured_data_map_add_unsigned(triage64, "DebuggerDataOffset", obj->triage64_header->DebuggerDataOffset, true);
rz_structured_data_map_add_unsigned(triage64, "DebuggerDataSize", obj->triage64_header->DebuggerDataSize, true);
rz_structured_data_map_add_unsigned(triage64, "DataBlocksOffset", obj->triage64_header->DataBlocksOffset, true);
rz_structured_data_map_add_unsigned(triage64, "DataBlocksCount", obj->triage64_header->DataBlocksCount, true);
}
return info;
}
static RzPVector /*<RzBinField *>*/ *fields(RzBinFile *bf) {
static RzPVector /*<RzBinField *>*/ *dmp64_fields(RzBinFile *bf) {
RzPVector *fields = rz_pvector_new((RzPVectorFree)rz_bin_field_free);
struct rz_bin_dmp64_obj_t *obj = (struct rz_bin_dmp64_obj_t *)bf->o->bin_obj;
#define FIELD_COMMENT(header, field, comment) \
@ -144,7 +175,7 @@ static RzPVector /*<RzBinField *>*/ *fields(RzBinFile *bf) {
return fields;
}
static RzBinInfo *info(RzBinFile *bf) {
static RzBinInfo *dmp64_info(RzBinFile *bf) {
RzBinInfo *ret;
if (!(ret = RZ_NEW0(RzBinInfo))) {
return NULL;
@ -181,7 +212,7 @@ static RzBinInfo *info(RzBinFile *bf) {
return ret;
}
static RzPVector /*<RzBinMap *>*/ *maps(RzBinFile *bf) {
static RzPVector /*<RzBinMap *>*/ *dmp64_maps(RzBinFile *bf) {
dmp_page_desc *page;
dmp64_triage_datablock *datablock;
RzPVector *ret;
@ -223,7 +254,7 @@ static RzPVector /*<RzBinMap *>*/ *maps(RzBinFile *bf) {
return ret;
}
static RzPVector /*<char *>*/ *libs(RzBinFile *bf) {
static RzPVector /*<char *>*/ *dmp64_libs(RzBinFile *bf) {
struct rz_bin_dmp64_obj_t *obj = (struct rz_bin_dmp64_obj_t *)bf->o->bin_obj;
if (!obj->drivers) {
return NULL;
@ -241,16 +272,16 @@ static RzPVector /*<char *>*/ *libs(RzBinFile *bf) {
return ret;
}
static int file_type(RzBinFile *bf) {
static int dmp64_file_type(RzBinFile *bf) {
return RZ_BIN_TYPE_CORE;
}
static char *regstate(RzBinFile *bf) {
static char *dmp64_regstate(RzBinFile *bf) {
struct rz_bin_dmp64_obj_t *dmp64 = bf->o->bin_obj;
return rz_hex_bin2strdup(dmp64->header->ContextRecord, sizeof(dmp64->header->ContextRecord));
}
static bool load_buffer(RzBinFile *bf, RzBinObject *obj, RzBuffer *buf, Sdb *sdb) {
static bool dmp64_load_buffer(RzBinFile *bf, RzBinObject *obj, RzBuffer *buf, Sdb *sdb) {
rz_return_val_if_fail(buf, false);
struct rz_bin_dmp64_obj_t *res = rz_bin_dmp64_new_buf(buf);
if (res) {
@ -261,7 +292,7 @@ static bool load_buffer(RzBinFile *bf, RzBinObject *obj, RzBuffer *buf, Sdb *sdb
return false;
}
static bool check_buffer(RzBuffer *b) {
static bool dmp64_check_buffer(RzBuffer *b) {
ut8 magic[8];
if (rz_buf_read_at(b, 0, magic, sizeof(magic)) == 8) {
return !memcmp(magic, DMP64_MAGIC, 8);
@ -274,17 +305,17 @@ RzBinPlugin rz_bin_plugin_dmp64 = {
.desc = "Windows x64 Crash Dump",
.license = "LGPL3",
.author = "abcSup",
.destroy = &destroy,
.get_sdb = &get_sdb,
.header = &header,
.info = &info,
.load_buffer = &load_buffer,
.check_buffer = &check_buffer,
.maps = &maps,
.libs = &libs,
.regstate = &regstate,
.file_type = &file_type,
.fields = &fields
.destroy = &dmp64_destroy,
.get_sdb = &dmp64_get_sdb,
.bin_structure = &dmp64_structure,
.info = &dmp64_info,
.load_buffer = &dmp64_load_buffer,
.check_buffer = &dmp64_check_buffer,
.maps = &dmp64_maps,
.libs = &dmp64_libs,
.regstate = &dmp64_regstate,
.file_type = &dmp64_file_type,
.fields = &dmp64_fields
};
#ifndef RZ_PLUGIN_INCORE

View file

@ -58,7 +58,7 @@ static struct MACH0_(obj_t) * bin_to_mach0(RzBinFile *bf, RzDyldBinImage *bin) {
return mach0;
}
static bool check_buffer(RzBuffer *buf) {
static bool dyldcache_check_buffer(RzBuffer *buf) {
if (rz_buf_size(buf) < 32) {
return false;
}
@ -72,7 +72,7 @@ static bool check_buffer(RzBuffer *buf) {
return rz_dyldcache_check_magic(hdr);
}
static bool load_buffer(RzBinFile *bf, RzBinObject *obj, RzBuffer *buf, Sdb *sdb) {
static bool dyldcache_load_buffer(RzBinFile *bf, RzBinObject *obj, RzBuffer *buf, Sdb *sdb) {
RzDyldCache *cache = rz_dyldcache_new_buf(buf);
if (!cache) {
return false;
@ -81,7 +81,7 @@ static bool load_buffer(RzBinFile *bf, RzBinObject *obj, RzBuffer *buf, Sdb *sdb
return true;
}
static RzPVector /*<RzBinAddr *>*/ *entries(RzBinFile *bf) {
static RzPVector /*<RzBinAddr *>*/ *dyldcache_entries(RzBinFile *bf) {
RzBinAddr *ptr = NULL;
RzPVector *ret = rz_pvector_new(free);
if (!ret) {
@ -93,7 +93,7 @@ static RzPVector /*<RzBinAddr *>*/ *entries(RzBinFile *bf) {
return ret;
}
static RzBinInfo *info(RzBinFile *bf) {
static RzBinInfo *dyldcache_info(RzBinFile *bf) {
RzBinInfo *ret = NULL;
if (!bf || !bf->o) {
@ -129,7 +129,7 @@ static RzBinInfo *info(RzBinFile *bf) {
return ret;
}
static ut64 baddr(RzBinFile *bf) {
static ut64 dyldcache_baddr(RzBinFile *bf) {
// XXX hardcoded
return 0x180000000;
}
@ -240,7 +240,7 @@ static void sections_from_bin(RzPVector /*<RzBinSection *>*/ *ret, RzBinFile *bf
(mach0);
}
static RzPVector /*<RzBinVirtualFile *>*/ *virtual_files(RzBinFile *bf) {
static RzPVector /*<RzBinVirtualFile *>*/ *dyldcache_virtual_files(RzBinFile *bf) {
RzPVector *ret = rz_pvector_new((RzPVectorFree)rz_bin_virtual_file_free);
if (!ret) {
return NULL;
@ -273,7 +273,7 @@ static int prot2perm(int x) {
return r;
}
static RzPVector /*<RzBinMap *>*/ *maps(RzBinFile *bf) {
static RzPVector /*<RzBinMap *>*/ *dyldcache_maps(RzBinFile *bf) {
RzDyldCache *cache = (RzDyldCache *)bf->o->bin_obj;
if (!cache) {
return NULL;
@ -303,7 +303,7 @@ static RzPVector /*<RzBinMap *>*/ *maps(RzBinFile *bf) {
return ret;
}
static RzPVector /*<RzBinSection *>*/ *sections(RzBinFile *bf) {
static RzPVector /*<RzBinSection *>*/ *dyldcache_sections(RzBinFile *bf) {
RzDyldCache *cache = (RzDyldCache *)bf->o->bin_obj;
if (!cache) {
return NULL;
@ -329,7 +329,7 @@ static RzPVector /*<RzBinSection *>*/ *sections(RzBinFile *bf) {
return ret;
}
static RzPVector /*<RzBinSymbol *>*/ *symbols(RzBinFile *bf) {
static RzPVector /*<RzBinSymbol *>*/ *dyldcache_symbols(RzBinFile *bf) {
RzDyldCache *cache = (RzDyldCache *)bf->o->bin_obj;
if (!cache) {
return NULL;
@ -366,12 +366,12 @@ static RzPVector /*<RzBinSymbol *>*/ *symbols(RzBinFile *bf) {
return ret;
}
static void destroy(RzBinFile *bf) {
static void dyldcache_destroy(RzBinFile *bf) {
RzDyldCache *cache = (RzDyldCache *)bf->o->bin_obj;
rz_dyldcache_free(cache);
}
static RzPVector /*<RzBinClass *>*/ *classes(RzBinFile *bf) {
static RzPVector /*<RzBinClass *>*/ *dyldcache_classes(RzBinFile *bf) {
RzDyldCache *cache = (RzDyldCache *)bf->o->bin_obj;
if (!cache) {
return NULL;
@ -502,234 +502,251 @@ beach:
return NULL;
}
static void header(RzBinFile *bf) {
if (!bf || !bf->o) {
return;
}
static RzStructuredData *dyldcache_structure(RzBinFile *bf) {
rz_return_val_if_fail(bf && bf->o && bf->o->bin_obj, NULL);
char uuidstr[128] = { 0 };
RzDyldCache *cache = (RzDyldCache *)bf->o->bin_obj;
if (!cache) {
return;
return NULL;
}
RzBin *bin = bf->rbin;
ut64 slide = rz_dyldcache_get_slide(cache);
PrintfCallback p = bin->cb_printf;
PJ *pj = pj_new();
if (!pj) {
return;
RzStructuredData *info = rz_structured_data_new_map();
if (!info) {
return NULL;
}
pj_o(pj);
RzStructuredData *dyldcache = rz_structured_data_map_add_map(info, "dyldcache");
if (!dyldcache) {
rz_structured_data_free(info);
return NULL;
}
pj_k(pj, "version");
RzDyldCacheHeaderVersion ver = rz_dyldcache_header_version(cache->hdr);
switch (ver) {
case RZ_DYLD_CACHE_HEADER_BEFORE_940:
pj_s(pj, "<940");
rz_structured_data_map_add_string(dyldcache, "version", "<940");
break;
case RZ_DYLD_CACHE_HEADER_940_OR_AFTER:
pj_s(pj, "940");
rz_structured_data_map_add_string(dyldcache, "version", "940");
break;
case RZ_DYLD_CACHE_HEADER_1042_1_OR_AFTER:
pj_s(pj, "1042.1");
rz_structured_data_map_add_string(dyldcache, "version", "1042.1");
break;
}
pj_k(pj, "header");
pj_o(pj);
pj_ks(pj, "magic", cache->hdr->magic);
pj_kn(pj, "mappingOffset", cache->hdr->mappingOffset);
pj_kn(pj, "mappingCount", cache->hdr->mappingCount);
pj_kn(pj, "imagesOffset", cache->hdr->imagesOffset);
pj_kn(pj, "imagesCount", cache->hdr->imagesCount);
pj_kn(pj, "dyldBaseAddress", cache->hdr->dyldBaseAddress);
pj_kn(pj, "codeSignatureOffset", cache->hdr->codeSignatureOffset);
pj_kn(pj, "codeSignatureSize", cache->hdr->codeSignatureSize);
pj_kn(pj, "slideInfoOffset", cache->hdr->slideInfoOffset);
pj_kn(pj, "slideInfoSize", cache->hdr->slideInfoSize);
pj_kn(pj, "localSymbolsOffset", cache->hdr->localSymbolsOffset);
pj_kn(pj, "localSymbolsSize", cache->hdr->localSymbolsSize);
char uuidstr[128];
rz_hex_bin2str((ut8 *)cache->hdr->uuid, 16, uuidstr);
pj_ks(pj, "uuid", uuidstr);
pj_ks(pj, "cacheType", (cache->hdr->cacheType == 0) ? "development" : "production");
pj_kn(pj, "branchPoolsOffset", cache->hdr->branchPoolsOffset);
pj_kn(pj, "branchPoolsCount", cache->hdr->branchPoolsCount);
if (rz_dyldcache_header_may_have_accel(cache->hdr)) {
pj_kn(pj, "accelerateInfoAddr", cache->hdr->accelerateInfoAddr + slide);
pj_kn(pj, "accelerateInfoSize", cache->hdr->accelerateInfoSize);
} else {
pj_kn(pj, "dyldInCacheMH", cache->hdr->dyldInCacheMH);
pj_kn(pj, "dyldInCacheEntry", cache->hdr->dyldInCacheEntry);
RzStructuredData *header = rz_structured_data_map_add_map(dyldcache, "header");
if (!header) {
rz_structured_data_free(info);
return NULL;
}
pj_kn(pj, "imagesTextOffset", cache->hdr->imagesTextOffset);
pj_kn(pj, "imagesTextCount", cache->hdr->imagesTextCount);
pj_kn(pj, "patchInfoAddr", cache->hdr->patchInfoAddr);
pj_kn(pj, "patchInfoSize", cache->hdr->patchInfoSize);
pj_kn(pj, "otherImageGroupAddrUnused", cache->hdr->otherImageGroupAddrUnused);
pj_kn(pj, "otherImageGroupSizeUnused", cache->hdr->otherImageGroupSizeUnused);
pj_kn(pj, "progClosuresAddr", cache->hdr->progClosuresAddr);
pj_kn(pj, "progClosuresSize", cache->hdr->progClosuresSize);
pj_kn(pj, "progClosuresTrieAddr", cache->hdr->progClosuresTrieAddr);
pj_kn(pj, "progClosuresTrieSize", cache->hdr->progClosuresTrieSize);
pj_kn(pj, "platform", cache->hdr->platform);
pj_kn(pj, "formatVersion", cache->hdr->formatVersion);
pj_kn(pj, "dylibsExpectedOnDisk", cache->hdr->dylibsExpectedOnDisk);
pj_kn(pj, "simulator", cache->hdr->simulator);
pj_kn(pj, "locallyBuiltCache", cache->hdr->locallyBuiltCache);
pj_kn(pj, "builtFromChainedFixups", cache->hdr->builtFromChainedFixups);
pj_kn(pj, "padding", cache->hdr->padding);
pj_kn(pj, "sharedRegionStart", cache->hdr->sharedRegionStart);
pj_kn(pj, "sharedRegionSize", cache->hdr->sharedRegionSize);
pj_kn(pj, "maxSlide", cache->hdr->maxSlide);
pj_kn(pj, "dylibsImageArrayAddr", cache->hdr->dylibsImageArrayAddr);
pj_kn(pj, "dylibsImageArraySize", cache->hdr->dylibsImageArraySize);
pj_kn(pj, "dylibsTrieAddr", cache->hdr->dylibsTrieAddr);
pj_kn(pj, "dylibsTrieSize", cache->hdr->dylibsTrieSize);
pj_kn(pj, "otherImageArrayAddr", cache->hdr->otherImageArrayAddr);
pj_kn(pj, "otherImageArraySize", cache->hdr->otherImageArraySize);
pj_kn(pj, "otherTrieAddr", cache->hdr->otherTrieAddr);
pj_kn(pj, "otherTrieSize", cache->hdr->otherTrieSize);
pj_kn(pj, "mappingWithSlideOffset", cache->hdr->mappingWithSlideOffset);
pj_kn(pj, "mappingWithSlideCount", cache->hdr->mappingWithSlideCount);
rz_structured_data_map_add_string(header, "magic", cache->hdr->magic);
rz_structured_data_map_add_unsigned(header, "mappingOffset", cache->hdr->mappingOffset, true);
rz_structured_data_map_add_unsigned(header, "mappingCount", cache->hdr->mappingCount, false);
rz_structured_data_map_add_unsigned(header, "imagesOffset", cache->hdr->imagesOffset, true);
rz_structured_data_map_add_unsigned(header, "imagesCount", cache->hdr->imagesCount, false);
rz_structured_data_map_add_unsigned(header, "dyldBaseAddress", cache->hdr->dyldBaseAddress, true);
rz_structured_data_map_add_unsigned(header, "codeSignatureOffset", cache->hdr->codeSignatureOffset, true);
rz_structured_data_map_add_unsigned(header, "codeSignatureSize", cache->hdr->codeSignatureSize, false);
rz_structured_data_map_add_unsigned(header, "slideInfoOffset", cache->hdr->slideInfoOffset, true);
rz_structured_data_map_add_unsigned(header, "slideInfoSize", cache->hdr->slideInfoSize, false);
rz_structured_data_map_add_unsigned(header, "localSymbolsOffset", cache->hdr->localSymbolsOffset, true);
rz_structured_data_map_add_unsigned(header, "localSymbolsSize", cache->hdr->localSymbolsSize, false);
rz_hex_bin2str((ut8 *)cache->hdr->uuid, 16, uuidstr);
rz_structured_data_map_add_string(header, "uuid", uuidstr);
rz_structured_data_map_add_string(header, "cacheType", (cache->hdr->cacheType == 0) ? "development" : "production");
rz_structured_data_map_add_unsigned(header, "branchPoolsOffset", cache->hdr->branchPoolsOffset, true);
rz_structured_data_map_add_unsigned(header, "branchPoolsCount", cache->hdr->branchPoolsCount, false);
if (rz_dyldcache_header_may_have_accel(cache->hdr)) {
rz_structured_data_map_add_unsigned(header, "accelerateInfoAddr", cache->hdr->accelerateInfoAddr + slide, false);
rz_structured_data_map_add_unsigned(header, "accelerateInfoSize", cache->hdr->accelerateInfoSize, false);
} else {
rz_structured_data_map_add_unsigned(header, "dyldInCacheMH", cache->hdr->dyldInCacheMH, true);
rz_structured_data_map_add_unsigned(header, "dyldInCacheEntry", cache->hdr->dyldInCacheEntry, true);
}
rz_structured_data_map_add_unsigned(header, "imagesTextOffset", cache->hdr->imagesTextOffset, true);
rz_structured_data_map_add_unsigned(header, "imagesTextCount", cache->hdr->imagesTextCount, false);
rz_structured_data_map_add_unsigned(header, "patchInfoAddr", cache->hdr->patchInfoAddr, false);
rz_structured_data_map_add_unsigned(header, "patchInfoSize", cache->hdr->patchInfoSize, false);
rz_structured_data_map_add_unsigned(header, "otherImageGroupAddrUnused", cache->hdr->otherImageGroupAddrUnused, true);
rz_structured_data_map_add_unsigned(header, "otherImageGroupSizeUnused", cache->hdr->otherImageGroupSizeUnused, false);
rz_structured_data_map_add_unsigned(header, "progClosuresAddr", cache->hdr->progClosuresAddr, true);
rz_structured_data_map_add_unsigned(header, "progClosuresSize", cache->hdr->progClosuresSize, false);
rz_structured_data_map_add_unsigned(header, "progClosuresTrieAddr", cache->hdr->progClosuresTrieAddr, true);
rz_structured_data_map_add_unsigned(header, "progClosuresTrieSize", cache->hdr->progClosuresTrieSize, false);
rz_structured_data_map_add_unsigned(header, "platform", cache->hdr->platform, false);
rz_structured_data_map_add_unsigned(header, "formatVersion", cache->hdr->formatVersion, false);
rz_structured_data_map_add_unsigned(header, "dylibsExpectedOnDisk", cache->hdr->dylibsExpectedOnDisk, false);
rz_structured_data_map_add_unsigned(header, "simulator", cache->hdr->simulator, false);
rz_structured_data_map_add_unsigned(header, "locallyBuiltCache", cache->hdr->locallyBuiltCache, false);
rz_structured_data_map_add_unsigned(header, "builtFromChainedFixups", cache->hdr->builtFromChainedFixups, false);
rz_structured_data_map_add_unsigned(header, "padding", cache->hdr->padding, true);
rz_structured_data_map_add_unsigned(header, "sharedRegionStart", cache->hdr->sharedRegionStart, false);
rz_structured_data_map_add_unsigned(header, "sharedRegionSize", cache->hdr->sharedRegionSize, false);
rz_structured_data_map_add_unsigned(header, "maxSlide", cache->hdr->maxSlide, false);
rz_structured_data_map_add_unsigned(header, "dylibsImageArrayAddr", cache->hdr->dylibsImageArrayAddr, true);
rz_structured_data_map_add_unsigned(header, "dylibsImageArraySize", cache->hdr->dylibsImageArraySize, false);
rz_structured_data_map_add_unsigned(header, "dylibsTrieAddr", cache->hdr->dylibsTrieAddr, true);
rz_structured_data_map_add_unsigned(header, "dylibsTrieSize", cache->hdr->dylibsTrieSize, false);
rz_structured_data_map_add_unsigned(header, "otherImageArrayAddr", cache->hdr->otherImageArrayAddr, true);
rz_structured_data_map_add_unsigned(header, "otherImageArraySize", cache->hdr->otherImageArraySize, false);
rz_structured_data_map_add_unsigned(header, "otherTrieAddr", cache->hdr->otherTrieAddr, true);
rz_structured_data_map_add_unsigned(header, "otherTrieSize", cache->hdr->otherTrieSize, false);
rz_structured_data_map_add_unsigned(header, "mappingWithSlideOffset", cache->hdr->mappingWithSlideOffset, true);
rz_structured_data_map_add_unsigned(header, "mappingWithSlideCount", cache->hdr->mappingWithSlideCount, false);
if (ver >= RZ_DYLD_CACHE_HEADER_940_OR_AFTER) {
pj_kn(pj, "dylibsPBLStateArrayAddrUnused", cache->hdr->dylibsPBLStateArrayAddrUnused);
pj_kn(pj, "dylibsPBLSetAddr", cache->hdr->dylibsPBLSetAddr);
pj_kn(pj, "programsPBLSetPoolAddr", cache->hdr->programsPBLSetPoolAddr);
pj_kn(pj, "programsPBLSetPoolSize", cache->hdr->programsPBLSetPoolSize);
pj_kn(pj, "programTrieAddr", cache->hdr->programTrieAddr);
pj_kn(pj, "programTrieSize", cache->hdr->programTrieSize);
pj_kn(pj, "osVersion", cache->hdr->osVersion);
pj_kn(pj, "altPlatform", cache->hdr->altPlatform);
pj_kn(pj, "altOsVersion", cache->hdr->altOsVersion);
pj_kn(pj, "swiftOptsOffset", cache->hdr->swiftOptsOffset);
pj_kn(pj, "swiftOptsSize", cache->hdr->swiftOptsSize);
pj_kn(pj, "subCacheArrayOffset", cache->hdr->subCacheArrayOffset);
pj_kn(pj, "subCacheArrayCount", cache->hdr->subCacheArrayCount);
rz_structured_data_map_add_unsigned(header, "dylibsPBLStateArrayAddrUnused", cache->hdr->dylibsPBLStateArrayAddrUnused, true);
rz_structured_data_map_add_unsigned(header, "dylibsPBLSetAddr", cache->hdr->dylibsPBLSetAddr, true);
rz_structured_data_map_add_unsigned(header, "programsPBLSetPoolAddr", cache->hdr->programsPBLSetPoolAddr, true);
rz_structured_data_map_add_unsigned(header, "programsPBLSetPoolSize", cache->hdr->programsPBLSetPoolSize, false);
rz_structured_data_map_add_unsigned(header, "programTrieAddr", cache->hdr->programTrieAddr, true);
rz_structured_data_map_add_unsigned(header, "programTrieSize", cache->hdr->programTrieSize, false);
rz_structured_data_map_add_unsigned(header, "osVersion", cache->hdr->osVersion, false);
rz_structured_data_map_add_unsigned(header, "altPlatform", cache->hdr->altPlatform, false);
rz_structured_data_map_add_unsigned(header, "altOsVersion", cache->hdr->altOsVersion, false);
rz_structured_data_map_add_unsigned(header, "swiftOptsOffset", cache->hdr->swiftOptsOffset, true);
rz_structured_data_map_add_unsigned(header, "swiftOptsSize", cache->hdr->swiftOptsSize, false);
rz_structured_data_map_add_unsigned(header, "subCacheArrayOffset", cache->hdr->subCacheArrayOffset, true);
rz_structured_data_map_add_unsigned(header, "subCacheArrayCount", cache->hdr->subCacheArrayCount, false);
rz_hex_bin2str(cache->hdr->symbolFileUUID, sizeof(cache->hdr->symbolFileUUID), uuidstr);
pj_ks(pj, "symbolFileUUID", uuidstr);
pj_kn(pj, "rosettaReadOnlyAddr", cache->hdr->rosettaReadOnlyAddr);
pj_kn(pj, "rosettaReadOnlySize", cache->hdr->rosettaReadOnlySize);
pj_kn(pj, "rosettaReadWriteAddr", cache->hdr->rosettaReadWriteAddr);
pj_kn(pj, "rosettaReadWriteSize", cache->hdr->rosettaReadWriteSize);
rz_structured_data_map_add_string(header, "symbolFileUUID", uuidstr);
rz_structured_data_map_add_unsigned(header, "rosettaReadOnlyAddr", cache->hdr->rosettaReadOnlyAddr, true);
rz_structured_data_map_add_unsigned(header, "rosettaReadOnlySize", cache->hdr->rosettaReadOnlySize, false);
rz_structured_data_map_add_unsigned(header, "rosettaReadWriteAddr", cache->hdr->rosettaReadWriteAddr, true);
rz_structured_data_map_add_unsigned(header, "rosettaReadWriteSize", cache->hdr->rosettaReadWriteSize, false);
}
if (ver >= RZ_DYLD_CACHE_HEADER_1042_1_OR_AFTER) {
pj_kn(pj, "cacheSubType", cache->hdr->cacheSubType);
pj_kn(pj, "objcOptsOffset", cache->hdr->objcOptsOffset);
pj_kn(pj, "objcOptsSize", cache->hdr->objcOptsSize);
pj_kn(pj, "cacheAtlasOffset", cache->hdr->cacheAtlasOffset);
pj_kn(pj, "cacheAtlasSize", cache->hdr->cacheAtlasSize);
pj_kn(pj, "dynamicDataOffset", cache->hdr->dynamicDataOffset);
pj_kn(pj, "dynamicDataMaxSize", cache->hdr->dynamicDataMaxSize);
rz_structured_data_map_add_unsigned(header, "cacheSubType", cache->hdr->cacheSubType, false);
rz_structured_data_map_add_unsigned(header, "objcOptsOffset", cache->hdr->objcOptsOffset, true);
rz_structured_data_map_add_unsigned(header, "objcOptsSize", cache->hdr->objcOptsSize, false);
rz_structured_data_map_add_unsigned(header, "cacheAtlasOffset", cache->hdr->cacheAtlasOffset, true);
rz_structured_data_map_add_unsigned(header, "cacheAtlasSize", cache->hdr->cacheAtlasSize, false);
rz_structured_data_map_add_unsigned(header, "dynamicDataOffset", cache->hdr->dynamicDataOffset, true);
rz_structured_data_map_add_unsigned(header, "dynamicDataMaxSize", cache->hdr->dynamicDataMaxSize, false);
}
pj_end(pj);
if (cache->accel) {
pj_k(pj, "accelerator");
pj_o(pj);
pj_kn(pj, "version", cache->accel->version);
pj_kn(pj, "imageExtrasCount", cache->accel->imageExtrasCount);
pj_kn(pj, "imagesExtrasOffset", cache->accel->imagesExtrasOffset);
pj_kn(pj, "bottomUpListOffset", cache->accel->bottomUpListOffset);
pj_kn(pj, "dylibTrieOffset", cache->accel->dylibTrieOffset);
pj_kn(pj, "dylibTrieSize", cache->accel->dylibTrieSize);
pj_kn(pj, "initializersOffset", cache->accel->initializersOffset);
pj_kn(pj, "initializersCount", cache->accel->initializersCount);
pj_kn(pj, "dofSectionsOffset", cache->accel->dofSectionsOffset);
pj_kn(pj, "dofSectionsCount", cache->accel->dofSectionsCount);
pj_kn(pj, "reExportListOffset", cache->accel->reExportListOffset);
pj_kn(pj, "reExportCount", cache->accel->reExportCount);
pj_kn(pj, "depListOffset", cache->accel->depListOffset);
pj_kn(pj, "depListCount", cache->accel->depListCount);
pj_kn(pj, "rangeTableOffset", cache->accel->rangeTableOffset);
pj_kn(pj, "rangeTableCount", cache->accel->rangeTableCount);
pj_kn(pj, "dyldSectionAddr", cache->accel->dyldSectionAddr + slide);
pj_end(pj);
RzStructuredData *acc = rz_structured_data_map_add_map(dyldcache, "accelerator");
if (!acc) {
rz_structured_data_free(info);
return NULL;
}
rz_structured_data_map_add_unsigned(acc, "version", cache->accel->version, false);
rz_structured_data_map_add_unsigned(acc, "imageExtrasCount", cache->accel->imageExtrasCount, false);
rz_structured_data_map_add_unsigned(acc, "imagesExtrasOffset", cache->accel->imagesExtrasOffset, true);
rz_structured_data_map_add_unsigned(acc, "bottomUpListOffset", cache->accel->bottomUpListOffset, true);
rz_structured_data_map_add_unsigned(acc, "dylibTrieOffset", cache->accel->dylibTrieOffset, true);
rz_structured_data_map_add_unsigned(acc, "dylibTrieSize", cache->accel->dylibTrieSize, false);
rz_structured_data_map_add_unsigned(acc, "initializersOffset", cache->accel->initializersOffset, true);
rz_structured_data_map_add_unsigned(acc, "initializersCount", cache->accel->initializersCount, false);
rz_structured_data_map_add_unsigned(acc, "dofSectionsOffset", cache->accel->dofSectionsOffset, true);
rz_structured_data_map_add_unsigned(acc, "dofSectionsCount", cache->accel->dofSectionsCount, false);
rz_structured_data_map_add_unsigned(acc, "reExportListOffset", cache->accel->reExportListOffset, true);
rz_structured_data_map_add_unsigned(acc, "reExportCount", cache->accel->reExportCount, false);
rz_structured_data_map_add_unsigned(acc, "depListOffset", cache->accel->depListOffset, true);
rz_structured_data_map_add_unsigned(acc, "depListCount", cache->accel->depListCount, false);
rz_structured_data_map_add_unsigned(acc, "rangeTableOffset", cache->accel->rangeTableOffset, true);
rz_structured_data_map_add_unsigned(acc, "rangeTableCount", cache->accel->rangeTableCount, false);
rz_structured_data_map_add_unsigned(acc, "dyldSectionAddr", cache->accel->dyldSectionAddr + slide, true);
}
if (cache->rebase_infos) {
size_t i;
pj_k(pj, "slideInfo");
pj_a(pj);
for (i = 0; i < cache->rebase_infos->length; i++) {
RzDyldRebaseInfo *rebase_info = cache->rebase_infos->entries[i].info;
pj_o(pj);
pj_kn(pj, "start", cache->rebase_infos->entries[i].start);
pj_kn(pj, "end", cache->rebase_infos->entries[i].end);
if (rebase_info) {
ut8 version = rebase_info->version;
pj_kn(pj, "version", version);
pj_kn(pj, "slide", slide);
if (version == 3) {
RzDyldRebaseInfo3 *info3 = (RzDyldRebaseInfo3 *)rebase_info;
pj_kn(pj, "page_starts_count", info3->page_starts_count);
pj_kn(pj, "page_size", info3->page_size);
pj_kn(pj, "auth_value_add", info3->auth_value_add);
} else if (version == 2 || version == 4) {
RzDyldRebaseInfo2 *info2 = (RzDyldRebaseInfo2 *)rebase_info;
pj_kn(pj, "page_starts_count", info2->page_starts_count);
pj_kn(pj, "page_extras_count", info2->page_extras_count);
pj_kn(pj, "delta_mask", info2->delta_mask);
pj_kn(pj, "value_mask", info2->value_mask);
pj_kn(pj, "value_add", info2->value_add);
pj_kn(pj, "delta_shift", info2->delta_shift);
pj_kn(pj, "page_size", info2->page_size);
} else if (version == 1) {
RzDyldRebaseInfo1 *info1 = (RzDyldRebaseInfo1 *)rebase_info;
pj_kn(pj, "toc_count", info1->toc_count);
pj_kn(pj, "entries_size", info1->entries_size);
pj_kn(pj, "page_size", 4096);
}
}
pj_end(pj);
RzStructuredData *slideInfo = rz_structured_data_map_add_array(dyldcache, "slideInfo");
if (!slideInfo) {
rz_structured_data_free(info);
return NULL;
}
for (size_t i = 0; i < cache->rebase_infos->length; i++) {
RzStructuredData *rbi = rz_structured_data_array_add_map(slideInfo);
if (!rbi) {
rz_structured_data_free(info);
return NULL;
}
RzDyldRebaseInfo *rebase_info = cache->rebase_infos->entries[i].info;
rz_structured_data_map_add_unsigned(rbi, "start", cache->rebase_infos->entries[i].start, true);
rz_structured_data_map_add_unsigned(rbi, "end", cache->rebase_infos->entries[i].end, true);
if (!rebase_info) {
continue;
}
ut8 version = rebase_info->version;
rz_structured_data_map_add_unsigned(rbi, "version", version, false);
rz_structured_data_map_add_unsigned(rbi, "slide", slide, false);
if (version == 3) {
RzDyldRebaseInfo3 *info3 = (RzDyldRebaseInfo3 *)rebase_info;
rz_structured_data_map_add_unsigned(rbi, "page_starts_count", info3->page_starts_count, false);
rz_structured_data_map_add_unsigned(rbi, "page_size", info3->page_size, false);
rz_structured_data_map_add_unsigned(rbi, "auth_value_add", info3->auth_value_add, false);
} else if (version == 2 || version == 4) {
RzDyldRebaseInfo2 *info2 = (RzDyldRebaseInfo2 *)rebase_info;
rz_structured_data_map_add_unsigned(rbi, "page_starts_count", info2->page_starts_count, false);
rz_structured_data_map_add_unsigned(rbi, "page_extras_count", info2->page_extras_count, false);
rz_structured_data_map_add_unsigned(rbi, "delta_mask", info2->delta_mask, true);
rz_structured_data_map_add_unsigned(rbi, "value_mask", info2->value_mask, true);
rz_structured_data_map_add_unsigned(rbi, "value_add", info2->value_add, false);
rz_structured_data_map_add_unsigned(rbi, "delta_shift", info2->delta_shift, false);
rz_structured_data_map_add_unsigned(rbi, "page_size", info2->page_size, false);
} else if (version == 1) {
RzDyldRebaseInfo1 *info1 = (RzDyldRebaseInfo1 *)rebase_info;
rz_structured_data_map_add_unsigned(rbi, "toc_count", info1->toc_count, false);
rz_structured_data_map_add_unsigned(rbi, "entries_size", info1->entries_size, false);
rz_structured_data_map_add_unsigned(rbi, "page_size", 4096, false);
}
}
pj_end(pj);
}
if (cache->hdr->imagesTextCount) {
pj_k(pj, "images");
pj_a(pj);
char file[256] = { 0 };
RzStructuredData *images = rz_structured_data_map_add_array(dyldcache, "images");
if (!images) {
rz_structured_data_free(info);
return NULL;
}
ut64 total_size = cache->hdr->imagesTextCount * sizeof(cache_text_info_t);
cache_text_info_t *text_infos = malloc(total_size);
if (!text_infos) {
goto beach;
RZ_LOG_ERROR("dyldcache: failed to allocate size: %" PFMT64u "\n", total_size);
return info;
}
if (rz_buf_fread_at(cache->buf, cache->hdr->imagesTextOffset, (ut8 *)text_infos, "16clii", cache->hdr->imagesTextCount) != total_size) {
free(text_infos);
goto beach;
RZ_LOG_ERROR("dyldcache: failed to read size: %" PFMT64u "\n", total_size);
return info;
}
size_t i;
for (i = 0; i != cache->hdr->imagesTextCount; i++) {
for (size_t i = 0; i != cache->hdr->imagesTextCount; i++) {
RzStructuredData *ti = rz_structured_data_array_add_map(images);
if (!ti) {
rz_structured_data_free(info);
return NULL;
}
cache_text_info_t *text_info = &text_infos[i];
rz_hex_bin2str((ut8 *)text_info->uuid, 16, uuidstr);
pj_o(pj);
pj_ks(pj, "uuid", uuidstr);
pj_kn(pj, "address", text_info->loadAddress + slide);
pj_kn(pj, "textSegmentSize", text_info->textSegmentSize);
char file[256];
rz_structured_data_map_add_string(ti, "uuid", uuidstr);
rz_structured_data_map_add_unsigned(ti, "address", text_info->loadAddress + slide, true);
rz_structured_data_map_add_unsigned(ti, "textSegmentSize", text_info->textSegmentSize, false);
if (rz_buf_read_at(cache->buf, text_info->pathOffset, (ut8 *)&file, sizeof(file)) == sizeof(file)) {
file[255] = 0;
pj_ks(pj, "path", file);
rz_structured_data_map_add_string(ti, "path", file);
char *last_slash = strrchr(file, '/');
if (last_slash && *last_slash) {
pj_ks(pj, "name", last_slash + 1);
if (RZ_STR_ISNOTEMPTY(last_slash)) {
rz_structured_data_map_add_string(ti, "name", last_slash + 1);
} else {
pj_ks(pj, "name", file);
rz_structured_data_map_add_string(ti, "name", file);
}
}
pj_end(pj);
}
pj_end(pj);
free(text_infos);
}
pj_end(pj);
p("%s\n", pj_string(pj));
beach:
pj_free(pj);
return info;
}
RzBinPlugin rz_bin_plugin_dyldcache = {
@ -737,18 +754,18 @@ RzBinPlugin rz_bin_plugin_dyldcache = {
.desc = "Apple DYLD Cache",
.license = "LGPL3",
.author = "pancake",
.load_buffer = &load_buffer,
.entries = &entries,
.baddr = &baddr,
.symbols = &symbols,
.virtual_files = &virtual_files,
.maps = &maps,
.sections = &sections,
.check_buffer = &check_buffer,
.destroy = &destroy,
.classes = &classes,
.header = &header,
.info = &info,
.load_buffer = &dyldcache_load_buffer,
.entries = &dyldcache_entries,
.baddr = &dyldcache_baddr,
.symbols = &dyldcache_symbols,
.virtual_files = &dyldcache_virtual_files,
.maps = &dyldcache_maps,
.sections = &dyldcache_sections,
.check_buffer = &dyldcache_check_buffer,
.destroy = &dyldcache_destroy,
.classes = &dyldcache_classes,
.bin_structure = &dyldcache_structure,
.info = &dyldcache_info,
};
#ifndef RZ_PLUGIN_INCORE

View file

@ -9,6 +9,13 @@ static bool check_buffer(RzBuffer *buf) {
return elf_check_buffer_aux(buf) == ELFCLASS32;
}
static RzStructuredData *elf_info_structure(RzBinFile *bf) {
rz_return_val_if_fail(bf && bf->o && bf->o->bin_obj, NULL);
ELFOBJ *bin = (ELFOBJ *)bf->o->bin_obj;
return elf_structure(bin);
}
RzBinPlugin rz_bin_plugin_elf = {
.name = "elf",
.desc = "ELF (Executable and Linkable Format)",
@ -27,8 +34,8 @@ RzBinPlugin rz_bin_plugin_elf = {
.symbols = &elf_symbols,
.imports = &elf_imports,
.info = &elf_info,
.bin_structure = &elf_info_structure,
.fields = &elf_fields,
.header = &elf_headers,
.size = &elf_size,
.libs = &elf_libs,
.relocs = &elf_relocs,

View file

@ -251,18 +251,6 @@ static RzPVector /*<RzBinAddr *>*/ *entries(RzBinFile *bf) {
return result;
}
static void headers_obj(ELFOBJ *bin, RZ_NONNULL PrintfCallback cb) {
Elf_(rz_bin_elf_print_ehdr)(bin, cb);
}
static void headers(RzBinFile *bf) {
rz_return_if_fail(bf && bf->o && bf->o->bin_obj);
ELFOBJ *bin = rz_bin_file_get_elf(bf);
headers_obj(bin, bf->rbin->cb_printf);
}
static bool create_set_e_ident(RzBuffer *result) {
return rz_buf_append_bytes(result, (ut8 *)ELFMAG, SELFMAG) &&
#ifdef RZ_BIN_ELF64

View file

@ -14,6 +14,13 @@ static ut64 get_elf_vaddr64(RzBinFile *bf, ut64 baddr, ut64 paddr, ut64 vaddr) {
return bin->baddr - bin->boffset + vaddr;
}
static RzStructuredData *elf64_info_structure(RzBinFile *bf) {
rz_return_val_if_fail(bf && bf->o && bf->o->bin_obj, NULL);
ELFOBJ *bin = (ELFOBJ *)bf->o->bin_obj;
return elf64_structure(bin);
}
RzBinPlugin rz_bin_plugin_elf64 = {
.name = "elf64",
.desc = "ELF64 (64-bit Executable and Linkable Format)",
@ -32,8 +39,8 @@ RzBinPlugin rz_bin_plugin_elf64 = {
.symbols = &elf64_symbols,
.imports = &elf64_imports,
.info = &elf64_info,
.bin_structure = &elf64_info_structure,
.fields = &elf64_fields,
.header = &elf64_headers,
.size = &elf64_size,
.libs = &elf64_libs,
.relocs = &elf64_relocs,

View file

@ -24,33 +24,59 @@ static RzBinInfo *le_info(RzBinFile *bf) {
return info;
}
static void le_header(RzBinFile *bf) {
rz_return_if_fail(bf && bf->rbin && bf->o && bf->o->bin_obj);
RzBin *rbin = bf->rbin;
static RzStructuredData *le_structure(RzBinFile *bf) {
rz_return_val_if_fail(bf && bf->rbin && bf->o && bf->o->bin_obj, NULL);
char magic[4] = { 0 };
rz_bin_le_obj_t *bin = bf->o->bin_obj;
if (!bin) {
return NULL;
}
LE_header *h = bin->header;
PrintfCallback p = rbin->cb_printf;
if (!h || !p) {
return;
if (!h) {
return NULL;
}
if (bin->mz_off == bin->le_off) {
p("MZ header not present\n");
} else {
p("MZ header offset: 0x%" PFMT64x "\n", bin->mz_off);
memcpy(magic, h->magic, sizeof(h->magic));
RzStructuredData *info = rz_structured_data_new_map();
if (!info) {
return NULL;
}
p("LE header offset: 0x%" PFMT64x "\n", bin->le_off);
p("Signature: %2s\n", h->magic);
p("Byte Order: %s\n", h->border ? "Big" : "Little");
p("Word Order: %s\n", h->worder ? "Big" : "Little");
p("Format Level: %u\n", h->level);
p("CPU: %s\n", bin->cpu);
p("OS: %s\n", bin->os);
p("Version: %u\n", h->ver);
p("Flags: 0x%08x", h->mflags);
RzStructuredData *le_info = rz_structured_data_map_add_map(info, "le");
if (!le_info) {
rz_structured_data_free(info);
return NULL;
}
rz_structured_data_map_add_string(le_info, "signature", magic);
rz_structured_data_map_add_unsigned(le_info, "le_offset", bin->le_off, true);
if (bin->mz_off && bin->mz_off != bin->le_off) {
rz_structured_data_map_add_unsigned(le_info, "mz_offset", bin->mz_off, true);
}
rz_structured_data_map_add_string(le_info, "byte_order", h->border ? "big endian" : "little endian");
rz_structured_data_map_add_string(le_info, "word_order", h->worder ? "big endian" : "little endian");
rz_structured_data_map_add_unsigned(le_info, "format_level", h->level, false);
rz_structured_data_map_add_string(le_info, "module_name", rz_str_get(bin->modname));
rz_structured_data_map_add_string(le_info, "type", rz_str_get(bin->type));
rz_structured_data_map_add_string(le_info, "cpu", rz_str_get(bin->cpu));
rz_structured_data_map_add_string(le_info, "os", rz_str_get(bin->os));
rz_structured_data_map_add_string(le_info, "arch", rz_str_get(bin->arch));
rz_structured_data_map_add_unsigned(le_info, "version", h->ver, false);
rz_structured_data_map_add_unsigned(le_info, "mflags", h->mflags, true);
RzStructuredData *flags = rz_structured_data_map_add_array(le_info, "flags");
if (!flags) {
rz_structured_data_free(info);
return NULL;
}
if (h->mflags) {
#define PF_(mask, cond, name) \
if ((h->mflags & mask) cond) { \
p(" " name); \
rz_structured_data_array_add_string(flags, name); \
}
PF_(M_SINGLE_DATA, , "SINGLEDATA");
PF_(M_PP_LIB_INIT, , "INITINSTANCE");
@ -58,10 +84,10 @@ static void le_header(RzBinFile *bf) {
PF_(M_INTERNAL_FIXUP, , "NOINTFIXUPS");
PF_(M_EXTERNAL_FIXUP, , "NOEXTFIXUPS");
if (h->mflags & M_USES_PM_WINDOWING) {
p(" PMWINAPI");
rz_structured_data_array_add_string(flags, "PMWINAPI");
} else {
PF_(M_PM_WINDOWING_INCOMP, , " PMWININCOMP");
PF_(M_PM_WINDOWING_COMPAT, , " PMWINCOMPAT");
PF_(M_PM_WINDOWING_INCOMP, , "PMWININCOMP");
PF_(M_PM_WINDOWING_COMPAT, , "PMWINCOMPAT");
}
PF_(M_TYPE_PM_DLL, , "PROTDLL");
PF_(M_TYPE_MASK, == M_TYPE_EXE, "EXE");
@ -70,50 +96,54 @@ static void le_header(RzBinFile *bf) {
PF_(M_TYPE_MASK, == M_TYPE_VDD, "VDD");
PF_(M_MP_UNSAFE, , "MPUNSAFE");
}
p("\n");
p("Pages: %u\n", h->mpages);
p("InitialEipObj: %u\n", h->startobj);
p("InitialEip: 0x%x\n", h->eip);
p("InitialStackObj: %u\n", h->stackobj);
p("InitialEsp: 0x%x\n", h->esp);
p("Page Size: 0x%x\n", h->pagesize);
rz_structured_data_map_add_unsigned(le_info, "mpages", h->mpages, false);
rz_structured_data_map_add_unsigned(le_info, "initial_eip_obj", h->startobj, false);
rz_structured_data_map_add_unsigned(le_info, "initial_eip", h->eip, true);
rz_structured_data_map_add_unsigned(le_info, "initial_stack_obj", h->stackobj, false);
rz_structured_data_map_add_unsigned(le_info, "initial_esp", h->esp, true);
rz_structured_data_map_add_unsigned(le_info, "page_size", h->pagesize, true);
if (bin->is_le) {
p("Last Page Size: 0x%x\n", h->le_last_page_size);
rz_structured_data_map_add_unsigned(le_info, "last_page_size", h->le_last_page_size, true);
} else {
p("Page Shift: 0x%x\n", h->pageshift);
rz_structured_data_map_add_unsigned(le_info, "page_shift", h->pageshift, true);
}
p("Fixup Size: 0x%x\n", h->fixupsize);
p("Fixup Checksum: 0x%x\n", h->fixupsum);
p("Loader Size: 0x%x\n", h->ldrsize);
p("Loader Checksum: 0x%x\n", h->ldrsum);
p("Obj Table: 0x%x\n", h->objtab);
p("Obj Count: %u\n", h->objcnt);
p("Obj Page Map: 0x%x\n", h->objmap);
p("Obj Iter Data Map: 0x%x\n", h->itermap);
p("Resource Table: 0x%x\n", h->rsrctab);
p("Resource Count: %u\n", h->rsrccnt);
p("Resident Name Table: 0x%x\n", h->restab);
p("Entry Table: 0x%x\n", h->enttab);
p("Directives Table: 0x%x\n", h->dirtab);
p("Directives Count: %u\n", h->dircnt);
p("Fixup Page Table: 0x%x\n", h->fpagetab);
p("Fixup Record Table: 0x%x\n", h->frectab);
p("Import Module Name Table: 0x%x\n", h->impmod);
p("Import Module Name Count: %u\n", h->impmodcnt);
p("Import Procedure Name Table: 0x%x\n", h->impproc);
p("Per-Page Checksum Table: 0x%x\n", h->pagesum);
p("Enumerated Data Pages: 0x%x\n", h->datapage);
p("Number of preload pages: %u\n", h->preload);
p("Non-resident Names Table: 0x%x\n", h->nrestab);
p("Size Non-resident Names: %u\n", h->cbnrestab);
p("Checksum Non-resident Names: 0x%x\n", h->nressum);
p("Autodata Obj: %u\n", h->autodata);
p("Debug Info: 0x%x\n", h->debuginfo);
p("Debug Length: 0x%x\n", h->debuglen);
p("Preload pages: %u\n", h->instpreload);
p("Demand pages: %u\n", h->instdemand);
p("Heap Size: 0x%x\n", h->heapsize);
p("Stack Size: 0x%x\n", h->stacksize);
rz_structured_data_map_add_unsigned(le_info, "fixup_size", h->fixupsize, true);
rz_structured_data_map_add_unsigned(le_info, "fixup_checksum", h->fixupsum, true);
rz_structured_data_map_add_unsigned(le_info, "loader_size", h->ldrsize, true);
rz_structured_data_map_add_unsigned(le_info, "loader_checksum", h->ldrsum, true);
rz_structured_data_map_add_unsigned(le_info, "obj_table", h->objtab, true);
rz_structured_data_map_add_unsigned(le_info, "obj_count", h->objcnt, false);
rz_structured_data_map_add_unsigned(le_info, "obj_page_map", h->objmap, true);
rz_structured_data_map_add_unsigned(le_info, "obj_iter_data_map", h->itermap, true);
rz_structured_data_map_add_unsigned(le_info, "resource_table", h->rsrctab, true);
rz_structured_data_map_add_unsigned(le_info, "resource_count", h->rsrccnt, false);
rz_structured_data_map_add_unsigned(le_info, "resident_name_table", h->restab, true);
rz_structured_data_map_add_unsigned(le_info, "entry_table", h->enttab, true);
rz_structured_data_map_add_unsigned(le_info, "directives_table", h->dirtab, true);
rz_structured_data_map_add_unsigned(le_info, "directives_count", h->dircnt, false);
rz_structured_data_map_add_unsigned(le_info, "fixup_page_table", h->fpagetab, true);
rz_structured_data_map_add_unsigned(le_info, "fixup_record_table", h->frectab, true);
rz_structured_data_map_add_unsigned(le_info, "import_module_name_table", h->impmod, true);
rz_structured_data_map_add_unsigned(le_info, "import_module_name_count", h->impmodcnt, false);
rz_structured_data_map_add_unsigned(le_info, "import_procedure_name_table", h->impproc, true);
rz_structured_data_map_add_unsigned(le_info, "per_page_checksum_table", h->pagesum, true);
rz_structured_data_map_add_unsigned(le_info, "enumerated_data_pages", h->datapage, true);
rz_structured_data_map_add_unsigned(le_info, "number_of_preload_pages", h->preload, false);
rz_structured_data_map_add_unsigned(le_info, "non_resident_names_table", h->nrestab, true);
rz_structured_data_map_add_unsigned(le_info, "size_non_resident_names", h->cbnrestab, false);
rz_structured_data_map_add_unsigned(le_info, "checksum_non_resident_names", h->nressum, true);
rz_structured_data_map_add_unsigned(le_info, "autodata_obj", h->autodata, false);
rz_structured_data_map_add_unsigned(le_info, "debug_info", h->debuginfo, true);
rz_structured_data_map_add_unsigned(le_info, "debug_length", h->debuglen, true);
rz_structured_data_map_add_unsigned(le_info, "preload_pages", h->instpreload, false);
rz_structured_data_map_add_unsigned(le_info, "demand_pages", h->instdemand, false);
rz_structured_data_map_add_unsigned(le_info, "heap_size", h->heapsize, true);
rz_structured_data_map_add_unsigned(le_info, "stack_size", h->stacksize, true);
return info;
}
RzBinPlugin rz_bin_plugin_le = {
@ -125,7 +155,7 @@ RzBinPlugin rz_bin_plugin_le = {
.load_buffer = &rz_bin_le_load_buffer,
.destroy = &rz_bin_le_destroy,
.info = &le_info,
.header = &le_header,
.bin_structure = &le_structure,
.virtual_files = &rz_bin_le_get_virtual_files,
.maps = &rz_bin_le_get_maps,
.sections = &rz_bin_le_get_sections,

View file

@ -345,7 +345,7 @@ RzBinPlugin rz_bin_plugin_mach0 = {
.imports = &mach0_imports,
.size = &mach0_size,
.info = &mach0_info,
.header = MACH0_(mach_headerfields),
.bin_structure = MACH0_(mach_structure),
.fields = MACH0_(mach_fields),
.libs = &mach0_libs,
.relocs = &mach0_relocs,

View file

@ -307,7 +307,7 @@ RzBinPlugin rz_bin_plugin_mach064 = {
.imports = &mach0_imports,
.info = &mach0_info,
.libs = &mach0_libs,
.header = MACH0_(mach_headerfields),
.bin_structure = MACH0_(mach_structure),
.relocs = &mach0_relocs,
.fields = MACH0_(mach_fields),
.create = &mach064_create,

View file

@ -10,7 +10,7 @@ RzBinPlugin rz_bin_plugin_mbn = {
.author = "pancake",
.load_buffer = &mbn_load_buffer,
.destroy = &mbn_destroy,
.header = &mbn_header,
.bin_structure = &mbn_structure_bin,
.size = &mbn_size,
.check_buffer = &mbn_check_buffer,
.baddr = &mbn_baddr,

View file

@ -37,7 +37,7 @@ RzBinPlugin rz_bin_plugin_mdt = {
.check_filename = &rz_bin_mdt_check_filename,
.load_buffer = &rz_bin_mdt_load_buffer,
.info = &mdt_info,
.header = &rz_bin_mdt_print_header,
.bin_structure = &rz_bin_mdt_structure,
.maps = &rz_bin_mdt_get_maps,
.entries = &rz_bin_mdt_get_entry_points,
.check_buffer = &rz_bin_mdt_check_buffer,

View file

@ -9,7 +9,7 @@
/* half-magic */
#define HM(x) (int)((int)(x[0] << 8) | (int)(x[1]))
static Sdb *get_sdb(RzBinFile *bf) {
static Sdb *mz_get_sdb(RzBinFile *bf) {
const struct rz_bin_mz_obj_t *bin;
if (bf && bf->o && bf->o->bin_obj) {
bin = (struct rz_bin_mz_obj_t *)bf->o->bin_obj;
@ -86,7 +86,7 @@ static bool checkEntrypointBuffer(RzBuffer *b) {
return false;
}
static bool check_buffer(RzBuffer *b) {
static bool mz_check_buffer(RzBuffer *b) {
rz_return_val_if_fail(b, false);
ut64 b_size = rz_buf_size(b);
if (b_size <= 0x3d) {
@ -121,7 +121,7 @@ static bool check_buffer(RzBuffer *b) {
return true;
}
static bool load(RzBinFile *bf, RzBinObject *obj, RzBuffer *buf, Sdb *sdb) {
static bool mz_load_buffer(RzBinFile *bf, RzBinObject *obj, RzBuffer *buf, Sdb *sdb) {
struct rz_bin_mz_obj_t *mz_obj = rz_bin_mz_new_buf(buf);
if (mz_obj) {
sdb_ns_set(sdb, "info", mz_obj->kv);
@ -131,11 +131,11 @@ static bool load(RzBinFile *bf, RzBinObject *obj, RzBuffer *buf, Sdb *sdb) {
return false;
}
static void destroy(RzBinFile *bf) {
static void mz_destroy(RzBinFile *bf) {
rz_bin_mz_free((struct rz_bin_mz_obj_t *)bf->o->bin_obj);
}
static RzBinAddr *binsym(RzBinFile *bf, RzBinSpecialSymbol type) {
static RzBinAddr *mz_binsym(RzBinFile *bf, RzBinSpecialSymbol type) {
RzBinAddr *mzaddr = NULL;
if (bf && bf->o && bf->o->bin_obj) {
switch (type) {
@ -149,7 +149,7 @@ static RzBinAddr *binsym(RzBinFile *bf, RzBinSpecialSymbol type) {
return mzaddr;
}
static RzPVector /*<RzBinAddr *>*/ *entries(RzBinFile *bf) {
static RzPVector /*<RzBinAddr *>*/ *mz_entries(RzBinFile *bf) {
RzBinAddr *ptr = NULL;
RzPVector *res = NULL;
if (!(res = rz_pvector_new(free))) {
@ -162,11 +162,11 @@ static RzPVector /*<RzBinAddr *>*/ *entries(RzBinFile *bf) {
return res;
}
static RzPVector /*<RzBinSection *>*/ *sections(RzBinFile *bf) {
static RzPVector /*<RzBinSection *>*/ *mz_sections(RzBinFile *bf) {
return rz_bin_mz_get_segments(bf->o->bin_obj);
}
static RzBinInfo *info(RzBinFile *bf) {
static RzBinInfo *mz_info(RzBinFile *bf) {
RzBinInfo *const ret = RZ_NEW0(RzBinInfo);
if (!ret) {
return NULL;
@ -191,40 +191,46 @@ static RzBinInfo *info(RzBinFile *bf) {
return ret;
}
static void header(RzBinFile *bf) {
const struct rz_bin_mz_obj_t *mz = (struct rz_bin_mz_obj_t *)bf->o->bin_obj;
eprintf("[0000:0000] Signature %c%c\n",
mz->dos_header->signature & 0xFF,
mz->dos_header->signature >> 8);
eprintf("[0000:0002] BytesInLastBlock 0x%04x\n",
mz->dos_header->bytes_in_last_block);
eprintf("[0000:0004] BlocksInFile 0x%04x\n",
mz->dos_header->blocks_in_file);
eprintf("[0000:0006] NumRelocs 0x%04x\n",
mz->dos_header->num_relocs);
eprintf("[0000:0008] HeaderParagraphs 0x%04x\n",
mz->dos_header->header_paragraphs);
eprintf("[0000:000a] MinExtraParagraphs 0x%04x\n",
mz->dos_header->min_extra_paragraphs);
eprintf("[0000:000c] MaxExtraParagraphs 0x%04x\n",
mz->dos_header->max_extra_paragraphs);
eprintf("[0000:000e] InitialSs 0x%04x\n",
mz->dos_header->ss);
eprintf("[0000:0010] InitialSp 0x%04x\n",
mz->dos_header->sp);
eprintf("[0000:0012] Checksum 0x%04x\n",
mz->dos_header->checksum);
eprintf("[0000:0014] InitialIp 0x%04x\n",
mz->dos_header->ip);
eprintf("[0000:0016] InitialCs 0x%04x\n",
mz->dos_header->cs);
eprintf("[0000:0018] RelocTableOffset 0x%04x\n",
mz->dos_header->reloc_table_offset);
eprintf("[0000:001a] OverlayNumber 0x%04x\n",
mz->dos_header->overlay_number);
static RzStructuredData *mz_structure(RzBinFile *bf) {
rz_return_val_if_fail(bf && bf->o && bf->o->bin_obj, NULL);
const struct rz_bin_mz_obj_t *mz_obj = (struct rz_bin_mz_obj_t *)bf->o->bin_obj;
RzStructuredData *info = rz_structured_data_new_map();
if (!info) {
return NULL;
}
RzStructuredData *mz = rz_structured_data_map_add_map(info, "mz");
if (!mz) {
rz_structured_data_free(info);
return NULL;
}
char signature[3];
signature[0] = mz_obj->dos_header->signature & 0xFF;
signature[1] = mz_obj->dos_header->signature >> 8;
signature[2] = 0;
rz_structured_data_map_add_string(mz, "Signature", signature);
rz_structured_data_map_add_unsigned(mz, "BytesInLastBlock", mz_obj->dos_header->bytes_in_last_block, true);
rz_structured_data_map_add_unsigned(mz, "BlocksInFile", mz_obj->dos_header->blocks_in_file, true);
rz_structured_data_map_add_unsigned(mz, "NumRelocs", mz_obj->dos_header->num_relocs, false);
rz_structured_data_map_add_unsigned(mz, "HeaderParagraphs", mz_obj->dos_header->header_paragraphs, true);
rz_structured_data_map_add_unsigned(mz, "MinExtraParagraphs", mz_obj->dos_header->min_extra_paragraphs, true);
rz_structured_data_map_add_unsigned(mz, "MaxExtraParagraphs", mz_obj->dos_header->max_extra_paragraphs, true);
rz_structured_data_map_add_unsigned(mz, "InitialSs", mz_obj->dos_header->ss, true);
rz_structured_data_map_add_unsigned(mz, "InitialSp", mz_obj->dos_header->sp, true);
rz_structured_data_map_add_unsigned(mz, "Checksum", mz_obj->dos_header->checksum, true);
rz_structured_data_map_add_unsigned(mz, "InitialIp", mz_obj->dos_header->ip, true);
rz_structured_data_map_add_unsigned(mz, "InitialCs", mz_obj->dos_header->cs, true);
rz_structured_data_map_add_unsigned(mz, "RelocTableOffset", mz_obj->dos_header->reloc_table_offset, true);
rz_structured_data_map_add_unsigned(mz, "OverlayNumber", mz_obj->dos_header->overlay_number, false);
return info;
}
static RzPVector /*<RzBinReloc *>*/ *relocs(RzBinFile *bf) {
static RzPVector /*<RzBinReloc *>*/ *mz_relocs(RzBinFile *bf) {
RzPVector *ret = NULL;
RzBinReloc *rel = NULL;
const struct rz_bin_mz_reloc_t *relocs = NULL;
@ -261,17 +267,17 @@ RzBinPlugin rz_bin_plugin_mz = {
.desc = "MZ (DOS MZ Executable)",
.license = "MIT",
.author = "nodepad",
.get_sdb = &get_sdb,
.load_buffer = &load,
.destroy = &destroy,
.check_buffer = &check_buffer,
.binsym = &binsym,
.entries = &entries,
.get_sdb = &mz_get_sdb,
.load_buffer = &mz_load_buffer,
.destroy = &mz_destroy,
.check_buffer = &mz_check_buffer,
.binsym = &mz_binsym,
.entries = &mz_entries,
.maps = &rz_bin_maps_of_file_sections,
.sections = &sections,
.info = &info,
.header = &header,
.relocs = &relocs,
.sections = &mz_sections,
.info = &mz_info,
.bin_structure = &mz_structure,
.relocs = &mz_relocs,
};
#ifndef RZ_PLUGIN_INCORE

View file

@ -8,7 +8,7 @@
#include "../i/private.h"
#include "../format/ne/ne.h"
static bool check_buffer(RzBuffer *b) {
static bool ne_check_buffer(RzBuffer *b) {
ut64 length = rz_buf_size(b);
if (length <= 0x3d) {
return false;
@ -32,7 +32,7 @@ static bool check_buffer(RzBuffer *b) {
return false;
}
static bool load_buffer(RzBinFile *bf, RzBinObject *obj, RzBuffer *buf, Sdb *sdb) {
static bool ne_load_buffer(RzBinFile *bf, RzBinObject *obj, RzBuffer *buf, Sdb *sdb) {
rz_return_val_if_fail(bf && obj && buf, false);
rz_bin_ne_obj_t *res = rz_bin_ne_new_buf(buf, bf->rbin->verbose);
if (res) {
@ -42,48 +42,65 @@ static bool load_buffer(RzBinFile *bf, RzBinObject *obj, RzBuffer *buf, Sdb *sdb
return false;
}
static void destroy(RzBinFile *bf) {
static void ne_destroy(RzBinFile *bf) {
rz_bin_ne_free(bf->o->bin_obj);
}
static void header(RzBinFile *bf) {
struct rz_bin_t *rbin = bf->rbin;
rz_bin_ne_obj_t *ne = bf->o->bin_obj;
rbin->cb_printf("Signature: NE\n");
rbin->cb_printf("MajLinkerVersion: %d\n", ne->ne_header->MajLinkerVersion);
rbin->cb_printf("MinLinkerVersion: %d\n", ne->ne_header->MinLinkerVersion);
rbin->cb_printf("EntryTableOffset: 0x%04x\n", ne->ne_header->EntryTableOffset);
rbin->cb_printf("EntryTableLength: %d\n", ne->ne_header->EntryTableLength);
rbin->cb_printf("FileLoadCRC: %08x\n", ne->ne_header->FileLoadCRC);
rbin->cb_printf("ProgFlags: %d\n", ne->ne_header->ProgFlags);
rbin->cb_printf("ApplFlags: %d\n", ne->ne_header->ApplFlags);
rbin->cb_printf("AutoDataSegIndex: %d\n", ne->ne_header->AutoDataSegIndex);
rbin->cb_printf("InitHeapSize: %d\n", ne->ne_header->InitHeapSize);
rbin->cb_printf("InitStackSize: %d\n", ne->ne_header->InitStackSize);
rbin->cb_printf("EntryPointCSIndex: %d\n", ne->ne_header->csEntryPoint);
rbin->cb_printf("EntryPointIPOff: 0x%04x\n", ne->ne_header->ipEntryPoint);
rbin->cb_printf("InitStack: %d\n", ne->ne_header->InitStack);
rbin->cb_printf("SegCount: %d\n", ne->ne_header->SegCount);
rbin->cb_printf("ModuleRefsCount: %d\n", ne->ne_header->ModRefs);
rbin->cb_printf("NonResNamesTblSiz: 0x%x\n", ne->ne_header->NoResNamesTabSiz);
rbin->cb_printf("SegTableOffset: 0x%x\n", ne->ne_header->SegTableOffset);
rbin->cb_printf("ResourceTblOff: 0x%x\n", ne->ne_header->ResTableOffset);
rbin->cb_printf("ResidentNameTblOff: 0x%x\n", ne->ne_header->ResidNamTable);
rbin->cb_printf("ModuleRefTblOff: 0x%x\n", ne->ne_header->ModRefTable);
rbin->cb_printf("ImportNameTblOff: 0x%x\n", ne->ne_header->ImportNameTable);
rbin->cb_printf("OffStartNonResTab: %d\n", ne->ne_header->OffStartNonResTab);
rbin->cb_printf("MovEntryCount: %d\n", ne->ne_header->MovEntryCount);
rbin->cb_printf("FileAlnSzShftCnt: %d\n", ne->ne_header->FileAlnSzShftCnt);
rbin->cb_printf("nResTabEntries: %d\n", ne->ne_header->nResTabEntries);
rbin->cb_printf("OS: %s\n", ne->os);
rbin->cb_printf("OS2EXEFlags: %x\n", ne->ne_header->OS2EXEFlags);
rbin->cb_printf("retThunkOffset: %d\n", ne->ne_header->retThunkOffset);
rbin->cb_printf("segRefThunksOff: %d\n", ne->ne_header->segrefthunksoff);
rbin->cb_printf("mincodeswap: %d\n", ne->ne_header->mincodeswap);
rbin->cb_printf("winver: %d.%d\n", ne->ne_header->expctwinver[1], ne->ne_header->expctwinver[0]);
static RzStructuredData *ne_structure(RzBinFile *bf) {
rz_return_val_if_fail(bf && bf->o && bf->o->bin_obj, NULL);
rz_bin_ne_obj_t *ne_obj = bf->o->bin_obj;
char tmp[256] = { 0 };
RzStructuredData *info = rz_structured_data_new_map();
if (!info) {
return NULL;
}
RzStructuredData *ne = rz_structured_data_map_add_map(info, "ne");
if (!ne) {
rz_structured_data_free(info);
return NULL;
}
rz_structured_data_map_add_unsigned(ne, "MajLinkerVersion", ne_obj->ne_header->MajLinkerVersion, false);
rz_structured_data_map_add_unsigned(ne, "MinLinkerVersion", ne_obj->ne_header->MinLinkerVersion, false);
rz_structured_data_map_add_unsigned(ne, "EntryTableOffset", ne_obj->ne_header->EntryTableOffset, true);
rz_structured_data_map_add_unsigned(ne, "EntryTableLength", ne_obj->ne_header->EntryTableLength, false);
rz_structured_data_map_add_unsigned(ne, "FileLoadCRC", ne_obj->ne_header->FileLoadCRC, true);
rz_structured_data_map_add_unsigned(ne, "ProgFlags", ne_obj->ne_header->ProgFlags, true);
rz_structured_data_map_add_unsigned(ne, "ApplFlags", ne_obj->ne_header->ApplFlags, true);
rz_structured_data_map_add_unsigned(ne, "AutoDataSegIndex", ne_obj->ne_header->AutoDataSegIndex, false);
rz_structured_data_map_add_unsigned(ne, "InitHeapSize", ne_obj->ne_header->InitHeapSize, false);
rz_structured_data_map_add_unsigned(ne, "InitStackSize", ne_obj->ne_header->InitStackSize, false);
rz_structured_data_map_add_unsigned(ne, "EntryPointCSIndex", ne_obj->ne_header->csEntryPoint, false);
rz_structured_data_map_add_unsigned(ne, "EntryPointIPOff", ne_obj->ne_header->ipEntryPoint, true);
rz_structured_data_map_add_unsigned(ne, "InitStack", ne_obj->ne_header->InitStack, true);
rz_structured_data_map_add_unsigned(ne, "SegCount", ne_obj->ne_header->SegCount, false);
rz_structured_data_map_add_unsigned(ne, "ModuleRefsCount", ne_obj->ne_header->ModRefs, false);
rz_structured_data_map_add_unsigned(ne, "NonResNamesTblSiz", ne_obj->ne_header->NoResNamesTabSiz, true);
rz_structured_data_map_add_unsigned(ne, "SegTableOffset", ne_obj->ne_header->SegTableOffset, true);
rz_structured_data_map_add_unsigned(ne, "ResourceTblOff", ne_obj->ne_header->ResTableOffset, true);
rz_structured_data_map_add_unsigned(ne, "ResidentNameTblOff", ne_obj->ne_header->ResidNamTable, true);
rz_structured_data_map_add_unsigned(ne, "ModuleRefTblOff", ne_obj->ne_header->ModRefTable, true);
rz_structured_data_map_add_unsigned(ne, "ImportNameTblOff", ne_obj->ne_header->ImportNameTable, true);
rz_structured_data_map_add_unsigned(ne, "OffStartNonResTab", ne_obj->ne_header->OffStartNonResTab, false);
rz_structured_data_map_add_unsigned(ne, "MovEntryCount", ne_obj->ne_header->MovEntryCount, false);
rz_structured_data_map_add_unsigned(ne, "FileAlnSzShftCnt", ne_obj->ne_header->FileAlnSzShftCnt, false);
rz_structured_data_map_add_unsigned(ne, "nResTabEntries", ne_obj->ne_header->nResTabEntries, false);
rz_structured_data_map_add_string(ne, "OS", ne_obj->os);
rz_structured_data_map_add_unsigned(ne, "OS2EXEFlags", ne_obj->ne_header->OS2EXEFlags, true);
rz_structured_data_map_add_unsigned(ne, "retThunkOffset", ne_obj->ne_header->retThunkOffset, true);
rz_structured_data_map_add_unsigned(ne, "segRefThunksOff", ne_obj->ne_header->segrefthunksoff, true);
rz_structured_data_map_add_unsigned(ne, "mincodeswap", ne_obj->ne_header->mincodeswap, false);
rz_strf(tmp, "%d.%d", ne_obj->ne_header->expctwinver[1], ne_obj->ne_header->expctwinver[0]);
rz_structured_data_map_add_string(ne, "winver", tmp);
return info;
}
RzBinInfo *info(RzBinFile *bf) {
RzBinInfo *ne_info(RzBinFile *bf) {
rz_bin_ne_obj_t *ne = bf->o->bin_obj;
RzBinInfo *i = RZ_NEW0(RzBinInfo);
if (i) {
@ -95,23 +112,23 @@ RzBinInfo *info(RzBinFile *bf) {
return i;
}
RzPVector /*<RzBinAddr *>*/ *entries(RzBinFile *bf) {
RzPVector /*<RzBinAddr *>*/ *ne_entries(RzBinFile *bf) {
return rz_bin_ne_get_entrypoints(bf->o->bin_obj);
}
RzPVector /*<RzBinSymbol *>*/ *symbols(RzBinFile *bf) {
RzPVector /*<RzBinSymbol *>*/ *ne_symbols(RzBinFile *bf) {
return rz_bin_ne_get_symbols(bf->o->bin_obj);
}
RzPVector /*<RzBinImport *>*/ *imports(RzBinFile *bf) {
RzPVector /*<RzBinImport *>*/ *ne_imports(RzBinFile *bf) {
return rz_bin_ne_get_imports(bf->o->bin_obj);
}
RzPVector /*<RzBinSection *>*/ *sections(RzBinFile *bf) {
RzPVector /*<RzBinSection *>*/ *ne_sections(RzBinFile *bf) {
return rz_bin_ne_get_segments(bf->o->bin_obj);
}
RzPVector /*<RzBinReloc *>*/ *relocs(RzBinFile *bf) {
RzPVector /*<RzBinReloc *>*/ *ne_relocs(RzBinFile *bf) {
return rz_bin_ne_get_relocs(bf->o->bin_obj);
}
@ -120,16 +137,16 @@ RzBinPlugin rz_bin_plugin_ne = {
.desc = "NE (New Executable)",
.author = "GustavoLCR",
.license = "LGPL3",
.check_buffer = &check_buffer,
.load_buffer = &load_buffer,
.destroy = &destroy,
.header = &header,
.info = &info,
.entries = &entries,
.sections = &sections,
.symbols = &symbols,
.imports = &imports,
.relocs = &relocs,
.check_buffer = &ne_check_buffer,
.load_buffer = &ne_load_buffer,
.destroy = &ne_destroy,
.bin_structure = &ne_structure,
.info = &ne_info,
.entries = &ne_entries,
.sections = &ne_sections,
.symbols = &ne_symbols,
.imports = &ne_imports,
.relocs = &ne_relocs,
};
#ifndef RZ_PLUGIN_INCORE

View file

@ -396,53 +396,116 @@ static bool n64_parse_homebrew_header(N64Rom *rom, N64Homebrew *hb) {
return true;
}
static void n64_header(RzBinFile *bf) {
rz_return_if_fail(bf);
static bool n64_structure_homebrew(N64Rom *rom, RzStructuredData *rom_data) {
N64Homebrew hb = { 0 };
if (!n64_parse_homebrew_header(rom, &hb)) {
return true;
}
RzStructuredData *homebrew = rz_structured_data_map_add_map(rom_data, "homebrew");
if (!homebrew) {
return false;
}
RzStructuredData *controllers = rz_structured_data_map_add_array(homebrew, "controllers");
if (!controllers) {
return false;
}
RzStructuredData *controller = rz_structured_data_array_add_map(controllers);
if (!controller) {
return false;
}
rz_structured_data_map_add_string(controller, "description", n64_decode_controller(hb.controller_1));
rz_structured_data_map_add_unsigned(controller, "value", hb.controller_1, true);
if (!(controller = rz_structured_data_array_add_map(controllers))) {
return false;
}
rz_structured_data_map_add_string(controller, "description", n64_decode_controller(hb.controller_2));
rz_structured_data_map_add_unsigned(controller, "value", hb.controller_2, true);
if (!(controller = rz_structured_data_array_add_map(controllers))) {
return false;
}
rz_structured_data_map_add_string(controller, "description", n64_decode_controller(hb.controller_3));
rz_structured_data_map_add_unsigned(controller, "value", hb.controller_3, true);
if (!(controller = rz_structured_data_array_add_map(controllers))) {
return false;
}
rz_structured_data_map_add_string(controller, "description", n64_decode_controller(hb.controller_4));
rz_structured_data_map_add_unsigned(controller, "value", hb.controller_4, true);
rz_structured_data_map_add_boolean(homebrew, "enable_rtc", hb.enable_rtc);
rz_structured_data_map_add_boolean(homebrew, "region_free", hb.is_region_free);
rz_structured_data_map_add_string(homebrew, "savetype_size", n64_decode_savetype_size(hb.save_size));
return true;
}
static RzStructuredData *n64_structure(RzBinFile *bf) {
rz_return_val_if_fail(bf && bf->o && bf->o->bin_obj, NULL);
RzBin *rbin = bf->rbin;
N64Rom *rom = bf->o->bin_obj;
N64Homebrew hb = { 0 };
char game_code[4] = { 0 };
ut8 rls = 0, pgs = 0;
n64_decode_rls_pgs(rom, &rls, &pgs);
// only the 3rd & 4th value
game_code[0] = rom->game_code[1];
game_code[1] = rom->game_code[2];
ut32 clock_rate = n64_decode_clock_rate(rom);
char *reserved1 = rz_hex_bin2strdup(rom->reserved1, sizeof(rom->reserved1));
char *game_title = rz_str_ndup(rom->game_title, sizeof(rom->game_title));
char *libultra_version = n64_decode_libultra_version(rom);
char *reserved2 = rz_hex_bin2strdup(rom->reserved2, sizeof(rom->reserved2));
rbin->cb_printf("ROM Reserved0: 0x%02x\n", rom->reserved0);
rbin->cb_printf("ROM Release Timing (PI_BSD_DOM1_RLS): 0x%02x\n", rls);
rbin->cb_printf("ROM Page Size (PI_BSD_DOM1_PGS): 0x%02x\n", pgs);
rbin->cb_printf("ROM Pulse Width (PI_BSD_DOM1_PWD): 0x%02x\n", rom->pulse_width);
rbin->cb_printf("ROM Latency (PI_BSD_DOM1_LAT): 0x%02x\n", rom->latency);
rbin->cb_printf("ROM Clock rate: 0x%08x\n", clock_rate);
rbin->cb_printf("ROM Boot Address: 0x%08x\n", rom->boot_address);
rbin->cb_printf("ROM Libultra Version: %s\n", rz_str_get(libultra_version));
rbin->cb_printf("ROM Check Code: 0x%016" PFMT64x "\n", rom->check_code);
rbin->cb_printf("ROM Reserved1: 0x%s\n", rz_str_get(reserved1));
rbin->cb_printf("ROM Game Title: %s\n", rz_str_get(game_title));
rbin->cb_printf("ROM Reserved2: 0x%s\n", rz_str_get(reserved2));
rbin->cb_printf("ROM Game Category: %s\n", n64_decode_game_category(rom));
rbin->cb_printf("ROM Game Unique Code: %c%c\n", rom->game_code[1], rom->game_code[2]);
rbin->cb_printf("ROM Game Destination: %s\n", n64_decode_game_destination(rom));
rbin->cb_printf("ROM Version: %u\n", (ut32)rom->rom_version);
if (n64_parse_homebrew_header(rom, &hb)) {
rbin->cb_printf("HB Controller 1: %s (0x%02x)\n", n64_decode_controller(hb.controller_1), hb.controller_1);
rbin->cb_printf("HB Controller 2: %s (0x%02x)\n", n64_decode_controller(hb.controller_2), hb.controller_2);
rbin->cb_printf("HB Controller 3: %s (0x%02x)\n", n64_decode_controller(hb.controller_3), hb.controller_3);
rbin->cb_printf("HB Controller 4: %s (0x%02x)\n", n64_decode_controller(hb.controller_4), hb.controller_4);
rbin->cb_printf("HB Enable RTC: %s\n", hb.enable_rtc ? "yes" : "no");
rbin->cb_printf("HB Region Free: %s\n", hb.is_region_free ? "yes" : "no");
rbin->cb_printf("HB Savetype Size: %s\n", n64_decode_savetype_size(hb.save_size));
RzStructuredData *info = rz_structured_data_new_map();
if (!info) {
return NULL;
}
RzStructuredData *rom_data = rz_structured_data_map_add_map(info, "n64_rom");
if (!rom_data) {
rz_structured_data_free(info);
return NULL;
}
rz_structured_data_map_add_unsigned(rom_data, "reserved_0", rom->reserved0, true);
rz_structured_data_map_add_unsigned(rom_data, "PI_BSD_DOM1_RLS", rls, true);
rz_structured_data_map_add_unsigned(rom_data, "PI_BSD_DOM1_PGS", pgs, true);
rz_structured_data_map_add_unsigned(rom_data, "PI_BSD_DOM1_PWD", rom->pulse_width, true);
rz_structured_data_map_add_unsigned(rom_data, "PI_BSD_DOM1_LAT", rom->latency, true);
rz_structured_data_map_add_unsigned(rom_data, "clock_rate", clock_rate, true);
rz_structured_data_map_add_unsigned(rom_data, "boot_address", rom->boot_address, true);
rz_structured_data_map_add_string(rom_data, "libultra_version", rz_str_get(libultra_version));
rz_structured_data_map_add_unsigned(rom_data, "check_code", rom->check_code, true);
rz_structured_data_map_add_string(rom_data, "reserved_1", reserved1);
rz_structured_data_map_add_string(rom_data, "game_title", rz_str_get(game_title));
rz_structured_data_map_add_string(rom_data, "reserved_2", reserved2);
rz_structured_data_map_add_string(rom_data, "game_category", n64_decode_game_category(rom));
rz_structured_data_map_add_string(rom_data, "game_unique_code", game_code);
rz_structured_data_map_add_string(rom_data, "game_destination", n64_decode_game_destination(rom));
rz_structured_data_map_add_unsigned(rom_data, "version", rom->rom_version, false);
free(reserved2);
free(libultra_version);
free(game_title);
free(reserved1);
if (!n64_structure_homebrew(rom, rom_data)) {
rz_structured_data_free(info);
return NULL;
}
return info;
}
RzBinPlugin rz_bin_plugin_z64 = {
@ -453,7 +516,7 @@ RzBinPlugin rz_bin_plugin_z64 = {
.load_buffer = &n64_load_buffer,
.check_buffer = &n64_check_buffer,
.destroy = &n64_destroy,
.header = &n64_header,
.bin_structure = &n64_structure,
.baddr = n64_baddr,
.boffset = &n64_boffset,
.entries = &n64_entries,

View file

@ -760,22 +760,22 @@ static RzPVector /*<RzBinAddr *>*/ *snes_entries(RzBinFile *bf) {
return ret;
}
static const char *snes_rom_get_map_mode(const SNESRom *rom) {
static char *snes_rom_get_map_mode(const SNESRom *rom) {
switch (rom->mode.map) {
case SNES_ROM_MODE_LOROM_32K:
return "LoROM 32K Banks (LoROM)";
return rz_str_dup("LoROM 32K Banks (LoROM)");
case SNES_ROM_MODE_HIROM_64K:
return "HiROM 64K Banks (HiROM)";
return rz_str_dup("HiROM 64K Banks (HiROM)");
case SNES_ROM_MODE_LOROM_32K_S_DD1:
return "LoROM 32K Banks + S-DD1 (LoROM Super MMC)";
return rz_str_dup("LoROM 32K Banks + S-DD1 (LoROM Super MMC)");
case SNES_ROM_MODE_LOROM_32K_SA_1:
return "LoROM 32K Banks + SA-1 (LoROM Emulates Super MMC)";
return rz_str_dup("LoROM 32K Banks + SA-1 (LoROM Emulates Super MMC)");
case SNES_ROM_MODE_EXTHIROM_64K:
return "HiROM 64K Banks (ExtHiROM)";
return rz_str_dup("HiROM 64K Banks (ExtHiROM)");
case SNES_ROM_MODE_HIROM_64K_SPC7110:
return "HiROM 64K Banks + SPC7110 (HiROM)";
return rz_str_dup("HiROM 64K Banks + SPC7110 (HiROM)");
default:
return "Unknown";
return rz_str_newf("unknown %u", (ut32)rom->mode.map);
}
}
@ -861,28 +861,24 @@ static char *snes_rom_get_cartridge_type(const SNESRom *rom) {
return rz_str_newf("%s+%s", base, cop);
}
static ut32 snes_rom_get_rom_size(const SNESRom *rom, const char **unit) {
static char *snes_rom_get_rom_size(const SNESRom *rom) {
ut32 size = 1u << rom->rom_size;
if (rom->rom_size > 10) {
*unit = "MB";
} else {
*unit = "KB";
return rz_str_newf("%u MB", size);
}
if (!rom->rom_size) {
return 0;
}
return 1u << rom->rom_size;
return rz_str_newf("%u KB", size);
}
static ut32 snes_rom_get_sram_size(const SNESRom *rom, const char **unit) {
if (rom->rom_size > 10) {
*unit = "MB";
} else {
*unit = "KB";
}
static char *snes_rom_get_sram_size(const SNESRom *rom) {
if (!rom->sram_size) {
return 0;
return NULL;
}
return 1u << rom->sram_size;
ut32 size = 1u << rom->sram_size;
if (rom->sram_size > 10) {
return rz_str_newf("%u MB", size);
}
return rz_str_newf("%u KB", size);
}
static const char *snes_rom_get_country(const SNESRom *rom) {
@ -909,62 +905,95 @@ static const char *snes_rom_get_country(const SNESRom *rom) {
}
}
static const char *snes_rom_get_developer(const SNESRom *rom) {
static char *snes_rom_get_developer(const SNESRom *rom) {
switch (rom->developer_id) {
case 0x00: return "None/Homebrew";
case 0x01: return "Nintendo";
default: return "Unknown";
case 0x00: return rz_str_dup("None/Homebrew");
case 0x01: return rz_str_dup("Nintendo");
default: return rz_str_newf("unknown 0x%02x", (ut32)rom->developer_id);
}
}
static void snes_header(RzBinFile *bf) {
rz_return_if_fail(bf);
static RzStructuredData *snes_structure(RzBinFile *bf) {
rz_return_val_if_fail(bf && bf->o && bf->o->bin_obj, NULL);
RzBin *rbin = bf->rbin;
const SNESRom *rom = bf->o->bin_obj;
char *game_title = rz_str_ndup(rom->game_title, sizeof(rom->game_title));
char *map_mode = snes_rom_get_map_mode(rom);
char *cartridge_type = snes_rom_get_cartridge_type(rom);
const char *unit = "";
ut32 size = 0;
char *size = NULL;
char *developer_id = snes_rom_get_developer(rom);
rbin->cb_printf("ROM Game Title: %s\n", game_title);
rbin->cb_printf("ROM Speed: %s\n", rom->mode.fast_rom ? "Fast" : "Slow");
rbin->cb_printf("ROM Map Mode: %s (0x%02x)\n", snes_rom_get_map_mode(rom), rom->mode.map);
rbin->cb_printf("ROM Cartridge: %s (0x%02x)\n", cartridge_type, rom->cartridge_type);
size = snes_rom_get_rom_size(rom, &unit);
rbin->cb_printf("ROM Size: %u %s (0x%02x)\n", size, unit, rom->rom_size);
size = snes_rom_get_sram_size(rom, &unit);
if (size > 0) {
rbin->cb_printf("ROM SRAM: %u %s (0x%02x)\n", size, unit, rom->sram_size);
} else {
rbin->cb_printf("ROM SRAM: missing (0x%02x)\n", rom->sram_size);
RzStructuredData *info = rz_structured_data_new_map();
if (!info) {
return NULL;
}
rbin->cb_printf("ROM Country: %s (0x%02x)\n", snes_rom_get_country(rom), rom->country);
rbin->cb_printf("ROM Developer: %s (0x%02x)\n", snes_rom_get_developer(rom), rom->developer_id);
rbin->cb_printf("ROM Version: 0x%02x\n", rom->rom_version);
rbin->cb_printf("ROM Checksum: 0x%04x (complement: 0x%04x)\n", rom->checksum, rom->checksum_compl);
RzStructuredData *rom_data = rz_structured_data_map_add_map(info, "snes_rom");
if (!rom_data) {
rz_structured_data_free(info);
return NULL;
}
rbin->cb_printf("ROM unused: 0x%08x\n", rom->vectors.unused0);
rbin->cb_printf("ROM cop: 0x%04x (native vector)\n", (ut32)rom->vectors.native_cop);
rbin->cb_printf("ROM br: 0x%04x (native vector)\n", (ut32)rom->vectors.native_br);
rbin->cb_printf("ROM abort: 0x%04x (native vector)\n", (ut32)rom->vectors.native_abort);
rbin->cb_printf("ROM nmi: 0x%04x (native vector)\n", (ut32)rom->vectors.native_nmi);
rbin->cb_printf("ROM unused: 0x%04x (native vector)\n", (ut32)rom->vectors.unused1);
rbin->cb_printf("ROM irq: 0x%04x (native vector)\n", (ut32)rom->vectors.native_irq);
rbin->cb_printf("ROM unused: 0x%08x\n", rom->vectors.unused2);
rbin->cb_printf("ROM cop: 0x%04x (emulator vector)\n", (ut32)rom->vectors.emu_cop);
rbin->cb_printf("ROM unused: 0x%04x (emulator vector)\n", (ut32)rom->vectors.unused3);
rbin->cb_printf("ROM abort: 0x%04x (emulator vector)\n", (ut32)rom->vectors.emu_abort);
rbin->cb_printf("ROM nmi: 0x%04x (emulator vector)\n", (ut32)rom->vectors.emu_nmi);
rbin->cb_printf("ROM reset: 0x%04x (emulator vector)\n", (ut32)rom->vectors.reset);
rbin->cb_printf("ROM irq: 0x%04x (emulator vector)\n", (ut32)rom->vectors.emu_irq);
rz_structured_data_map_add_string(rom_data, "game_title", game_title);
rz_structured_data_map_add_string(rom_data, "speed", rom->mode.fast_rom ? "fast" : "slow");
rz_structured_data_map_add_string(rom_data, "map_mode", map_mode);
rz_structured_data_map_add_string(rom_data, "cartridge", cartridge_type);
size = snes_rom_get_rom_size(rom);
rz_structured_data_map_add_string(rom_data, "size", size);
RZ_FREE(size);
if ((size = snes_rom_get_sram_size(rom))) {
rz_structured_data_map_add_string(rom_data, "sram_size", size);
RZ_FREE(size);
}
rz_structured_data_map_add_string(rom_data, "country", snes_rom_get_country(rom));
rz_structured_data_map_add_string(rom_data, "developer", developer_id);
rz_structured_data_map_add_unsigned(rom_data, "version", rom->rom_version, true);
rz_structured_data_map_add_unsigned(rom_data, "checksum", rom->checksum, true);
rz_structured_data_map_add_unsigned(rom_data, "checksum_compl", rom->checksum_compl, true);
RzStructuredData *vectors = rz_structured_data_map_add_map(rom_data, "vectors");
if (!vectors) {
rz_structured_data_free(info);
return NULL;
}
RzStructuredData *native = rz_structured_data_map_add_map(vectors, "native");
if (!native) {
rz_structured_data_free(info);
return NULL;
}
rz_structured_data_map_add_unsigned(native, "unused0", rom->vectors.unused0, true);
rz_structured_data_map_add_unsigned(native, "cop", rom->vectors.native_cop, true);
rz_structured_data_map_add_unsigned(native, "br", rom->vectors.native_br, true);
rz_structured_data_map_add_unsigned(native, "abort", rom->vectors.native_abort, true);
rz_structured_data_map_add_unsigned(native, "nmi", rom->vectors.native_nmi, true);
rz_structured_data_map_add_unsigned(native, "unused1", rom->vectors.unused1, true);
rz_structured_data_map_add_unsigned(native, "irq", rom->vectors.native_irq, true);
RzStructuredData *emulator = rz_structured_data_map_add_map(vectors, "emulator");
if (!emulator) {
rz_structured_data_free(info);
return NULL;
}
rz_structured_data_map_add_unsigned(emulator, "unused2", rom->vectors.unused2, true);
rz_structured_data_map_add_unsigned(emulator, "cop", rom->vectors.emu_cop, true);
rz_structured_data_map_add_unsigned(emulator, "unused3", rom->vectors.unused3, true);
rz_structured_data_map_add_unsigned(emulator, "abort", rom->vectors.emu_abort, true);
rz_structured_data_map_add_unsigned(emulator, "nmi", rom->vectors.emu_nmi, true);
rz_structured_data_map_add_unsigned(emulator, "reset", rom->vectors.reset, true);
rz_structured_data_map_add_unsigned(emulator, "irq", rom->vectors.emu_irq, true);
free(developer_id);
free(cartridge_type);
free(map_mode);
free(game_title);
return info;
}
RzBinPlugin rz_bin_plugin_sfc = {
@ -974,7 +1003,7 @@ RzBinPlugin rz_bin_plugin_sfc = {
.author = "usrshare",
.load_buffer = &snes_load_buffer,
.check_buffer = &snes_check_buffer,
.header = &snes_header,
.bin_structure = &snes_structure,
.entries = &snes_entries,
.maps = &rz_bin_maps_of_file_sections,
.sections = snes_sections,

View file

@ -5,7 +5,7 @@
#include "bin_pe.inc"
static bool check_buffer(RzBuffer *b) {
static bool pe_check_buffer(RzBuffer *b) {
ut64 length = rz_buf_size(b);
if (length <= 0x3d) {
return false;
@ -38,7 +38,7 @@ static bool check_buffer(RzBuffer *b) {
}
/* inspired in http://www.phreedom.org/solar/code/tinype/tiny.97/tiny.asm */
static RzBuffer *create(RzBin *bin, const ut8 *code, int codelen, const ut8 *data, int datalen, RzBinArchOptions *opt) {
static RzBuffer *pe_create(RzBin *bin, const ut8 *code, int codelen, const ut8 *data, int datalen, RzBinArchOptions *opt) {
ut32 hdrsize, p_start, p_opthdr, p_sections, p_lsrlc, n;
ut32 baddr = 0x400000;
RzBuffer *buf = rz_buf_new_with_bytes(NULL, 0);
@ -114,7 +114,7 @@ static RzBuffer *create(RzBin *bin, const ut8 *code, int codelen, const ut8 *dat
return buf;
}
static char *signature(RzBinFile *bf, bool json) {
static char *pe_signature(RzBinFile *bf, bool json) {
if (!bf || !bf->o || !bf->o->bin_obj) {
return NULL;
}
@ -130,7 +130,7 @@ static char *signature(RzBinFile *bf, bool json) {
return rz_pkcs7_cms_to_string(bin->cms);
}
static RzPVector /*<RzBinField *>*/ *fields(RzBinFile *bf) {
static RzPVector /*<RzBinField *>*/ *pe_fields(RzBinFile *bf) {
RzPVector *ret = rz_pvector_new((RzPVectorFree)rz_bin_field_free);
if (!ret) {
return NULL;
@ -350,112 +350,167 @@ static RzPVector /*<RzBinField *>*/ *fields(RzBinFile *bf) {
return ret;
}
static void header(RzBinFile *bf) {
static RzStructuredData *pe_structure(RzBinFile *bf) {
rz_return_val_if_fail(bf && bf->o && bf->o->bin_obj, NULL);
struct PE_(rz_bin_pe_obj_t) *bin = bf->o->bin_obj;
struct rz_bin_t *rbin = bf->rbin;
rbin->cb_printf("PE file header:\n");
rbin->cb_printf("IMAGE_NT_HEADERS\n");
rbin->cb_printf(" Signature : 0x%x\n", bin->nt_headers->Signature);
rbin->cb_printf("IMAGE_FILE_HEADERS\n");
rbin->cb_printf(" Machine : 0x%x\n", bin->nt_headers->file_header.Machine);
rbin->cb_printf(" NumberOfSections : 0x%x\n", bin->nt_headers->file_header.NumberOfSections);
rbin->cb_printf(" TimeDateStamp : 0x%x\n", bin->nt_headers->file_header.TimeDateStamp);
rbin->cb_printf(" PointerToSymbolTable : 0x%x\n", bin->nt_headers->file_header.PointerToSymbolTable);
rbin->cb_printf(" NumberOfSymbols : 0x%x\n", bin->nt_headers->file_header.NumberOfSymbols);
rbin->cb_printf(" SizeOfOptionalHeader : 0x%x\n", bin->nt_headers->file_header.SizeOfOptionalHeader);
rbin->cb_printf(" Characteristics : 0x%x\n", bin->nt_headers->file_header.Characteristics);
rbin->cb_printf("IMAGE_OPTIONAL_HEADERS\n");
rbin->cb_printf(" Magic : 0x%x\n", bin->nt_headers->optional_header.Magic);
rbin->cb_printf(" MajorLinkerVersion : 0x%x\n", bin->nt_headers->optional_header.MajorLinkerVersion);
rbin->cb_printf(" MinorLinkerVersion : 0x%x\n", bin->nt_headers->optional_header.MinorLinkerVersion);
rbin->cb_printf(" SizeOfCode : 0x%x\n", bin->nt_headers->optional_header.SizeOfCode);
rbin->cb_printf(" SizeOfInitializedData : 0x%x\n", bin->nt_headers->optional_header.SizeOfInitializedData);
rbin->cb_printf(" SizeOfUninitializedData : 0x%x\n", bin->nt_headers->optional_header.SizeOfUninitializedData);
rbin->cb_printf(" AddressOfEntryPoint : 0x%x\n", bin->nt_headers->optional_header.AddressOfEntryPoint);
rbin->cb_printf(" BaseOfCode : 0x%x\n", bin->nt_headers->optional_header.BaseOfCode);
rbin->cb_printf(" BaseOfData : 0x%x\n", bin->nt_headers->optional_header.BaseOfData);
rbin->cb_printf(" ImageBase : 0x%x\n", bin->nt_headers->optional_header.ImageBase);
rbin->cb_printf(" SectionAlignment : 0x%x\n", bin->nt_headers->optional_header.SectionAlignment);
rbin->cb_printf(" FileAlignment : 0x%x\n", bin->nt_headers->optional_header.FileAlignment);
rbin->cb_printf(" MajorOperatingSystemVersion : 0x%x\n", bin->nt_headers->optional_header.MajorOperatingSystemVersion);
rbin->cb_printf(" MinorOperatingSystemVersion : 0x%x\n", bin->nt_headers->optional_header.MinorOperatingSystemVersion);
rbin->cb_printf(" MajorImageVersion : 0x%x\n", bin->nt_headers->optional_header.MajorImageVersion);
rbin->cb_printf(" MinorImageVersion : 0x%x\n", bin->nt_headers->optional_header.MinorImageVersion);
rbin->cb_printf(" MajorSubsystemVersion : 0x%x\n", bin->nt_headers->optional_header.MajorSubsystemVersion);
rbin->cb_printf(" MinorSubsystemVersion : 0x%x\n", bin->nt_headers->optional_header.MinorSubsystemVersion);
rbin->cb_printf(" Win32VersionValue : 0x%x\n", bin->nt_headers->optional_header.Win32VersionValue);
rbin->cb_printf(" SizeOfImage : 0x%x\n", bin->nt_headers->optional_header.SizeOfImage);
rbin->cb_printf(" SizeOfHeaders : 0x%x\n", bin->nt_headers->optional_header.SizeOfHeaders);
rbin->cb_printf(" CheckSum : 0x%x\n", bin->nt_headers->optional_header.CheckSum);
rbin->cb_printf(" Subsystem : 0x%x\n", bin->nt_headers->optional_header.Subsystem);
rbin->cb_printf(" DllCharacteristics : 0x%x\n", bin->nt_headers->optional_header.DllCharacteristics);
rbin->cb_printf(" SizeOfStackReserve : 0x%x\n", bin->nt_headers->optional_header.SizeOfStackReserve);
rbin->cb_printf(" SizeOfStackCommit : 0x%x\n", bin->nt_headers->optional_header.SizeOfStackCommit);
rbin->cb_printf(" SizeOfHeapReserve : 0x%x\n", bin->nt_headers->optional_header.SizeOfHeapReserve);
rbin->cb_printf(" SizeOfHeapCommit : 0x%x\n", bin->nt_headers->optional_header.SizeOfHeapCommit);
rbin->cb_printf(" LoaderFlags : 0x%x\n", bin->nt_headers->optional_header.LoaderFlags);
rbin->cb_printf(" NumberOfRvaAndSizes : 0x%x\n", bin->nt_headers->optional_header.NumberOfRvaAndSizes);
RzListIter *it;
Pe_image_rich_entry *entry;
rbin->cb_printf("RICH_FIELDS\n");
rz_list_foreach (bin->rich_entries, it, entry) {
rbin->cb_printf(" Product: %d Name: %s Version: %d Times: %d\n", entry->productId, entry->productName, entry->minVersion, entry->timesUsed);
if (!bin) {
return NULL;
}
int i;
for (i = 0; i < PE_IMAGE_DIRECTORY_ENTRIES - 1; i++) {
if (bin->nt_headers->optional_header.DataDirectory[i].Size > 0) {
switch (i) {
case PE_IMAGE_DIRECTORY_ENTRY_EXPORT:
rbin->cb_printf("IMAGE_DIRECTORY_ENTRY_EXPORT\n");
break;
case PE_IMAGE_DIRECTORY_ENTRY_IMPORT:
rbin->cb_printf("IMAGE_DIRECTORY_ENTRY_IMPORT\n");
break;
case PE_IMAGE_DIRECTORY_ENTRY_RESOURCE:
rbin->cb_printf("IMAGE_DIRECTORY_ENTRY_RESOURCE\n");
break;
case PE_IMAGE_DIRECTORY_ENTRY_EXCEPTION:
rbin->cb_printf("IMAGE_DIRECTORY_ENTRY_EXCEPTION\n");
break;
case PE_IMAGE_DIRECTORY_ENTRY_SECURITY:
rbin->cb_printf("IMAGE_DIRECTORY_ENTRY_SECURITY\n");
break;
case PE_IMAGE_DIRECTORY_ENTRY_BASERELOC:
rbin->cb_printf("IMAGE_DIRECTORY_ENTRY_BASERELOC\n");
break;
case PE_IMAGE_DIRECTORY_ENTRY_DEBUG:
rbin->cb_printf("IMAGE_DIRECTORY_ENTRY_DEBUG\n");
break;
case PE_IMAGE_DIRECTORY_ENTRY_COPYRIGHT:
rbin->cb_printf("IMAGE_DIRECTORY_ENTRY_COPYRIGHT\n");
rbin->cb_printf("IMAGE_DIRECTORY_ENTRY_ARCHITECTURE\n");
break;
case PE_IMAGE_DIRECTORY_ENTRY_GLOBALPTR:
rbin->cb_printf("IMAGE_DIRECTORY_ENTRY_GLOBALPTR\n");
break;
case PE_IMAGE_DIRECTORY_ENTRY_TLS:
rbin->cb_printf("IMAGE_DIRECTORY_ENTRY_TLS\n");
break;
case PE_IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG:
rbin->cb_printf("IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG\n");
break;
case PE_IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT:
rbin->cb_printf("IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT\n");
break;
case PE_IMAGE_DIRECTORY_ENTRY_IAT:
rbin->cb_printf("IMAGE_DIRECTORY_ENTRY_IAT\n");
break;
case PE_IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT:
rbin->cb_printf("IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT\n");
break;
case PE_IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR:
rbin->cb_printf("IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR\n");
break;
RzStructuredData *info = rz_structured_data_new_map();
if (!info) {
return NULL;
}
RzStructuredData *pe32 = rz_structured_data_map_add_map(info, "pe32");
if (!pe32) {
rz_structured_data_free(info);
return NULL;
}
RzStructuredData *image = rz_structured_data_map_add_map(pe32, "IMAGE_NT_HEADERS");
if (!image) {
rz_structured_data_free(info);
return NULL;
}
rz_structured_data_map_add_unsigned(image, "Signature", bin->nt_headers->Signature, true);
if (!(image = rz_structured_data_map_add_map(pe32, "IMAGE_FILE_HEADERS"))) {
rz_structured_data_free(info);
return NULL;
}
rz_structured_data_map_add_unsigned(image, "Machine", bin->nt_headers->file_header.Machine, true);
rz_structured_data_map_add_unsigned(image, "NumberOfSections", bin->nt_headers->file_header.NumberOfSections, false);
rz_structured_data_map_add_unsigned(image, "TimeDateStamp", bin->nt_headers->file_header.TimeDateStamp, false);
rz_structured_data_map_add_unsigned(image, "PointerToSymbolTable", bin->nt_headers->file_header.PointerToSymbolTable, true);
rz_structured_data_map_add_unsigned(image, "NumberOfSymbols", bin->nt_headers->file_header.NumberOfSymbols, false);
rz_structured_data_map_add_unsigned(image, "SizeOfOptionalHeader", bin->nt_headers->file_header.SizeOfOptionalHeader, false);
rz_structured_data_map_add_unsigned(image, "Characteristics", bin->nt_headers->file_header.Characteristics, true);
if (!(image = rz_structured_data_map_add_map(pe32, "IMAGE_OPTIONAL_HEADERS"))) {
rz_structured_data_free(info);
return NULL;
}
rz_structured_data_map_add_unsigned(image, "Magic", bin->nt_headers->optional_header.Magic, true);
rz_structured_data_map_add_unsigned(image, "MajorLinkerVersion", bin->nt_headers->optional_header.MajorLinkerVersion, false);
rz_structured_data_map_add_unsigned(image, "MinorLinkerVersion", bin->nt_headers->optional_header.MinorLinkerVersion, false);
rz_structured_data_map_add_unsigned(image, "SizeOfCode", bin->nt_headers->optional_header.SizeOfCode, false);
rz_structured_data_map_add_unsigned(image, "SizeOfInitializedData", bin->nt_headers->optional_header.SizeOfInitializedData, false);
rz_structured_data_map_add_unsigned(image, "SizeOfUninitializedData", bin->nt_headers->optional_header.SizeOfUninitializedData, false);
rz_structured_data_map_add_unsigned(image, "AddressOfEntryPoint", bin->nt_headers->optional_header.AddressOfEntryPoint, true);
rz_structured_data_map_add_unsigned(image, "BaseOfCode", bin->nt_headers->optional_header.BaseOfCode, true);
rz_structured_data_map_add_unsigned(image, "BaseOfData", bin->nt_headers->optional_header.BaseOfData, true);
rz_structured_data_map_add_unsigned(image, "ImageBase", bin->nt_headers->optional_header.ImageBase, true);
rz_structured_data_map_add_unsigned(image, "SectionAlignment", bin->nt_headers->optional_header.SectionAlignment, true);
rz_structured_data_map_add_unsigned(image, "FileAlignment", bin->nt_headers->optional_header.FileAlignment, true);
rz_structured_data_map_add_unsigned(image, "MajorOperatingSystemVersion", bin->nt_headers->optional_header.MajorOperatingSystemVersion, true);
rz_structured_data_map_add_unsigned(image, "MinorOperatingSystemVersion", bin->nt_headers->optional_header.MinorOperatingSystemVersion, true);
rz_structured_data_map_add_unsigned(image, "MajorImageVersion", bin->nt_headers->optional_header.MajorImageVersion, true);
rz_structured_data_map_add_unsigned(image, "MinorImageVersion", bin->nt_headers->optional_header.MinorImageVersion, true);
rz_structured_data_map_add_unsigned(image, "MajorSubsystemVersion", bin->nt_headers->optional_header.MajorSubsystemVersion, true);
rz_structured_data_map_add_unsigned(image, "MinorSubsystemVersion", bin->nt_headers->optional_header.MinorSubsystemVersion, true);
rz_structured_data_map_add_unsigned(image, "Win32VersionValue", bin->nt_headers->optional_header.Win32VersionValue, true);
rz_structured_data_map_add_unsigned(image, "SizeOfImage", bin->nt_headers->optional_header.SizeOfImage, false);
rz_structured_data_map_add_unsigned(image, "SizeOfHeaders", bin->nt_headers->optional_header.SizeOfHeaders, false);
rz_structured_data_map_add_unsigned(image, "CheckSum", bin->nt_headers->optional_header.CheckSum, true);
rz_structured_data_map_add_unsigned(image, "Subsystem", bin->nt_headers->optional_header.Subsystem, true);
rz_structured_data_map_add_unsigned(image, "DllCharacteristics", bin->nt_headers->optional_header.DllCharacteristics, true);
rz_structured_data_map_add_unsigned(image, "SizeOfStackReserve", bin->nt_headers->optional_header.SizeOfStackReserve, false);
rz_structured_data_map_add_unsigned(image, "SizeOfStackCommit", bin->nt_headers->optional_header.SizeOfStackCommit, false);
rz_structured_data_map_add_unsigned(image, "SizeOfHeapReserve", bin->nt_headers->optional_header.SizeOfHeapReserve, false);
rz_structured_data_map_add_unsigned(image, "SizeOfHeapCommit", bin->nt_headers->optional_header.SizeOfHeapCommit, false);
rz_structured_data_map_add_unsigned(image, "LoaderFlags", bin->nt_headers->optional_header.LoaderFlags, true);
rz_structured_data_map_add_unsigned(image, "NumberOfRvaAndSizes", bin->nt_headers->optional_header.NumberOfRvaAndSizes, false);
if (rz_list_length(bin->rich_entries) > 0) {
if (!(image = rz_structured_data_map_add_array(pe32, "RICH_FIELDS"))) {
rz_structured_data_free(info);
return NULL;
}
RzListIter *it;
Pe_image_rich_entry *entry;
rz_list_foreach (bin->rich_entries, it, entry) {
RzStructuredData *field = rz_structured_data_array_add_map(image);
if (!field) {
rz_structured_data_free(info);
return NULL;
}
rbin->cb_printf(" VirtualAddress : 0x%x\n", bin->nt_headers->optional_header.DataDirectory[i].VirtualAddress);
rbin->cb_printf(" Size : 0x%x\n", bin->nt_headers->optional_header.DataDirectory[i].Size);
rz_structured_data_map_add_unsigned(field, "Product", entry->productId, false);
rz_structured_data_map_add_string(field, "Name", entry->productName);
rz_structured_data_map_add_unsigned(field, "Version", entry->minVersion, false);
rz_structured_data_map_add_unsigned(field, "Times", entry->timesUsed, false);
}
}
for (size_t i = 0; i < PE_IMAGE_DIRECTORY_ENTRIES - 1; i++) {
if (bin->nt_headers->optional_header.DataDirectory[i].Size < 1) {
continue;
}
const char *name = "unknown";
switch (i) {
case PE_IMAGE_DIRECTORY_ENTRY_EXPORT:
name = "IMAGE_DIRECTORY_ENTRY_EXPORT";
break;
case PE_IMAGE_DIRECTORY_ENTRY_IMPORT:
name = "IMAGE_DIRECTORY_ENTRY_IMPORT";
break;
case PE_IMAGE_DIRECTORY_ENTRY_RESOURCE:
name = "IMAGE_DIRECTORY_ENTRY_RESOURCE";
break;
case PE_IMAGE_DIRECTORY_ENTRY_EXCEPTION:
name = "IMAGE_DIRECTORY_ENTRY_EXCEPTION";
break;
case PE_IMAGE_DIRECTORY_ENTRY_SECURITY:
name = "IMAGE_DIRECTORY_ENTRY_SECURITY";
break;
case PE_IMAGE_DIRECTORY_ENTRY_BASERELOC:
name = "IMAGE_DIRECTORY_ENTRY_BASERELOC";
break;
case PE_IMAGE_DIRECTORY_ENTRY_DEBUG:
name = "IMAGE_DIRECTORY_ENTRY_DEBUG";
break;
case PE_IMAGE_DIRECTORY_ENTRY_COPYRIGHT:
name = "IMAGE_DIRECTORY_ENTRY_COPYRIGHT";
name = "IMAGE_DIRECTORY_ENTRY_ARCHITECTURE";
break;
case PE_IMAGE_DIRECTORY_ENTRY_GLOBALPTR:
name = "IMAGE_DIRECTORY_ENTRY_GLOBALPTR";
break;
case PE_IMAGE_DIRECTORY_ENTRY_TLS:
name = "IMAGE_DIRECTORY_ENTRY_TLS";
break;
case PE_IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG:
name = "IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG";
break;
case PE_IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT:
name = "IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT";
break;
case PE_IMAGE_DIRECTORY_ENTRY_IAT:
name = "IMAGE_DIRECTORY_ENTRY_IAT";
break;
case PE_IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT:
name = "IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT";
break;
case PE_IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR:
name = "IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR";
break;
}
if (!(image = rz_structured_data_map_add_map(pe32, name))) {
rz_structured_data_free(info);
return NULL;
}
rz_structured_data_map_add_unsigned(image, "VirtualAddress", bin->nt_headers->optional_header.DataDirectory[i].VirtualAddress, true);
rz_structured_data_map_add_unsigned(image, "Size", bin->nt_headers->optional_header.DataDirectory[i].Size, false);
}
return info;
}
RzBinPlugin rz_bin_plugin_pe = {
@ -463,28 +518,28 @@ RzBinPlugin rz_bin_plugin_pe = {
.desc = "PE (Portable Executable)",
.license = "LGPL3",
.author = "nibble",
.get_sdb = &get_sdb,
.load_buffer = &load_buffer,
.destroy = &destroy,
.check_buffer = &check_buffer,
.baddr = &baddr,
.binsym = &binsym,
.entries = &entries,
.maps = &maps,
.sections = &sections,
.signature = &signature,
.symbols = &symbols,
.imports = &imports,
.info = &info,
.header = &header,
.fields = &fields,
.libs = &libs,
.relocs = &relocs,
.create = &create,
.get_offset = &get_offset,
.get_vaddr = &get_vaddr,
.hashes = &compute_hashes,
.resources = &resources,
.get_sdb = &pe_get_sdb,
.load_buffer = &pe_load_buffer,
.destroy = &pe_destroy,
.check_buffer = &pe_check_buffer,
.baddr = &pe_baddr,
.binsym = &pe_binsym,
.entries = &pe_entries,
.maps = &pe_maps,
.sections = &pe_sections,
.signature = &pe_signature,
.symbols = &pe_symbols,
.imports = &pe_imports,
.info = &pe_info,
.bin_structure = &pe_structure,
.fields = &pe_fields,
.libs = &pe_libs,
.relocs = &pe_relocs,
.create = &pe_create,
.get_offset = &pe_get_offset,
.get_vaddr = &pe_get_vaddr,
.hashes = &pe_compute_hashes,
.resources = &pe_resources,
.section_flag_to_rzlist = &PE_(section_flag_to_rzlist),
};

View file

@ -10,7 +10,7 @@
#include "../i/private.h"
#include "pe/pe.h"
static Sdb *get_sdb(RzBinFile *bf) {
static Sdb *pe_get_sdb(RzBinFile *bf) {
RzBinObject *o = bf->o;
struct PE_(rz_bin_pe_obj_t) * bin;
if (!o || !o->bin_obj) {
@ -20,7 +20,7 @@ static Sdb *get_sdb(RzBinFile *bf) {
return bin ? bin->kv : NULL;
}
static bool load_buffer(RzBinFile *bf, RzBinObject *obj, RzBuffer *buf, Sdb *sdb) {
static bool pe_load_buffer(RzBinFile *bf, RzBinObject *obj, RzBuffer *buf, Sdb *sdb) {
rz_return_val_if_fail(bf && obj && buf, false);
struct PE_(rz_bin_pe_obj_t) *res = PE_(rz_bin_pe_new_buf)(buf, bf->rbin->verbose);
if (res) {
@ -31,16 +31,16 @@ static bool load_buffer(RzBinFile *bf, RzBinObject *obj, RzBuffer *buf, Sdb *sdb
return false;
}
static void destroy(RzBinFile *bf) {
static void pe_destroy(RzBinFile *bf) {
PE_(rz_bin_pe_free)
((struct PE_(rz_bin_pe_obj_t) *)bf->o->bin_obj);
}
static ut64 baddr(RzBinFile *bf) {
static ut64 pe_baddr(RzBinFile *bf) {
return PE_(rz_bin_pe_get_image_base)(bf->o->bin_obj);
}
static RzBinAddr *binsym(RzBinFile *bf, RzBinSpecialSymbol type) {
static RzBinAddr *pe_binsym(RzBinFile *bf, RzBinSpecialSymbol type) {
struct rz_bin_pe_addr_t *peaddr = NULL;
RzBinAddr *ret = NULL;
if (bf && bf->o && bf->o->bin_obj) {
@ -97,7 +97,7 @@ static void add_tls_callbacks(RzBinFile *bf, RzPVector /*<RzBinAddr *>*/ *vec) {
} while (vaddr);
}
static RzPVector /*<RzBinAddr *>*/ *entries(RzBinFile *bf) {
static RzPVector /*<RzBinAddr *>*/ *pe_entries(RzBinFile *bf) {
struct rz_bin_pe_addr_t *entry = NULL;
RzBinAddr *ptr = NULL;
RzPVector *ret;
@ -140,7 +140,7 @@ static ut32 perm_of_section_perm(ut64 perm) {
return r;
}
static RzPVector /*<RzBinMap *>*/ *maps(RzBinFile *bf) {
static RzPVector /*<RzBinMap *>*/ *pe_maps(RzBinFile *bf) {
struct PE_(rz_bin_pe_obj_t) *bin = (struct PE_(rz_bin_pe_obj_t) *)bf->o->bin_obj;
struct rz_bin_pe_section_t *sections = NULL;
if (!bin || !(sections = bin->sections)) {
@ -150,7 +150,7 @@ static RzPVector /*<RzBinMap *>*/ *maps(RzBinFile *bf) {
if (!ret) {
return NULL;
}
ut64 ba = baddr(bf);
ut64 ba = pe_baddr(bf);
RzBinMap *map = RZ_NEW0(RzBinMap);
if (!map) {
return ret;
@ -195,12 +195,12 @@ static RzPVector /*<RzBinMap *>*/ *maps(RzBinFile *bf) {
return ret;
}
static RzPVector /*<RzBinSection *>*/ *sections(RzBinFile *bf) {
static RzPVector /*<RzBinSection *>*/ *pe_sections(RzBinFile *bf) {
RzPVector *ret = NULL;
RzBinSection *ptr = NULL;
struct rz_bin_pe_section_t *sections = NULL;
struct PE_(rz_bin_pe_obj_t) *bin = (struct PE_(rz_bin_pe_obj_t) *)bf->o->bin_obj;
ut64 ba = baddr(bf);
ut64 ba = pe_baddr(bf);
int n_nonzero = 0;
int i;
if (!(ret = rz_pvector_new((RzPVectorFree)rz_bin_section_free))) {
@ -287,7 +287,7 @@ static ut64 find_go_pclntab(RzBinFile *bf, ut32 *size, ut64 *vaddr) {
if (!sections) {
return 0;
}
ut64 ba = baddr(bf);
ut64 ba = pe_baddr(bf);
for (int i = 0; !sections[i].last; i++) {
if (!strstr((char *)sections[i].name, "data")) {
continue;
@ -317,7 +317,7 @@ static ut64 find_go_pclntab(RzBinFile *bf, ut32 *size, ut64 *vaddr) {
return 0;
}
static RzPVector /*<RzBinSymbol *>*/ *symbols(RzBinFile *bf) {
static RzPVector /*<RzBinSymbol *>*/ *pe_symbols(RzBinFile *bf) {
RzPVector *ret = NULL;
ut64 go_pclntab_paddr = 0;
ut64 go_pclntab_vaddr = 0;
@ -421,7 +421,7 @@ static void filter_import(ut8 *n) {
}
}
static RzPVector /*<RzBinImport *>*/ *imports(RzBinFile *bf) {
static RzPVector /*<RzBinImport *>*/ *pe_imports(RzBinFile *bf) {
RzBinImport *ptr = NULL;
struct rz_bin_pe_import_t *imports = NULL;
int i;
@ -549,7 +549,7 @@ static const char *get_reloc_type_name(const ut8 reloc_type, const ut32 machine_
// NOTE: No patching is needed because base relocations (as their name suggests) patch relocations based off the delta
// between the executable expected load address, and the actual load address. And since Rizin always loads
// the binaries at their preferred base address, the delta is always 0 and so no patching is needed.
static RzPVector /*<RzBinReloc *>*/ *relocs(RzBinFile *bf) {
static RzPVector /*<RzBinReloc *>*/ *pe_relocs(RzBinFile *bf) {
rz_return_val_if_fail(bf && bf->o && bf->o->bin_obj, NULL);
RzBinPEObj *bin = bf->o->bin_obj;
@ -592,11 +592,11 @@ static RzPVector /*<RzBinReloc *>*/ *relocs(RzBinFile *bf) {
return ret;
}
static RzPVector /*<char *>*/ *libs(RzBinFile *bf) {
static RzPVector /*<char *>*/ *pe_libs(RzBinFile *bf) {
return PE_(rz_bin_pe_get_libs)(bf->o->bin_obj);
}
static RzPVector /*<RzBinResource *>*/ *resources(RzBinFile *bf) {
static RzPVector /*<RzBinResource *>*/ *pe_resources(RzBinFile *bf) {
struct PE_(rz_bin_pe_obj_t) *obj = bf->o->bin_obj;
if (!obj) {
return NULL;
@ -656,7 +656,7 @@ static int compare_strings(const void *a, const void *b, RZ_UNUSED void *user) {
return strcmp((const char *)a, (const char *)b);
}
static RzBinInfo *info(RzBinFile *bf) {
static RzBinInfo *pe_info(RzBinFile *bf) {
struct PE_(rz_bin_pe_obj_t) * bin;
SDebugInfo di = { { 0 } };
RzBinInfo *ret = RZ_NEW0(RzBinInfo);
@ -749,11 +749,11 @@ static RzBinInfo *info(RzBinFile *bf) {
return ret;
}
static ut64 get_vaddr(RzBinFile *bf, ut64 baddr, ut64 paddr, ut64 vaddr) {
static ut64 pe_get_vaddr(RzBinFile *bf, ut64 baddr, ut64 paddr, ut64 vaddr) {
return baddr + vaddr;
}
static RzPVector /*<RzBinFileHash *>*/ *compute_hashes(RzBinFile *bf) {
static RzPVector /*<RzBinFileHash *>*/ *pe_compute_hashes(RzBinFile *bf) {
RzPVector *file_hashes = rz_pvector_new((RzPVectorFree)rz_bin_file_hash_free);
const char *authentihash = PE_(bin_pe_get_authentihash)(bf->o->bin_obj);
if (authentihash) {
@ -772,7 +772,7 @@ static RzPVector /*<RzBinFileHash *>*/ *compute_hashes(RzBinFile *bf) {
* Currently only used by CIL plugin to resolve `call` and `jmp` targets
* \returns offset on success, UT64_MAX on fail
*/
static ut64 get_offset(RzBinFile *bf, int type, int idx) {
static ut64 pe_get_offset(RzBinFile *bf, int type, int idx) {
struct PE_(rz_bin_pe_obj_t) * bin;
Pe_image_clr *clr;

View file

@ -32,7 +32,7 @@ static bool windows_unwind_info_read(WinUnwindInfo *info, RzBuffer *b, ut64 at)
return true;
}
static bool check_buffer(RzBuffer *b) {
static bool pe64_check_buffer(RzBuffer *b) {
ut64 length = rz_buf_size(b);
if (length <= 0x3d) {
return false;
@ -62,7 +62,7 @@ static bool check_buffer(RzBuffer *b) {
return false;
}
static RzPVector /*<RzBinField *>*/ *fields(RzBinFile *bf) {
static RzPVector /*<RzBinField *>*/ *pe64_fields(RzBinFile *bf) {
RzPVector *ret = rz_pvector_new((RzPVectorFree)rz_bin_field_free);
if (!ret) {
return NULL;
@ -280,111 +280,167 @@ static RzPVector /*<RzBinField *>*/ *fields(RzBinFile *bf) {
return ret;
}
static void header(RzBinFile *bf) {
static RzStructuredData *pe64_structure(RzBinFile *bf) {
rz_return_val_if_fail(bf && bf->o && bf->o->bin_obj, NULL);
struct PE_(rz_bin_pe_obj_t) *bin = bf->o->bin_obj;
struct rz_bin_t *rbin = bf->rbin;
rbin->cb_printf("PE file header:\n");
rbin->cb_printf("IMAGE_NT_HEADERS\n");
rbin->cb_printf(" Signature : 0x%x\n", bin->nt_headers->Signature);
rbin->cb_printf("IMAGE_FILE_HEADERS\n");
rbin->cb_printf(" Machine : 0x%x\n", bin->nt_headers->file_header.Machine);
rbin->cb_printf(" NumberOfSections : 0x%x\n", bin->nt_headers->file_header.NumberOfSections);
rbin->cb_printf(" TimeDateStamp : 0x%x\n", bin->nt_headers->file_header.TimeDateStamp);
rbin->cb_printf(" PointerToSymbolTable : 0x%x\n", bin->nt_headers->file_header.PointerToSymbolTable);
rbin->cb_printf(" NumberOfSymbols : 0x%x\n", bin->nt_headers->file_header.NumberOfSymbols);
rbin->cb_printf(" SizeOfOptionalHeader : 0x%x\n", bin->nt_headers->file_header.SizeOfOptionalHeader);
rbin->cb_printf(" Characteristics : 0x%x\n", bin->nt_headers->file_header.Characteristics);
rbin->cb_printf("IMAGE_OPTIONAL_HEADERS\n");
rbin->cb_printf(" Magic : 0x%x\n", bin->nt_headers->optional_header.Magic);
rbin->cb_printf(" MajorLinkerVersion : 0x%x\n", bin->nt_headers->optional_header.MajorLinkerVersion);
rbin->cb_printf(" MinorLinkerVersion : 0x%x\n", bin->nt_headers->optional_header.MinorLinkerVersion);
rbin->cb_printf(" SizeOfCode : 0x%x\n", bin->nt_headers->optional_header.SizeOfCode);
rbin->cb_printf(" SizeOfInitializedData : 0x%x\n", bin->nt_headers->optional_header.SizeOfInitializedData);
rbin->cb_printf(" SizeOfUninitializedData : 0x%x\n", bin->nt_headers->optional_header.SizeOfUninitializedData);
rbin->cb_printf(" AddressOfEntryPoint : 0x%x\n", bin->nt_headers->optional_header.AddressOfEntryPoint);
rbin->cb_printf(" BaseOfCode : 0x%x\n", bin->nt_headers->optional_header.BaseOfCode);
rbin->cb_printf(" ImageBase : 0x%" PFMT64x "\n", bin->nt_headers->optional_header.ImageBase);
rbin->cb_printf(" SectionAlignment : 0x%x\n", bin->nt_headers->optional_header.SectionAlignment);
rbin->cb_printf(" FileAlignment : 0x%x\n", bin->nt_headers->optional_header.FileAlignment);
rbin->cb_printf(" MajorOperatingSystemVersion : 0x%x\n", bin->nt_headers->optional_header.MajorOperatingSystemVersion);
rbin->cb_printf(" MinorOperatingSystemVersion : 0x%x\n", bin->nt_headers->optional_header.MinorOperatingSystemVersion);
rbin->cb_printf(" MajorImageVersion : 0x%x\n", bin->nt_headers->optional_header.MajorImageVersion);
rbin->cb_printf(" MinorImageVersion : 0x%x\n", bin->nt_headers->optional_header.MinorImageVersion);
rbin->cb_printf(" MajorSubsystemVersion : 0x%x\n", bin->nt_headers->optional_header.MajorSubsystemVersion);
rbin->cb_printf(" MinorSubsystemVersion : 0x%x\n", bin->nt_headers->optional_header.MinorSubsystemVersion);
rbin->cb_printf(" Win32VersionValue : 0x%x\n", bin->nt_headers->optional_header.Win32VersionValue);
rbin->cb_printf(" SizeOfImage : 0x%x\n", bin->nt_headers->optional_header.SizeOfImage);
rbin->cb_printf(" SizeOfHeaders : 0x%x\n", bin->nt_headers->optional_header.SizeOfHeaders);
rbin->cb_printf(" CheckSum : 0x%x\n", bin->nt_headers->optional_header.CheckSum);
rbin->cb_printf(" Subsystem : 0x%x\n", bin->nt_headers->optional_header.Subsystem);
rbin->cb_printf(" DllCharacteristics : 0x%x\n", bin->nt_headers->optional_header.DllCharacteristics);
rbin->cb_printf(" SizeOfStackReserve : 0x%" PFMT64x "\n", bin->nt_headers->optional_header.SizeOfStackReserve);
rbin->cb_printf(" SizeOfStackCommit : 0x%" PFMT64x "\n", bin->nt_headers->optional_header.SizeOfStackCommit);
rbin->cb_printf(" SizeOfHeapReserve : 0x%" PFMT64x "\n", bin->nt_headers->optional_header.SizeOfHeapReserve);
rbin->cb_printf(" SizeOfHeapCommit : 0x%" PFMT64x "\n", bin->nt_headers->optional_header.SizeOfHeapCommit);
rbin->cb_printf(" LoaderFlags : 0x%x\n", bin->nt_headers->optional_header.LoaderFlags);
rbin->cb_printf(" NumberOfRvaAndSizes : 0x%x\n", bin->nt_headers->optional_header.NumberOfRvaAndSizes);
RzListIter *it;
Pe_image_rich_entry *entry;
rbin->cb_printf("RICH_FIELDS\n");
rz_list_foreach (bin->rich_entries, it, entry) {
rbin->cb_printf(" Product: %d Name: %s Version: %d Times: %d\n", entry->productId, entry->productName, entry->minVersion, entry->timesUsed);
if (!bin) {
return NULL;
}
int i;
for (i = 0; i < PE_IMAGE_DIRECTORY_ENTRIES - 1; i++) {
if (bin->nt_headers->optional_header.DataDirectory[i].Size > 0) {
switch (i) {
case PE_IMAGE_DIRECTORY_ENTRY_EXPORT:
rbin->cb_printf("IMAGE_DIRECTORY_ENTRY_EXPORT\n");
break;
case PE_IMAGE_DIRECTORY_ENTRY_IMPORT:
rbin->cb_printf("IMAGE_DIRECTORY_ENTRY_IMPORT\n");
break;
case PE_IMAGE_DIRECTORY_ENTRY_RESOURCE:
rbin->cb_printf("IMAGE_DIRECTORY_ENTRY_RESOURCE\n");
break;
case PE_IMAGE_DIRECTORY_ENTRY_EXCEPTION:
rbin->cb_printf("IMAGE_DIRECTORY_ENTRY_EXCEPTION\n");
break;
case PE_IMAGE_DIRECTORY_ENTRY_SECURITY:
rbin->cb_printf("IMAGE_DIRECTORY_ENTRY_SECURITY\n");
break;
case PE_IMAGE_DIRECTORY_ENTRY_BASERELOC:
rbin->cb_printf("IMAGE_DIRECTORY_ENTRY_BASERELOC\n");
break;
case PE_IMAGE_DIRECTORY_ENTRY_DEBUG:
rbin->cb_printf("IMAGE_DIRECTORY_ENTRY_DEBUG\n");
break;
case PE_IMAGE_DIRECTORY_ENTRY_COPYRIGHT:
rbin->cb_printf("IMAGE_DIRECTORY_ENTRY_COPYRIGHT\n");
rbin->cb_printf("IMAGE_DIRECTORY_ENTRY_ARCHITECTURE\n");
break;
case PE_IMAGE_DIRECTORY_ENTRY_GLOBALPTR:
rbin->cb_printf("IMAGE_DIRECTORY_ENTRY_GLOBALPTR\n");
break;
case PE_IMAGE_DIRECTORY_ENTRY_TLS:
rbin->cb_printf("IMAGE_DIRECTORY_ENTRY_TLS\n");
break;
case PE_IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG:
rbin->cb_printf("IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG\n");
break;
case PE_IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT:
rbin->cb_printf("IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT\n");
break;
case PE_IMAGE_DIRECTORY_ENTRY_IAT:
rbin->cb_printf("IMAGE_DIRECTORY_ENTRY_IAT\n");
break;
case PE_IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT:
rbin->cb_printf("IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT\n");
break;
case PE_IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR:
rbin->cb_printf("IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR\n");
break;
RzStructuredData *info = rz_structured_data_new_map();
if (!info) {
return NULL;
}
RzStructuredData *pe64 = rz_structured_data_map_add_map(info, "pe64");
if (!pe64) {
rz_structured_data_free(info);
return NULL;
}
RzStructuredData *image = rz_structured_data_map_add_map(pe64, "IMAGE_NT_HEADERS");
if (!image) {
rz_structured_data_free(info);
return NULL;
}
rz_structured_data_map_add_unsigned(image, "Signature", bin->nt_headers->Signature, true);
if (!(image = rz_structured_data_map_add_map(pe64, "IMAGE_FILE_HEADERS"))) {
rz_structured_data_free(info);
return NULL;
}
rz_structured_data_map_add_unsigned(image, "Machine", bin->nt_headers->file_header.Machine, true);
rz_structured_data_map_add_unsigned(image, "NumberOfSections", bin->nt_headers->file_header.NumberOfSections, false);
rz_structured_data_map_add_unsigned(image, "TimeDateStamp", bin->nt_headers->file_header.TimeDateStamp, false);
rz_structured_data_map_add_unsigned(image, "PointerToSymbolTable", bin->nt_headers->file_header.PointerToSymbolTable, true);
rz_structured_data_map_add_unsigned(image, "NumberOfSymbols", bin->nt_headers->file_header.NumberOfSymbols, false);
rz_structured_data_map_add_unsigned(image, "SizeOfOptionalHeader", bin->nt_headers->file_header.SizeOfOptionalHeader, false);
rz_structured_data_map_add_unsigned(image, "Characteristics", bin->nt_headers->file_header.Characteristics, true);
if (!(image = rz_structured_data_map_add_map(pe64, "IMAGE_OPTIONAL_HEADERS"))) {
rz_structured_data_free(info);
return NULL;
}
rz_structured_data_map_add_unsigned(image, "Magic", bin->nt_headers->optional_header.Magic, true);
rz_structured_data_map_add_unsigned(image, "MajorLinkerVersion", bin->nt_headers->optional_header.MajorLinkerVersion, false);
rz_structured_data_map_add_unsigned(image, "MinorLinkerVersion", bin->nt_headers->optional_header.MinorLinkerVersion, false);
rz_structured_data_map_add_unsigned(image, "SizeOfCode", bin->nt_headers->optional_header.SizeOfCode, false);
rz_structured_data_map_add_unsigned(image, "SizeOfInitializedData", bin->nt_headers->optional_header.SizeOfInitializedData, false);
rz_structured_data_map_add_unsigned(image, "SizeOfUninitializedData", bin->nt_headers->optional_header.SizeOfUninitializedData, false);
rz_structured_data_map_add_unsigned(image, "AddressOfEntryPoint", bin->nt_headers->optional_header.AddressOfEntryPoint, true);
rz_structured_data_map_add_unsigned(image, "BaseOfCode", bin->nt_headers->optional_header.BaseOfCode, true);
rz_structured_data_map_add_unsigned(image, "ImageBase", bin->nt_headers->optional_header.ImageBase, true);
rz_structured_data_map_add_unsigned(image, "SectionAlignment", bin->nt_headers->optional_header.SectionAlignment, true);
rz_structured_data_map_add_unsigned(image, "FileAlignment", bin->nt_headers->optional_header.FileAlignment, true);
rz_structured_data_map_add_unsigned(image, "MajorOperatingSystemVersion", bin->nt_headers->optional_header.MajorOperatingSystemVersion, true);
rz_structured_data_map_add_unsigned(image, "MinorOperatingSystemVersion", bin->nt_headers->optional_header.MinorOperatingSystemVersion, true);
rz_structured_data_map_add_unsigned(image, "MajorImageVersion", bin->nt_headers->optional_header.MajorImageVersion, true);
rz_structured_data_map_add_unsigned(image, "MinorImageVersion", bin->nt_headers->optional_header.MinorImageVersion, true);
rz_structured_data_map_add_unsigned(image, "MajorSubsystemVersion", bin->nt_headers->optional_header.MajorSubsystemVersion, true);
rz_structured_data_map_add_unsigned(image, "MinorSubsystemVersion", bin->nt_headers->optional_header.MinorSubsystemVersion, true);
rz_structured_data_map_add_unsigned(image, "Win32VersionValue", bin->nt_headers->optional_header.Win32VersionValue, true);
rz_structured_data_map_add_unsigned(image, "SizeOfImage", bin->nt_headers->optional_header.SizeOfImage, false);
rz_structured_data_map_add_unsigned(image, "SizeOfHeaders", bin->nt_headers->optional_header.SizeOfHeaders, false);
rz_structured_data_map_add_unsigned(image, "CheckSum", bin->nt_headers->optional_header.CheckSum, true);
rz_structured_data_map_add_unsigned(image, "Subsystem", bin->nt_headers->optional_header.Subsystem, true);
rz_structured_data_map_add_unsigned(image, "DllCharacteristics", bin->nt_headers->optional_header.DllCharacteristics, true);
rz_structured_data_map_add_unsigned(image, "SizeOfStackReserve", bin->nt_headers->optional_header.SizeOfStackReserve, false);
rz_structured_data_map_add_unsigned(image, "SizeOfStackCommit", bin->nt_headers->optional_header.SizeOfStackCommit, false);
rz_structured_data_map_add_unsigned(image, "SizeOfHeapReserve", bin->nt_headers->optional_header.SizeOfHeapReserve, false);
rz_structured_data_map_add_unsigned(image, "SizeOfHeapCommit", bin->nt_headers->optional_header.SizeOfHeapCommit, false);
rz_structured_data_map_add_unsigned(image, "LoaderFlags", bin->nt_headers->optional_header.LoaderFlags, true);
rz_structured_data_map_add_unsigned(image, "NumberOfRvaAndSizes", bin->nt_headers->optional_header.NumberOfRvaAndSizes, false);
if (rz_list_length(bin->rich_entries) > 0) {
if (!(image = rz_structured_data_map_add_array(pe64, "RICH_FIELDS"))) {
rz_structured_data_free(info);
return NULL;
}
RzListIter *it;
Pe_image_rich_entry *entry;
rz_list_foreach (bin->rich_entries, it, entry) {
RzStructuredData *field = rz_structured_data_array_add_map(image);
if (!field) {
rz_structured_data_free(info);
return NULL;
}
rbin->cb_printf(" VirtualAddress : 0x%x\n", bin->nt_headers->optional_header.DataDirectory[i].VirtualAddress);
rbin->cb_printf(" Size : 0x%x\n", bin->nt_headers->optional_header.DataDirectory[i].Size);
rz_structured_data_map_add_unsigned(field, "Product", entry->productId, false);
rz_structured_data_map_add_string(field, "Name", entry->productName);
rz_structured_data_map_add_unsigned(field, "Version", entry->minVersion, false);
rz_structured_data_map_add_unsigned(field, "Times", entry->timesUsed, false);
}
}
for (size_t i = 0; i < PE_IMAGE_DIRECTORY_ENTRIES - 1; i++) {
if (bin->nt_headers->optional_header.DataDirectory[i].Size < 1) {
continue;
}
const char *name = "unknown";
switch (i) {
case PE_IMAGE_DIRECTORY_ENTRY_EXPORT:
name = "IMAGE_DIRECTORY_ENTRY_EXPORT";
break;
case PE_IMAGE_DIRECTORY_ENTRY_IMPORT:
name = "IMAGE_DIRECTORY_ENTRY_IMPORT";
break;
case PE_IMAGE_DIRECTORY_ENTRY_RESOURCE:
name = "IMAGE_DIRECTORY_ENTRY_RESOURCE";
break;
case PE_IMAGE_DIRECTORY_ENTRY_EXCEPTION:
name = "IMAGE_DIRECTORY_ENTRY_EXCEPTION";
break;
case PE_IMAGE_DIRECTORY_ENTRY_SECURITY:
name = "IMAGE_DIRECTORY_ENTRY_SECURITY";
break;
case PE_IMAGE_DIRECTORY_ENTRY_BASERELOC:
name = "IMAGE_DIRECTORY_ENTRY_BASERELOC";
break;
case PE_IMAGE_DIRECTORY_ENTRY_DEBUG:
name = "IMAGE_DIRECTORY_ENTRY_DEBUG";
break;
case PE_IMAGE_DIRECTORY_ENTRY_COPYRIGHT:
name = "IMAGE_DIRECTORY_ENTRY_COPYRIGHT";
name = "IMAGE_DIRECTORY_ENTRY_ARCHITECTURE";
break;
case PE_IMAGE_DIRECTORY_ENTRY_GLOBALPTR:
name = "IMAGE_DIRECTORY_ENTRY_GLOBALPTR";
break;
case PE_IMAGE_DIRECTORY_ENTRY_TLS:
name = "IMAGE_DIRECTORY_ENTRY_TLS";
break;
case PE_IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG:
name = "IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG";
break;
case PE_IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT:
name = "IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT";
break;
case PE_IMAGE_DIRECTORY_ENTRY_IAT:
name = "IMAGE_DIRECTORY_ENTRY_IAT";
break;
case PE_IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT:
name = "IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT";
break;
case PE_IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR:
name = "IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR";
break;
}
if (!(image = rz_structured_data_map_add_map(pe64, name))) {
rz_structured_data_free(info);
return NULL;
}
rz_structured_data_map_add_unsigned(image, "VirtualAddress", bin->nt_headers->optional_header.DataDirectory[i].VirtualAddress, true);
rz_structured_data_map_add_unsigned(image, "Size", bin->nt_headers->optional_header.DataDirectory[i].Size, false);
}
return info;
}
#define RzBinPEObj struct PE_(rz_bin_pe_obj_t)
@ -434,7 +490,7 @@ static bool read_pe64_scope_record(RzBuffer *buf, ut64 base, PE64_SCOPE_RECORD *
rz_buf_read_ble32_offset(buf, &offset, &record->JumpTarget, big_endian);
}
static RzPVector /*<RzBinTrycatch *>*/ *trycatch(RzBinFile *bf) {
static RzPVector /*<RzBinTrycatch *>*/ *pe64_trycatch(RzBinFile *bf) {
ut64 baseAddr = bf->o->opts.baseaddr;
ut64 offset;
@ -582,27 +638,27 @@ RzBinPlugin rz_bin_plugin_pe64 = {
.desc = "PE64 (PE32+) binary",
.license = "LGPL3",
.author = "nibble",
.get_sdb = &get_sdb,
.load_buffer = &load_buffer,
.destroy = &destroy,
.check_buffer = &check_buffer,
.baddr = &baddr,
.binsym = &binsym,
.entries = &entries,
.maps = &maps,
.sections = &sections,
.symbols = &symbols,
.imports = &imports,
.info = &info,
.header = &header,
.fields = &fields,
.libs = &libs,
.relocs = &relocs,
.get_offset = &get_offset,
.get_vaddr = &get_vaddr,
.trycatch = &trycatch,
.hashes = &compute_hashes,
.resources = &resources,
.get_sdb = &pe_get_sdb,
.load_buffer = &pe_load_buffer,
.destroy = &pe_destroy,
.check_buffer = &pe64_check_buffer,
.baddr = &pe_baddr,
.binsym = &pe_binsym,
.entries = &pe_entries,
.maps = &pe_maps,
.sections = &pe_sections,
.symbols = &pe_symbols,
.imports = &pe_imports,
.info = &pe_info,
.bin_structure = &pe64_structure,
.fields = &pe64_fields,
.libs = &pe_libs,
.relocs = &pe_relocs,
.get_offset = &pe_get_offset,
.get_vaddr = &pe_get_vaddr,
.trycatch = &pe64_trycatch,
.hashes = &pe_compute_hashes,
.resources = &pe_resources,
.section_flag_to_rzlist = &PE_(section_flag_to_rzlist),
};

View file

@ -49,13 +49,13 @@ static bool lmf_header_load(lmf_header *lmfh, RzBuffer *buf, Sdb *db) {
return true;
}
static bool check_buffer(RzBuffer *buf) {
static bool qnx_check_buffer(RzBuffer *buf) {
ut8 tmp[6];
int r = rz_buf_read_at(buf, 0, tmp, sizeof(tmp));
return r == sizeof(tmp) && !memcmp(tmp, QNX_MAGIC, sizeof(tmp));
}
static void destroy(RzBinFile *bf) {
static void qnx_destroy(RzBinFile *bf) {
QnxObj *qo = bf->o->bin_obj;
rz_pvector_free(qo->sections);
rz_pvector_free(qo->maps);
@ -64,7 +64,7 @@ static void destroy(RzBinFile *bf) {
free(qo);
}
static bool load_buffer(RzBinFile *bf, RzBinObject *obj, RzBuffer *buf, Sdb *sdb) {
static bool qnx_load_buffer(RzBinFile *bf, RzBinObject *obj, RzBuffer *buf, Sdb *sdb) {
lmf_record lrec;
lmf_resource lres;
lmf_data ldata;
@ -225,7 +225,7 @@ beach:
* @param RzBinFile to extract the data from
* @return RzBinInfo file with the info
*/
static RzBinInfo *info(RzBinFile *bf) {
static RzBinInfo *qnx_info(RzBinFile *bf) {
rz_return_val_if_fail(bf && bf->o && bf->o->bin_obj, NULL);
RzBinInfo *ret = RZ_NEW0(RzBinInfo);
if (!ret) {
@ -244,7 +244,7 @@ static RzBinInfo *info(RzBinFile *bf) {
return ret;
}
static RzPVector /*<RzBinReloc *>*/ *relocs(RzBinFile *bf) {
static RzPVector /*<RzBinReloc *>*/ *qnx_relocs(RzBinFile *bf) {
rz_return_val_if_fail(bf && bf->o, NULL);
QnxObj *qo = bf->o->bin_obj;
RzBinReloc *reloc = NULL;
@ -267,42 +267,74 @@ static RzPVector /*<RzBinReloc *>*/ *relocs(RzBinFile *bf) {
return relocs;
}
static void header(RzBinFile *bf) {
rz_return_if_fail(bf && bf->o && bf->rbin);
static RzStructuredData *qnx_structure(RzBinFile *bf) {
rz_return_val_if_fail(bf && bf->o && bf->o->bin_obj, NULL);
QnxObj *bin = bf->o->bin_obj;
RzBin *rbin = bf->rbin;
rbin->cb_printf("QNX file header:\n");
rbin->cb_printf("version : 0x%xH\n", bin->lmfh.version);
rbin->cb_printf("cflags : 0x%xH\n", bin->lmfh.cflags);
rbin->cb_printf("cpu : 0x%xH\n", bin->lmfh.cpu);
rbin->cb_printf("fpu : 0x%xH\n", bin->lmfh.fpu);
rbin->cb_printf("code_index : 0x%xH\n", bin->lmfh.code_index);
rbin->cb_printf("stack_index : 0x%xH\n", bin->lmfh.stack_index);
rbin->cb_printf("heap_index : 0x%xH\n", bin->lmfh.heap_index);
rbin->cb_printf("argv_index : 0x%xH\n", bin->lmfh.argv_index);
rbin->cb_printf("spare2[4] : 0x0H\n");
rbin->cb_printf("code_offset : 0x%xH\n", bin->lmfh.code_offset);
rbin->cb_printf("stack_nbytes : 0x%xH\n", bin->lmfh.stack_nbytes);
rbin->cb_printf("heap_nbytes : 0x%xH\n", bin->lmfh.heap_nbytes);
rbin->cb_printf("image_base : 0x%xH\n", bin->lmfh.image_base);
rbin->cb_printf("spare3[2] : 0x0H\n");
RzStructuredData *info = rz_structured_data_new_map();
if (!info) {
return NULL;
}
RzStructuredData *qnx_lmf = rz_structured_data_map_add_map(info, "qnx_lmf");
if (!qnx_lmf) {
rz_structured_data_free(info);
return NULL;
}
rz_structured_data_map_add_unsigned(qnx_lmf, "version", bin->lmfh.version, false);
rz_structured_data_map_add_unsigned(qnx_lmf, "cflags", bin->lmfh.cflags, true);
rz_structured_data_map_add_unsigned(qnx_lmf, "cpu", bin->lmfh.cpu, false);
rz_structured_data_map_add_unsigned(qnx_lmf, "fpu", bin->lmfh.fpu, false);
rz_structured_data_map_add_unsigned(qnx_lmf, "code_index", bin->lmfh.code_index, false);
rz_structured_data_map_add_unsigned(qnx_lmf, "stack_index", bin->lmfh.stack_index, false);
rz_structured_data_map_add_unsigned(qnx_lmf, "heap_index", bin->lmfh.heap_index, false);
rz_structured_data_map_add_unsigned(qnx_lmf, "argv_index", bin->lmfh.argv_index, false);
RzStructuredData *spare2 = rz_structured_data_map_add_array(qnx_lmf, "spare2");
if (!spare2) {
rz_structured_data_free(info);
return NULL;
}
for (size_t i = 0; i < RZ_ARRAY_SIZE(bin->lmfh.spare2); ++i) {
rz_structured_data_array_add_unsigned(spare2, bin->lmfh.spare2[i], true);
}
rz_structured_data_map_add_unsigned(qnx_lmf, "code_offset", bin->lmfh.code_offset, true);
rz_structured_data_map_add_unsigned(qnx_lmf, "stack_nbytes", bin->lmfh.stack_nbytes, true);
rz_structured_data_map_add_unsigned(qnx_lmf, "heap_nbytes", bin->lmfh.heap_nbytes, true);
rz_structured_data_map_add_unsigned(qnx_lmf, "image_base", bin->lmfh.image_base, true);
RzStructuredData *spare3 = rz_structured_data_map_add_array(qnx_lmf, "spare3");
if (!spare3) {
rz_structured_data_free(info);
return NULL;
}
for (size_t i = 0; i < RZ_ARRAY_SIZE(bin->lmfh.spare3); ++i) {
rz_structured_data_array_add_unsigned(spare3, bin->lmfh.spare3[i], true);
}
return info;
}
/*
* No mention of symbols in the doc
*/
static RzPVector /*<RzBinSymbol *>*/ *symbols(RzBinFile *bf) {
static RzPVector /*<RzBinSymbol *>*/ *qnx_symbols(RzBinFile *bf) {
return NULL;
}
static RzPVector /*<RzBinMap *>*/ *maps(RzBinFile *bf) {
static RzPVector /*<RzBinMap *>*/ *qnx_maps(RzBinFile *bf) {
rz_return_val_if_fail(bf && bf->o, NULL);
QnxObj *qo = bf->o->bin_obj;
return rz_pvector_clone(qo->maps);
}
// Returns the sections
static RzPVector /*<RzBinSection *>*/ *sections(RzBinFile *bf) {
static RzPVector /*<RzBinSection *>*/ *qnx_sections(RzBinFile *bf) {
rz_return_val_if_fail(bf && bf->o, NULL);
QnxObj *qo = bf->o->bin_obj;
return rz_pvector_clone(qo->sections);
@ -313,7 +345,7 @@ static RzPVector /*<RzBinSection *>*/ *sections(RzBinFile *bf) {
* @param RzBinFile
* @return sdb of the bin_obj
*/
static Sdb *get_sdb(RzBinFile *bf) {
static Sdb *qnx_get_sdb(RzBinFile *bf) {
RzBinObject *o = bf->o;
if (!o) {
return NULL;
@ -327,7 +359,7 @@ static Sdb *get_sdb(RzBinFile *bf) {
* @param RzBinFile
* @return image_base address
*/
static ut64 baddr(RzBinFile *bf) {
static ut64 qnx_baddr(RzBinFile *bf) {
QnxObj *qo = bf->o->bin_obj;
return qo ? qo->lmfh.image_base : 0;
}
@ -336,7 +368,7 @@ static ut64 baddr(RzBinFile *bf) {
* Currently both physical and virtual address are set to 0
* The memory map has different values for entry
*/
static RzPVector /*<RzBinAddr *>*/ *entries(RzBinFile *bf) {
static RzPVector /*<RzBinAddr *>*/ *qnx_entries(RzBinFile *bf) {
RzPVector *ret;
RzBinAddr *ptr = NULL;
QnxObj *qo = bf->o->bin_obj;
@ -347,7 +379,7 @@ static RzPVector /*<RzBinAddr *>*/ *entries(RzBinFile *bf) {
return ret;
}
ptr->paddr = qo->lmfh.code_offset;
ptr->vaddr = qo->lmfh.code_offset + baddr(bf);
ptr->vaddr = qo->lmfh.code_offset + qnx_baddr(bf);
rz_pvector_push(ret, ptr);
return ret;
}
@ -356,7 +388,7 @@ static RzPVector /*<RzBinAddr *>*/ *entries(RzBinFile *bf) {
* @param RzBinFile
* @return signature of the binary
*/
static char *signature(RzBinFile *bf, bool json) {
static char *qnx_signature(RzBinFile *bf, bool json) {
char buf[64];
QnxObj *qo = bf->o->bin_obj;
if (!qo) {
@ -374,7 +406,7 @@ static char *signature(RzBinFile *bf, bool json) {
/*
* @return: returns the vaddr
*/
static ut64 get_vaddr(RzBinFile *bf, ut64 baddr, ut64 paddr, ut64 vaddr) {
static ut64 qnx_get_vaddr(RzBinFile *bf, ut64 baddr, ut64 paddr, ut64 vaddr) {
return vaddr;
}
@ -383,21 +415,21 @@ RzBinPlugin rz_bin_plugin_qnx = {
.name = "qnx",
.desc = "QNX executable",
.license = "LGPL3",
.load_buffer = &load_buffer,
.destroy = &destroy,
.relocs = &relocs,
.baddr = &baddr,
.load_buffer = &qnx_load_buffer,
.destroy = &qnx_destroy,
.relocs = &qnx_relocs,
.baddr = &qnx_baddr,
.author = "deepakchethan",
.check_buffer = &check_buffer,
.header = &header,
.get_sdb = &get_sdb,
.entries = &entries,
.maps = &maps,
.sections = &sections,
.symbols = &symbols,
.signature = &signature,
.get_vaddr = &get_vaddr,
.info = &info
.check_buffer = &qnx_check_buffer,
.bin_structure = &qnx_structure,
.get_sdb = &qnx_get_sdb,
.entries = &qnx_entries,
.maps = &qnx_maps,
.sections = &qnx_sections,
.symbols = &qnx_symbols,
.signature = &qnx_signature,
.get_vaddr = &qnx_get_vaddr,
.info = &qnx_info
};
#ifndef RZ_PLUGIN_INCORE

View file

@ -295,30 +295,54 @@ static void sms_destroy(RzBinFile *bf) {
sms_info_free(bf->o->bin_obj);
}
static void sms_header(RzBinFile *bf) {
RzBin *rbin = bf->rbin;
static RzStructuredData *sms_structure(RzBinFile *bf) {
rz_return_val_if_fail(bf && bf->o && bf->o->bin_obj, NULL);
char tmp[256] = { 0 };
SMSInfo *sms = bf->o->bin_obj;
rbin->cb_printf("ROM Offset: 0x%08" PFMT64x "\n", sms->rom.offset);
rbin->cb_printf("ROM Reserved0: %u (0x%02x)\n", (ut32)sms->rom.reserved[0], (ut32)sms->rom.reserved[0]);
rbin->cb_printf("ROM Reserved1: %u (0x%02x)\n", (ut32)sms->rom.reserved[1], (ut32)sms->rom.reserved[1]);
rbin->cb_printf("ROM Checksum: 0x%04x\n", sms->rom.checksum);
rbin->cb_printf("ROM Product Code: %06u\n", sms->rom.product_code);
rbin->cb_printf("ROM Version: %u\n", sms->rom.version);
rbin->cb_printf("ROM Console: %s\n", rz_str_get(sms->rom.system));
rbin->cb_printf("ROM Region: %s\n", rz_str_get(sms->rom.region));
rbin->cb_printf("ROM Size: %dKB\n", sms->rom.size_kb);
if (sms->sdsc.offset == UT64_MAX) {
return;
RzStructuredData *info = rz_structured_data_new_map();
if (!info) {
return NULL;
}
rbin->cb_printf("SDSC Offset: 0x%08" PFMT64x "\n", sms->sdsc.offset);
rbin->cb_printf("SDSC Version: %02u.%02u\n", sms->sdsc.version.major, sms->sdsc.version.minor);
rbin->cb_printf("SDSC Date: %04u-%02u-%02u\n", sms->sdsc.date.year, sms->sdsc.date.month, sms->sdsc.date.day);
rbin->cb_printf("SDSC Author: %s\n", rz_str_get(sms->sdsc.author));
rbin->cb_printf("SDSC Name: %s\n", rz_str_get(sms->sdsc.name));
rbin->cb_printf("SDSC Description: %s\n", rz_str_get(sms->sdsc.description));
RzStructuredData *rom = rz_structured_data_map_add_map(info, "sms_rom");
if (!rom) {
rz_structured_data_free(info);
return NULL;
}
rz_structured_data_map_add_unsigned(rom, "offset", sms->rom.offset, true);
rz_structured_data_map_add_unsigned(rom, "reserved0", sms->rom.reserved[0], false);
rz_structured_data_map_add_unsigned(rom, "reserved1", sms->rom.reserved[1], false);
rz_structured_data_map_add_unsigned(rom, "checksum", sms->rom.checksum, true);
rz_strf(tmp, "%06u", sms->rom.product_code);
rz_structured_data_map_add_string(rom, "product_code", tmp);
rz_structured_data_map_add_unsigned(rom, "version", sms->rom.version, false);
rz_structured_data_map_add_string(rom, "console", rz_str_get(sms->rom.system));
rz_structured_data_map_add_string(rom, "region", rz_str_get(sms->rom.region));
rz_structured_data_map_add_unsigned(rom, "size_kb", sms->rom.size_kb, false);
if (sms->sdsc.offset == UT64_MAX) {
return info;
}
RzStructuredData *sdsc = rz_structured_data_map_add_map(rom, "sdsc");
if (!sdsc) {
rz_structured_data_free(info);
return NULL;
}
rz_structured_data_map_add_unsigned(sdsc, "offset", sms->sdsc.offset, true);
rz_strf(tmp, "%02u.%02u\n", sms->sdsc.version.major, sms->sdsc.version.minor);
rz_structured_data_map_add_string(sdsc, "version", tmp);
rz_strf(tmp, "%04u-%02u-%02u\n", sms->sdsc.date.year, sms->sdsc.date.month, sms->sdsc.date.day);
rz_structured_data_map_add_string(sdsc, "date", tmp);
rz_structured_data_map_add_string(sdsc, "author", rz_str_get(sms->sdsc.author));
rz_structured_data_map_add_string(sdsc, "name", rz_str_get(sms->sdsc.name));
rz_structured_data_map_add_string(sdsc, "description", rz_str_get(sms->sdsc.description));
return info;
}
static RzBinInfo *sms_info(RzBinFile *bf) {
@ -355,7 +379,7 @@ RzBinPlugin rz_bin_plugin_sms = {
.load_buffer = &sms_load_buffer,
.check_buffer = &sms_check_buffer,
.destroy = &sms_destroy,
.header = &sms_header,
.bin_structure = &sms_structure,
.info = &sms_info,
.strings = &sms_strings,
.strfilter = 'U'

View file

@ -256,7 +256,7 @@ static RzCoreSymCacheElement *parseDragons(RzBinFile *bf, RzBuffer *buf, int off
return rz_coresym_cache_element_new(bf, buf, off + 16, bits, file_name);
}
static bool load_buffer(RzBinFile *bf, RzBinObject *obj, RzBuffer *buf, Sdb *sdb) {
static bool coresyms_load_buffer(RzBinFile *bf, RzBinObject *obj, RzBuffer *buf, Sdb *sdb) {
// SYMBOLS HEADER
//
// 0 MAGIC 02ff01ff
@ -297,7 +297,7 @@ static bool load_buffer(RzBinFile *bf, RzBinObject *obj, RzBuffer *buf, Sdb *sdb
return obj->bin_obj != NULL;
}
static RzPVector /*<RzBinSection *>*/ *sections(RzBinFile *bf) {
static RzPVector /*<RzBinSection *>*/ *coresyms_sections(RzBinFile *bf) {
RzPVector *res = rz_pvector_new((RzPVectorFree)rz_bin_section_free);
rz_return_val_if_fail(res && bf->o && bf->o->bin_obj, res);
RzCoreSymCacheElement *element = bf->o->bin_obj;
@ -319,11 +319,11 @@ static RzPVector /*<RzBinSection *>*/ *sections(RzBinFile *bf) {
return res;
}
static ut64 baddr(RzBinFile *bf) {
static ut64 coresyms_baddr(RzBinFile *bf) {
return 0LL;
}
static RzBinInfo *info(RzBinFile *bf) {
static RzBinInfo *coresyms_info(RzBinFile *bf) {
SymbolsMetadata sm = { 0 };
if (!parseMetadata(bf->buf, 0x40, &sm)) {
return NULL;
@ -344,13 +344,13 @@ static RzBinInfo *info(RzBinFile *bf) {
return ret;
}
static bool check_buffer(RzBuffer *b) {
static bool coresyms_check_buffer(RzBuffer *b) {
ut8 buf[4];
rz_buf_read_at(b, 0, buf, sizeof(buf));
return !memcmp(buf, "\x02\xff\x01\xff", 4);
}
static RzPVector /*<RzBinSymbol *>*/ *symbols(RzBinFile *bf) {
static RzPVector /*<RzBinSymbol *>*/ *coresyms_symbols(RzBinFile *bf) {
RzPVector *res = rz_pvector_new((RzPVectorFree)rz_bin_symbol_free);
rz_return_val_if_fail(res && bf->o && bf->o->bin_obj, res);
RzCoreSymCacheElement *element = bf->o->bin_obj;
@ -387,53 +387,57 @@ static RzPVector /*<RzBinSymbol *>*/ *symbols(RzBinFile *bf) {
return res;
}
static ut64 size(RzBinFile *bf) {
static ut64 coresyms_size(RzBinFile *bf) {
return UT64_MAX;
}
static void destroy(RzBinFile *bf) {
static void coresyms_destroy(RzBinFile *bf) {
rz_coresym_cache_element_free(bf->o->bin_obj);
}
static void header(RzBinFile *bf) {
rz_return_if_fail(bf && bf->o);
static RzStructuredData *coresyms_structure(RzBinFile *bf) {
rz_return_val_if_fail(bf && bf->o && bf->o->bin_obj, NULL);
char uuidstr[RZ_UUID_LENGTH] = { 0 };
RzCoreSymCacheElement *element = bf->o->bin_obj;
if (!element) {
return;
return NULL;
}
RzBin *bin = bf->rbin;
PrintfCallback p = bin->cb_printf;
PJ *pj = pj_new();
if (!pj) {
return;
RzStructuredData *info = rz_structured_data_new_map();
if (!info) {
return NULL;
}
pj_o(pj);
pj_kn(pj, "cs_version", element->hdr->version);
pj_kn(pj, "size", element->hdr->size);
if (element->file_name) {
pj_ks(pj, "name", element->file_name);
RzStructuredData *csyms = rz_structured_data_map_add_map(info, "symbols");
if (!csyms) {
rz_structured_data_free(info);
return NULL;
}
if (element->binary_version) {
pj_ks(pj, "version", element->binary_version);
}
char uuidstr[RZ_UUID_LENGTH];
rz_hex_bin2str(element->hdr->uuid, 16, uuidstr);
pj_ks(pj, "uuid", uuidstr);
pj_kn(pj, "segments", element->hdr->n_segments);
pj_kn(pj, "sections", element->hdr->n_sections);
pj_kn(pj, "symbols", element->hdr->n_symbols);
pj_kn(pj, "lined_symbols", element->hdr->n_lined_symbols);
pj_kn(pj, "line_info", element->hdr->n_line_info);
pj_end(pj);
p("%s\n", pj_string(pj));
pj_free(pj);
rz_structured_data_map_add_unsigned(csyms, "cs_version", element->hdr->version, false);
rz_structured_data_map_add_unsigned(csyms, "size", element->hdr->size, false);
RzStructuredData *binary = rz_structured_data_map_add_map(csyms, "binary");
if (!binary) {
rz_structured_data_free(info);
return NULL;
}
rz_structured_data_map_add_string(binary, "name", rz_str_get(element->file_name));
rz_structured_data_map_add_string(binary, "version", rz_str_get(element->binary_version));
rz_hex_bin2str(element->hdr->uuid, sizeof(element->hdr->uuid), uuidstr);
rz_structured_data_map_add_string(csyms, "uuid", uuidstr);
rz_structured_data_map_add_unsigned(csyms, "n_segments", element->hdr->n_segments, false);
rz_structured_data_map_add_unsigned(csyms, "n_sections", element->hdr->n_sections, false);
rz_structured_data_map_add_unsigned(csyms, "n_symbols", element->hdr->n_symbols, false);
rz_structured_data_map_add_unsigned(csyms, "n_lined_symbols", element->hdr->n_lined_symbols, false);
rz_structured_data_map_add_unsigned(csyms, "n_line_info", element->hdr->n_line_info, false);
return info;
}
static RzBinSourceLineInfo *lines(RzBinFile *bf) {
static RzBinSourceLineInfo *coresyms_lines(RzBinFile *bf) {
rz_return_val_if_fail(bf && bf->o, NULL);
RzCoreSymCacheElement *element = bf->o->bin_obj;
if (!element || !element->hdr) {
@ -467,17 +471,17 @@ RzBinPlugin rz_bin_plugin_symbols = {
.desc = "Apple Symbols file",
.license = "MIT",
.author = "pancake",
.load_buffer = &load_buffer,
.check_buffer = &check_buffer,
.symbols = &symbols,
.load_buffer = &coresyms_load_buffer,
.check_buffer = &coresyms_check_buffer,
.symbols = &coresyms_symbols,
.maps = &rz_bin_maps_of_file_sections,
.sections = &sections,
.size = &size,
.baddr = &baddr,
.info = &info,
.header = &header,
.destroy = &destroy,
.lines = lines
.sections = &coresyms_sections,
.size = &coresyms_size,
.baddr = &coresyms_baddr,
.info = &coresyms_info,
.bin_structure = &coresyms_structure,
.destroy = &coresyms_destroy,
.lines = coresyms_lines
};
#ifndef RZ_PLUGIN_INCORE

View file

@ -4270,14 +4270,34 @@ RZ_API bool rz_core_bin_fields_print(RZ_NONNULL RzCore *core, RZ_NONNULL RzBinFi
return true;
}
RZ_API bool rz_core_bin_headers_print(RZ_NONNULL RzCore *core, RZ_NONNULL RzBinFile *bf) {
rz_return_val_if_fail(core, false);
RZ_API bool rz_core_bin_structured_data_print(RZ_NONNULL RzCore *core, RZ_NONNULL RzBinFile *bf, RzOutputMode mode) {
rz_return_val_if_fail(core && bf, false);
RzBinFile *cur = rz_bin_cur(core->bin);
RzBinPlugin *plg = rz_bin_file_cur_plugin(cur);
if (plg && plg->header) {
plg->header(cur);
RzBinObject *obj = rz_bin_cur_object(core->bin);
const RzStructuredData *sf = obj ? rz_bin_object_get_structured_data(obj) : NULL;
if (!sf) {
if (mode == RZ_OUTPUT_MODE_JSON) {
rz_cons_print("{}\n");
}
return true;
}
char *output = NULL;
switch (mode) {
case RZ_OUTPUT_MODE_JSON:
output = rz_structured_data_to_json(sf);
break;
case RZ_OUTPUT_MODE_STANDARD:
output = rz_structured_data_to_yaml(sf);
break;
default:
rz_warn_if_reached();
break;
}
rz_cons_printf("%s\n", output);
free(output);
return true;
}

View file

@ -413,9 +413,9 @@ RZ_IPI RzCmdStatus rz_cmd_info_fields_handler(RzCore *core, int argc, const char
return bool2status(rz_core_bin_fields_print(core, bf, state));
}
RZ_IPI RzCmdStatus rz_cmd_info_headers_handler(RzCore *core, int argc, const char **argv) {
RZ_IPI RzCmdStatus rz_cmd_info_structured_data_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode) {
GET_CHECK_CUR_BINFILE(core);
return bool2status(rz_core_bin_headers_print(core, bf));
return bool2status(rz_core_bin_structured_data_print(core, bf, mode));
}
RZ_IPI RzCmdStatus rz_cmd_info_binary_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) {

View file

@ -12948,12 +12948,12 @@ static const RzCmdDescHelp cmd_info_fields_help = {
.args = cmd_info_fields_args,
};
static const RzCmdDescArg cmd_info_headers_args[] = {
static const RzCmdDescArg cmd_info_structured_data_args[] = {
{ 0 },
};
static const RzCmdDescHelp cmd_info_headers_help = {
.summary = "Show binary headers",
.args = cmd_info_headers_args,
static const RzCmdDescHelp cmd_info_structured_data_help = {
.summary = "Show binary structured data",
.args = cmd_info_structured_data_args,
};
static const RzCmdDescArg cmd_info_imports_args[] = {
@ -23491,8 +23491,8 @@ RZ_IPI void rzshell_cmddescs_init(RzCore *core) {
rz_warn_if_fail(cmd_info_fields_cd);
rz_cmd_desc_set_default_mode(cmd_info_fields_cd, RZ_OUTPUT_MODE_TABLE);
RzCmdDesc *cmd_info_headers_cd = rz_cmd_desc_argv_new(core->rcmd, i_cd, "iH", rz_cmd_info_headers_handler, &cmd_info_headers_help);
rz_warn_if_fail(cmd_info_headers_cd);
RzCmdDesc *cmd_info_structured_data_cd = rz_cmd_desc_argv_modes_new(core->rcmd, i_cd, "iH", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_JSON, rz_cmd_info_structured_data_handler, &cmd_info_structured_data_help);
rz_warn_if_fail(cmd_info_structured_data_cd);
RzCmdDesc *cmd_info_imports_cd = rz_cmd_desc_argv_state_new(core->rcmd, i_cd, "ii", RZ_OUTPUT_MODE_TABLE | RZ_OUTPUT_MODE_JSON | RZ_OUTPUT_MODE_QUIET, rz_cmd_info_imports_handler, &cmd_info_imports_help);
rz_warn_if_fail(cmd_info_imports_cd);

View file

@ -1683,7 +1683,7 @@ RZ_IPI RzCmdStatus rz_cmd_info_cur_export_handler(RzCore *core, int argc, const
// "ih"
RZ_IPI RzCmdStatus rz_cmd_info_fields_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state);
// "iH"
RZ_IPI RzCmdStatus rz_cmd_info_headers_handler(RzCore *core, int argc, const char **argv);
RZ_IPI RzCmdStatus rz_cmd_info_structured_data_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode);
// "ii"
RZ_IPI RzCmdStatus rz_cmd_info_imports_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state);
// "iI"

View file

@ -220,8 +220,12 @@ commands:
- RZ_OUTPUT_MODE_QUIET
args: []
- name: iH
cname: cmd_info_headers
summary: Show binary headers
cname: cmd_info_structured_data
summary: Show binary structured data
type: RZ_CMD_DESC_TYPE_ARGV_MODES
modes:
- RZ_OUTPUT_MODE_STANDARD
- RZ_OUTPUT_MODE_JSON
args: []
- name: ii
cname: cmd_info_imports

View file

@ -24,6 +24,7 @@ include_files = [
'rz_flag.h',
'rz_flirt.h',
'rz_getopt.h',
'rz_hash.h',
'rz_heap_glibc.h',
'rz_heap_jemalloc.h',
'rz_il.h',
@ -33,12 +34,12 @@ include_files = [
'rz_list.h',
'rz_magic.h',
'rz_main.h',
'rz_hash.h',
'rz_parse.h',
'rz_pdb.h',
'rz_platform.h',
'rz_project.h',
'rz_reg.h',
'rz_rop.h',
'rz_search.h',
'rz_sign.h',
'rz_skiplist.h',
@ -54,7 +55,6 @@ include_files = [
'rz_vector.h',
'rz_windows.h',
'rz_windows_heap.h',
'rz_rop.h',
]
install_headers(include_files, install_dir: rizin_incdir)
@ -84,6 +84,7 @@ rz_util_files = [
'rz_util/rz_hex.h',
'rz_util/rz_idpool.h',
'rz_util/rz_intervaltree.h',
'rz_util/rz_iterator.h',
'rz_util/rz_itv.h',
'rz_util/rz_json.h',
'rz_util/rz_lang_byte_array.h',
@ -102,8 +103,8 @@ rz_util_files = [
'rz_util/rz_range.h',
'rz_util/rz_rbtree.h',
'rz_util/rz_regex.h',
'rz_util/rz_iterator.h',
'rz_util/rz_serialize.h',
'rz_util/rz_set.h',
'rz_util/rz_signal.h',
'rz_util/rz_spaces.h',
'rz_util/rz_stack.h',
@ -113,6 +114,7 @@ rz_util_files = [
'rz_util/rz_str_util.h',
'rz_util/rz_strbuf.h',
'rz_util/rz_strpool.h',
'rz_util/rz_structured_data.h',
'rz_util/rz_subprocess.h',
'rz_util/rz_sys.h',
'rz_util/rz_table.h',
@ -134,7 +136,6 @@ rz_util_files = [
'rz_util/ht_sp.h',
'rz_util/ht_ss.h',
'rz_util/ht_su.h',
'rz_util/rz_set.h',
]
install_headers(rz_util_files, install_dir: join_paths(rizin_incdir, 'rz_util'))

View file

@ -338,6 +338,7 @@ typedef struct rz_bin_object_t {
RzPVector /*<RzBinMem *>*/ *mem;
char *regstate;
RzBinInfo *info;
RzStructuredData *structured_data;
RzBinAddr *binsym[RZ_BIN_SPECIAL_SYMBOL_LAST];
struct rz_bin_plugin_t *plugin;
RzBinLanguage lang;
@ -505,6 +506,7 @@ typedef struct rz_bin_plugin_t {
RzPVector /*<RzBinImport *>*/ *(*imports)(RzBinFile *bf);
RzPVector /*<RzBinString *>*/ *(*strings)(RzBinFile *bf);
RzBinInfo *(*info)(RzBinFile *bf);
RzStructuredData *(*bin_structure)(RzBinFile *bf);
RzPVector /*<RzBinField *>*/ *(*fields)(RzBinFile *bf);
RzPVector /*<char *>*/ *(*libs)(RzBinFile *bf);
RzPVector /*<RzBinReloc *>*/ *(*relocs)(RzBinFile *bf);
@ -514,7 +516,6 @@ typedef struct rz_bin_plugin_t {
RzPVector /*<RzBinReloc *>*/ *(*patch_relocs)(RzBinFile *bf);
RzPVector /*<RzBinFileHash *>*/ *(*hashes)(RzBinFile *bf);
RzPVector /*<RzBinResource *>*/ *(*resources)(RzBinFile *bf);
void (*header)(RzBinFile *bf);
char *(*signature)(RzBinFile *bf, bool json);
int (*demangle_type)(const char *str);
char *(*enrich_asm)(RzBinFile *bf, const char *asm_str, int asm_len);
@ -967,6 +968,7 @@ RZ_API RZ_BORROW const RzPVector /*<RzBinAddr *>*/ *rz_bin_object_get_entries(RZ
RZ_API const RzPVector /*<RzBinField *>*/ *rz_bin_object_get_fields(RZ_NONNULL RzBinObject *obj);
RZ_API const RzPVector /*<RzBinImport *>*/ *rz_bin_object_get_imports(RZ_NONNULL RzBinObject *obj);
RZ_API const RzBinInfo *rz_bin_object_get_info(RZ_NONNULL RzBinObject *obj);
RZ_API const RzStructuredData *rz_bin_object_get_structured_data(RZ_BORROW RZ_NONNULL RzBinObject *obj);
RZ_API const RzPVector /*<char *>*/ *rz_bin_object_get_libs(RZ_NONNULL RzBinObject *obj);
RZ_API const RzPVector /*<RzBinSection *>*/ *rz_bin_object_get_sections_all(RZ_NONNULL RzBinObject *obj);
RZ_API RZ_OWN RzPVector /*<RzBinSection *>*/ *rz_bin_object_get_sections(RZ_NONNULL RzBinObject *obj);

View file

@ -1032,7 +1032,7 @@ RZ_API bool rz_core_bin_class_fields_print(RZ_NONNULL RzCore *core, RZ_NONNULL R
RZ_API bool rz_core_bin_class_methods_print(RZ_NONNULL RzCore *core, RZ_NONNULL RzBinFile *bf, RZ_NONNULL RzCmdStateOutput *state, const char *class_name);
RZ_API bool rz_core_bin_signatures_print(RZ_NONNULL RzCore *core, RZ_NONNULL RzBinFile *bf, RZ_NONNULL RzCmdStateOutput *state);
RZ_API bool rz_core_bin_fields_print(RZ_NONNULL RzCore *core, RZ_NONNULL RzBinFile *bf, RZ_NONNULL RzCmdStateOutput *state);
RZ_API bool rz_core_bin_headers_print(RZ_NONNULL RzCore *core, RZ_NONNULL RzBinFile *bf);
RZ_API bool rz_core_bin_structured_data_print(RZ_NONNULL RzCore *core, RZ_NONNULL RzBinFile *bf, RzOutputMode mode);
RZ_API bool rz_core_bin_dwarf_print(RZ_NONNULL RzCore *core, RZ_NONNULL RzBinFile *bf, RZ_NONNULL RzCmdStateOutput *state);
RZ_API bool rz_core_bin_memory_print(RZ_NONNULL RzCore *core, RZ_NONNULL RzBinFile *bf, RZ_NONNULL RzCmdStateOutput *state);
RZ_API bool rz_core_bin_resources_print(RZ_NONNULL RzCore *core, RZ_NONNULL RzBinFile *bf, RZ_NONNULL RzCmdStateOutput *state, RZ_NULLABLE RzList /*<char *>*/ *hashes);

View file

@ -20,68 +20,67 @@
#if HAVE_LIB_SSL
#include <openssl/bn.h>
#endif
#include "rz_util/rz_axml.h"
#include "rz_util/rz_event.h"
#include "rz_util/rz_assert.h"
#include "rz_util/rz_itv.h"
#include "rz_util/rz_signal.h"
#include "rz_util/rz_alloc.h"
#include "rz_util/rz_rbtree.h"
#include "rz_util/rz_intervaltree.h"
#include "rz_util/rz_big.h"
#include "rz_util/rz_ascii_table.h"
#include "rz_util/rz_asn1.h"
#include "rz_util/rz_assert.h"
#include "rz_util/rz_axml.h"
#include "rz_util/rz_base16.h"
#include "rz_util/rz_base32.h"
#include "rz_util/rz_base36.h"
#include "rz_util/rz_base64.h"
#include "rz_util/rz_base85.h"
#include "rz_util/rz_base91.h"
#include "rz_util/rz_buf.h"
#include "rz_util/rz_big.h"
#include "rz_util/rz_bits.h"
#include "rz_util/rz_bitvector.h"
#include "rz_util/rz_time.h"
#include "rz_util/rz_buf.h"
#include "rz_util/rz_debruijn.h"
#include "rz_util/rz_event.h"
#include "rz_util/rz_file.h"
#include "rz_util/rz_float.h"
#include "rz_util/rz_graph.h"
#include "rz_util/rz_hex.h"
#include "rz_util/rz_idpool.h"
#include "rz_util/rz_intervaltree.h"
#include "rz_util/rz_iterator.h"
#include "rz_util/rz_itv.h"
#include "rz_util/rz_lang_byte_array.h"
#include "rz_util/rz_log.h"
#include "rz_util/rz_luhn.h"
#include "rz_util/rz_mem.h"
#include "rz_util/rz_name.h"
#include "rz_util/rz_num.h"
#include "rz_util/rz_table.h"
#include "rz_util/rz_graph.h"
#include "rz_util/rz_path.h"
#include "rz_util/rz_panels.h"
#include "rz_util/rz_path.h"
#include "rz_util/rz_pj.h"
#include "rz_util/rz_pkcs7.h"
#include "rz_util/rz_protobuf.h"
#include "rz_util/rz_punycode.h"
#include "rz_util/rz_range.h"
#include "rz_util/rz_rbtree.h"
#include "rz_util/rz_regex.h"
#include "rz_util/rz_signal.h"
#include "rz_util/rz_spaces.h"
#include "rz_util/rz_stack.h"
#include "rz_util/rz_str.h"
#include "rz_util/rz_ascii_table.h"
#include "rz_util/rz_strbuf.h"
#include "rz_util/rz_str_search.h"
#include "rz_util/rz_strpool.h"
#include "rz_util/rz_str_constpool.h"
#include "rz_util/rz_str_search.h"
#include "rz_util/rz_strbuf.h"
#include "rz_util/rz_strpool.h"
#include "rz_util/rz_structured_data.h"
#include "rz_util/rz_subprocess.h"
#include "rz_util/rz_sys.h"
#include "rz_util/rz_table.h"
#include "rz_util/rz_time.h"
#include "rz_util/rz_tree.h"
#include "rz_util/rz_uleb128.h"
#include "rz_util/rz_unicode.h"
#include "rz_util/rz_utf8.h"
#include "rz_util/rz_utf16.h"
#include "rz_util/rz_utf32.h"
#include "rz_util/rz_idpool.h"
#include "rz_util/rz_asn1.h"
#include "rz_util/rz_pj.h"
#include "rz_util/rz_x509.h"
#include "rz_util/rz_pkcs7.h"
#include "rz_util/rz_protobuf.h"
#include "rz_util/rz_big.h"
#include "rz_util/rz_subprocess.h"
#include "rz_util/rz_luhn.h"
#include "rz_util/rz_utf8.h"
#include "rz_util/rz_version.h"
#include "rz_util/rz_lang_byte_array.h"
#include "rz_util/rz_iterator.h"
#include "rz_util/rz_x509.h"
// requires io, core, ... #include "rz_util/rz_print.h"
#ifdef __cplusplus

View file

@ -75,7 +75,7 @@ typedef int (*RzStrRangeCallback)(void *, int);
RZ_API const char *rz_str_enc_as_string(RzStrEnc enc);
RZ_API RzStrEnc rz_str_enc_string_as_type(RZ_NULLABLE const char *enc);
RZ_API RZ_OWN char *rz_str_repeat(const char *str, ut16 times);
RZ_API RZ_OWN char *rz_str_pad(const char ch, int len);
RZ_API RZ_OWN char *rz_str_pad(const char ch, ssize_t len);
RZ_API const char *rz_str_rstr(const char *base, const char *p);
RZ_API const char *rz_strstr_ansi(RZ_NONNULL const char *a, RZ_NONNULL const char *b, bool icase);
RZ_API const char *rz_str_rchr(const char *base, const char *p, int ch);

View file

@ -0,0 +1,72 @@
// SPDX-FileCopyrightText: 2025 deroad <deroad@kumo.xn--q9jyb4c>
// SPDX-License-Identifier: LGPL-3.0-only
#ifndef RZ_STRUCTURED_DATA_H
#define RZ_STRUCTURED_DATA_H
#include <rz_util/rz_strbuf.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef enum rz_structured_data_block_t {
RZ_STRUCTURED_DATA_BLOCK_MAP = 0,
RZ_STRUCTURED_DATA_BLOCK_ARRAY = 1,
} RzStructuredDataBlock;
typedef struct rz_structured_data_t RzStructuredData;
typedef void (*RzStructuredDataIteratorNew)(RZ_NULLABLE void *user, RzStructuredDataBlock block);
typedef void (*RzStructuredDataIteratorEnd)(RZ_NULLABLE void *user);
typedef void (*RzStructuredDataIteratorKey)(RZ_NULLABLE void *user, RZ_NONNULL const char *key);
typedef void (*RzStructuredDataIteratorValueUnsigned)(RZ_NULLABLE void *user, ut64 n, bool hex);
typedef void (*RzStructuredDataIteratorValueSigned)(RZ_NULLABLE void *user, st64 n);
typedef void (*RzStructuredDataIteratorValueDouble)(RZ_NULLABLE void *user, double d);
typedef void (*RzStructuredDataIteratorValueBool)(RZ_NULLABLE void *user, bool b);
typedef void (*RzStructuredDataIteratorValueString)(RZ_NULLABLE void *user, RZ_NONNULL const char *v);
typedef struct rz_structured_data_iterator_t {
RzStructuredDataIteratorNew new_struct; ///< Creates a new structure
RzStructuredDataIteratorEnd end_struct; ///< Ends the current structure
RzStructuredDataIteratorKey key; ///< Defines a key, called before a enter() or value_*()
RzStructuredDataIteratorValueUnsigned val_unsigned; ///< Inserts a value of numeric unsigned type
RzStructuredDataIteratorValueSigned val_signed; ///< Inserts a value of numeric signed type
RzStructuredDataIteratorValueDouble val_double; ///< Inserts a value of numeric double type
RzStructuredDataIteratorValueBool val_bool; ///< Inserts a value of boolean type
RzStructuredDataIteratorValueString val_string; ///< Inserts a value of string type
} RzStructuredDataIterator;
RZ_API RZ_OWN RzStructuredData *rz_structured_data_new_map();
RZ_API RZ_OWN RzStructuredData *rz_structured_data_new_array();
RZ_API void rz_structured_data_free(RZ_NULLABLE RzStructuredData *sd);
/* primitive types for maps */
RZ_API RZ_BORROW RzStructuredData *rz_structured_data_map_add_map(RZ_NONNULL RzStructuredData *parent, RZ_NONNULL const char *key);
RZ_API RZ_BORROW RzStructuredData *rz_structured_data_map_add_array(RZ_NONNULL RzStructuredData *parent, RZ_NONNULL const char *key);
RZ_API bool rz_structured_data_map_add(RZ_NONNULL RzStructuredData *parent, RZ_NONNULL const char *key, RZ_NONNULL RZ_OWN RzStructuredData *child);
RZ_API bool rz_structured_data_map_add_unsigned(RZ_NONNULL RzStructuredData *parent, RZ_NONNULL const char *key, ut64 n, bool hex);
RZ_API bool rz_structured_data_map_add_signed(RZ_NONNULL RzStructuredData *parent, RZ_NONNULL const char *key, st64 n);
RZ_API bool rz_structured_data_map_add_double(RZ_NONNULL RzStructuredData *parent, RZ_NONNULL const char *key, double d);
RZ_API bool rz_structured_data_map_add_boolean(RZ_NONNULL RzStructuredData *parent, RZ_NONNULL const char *key, bool b);
RZ_API bool rz_structured_data_map_add_string(RZ_NONNULL RzStructuredData *parent, RZ_NONNULL const char *key, RZ_NONNULL const char *v);
/* primitive types for arrays */
RZ_API RZ_BORROW RzStructuredData *rz_structured_data_array_add_map(RZ_NONNULL RzStructuredData *parent);
RZ_API RZ_BORROW RzStructuredData *rz_structured_data_array_add_array(RZ_NONNULL RzStructuredData *parent);
RZ_API bool rz_structured_data_array_add(RZ_NONNULL RzStructuredData *parent, RZ_NONNULL RZ_OWN RzStructuredData *child);
RZ_API bool rz_structured_data_array_add_unsigned(RZ_NONNULL RzStructuredData *parent, ut64 n, bool hex);
RZ_API bool rz_structured_data_array_add_signed(RZ_NONNULL RzStructuredData *parent, st64 n);
RZ_API bool rz_structured_data_array_add_double(RZ_NONNULL RzStructuredData *parent, double d);
RZ_API bool rz_structured_data_array_add_boolean(RZ_NONNULL RzStructuredData *parent, bool b);
RZ_API bool rz_structured_data_array_add_string(RZ_NONNULL RzStructuredData *parent, RZ_NONNULL const char *v);
RZ_API void rz_structured_data_iterate(RZ_NONNULL const RzStructuredData *sd, RZ_NONNULL const RzStructuredDataIterator *iterator, RZ_NULLABLE void *user);
RZ_API RZ_OWN char *rz_structured_data_to_json(RZ_NONNULL const RzStructuredData *sd);
RZ_API RZ_OWN char *rz_structured_data_to_yaml(RZ_NONNULL const RzStructuredData *sd);
#ifdef __cplusplus
}
#endif
#endif /* RZ_STRUCTURED_DATA_H */

View file

@ -25,6 +25,7 @@ rz_util_common_sources = [
'hex.c',
'idpool.c',
'intervaltree.c',
'iterator.c',
'itv.c',
'json_indent.c',
'json_parser.c',
@ -44,8 +45,8 @@ rz_util_common_sources = [
'range.c',
'rbtree.c',
'regex.c',
'iterator.c',
'serialize_spaces.c',
'set.c',
'signal.c',
'skiplist.c',
'skyline.c',
@ -57,6 +58,7 @@ rz_util_common_sources = [
'str_trim.c',
'strbuf.c',
'strpool.c',
'structured_data.c',
'subprocess.c',
'sys.c',
'syscmd.c',
@ -79,11 +81,11 @@ rz_util_common_sources = [
'base85.c',
'base91.c',
'uleb128.c',
'unicode.c',
'unum.c',
'utf16.c',
'utf32.c',
'utf8.c',
'unicode.c',
'vector.c',
'version.c',
'w32-sys.c',
@ -95,7 +97,6 @@ rz_util_common_sources = [
'ht/ht_sp.c',
'ht/ht_ss.c',
'ht/ht_su.c',
'set.c',
]
rz_util_sources = rz_util_common_sources

View file

@ -3313,7 +3313,7 @@ RZ_API int rz_str_do_until_token(str_operation op, char *str, const char tok) {
return ret;
}
RZ_API RZ_OWN char *rz_str_pad(const char ch, int sz) {
RZ_API RZ_OWN char *rz_str_pad(const char ch, ssize_t sz) {
if (sz < 0) {
sz = 0;
}

View file

@ -0,0 +1,583 @@
// SPDX-FileCopyrightText: 2025 deroad <deroad@kumo.xn--q9jyb4c>
// SPDX-License-Identifier: LGPL-3.0-only
#include <rz_util.h>
/**
* \file structured_data.c
*
* Generates a structured data which can be converted
* in a human readable output (like json or yaml).
*
*/
#include "structured_data_json.c"
#include "structured_data_yaml.c"
typedef enum {
STRUCTURED_DATA_TYPE_MAP = 0,
STRUCTURED_DATA_TYPE_ARRAY,
STRUCTURED_DATA_TYPE_UNSIGNED,
STRUCTURED_DATA_TYPE_HEXADECIMAL,
STRUCTURED_DATA_TYPE_SIGNED,
STRUCTURED_DATA_TYPE_DOUBLE,
STRUCTURED_DATA_TYPE_BOOL,
STRUCTURED_DATA_TYPE_STRING,
} StructuredDataType;
struct rz_structured_data_t {
StructuredDataType type;
union {
ut64 v_unsigned;
st64 v_signed;
double v_double;
bool v_bool;
char *v_string;
HtSP /*<RzStructuredData *>*/ *v_map;
};
RzPVector /*<void *>*/ *v_array; // used also to keep the map keys in order
};
typedef struct structured_data_iter_over_t {
const RzStructuredDataIterator *fit;
void *user;
} StructuredDataIterOver;
/**
* \brief Free a RzStructuredData pointer
*
* \param sd The RzStructuredData to free.
*/
RZ_API void rz_structured_data_free(RZ_NULLABLE RzStructuredData *sd) {
if (!sd) {
return;
}
if (sd->type == STRUCTURED_DATA_TYPE_MAP) {
ht_sp_free(sd->v_map);
rz_pvector_free(sd->v_array);
} else if (sd->type == STRUCTURED_DATA_TYPE_ARRAY) {
rz_pvector_free(sd->v_array);
} else if (sd->type == STRUCTURED_DATA_TYPE_STRING) {
free(sd->v_string);
}
free(sd);
}
static RzStructuredData *structured_data_new_map() {
RzStructuredData *sd = RZ_NEW0(RzStructuredData);
if (!sd) {
return NULL;
}
sd->type = STRUCTURED_DATA_TYPE_MAP;
sd->v_map = ht_sp_new(HT_STR_DUP, NULL, (HtSPFreeValue)rz_structured_data_free);
sd->v_array = rz_pvector_new((RzPVectorFree)free);
if (!sd->v_map || !sd->v_array) {
rz_structured_data_free(sd);
return NULL;
}
return sd;
}
static RzStructuredData *structured_data_new_array() {
RzStructuredData *sd = RZ_NEW0(RzStructuredData);
if (!sd) {
return NULL;
}
sd->type = STRUCTURED_DATA_TYPE_ARRAY;
sd->v_array = rz_pvector_new((RzPVectorFree)rz_structured_data_free);
if (!sd->v_array) {
free(sd);
return NULL;
}
return sd;
}
static RzStructuredData *structured_data_new_unsigned(ut64 v_unsigned, bool hex) {
RzStructuredData *sd = RZ_NEW0(RzStructuredData);
if (!sd) {
return NULL;
}
sd->type = hex ? STRUCTURED_DATA_TYPE_HEXADECIMAL : STRUCTURED_DATA_TYPE_UNSIGNED;
sd->v_unsigned = v_unsigned;
return sd;
}
static RzStructuredData *structured_data_new_signed(st64 v_signed) {
RzStructuredData *sd = RZ_NEW0(RzStructuredData);
if (!sd) {
return NULL;
}
sd->type = STRUCTURED_DATA_TYPE_SIGNED;
sd->v_signed = v_signed;
return sd;
}
static RzStructuredData *structured_data_new_double(double v_double) {
RzStructuredData *sd = RZ_NEW0(RzStructuredData);
if (!sd) {
return NULL;
}
sd->type = STRUCTURED_DATA_TYPE_DOUBLE;
sd->v_double = v_double;
return sd;
}
static RzStructuredData *structured_data_new_bool(bool v_bool) {
RzStructuredData *sd = RZ_NEW0(RzStructuredData);
if (!sd) {
return NULL;
}
sd->type = STRUCTURED_DATA_TYPE_BOOL;
sd->v_bool = v_bool;
return sd;
}
static RzStructuredData *structured_data_new_string(char *v_string) {
RzStructuredData *sd = RZ_NEW0(RzStructuredData);
if (!sd) {
return NULL;
}
sd->type = STRUCTURED_DATA_TYPE_STRING;
sd->v_string = v_string;
return sd;
}
static bool structured_data_map_add(RZ_NONNULL RzStructuredData *parent, const char *key, RZ_NONNULL RZ_OWN RzStructuredData *child) {
RzPVector *pvec = parent->v_array;
HtSP *map = parent->v_map;
if (!map || !pvec || !child || RZ_STR_ISEMPTY(key)) {
rz_structured_data_free(child);
RZ_LOG_ERROR("struct_factory: invalid key: '%s'\n", key);
return false;
}
bool found = false;
ht_sp_find(map, key, &found);
if (found) {
rz_structured_data_free(child);
RZ_LOG_ERROR("struct_factory: found duplicated key: '%s'\n", key);
return false;
}
char *key_copy = rz_str_dup(key);
if (!key_copy || !ht_sp_insert(map, key_copy, child)) {
rz_structured_data_free(child);
free(key_copy);
RZ_LOG_ERROR("struct_factory: cannot add value with key: '%s'\n", key);
return false;
}
return rz_pvector_push(pvec, key_copy);
}
static bool structured_data_array_add(RZ_NONNULL RzStructuredData *parent, RZ_NONNULL RZ_OWN RzStructuredData *child) {
RzPVector *pvec = parent->v_array;
if (!pvec || !child) {
RZ_LOG_ERROR("struct_factory: invalid array value\n");
rz_structured_data_free(child);
return false;
}
rz_pvector_push(pvec, child);
return true;
}
/**
* \brief Creates a new RzStructuredData initialized as a map
*
* \return On success returns a valid opaque pointer to a RzStructuredData
*/
RZ_API RZ_OWN RzStructuredData *rz_structured_data_new_map() {
return structured_data_new_map();
}
/**
* \brief Creates a new RzStructuredData initialized as an array
*
* \return On success returns a valid opaque pointer to a RzStructuredData
*/
RZ_API RZ_OWN RzStructuredData *rz_structured_data_new_array() {
return structured_data_new_array();
}
/**
* \brief Returns a child, map type, RzStructuredData that has been added to the given parent
*
* \param parent Where to add the child RzStructuredData
* \param[in] key The key to assign the child RzStructuredData
*
* \return On success returns a valid pointer to the child RzStructuredData, otherwise NULL
*/
RZ_API RZ_BORROW RzStructuredData *rz_structured_data_map_add_map(RZ_NONNULL RzStructuredData *parent, RZ_NONNULL const char *key) {
rz_return_val_if_fail(parent && parent->type == STRUCTURED_DATA_TYPE_MAP && key, false);
RzStructuredData *child = structured_data_new_map();
if (!structured_data_map_add(parent, key, child)) {
return NULL;
}
return child;
}
/**
* \brief Returns a child, array type, RzStructuredData that has been added to the given parent
*
* \param parent Where to add the child RzStructuredData
* \param[in] key The key to assign the child RzStructuredData
*
* \return On success returns a valid pointer to the child RzStructuredData, otherwise NULL
*/
RZ_API RZ_BORROW RzStructuredData *rz_structured_data_map_add_array(RZ_NONNULL RzStructuredData *parent, RZ_NONNULL const char *key) {
rz_return_val_if_fail(parent && parent->type == STRUCTURED_DATA_TYPE_MAP && key, false);
RzStructuredData *child = structured_data_new_array();
if (!structured_data_map_add(parent, key, child)) {
return NULL;
}
return child;
}
/**
* \brief Adds an owned RzStructuredData child to a parent and assigns it a map key
*
* \param parent Where to add the child RzStructuredData
* \param[in] key The key to assign the child RzStructuredData
* \param child The child RzStructuredData
*
* \return On success returns true, otherwise the child gets deallocated by the function and return false.
*/
RZ_API bool rz_structured_data_map_add(RZ_NONNULL RzStructuredData *parent, RZ_NONNULL const char *key, RZ_NONNULL RZ_OWN RzStructuredData *child) {
rz_return_val_if_fail(parent && parent->type == STRUCTURED_DATA_TYPE_MAP && key && child, false);
return structured_data_map_add(parent, key, child);
}
/**
* \brief Adds unsigned type child to a parent and assigns it a map key
*
* \param parent Where to add the child RzStructuredData
* \param[in] key The key to assign the child RzStructuredData
* \param n The value to assign to the child
* \param hex When true the type is going to be set as base16 number instead of base10 unsigned number.
*
* \return On success returns true, otherwise false.
*/
RZ_API bool rz_structured_data_map_add_unsigned(RZ_NONNULL RzStructuredData *parent, RZ_NONNULL const char *key, ut64 n, bool hex) {
rz_return_val_if_fail(parent && parent->type == STRUCTURED_DATA_TYPE_MAP && key, false);
RzStructuredData *child = structured_data_new_unsigned(n, hex);
return structured_data_map_add(parent, key, child);
}
/**
* \brief Adds signed type child to a parent and assigns it a map key
*
* \param parent Where to add the child RzStructuredData
* \param[in] key The key to assign the child RzStructuredData
* \param n The value to assign to the child
*
* \return On success returns true, otherwise false.
*/
RZ_API bool rz_structured_data_map_add_signed(RZ_NONNULL RzStructuredData *parent, RZ_NONNULL const char *key, st64 n) {
rz_return_val_if_fail(parent && parent->type == STRUCTURED_DATA_TYPE_MAP && key, false);
RzStructuredData *child = structured_data_new_signed(n);
return structured_data_map_add(parent, key, child);
}
/**
* \brief Adds double type child to a parent and assigns it a map key
*
* \param parent Where to add the child RzStructuredData
* \param[in] key The key to assign the child RzStructuredData
* \param d The value to assign to the child
*
* \return On success returns true, otherwise false.
*/
RZ_API bool rz_structured_data_map_add_double(RZ_NONNULL RzStructuredData *parent, RZ_NONNULL const char *key, double d) {
rz_return_val_if_fail(parent && parent->type == STRUCTURED_DATA_TYPE_MAP && key, false);
RzStructuredData *child = structured_data_new_double(d);
return structured_data_map_add(parent, key, child);
}
/**
* \brief Adds boolean type child to a parent and assigns it a map key
*
* \param parent Where to add the child RzStructuredData
* \param[in] key The key to assign the child RzStructuredData
* \param b The value to assign to the child
*
* \return On success returns true, otherwise false.
*/
RZ_API bool rz_structured_data_map_add_boolean(RZ_NONNULL RzStructuredData *parent, RZ_NONNULL const char *key, bool b) {
rz_return_val_if_fail(parent && parent->type == STRUCTURED_DATA_TYPE_MAP && key, false);
RzStructuredData *child = structured_data_new_bool(b);
return structured_data_map_add(parent, key, child);
}
/**
* \brief Adds a null terminated string type child to a parent and assigns it a map key
*
* \param parent Where to add the child RzStructuredData
* \param[in] key The key to assign the child RzStructuredData
* \param s The value to assign to the child
*
* \return On success returns true, otherwise false.
*/
RZ_API bool rz_structured_data_map_add_string(RZ_NONNULL RzStructuredData *parent, RZ_NONNULL const char *key, RZ_NONNULL const char *s) {
rz_return_val_if_fail(parent && parent->type == STRUCTURED_DATA_TYPE_MAP && key && s, false);
char *copy = rz_str_dup(s);
if (!copy) {
return false;
}
RzStructuredData *child = structured_data_new_string(copy);
return structured_data_map_add(parent, key, child);
}
/**
* \brief Returns a child, map type, RzStructuredData that has been added to the given parent
*
* \param parent Where to add the child RzStructuredData
*
* \return On success returns a valid pointer to the child RzStructuredData, otherwise NULL
*/
RZ_API RZ_BORROW RzStructuredData *rz_structured_data_array_add_map(RZ_NONNULL RzStructuredData *parent) {
rz_return_val_if_fail(parent && parent->type == STRUCTURED_DATA_TYPE_ARRAY, false);
RzStructuredData *child = structured_data_new_map();
if (!structured_data_array_add(parent, child)) {
return NULL;
}
return child;
}
/**
* \brief Returns a child, array type, RzStructuredData that has been added to the given parent
*
* \param parent Where to add the child RzStructuredData
*
* \return On success returns a valid pointer to the child RzStructuredData, otherwise NULL
*/
RZ_API RZ_BORROW RzStructuredData *rz_structured_data_array_add_array(RZ_NONNULL RzStructuredData *parent) {
rz_return_val_if_fail(parent && parent->type == STRUCTURED_DATA_TYPE_ARRAY, false);
RzStructuredData *child = structured_data_new_array();
if (!structured_data_array_add(parent, child)) {
return NULL;
}
return child;
}
/**
* \brief Adds an owned RzStructuredData child to an array type parent
*
* \param parent Where to add the child RzStructuredData
* \param child The child RzStructuredData
*
* \return On success returns true, otherwise the child gets deallocated by the function and return false.
*/
RZ_API bool rz_structured_data_array_add(RZ_NONNULL RzStructuredData *parent, RZ_NONNULL RZ_OWN RzStructuredData *child) {
rz_return_val_if_fail(parent && parent->type == STRUCTURED_DATA_TYPE_ARRAY && child, false);
return structured_data_array_add(parent, child);
}
/**
* \brief Adds unsigned type child to an array type parent
*
* \param parent Where to add the child RzStructuredData
* \param n The value to assign to the child
* \param hex When true the type is going to be set as base16 number instead of base10 unsigned number.
*
* \return On success returns true, otherwise false.
*/
RZ_API bool rz_structured_data_array_add_unsigned(RZ_NONNULL RzStructuredData *parent, ut64 n, bool hex) {
rz_return_val_if_fail(parent && parent->type == STRUCTURED_DATA_TYPE_ARRAY, false);
RzStructuredData *child = structured_data_new_unsigned(n, hex);
return structured_data_array_add(parent, child);
}
/**
* \brief Adds signed type child to an array type parent
*
* \param parent Where to add the child RzStructuredData
* \param n The value to assign to the child
*
* \return On success returns true, otherwise false.
*/
RZ_API bool rz_structured_data_array_add_signed(RZ_NONNULL RzStructuredData *parent, st64 n) {
rz_return_val_if_fail(parent && parent->type == STRUCTURED_DATA_TYPE_ARRAY, false);
RzStructuredData *child = structured_data_new_signed(n);
return structured_data_array_add(parent, child);
}
/**
* \brief Adds double type child to an array type parent
*
* \param parent Where to add the child RzStructuredData
* \param n The value to assign to the child
*
* \return On success returns true, otherwise false.
*/
RZ_API bool rz_structured_data_array_add_double(RZ_NONNULL RzStructuredData *parent, double d) {
rz_return_val_if_fail(parent && parent->type == STRUCTURED_DATA_TYPE_ARRAY, false);
RzStructuredData *child = structured_data_new_double(d);
return structured_data_array_add(parent, child);
}
/**
* \brief Adds signed type child to an array type parent
*
* \param parent Where to add the child RzStructuredData
* \param n The value to assign to the child
*
* \return On success returns true, otherwise false.
*/
RZ_API bool rz_structured_data_array_add_boolean(RZ_NONNULL RzStructuredData *parent, bool b) {
rz_return_val_if_fail(parent && parent->type == STRUCTURED_DATA_TYPE_ARRAY, false);
RzStructuredData *child = structured_data_new_bool(b);
return structured_data_array_add(parent, child);
}
/**
* \brief Adds a null terminated string type child to an array type parent
*
* \param parent Where to add the child RzStructuredData
* \param n The value to assign to the child
*
* \return On success returns true, otherwise false.
*/
RZ_API bool rz_structured_data_array_add_string(RZ_NONNULL RzStructuredData *parent, RZ_NONNULL const char *s) {
rz_return_val_if_fail(parent && parent->type == STRUCTURED_DATA_TYPE_ARRAY && s, false);
char *copy = rz_str_dup(s);
if (!copy) {
return false;
}
RzStructuredData *child = structured_data_new_string(copy);
return structured_data_array_add(parent, child);
}
static void structured_data_iterate_over(StructuredDataIterOver *sdio, const RzStructuredData *sd);
static void structured_data_iterate_over_map(StructuredDataIterOver *sdio, const RzStructuredData *sd) {
void **pit = NULL;
sdio->fit->new_struct(sdio->user, RZ_STRUCTURED_DATA_BLOCK_MAP);
rz_pvector_foreach (sd->v_array, pit) {
const char *key = *pit;
const RzStructuredData *elem = (const RzStructuredData *)ht_sp_find(sd->v_map, key, NULL);
sdio->fit->key(sdio->user, key);
structured_data_iterate_over(sdio, elem);
}
sdio->fit->end_struct(sdio->user);
}
static void structured_data_iterate_over_array(StructuredDataIterOver *sdio, const RzStructuredData *sd) {
void **pit = NULL;
sdio->fit->new_struct(sdio->user, RZ_STRUCTURED_DATA_BLOCK_ARRAY);
rz_pvector_foreach (sd->v_array, pit) {
const RzStructuredData *elem = (const RzStructuredData *)*pit;
structured_data_iterate_over(sdio, elem);
}
sdio->fit->end_struct(sdio->user);
}
static void structured_data_iterate_over(StructuredDataIterOver *sdio, const RzStructuredData *sd) {
if (!sd) {
return;
}
switch (sd->type) {
case STRUCTURED_DATA_TYPE_MAP:
structured_data_iterate_over_map(sdio, sd);
return;
case STRUCTURED_DATA_TYPE_ARRAY:
structured_data_iterate_over_array(sdio, sd);
return;
case STRUCTURED_DATA_TYPE_HEXADECIMAL:
sdio->fit->val_unsigned(sdio->user, sd->v_unsigned, true);
return;
case STRUCTURED_DATA_TYPE_UNSIGNED:
sdio->fit->val_unsigned(sdio->user, sd->v_unsigned, false);
return;
case STRUCTURED_DATA_TYPE_SIGNED:
sdio->fit->val_signed(sdio->user, sd->v_signed);
return;
case STRUCTURED_DATA_TYPE_DOUBLE:
sdio->fit->val_double(sdio->user, sd->v_double);
return;
case STRUCTURED_DATA_TYPE_BOOL:
sdio->fit->val_bool(sdio->user, sd->v_bool);
return;
case STRUCTURED_DATA_TYPE_STRING:
sdio->fit->val_string(sdio->user, sd->v_string);
return;
default:
rz_warn_if_reached();
return;
}
}
/**
* \brief Iterates over a given RzStructuredData using the provided iterator
*
* \param[in] sd The RzStructuredData to iterate over
* \param[in] iterator The iterator to use
* \param user The user ponter (can be null)
*/
RZ_API void rz_structured_data_iterate(RZ_NONNULL const RzStructuredData *sd, RZ_NONNULL const RzStructuredDataIterator *iterator, RZ_NULLABLE void *user) {
rz_return_if_fail(sd && iterator && iterator);
StructuredDataIterOver sdio = {
.fit = iterator,
.user = user,
};
structured_data_iterate_over(&sdio, sd);
}
/**
* \brief Iterates over a given RzStructuredData and generates a json string
*
* \param[in] sd The RzStructuredData to iterate over
*/
RZ_API RZ_OWN char *rz_structured_data_to_json(RZ_NONNULL const RzStructuredData *sd) {
rz_return_val_if_fail(sd, NULL);
PJ *pj = pj_new();
if (!pj) {
return NULL;
}
rz_structured_data_iterate(sd, &builder_json_iterator, pj);
return pj_drain(pj);
}
/**
* \brief Iterates over a given RzStructuredData and generates a yaml string
*
* \param[in] sd The RzStructuredData to iterate over
*/
RZ_API RZ_OWN char *rz_structured_data_to_yaml(RZ_NONNULL const RzStructuredData *sd) {
rz_return_val_if_fail(sd, NULL);
StructYamlPrinter yaml = { 0 };
builder_yaml_init_printer(&yaml);
rz_structured_data_iterate(sd, &builder_yaml_iterator, &yaml);
return builder_yaml_fini_printer(&yaml);
}

View file

@ -0,0 +1,54 @@
// SPDX-FileCopyrightText: 2025 deroad <deroad@kumo.xn--q9jyb4c>
// SPDX-License-Identifier: LGPL-3.0-only
static void builder_json_new_struct(RZ_NULLABLE void *user, RzStructuredDataBlock block) {
switch (block) {
case RZ_STRUCTURED_DATA_BLOCK_MAP:
pj_o((PJ *)user);
break;
case RZ_STRUCTURED_DATA_BLOCK_ARRAY:
pj_a((PJ *)user);
break;
default:
break;
}
}
static void builder_json_end_struct(RZ_NULLABLE void *user) {
pj_end((PJ *)user);
}
static void builder_json_key(RZ_NULLABLE void *user, RZ_NONNULL const char *key) {
pj_k((PJ *)user, key);
}
static void builder_json_val_unsigned(RZ_NULLABLE void *user, ut64 n, bool hex) {
pj_n((PJ *)user, n);
}
static void builder_json_val_signed(RZ_NULLABLE void *user, st64 n) {
pj_N((PJ *)user, n);
}
static void builder_json_val_double(RZ_NULLABLE void *user, double d) {
pj_d((PJ *)user, d);
}
static void builder_json_val_bool(RZ_NULLABLE void *user, bool b) {
pj_b((PJ *)user, b);
}
static void builder_json_val_string(RZ_NULLABLE void *user, RZ_NONNULL const char *v) {
pj_s((PJ *)user, v);
}
static const RzStructuredDataIterator builder_json_iterator = {
.new_struct = builder_json_new_struct,
.end_struct = builder_json_end_struct,
.key = builder_json_key,
.val_unsigned = builder_json_val_unsigned,
.val_signed = builder_json_val_signed,
.val_double = builder_json_val_double,
.val_bool = builder_json_val_bool,
.val_string = builder_json_val_string,
};

View file

@ -0,0 +1,154 @@
// SPDX-FileCopyrightText: 2025 deroad <deroad@kumo.xn--q9jyb4c>
// SPDX-License-Identifier: LGPL-3.0-only
// use the same max depth as pj
#define STRUCT_YAML_MAX_DEPTH RZ_PRINT_JSON_DEPTH_LIMIT
#define STRUCT_YAML_MAX_PAD_LEN (STRUCT_YAML_MAX_DEPTH << 1)
typedef struct struct_yaml_printer_t {
RzStrBuf sb;
size_t depth;
bool first;
ut8 stack[STRUCT_YAML_MAX_DEPTH];
char pad[STRUCT_YAML_MAX_PAD_LEN];
} StructYamlPrinter;
#define builder_yaml_is_array(y) (y->stack[y->depth - 1] == RZ_STRUCTURED_DATA_BLOCK_ARRAY)
#define builder_yaml_was_array(y) (y->depth > 2 && y->stack[y->depth - 2] == RZ_STRUCTURED_DATA_BLOCK_ARRAY)
#define builder_yaml_add_padding(y) \
do { \
if (y->depth > 1) { \
size_t n = (y->depth - 1) << 1; \
if (n > sizeof(y->pad)) { \
n = sizeof(y->pad); \
} \
rz_strbuf_append_n(&y->sb, y->pad, n); \
} \
} while (0)
static void builder_yaml_init_printer(StructYamlPrinter *yaml) {
memset(yaml, 0, sizeof(StructYamlPrinter));
rz_strbuf_init(&yaml->sb);
memset(yaml->pad, ' ', sizeof(yaml->pad));
}
static char *builder_yaml_fini_printer(StructYamlPrinter *yaml) {
return rz_strbuf_drain_nofree(&yaml->sb);
}
static void builder_yaml_new_struct(RZ_NULLABLE void *user, RzStructuredDataBlock block) {
StructYamlPrinter *yaml = (StructYamlPrinter *)user;
if (yaml->depth > 0) {
if (builder_yaml_is_array(yaml)) {
builder_yaml_add_padding(yaml);
rz_strbuf_append(&yaml->sb, "-");
} else {
rz_strbuf_append(&yaml->sb, "\n");
}
}
yaml->first = true;
yaml->depth++;
yaml->stack[yaml->depth - 1] = (ut8)block;
}
static void builder_yaml_end_struct(RZ_NULLABLE void *user) {
StructYamlPrinter *yaml = (StructYamlPrinter *)user;
yaml->depth--;
}
static void builder_yaml_key(RZ_NULLABLE void *user, RZ_NONNULL const char *key) {
StructYamlPrinter *yaml = (StructYamlPrinter *)user;
if (yaml->first && builder_yaml_was_array(yaml)) {
rz_strbuf_appendf(&yaml->sb, " %s:", key);
} else {
builder_yaml_add_padding(yaml);
rz_strbuf_appendf(&yaml->sb, "%s:", key);
}
yaml->first = false;
}
static void builder_yaml_val_unsigned(RZ_NULLABLE void *user, ut64 n, bool hex) {
StructYamlPrinter *yaml = (StructYamlPrinter *)user;
if (builder_yaml_is_array(yaml)) {
builder_yaml_add_padding(yaml);
if (hex) {
rz_strbuf_appendf(&yaml->sb, "- 0x%" PFMT64x "\n", n);
} else {
rz_strbuf_appendf(&yaml->sb, "- %" PFMT64u "\n", n);
}
} else {
if (hex) {
rz_strbuf_appendf(&yaml->sb, " 0x%" PFMT64x "\n", n);
} else {
rz_strbuf_appendf(&yaml->sb, " %" PFMT64u "\n", n);
}
}
yaml->first = false;
}
static void builder_yaml_val_signed(RZ_NULLABLE void *user, st64 n) {
StructYamlPrinter *yaml = (StructYamlPrinter *)user;
if (builder_yaml_is_array(yaml)) {
builder_yaml_add_padding(yaml);
rz_strbuf_appendf(&yaml->sb, "- %" PFMT64d "\n", n);
} else {
rz_strbuf_appendf(&yaml->sb, " %" PFMT64d "\n", n);
}
yaml->first = false;
}
static void builder_yaml_val_double(RZ_NULLABLE void *user, double d) {
StructYamlPrinter *yaml = (StructYamlPrinter *)user;
if (builder_yaml_is_array(yaml)) {
builder_yaml_add_padding(yaml);
rz_strbuf_appendf(&yaml->sb, "- %f\n", d);
} else {
rz_strbuf_appendf(&yaml->sb, " %f\n", d);
}
yaml->first = false;
}
static void builder_yaml_val_bool(RZ_NULLABLE void *user, bool b) {
const char *s = b ? "true" : "false";
StructYamlPrinter *yaml = (StructYamlPrinter *)user;
if (builder_yaml_is_array(yaml)) {
builder_yaml_add_padding(yaml);
rz_strbuf_appendf(&yaml->sb, "- %s\n", s);
} else {
rz_strbuf_appendf(&yaml->sb, " %s\n", s);
}
yaml->first = false;
}
static void builder_yaml_val_string(RZ_NULLABLE void *user, RZ_NONNULL const char *s) {
StructYamlPrinter *yaml = (StructYamlPrinter *)user;
char *escaped = rz_str_escape_utf8_for_json(s, -1);
if (builder_yaml_is_array(yaml)) {
builder_yaml_add_padding(yaml);
rz_strbuf_appendf(&yaml->sb, "- \"%s\"\n", escaped);
} else {
rz_strbuf_appendf(&yaml->sb, " \"%s\"\n", escaped);
}
yaml->first = false;
free(escaped);
}
static const RzStructuredDataIterator builder_yaml_iterator = {
.new_struct = builder_yaml_new_struct,
.end_struct = builder_yaml_end_struct,
.key = builder_yaml_key,
.val_unsigned = builder_yaml_val_unsigned,
.val_signed = builder_yaml_val_signed,
.val_double = builder_yaml_val_double,
.val_bool = builder_yaml_val_bool,
.val_string = builder_yaml_val_string,
};

View file

@ -3372,20 +3372,27 @@ NAME=iH (file x86_64)
FILE=bins/elf/analysis/hello-linux-x86_64
CMDS=iH
EXPECT=<<EOF
0x00000000 MAGIC 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
0x00000010 Type 0x0002
0x00000012 Machine 0x003e
0x00000014 Version 0x00000001
0x00000018 Entrypoint 0x00400410
0x00000020 PhOff 0x00000040
0x00000028 ShOff 0x00000a30
0x00000030 Flags 0x0000
0x00000034 EhSize 64
0x00000036 PhentSize 56
0x00000038 PhNum 8
0x0000003a ShentSize 64
0x0000003c ShNum 30
0x0000003e ShStrndx 27
elf:
e_ident:
bytes: "7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00"
ei_class: 2
ei_data: 1
ei_version: 1
ei_osabi: 0
ei_abiversion: 0
e_machine: 62
e_version: 1
e_entry: 0x400410
e_phoff: 0x40
e_shoff: 0xa30
e_flags: 0x0
e_ehsize: 64
e_phentsize: 56
e_phnum: 8
e_shentsize: 64
e_shnum: 30
e_shstrndx: 27
EOF
RUN

View file

@ -54,29 +54,31 @@ NAME=: DMP header & bmp header
FILE=bins/dmp/bmp.dmp
CMDS=iH
EXPECT=<<EOF
DUMP_HEADER64:
MajorVersion : 0x0000000f
MinorVersion : 0x000047ba
DirectoryTableBase : 0x00000000006d4002
PfnDataBase : 0xfffff80510c22468
PsLoadedModuleList : 0xfffff80510af62f0
PsActiveProcessHead : 0xfffff80510ae6980
MachineImageType : 0x00008664
NumberProcessors : 0x00000001
BugCheckCode : 0x00000000 (Not a crash)
BugCheckParameter1 : 0x0000000000000000
BugCheckParameter2 : 0x0000000000000000
BugCheckParameter3 : 0x0000000000000000
BugCheckParameter4 : 0x0000000000000000
KdDebuggerDataBlock : 0xfffff80510ad45e0
SecondaryDataState : 0x45474150
ProductType : 0x45474150
SuiteMask : 0x45474150
dmp64:
MajorVersion: 0xf
MinorVersion: 0x47ba
DirectoryTableBase: 0x6d4002
PfnDataBase: 0xfffff80510c22468
PsLoadedModuleList: 0xfffff80510af62f0
PsActiveProcessHead: 0xfffff80510ae6980
MachineImageType: 0x8664
NumberProcessors: 0x1
BugCheckCode:
Value: 0x0
Meaning: "Not a crash"
BugCheckParameter1: 0x0
BugCheckParameter2: 0x0
BugCheckParameter3: 0x0
BugCheckParameter4: 0x0
KdDebuggerDataBlock: 0xfffff80510ad45e0
SecondaryDataState: 0x45474150
ProductType: 0x45474150
SuiteMask: 0x45474150
Bitmap:
HeaderSize: 0xa038
BitmapSize: 0x40000
Pages: 0x544b
BITMAP_DUMP:
HeaderSize : 0x0000a038
BitmapSize : 0x00040000
Pages : 0x0000544b
EOF
RUN
@ -116,55 +118,57 @@ pi 4
dbt
EOF
EXPECT=<<EOF
DUMP_HEADER64:
MajorVersion : 0x0000000f
MinorVersion : 0x00004a61
DirectoryTableBase : 0x00000000001ad000
PfnDataBase : 0xfffff8047c6fc500
PsLoadedModuleList : 0xfffff8047c62a390
PsActiveProcessHead : 0xfffff8047c61e200
MachineImageType : 0x00008664
NumberProcessors : 0x00000010
BugCheckCode : 0x1000007e (SYSTEM_THREAD_EXCEPTION_NOT_HANDLED_M)
BugCheckParameter1 : 0xffffffffc0000005
BugCheckParameter2 : 0xfffff8048b58334c
BugCheckParameter3 : 0xffff850429891ee8
BugCheckParameter4 : 0xffff850429891720
KdDebuggerDataBlock : 0xfffff8047c600b20
SecondaryDataState : 0x45474150
ProductType : 0x00000001
SuiteMask : 0x00000110
dmp64:
MajorVersion: 0xf
MinorVersion: 0x4a61
DirectoryTableBase: 0x1ad000
PfnDataBase: 0xfffff8047c6fc500
PsLoadedModuleList: 0xfffff8047c62a390
PsActiveProcessHead: 0xfffff8047c61e200
MachineImageType: 0x8664
NumberProcessors: 0x10
BugCheckCode:
Value: 0x1000007e
Meaning: "SYSTEM_THREAD_EXCEPTION_NOT_HANDLED_M"
BugCheckParameter1: 0xffffffffc0000005
BugCheckParameter2: 0xfffff8048b58334c
BugCheckParameter3: 0xffff850429891ee8
BugCheckParameter4: 0xffff850429891720
KdDebuggerDataBlock: 0xfffff8047c600b20
SecondaryDataState: 0x45474150
ProductType: 0x1
SuiteMask: 0x110
TriageDump64:
ServicePackBuild: 0x0
SizeOfDump: 0x13a28c
ValidOffset: 0x13a288
ContextOffset: 0x348
ExceptionOffset: 0xf00
MmOffset: 0x2080
UnloadedDriversOffset: 0x20d0
PrcbOffset: 0x21b8
ProcessOffset: 0xd0b8
ThreadOffset: 0xdaf8
CallStackOffset: 0xe390
SizeOfCallStack: 0x2118
DriverListOffset: 0x10828
DriverCount: 0x97
StringPoolOffset: 0x15d18
StringPoolSize: 0x3720
BrokenDriverOffset: 0x0
TriageOptions: 0xffffffff
TopOfStack: 0xffff850429890ee8
BStoreOffset: 0x0
SizeOfBStore: 0x0
LimitOfBStore: 0x0
DataPageAddress: 0x0
DataPageOffset: 0x0
DataPageSize: 0x0
DebuggerDataOffset: 0x104a8
DebuggerDataSize: 0x380
DataBlocksOffset: 0x19438
DataBlocksCount: 0x727
TRIAGE_DUMP64:
ServicePackBuild : 0x00000000
SizeOfDump : 0x0013a28c
ValidOffset : 0x0013a288
ContextOffset : 0x00000348
ExceptionOffset : 0x00000f00
MmOffset : 0x00002080
UnloadedDriversOffset : 0x000020d0
PrcbOffset : 0x000021b8
ProcessOffset : 0x0000d0b8
ThreadOffset : 0x0000daf8
CallStackOffset : 0x0000e390
SizeOfCallStack : 0x00002118
DriverListOffset : 0x00010828
DriverCount : 0x00000097
StringPoolOffset : 0x00015d18
StringPoolSize : 0x00003720
BrokenDriverOffset : 0x00000000
TriageOptions : 0xffffffff
TopOfStack : 0xffff850429890ee8
BStoreOffset : 0x00000000
SizeOfBStore : 0x00000000
LimitOfBStore : 0x0000000000000000
DataPageAddress : 0x0000000000000000
DataPageOffset : 0x00000000
DataPageSize : 0x00000000
DebuggerDataOffset : 0x000104a8
DebuggerDataSize : 0x00000380
DataBlocksOffset : 0x00019438
DataBlocksCount : 0x00000727
mxcsr = 0x00001f80
rflags = 0x0000000000040286
rax = 0xffff850429891720
@ -244,55 +248,57 @@ pi 4
dbt
EOF
EXPECT=<<EOF
DUMP_HEADER64:
MajorVersion : 0x0000000f
MinorVersion : 0x000055f0
DirectoryTableBase : 0x00000000946aa000
PfnDataBase : 0xfffff803f3b19960
PsLoadedModuleList : 0xfffff803f3a2aa20
PsActiveProcessHead : 0xfffff803f3a1d1c0
MachineImageType : 0x0000aa64
NumberProcessors : 0x00000008
BugCheckCode : 0x000001c8 (MANUALLY_INITIATED_POWER_BUTTON_HOLD)
BugCheckParameter1 : 0x0000000000001b58
BugCheckParameter2 : 0xfffff803f3a20860
BugCheckParameter3 : 0x0000000000000000
BugCheckParameter4 : 0x0000000000000000
KdDebuggerDataBlock : 0xfffff803f3a00d00
SecondaryDataState : 0x45474150
ProductType : 0x00000001
SuiteMask : 0x00000110
dmp64:
MajorVersion: 0xf
MinorVersion: 0x55f0
DirectoryTableBase: 0x946aa000
PfnDataBase: 0xfffff803f3b19960
PsLoadedModuleList: 0xfffff803f3a2aa20
PsActiveProcessHead: 0xfffff803f3a1d1c0
MachineImageType: 0xaa64
NumberProcessors: 0x8
BugCheckCode:
Value: 0x1c8
Meaning: "MANUALLY_INITIATED_POWER_BUTTON_HOLD"
BugCheckParameter1: 0x1b58
BugCheckParameter2: 0xfffff803f3a20860
BugCheckParameter3: 0x0
BugCheckParameter4: 0x0
KdDebuggerDataBlock: 0xfffff803f3a00d00
SecondaryDataState: 0x45474150
ProductType: 0x1
SuiteMask: 0x110
TriageDump64:
ServicePackBuild: 0x0
SizeOfDump: 0xac46c
ValidOffset: 0xac468
ContextOffset: 0x348
ExceptionOffset: 0xf00
MmOffset: 0x2080
UnloadedDriversOffset: 0x20d0
PrcbOffset: 0x2340
ProcessOffset: 0xb9c0
ThreadOffset: 0xc640
CallStackOffset: 0xcf50
SizeOfCallStack: 0xb60
DriverListOffset: 0xde30
DriverCount: 0xf5
StringPoolOffset: 0x16800
StringPoolSize: 0x6eb0
BrokenDriverOffset: 0x0
TriageOptions: 0xffffffff
TopOfStack: 0xffffe00e0e4bc4a0
BStoreOffset: 0x0
SizeOfBStore: 0x0
LimitOfBStore: 0x0
DataPageAddress: 0x0
DataPageOffset: 0x0
DataPageSize: 0x0
DebuggerDataOffset: 0xdab0
DebuggerDataSize: 0x380
DataBlocksOffset: 0x1d6b0
DataBlocksCount: 0x2a7
TRIAGE_DUMP64:
ServicePackBuild : 0x00000000
SizeOfDump : 0x000ac46c
ValidOffset : 0x000ac468
ContextOffset : 0x00000348
ExceptionOffset : 0x00000f00
MmOffset : 0x00002080
UnloadedDriversOffset : 0x000020d0
PrcbOffset : 0x00002340
ProcessOffset : 0x0000b9c0
ThreadOffset : 0x0000c640
CallStackOffset : 0x0000cf50
SizeOfCallStack : 0x00000b60
DriverListOffset : 0x0000de30
DriverCount : 0x000000f5
StringPoolOffset : 0x00016800
StringPoolSize : 0x00006eb0
BrokenDriverOffset : 0x00000000
TriageOptions : 0xffffffff
TopOfStack : 0xffffe00e0e4bc4a0
BStoreOffset : 0x00000000
SizeOfBStore : 0x00000000
LimitOfBStore : 0x0000000000000000
DataPageAddress : 0x0000000000000000
DataPageOffset : 0x00000000
DataPageSize : 0x00000000
DebuggerDataOffset : 0x0000dab0
DebuggerDataSize : 0x00000380
DataBlocksOffset : 0x0001d6b0
DataBlocksCount : 0x000002a7
cpsr = 0x80000144
x0 = 0x0000000000000000
x1 = 0x0000000000000001
@ -358,29 +364,31 @@ dbt
oml
EOF
EXPECT=<<EOF
DUMP_HEADER64:
MajorVersion : 0x0000000f
MinorVersion : 0x000047ba
DirectoryTableBase : 0x00000000006d4002
PfnDataBase : 0xfffff80510c22468
PsLoadedModuleList : 0xfffff80510af62f0
PsActiveProcessHead : 0xfffff80510ae6980
MachineImageType : 0x00008664
NumberProcessors : 0x00000001
BugCheckCode : 0x00000000 (Not a crash)
BugCheckParameter1 : 0x0000000000000000
BugCheckParameter2 : 0x0000000000000000
BugCheckParameter3 : 0x0000000000000000
BugCheckParameter4 : 0x0000000000000000
KdDebuggerDataBlock : 0xfffff80510ad45e0
SecondaryDataState : 0x45474150
ProductType : 0x45474150
SuiteMask : 0x45474150
dmp64:
MajorVersion: 0xf
MinorVersion: 0x47ba
DirectoryTableBase: 0x6d4002
PfnDataBase: 0xfffff80510c22468
PsLoadedModuleList: 0xfffff80510af62f0
PsActiveProcessHead: 0xfffff80510ae6980
MachineImageType: 0x8664
NumberProcessors: 0x1
BugCheckCode:
Value: 0x0
Meaning: "Not a crash"
BugCheckParameter1: 0x0
BugCheckParameter2: 0x0
BugCheckParameter3: 0x0
BugCheckParameter4: 0x0
KdDebuggerDataBlock: 0xfffff80510ad45e0
SecondaryDataState: 0x45474150
ProductType: 0x45474150
SuiteMask: 0x45474150
Bitmap:
HeaderSize: 0xa038
BitmapSize: 0x40000
Pages: 0x544b
BITMAP_DUMP:
HeaderSize : 0x0000a038
BitmapSize : 0x00040000
Pages : 0x0000544b
mxcsr = 0x00001f80
rflags = 0x0000000000040202
rax = 0x0000000000000003

View file

@ -4,7 +4,7 @@ CMDS=<<EOF
i
is
iS
iH~{}
iH
oml
pi 4@ sym._what_is_cool
EOF
@ -67,90 +67,81 @@ nth paddr vaddr bind type size lib name
0x00004fb0 0x50 0x180004fb0 0x50 0x0 -r-x lib_liba-1.0.dylib.2.__TEXT.__unwind_info
0x00008fa0 0x18 0x180008fa0 0x18 0x0 -r-x lib_libb-1.0.dylib.0.__TEXT.__text
0x00008fb8 0x48 0x180008fb8 0x48 0x0 -r-x lib_libb-1.0.dylib.1.__TEXT.__unwind_info
{
"version": "<940",
"header": {
"magic": "dyld_v1 arm64",
"mappingOffset": 320,
"mappingCount": 3,
"imagesOffset": 656,
"imagesCount": 2,
"dyldBaseAddress": 0,
"codeSignatureOffset": 196608,
"codeSignatureSize": 16384,
"slideInfoOffset": 0,
"slideInfoSize": 0,
"localSymbolsOffset": 0,
"localSymbolsSize": 0,
"uuid": "857bce1a017e34649909d58ee21cf8dc",
"cacheType": "production",
"branchPoolsOffset": 0,
"branchPoolsCount": 0,
"accelerateInfoAddr": 0,
"accelerateInfoSize": 0,
"imagesTextOffset": 720,
"imagesTextCount": 2,
"patchInfoAddr": 6509723956,
"patchInfoSize": 80,
"otherImageGroupAddrUnused": 0,
"otherImageGroupSizeUnused": 0,
"progClosuresAddr": 6509740032,
"progClosuresSize": 0,
"progClosuresTrieAddr": 6509740032,
"progClosuresTrieSize": 8,
"platform": 1,
"formatVersion": 10,
"dylibsExpectedOnDisk": 0,
"simulator": 0,
"locallyBuiltCache": 1,
"builtFromChainedFixups": 0,
"padding": 0,
"sharedRegionStart": 6442450944,
"sharedRegionSize": 4294967296,
"maxSlide": 2147385344,
"dylibsImageArrayAddr": 6509723648,
"dylibsImageArraySize": 240,
"dylibsTrieAddr": 6509723888,
"dylibsTrieSize": 68,
"otherImageArrayAddr": 0,
"otherImageArraySize": 0,
"otherTrieAddr": 0,
"otherTrieSize": 0,
"mappingWithSlideOffset": 488,
"mappingWithSlideCount": 3
},
"slideInfo": [
{
"start": 98304,
"end": 114688,
"version": 2,
"slide": 0,
"page_starts_count": 4,
"page_extras_count": 0,
"delta_mask": 72056494526300160,
"value_mask": 18374687579183251455,
"value_add": 0,
"delta_shift": 38,
"page_size": 4096
}
],
"images": [
{
"uuid": "ccbf29d455693a1592314e14d41a542a",
"address": 6442455040,
"textSegmentSize": 16384,
"path": "/usr/lib/liba-1.0.dylib",
"name": "liba-1.0.dylib"
},
{
"uuid": "60d2f3d644a2391087503a56a3d8ff07",
"address": 6442471424,
"textSegmentSize": 16384,
"path": "/usr/lib/libb-1.0.dylib",
"name": "libb-1.0.dylib"
}
]
}
dyldcache:
version: "<940"
header:
magic: "dyld_v1 arm64"
mappingOffset: 0x140
mappingCount: 3
imagesOffset: 0x290
imagesCount: 2
dyldBaseAddress: 0x0
codeSignatureOffset: 0x30000
codeSignatureSize: 16384
slideInfoOffset: 0x0
slideInfoSize: 0
localSymbolsOffset: 0x0
localSymbolsSize: 0
uuid: "857bce1a017e34649909d58ee21cf8dc"
cacheType: "production"
branchPoolsOffset: 0x0
branchPoolsCount: 0
accelerateInfoAddr: 0
accelerateInfoSize: 0
imagesTextOffset: 0x2d0
imagesTextCount: 2
patchInfoAddr: 6509723956
patchInfoSize: 80
otherImageGroupAddrUnused: 0x0
otherImageGroupSizeUnused: 0
progClosuresAddr: 0x18402c000
progClosuresSize: 0
progClosuresTrieAddr: 0x18402c000
progClosuresTrieSize: 8
platform: 1
formatVersion: 10
dylibsExpectedOnDisk: 0
simulator: 0
locallyBuiltCache: 1
builtFromChainedFixups: 0
padding: 0x0
sharedRegionStart: 6442450944
sharedRegionSize: 4294967296
maxSlide: 2147385344
dylibsImageArrayAddr: 0x184028000
dylibsImageArraySize: 240
dylibsTrieAddr: 0x1840280f0
dylibsTrieSize: 68
otherImageArrayAddr: 0x0
otherImageArraySize: 0
otherTrieAddr: 0x0
otherTrieSize: 0
mappingWithSlideOffset: 0x1e8
mappingWithSlideCount: 3
slideInfo:
- start: 0x18000
end: 0x1c000
version: 2
slide: 0
page_starts_count: 4
page_extras_count: 0
delta_mask: 0xffff0000000000
value_mask: 0xff0000ffffffffff
value_add: 0
delta_shift: 38
page_size: 4096
images:
- uuid: "ccbf29d455693a1592314e14d41a542a"
address: 0x180001000
textSegmentSize: 16384
path: "/usr/lib/liba-1.0.dylib"
name: "liba-1.0.dylib"
- uuid: "60d2f3d644a2391087503a56a3d8ff07"
address: 0x180005000
textSegmentSize: 16384
path: "/usr/lib/libb-1.0.dylib"
name: "libb-1.0.dylib"
1 fd: 4 +0x00000000 0x180000000 - 0x180017fff r-x vmap.cache_map.0
2 fd: 4 +0x00018000 0x182018000 - 0x18201bfff r-- vmap.cache_map.1
3 fd: 4 +0x0001c000 0x18401c000 - 0x18402ffff r-- vmap.cache_map.2
@ -169,7 +160,7 @@ o bins/dyldcache/dyld_shared_cache_arm64-macOS
i
is
iS
iH~{}
iH
oml
pi 4@ sym._what_is_cool
EOF
@ -229,90 +220,81 @@ nth paddr vaddr bind type size lib name
0x00004f60 0x48 0x180004f60 0x48 0x0 -r-x lib_liba-1.0.dylib.0.__TEXT.__text
0x00004fa8 0x6 0x180004fa8 0x6 0x0 -r-x lib_liba-1.0.dylib.1.__TEXT.__cstring
0x00004fb0 0x50 0x180004fb0 0x50 0x0 -r-x lib_liba-1.0.dylib.2.__TEXT.__unwind_info
{
"version": "<940",
"header": {
"magic": "dyld_v1 arm64",
"mappingOffset": 320,
"mappingCount": 3,
"imagesOffset": 656,
"imagesCount": 2,
"dyldBaseAddress": 0,
"codeSignatureOffset": 196608,
"codeSignatureSize": 16384,
"slideInfoOffset": 0,
"slideInfoSize": 0,
"localSymbolsOffset": 0,
"localSymbolsSize": 0,
"uuid": "857bce1a017e34649909d58ee21cf8dc",
"cacheType": "production",
"branchPoolsOffset": 0,
"branchPoolsCount": 0,
"accelerateInfoAddr": 0,
"accelerateInfoSize": 0,
"imagesTextOffset": 720,
"imagesTextCount": 2,
"patchInfoAddr": 6509723956,
"patchInfoSize": 80,
"otherImageGroupAddrUnused": 0,
"otherImageGroupSizeUnused": 0,
"progClosuresAddr": 6509740032,
"progClosuresSize": 0,
"progClosuresTrieAddr": 6509740032,
"progClosuresTrieSize": 8,
"platform": 1,
"formatVersion": 10,
"dylibsExpectedOnDisk": 0,
"simulator": 0,
"locallyBuiltCache": 1,
"builtFromChainedFixups": 0,
"padding": 0,
"sharedRegionStart": 6442450944,
"sharedRegionSize": 4294967296,
"maxSlide": 2147385344,
"dylibsImageArrayAddr": 6509723648,
"dylibsImageArraySize": 240,
"dylibsTrieAddr": 6509723888,
"dylibsTrieSize": 68,
"otherImageArrayAddr": 0,
"otherImageArraySize": 0,
"otherTrieAddr": 0,
"otherTrieSize": 0,
"mappingWithSlideOffset": 488,
"mappingWithSlideCount": 3
},
"slideInfo": [
{
"start": 98304,
"end": 114688,
"version": 2,
"slide": 0,
"page_starts_count": 4,
"page_extras_count": 0,
"delta_mask": 72056494526300160,
"value_mask": 18374687579183251455,
"value_add": 0,
"delta_shift": 38,
"page_size": 4096
}
],
"images": [
{
"uuid": "ccbf29d455693a1592314e14d41a542a",
"address": 6442455040,
"textSegmentSize": 16384,
"path": "/usr/lib/liba-1.0.dylib",
"name": "liba-1.0.dylib"
},
{
"uuid": "60d2f3d644a2391087503a56a3d8ff07",
"address": 6442471424,
"textSegmentSize": 16384,
"path": "/usr/lib/libb-1.0.dylib",
"name": "libb-1.0.dylib"
}
]
}
dyldcache:
version: "<940"
header:
magic: "dyld_v1 arm64"
mappingOffset: 0x140
mappingCount: 3
imagesOffset: 0x290
imagesCount: 2
dyldBaseAddress: 0x0
codeSignatureOffset: 0x30000
codeSignatureSize: 16384
slideInfoOffset: 0x0
slideInfoSize: 0
localSymbolsOffset: 0x0
localSymbolsSize: 0
uuid: "857bce1a017e34649909d58ee21cf8dc"
cacheType: "production"
branchPoolsOffset: 0x0
branchPoolsCount: 0
accelerateInfoAddr: 0
accelerateInfoSize: 0
imagesTextOffset: 0x2d0
imagesTextCount: 2
patchInfoAddr: 6509723956
patchInfoSize: 80
otherImageGroupAddrUnused: 0x0
otherImageGroupSizeUnused: 0
progClosuresAddr: 0x18402c000
progClosuresSize: 0
progClosuresTrieAddr: 0x18402c000
progClosuresTrieSize: 8
platform: 1
formatVersion: 10
dylibsExpectedOnDisk: 0
simulator: 0
locallyBuiltCache: 1
builtFromChainedFixups: 0
padding: 0x0
sharedRegionStart: 6442450944
sharedRegionSize: 4294967296
maxSlide: 2147385344
dylibsImageArrayAddr: 0x184028000
dylibsImageArraySize: 240
dylibsTrieAddr: 0x1840280f0
dylibsTrieSize: 68
otherImageArrayAddr: 0x0
otherImageArraySize: 0
otherTrieAddr: 0x0
otherTrieSize: 0
mappingWithSlideOffset: 0x1e8
mappingWithSlideCount: 3
slideInfo:
- start: 0x18000
end: 0x1c000
version: 2
slide: 0
page_starts_count: 4
page_extras_count: 0
delta_mask: 0xffff0000000000
value_mask: 0xff0000ffffffffff
value_add: 0
delta_shift: 38
page_size: 4096
images:
- uuid: "ccbf29d455693a1592314e14d41a542a"
address: 0x180001000
textSegmentSize: 16384
path: "/usr/lib/liba-1.0.dylib"
name: "liba-1.0.dylib"
- uuid: "60d2f3d644a2391087503a56a3d8ff07"
address: 0x180005000
textSegmentSize: 16384
path: "/usr/lib/libb-1.0.dylib"
name: "libb-1.0.dylib"
1 fd: 4 +0x00000000 0x180000000 - 0x180017fff r-x vmap.cache_map.0
2 fd: 4 +0x00018000 0x182018000 - 0x18201bfff r-- vmap.cache_map.1
3 fd: 4 +0x0001c000 0x18401c000 - 0x18402ffff r-- vmap.cache_map.2
@ -609,7 +591,7 @@ CMDS=<<EOF
i
is
iS
iH~{}
iH
oml
EOF
EXPECT=<<EOF
@ -677,114 +659,104 @@ nth paddr vaddr bind type size lib name
0x0000ffb8 0x48 0x18000ffb8 0x48 0x0 -r-x system_libdyld.dylib.2.__TEXT.__unwind_info
0x00013fb4 0x4 0x180013fb4 0x4 0x0 -r-x system_libsystem_kernel.dylib.0.__TEXT.__text
0x00013fb8 0x48 0x180013fb8 0x48 0x0 -r-x system_libsystem_kernel.dylib.1.__TEXT.__unwind_info
{
"version": "1042.1",
"header": {
"magic": "dyld_v1 arm64",
"mappingOffset": 512,
"mappingCount": 2,
"imagesOffset": 736,
"imagesCount": 4,
"dyldBaseAddress": 0,
"codeSignatureOffset": 114688,
"codeSignatureSize": 16384,
"slideInfoOffset": 0,
"slideInfoSize": 0,
"localSymbolsOffset": 0,
"localSymbolsSize": 0,
"uuid": "c0a042e3c0db394caa455cd7e767643f",
"cacheType": "development",
"branchPoolsOffset": 0,
"branchPoolsCount": 0,
"dyldInCacheMH": 0,
"dyldInCacheEntry": 0,
"imagesTextOffset": 864,
"imagesTextCount": 4,
"patchInfoAddr": 6442532976,
"patchInfoSize": 264,
"otherImageGroupAddrUnused": 0,
"otherImageGroupSizeUnused": 0,
"progClosuresAddr": 0,
"progClosuresSize": 0,
"progClosuresTrieAddr": 0,
"progClosuresTrieSize": 0,
"platform": 1,
"formatVersion": 0,
"dylibsExpectedOnDisk": 0,
"simulator": 0,
"locallyBuiltCache": 1,
"builtFromChainedFixups": 0,
"padding": 0,
"sharedRegionStart": 6442450944,
"sharedRegionSize": 131072,
"maxSlide": 2147401728,
"dylibsImageArrayAddr": 0,
"dylibsImageArraySize": 0,
"dylibsTrieAddr": 6442532864,
"dylibsTrieSize": 112,
"otherImageArrayAddr": 0,
"otherImageArraySize": 0,
"otherTrieAddr": 0,
"otherTrieSize": 0,
"mappingWithSlideOffset": 624,
"mappingWithSlideCount": 2,
"dylibsPBLStateArrayAddrUnused": 0,
"dylibsPBLSetAddr": 6442533240,
"programsPBLSetPoolAddr": 6442534280,
"programsPBLSetPoolSize": 16384,
"programTrieAddr": 6442550664,
"programTrieSize": 88,
"osVersion": 851968,
"altPlatform": 0,
"altOsVersion": 0,
"swiftOptsOffset": 0,
"swiftOptsSize": 0,
"subCacheArrayOffset": 992,
"subCacheArrayCount": 0,
"symbolFileUUID": "00000000000000000000000000000000",
"rosettaReadOnlyAddr": 0,
"rosettaReadOnlySize": 0,
"rosettaReadWriteAddr": 0,
"rosettaReadWriteSize": 0,
"cacheSubType": 0,
"objcOptsOffset": 0,
"objcOptsSize": 0,
"cacheAtlasOffset": 0,
"cacheAtlasSize": 0,
"dynamicDataOffset": 114688,
"dynamicDataMaxSize": 16384
},
"images": [
{
"uuid": "e0a310e1c61e3b289c5df43f04e71a44",
"address": 6442467328,
"textSegmentSize": 16384,
"path": "/usr/lib/libSystem.B.dylib",
"name": "libSystem.B.dylib"
},
{
"uuid": "f2c8e54bd02937e69928edd8b4bbec63",
"address": 6442483712,
"textSegmentSize": 16384,
"path": "/usr/lib/libhello.dylib",
"name": "libhello.dylib"
},
{
"uuid": "439351ae77ca308ebf1da32729a79709",
"address": 6442500096,
"textSegmentSize": 16384,
"path": "/usr/lib/system/libdyld.dylib",
"name": "libdyld.dylib"
},
{
"uuid": "4ce071b5dd373397aca699d517bdb6e7",
"address": 6442516480,
"textSegmentSize": 16384,
"path": "/usr/lib/system/libsystem_kernel.dylib",
"name": "libsystem_kernel.dylib"
}
]
}
dyldcache:
version: "1042.1"
header:
magic: "dyld_v1 arm64"
mappingOffset: 0x200
mappingCount: 2
imagesOffset: 0x2e0
imagesCount: 4
dyldBaseAddress: 0x0
codeSignatureOffset: 0x1c000
codeSignatureSize: 16384
slideInfoOffset: 0x0
slideInfoSize: 0
localSymbolsOffset: 0x0
localSymbolsSize: 0
uuid: "c0a042e3c0db394caa455cd7e767643f"
cacheType: "development"
branchPoolsOffset: 0x0
branchPoolsCount: 0
dyldInCacheMH: 0x0
dyldInCacheEntry: 0x0
imagesTextOffset: 0x360
imagesTextCount: 4
patchInfoAddr: 6442532976
patchInfoSize: 264
otherImageGroupAddrUnused: 0x0
otherImageGroupSizeUnused: 0
progClosuresAddr: 0x0
progClosuresSize: 0
progClosuresTrieAddr: 0x0
progClosuresTrieSize: 0
platform: 1
formatVersion: 0
dylibsExpectedOnDisk: 0
simulator: 0
locallyBuiltCache: 1
builtFromChainedFixups: 0
padding: 0x0
sharedRegionStart: 6442450944
sharedRegionSize: 131072
maxSlide: 2147401728
dylibsImageArrayAddr: 0x0
dylibsImageArraySize: 0
dylibsTrieAddr: 0x180014000
dylibsTrieSize: 112
otherImageArrayAddr: 0x0
otherImageArraySize: 0
otherTrieAddr: 0x0
otherTrieSize: 0
mappingWithSlideOffset: 0x270
mappingWithSlideCount: 2
dylibsPBLStateArrayAddrUnused: 0x0
dylibsPBLSetAddr: 0x180014178
programsPBLSetPoolAddr: 0x180014588
programsPBLSetPoolSize: 16384
programTrieAddr: 0x180018588
programTrieSize: 88
osVersion: 851968
altPlatform: 0
altOsVersion: 0
swiftOptsOffset: 0x0
swiftOptsSize: 0
subCacheArrayOffset: 0x3e0
subCacheArrayCount: 0
symbolFileUUID: "00000000000000000000000000000000"
rosettaReadOnlyAddr: 0x0
rosettaReadOnlySize: 0
rosettaReadWriteAddr: 0x0
rosettaReadWriteSize: 0
cacheSubType: 0
objcOptsOffset: 0x0
objcOptsSize: 0
cacheAtlasOffset: 0x0
cacheAtlasSize: 0
dynamicDataOffset: 0x1c000
dynamicDataMaxSize: 16384
images:
- uuid: "e0a310e1c61e3b289c5df43f04e71a44"
address: 0x180004000
textSegmentSize: 16384
path: "/usr/lib/libSystem.B.dylib"
name: "libSystem.B.dylib"
- uuid: "f2c8e54bd02937e69928edd8b4bbec63"
address: 0x180008000
textSegmentSize: 16384
path: "/usr/lib/libhello.dylib"
name: "libhello.dylib"
- uuid: "439351ae77ca308ebf1da32729a79709"
address: 0x18000c000
textSegmentSize: 16384
path: "/usr/lib/system/libdyld.dylib"
name: "libdyld.dylib"
- uuid: "4ce071b5dd373397aca699d517bdb6e7"
address: 0x180010000
textSegmentSize: 16384
path: "/usr/lib/system/libsystem_kernel.dylib"
name: "libsystem_kernel.dylib"
1 fd: 3 +0x00000000 0x180000000 - 0x180013fff r-x fmap.cache_map.0
2 fd: 3 +0x00014000 0x180014000 - 0x18001bfff r-- fmap.cache_map.1
EOF

View file

@ -1,8 +1,63 @@
NAME=Open LE cdogs.exe
FILE=bins/le/cdogs.exe
CMDS=iH~Signature[1]
CMDS=iH
EXPECT=<<EOF
LE
le:
signature: "LE"
le_offset: 0x2d98
byte_order: "little endian"
word_order: "little endian"
format_level: 0
module_name: "cdogs"
type: "Program module (EXE)"
cpu: "80386"
os: "OS/2"
arch: "x86"
version: 0
mflags: 0x200
flags:
- "PMWINAPI"
- "EXE"
mpages: 61
initial_eip_obj: 1
initial_eip: 0x16058
initial_stack_obj: 2
initial_esp: 0x26030
page_size: 0x1000
last_page_size: 0xd8c
fixup_size: 0xa14a
fixup_checksum: 0x0
loader_size: 0xa278
loader_checksum: 0x0
obj_table: 0xc4
obj_count: 2
obj_page_map: 0xf4
obj_iter_data_map: 0x0
resource_table: 0x1e8
resource_count: 0
resident_name_table: 0x1e8
entry_table: 0x1f1
directives_table: 0x0
directives_count: 0
fixup_page_table: 0x1f2
fixup_record_table: 0x2ea
import_module_name_table: 0xa33b
import_module_name_count: 0
import_procedure_name_table: 0xa33b
per_page_checksum_table: 0x0
enumerated_data_pages: 0xd200
number_of_preload_pages: 0
non_resident_names_table: 0x0
size_non_resident_names: 0
checksum_non_resident_names: 0x0
autodata_obj: 2
debug_info: 0x0
debug_length: 0x0
preload_pages: 0
demand_pages: 0
heap_size: 0x0
stack_size: 0x0
EOF
RUN
@ -166,9 +221,65 @@ RUN
NAME=Open LX GCC.EXE
FILE=bins/le/GCC.EXE
CMDS=iH~Signature[1]
CMDS=iH
EXPECT=<<EOF
LX
le:
signature: "LX"
le_offset: 0x600
byte_order: "little endian"
word_order: "little endian"
format_level: 0
module_name: "gcc"
type: "Program module (EXE)"
cpu: "80386"
os: "OS/2"
arch: "x86"
version: 0
mflags: 0x210
flags:
- "NOINTFIXUPS"
- "PMWINAPI"
- "EXE"
mpages: 16
initial_eip_obj: 1
initial_eip: 0x0
initial_stack_obj: 4
initial_esp: 0x800000
page_size: 0x1000
page_shift: 0xc
fixup_size: 0x9b
fixup_checksum: 0x0
loader_size: 0xe8
loader_checksum: 0x0
obj_table: 0xc4
obj_count: 4
obj_page_map: 0x124
obj_iter_data_map: 0x0
resource_table: 0x0
resource_count: 0
resident_name_table: 0x1a4
entry_table: 0x1ab
directives_table: 0x0
directives_count: 0
fixup_page_table: 0x1ac
fixup_record_table: 0x1f0
import_module_name_table: 0x239
import_module_name_count: 2
import_procedure_name_table: 0x246
per_page_checksum_table: 0x0
enumerated_data_pages: 0x1000
number_of_preload_pages: 0
non_resident_names_table: 0x0
size_non_resident_names: 0
checksum_non_resident_names: 0x0
autodata_obj: 2
debug_info: 0x0
debug_length: 0x0
preload_pages: 0
demand_pages: 1
heap_size: 0x0
stack_size: 0x0
EOF
RUN
@ -226,9 +337,63 @@ RUN
NAME=Open LX GNUGREP.DLL
FILE=bins/le/GNUGREP.DLL
CMDS=iH~Signature[1]
CMDS=iH
EXPECT=<<EOF
LX
le:
signature: "LX"
le_offset: 0x80
byte_order: "little endian"
word_order: "little endian"
format_level: 0
module_name: "GNUGREP"
type: "Library module (DLL)"
cpu: "80386"
os: "OS/2"
arch: "x86"
version: 131073
mflags: 0x8002
flags:
- "DLL"
mpages: 11
initial_eip_obj: 1
initial_eip: 0x0
initial_stack_obj: 0
initial_esp: 0x0
page_size: 0x1000
page_shift: 0x9
fixup_size: 0x10be
fixup_checksum: 0x0
loader_size: 0xcd
loader_checksum: 0x0
obj_table: 0xc4
obj_count: 4
obj_page_map: 0x124
obj_iter_data_map: 0x0
resource_table: 0x0
resource_count: 0
resident_name_table: 0x17c
entry_table: 0x187
directives_table: 0x0
directives_count: 0
fixup_page_table: 0x191
fixup_record_table: 0x1c1
import_module_name_table: 0x123a
import_module_name_count: 3
import_procedure_name_table: 0x124f
per_page_checksum_table: 0x0
enumerated_data_pages: 0x1400
number_of_preload_pages: 0
non_resident_names_table: 0x9800
size_non_resident_names: 38
checksum_non_resident_names: 0x0
autodata_obj: 4
debug_info: 0x0
debug_length: 0x0
preload_pages: 0
demand_pages: 1
heap_size: 0x0
stack_size: 0x0
EOF
RUN
@ -365,10 +530,65 @@ RUN
NAME=DOSEXT.EXE open extender binary
FILE=bins/le/DOSEXT.EXE
CMDS=iH~header offset
CMDS=iH
EXPECT=<<EOF
MZ header offset: 0x352a4
LE header offset: 0x3803c
le:
signature: "LE"
le_offset: 0x3803c
mz_offset: 0x352a4
byte_order: "little endian"
word_order: "little endian"
format_level: 0
module_name: "hello"
type: "Program module (EXE)"
cpu: "80386"
os: "OS/2"
arch: "x86"
version: 0
mflags: 0x200
flags:
- "PMWINAPI"
- "EXE"
mpages: 7
initial_eip_obj: 1
initial_eip: 0xc4
initial_stack_obj: 2
initial_esp: 0x1f30
page_size: 0x1000
last_page_size: 0x96e
fixup_size: 0xfbe
fixup_checksum: 0x0
loader_size: 0x56
loader_checksum: 0x0
obj_table: 0xc4
obj_count: 2
obj_page_map: 0xf4
obj_iter_data_map: 0x0
resource_table: 0x110
resource_count: 0
resident_name_table: 0x110
entry_table: 0x119
directives_table: 0x0
directives_count: 0
fixup_page_table: 0x11a
fixup_record_table: 0x13a
import_module_name_table: 0x10d7
import_module_name_count: 0
import_procedure_name_table: 0x10d7
per_page_checksum_table: 0x0
enumerated_data_pages: 0x4000
number_of_preload_pages: 0
non_resident_names_table: 0x0
size_non_resident_names: 0
checksum_non_resident_names: 0x0
autodata_obj: 2
debug_info: 0x0
debug_length: 0x0
preload_pages: 0
demand_pages: 0
heap_size: 0x0
stack_size: 0x1000
EOF
RUN

View file

@ -12,33 +12,41 @@ RUN
NAME=Xcode symbols cache (header)
FILE=bins/mach0/D9A37B67-F10A-35AA-A852-ABFBBECC03AE.symbols
CMDS=iH~{:
CMDS=iH
EXPECT=<<EOF
cs_version: 1
size: 7406
name: /Users/ftamagni/Library/Developer/Xcode/Archives/2020-05-12/TestRTTI 12-05-2020, 12.15.xcarchive/dSYMs/TestRTTI.app.dSYM/Contents/Resources/DWARF/TestRTTI
uuid: d9a37b67f10a35aaa852abfbbecc03ae
segments: 6
sections: 35
symbols: 67
lined_symbols: 0
line_info: 32
symbols:
cs_version: 1
size: 7406
binary:
name: "/Users/ftamagni/Library/Developer/Xcode/Archives/2020-05-12/TestRTTI 12-05-2020, 12.15.xcarchive/dSYMs/TestRTTI.app.dSYM/Contents/Resources/DWARF/TestRTTI"
version: ""
uuid: "d9a37b67f10a35aaa852abfbbecc03ae"
n_segments: 6
n_sections: 35
n_symbols: 67
n_lined_symbols: 0
n_line_info: 32
EOF
RUN
NAME=Xcode symbols cache new (header)
FILE=bins/mach0/D9A37B67-F10A-35AA-A852-ABFBBECC03AE-new.symbols
CMDS=iH~{:
CMDS=iH
EXPECT=<<EOF
cs_version: 1
size: 7231
name: /Users/ftamagni/Library/Developer/Xcode/Archives/2020-05-12/TestRTTI 12-05-2020, 12.15.xcarchive/dSYMs/TestRTTI.app.dSYM/Contents/Resources/DWARF/TestRTTI
uuid: d9a37b67f10a35aaa852abfbbecc03ae
segments: 6
sections: 35
symbols: 67
lined_symbols: 0
line_info: 32
symbols:
cs_version: 1
size: 7231
binary:
name: "/Users/ftamagni/Library/Developer/Xcode/Archives/2020-05-12/TestRTTI 12-05-2020, 12.15.xcarchive/dSYMs/TestRTTI.app.dSYM/Contents/Resources/DWARF/TestRTTI"
version: ""
uuid: "d9a37b67f10a35aaa852abfbbecc03ae"
n_segments: 6
n_sections: 35
n_symbols: 67
n_lined_symbols: 0
n_line_info: 32
EOF
RUN

View file

@ -5,5 +5,6 @@ EOF
EXPECT_ERR=<<EOF
ERROR: malformed uleb128
ERROR: malformed uleb128
ERROR: Invalid size for a load command
EOF
RUN

View file

@ -1,5 +1,6 @@
NAME=mach0 headers
FILE=bins/mach0/hello-osx-i386
BROKEN=1
CMDS=iH
EXPECT=<<EOF
pf.mach0_header @ 0x00001000
@ -65,6 +66,7 @@ RUN
NAME=mach0 headers big-endian
FILE=bins/mach0/ppc-ls
BROKEN=1
CMDS=iH
EXPECT=<<EOF
pf.mach0_header @ 0x00001000
@ -136,6 +138,7 @@ RUN
NAME=mach0 headers2
FILE=bins/mach0/ired
BROKEN=1
ARGS=-aarm -b32
CMDS=iH
EXPECT=<<EOF

View file

@ -4,79 +4,104 @@ CMDS=<<EOF
iH
EOF
EXPECT=<<EOF
==== MDT Segment 0 ====
priv_p_flags: 0b00000111: layout | ELF
-- ELF HEADER BEGIN --
0x00000000 MAGIC 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
0x00000010 Type 0x0002
0x00000012 Machine 0x00a4
0x00000014 Version 0x00000001
0x00000018 Entrypoint 0x87400000
0x0000001c PhOff 0x00000034
0x00000020 ShOff 0x00000000
0x00000024 Flags 0x0066
0x00000028 EhSize 52
0x0000002a PhentSize 32
0x0000002c PhNum 5
0x0000002e ShentSize 40
0x00000030 ShNum 0
0x00000032 ShStrndx 0
--- ELF HEADER END ---
==== MDT Segment 1 ====
priv_p_flags: 0b00000010: | MBN signature segment
-- MBN AUTH HEADER BEGIN --
0x00 image_id: kMbnImageNone (0x0)
0x04 version: 0x0
0x08 paddr: 0x0
0x0c vaddr: 0x0
0x10 psize: 0x0
0x14 code_pa: 0x0
0x18 sign_va: 0x0
0x1c sign_sz: 0x0
0x20 cert_va: 0x0
0x24 cert_sz: 0x0
--- MBN AUTH HEADER END ---
==== MDT Segment 2 ====
priv_p_flags: 0b00001000: reloc | Unidentified
==== MDT Segment 3 ====
priv_p_flags: 0b00001000: reloc | ELF
-- ELF HEADER BEGIN --
0x00000000 MAGIC 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
0x00000010 Type 0x0002
0x00000012 Machine 0x00a4
0x00000014 Version 0x00000001
0x00000018 Entrypoint 0x00000000
0x0000001c PhOff 0x00000034
0x00000020 ShOff 0x00011ee0
0x00000024 Flags 0x0060
0x00000028 EhSize 52
0x0000002a PhentSize 32
0x0000002c PhNum 3
0x0000002e ShentSize 40
0x00000030 ShNum 16
0x00000032 ShStrndx 13
--- ELF HEADER END ---
==== MDT Segment 4 ====
priv_p_flags: 0b00001000: reloc | ELF
-- ELF HEADER BEGIN --
0x00000000 MAGIC 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
0x00000010 Type 0x0001
0x00000012 Machine 0x00a4
0x00000014 Version 0x00000001
0x00000018 Entrypoint 0x00000000
0x0000001c PhOff 0x00000000
0x00000020 ShOff 0x000004ec
0x00000024 Flags 0x0060
0x00000028 EhSize 52
0x0000002a PhentSize 0
0x0000002c PhNum 0
0x0000002e ShentSize 40
0x00000030 ShNum 5
0x00000032 ShStrndx 1
--- ELF HEADER END ---
mdt_segments:
- priv_p_flags: "0b00000111"
is_layout: true
is_relocatable: false
format: "elf binary"
content:
elf:
e_ident:
bytes: "7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00"
ei_class: 1
ei_data: 1
ei_version: 1
ei_osabi: 0
ei_abiversion: 0
e_machine: 164
e_version: 1
e_entry: 0x87400000
e_phoff: 0x34
e_shoff: 0x0
e_flags: 0x66
e_ehsize: 52
e_phentsize: 32
e_phnum: 5
e_shentsize: 40
e_shnum: 0
e_shstrndx: 0
- priv_p_flags: "0b00000010"
is_layout: false
is_relocatable: false
format: "mbn signature"
content:
mbn:
image:
name: "kMbnImageNone"
id: 0x0
version: 0x0
paddr: 0x0
vaddr: 0x0
psize: 0x0
code_pa: 0x0
sign_va: 0x0
sign_sz: 0x0
cert_va: 0x0
cert_sz: 0x0
- priv_p_flags: "0b00001000"
is_layout: false
is_relocatable: true
format: "unidentified"
- priv_p_flags: "0b00001000"
is_layout: false
is_relocatable: true
format: "elf binary"
content:
elf:
e_ident:
bytes: "7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00"
ei_class: 1
ei_data: 1
ei_version: 1
ei_osabi: 0
ei_abiversion: 0
e_machine: 164
e_version: 1
e_entry: 0x0
e_phoff: 0x34
e_shoff: 0x11ee0
e_flags: 0x60
e_ehsize: 52
e_phentsize: 32
e_phnum: 3
e_shentsize: 40
e_shnum: 16
e_shstrndx: 13
- priv_p_flags: "0b00001000"
is_layout: false
is_relocatable: true
format: "elf binary"
content:
elf:
e_ident:
bytes: "7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00"
ei_class: 1
ei_data: 1
ei_version: 1
ei_osabi: 0
ei_abiversion: 0
e_machine: 164
e_version: 1
e_entry: 0x0
e_phoff: 0x0
e_shoff: 0x4ec
e_flags: 0x60
e_ehsize: 52
e_phentsize: 0
e_phnum: 0
e_shentsize: 40
e_shnum: 5
e_shstrndx: 1
EOF
RUN

View file

@ -1,8 +1,25 @@
NAME=MZ: blocks.exe - open
NAME=MZ: blocks.exe - open & header
FILE=bins/mz/blocks.exe
ARGS=-A
CMDS=q!
EXPECT=
CMDS=iH
EXPECT=<<EOF
mz:
Signature: "MZ"
BytesInLastBlock: 0xcd
BlocksInFile: 0x1d
NumRelocs: 1
HeaderParagraphs: 0x7
MinExtraParagraphs: 0x835
MaxExtraParagraphs: 0xffff
InitialSs: 0x38d
InitialSp: 0x200
Checksum: 0x0
InitialIp: 0x100
InitialCs: 0xfff0
RelocTableOffset: 0x52
OverlayNumber: 0
EOF
RUN
NAME=MZ: blocks.exe - entrypoint

View file

@ -1061,3 +1061,43 @@ EXPECT=<<EOF
0x0000d544 0x0000d544 POI_32_IMPORTED_ORD GDI.SETDIBITSTODEVICE
EOF
RUN
NAME=NE header
FILE=bins/ne/anim8.exe
CMDS=iH
EXPECT=<<EOF
ne:
MajLinkerVersion: 5
MinLinkerVersion: 10
EntryTableOffset: 0x3c4
EntryTableLength: 16
FileLoadCRC: 0x0
ProgFlags: 0xa
ApplFlags: 0x3
AutoDataSegIndex: 2
InitHeapSize: 1024
InitStackSize: 30000
EntryPointCSIndex: 1
EntryPointIPOff: 0x0
InitStack: 0x20000
SegCount: 2
ModuleRefsCount: 4
NonResNamesTblSiz: 0x9
SegTableOffset: 0x40
ResourceTblOff: 0x50
ResidentNameTblOff: 0x383
ModuleRefTblOff: 0x3a3
ImportNameTblOff: 0x3ab
OffStartNonResTab: 1572
MovEntryCount: 2
FileAlnSzShftCnt: 9
nResTabEntries: 0
OS: "Windows"
OS2EXEFlags: 0x8
retThunkOffset: 0x4
segRefThunksOff: 0x58
mincodeswap: 0
winver: "3.0"
EOF
RUN

View file

@ -97,77 +97,102 @@ nth paddr vaddr bind type size lib name
1 0x00000e44 0x00402044 NONE FUNC 0 api-ms-win-crt-math-l1-1-0.dll imp.__setusermatherr
1 0x00000e3c 0x0040203c NONE FUNC 0 api-ms-win-crt-locale-l1-1-0.dll imp._configthreadlocale
1 0x00000e34 0x00402034 NONE FUNC 0 api-ms-win-crt-heap-l1-1-0.dll imp._set_new_mode
PE file header:
IMAGE_NT_HEADERS
Signature : 0x4550
IMAGE_FILE_HEADERS
Machine : 0x1c4
NumberOfSections : 0x5
TimeDateStamp : 0x61149c1c
PointerToSymbolTable : 0x0
NumberOfSymbols : 0x0
SizeOfOptionalHeader : 0xe0
Characteristics : 0x122
IMAGE_OPTIONAL_HEADERS
Magic : 0x10b
MajorLinkerVersion : 0xe
MinorLinkerVersion : 0x1d
SizeOfCode : 0xa00
SizeOfInitializedData : 0x1000
SizeOfUninitializedData : 0x0
AddressOfEntryPoint : 0x11d5
BaseOfCode : 0x1000
BaseOfData : 0x2000
ImageBase : 0x400000
SectionAlignment : 0x1000
FileAlignment : 0x200
MajorOperatingSystemVersion : 0x6
MinorOperatingSystemVersion : 0x2
MajorImageVersion : 0x0
MinorImageVersion : 0x0
MajorSubsystemVersion : 0x6
MinorSubsystemVersion : 0x2
Win32VersionValue : 0x0
SizeOfImage : 0x6000
SizeOfHeaders : 0x400
CheckSum : 0x0
Subsystem : 0x3
DllCharacteristics : 0x8140
SizeOfStackReserve : 0x100000
SizeOfStackCommit : 0x1000
SizeOfHeapReserve : 0x100000
SizeOfHeapCommit : 0x1000
LoaderFlags : 0x0
NumberOfRvaAndSizes : 0x10
RICH_FIELDS
Product: 258 Name: Linker1400 Version: 30133 Times: 1
Product: 260 Name: Utc1900_C Version: 30133 Times: 1
Product: 260 Name: Utc1900_C Version: 30034 Times: 9
Product: 261 Name: Utc1900_CPP Version: 30034 Times: 17
Product: 1 Name: Import0 Version: 0 Times: 41
Product: 257 Name: Implib1400 Version: 27412 Times: 3
Product: 257 Name: Implib1400 Version: 30034 Times: 2
Product: 147 Name: Implib900 Version: 30729 Times: 10
IMAGE_DIRECTORY_ENTRY_IMPORT
VirtualAddress : 0x2494
Size : 0xa0
IMAGE_DIRECTORY_ENTRY_EXCEPTION
VirtualAddress : 0x4000
Size : 0x120
IMAGE_DIRECTORY_ENTRY_BASERELOC
VirtualAddress : 0x5000
Size : 0xac
IMAGE_DIRECTORY_ENTRY_DEBUG
VirtualAddress : 0x20e8
Size : 0x1c
IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG
VirtualAddress : 0x2108
Size : 0xbc
IMAGE_DIRECTORY_ENTRY_IAT
VirtualAddress : 0x2000
Size : 0xa8
IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT
VirtualAddress : 0x0
Size : 0xffff
pe32:
IMAGE_NT_HEADERS:
Signature: 0x4550
IMAGE_FILE_HEADERS:
Machine: 0x1c4
NumberOfSections: 5
TimeDateStamp: 1628740636
PointerToSymbolTable: 0x0
NumberOfSymbols: 0
SizeOfOptionalHeader: 224
Characteristics: 0x122
IMAGE_OPTIONAL_HEADERS:
Magic: 0x10b
MajorLinkerVersion: 14
MinorLinkerVersion: 29
SizeOfCode: 2560
SizeOfInitializedData: 4096
SizeOfUninitializedData: 0
AddressOfEntryPoint: 0x11d5
BaseOfCode: 0x1000
BaseOfData: 0x2000
ImageBase: 0x400000
SectionAlignment: 0x1000
FileAlignment: 0x200
MajorOperatingSystemVersion: 0x6
MinorOperatingSystemVersion: 0x2
MajorImageVersion: 0x0
MinorImageVersion: 0x0
MajorSubsystemVersion: 0x6
MinorSubsystemVersion: 0x2
Win32VersionValue: 0x0
SizeOfImage: 24576
SizeOfHeaders: 1024
CheckSum: 0x0
Subsystem: 0x3
DllCharacteristics: 0x8140
SizeOfStackReserve: 1048576
SizeOfStackCommit: 4096
SizeOfHeapReserve: 1048576
SizeOfHeapCommit: 4096
LoaderFlags: 0x0
NumberOfRvaAndSizes: 16
RICH_FIELDS:
- Product: 258
Name: "Linker1400"
Version: 30133
Times: 1
- Product: 260
Name: "Utc1900_C"
Version: 30133
Times: 1
- Product: 260
Name: "Utc1900_C"
Version: 30034
Times: 9
- Product: 261
Name: "Utc1900_CPP"
Version: 30034
Times: 17
- Product: 1
Name: "Import0"
Version: 0
Times: 41
- Product: 257
Name: "Implib1400"
Version: 27412
Times: 3
- Product: 257
Name: "Implib1400"
Version: 30034
Times: 2
- Product: 147
Name: "Implib900"
Version: 30729
Times: 10
IMAGE_DIRECTORY_ENTRY_IMPORT:
VirtualAddress: 0x2494
Size: 160
IMAGE_DIRECTORY_ENTRY_EXCEPTION:
VirtualAddress: 0x4000
Size: 288
IMAGE_DIRECTORY_ENTRY_BASERELOC:
VirtualAddress: 0x5000
Size: 172
IMAGE_DIRECTORY_ENTRY_DEBUG:
VirtualAddress: 0x20e8
Size: 28
IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG:
VirtualAddress: 0x2108
Size: 188
IMAGE_DIRECTORY_ENTRY_IAT:
VirtualAddress: 0x2000
Size: 168
IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT:
VirtualAddress: 0x0
Size: 65535
EOF
RUN

View file

@ -1578,9 +1578,88 @@ RUN
NAME=pe32 header
FILE=bins/pe/single_import.exe
CMDS=iH~Signature~0x4550?
CMDS=iH
EXPECT=<<EOF
1
pe32:
IMAGE_NT_HEADERS:
Signature: 0x4550
IMAGE_FILE_HEADERS:
Machine: 0x14c
NumberOfSections: 2
TimeDateStamp: 1264260641
PointerToSymbolTable: 0x0
NumberOfSymbols: 0
SizeOfOptionalHeader: 224
Characteristics: 0x103
IMAGE_OPTIONAL_HEADERS:
Magic: 0x10b
MajorLinkerVersion: 9
MinorLinkerVersion: 0
SizeOfCode: 76800
SizeOfInitializedData: 1536
SizeOfUninitializedData: 0
AddressOfEntryPoint: 0x13bc8
BaseOfCode: 0x1000
BaseOfData: 0x14000
ImageBase: 0x400000
SectionAlignment: 0x1000
FileAlignment: 0x200
MajorOperatingSystemVersion: 0x5
MinorOperatingSystemVersion: 0x0
MajorImageVersion: 0x0
MinorImageVersion: 0x0
MajorSubsystemVersion: 0x5
MinorSubsystemVersion: 0x0
Win32VersionValue: 0x0
SizeOfImage: 90112
SizeOfHeaders: 1024
CheckSum: 0x0
Subsystem: 0x2
DllCharacteristics: 0x8000
SizeOfStackReserve: 1048576
SizeOfStackCommit: 4096
SizeOfHeapReserve: 1048576
SizeOfHeapCommit: 4096
LoaderFlags: 0x0
NumberOfRvaAndSizes: 16
RICH_FIELDS:
- Product: 145
Name: "Linker900"
Version: 30729
Times: 1
- Product: 148
Name: "Cvtres900"
Version: 30729
Times: 1
- Product: 149
Name: "Masm900"
Version: 30729
Times: 1
- Product: 138
Name: "Utc1500_LTCG_CPP"
Version: 30729
Times: 1
- Product: 1
Name: "Import0"
Version: 0
Times: 1
- Product: 93
Name: "Implib710"
Version: 4035
Times: 3
IMAGE_DIRECTORY_ENTRY_IMPORT:
VirtualAddress: 0x14008
Size: 40
IMAGE_DIRECTORY_ENTRY_RESOURCE:
VirtualAddress: 0x15000
Size: 992
IMAGE_DIRECTORY_ENTRY_IAT:
VirtualAddress: 0x14000
Size: 8
IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT:
VirtualAddress: 0x0
Size: 65535
EOF
RUN

View file

@ -10,9 +10,56 @@ RUN
NAME=pe64 header
FILE=bins/pe/tls64.exe
CMDS=iH~Signature~0x4550?
CMDS=iH
EXPECT=<<EOF
1
pe64:
IMAGE_NT_HEADERS:
Signature: 0x4550
IMAGE_FILE_HEADERS:
Machine: 0x8664
NumberOfSections: 1
TimeDateStamp: 0
PointerToSymbolTable: 0x0
NumberOfSymbols: 0
SizeOfOptionalHeader: 240
Characteristics: 0x102
IMAGE_OPTIONAL_HEADERS:
Magic: 0x20b
MajorLinkerVersion: 0
MinorLinkerVersion: 0
SizeOfCode: 0
SizeOfInitializedData: 0
SizeOfUninitializedData: 0
AddressOfEntryPoint: 0x1015
BaseOfCode: 0x0
ImageBase: 0x400000
SectionAlignment: 0x1000
FileAlignment: 0x200
MajorOperatingSystemVersion: 0x0
MinorOperatingSystemVersion: 0x0
MajorImageVersion: 0x0
MinorImageVersion: 0x0
MajorSubsystemVersion: 0x4
MinorSubsystemVersion: 0x0
Win32VersionValue: 0x0
SizeOfImage: 8192
SizeOfHeaders: 368
CheckSum: 0x0
Subsystem: 0x3
DllCharacteristics: 0x0
SizeOfStackReserve: 0
SizeOfStackCommit: 0
SizeOfHeapReserve: 0
SizeOfHeapCommit: 0
LoaderFlags: 0x0
NumberOfRvaAndSizes: 16
IMAGE_DIRECTORY_ENTRY_IMPORT:
VirtualAddress: 0x1070
Size: 65535
IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT:
VirtualAddress: 0x0
Size: 65535
EOF
RUN

View file

@ -56,20 +56,27 @@ NAME=get header info
FILE=bins/qnx/test.x
CMDS=iH
EXPECT=<<EOF
QNX file header:
version : 0x190H
cflags : 0x16H
cpu : 0x182H
fpu : 0x0H
code_index : 0x0H
stack_index : 0x1H
heap_index : 0x1H
argv_index : 0x1H
spare2[4] : 0x0H
code_offset : 0x21cH
stack_nbytes : 0x8000H
heap_nbytes : 0x1000H
image_base : 0xa000H
spare3[2] : 0x0H
qnx_lmf:
version: 400
cflags: 0x16
cpu: 386
fpu: 0
code_index: 0
stack_index: 1
heap_index: 1
argv_index: 1
spare2:
- 0x0
- 0x0
- 0x0
- 0x0
code_offset: 0x21c
stack_nbytes: 0x8000
heap_nbytes: 0x1000
image_base: 0xa000
spare3:
- 0x0
- 0x0
EOF
RUN

View file

@ -43,30 +43,36 @@ canary false
PIE false
RELROCS false
NX false
ROM Game Title: SA-1 Support Test
ROM Speed: Slow
ROM Map Mode: LoROM 32K Banks + SA-1 (LoROM Emulates Super MMC) (0x03)
ROM Cartridge: ROM+RAM+Battery+SA-1 (0x35)
ROM Size: 512 KB (0x09)
ROM SRAM: 32 KB (0x05)
ROM Country: Japan (NTSC) (0x00)
ROM Developer: Unknown (0x33)
ROM Version: 0x01
ROM Checksum: 0xffff (complement: 0x0000)
ROM unused: 0x00000000
ROM cop: 0x8347 (native vector)
ROM br: 0x8347 (native vector)
ROM abort: 0x8347 (native vector)
ROM nmi: 0x0a00 (native vector)
ROM unused: 0x8347 (native vector)
ROM irq: 0x8347 (native vector)
ROM unused: 0x00000000
ROM cop: 0x8347 (emulator vector)
ROM unused: 0x8347 (emulator vector)
ROM abort: 0x8347 (emulator vector)
ROM nmi: 0x8347 (emulator vector)
ROM reset: 0x8000 (emulator vector)
ROM irq: 0x8347 (emulator vector)
snes_rom:
game_title: "SA-1 Support Test "
speed: "slow"
map_mode: "LoROM 32K Banks + SA-1 (LoROM Emulates Super MMC)"
cartridge: "ROM+RAM+Battery+SA-1"
size: "512 KB"
sram_size: "32 KB"
country: "Japan (NTSC)"
developer: "unknown 0x33"
version: 0x1
checksum: 0xffff
checksum_compl: 0x0
vectors:
native:
unused0: 0x0
cop: 0x8347
br: 0x8347
abort: 0x8347
nmi: 0xa00
unused1: 0x8347
irq: 0x8347
emulator:
unused2: 0x0
cop: 0x8347
unused3: 0x8347
abort: 0x8347
nmi: 0x8347
reset: 0x8000
irq: 0x8347
name size address flags mirror
---------------------------------------------
SRAM_70 0x10000 0x00700000 rwx
@ -656,29 +662,34 @@ canary false
PIE false
RELROCS false
NX false
ROM Game Title: CX4 TEST PROGRAM
ROM Speed: Slow
ROM Map Mode: LoROM 32K Banks (LoROM) (0x00)
ROM Cartridge: ROM+CX4 (0xf3)
ROM Size: 32 KB (0x05)
ROM SRAM: missing (0x00)
ROM Country: Japan (NTSC) (0x00)
ROM Developer: Unknown (0x33)
ROM Version: 0x00
ROM Checksum: 0xaf96 (complement: 0x5069)
ROM unused: 0x00000000
ROM cop: 0x8333 (native vector)
ROM br: 0x8333 (native vector)
ROM abort: 0x8333 (native vector)
ROM nmi: 0x8333 (native vector)
ROM unused: 0x0000 (native vector)
ROM irq: 0x8333 (native vector)
ROM unused: 0x00000000
ROM cop: 0x8333 (emulator vector)
ROM unused: 0x0000 (emulator vector)
ROM abort: 0x8333 (emulator vector)
ROM nmi: 0x8333 (emulator vector)
ROM reset: 0x8000 (emulator vector)
ROM irq: 0x8333 (emulator vector)
snes_rom:
game_title: "CX4 TEST PROGRAM"
speed: "slow"
map_mode: "LoROM 32K Banks (LoROM)"
cartridge: "ROM+CX4"
size: "32 KB"
country: "Japan (NTSC)"
developer: "unknown 0x33"
version: 0x0
checksum: 0xaf96
checksum_compl: 0x5069
vectors:
native:
unused0: 0x0
cop: 0x8333
br: 0x8333
abort: 0x8333
nmi: 0x8333
unused1: 0x0
irq: 0x8333
emulator:
unused2: 0x0
cop: 0x8333
unused3: 0x0
abort: 0x8333
nmi: 0x8333
reset: 0x8000
irq: 0x8333
EOF
RUN

View file

@ -2,21 +2,24 @@ NAME=SMS: Open/iI
FILE=bins/sms/demo.sms
CMDS=iH;iI
EXPECT=<<EOF
ROM Offset: 0x00007ff0
ROM Reserved0: 255 (0xff)
ROM Reserved1: 255 (0xff)
ROM Checksum: 0x0000
ROM Product Code: 000000
ROM Version: 0
ROM Console:
ROM Region: Unknown
ROM Size: 256KB
SDSC Offset: 0x00007fe0
SDSC Version: 01.00
SDSC Date: 2001-07-30
SDSC Author:
SDSC Name: 64-Color Palette Test Program
SDSC Description: Author: Charles MacDonald
sms_rom:
offset: 0x7ff0
reserved0: 255
reserved1: 255
checksum: 0x0
product_code: "000000"
version: 0
console: ""
region: "Unknown"
size_kb: 256
sdsc:
offset: 0x7fe0
version: "01.00\n"
date: "2001-07-30\n"
author: ""
name: "64-Color Palette Test Program"
description: "Author: Charles MacDonald"
arch z80
cpu N/A
features N/A
@ -69,15 +72,17 @@ NAME=SMS: maps
FILE=bins/sms/colorcheck.sms
CMDS=iH;iI
EXPECT=<<EOF
ROM Offset: 0x00007ff0
ROM Reserved0: 0 (0x00)
ROM Reserved1: 0 (0x00)
ROM Checksum: 0x5e2a
ROM Product Code: 000000
ROM Version: 0
ROM Console:
ROM Region: Unknown
ROM Size: 256KB
sms_rom:
offset: 0x7ff0
reserved0: 0
reserved1: 0
checksum: 0x5e2a
product_code: "000000"
version: 0
console: ""
region: "Unknown"
size_kb: 256
arch z80
cpu N/A
features N/A

View file

@ -81,22 +81,24 @@ name size address flags mirror
paddr vaddr len size section type string
-----------------------------------------
ROM Reserved0: 0x80
ROM Release Timing (PI_BSD_DOM1_RLS): 0x03
ROM Page Size (PI_BSD_DOM1_PGS): 0x07
ROM Pulse Width (PI_BSD_DOM1_PWD): 0x12
ROM Latency (PI_BSD_DOM1_LAT): 0x40
ROM Clock rate: 0x03b9aca0
ROM Boot Address: 0x80001000
ROM Libultra Version: 2.0D
ROM Check Code: 0x877efaee94e765a8
ROM Reserved1: 0x0000000000000000
ROM Game Title: shut up and code
ROM Reserved2: 0x00000000000000
ROM Game Category: Unset
ROM Game Unique Code: ..
ROM Game Destination: Unset
ROM Version: 0
n64_rom:
reserved_0: 0x80
PI_BSD_DOM1_RLS: 0x3
PI_BSD_DOM1_PGS: 0x7
PI_BSD_DOM1_PWD: 0x12
PI_BSD_DOM1_LAT: 0x40
clock_rate: 0x3b9aca0
boot_address: 0x80001000
libultra_version: "2.0D"
check_code: 0x877efaee94e765a8
reserved_1: "0000000000000000"
game_title: "shut up and code "
reserved_2: "00000000000000"
game_category: "Unset"
game_unique_code: ".."
game_destination: "Unset"
version: 0
1 fd: 3 +0x00000000 0x04000000 * 0x04000fff r-x fmap.ipl3
2 fd: 3 +0x00001000 0x80001000 - 0x8013ffff r-x fmap.text
EOF
@ -106,29 +108,37 @@ NAME=Nintendo 64 Advanced Homebrew Transfer Pak
FILE=bins/z64/PokeMe64.z64
CMDS=iH
EXPECT=<<EOF
ROM Reserved0: 0x80
ROM Release Timing (PI_BSD_DOM1_RLS): 0x03
ROM Page Size (PI_BSD_DOM1_PGS): 0x07
ROM Pulse Width (PI_BSD_DOM1_PWD): 0x12
ROM Latency (PI_BSD_DOM1_LAT): 0x40
ROM Clock rate: 0x03b9aca0
ROM Boot Address: 0x80000400
ROM Libultra Version: 0.0
ROM Check Code: 0x0000000000000000
ROM Reserved1: 0x0000000000000000
ROM Game Title: PokeMe64
ROM Reserved2: 0x03000000000000
ROM Game Category: Homebrew
ROM Game Unique Code: ED
ROM Game Destination: Region Free
ROM Version: 2
HB Controller 1: Transfer Pak (0x03)
HB Controller 2: Not Used (0x00)
HB Controller 3: Not Used (0x00)
HB Controller 4: Not Used (0x00)
HB Enable RTC: no
HB Region Free: yes
HB Savetype Size:
n64_rom:
reserved_0: 0x80
PI_BSD_DOM1_RLS: 0x3
PI_BSD_DOM1_PGS: 0x7
PI_BSD_DOM1_PWD: 0x12
PI_BSD_DOM1_LAT: 0x40
clock_rate: 0x3b9aca0
boot_address: 0x80000400
libultra_version: "0.0"
check_code: 0x0
reserved_1: "0000000000000000"
game_title: "PokeMe64"
reserved_2: "03000000000000"
game_category: "Homebrew"
game_unique_code: "ED"
game_destination: "Region Free"
version: 2
homebrew:
controllers:
- description: "Transfer Pak"
value: 0x3
- description: "Not Used"
value: 0x0
- description: "Not Used"
value: 0x0
- description: "Not Used"
value: 0x0
enable_rtc: false
region_free: true
savetype_size: ""
EOF
RUN
@ -136,29 +146,37 @@ NAME=Nintendo 64 Advanced Homebrew 1M SRAM
FILE=bins/z64/omnispeak64_ep4.z64
CMDS=iH
EXPECT=<<EOF
ROM Reserved0: 0x80
ROM Release Timing (PI_BSD_DOM1_RLS): 0x03
ROM Page Size (PI_BSD_DOM1_PGS): 0x07
ROM Pulse Width (PI_BSD_DOM1_PWD): 0x12
ROM Latency (PI_BSD_DOM1_LAT): 0x40
ROM Clock rate: 0x03b9aca0
ROM Boot Address: 0x80000400
ROM Libultra Version: 0.0
ROM Check Code: 0x0000000000000000
ROM Reserved1: 0x0000000000000000
ROM Game Title: Made with libdragon
ROM Reserved2: 0x00000000000000
ROM Game Category: Homebrew
ROM Game Unique Code: ED
ROM Game Destination: Region Free
ROM Version: 98
HB Controller 1: Not Used (0x00)
HB Controller 2: Not Used (0x00)
HB Controller 3: Not Used (0x00)
HB Controller 4: Not Used (0x00)
HB Enable RTC: no
HB Region Free: yes
HB Savetype Size: 1M SRAM
n64_rom:
reserved_0: 0x80
PI_BSD_DOM1_RLS: 0x3
PI_BSD_DOM1_PGS: 0x7
PI_BSD_DOM1_PWD: 0x12
PI_BSD_DOM1_LAT: 0x40
clock_rate: 0x3b9aca0
boot_address: 0x80000400
libultra_version: "0.0"
check_code: 0x0
reserved_1: "0000000000000000"
game_title: "Made with libdragon"
reserved_2: "00000000000000"
game_category: "Homebrew"
game_unique_code: "ED"
game_destination: "Region Free"
version: 98
homebrew:
controllers:
- description: "Not Used"
value: 0x0
- description: "Not Used"
value: 0x0
- description: "Not Used"
value: 0x0
- description: "Not Used"
value: 0x0
enable_rtc: false
region_free: true
savetype_size: "1M SRAM"
EOF
RUN
@ -166,28 +184,36 @@ NAME=Nintendo 64 Advanced Homebrew 256K SRAM
FILE=bins/z64/cosmo64_ep1.z64
CMDS=iH
EXPECT=<<EOF
ROM Reserved0: 0x80
ROM Release Timing (PI_BSD_DOM1_RLS): 0x03
ROM Page Size (PI_BSD_DOM1_PGS): 0x07
ROM Pulse Width (PI_BSD_DOM1_PWD): 0x12
ROM Latency (PI_BSD_DOM1_LAT): 0x40
ROM Clock rate: 0x03b9aca0
ROM Boot Address: 0x80000400
ROM Libultra Version: 2.0D
ROM Check Code: 0x7fe520a3473b1fb4
ROM Reserved1: 0x0000000000000000
ROM Game Title: cosmo64_ep1
ROM Reserved2: 0x00000000000000
ROM Game Category: Homebrew
ROM Game Unique Code: ED
ROM Game Destination: Region Free
ROM Version: 50
HB Controller 1: Not Used (0x00)
HB Controller 2: Not Used (0x00)
HB Controller 3: Not Used (0x00)
HB Controller 4: Not Used (0x00)
HB Enable RTC: no
HB Region Free: yes
HB Savetype Size: 256K SRAM
n64_rom:
reserved_0: 0x80
PI_BSD_DOM1_RLS: 0x3
PI_BSD_DOM1_PGS: 0x7
PI_BSD_DOM1_PWD: 0x12
PI_BSD_DOM1_LAT: 0x40
clock_rate: 0x3b9aca0
boot_address: 0x80000400
libultra_version: "2.0D"
check_code: 0x7fe520a3473b1fb4
reserved_1: "0000000000000000"
game_title: "cosmo64_ep1"
reserved_2: "00000000000000"
game_category: "Homebrew"
game_unique_code: "ED"
game_destination: "Region Free"
version: 50
homebrew:
controllers:
- description: "Not Used"
value: 0x0
- description: "Not Used"
value: 0x0
- description: "Not Used"
value: 0x0
- description: "Not Used"
value: 0x0
enable_rtc: false
region_free: true
savetype_size: "256K SRAM"
EOF
RUN