analysis: add enum immediate hints with ahie command (#6052)
This commit is contained in:
parent
964335bcf6
commit
c10d9c4a34
14 changed files with 349 additions and 58 deletions
|
|
@ -9,6 +9,7 @@
|
|||
#include <rz_util/rz_regex.h>
|
||||
#include <rz_types.h>
|
||||
#include <rz_arch.h>
|
||||
#include <rz_type.h>
|
||||
|
||||
#define isx86separator(x) ( \
|
||||
(x) == ' ' || (x) == '\t' || (x) == '\n' || (x) == '\r' || (x) == ' ' || \
|
||||
|
|
@ -42,6 +43,39 @@ static void insert(char *dst, const char *src) {
|
|||
free(endNum);
|
||||
}
|
||||
|
||||
static void replace_number_token(char *out, size_t out_len, char *data, char *num_start, char *num_end, const char *value) {
|
||||
*num_start = 0;
|
||||
snprintf(out, out_len, "%s%s%s", data, value, (num_start != num_end) ? num_end : "");
|
||||
}
|
||||
|
||||
static bool replace_enum_hint(RzParse *p, RzAnalysisHint *hint, ut64 off, char *data, char *out, size_t out_len, char *num_start, char *num_end) {
|
||||
if (RZ_STR_ISEMPTY(hint->enum_name) || !p->analb.analysis || !p->analb.analysis->typedb) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *member = rz_type_db_enum_member_by_val(
|
||||
p->analb.analysis->typedb, hint->enum_name, off);
|
||||
if (!member) {
|
||||
return false;
|
||||
}
|
||||
|
||||
char ename[512] = "";
|
||||
size_t ename_len = strlen(hint->enum_name) + strlen(member) + 2;
|
||||
if (ename_len <= sizeof(ename)) {
|
||||
rz_strf(ename, "%s.%s", hint->enum_name, member);
|
||||
replace_number_token(out, out_len, data, num_start, num_end, ename);
|
||||
return true;
|
||||
}
|
||||
|
||||
char *ename_dyn = rz_str_newf("%s.%s", hint->enum_name, member);
|
||||
if (!ename_dyn) {
|
||||
return false;
|
||||
}
|
||||
replace_number_token(out, out_len, data, num_start, num_end, ename_dyn);
|
||||
free(ename_dyn);
|
||||
return true;
|
||||
}
|
||||
|
||||
static int parse_number(const char *str) {
|
||||
const char *p = str;
|
||||
// Parse as hexadecmial (0x notation)
|
||||
|
|
@ -405,6 +439,8 @@ static bool filter(RzParse *p, ut64 addr, RzFlag *f, RzAnalysisHint *hint, char
|
|||
}
|
||||
}
|
||||
if (hint) {
|
||||
char *num_start = ptr;
|
||||
char *num_end = ptr2;
|
||||
const int nw = hint->nword;
|
||||
if (count != nw) {
|
||||
ptr = ptr2;
|
||||
|
|
@ -414,11 +450,13 @@ static bool filter(RzParse *p, ut64 addr, RzFlag *f, RzAnalysisHint *hint, char
|
|||
char num[256] = { 0 }, *pnum, *tmp;
|
||||
int tmp_count;
|
||||
if (hint->offset) {
|
||||
*ptr = 0;
|
||||
snprintf(str, len, "%s%s%s", data, hint->offset, (ptr != ptr2) ? ptr2 : "");
|
||||
replace_number_token(str, len, data, num_start, num_end, hint->offset);
|
||||
return true;
|
||||
}
|
||||
strncpy(num, ptr, sizeof(num) - 2);
|
||||
if (replace_enum_hint(p, hint, off, data, str, len, num_start, num_end)) {
|
||||
return true;
|
||||
}
|
||||
strncpy(num, num_start, sizeof(num) - 2);
|
||||
pnum = num + parse_number(num);
|
||||
*pnum = 0;
|
||||
switch (immbase) {
|
||||
|
|
@ -427,9 +465,9 @@ static bool filter(RzParse *p, ut64 addr, RzFlag *f, RzAnalysisHint *hint, char
|
|||
break;
|
||||
case 1: // hack for ascii
|
||||
tmp_count = 0;
|
||||
for (tmp = data; tmp < ptr; tmp++) {
|
||||
for (tmp = data; tmp < num_start; tmp++) {
|
||||
if (*tmp == 0x1b) {
|
||||
while (tmp < ptr - 1 && *tmp != 'm') {
|
||||
while (tmp < num_start - 1 && *tmp != 'm') {
|
||||
tmp++;
|
||||
}
|
||||
continue;
|
||||
|
|
@ -545,8 +583,7 @@ static bool filter(RzParse *p, ut64 addr, RzFlag *f, RzAnalysisHint *hint, char
|
|||
snprintf(num, sizeof(num), "0x%" PFMT64x, (ut64)off);
|
||||
break;
|
||||
}
|
||||
*ptr = 0;
|
||||
snprintf(str, len, "%s%s%s", data, num, (ptr != ptr2) ? ptr2 : "");
|
||||
replace_number_token(str, len, data, num_start, num_end, num);
|
||||
return true;
|
||||
}
|
||||
ptr = ptr2;
|
||||
|
|
|
|||
|
|
@ -49,6 +49,9 @@ static void addr_hint_record_fini(void *element, void *user) {
|
|||
case RZ_ANALYSIS_ADDR_HINT_TYPE_ESIL:
|
||||
free(record->esil);
|
||||
break;
|
||||
case RZ_ANALYSIS_ADDR_HINT_TYPE_ENUM:
|
||||
free(record->enum_name);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -230,6 +233,16 @@ RZ_API void rz_analysis_hint_set_immbase(RzAnalysis *a, ut64 addr, int base) {
|
|||
}
|
||||
}
|
||||
|
||||
RZ_API void rz_analysis_hint_set_enum(RzAnalysis *a, ut64 addr, const char *enum_name) {
|
||||
if (RZ_STR_ISEMPTY(enum_name)) {
|
||||
rz_analysis_hint_unset_enum(a, addr);
|
||||
return;
|
||||
}
|
||||
SET_HINT(RZ_ANALYSIS_ADDR_HINT_TYPE_ENUM,
|
||||
free(r->enum_name);
|
||||
r->enum_name = rz_str_dup(enum_name););
|
||||
}
|
||||
|
||||
RZ_API void rz_analysis_hint_set_pointer(RzAnalysis *a, ut64 addr, ut64 ptr) {
|
||||
SET_HINT(RZ_ANALYSIS_ADDR_HINT_TYPE_PTR, r->ptr = ptr;);
|
||||
}
|
||||
|
|
@ -312,6 +325,10 @@ RZ_API void rz_analysis_hint_unset_immbase(RzAnalysis *a, ut64 addr) {
|
|||
unset_addr_hint_record(a, RZ_ANALYSIS_ADDR_HINT_TYPE_IMMBASE, addr);
|
||||
}
|
||||
|
||||
RZ_API void rz_analysis_hint_unset_enum(RzAnalysis *a, ut64 addr) {
|
||||
unset_addr_hint_record(a, RZ_ANALYSIS_ADDR_HINT_TYPE_ENUM, addr);
|
||||
}
|
||||
|
||||
RZ_API void rz_analysis_hint_unset_nword(RzAnalysis *a, ut64 addr) {
|
||||
unset_addr_hint_record(a, RZ_ANALYSIS_ADDR_HINT_TYPE_NWORD, addr);
|
||||
}
|
||||
|
|
@ -371,6 +388,7 @@ RZ_API void rz_analysis_hint_free(RzAnalysisHint *h) {
|
|||
free(h->opcode);
|
||||
free(h->syntax);
|
||||
free(h->offset);
|
||||
free(h->enum_name);
|
||||
free(h);
|
||||
}
|
||||
}
|
||||
|
|
@ -496,6 +514,10 @@ static void hint_merge(RzAnalysisHint *hint, RzAnalysisAddrHintRecord *record) {
|
|||
case RZ_ANALYSIS_ADDR_HINT_TYPE_VAL:
|
||||
hint->val = record->val;
|
||||
break;
|
||||
case RZ_ANALYSIS_ADDR_HINT_TYPE_ENUM:
|
||||
free(hint->enum_name);
|
||||
hint->enum_name = rz_str_dup(record->enum_name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1848,6 +1848,11 @@ static bool hints_acc_store_cb(void *user, const ut64 addr, const void *v) {
|
|||
case RZ_ANALYSIS_ADDR_HINT_TYPE_VAL:
|
||||
pj_kn(j, "val", record->val);
|
||||
break;
|
||||
case RZ_ANALYSIS_ADDR_HINT_TYPE_ENUM:
|
||||
if (!RZ_STR_ISEMPTY(record->enum_name)) {
|
||||
pj_ks(j, "enum", record->enum_name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1884,7 +1889,8 @@ enum {
|
|||
HINTS_FIELD_TYPE_OFFSET,
|
||||
HINTS_FIELD_ESIL,
|
||||
HINTS_FIELD_HIGH,
|
||||
HINTS_FIELD_VAL
|
||||
HINTS_FIELD_VAL,
|
||||
HINTS_FIELD_ENUM
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -2015,6 +2021,12 @@ static bool hints_load_cb(void *user, const SdbKv *kv) {
|
|||
}
|
||||
rz_analysis_hint_set_val(analysis, addr, child->num.u_value);
|
||||
break;
|
||||
case HINTS_FIELD_ENUM:
|
||||
if (child->type != RZ_JSON_STRING) {
|
||||
break;
|
||||
}
|
||||
rz_analysis_hint_set_enum(analysis, addr, child->str_value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
})
|
||||
|
|
@ -2054,6 +2066,7 @@ RZ_API bool rz_serialize_analysis_hints_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzAn
|
|||
rz_key_parser_add(ctx.parser, "esil", HINTS_FIELD_ESIL);
|
||||
rz_key_parser_add(ctx.parser, "high", HINTS_FIELD_HIGH);
|
||||
rz_key_parser_add(ctx.parser, "val", HINTS_FIELD_VAL);
|
||||
rz_key_parser_add(ctx.parser, "enum", HINTS_FIELD_ENUM);
|
||||
ret = sdb_foreach(db, hints_load_cb, &ctx);
|
||||
if (!ret) {
|
||||
RZ_SERIALIZE_ERR(res, "hints parsing failed");
|
||||
|
|
|
|||
|
|
@ -1118,6 +1118,9 @@ static void print_hint_h_format(HintNode *node) {
|
|||
case RZ_ANALYSIS_ADDR_HINT_TYPE_VAL:
|
||||
rz_cons_printf(" val=0x%08" PFMT64x, record->val);
|
||||
break;
|
||||
case RZ_ANALYSIS_ADDR_HINT_TYPE_ENUM:
|
||||
rz_cons_printf(" enum='%s'", rz_str_get(record->enum_name));
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -1199,6 +1202,9 @@ static void hint_node_print(HintNode *node, RzOutputMode mode, PJ *pj) {
|
|||
case RZ_ANALYSIS_ADDR_HINT_TYPE_VAL:
|
||||
pj_kn(pj, "val", record->val);
|
||||
break;
|
||||
case RZ_ANALYSIS_ADDR_HINT_TYPE_ENUM:
|
||||
pj_ks(pj, "enum", rz_str_get(record->enum_name));
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -4601,7 +4601,7 @@ RZ_IPI RzCmdStatus rz_analysis_hint_del_optype_handler(RzCore *core, int argc, c
|
|||
return RZ_CMD_STATUS_OK;
|
||||
}
|
||||
|
||||
RZ_IPI RzCmdStatus rz_analysis_hint_set_immbase_handler(RzCore *core, int argc, const char **argv) {
|
||||
RZ_IPI RzCmdStatus rz_analysis_hint_set_immbase_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode RZ_UNUSED) {
|
||||
int base = rz_num_base_of_string(core->num, argv[1]);
|
||||
if (argc == 3) {
|
||||
ut64 nword = rz_num_math(core->num, argv[2]);
|
||||
|
|
@ -4616,6 +4616,20 @@ RZ_IPI RzCmdStatus rz_analysis_hint_del_immbase_handler(RzCore *core, int argc,
|
|||
return RZ_CMD_STATUS_OK;
|
||||
}
|
||||
|
||||
RZ_IPI RzCmdStatus rz_analysis_hint_set_enum_handler(RzCore *core, int argc, const char **argv) {
|
||||
if (argc == 3) {
|
||||
ut64 nword = rz_num_math(core->num, argv[2]);
|
||||
rz_analysis_hint_set_nword(core->analysis, core->offset, (int)(nword));
|
||||
}
|
||||
rz_analysis_hint_set_enum(core->analysis, core->offset, argv[1]);
|
||||
return RZ_CMD_STATUS_OK;
|
||||
}
|
||||
|
||||
RZ_IPI RzCmdStatus rz_analysis_hint_del_enum_handler(RzCore *core, int argc, const char **argv) {
|
||||
rz_analysis_hint_unset_enum(core->analysis, core->offset);
|
||||
return RZ_CMD_STATUS_OK;
|
||||
}
|
||||
|
||||
RZ_IPI RzCmdStatus rz_analysis_hint_set_offset_handler(RzCore *core, int argc, const char **argv) {
|
||||
return bool2status(rz_core_analysis_hint_set_offset(core, argv[1]));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1980,47 +1980,65 @@ commands:
|
|||
cname: analysis_hint_del_optype
|
||||
args: []
|
||||
- name: ahi
|
||||
summary: Set immediate base hint
|
||||
cname: analysis_hint_set_immbase
|
||||
args:
|
||||
- name: type
|
||||
type: RZ_CMD_ARG_TYPE_CHOICES
|
||||
choices: ["2", "8", "10", "10u", "16", "b", "o", "h", "i", "p", "S", "s"]
|
||||
- name: nword
|
||||
type: RZ_CMD_ARG_TYPE_NUM
|
||||
optional: true
|
||||
details:
|
||||
- name: ""
|
||||
entries:
|
||||
- text: "ahi "
|
||||
arg_str: <base>
|
||||
comment: Set numeric <base> (2, 8, 10, 16)
|
||||
- text: ahi 10|d
|
||||
comment: Set base to signed decimal (10), sign bit should depend on receiver size
|
||||
- text: ahi 10u|du
|
||||
comment: Set base to unsigned decimal (11)
|
||||
- text: ahi b
|
||||
comment: Set base to binary (2)
|
||||
- text: ahi o
|
||||
comment: Set base to octal (8)
|
||||
- text: ahi h
|
||||
comment: Set base to hexadecimal (16)
|
||||
- text: ahi i
|
||||
comment: Set base to IP address (32)
|
||||
- text: ahi p
|
||||
comment: Set base to htons(port) (3)
|
||||
- text: ahi S
|
||||
comment: Set base to syscall (80)
|
||||
- text: ahi s
|
||||
comment: Set base to string (1)
|
||||
- name: Set base of the N-th immediate (indexing starts from 0)
|
||||
entries:
|
||||
- text: ahi 16 1
|
||||
comment: Set base of the 1-st immediate to hexadecimal
|
||||
- name: ahi-
|
||||
summary: Delete immediate base hint
|
||||
cname: analysis_hint_del_immbase
|
||||
args: []
|
||||
summary: Manage immediate operand hints
|
||||
subcommands:
|
||||
- name: ahi
|
||||
summary: Set immediate base hint
|
||||
cname: analysis_hint_set_immbase
|
||||
modes:
|
||||
- RZ_OUTPUT_MODE_STANDARD
|
||||
args:
|
||||
- name: type
|
||||
type: RZ_CMD_ARG_TYPE_CHOICES
|
||||
choices: ["2", "8", "10", "10u", "16", "b", "o", "h", "i", "p", "S", "s"]
|
||||
- name: nword
|
||||
type: RZ_CMD_ARG_TYPE_NUM
|
||||
optional: true
|
||||
details:
|
||||
- name: ""
|
||||
entries:
|
||||
- text: "ahi "
|
||||
arg_str: <base>
|
||||
comment: Set numeric <base> (2, 8, 10, 16)
|
||||
- text: ahi 10|d
|
||||
comment: Set base to signed decimal (10), sign bit should depend on receiver size
|
||||
- text: ahi 10u|du
|
||||
comment: Set base to unsigned decimal (11)
|
||||
- text: ahi b
|
||||
comment: Set base to binary (2)
|
||||
- text: ahi o
|
||||
comment: Set base to octal (8)
|
||||
- text: ahi h
|
||||
comment: Set base to hexadecimal (16)
|
||||
- text: ahi i
|
||||
comment: Set base to IP address (32)
|
||||
- text: ahi p
|
||||
comment: Set base to htons(port) (3)
|
||||
- text: ahi S
|
||||
comment: Set base to syscall (80)
|
||||
- text: ahi s
|
||||
comment: Set base to string (1)
|
||||
- name: Set base of the N-th immediate (indexing starts from 0)
|
||||
entries:
|
||||
- text: ahi 16 1
|
||||
comment: Set base of the 1-st immediate to hexadecimal
|
||||
- name: ahi-
|
||||
summary: Delete immediate base hint
|
||||
cname: analysis_hint_del_immbase
|
||||
args: []
|
||||
- name: ahie
|
||||
summary: Set enum type hint for operand
|
||||
cname: analysis_hint_set_enum
|
||||
args:
|
||||
- name: enum
|
||||
type: RZ_CMD_ARG_TYPE_ENUM_TYPE
|
||||
- name: nword
|
||||
type: RZ_CMD_ARG_TYPE_NUM
|
||||
optional: true
|
||||
- name: ahie-
|
||||
summary: Delete enum type hint
|
||||
cname: analysis_hint_del_enum
|
||||
args: []
|
||||
- name: aht
|
||||
summary: Set structure offset hint
|
||||
cname: analysis_hint_set_offset
|
||||
|
|
|
|||
|
|
@ -356,6 +356,7 @@ static const RzCmdDescArg analysis_hint_set_ret_args[2];
|
|||
static const RzCmdDescArg analysis_hint_set_val_args[2];
|
||||
static const RzCmdDescArg analysis_hint_set_optype_args[2];
|
||||
static const RzCmdDescArg analysis_hint_set_immbase_args[3];
|
||||
static const RzCmdDescArg analysis_hint_set_enum_args[3];
|
||||
static const RzCmdDescArg analysis_hint_set_offset_args[2];
|
||||
static const RzCmdDescArg analysis_list_struct_offsets_args[2];
|
||||
static const RzCmdDescArg analysis_class_add_args[2];
|
||||
|
|
@ -6996,6 +6997,9 @@ static const RzCmdDescHelp analysis_hint_del_optype_help = {
|
|||
.args = analysis_hint_del_optype_args,
|
||||
};
|
||||
|
||||
static const RzCmdDescHelp ahi_help = {
|
||||
.summary = "Manage immediate operand hints",
|
||||
};
|
||||
static const RzCmdDescDetailEntry analysis_hint_set_immbase_empty_detail_entries[] = {
|
||||
{ .text = "ahi ", .arg_str = "<base>", .comment = "Set numeric <base> (2, 8, 10, 16)" },
|
||||
{ .text = "ahi 10|d", .arg_str = NULL, .comment = "Set base to signed decimal (10), sign bit should depend on receiver size" },
|
||||
|
|
@ -7049,6 +7053,33 @@ static const RzCmdDescHelp analysis_hint_del_immbase_help = {
|
|||
.args = analysis_hint_del_immbase_args,
|
||||
};
|
||||
|
||||
static const RzCmdDescArg analysis_hint_set_enum_args[] = {
|
||||
{
|
||||
.name = "enum",
|
||||
.type = RZ_CMD_ARG_TYPE_ENUM_TYPE,
|
||||
|
||||
},
|
||||
{
|
||||
.name = "nword",
|
||||
.type = RZ_CMD_ARG_TYPE_NUM,
|
||||
.optional = true,
|
||||
|
||||
},
|
||||
{ 0 },
|
||||
};
|
||||
static const RzCmdDescHelp analysis_hint_set_enum_help = {
|
||||
.summary = "Set enum type hint for operand",
|
||||
.args = analysis_hint_set_enum_args,
|
||||
};
|
||||
|
||||
static const RzCmdDescArg analysis_hint_del_enum_args[] = {
|
||||
{ 0 },
|
||||
};
|
||||
static const RzCmdDescHelp analysis_hint_del_enum_help = {
|
||||
.summary = "Delete enum type hint",
|
||||
.args = analysis_hint_del_enum_args,
|
||||
};
|
||||
|
||||
static const RzCmdDescDetailEntry analysis_hint_set_offset_empty_detail_entries[] = {
|
||||
{ .text = "aht ", .arg_str = "struct.member", .comment = "Replace immediate with <struct.member>" },
|
||||
{ 0 },
|
||||
|
|
@ -22654,12 +22685,17 @@ RZ_IPI void rzshell_cmddescs_init(RzCore *core) {
|
|||
RzCmdDesc *analysis_hint_del_optype_cd = rz_cmd_desc_argv_new(core->rcmd, ah_cd, "aho-", rz_analysis_hint_del_optype_handler, &analysis_hint_del_optype_help);
|
||||
rz_warn_if_fail(analysis_hint_del_optype_cd);
|
||||
|
||||
RzCmdDesc *analysis_hint_set_immbase_cd = rz_cmd_desc_argv_new(core->rcmd, ah_cd, "ahi", rz_analysis_hint_set_immbase_handler, &analysis_hint_set_immbase_help);
|
||||
rz_warn_if_fail(analysis_hint_set_immbase_cd);
|
||||
|
||||
RzCmdDesc *analysis_hint_del_immbase_cd = rz_cmd_desc_argv_new(core->rcmd, ah_cd, "ahi-", rz_analysis_hint_del_immbase_handler, &analysis_hint_del_immbase_help);
|
||||
RzCmdDesc *ahi_cd = rz_cmd_desc_group_modes_new(core->rcmd, ah_cd, "ahi", RZ_OUTPUT_MODE_STANDARD, rz_analysis_hint_set_immbase_handler, &analysis_hint_set_immbase_help, &ahi_help);
|
||||
rz_warn_if_fail(ahi_cd);
|
||||
RzCmdDesc *analysis_hint_del_immbase_cd = rz_cmd_desc_argv_new(core->rcmd, ahi_cd, "ahi-", rz_analysis_hint_del_immbase_handler, &analysis_hint_del_immbase_help);
|
||||
rz_warn_if_fail(analysis_hint_del_immbase_cd);
|
||||
|
||||
RzCmdDesc *analysis_hint_set_enum_cd = rz_cmd_desc_argv_new(core->rcmd, ahi_cd, "ahie", rz_analysis_hint_set_enum_handler, &analysis_hint_set_enum_help);
|
||||
rz_warn_if_fail(analysis_hint_set_enum_cd);
|
||||
|
||||
RzCmdDesc *analysis_hint_del_enum_cd = rz_cmd_desc_argv_new(core->rcmd, ahi_cd, "ahie-", rz_analysis_hint_del_enum_handler, &analysis_hint_del_enum_help);
|
||||
rz_warn_if_fail(analysis_hint_del_enum_cd);
|
||||
|
||||
RzCmdDesc *analysis_hint_set_offset_cd = rz_cmd_desc_argv_new(core->rcmd, ah_cd, "aht", rz_analysis_hint_set_offset_handler, &analysis_hint_set_offset_help);
|
||||
rz_warn_if_fail(analysis_hint_set_offset_cd);
|
||||
|
||||
|
|
|
|||
|
|
@ -800,9 +800,13 @@ RZ_IPI RzCmdStatus rz_analysis_hint_set_optype_handler(RzCore *core, int argc, c
|
|||
// "aho-"
|
||||
RZ_IPI RzCmdStatus rz_analysis_hint_del_optype_handler(RzCore *core, int argc, const char **argv);
|
||||
// "ahi"
|
||||
RZ_IPI RzCmdStatus rz_analysis_hint_set_immbase_handler(RzCore *core, int argc, const char **argv);
|
||||
RZ_IPI RzCmdStatus rz_analysis_hint_set_immbase_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode);
|
||||
// "ahi-"
|
||||
RZ_IPI RzCmdStatus rz_analysis_hint_del_immbase_handler(RzCore *core, int argc, const char **argv);
|
||||
// "ahie"
|
||||
RZ_IPI RzCmdStatus rz_analysis_hint_set_enum_handler(RzCore *core, int argc, const char **argv);
|
||||
// "ahie-"
|
||||
RZ_IPI RzCmdStatus rz_analysis_hint_del_enum_handler(RzCore *core, int argc, const char **argv);
|
||||
// "aht"
|
||||
RZ_IPI RzCmdStatus rz_analysis_hint_set_offset_handler(RzCore *core, int argc, const char **argv);
|
||||
// "aht-"
|
||||
|
|
|
|||
|
|
@ -571,7 +571,8 @@ typedef enum rz_analysis_addr_hint_type_t {
|
|||
RZ_ANALYSIS_ADDR_HINT_TYPE_TYPE_OFFSET,
|
||||
RZ_ANALYSIS_ADDR_HINT_TYPE_ESIL,
|
||||
RZ_ANALYSIS_ADDR_HINT_TYPE_HIGH,
|
||||
RZ_ANALYSIS_ADDR_HINT_TYPE_VAL
|
||||
RZ_ANALYSIS_ADDR_HINT_TYPE_VAL,
|
||||
RZ_ANALYSIS_ADDR_HINT_TYPE_ENUM
|
||||
} RzAnalysisAddrHintType;
|
||||
|
||||
typedef struct rz_analysis_addr_hint_record_t {
|
||||
|
|
@ -592,6 +593,7 @@ typedef struct rz_analysis_addr_hint_record_t {
|
|||
ut64 size;
|
||||
ut64 stackframe;
|
||||
ut64 val;
|
||||
char *enum_name;
|
||||
};
|
||||
} RzAnalysisAddrHintRecord;
|
||||
|
||||
|
|
@ -615,6 +617,7 @@ typedef struct rz_analysis_hint_t {
|
|||
bool high; // highlight hint
|
||||
int nword;
|
||||
ut64 stackframe;
|
||||
char *enum_name;
|
||||
} RzAnalysisHint;
|
||||
|
||||
typedef RzAnalysisFunction *(*RzAnalysisGetFcnIn)(RzAnalysis *analysis, ut64 addr, int type);
|
||||
|
|
@ -2179,6 +2182,7 @@ RZ_API void rz_analysis_hint_set_newbits(RzAnalysis *a, ut64 addr, int bits);
|
|||
RZ_API void rz_analysis_hint_set_nword(RzAnalysis *a, ut64 addr, int nword);
|
||||
RZ_API void rz_analysis_hint_set_offset(RzAnalysis *a, ut64 addr, const char *typeoff);
|
||||
RZ_API void rz_analysis_hint_set_immbase(RzAnalysis *a, ut64 addr, int base);
|
||||
RZ_API void rz_analysis_hint_set_enum(RzAnalysis *a, ut64 addr, const char *enum_name);
|
||||
RZ_API void rz_analysis_hint_set_size(RzAnalysis *a, ut64 addr, ut64 size);
|
||||
RZ_API void rz_analysis_hint_set_opcode(RzAnalysis *a, ut64 addr, const char *str);
|
||||
RZ_API void rz_analysis_hint_set_esil(RzAnalysis *a, ut64 addr, const char *str);
|
||||
|
|
@ -2192,6 +2196,7 @@ RZ_API void rz_analysis_hint_set_bits(RzAnalysis *a, ut64 addr, int bits); // bi
|
|||
RZ_API void rz_analysis_hint_unset_val(RzAnalysis *a, ut64 addr);
|
||||
RZ_API void rz_analysis_hint_unset_high(RzAnalysis *a, ut64 addr);
|
||||
RZ_API void rz_analysis_hint_unset_immbase(RzAnalysis *a, ut64 addr);
|
||||
RZ_API void rz_analysis_hint_unset_enum(RzAnalysis *a, ut64 addr);
|
||||
RZ_API void rz_analysis_hint_unset_nword(RzAnalysis *a, ut64 addr);
|
||||
RZ_API void rz_analysis_hint_unset_size(RzAnalysis *a, ut64 addr);
|
||||
RZ_API void rz_analysis_hint_unset_type(RzAnalysis *a, ut64 addr);
|
||||
|
|
|
|||
|
|
@ -114,6 +114,12 @@ int parse_primitive_type(CParserState *state, TSNode node, const char *text, Par
|
|||
free(real_type);
|
||||
return 0;
|
||||
}
|
||||
if ((*tpair = c_parser_get_typedef(state, real_type))) {
|
||||
(*tpair)->type->identifier.is_const = is_const;
|
||||
parser_debug(state, "Fetched type alias: \"%s\"\n", real_type);
|
||||
free(real_type);
|
||||
return 0;
|
||||
}
|
||||
// If not - we form both RzType and RzBaseType to store in the Types database
|
||||
ParserTypePair *type_pair = c_parser_new_primitive_type(state, real_type, is_const);
|
||||
if (!type_pair) {
|
||||
|
|
@ -150,6 +156,12 @@ int parse_sized_primitive_type(CParserState *state, TSNode node, const char *tex
|
|||
free(real_type);
|
||||
return 0;
|
||||
}
|
||||
if ((*tpair = c_parser_get_typedef(state, real_type))) {
|
||||
(*tpair)->type->identifier.is_const = is_const;
|
||||
parser_debug(state, "Fetched type alias: \"%s\"\n", real_type);
|
||||
free(real_type);
|
||||
return 0;
|
||||
}
|
||||
// If not - we form both RzType and RzBaseType to store in the Types database
|
||||
ParserTypePair *type_pair = c_parser_new_primitive_type(state, real_type, is_const);
|
||||
if (!type_pair) {
|
||||
|
|
|
|||
|
|
@ -380,3 +380,87 @@ EXPECT=<<EOF
|
|||
0x00000000 cmp rax, 18446744073709551615
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=ahie enum operands
|
||||
FILE==
|
||||
CMDS=<<EOF
|
||||
o malloc://256
|
||||
td "enum E { SEVEN = 7, EIGHT = 8, MASK = 0x100, WORD = 0xffc643 };"
|
||||
e asm.arch=x86
|
||||
e asm.bits=64
|
||||
e cfg.bigendian=false
|
||||
s 0
|
||||
wx 4180fc07
|
||||
ahie E
|
||||
pi 1
|
||||
ahie-
|
||||
pi 1
|
||||
wx 4883f803
|
||||
ahie E
|
||||
pi 1
|
||||
s 0x10
|
||||
wx c7458843c6ff00
|
||||
ahie E 1
|
||||
pdq 1
|
||||
e asm.arch=arm
|
||||
e asm.bits=32
|
||||
e cfg.bigendian=false
|
||||
s 0x20
|
||||
wx 0700a0e3
|
||||
ahie E
|
||||
pi 1
|
||||
e asm.arch=arm
|
||||
e asm.bits=64
|
||||
s 0x30
|
||||
wx e00080d2
|
||||
ahie E
|
||||
pi 1
|
||||
e asm.arch=ppc
|
||||
e asm.bits=32
|
||||
e cfg.bigendian=true
|
||||
s 0x40
|
||||
wx 38600007
|
||||
ahie E
|
||||
pi 1
|
||||
e asm.arch=mips
|
||||
e asm.bits=32
|
||||
e cfg.bigendian=true
|
||||
s 0x50
|
||||
wx 20020007
|
||||
ahie E
|
||||
pi 1
|
||||
e asm.arch=8051
|
||||
e asm.bits=8
|
||||
s 0x60
|
||||
wx 7407
|
||||
ahie E
|
||||
pi 1
|
||||
e asm.arch=tricore
|
||||
e asm.bits=32
|
||||
e cfg.bigendian=true
|
||||
s 0x70
|
||||
wx 8f005001
|
||||
ahie E
|
||||
pi 1
|
||||
e asm.arch=hexagon
|
||||
e asm.bits=32
|
||||
e cfg.bigendian=false
|
||||
s 0x80
|
||||
wx 01c09da0
|
||||
ahie E
|
||||
pi 1
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
cmp r12b, E.SEVEN
|
||||
cmp r12b, 0x07
|
||||
cmp rax, 0x03
|
||||
0x00000010 mov dword [rbp-0x78], E.WORD
|
||||
mov r0, E.SEVEN
|
||||
mov x0, E.SEVEN
|
||||
li r3, E.SEVEN
|
||||
addi v0, zero, E.SEVEN
|
||||
mov a, #E.SEVEN
|
||||
or d0, d0, #E.MASK
|
||||
[ allocframe(SP,#E.EIGHT):raw
|
||||
EOF
|
||||
RUN
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ const RzAnalysisHint empty_hint = {
|
|||
.high = 0,
|
||||
.nword = 0,
|
||||
.stackframe = UT64_MAX,
|
||||
.enum_name = NULL,
|
||||
};
|
||||
|
||||
bool hint_equals(const RzAnalysisHint *a, const RzAnalysisHint *b) {
|
||||
|
|
@ -49,6 +50,7 @@ bool hint_equals(const RzAnalysisHint *a, const RzAnalysisHint *b) {
|
|||
CHECK_STREQ(syntax);
|
||||
CHECK_STREQ(esil);
|
||||
CHECK_STREQ(offset);
|
||||
CHECK_STREQ(enum_name);
|
||||
#undef CHECK_STREQ
|
||||
return true;
|
||||
}
|
||||
|
|
@ -109,6 +111,10 @@ bool test_rz_analysis_addr_hints() {
|
|||
cur.immbase = 7;
|
||||
CHECK
|
||||
|
||||
rz_analysis_hint_set_enum(analysis, 0x1337, "BLA");
|
||||
cur.enum_name = "BLA";
|
||||
CHECK
|
||||
|
||||
rz_analysis_hint_set_size(analysis, 0x1337, 0x123);
|
||||
cur.size = 0x123;
|
||||
CHECK
|
||||
|
|
@ -175,6 +181,10 @@ bool test_rz_analysis_addr_hints() {
|
|||
cur.immbase = 0;
|
||||
CHECK
|
||||
|
||||
rz_analysis_hint_unset_enum(analysis, 0x1337);
|
||||
cur.enum_name = NULL;
|
||||
CHECK
|
||||
|
||||
rz_analysis_hint_unset_size(analysis, 0x1337);
|
||||
cur.size = 0;
|
||||
CHECK
|
||||
|
|
@ -343,4 +353,4 @@ bool all_tests() {
|
|||
return tests_passed != tests_run;
|
||||
}
|
||||
|
||||
mu_main(all_tests)
|
||||
mu_main(all_tests)
|
||||
|
|
|
|||
|
|
@ -979,6 +979,7 @@ Sdb *hints_ref_db() {
|
|||
sdb_set(db, "0x2b0", "{\"esil\":\"13,29,+\"}");
|
||||
sdb_set(db, "0x2c0", "{\"high\":true}");
|
||||
sdb_set(db, "0x2d0", "{\"val\":54323}");
|
||||
sdb_set(db, "0x2e0", "{\"enum\":\"BLA\"}");
|
||||
return db;
|
||||
}
|
||||
|
||||
|
|
@ -1026,6 +1027,7 @@ bool test_analysis_hints_save() {
|
|||
rz_analysis_hint_set_esil(analysis, 0x2b0, "13,29,+");
|
||||
rz_analysis_hint_set_high(analysis, 0x2c0);
|
||||
rz_analysis_hint_set_val(analysis, 0x2d0, 54323);
|
||||
rz_analysis_hint_set_enum(analysis, 0x2e0, "BLA");
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < ALL_OPTYPES_COUNT; i++) {
|
||||
|
|
@ -1070,7 +1072,7 @@ bool test_analysis_hints_load() {
|
|||
rz_analysis_addr_hints_foreach(analysis, addr_hints_count_cb, &count);
|
||||
rz_analysis_arch_hints_foreach(analysis, arch_hints_count_cb, &count);
|
||||
rz_analysis_bits_hints_foreach(analysis, bits_hints_count_cb, &count);
|
||||
mu_assert_eq(count, 19 + ALL_OPTYPES_COUNT, "hints count");
|
||||
mu_assert_eq(count, 20 + ALL_OPTYPES_COUNT, "hints count");
|
||||
|
||||
ut64 addr;
|
||||
const char *arch = rz_analysis_hint_arch_at(analysis, 0x100, &addr);
|
||||
|
|
@ -1116,6 +1118,7 @@ bool test_analysis_hints_load() {
|
|||
assert_addr_hint(0x2b0, ESIL, mu_assert_streq(record->esil, "13,29,+", "esil hint"));
|
||||
assert_addr_hint(0x2c0, HIGH, );
|
||||
assert_addr_hint(0x2d0, VAL, mu_assert_eq(record->val, 54323, "val hint"));
|
||||
assert_addr_hint(0x2e0, ENUM, mu_assert_streq(record->enum_name, "BLA", "enum hint"));
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < ALL_OPTYPES_COUNT; i++) {
|
||||
|
|
|
|||
|
|
@ -762,6 +762,32 @@ static bool test_array_types(void) {
|
|||
mu_end;
|
||||
}
|
||||
|
||||
static bool test_single_typedef_aliases(void) {
|
||||
RzTypeDB *typedb = rz_type_db_new();
|
||||
mu_assert_notnull(typedb, "Couldn't create new RzTypeDB");
|
||||
mu_assert_notnull(typedb->types, "Couldn't create new types hashtable");
|
||||
const char *types_dir = TEST_BUILD_TYPES_DIR;
|
||||
const char *src[] = { "size_t", "uint32_t", "uint64_t", "const size_t" };
|
||||
const char *name[] = { "size_t", "uint32_t", "uint64_t", "size_t" };
|
||||
const bool cnst[] = { false, false, false, true };
|
||||
rz_type_db_init(typedb, types_dir, "x86", 64, "linux");
|
||||
rz_type_db_set_bits(typedb, 64);
|
||||
|
||||
for (size_t i = 0; i < RZ_ARRAY_SIZE(src); i++) {
|
||||
char *error_msg = NULL;
|
||||
RzType *ttype = rz_type_parse_string_single(typedb->parser, src[i], &error_msg);
|
||||
mu_assert_notnull(ttype, "typedef alias parse successful");
|
||||
mu_assert_null(error_msg, "parsing errors");
|
||||
mu_assert_eq(ttype->kind, RZ_TYPE_KIND_IDENTIFIER, "parsed type");
|
||||
mu_assert_streq(ttype->identifier.name, name[i], "parsed type");
|
||||
mu_assert_eq(ttype->identifier.is_const, cnst[i], "parsed const");
|
||||
rz_type_free(ttype);
|
||||
}
|
||||
|
||||
rz_type_db_free(typedb);
|
||||
mu_end;
|
||||
}
|
||||
|
||||
static char *func_ptr_struct = "struct bla { int a; wchar_t (*func)(int a, const char *b); }";
|
||||
static char *func_double_ptr_struct = "struct blabla { int a; wchar_t (**funk)(int a, const char *b); }";
|
||||
|
||||
|
|
@ -1866,6 +1892,7 @@ int all_tests() {
|
|||
mu_run_test(test_enum_types);
|
||||
mu_run_test(test_const_types);
|
||||
mu_run_test(test_array_types);
|
||||
mu_run_test(test_single_typedef_aliases);
|
||||
mu_run_test(test_struct_func_types);
|
||||
mu_run_test(test_struct_array_types);
|
||||
mu_run_test(test_struct_identifier_without_specifier);
|
||||
|
|
|
|||
Loading…
Reference in a new issue