Skip to content

Commit

Permalink
Use RzCmdStateOutput instead of RzOutputMode to solve invalid JSO…
Browse files Browse the repository at this point in the history
…N issue
  • Loading branch information
Basstorm committed Oct 7, 2021
1 parent 4671965 commit 3925afb
Show file tree
Hide file tree
Showing 8 changed files with 322 additions and 300 deletions.
117 changes: 78 additions & 39 deletions librz/bin/pdb/pdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,12 @@ static char *pdb_type_as_string_regular(const RzTypeDB *db, const RzPdb *pdb, co
return str;
}

static char *pdb_type_as_string_json(const RzTypeDB *db, const RzPdb *pdb, const RzList *types) {
rz_return_val_if_fail(db && pdb && types, NULL);

static char *pdb_type_as_string_json(const RzTypeDB *db, const RzPdb *pdb, const RzList *types, PJ *pj) {
rz_return_val_if_fail(db && pdb && types && pj, NULL);
RzListIter *it;
RzBaseType *type;
PJ *pj = pj_new();
if (!pj) {
return NULL;
}
pj_a(pj);
pj_o(pj);
pj_ka(pj, "types");
rz_list_foreach (types, it, type) {
switch (type->kind) {
case RZ_BASE_TYPE_KIND_STRUCT: {
Expand Down Expand Up @@ -101,30 +97,29 @@ static char *pdb_type_as_string_json(const RzTypeDB *db, const RzPdb *pdb, const
}
}
pj_end(pj);
char *str = strdup(pj_string(pj));
pj_free(pj);
return str;
pj_end(pj);
return NULL;
}

/**
* \brief return the output text for types in PDB
* \param db RzTypeDB
* \param pdb PDB instance
* \param mode printing mode
* \param state output state
* \return string of pdb types
*/
RZ_API RZ_OWN char *rz_bin_pdb_types_as_string(RZ_NONNULL const RzTypeDB *db, RZ_NONNULL const RzPdb *pdb, const RzOutputMode mode) {
rz_return_val_if_fail(db && pdb, NULL);
RZ_API RZ_OWN char *rz_bin_pdb_types_as_string(RZ_NONNULL const RzTypeDB *db, RZ_NONNULL const RzPdb *pdb, const RzCmdStateOutput *state) {
rz_return_val_if_fail(db && pdb && state, NULL);
TpiStream *stream = pdb->s_tpi;
if (!stream) {
eprintf("There is no tpi stream in current pdb\n");
return NULL;
}
switch (mode) {
switch (state->mode) {
case RZ_OUTPUT_MODE_STANDARD:
return pdb_type_as_string_regular(db, pdb, stream->print_type);
case RZ_OUTPUT_MODE_JSON:
return pdb_type_as_string_json(db, pdb, stream->print_type);
return pdb_type_as_string_json(db, pdb, stream->print_type, state->d.pj);
default:
return NULL;
}
Expand All @@ -135,30 +130,30 @@ RZ_API RZ_OWN char *rz_bin_pdb_types_as_string(RZ_NONNULL const RzTypeDB *db, RZ
*
* \param pdb PDB instance
* \param img_base image base addr
* \param mode print mode
* \param state output state
* \return string of pdb symbols
*/
RZ_API RZ_OWN char *rz_bin_pdb_gvars_as_string(RZ_NONNULL const RzPdb *pdb, const ut64 img_base, RzOutputMode mode) {
rz_return_val_if_fail(pdb, NULL);
RZ_API RZ_OWN char *rz_bin_pdb_gvars_as_string(RZ_NONNULL const RzPdb *pdb, const ut64 img_base, const RzCmdStateOutput *state) {
rz_return_val_if_fail(pdb && state, NULL);
PeImageSectionHeader *sctn_header = 0;
GDataStream *gsym_data_stream = 0;
PeStream *pe_stream = 0;
OmapStream *omap_stream;
GDataGlobal *gdata = 0;
RzListIter *it = 0;
PJ *pj = NULL;
PJ *pj = state->d.pj;
char *name;
char *filtered_name;
RzStrBuf *buf = rz_strbuf_new(NULL);
if (!buf) {
return NULL;
}
if (mode == RZ_OUTPUT_MODE_JSON) {
pj = pj_new();
if (!pj) {
rz_strbuf_free(buf);
return NULL;
}
RzStrBuf *cmd = rz_strbuf_new(NULL);
if (!cmd) {
rz_strbuf_free(buf);
return NULL;
}
if (state->mode == RZ_OUTPUT_MODE_JSON) {
pj_o(pj);
pj_ka(pj, "gvars");
}
Expand All @@ -174,7 +169,7 @@ RZ_API RZ_OWN char *rz_bin_pdb_gvars_as_string(RZ_NONNULL const RzPdb *pdb, cons
if (sctn_header) {
name = rz_demangler_msvc(gdata->name);
name = (name) ? name : strdup(gdata->name);
switch (mode) {
switch (state->mode) {
case RZ_OUTPUT_MODE_JSON: // JSON
pj_o(pj);
pj_kN(pj, "address", (img_base + omap_remap(omap_stream, gdata->offset + sctn_header->virtual_address)));
Expand All @@ -188,32 +183,76 @@ RZ_API RZ_OWN char *rz_bin_pdb_gvars_as_string(RZ_NONNULL const RzPdb *pdb, cons
(ut64)(img_base + omap_remap(omap_stream, gdata->offset + sctn_header->virtual_address)),
gdata->symtype, PDB_SIZEOF_SECTION_NAME, sctn_header->name, name);
break;
case RZ_OUTPUT_MODE_RIZIN:
filtered_name = rz_name_filter2(name, true);
rz_strbuf_appendf(buf, "f pdb.%s = 0x%" PFMT64x " # %d %.*s\n",
filtered_name,
(ut64)(img_base + omap_remap(omap_stream, gdata->offset + sctn_header->virtual_address)),
gdata->symtype, PDB_SIZEOF_SECTION_NAME, sctn_header->name);
rz_strbuf_appendf(buf, "\"fN pdb.%s %s\"\n", filtered_name, name);
free(filtered_name);
break;
default:
break;
}
filtered_name = rz_name_filter2(name, true);
rz_strbuf_appendf(cmd, "f pdb.%s = 0x%" PFMT64x " # %d %.*s\n",
filtered_name,
(ut64)(img_base + omap_remap(omap_stream, gdata->offset + sctn_header->virtual_address)),
gdata->symtype, PDB_SIZEOF_SECTION_NAME, sctn_header->name);
rz_strbuf_appendf(cmd, "\"fN pdb.%s %s\"\n", filtered_name, name);
free(filtered_name);
free(name);
}
}
if (mode == RZ_OUTPUT_MODE_JSON) {
if (state->mode == RZ_OUTPUT_MODE_JSON) {
pj_end(pj);
pj_end(pj);
rz_strbuf_append(buf, pj_string(pj));
pj_free(pj);
}
char *str = strdup(rz_strbuf_get(buf));
rz_strbuf_free(buf);
return str;
}

/**
* \brief return the command text for global symbols in PDB
*
* \param pdb PDB instance
* \param img_base image base addr
* \return command of pdb symbols
*/
RZ_API RZ_OWN char *rz_bin_pdb_gvars_as_cmd_string(RZ_NONNULL const RzPdb *pdb, const ut64 img_base) {
rz_return_val_if_fail(pdb, NULL);
PeImageSectionHeader *sctn_header = 0;
GDataStream *gsym_data_stream = 0;
PeStream *pe_stream = 0;
OmapStream *omap_stream;
GDataGlobal *gdata = 0;
RzListIter *it = 0;
char *name;
char *filtered_name;
RzStrBuf *cmd_buf = rz_strbuf_new(NULL);
if (!cmd_buf) {
return NULL;
}
gsym_data_stream = pdb->s_gdata;
pe_stream = pdb->s_pe;
omap_stream = pdb->s_omap;
if (!pe_stream) {
rz_strbuf_free(cmd_buf);
return NULL;
}
rz_list_foreach (gsym_data_stream->global_list, it, gdata) {
sctn_header = rz_list_get_n(pe_stream->sections_hdrs, (gdata->segment - 1));
if (sctn_header) {
name = rz_demangler_msvc(gdata->name);
name = (name) ? name : strdup(gdata->name);
filtered_name = rz_name_filter2(name, true);
rz_strbuf_appendf(cmd_buf, "f pdb.%s = 0x%" PFMT64x " # %d %.*s\n",
filtered_name,
(ut64)(img_base + omap_remap(omap_stream, gdata->offset + sctn_header->virtual_address)),
gdata->symtype, PDB_SIZEOF_SECTION_NAME, sctn_header->name);
rz_strbuf_appendf(cmd_buf, "\"fN pdb.%s %s\"\n", filtered_name, name);
free(filtered_name);
free(name);
}
}
char *str = strdup(rz_strbuf_get(cmd_buf));
rz_strbuf_free(cmd_buf);
return str;
}

static bool parse_pdb_stream(RzPdb *pdb, MsfStream *stream) {
if (!pdb || !stream) {
return false;
Expand Down
16 changes: 2 additions & 14 deletions librz/core/cbin.c
Original file line number Diff line number Diff line change
Expand Up @@ -514,19 +514,7 @@ RZ_API bool rz_core_bin_print(RzCore *core, RzBinFile *bf, ut32 mask, RzCoreBinF
if (mask & RZ_CORE_BIN_ACC_PDB) {
if (state->mode & (RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_JSON | RZ_OUTPUT_MODE_RIZIN)) {
RzCmdStateOutput *st = add_header(state, RZ_OUTPUT_MODE_STANDARD, "pdb");
switch (st->mode) {
case RZ_OUTPUT_MODE_STANDARD:
rz_core_pdb_info_print(core, core->bin->file, RZ_MODE_PRINT);
break;
case RZ_OUTPUT_MODE_JSON:
rz_core_pdb_info_print(core, core->bin->file, RZ_MODE_JSON);
break;
case RZ_OUTPUT_MODE_RIZIN:
rz_core_pdb_info_print(core, core->bin->file, RZ_MODE_RIZINCMD);
break;
default:
break;
}
rz_core_pdb_info_print(core, core->bin->file, st);
add_footer(state, st);
}
}
Expand Down Expand Up @@ -5203,7 +5191,7 @@ RZ_API bool rz_core_bin_archs_print(RzBin *bin, RzCmdStateOutput *state) {

RZ_API bool rz_core_bin_pdb_load(RZ_NONNULL RzCore *core, RZ_NONNULL const char *filename) {
rz_cons_push();
rz_core_pdb_info_print(core, filename, RZ_MODE_RIZINCMD);
rz_core_pdb_info_print(core, filename, NULL);
const char *buf = rz_cons_get_buffer();
if (!buf) {
rz_cons_pop();
Expand Down
15 changes: 1 addition & 14 deletions librz/core/cmd_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -518,20 +518,7 @@ RZ_IPI RzCmdStatus rz_cmd_info_pdb_show_handler(RzCore *core, int argc, const ch
return RZ_CMD_STATUS_ERROR;
}

switch (state->mode) {
case RZ_OUTPUT_MODE_STANDARD:
rz_core_pdb_info_print(core, filename, RZ_MODE_PRINT);
break;
case RZ_OUTPUT_MODE_JSON:
rz_core_pdb_info_print(core, filename, RZ_MODE_JSON);
break;
case RZ_OUTPUT_MODE_RIZIN:
rz_core_pdb_info_print(core, filename, RZ_MODE_RIZINCMD);
break;
default:
rz_warn_if_reached();
break;
}
rz_core_pdb_info_print(core, filename, state);
free(filename);
return RZ_CMD_STATUS_OK;
}
Expand Down
30 changes: 13 additions & 17 deletions librz/core/cpdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,19 @@
#include <rz_core.h>
#include <rz_pdb.h>

static void rz_core_bin_pdb_types_print(const RzTypeDB *db, const RzPdb *pdb, const RzOutputMode mode) {
static void rz_core_bin_pdb_types_print(const RzTypeDB *db, const RzPdb *pdb, const RzCmdStateOutput *state) {
rz_return_if_fail(db && pdb);
char *str = rz_bin_pdb_types_as_string(db, pdb, mode);
char *str = rz_bin_pdb_types_as_string(db, pdb, state);
if (!str) {
return;
}
rz_cons_print(str);
RZ_FREE(str);
}

static void rz_core_bin_pdb_gvars_print(const RzPdb *pdb, const ut64 img_base, const RzOutputMode mode) {
static void rz_core_bin_pdb_gvars_print(const RzPdb *pdb, const ut64 img_base, const RzCmdStateOutput *state) {
rz_return_if_fail(pdb);
char *str = rz_bin_pdb_gvars_as_string(pdb, img_base, mode);
char *str = rz_bin_pdb_gvars_as_string(pdb, img_base, state);
if (!str) {
return;
}
Expand All @@ -29,20 +29,12 @@ static void rz_core_bin_pdb_gvars_print(const RzPdb *pdb, const ut64 img_base, c
*
* \param core RzCore instance
* \param file Path of PDB file
* \param mode Output Mode
* \param state Output State
* \return bool
*/
RZ_API bool rz_core_pdb_info_print(RzCore *core, const char *file, RzOutputMode mode) {
RZ_API bool rz_core_pdb_info_print(RzCore *core, const char *file, RzCmdStateOutput *state) {
rz_return_val_if_fail(core && file, false);

if (mode == RZ_MODE_JSON) {
mode = RZ_OUTPUT_MODE_JSON;
} else if (mode == RZ_MODE_PRINT) {
mode = RZ_OUTPUT_MODE_STANDARD;
} else if (mode == RZ_MODE_RIZINCMD) {
mode = RZ_OUTPUT_MODE_QUIET;
}

ut64 baddr = rz_config_get_i(core->config, "bin.baddr");
if (core->bin->cur && core->bin->cur->o && core->bin->cur->o->opts.baseaddr) {
baddr = core->bin->cur->o->opts.baseaddr;
Expand All @@ -57,9 +49,13 @@ RZ_API bool rz_core_pdb_info_print(RzCore *core, const char *file, RzOutputMode

// Save compound types into types database
rz_parse_pdb_types(core->analysis->typedb, pdb);
rz_core_bin_pdb_types_print(core->analysis->typedb, pdb, mode);
rz_core_bin_pdb_gvars_print(pdb, baddr, mode);
char *cmd = rz_bin_pdb_gvars_as_string(pdb, baddr, RZ_OUTPUT_MODE_RIZIN);
if (state) {
rz_cmd_state_output_array_start(state);
rz_core_bin_pdb_types_print(core->analysis->typedb, pdb, state);
rz_core_bin_pdb_gvars_print(pdb, baddr, state);
rz_cmd_state_output_array_end(state);
}
char *cmd = rz_bin_pdb_gvars_as_cmd_string(pdb, baddr);
rz_core_cmd0(core, cmd);
free(cmd);
rz_bin_pdb_free(pdb);
Expand Down
2 changes: 1 addition & 1 deletion librz/include/rz_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -862,7 +862,7 @@ RZ_API RZ_OWN char *rz_core_bin_field_build_flag_name(RZ_NONNULL RzBinClass *cls
RZ_API char *rz_core_bin_method_flags_str(ut64 flags, int mode);
RZ_API RZ_OWN char *rz_core_bin_pdb_get_filename(RZ_NONNULL RzCore *core);
RZ_API bool rz_core_bin_pdb_load(RZ_NONNULL RzCore *core, RZ_NONNULL const char *filename);
RZ_API bool rz_core_pdb_info_print(RzCore *core, const char *file, RzOutputMode mode);
RZ_API bool rz_core_pdb_info_print(RzCore *core, const char *file, RzCmdStateOutput *state);
RZ_API RzCmdStatus rz_core_bin_plugins_print(RzBin *bin, RzCmdStateOutput *state);

RZ_API bool rz_core_bin_archs_print(RZ_NONNULL RzBin *bin, RZ_NONNULL RzCmdStateOutput *state);
Expand Down
6 changes: 4 additions & 2 deletions librz/include/rz_pdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include <rz_util.h>
#include <rz_type.h>
#include <rz_cmd.h>

#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -870,8 +871,9 @@ typedef struct rz_pdb_t {
// PDB
RZ_API RZ_OWN RzPdb *rz_bin_pdb_parse_from_file(RZ_NONNULL const char *filename);
RZ_API RZ_OWN RzPdb *rz_bin_pdb_parse_from_buf(RZ_NONNULL const RzBuffer *buf);
RZ_API RZ_OWN char *rz_bin_pdb_types_as_string(RZ_NONNULL const RzTypeDB *db, RZ_NONNULL const RzPdb *pdb, const RzOutputMode mode);
RZ_API RZ_OWN char *rz_bin_pdb_gvars_as_string(RZ_NONNULL const RzPdb *pdb, const ut64 img_base, RzOutputMode mode);
RZ_API RZ_OWN char *rz_bin_pdb_types_as_string(RZ_NONNULL const RzTypeDB *db, RZ_NONNULL const RzPdb *pdb, const RzCmdStateOutput *state);
RZ_API RZ_OWN char *rz_bin_pdb_gvars_as_string(RZ_NONNULL const RzPdb *pdb, const ut64 img_base, const RzCmdStateOutput *state);
RZ_API RZ_OWN char *rz_bin_pdb_gvars_as_cmd_string(RZ_NONNULL const RzPdb *pdb, const ut64 img_base);
RZ_API void rz_bin_pdb_free(RzPdb *pdb);

// TPI
Expand Down
Loading

0 comments on commit 3925afb

Please sign in to comment.