Skip to content

Commit a6b94e2

Browse files
committed
implement rop.cache to store and return cached ROP search results
1 parent 11ae0c9 commit a6b94e2

File tree

3 files changed

+44
-0
lines changed

3 files changed

+44
-0
lines changed

librz/arch/analysis.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ RZ_API RzAnalysis *rz_analysis_free(RzAnalysis *a) {
212212
rz_str_constpool_fini(&a->constpool);
213213
ht_sp_free(a->ht_global_var);
214214
ht_up_free(a->ht_rop_semantics);
215+
ht_up_free(a->ht_rop);
215216
ht_sp_free(a->plugins);
216217
rz_analysis_debug_info_free(a->debug_info);
217218
ht_sp_free(a->ht_virtual_xrefs);

librz/core/rop.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1726,6 +1726,19 @@ static int handle_rop_search_address(RzCore *core, RzRopSearchContext *context,
17261726
RZ_API RzCmdStatus rz_core_rop_search(RZ_NONNULL RzCore *core, RZ_NONNULL RzRopSearchContext *context) {
17271727
rz_return_val_if_fail(core && core->search && context, RZ_CMD_STATUS_ERROR);
17281728

1729+
if (context->cache && context->greparg) {
1730+
if (!core->analysis->ht_rop) {
1731+
core->analysis->ht_rop = ht_up_new(NULL, free);
1732+
}
1733+
ut64 cache_key = rz_str_djb2_hash(context->greparg);
1734+
char *cached_result = ht_up_find(core->analysis->ht_rop, cache_key, NULL);
1735+
if (cached_result) {
1736+
rz_cons_print(cached_result);
1737+
return RZ_CMD_STATUS_OK;
1738+
}
1739+
context->ret_val = true;
1740+
}
1741+
17291742
RzInterval search_itv = { 0 };
17301743
if (!fetch_search_itv(core, &search_itv)) {
17311744
return RZ_CMD_STATUS_ERROR;
@@ -1792,6 +1805,18 @@ RZ_API RzCmdStatus rz_core_rop_search(RZ_NONNULL RzCore *core, RZ_NONNULL RzRopS
17921805
eprintf("\n");
17931806
}
17941807

1808+
if (context->cache && context->greparg && context->buf) {
1809+
ut64 cache_key = rz_str_djb2_hash(context->greparg);
1810+
char *result = rz_strbuf_drain(context->buf);
1811+
context->buf = NULL;
1812+
if (result && *result) {
1813+
ht_up_insert(core->analysis->ht_rop, cache_key, result);
1814+
rz_cons_print(result);
1815+
} else {
1816+
free(result);
1817+
}
1818+
}
1819+
17951820
if (context->state) {
17961821
rz_cmd_state_output_array_end(context->state);
17971822
}

test/unit/test_rop.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,26 @@ bool test_rz_direct_solver() {
141141
mu_end;
142142
}
143143

144+
bool test_rop_cache() {
145+
RzCore *core = setup_rz_core("x86", 64);
146+
mu_assert_notnull(core, "setup_rz_core failed");
147+
mu_assert_null(core->analysis->ht_rop, "ht_rop should be NULL initially");
148+
ut8 buf[8];
149+
rz_hex_str2bin("48C7C301000000C3", buf);
150+
rz_io_write_at(core->io, 0, buf, 8);
151+
rz_config_set_b(core->config, "rop.cache", true);
152+
RzRopSearchContext *context = rz_core_rop_search_context_new(
153+
core, "ret", false, RZ_ROP_GADGET_PRINT, RZ_ROP_DETAIL_SEARCH_NON, NULL);
154+
rz_core_rop_search(core, context);
155+
mu_assert_notnull(core->analysis->ht_rop, "ht_rop should be initialized after cached search");
156+
rz_core_rop_search_context_free(context);
157+
rz_core_free(core);
158+
mu_end;
159+
}
160+
144161
bool all_tests() {
145162
mu_run_test(test_rz_direct_solver);
163+
mu_run_test(test_rop_cache);
146164
return tests_passed != tests_run;
147165
}
148166

0 commit comments

Comments
 (0)