Skip to content

Commit 03ec38b

Browse files
committed
implement rop.cache to store and return cached ROP search results
1 parent ea21a4a commit 03ec38b

File tree

3 files changed

+45
-0
lines changed

3 files changed

+45
-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
@@ -1878,6 +1878,19 @@ static int handle_rop_search_address(RzCore *core, RzRopSearchContext *context,
18781878
RZ_API RzCmdStatus rz_core_rop_search(RZ_NONNULL RzCore *core, RZ_NONNULL RzRopSearchContext *context) {
18791879
rz_return_val_if_fail(core && core->search && context, RZ_CMD_STATUS_ERROR);
18801880

1881+
if (context->cache && context->greparg) {
1882+
if (!core->analysis->ht_rop) {
1883+
core->analysis->ht_rop = ht_up_new(NULL, free);
1884+
}
1885+
ut64 cache_key = rz_str_djb2_hash(context->greparg);
1886+
char *cached_result = ht_up_find(core->analysis->ht_rop, cache_key, NULL);
1887+
if (cached_result) {
1888+
rz_cons_print(cached_result);
1889+
return RZ_CMD_STATUS_OK;
1890+
}
1891+
context->ret_val = true;
1892+
}
1893+
18811894
RzInterval search_itv = { 0 };
18821895
if (!fetch_search_itv(core, &search_itv)) {
18831896
return RZ_CMD_STATUS_ERROR;
@@ -1944,6 +1957,18 @@ RZ_API RzCmdStatus rz_core_rop_search(RZ_NONNULL RzCore *core, RZ_NONNULL RzRopS
19441957
eprintf("\n");
19451958
}
19461959

1960+
if (context->cache && context->greparg && context->buf) {
1961+
ut64 cache_key = rz_str_djb2_hash(context->greparg);
1962+
char *result = rz_strbuf_drain(context->buf);
1963+
context->buf = NULL;
1964+
if (result && *result) {
1965+
ht_up_insert(core->analysis->ht_rop, cache_key, result);
1966+
rz_cons_print(result);
1967+
} else {
1968+
free(result);
1969+
}
1970+
}
1971+
19471972
if (context->state) {
19481973
rz_cmd_state_output_array_end(context->state);
19491974
}

test/unit/test_rop.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,27 @@ 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, "mov", false, RZ_ROP_GADGET_PRINT, RZ_ROP_DETAIL_SEARCH_NON, NULL);
154+
RzCmdStatus status = rz_core_rop_search(core, context);
155+
mu_assert_eq(status, RZ_CMD_STATUS_OK, "rop search should succeed");
156+
mu_assert_notnull(core->analysis->ht_rop, "ht_rop should be initialized after cached search");
157+
rz_core_rop_search_context_free(context);
158+
rz_core_free(core);
159+
mu_end;
160+
}
161+
144162
bool all_tests() {
145163
mu_run_test(test_rz_direct_solver);
164+
mu_run_test(test_rop_cache);
146165
return tests_passed != tests_run;
147166
}
148167

0 commit comments

Comments
 (0)