Split rz_core_get_boundaries_prot and rewrite the code. (#4724)

This commit is contained in:
Giovanni 2024-11-19 12:51:26 +08:00 committed by GitHub
parent 03fccba3a9
commit 266fe6b3c7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
26 changed files with 1056 additions and 532 deletions

View file

@ -605,16 +605,16 @@ RZ_API void rz_bin_set_baddr(RzBin *bin, ut64 baddr) {
*
* \param o Reference to the \p RzBinObject instance
* \param off Address to search
* \param va When 0 the offset \p off is considered a physical address, otherwise a virtual address
* \param va When false the offset \p off is considered a physical address, otherwise a virtual address
* \return Pointer to a \p RzBinSection containing the address
*/
RZ_API RZ_BORROW RzBinSection *rz_bin_get_section_at(RzBinObject *o, ut64 off, int va) {
RZ_API RZ_BORROW RzBinSection *rz_bin_get_section_at(RZ_NONNULL RzBinObject *o, ut64 off, bool va) {
rz_return_val_if_fail(o, NULL);
RzBinSection *section;
void **iter;
ut64 from, to;
rz_return_val_if_fail(o, NULL);
// TODO: must be O(1) .. use sdb here
rz_pvector_foreach (o->sections, iter) {
section = *iter;
if (section->is_segment) {
@ -629,6 +629,35 @@ RZ_API RZ_BORROW RzBinSection *rz_bin_get_section_at(RzBinObject *o, ut64 off, i
return NULL;
}
/**
* \brief Find the binary segment at offset \p off.
*
* \param o Reference to the \p RzBinObject instance
* \param off Address to search
* \param va When false the offset \p off is considered a physical address, otherwise a virtual address
* \return Pointer to a \p RzBinSection containing the address
*/
RZ_API RZ_BORROW RzBinSection *rz_bin_get_segment_at(RZ_NONNULL RzBinObject *o, ut64 off, bool va) {
rz_return_val_if_fail(o, NULL);
RzBinSection *section;
void **iter;
ut64 from, to;
rz_pvector_foreach (o->sections, iter) {
section = *iter;
if (!section->is_segment) {
continue;
}
from = va ? rz_bin_object_addr_with_base(o, section->vaddr) : section->paddr;
to = from + (va ? section->vsize : section->size);
if (off >= from && off < to) {
return section;
}
}
return NULL;
}
/**
* \brief Find the last binary map at offset \p off .
*

View file

@ -162,9 +162,6 @@ RZ_API const char *rz_config_node_type(RzConfigNode *node) {
return "str";
}
if (rz_config_node_is_int(node)) {
if (!strncmp(node->value, "0x", 2)) {
return "addr";
}
return "int";
}
return "";

View file

@ -2091,11 +2091,11 @@ RZ_API bool rz_core_analysis_refs(RZ_NONNULL RzCore *core, size_t nbytes) {
return core_search_for_xrefs_in_boundaries(core, from, to);
}
RzList *list = rz_core_get_boundaries_prot(core, RZ_PERM_X, NULL, "analysis");
RzList *list = rz_core_get_boundaries_select(core, "analysis.from", "analysis.to", "analysis.in");
RzListIter *iter;
RzIOMap *map;
if (!list) {
RZ_LOG_ERROR("cannot find maps with exec permisions\n");
RZ_LOG_ERROR("Cannot get xrefs boundaries when analysis.in=%s.\n", rz_config_get(core->config, "analysis.in"));
return false;
}
@ -4772,7 +4772,11 @@ RZ_IPI void rz_core_analysis_value_pointers(RzCore *core, RzOutputMode mode) {
rz_core_notify_done(core, "Analyze value pointers (aav)");
rz_cons_break_push(NULL, NULL);
if (is_debug) {
RzList *list = rz_core_get_boundaries_prot(core, 0, "dbg.map", "analysis");
RzInterval interval;
interval.addr = rz_config_get_i(core->config, "analysis.from");
interval.size = rz_config_get_i(core->config, "analysis.to") - interval.addr;
RzList *list = rz_core_get_boundaries_all_debug_maps(core, interval);
RzListIter *iter;
RzIOMap *map;
if (!list) {
@ -4788,7 +4792,7 @@ RZ_IPI void rz_core_analysis_value_pointers(RzCore *core, RzOutputMode mode) {
}
rz_list_free(list);
} else {
RzList *list = rz_core_get_boundaries_prot(core, 0, NULL, "analysis");
RzList *list = rz_core_get_boundaries_select(core, "analysis.from", "analysis.to", "analysis.in");
if (!list) {
goto beach;
}
@ -5825,14 +5829,14 @@ RZ_API void rz_core_analysis_calls(RZ_NONNULL RzCore *core, bool imports_only) {
RzBinFile *binfile = rz_bin_cur(core->bin);
addr = core->offset;
if (binfile) {
ranges = rz_core_get_boundaries_prot(core, RZ_PERM_X, NULL, "analysis");
ranges = rz_core_get_boundaries_select(core, "analysis.from", "analysis.to", "analysis.in");
}
rz_cons_break_push(NULL, NULL);
if (!binfile || rz_list_length(ranges) < 1) {
RzListIter *iter;
RzIOMap *map;
rz_list_free(ranges);
ranges = rz_core_get_boundaries_prot(core, 0, NULL, "analysis");
ranges = rz_core_get_boundaries_select(core, "analysis.from", "analysis.to", "analysis.in");
if (ranges) {
rz_list_foreach (ranges, iter, map) {
ut64 addr = map->itv.addr;

775
librz/core/cbounds.c Normal file
View file

@ -0,0 +1,775 @@
// SPDX-FileCopyrightText: 2024 deroad <deroad@kumo.xn--q9jyb4c>
// SPDX-License-Identifier: LGPL-3.0-only
#include <rz_core.h>
static bool add_interval(RzIO *io, RzList /*<RzIOMap *>*/ *list, const RzInterval boundaries, const RzInterval interval, int perms) {
RzInterval map_itv = { 0 };
RzIOMap *map = NULL;
if (interval.addr == UT64_MAX && !interval.size) {
// use the boundaries
map_itv = boundaries;
} else if (rz_itv_overlap(boundaries, interval)) {
// use the intersect.
map_itv = rz_itv_intersect(boundaries, interval);
}
if (!map_itv.size) {
// invalid interval which we always ignore.
return true;
}
map = RZ_NEW0(RzIOMap);
if (!map || !rz_list_append(list, map)) {
RZ_LOG_ERROR("core: failed to allocate and append RzIOMap boundaries.\n");
free(map);
return false;
}
map->itv = map_itv;
map->perm = perms;
if (io && io->desc) {
map->fd = rz_io_fd_get_current(io);
}
return true;
}
static RZ_OWN RzList /*<RzIOMap *>*/ *core_get_boundaries_generic(RzCore *core, ut64 address, ut64 size, const RzInterval interval, int perms) {
RzList *list = NULL;
RzInterval boundaries = { 0 };
boundaries.addr = address;
boundaries.size = size;
if (boundaries.size == UT64_MAX) {
RZ_LOG_ERROR("core: invalid boundaries (size is UT64_MAX).\n");
return NULL;
}
// rz_io_map_free does not exist.
list = rz_list_newf(free);
if (!list) {
RZ_LOG_ERROR("core: failed to allocate RzList for RzIOMap boundaries.\n");
return NULL;
}
if (!add_interval(core->io, list, boundaries, interval, perms)) {
rz_list_free(list);
return NULL;
}
return list;
}
/**
* \brief Returns the malloc:// or the file boundaries as a RzIOMap list
*
* \param core The RzCore to use
* \param interval The requested interval in RzIOMaps
*
* \return On success a valid pointer (can be an empty list), otherwise NULL
*/
RZ_API RZ_OWN RzList /*<RzIOMap *>*/ *rz_core_get_boundaries_raw(RZ_NONNULL RzCore *core, const RzInterval interval) {
rz_return_val_if_fail(core, NULL);
ut64 size = rz_io_size(core->io);
// raw/file is always RWX
return core_get_boundaries_generic(core, 0, size, interval, RZ_PERM_RWX);
}
/**
* \brief Returns the current RzCore block boundaries as a RzIOMap list
*
* \param core The RzCore to use
* \param interval The requested interval in RzIOMaps
*
* \return On success a valid pointer (can be an empty list), otherwise NULL
*/
RZ_API RZ_OWN RzList /*<RzIOMap *>*/ *rz_core_get_boundaries_block(RZ_NONNULL RzCore *core, const RzInterval interval) {
rz_return_val_if_fail(core, NULL);
// block is always RWX
return core_get_boundaries_generic(core, core->offset, core->blocksize, interval, RZ_PERM_RWX);
}
/**
* \brief Returns the current function boundaries as a RzIOMap list
*
* \param core The RzCore to use
* \param interval The requested interval in RzIOMaps
*
* \return On success a valid pointer (can be an empty list), otherwise NULL
*/
RZ_API RZ_OWN RzList /*<RzIOMap *>*/ *rz_core_get_boundaries_current_function(RZ_NONNULL RzCore *core, const RzInterval interval) {
rz_return_val_if_fail(core, NULL);
RzAnalysisFunction *f = rz_analysis_get_fcn_in(core->analysis, core->offset, RZ_ANALYSIS_FCN_TYPE_FCN | RZ_ANALYSIS_FCN_TYPE_SYM);
if (!f) {
RZ_LOG_ERROR("core: invalid function boundaries, not found at 0x%" PFMT64x "\n", core->offset);
return NULL;
}
ut64 from = rz_analysis_function_min_addr(f);
ut64 size = rz_analysis_function_linear_size(f);
return core_get_boundaries_generic(core, from, size, interval, RZ_PERM_RX);
}
/**
* \brief Returns the current basic block boundaries as a RzIOMap list
*
* \param core The RzCore to use
* \param interval The requested interval in RzIOMaps
*
* \return On success a valid pointer (can be an empty list), otherwise NULL
*/
RZ_API RZ_OWN RzList /*<RzIOMap *>*/ *rz_core_get_boundaries_current_function_bb(RZ_NONNULL RzCore *core, const RzInterval interval) {
rz_return_val_if_fail(core, NULL);
RzAnalysisFunction *f = rz_analysis_get_fcn_in(core->analysis, core->offset, RZ_ANALYSIS_FCN_TYPE_FCN | RZ_ANALYSIS_FCN_TYPE_SYM);
if (!f) {
RZ_LOG_ERROR("core: invalid basic block boundaries, function not found at 0x%" PFMT64x "\n", core->offset);
return NULL;
}
void **iter;
RzAnalysisBlock *bb;
rz_pvector_foreach (f->bbs, iter) {
bb = (RzAnalysisBlock *)*iter;
if (RZ_BETWEEN(bb->addr, core->offset, (bb->addr + bb->size))) {
return core_get_boundaries_generic(core, bb->addr, bb->size, interval, RZ_PERM_RX);
}
}
RZ_LOG_ERROR("core: invalid basic block boundaries, bb not found at 0x%" PFMT64x "\n", core->offset);
return NULL;
}
/**
* \brief Returns the current RzIO map boundaries as a RzIOMap list
*
* \param core The RzCore to use
* \param interval The requested interval in RzIOMaps
*
* \return On success a valid pointer (can be an empty list), otherwise NULL
*/
RZ_API RZ_OWN RzList /*<RzIOMap *>*/ *rz_core_get_boundaries_current_io_map(RZ_NONNULL RzCore *core, const RzInterval interval) {
rz_return_val_if_fail(core, NULL);
const RzIOMap *m = rz_io_map_get(core->io, core->offset);
if (!m) {
// return an empty list.
return rz_list_newf(free);
}
return core_get_boundaries_generic(core, m->itv.addr, m->itv.size, interval, m->perm);
}
/**
* \brief Returns the current RzBin section boundaries as a RzIOMap list
*
* \param core The RzCore to use
* \param interval The requested interval in RzIOMaps
*
* \return On success a valid pointer (can be an empty list), otherwise NULL
*/
RZ_API RZ_OWN RzList /*<RzIOMap *>*/ *rz_core_get_boundaries_current_bin_section(RZ_NONNULL RzCore *core, const RzInterval interval) {
rz_return_val_if_fail(core, NULL);
bool va = rz_config_get_b(core->config, "io.va");
RzBinObject *obj = rz_bin_cur_object(core->bin);
RzBinSection *elem = NULL;
if (!obj || !(elem = rz_bin_get_section_at(obj, core->offset, va))) {
// return an empty list
return rz_list_newf(free);
}
if (va) {
// virtual
return core_get_boundaries_generic(core, elem->vaddr, elem->vsize, interval, elem->perm);
}
// physical
return core_get_boundaries_generic(core, elem->paddr, elem->size, interval, elem->perm);
}
/**
* \brief Returns the current RzBin segment boundaries as a RzIOMap list
*
* \param core The RzCore to use
* \param interval The requested interval in RzIOMaps
*
* \return On success a valid pointer (can be an empty list), otherwise NULL
*/
RZ_API RZ_OWN RzList /*<RzIOMap *>*/ *rz_core_get_boundaries_current_bin_segment(RZ_NONNULL RzCore *core, const RzInterval interval) {
rz_return_val_if_fail(core, NULL);
bool va = rz_config_get_b(core->config, "io.va");
RzBinObject *obj = rz_bin_cur_object(core->bin);
RzBinSection *elem = NULL;
if (!obj || !(elem = rz_bin_get_segment_at(obj, core->offset, va))) {
// return an empty list
return rz_list_newf(free);
}
if (va) {
// virtual
return core_get_boundaries_generic(core, elem->vaddr, elem->vsize, interval, elem->perm);
}
// physical
return core_get_boundaries_generic(core, elem->paddr, elem->size, interval, elem->perm);
}
/**
* \brief Returns the RzIO maps boundaries as a RzIOMap list
*
* \param core The RzCore to use
* \param interval The requested interval in RzIOMaps
* \param perms The permissions to match
* \param perms_mask The permissions mask filter
*
* \return On success a valid pointer (can be an empty list), otherwise NULL
*/
RZ_API RZ_OWN RzList /*<RzIOMap *>*/ *rz_core_get_boundaries_io_maps(RZ_NONNULL RzCore *core, const RzInterval interval, int perms, int perms_mask) {
rz_return_val_if_fail(core, NULL);
void **it;
RzList *list = NULL;
RzPVector *maps = rz_io_maps(core->io);
// rz_io_map_free does not exist.
list = rz_list_newf(free);
if (!list) {
RZ_LOG_ERROR("core: failed to allocate RzList for io.maps boundaries.\n");
return NULL;
}
rz_pvector_foreach (maps, it) {
RzIOMap *map = *it;
if ((map->perm & perms_mask) != perms) {
continue;
}
if (!add_interval(core->io, list, map->itv, interval, map->perm)) {
rz_list_free(list);
return NULL;
}
}
return list;
}
/**
* \brief Returns the RzIO skyline boundaries as a RzIOMap list
*
* \param core The RzCore to use
* \param interval The requested interval in RzIOMaps
* \param perms The permissions to match
* \param perms_mask The permissions mask filter
*
* \return On success a valid pointer (can be an empty list), otherwise NULL
*/
RZ_API RZ_OWN RzList /*<RzIOMap *>*/ *rz_core_get_boundaries_io_skyline(RZ_NONNULL RzCore *core, const RzInterval interval, int perms, int perms_mask) {
rz_return_val_if_fail(core, NULL);
RzList *list = NULL;
RzVector *skyline = core->io ? &core->io->map_skyline.v : NULL;
size_t skyline_size = skyline ? rz_vector_len(skyline) : 0;
// rz_io_map_free does not exist.
list = rz_list_newf(free);
if (!list) {
RZ_LOG_ERROR("core: failed to allocate RzList for io.sky boundaries.\n");
return NULL;
}
for (size_t i = 0; i < skyline_size; i++) {
const RzSkylineItem *item = rz_vector_index_ptr(skyline, i);
RzIOMap *map = ((RzIOMap *)item->user);
if ((map->perm & perms_mask) != perms) {
continue;
}
if (!add_interval(core->io, list, item->itv, interval, map->perm)) {
rz_list_free(list);
return NULL;
}
}
return list;
}
/**
* \brief Returns the RzBin segments boundaries as a RzIOMap list
*
* \param core The RzCore to use
* \param interval The requested interval in RzIOMaps
* \param perms The permissions to match
* \param perms_mask The permissions mask filter
*
* \return On success a valid pointer (can be an empty list), otherwise NULL
*/
RZ_API RZ_OWN RzList /*<RzIOMap *>*/ *rz_core_get_boundaries_bin_segments(RZ_NONNULL RzCore *core, const RzInterval interval, int perms, int perms_mask) {
rz_return_val_if_fail(core, NULL);
void **iter = NULL;
RzList *list = NULL;
RzInterval boundaries = { 0 };
bool va = rz_config_get_b(core->config, "io.va");
RzBinObject *obj = rz_bin_cur_object(core->bin);
RzPVector *pvec = NULL;
// rz_io_map_free does not exist.
list = rz_list_newf(free);
if (!list) {
RZ_LOG_ERROR("core: failed to allocate RzList for io.segments boundaries.\n");
return NULL;
}
if (obj) {
// returns as RZ_OWN
pvec = rz_bin_object_get_segments(obj);
}
rz_pvector_foreach (pvec, iter) {
RzBinSection *elem = *iter;
if ((elem->perm & perms_mask) != perms) {
continue;
}
if (va) {
// virtual
boundaries.addr = elem->vaddr;
boundaries.size = elem->vsize;
} else {
// physical
boundaries.addr = elem->paddr;
boundaries.size = elem->size;
}
if (!add_interval(core->io, list, boundaries, interval, elem->perm)) {
rz_list_free(list);
list = NULL;
break;
}
}
rz_pvector_free(pvec);
return list;
}
/**
* \brief Returns the RzBin sections boundaries as a RzIOMap list
*
* \param core The RzCore to use
* \param interval The requested interval in RzIOMaps
* \param perms The permissions to match
* \param perms_mask The permissions mask filter
*
* \return On success a valid pointer (can be an empty list), otherwise NULL
*/
RZ_API RZ_OWN RzList /*<RzIOMap *>*/ *rz_core_get_boundaries_bin_sections(RZ_NONNULL RzCore *core, const RzInterval interval, int perms, int perms_mask) {
rz_return_val_if_fail(core, NULL);
void **iter = NULL;
RzList *list = NULL;
RzInterval boundaries = { 0 };
bool va = rz_config_get_b(core->config, "io.va");
RzBinObject *obj = rz_bin_cur_object(core->bin);
RzPVector *pvec = NULL;
// rz_io_map_free does not exist.
list = rz_list_newf(free);
if (!list) {
RZ_LOG_ERROR("core: failed to allocate RzList for io.segments boundaries.\n");
return NULL;
}
if (obj) {
// returns as RZ_OWN
pvec = rz_bin_object_get_sections(obj);
}
rz_pvector_foreach (pvec, iter) {
RzBinSection *elem = *iter;
if ((elem->perm & perms_mask) != perms) {
continue;
}
if (va) {
// virtual
boundaries.addr = elem->vaddr;
boundaries.size = elem->vsize;
} else {
// physical
boundaries.addr = elem->paddr;
boundaries.size = elem->size;
}
if (!add_interval(core->io, list, boundaries, interval, elem->perm)) {
rz_list_free(list);
list = NULL;
break;
}
}
rz_pvector_free(pvec);
return list;
}
/**
* \brief Returns all the RzBin sections or RzIO maps with exec perms set as boundaries list of RzIOMap
*
* \param core The RzCore to use
* \param interval The requested interval in RzIOMaps
*
* \return On success a valid pointer (can be an empty list), otherwise NULL
*/
RZ_API RZ_OWN RzList /*<RzIOMap *>*/ *rz_core_get_boundaries_code_only(RZ_NONNULL RzCore *core, const RzInterval interval) {
rz_return_val_if_fail(core, NULL);
void **iter = NULL;
RzList *list = NULL;
RzInterval boundaries = { 0 };
bool va = rz_config_get_b(core->config, "io.va");
RzBinObject *obj = rz_bin_cur_object(core->bin);
RzPVector *pvec = NULL;
// rz_io_map_free does not exist.
list = rz_list_newf(free);
if (!list) {
RZ_LOG_ERROR("core: failed to allocate RzList for code-only boundaries.\n");
return NULL;
}
if (obj) {
// returns as RZ_OWN
pvec = rz_bin_object_get_sections(obj);
}
rz_pvector_foreach (pvec, iter) {
RzBinSection *elem = *iter;
if (!(elem->perm & RZ_PERM_X)) {
continue;
}
if (va) {
// virtual
boundaries.addr = elem->vaddr;
boundaries.size = elem->vsize;
} else {
// physical
boundaries.addr = elem->paddr;
boundaries.size = elem->size;
}
if (!add_interval(core->io, list, boundaries, interval, elem->perm)) {
rz_list_free(list);
list = NULL;
break;
}
}
rz_pvector_free(pvec);
if (rz_list_empty(list)) {
// if no matches with sections, then we use maps.
pvec = rz_io_maps(core->io);
rz_pvector_foreach (pvec, iter) {
RzIOMap *map = *iter;
if (!(map->perm & RZ_PERM_X)) {
continue;
}
if (!add_interval(core->io, list, map->itv, interval, map->perm)) {
rz_list_free(list);
return NULL;
}
}
}
return list;
}
/**
* \brief Returns the RzDebug maps boundaries as a RzIOMap list
*
* \param core The RzCore to use
* \param interval The requested interval in RzIOMaps
* \param perms The permissions to match
* \param perms_mask The permissions mask filter
* \param current When true, returns only the RzIOMaps that matches the current offset
*
* \return On success a valid pointer (can be an empty list), otherwise NULL
*/
RZ_API RZ_OWN RzList /*<RzIOMap *>*/ *rz_core_get_boundaries_debug_maps(RZ_NONNULL RzCore *core, const RzInterval interval, int perms, int perms_mask, bool current) {
rz_return_val_if_fail(core, NULL);
if (!core->bin->is_debugger) {
RZ_LOG_ERROR("core: no debugger connected for debug maps boundaries.\n");
return NULL;
}
// ensure data is syncronized
rz_debug_map_sync(core->dbg);
RzList *list = NULL;
RzListIter *iter = NULL;
RzDebugMap *map = NULL;
RzInterval boundaries;
// rz_io_map_free does not exist.
list = rz_list_newf(free);
if (!list) {
RZ_LOG_ERROR("core: failed to allocate RzList for io.maps boundaries.\n");
return NULL;
}
rz_list_foreach (core->dbg->maps, iter, map) {
if ((map->perm & perms_mask) != perms) {
continue;
}
boundaries.addr = map->addr;
boundaries.size = map->addr_end - map->addr;
if (current) {
// accept only elements which includes the current offset.
const ut64 begin = rz_itv_begin(boundaries);
const ut64 end = rz_itv_end(boundaries);
if (!RZ_BETWEEN(begin, core->offset, end)) {
continue;
}
}
if (!add_interval(core->io, list, boundaries, interval, map->perm)) {
rz_list_free(list);
return NULL;
}
}
return list;
}
/**
* \brief Returns the RzDebug heap boundaries as a RzIOMap list
*
* \param core The RzCore to use
* \param interval The requested interval in RzIOMaps
*
* \return On success a valid pointer (can be an empty list), otherwise NULL
*/
RZ_API RZ_OWN RzList /*<RzIOMap *>*/ *rz_core_get_boundaries_debug_heap(RZ_NONNULL RzCore *core, const RzInterval interval) {
rz_return_val_if_fail(core, NULL);
if (!core->bin->is_debugger) {
RZ_LOG_ERROR("core: no debugger connected for debug heap boundaries.\n");
return NULL;
}
// ensure data is syncronized
rz_debug_map_sync(core->dbg);
RzList *list = NULL;
RzListIter *iter = NULL;
RzDebugMap *map = NULL;
RzInterval boundaries;
// rz_io_map_free does not exist.
list = rz_list_newf(free);
if (!list) {
RZ_LOG_ERROR("core: failed to allocate RzList for debug heap boundaries.\n");
return NULL;
}
rz_list_foreach (core->dbg->maps, iter, map) {
if (!strstr(map->name, "heap") || !(map->perm & RZ_PERM_W)) {
continue;
}
boundaries.addr = map->addr;
boundaries.size = map->addr_end - map->addr;
if (!add_interval(core->io, list, boundaries, interval, map->perm)) {
rz_list_free(list);
return NULL;
}
}
return list;
}
/**
* \brief Returns the RzDebug stack boundaries as a RzIOMap list
*
* \param core The RzCore to use
* \param interval The requested interval in RzIOMaps
*
* \return On success a valid pointer (can be an empty list), otherwise NULL
*/
RZ_API RZ_OWN RzList /*<RzIOMap *>*/ *rz_core_get_boundaries_debug_stack(RZ_NONNULL RzCore *core, const RzInterval interval) {
rz_return_val_if_fail(core, NULL);
if (!core->bin->is_debugger) {
RZ_LOG_ERROR("core: no debugger connected for debug stack boundaries.\n");
return NULL;
}
// ensure data is syncronized
rz_debug_map_sync(core->dbg);
RzList *list = NULL;
RzListIter *iter = NULL;
RzDebugMap *map = NULL;
RzInterval boundaries;
// rz_io_map_free does not exist.
list = rz_list_newf(free);
if (!list) {
RZ_LOG_ERROR("core: failed to allocate RzList for debug stack boundaries.\n");
return NULL;
}
rz_list_foreach (core->dbg->maps, iter, map) {
if (!strstr(map->name, "stack")) {
continue;
}
boundaries.addr = map->addr;
boundaries.size = map->addr_end - map->addr;
if (!add_interval(core->io, list, boundaries, interval, map->perm)) {
rz_list_free(list);
return NULL;
}
}
return list;
}
/**
* \brief Returns the RzDebug exec-set maps boundaries as a RzIOMap list
*
* \param core The RzCore to use
* \param interval The requested interval in RzIOMaps
*
* \return On success a valid pointer (can be an empty list), otherwise NULL
*/
RZ_API RZ_OWN RzList /*<RzIOMap *>*/ *rz_core_get_boundaries_debug_program(RZ_NONNULL RzCore *core, const RzInterval interval) {
rz_return_val_if_fail(core, NULL);
if (!core->bin->is_debugger) {
RZ_LOG_ERROR("core: no debugger connected for debug program boundaries.\n");
return NULL;
}
// ensure data is syncronized
rz_debug_map_sync(core->dbg);
RzList *list = NULL;
RzListIter *iter = NULL;
RzDebugMap *map = NULL;
RzInterval boundaries;
// rz_io_map_free does not exist.
list = rz_list_newf(free);
if (!list) {
RZ_LOG_ERROR("core: failed to allocate RzList for debug program boundaries.\n");
return NULL;
}
rz_list_foreach (core->dbg->maps, iter, map) {
if (!(map->perm & RZ_PERM_X)) {
continue;
}
boundaries.addr = map->addr;
boundaries.size = map->addr_end - map->addr;
if (!add_interval(core->io, list, boundaries, interval, map->perm)) {
rz_list_free(list);
return NULL;
}
}
return list;
}
/**
* \brief Returns a list of boundaries (as RzIOMap), based on the selected mode; see [search/analysis/zoom/[in/from/to]] for available modes.
*
* \param core The RzCore to use
* \param from_key The [search|analysis|zoom].from keyword to use in RzConfig
* \param to_key The [search|analysis|zoom].to keyword to use in RzConfig
* \param in_key The [search|analysis|zoom].in keyword to use in RzConfig
*
* \return On success a valid pointer (can be an empty list), otherwise NULL
*/
RZ_API RZ_OWN RzList /*<RzIOMap *>*/ *rz_core_get_boundaries_select(RZ_NONNULL RzCore *core, RZ_NONNULL const char *from_key, RZ_NONNULL const char *to_key, RZ_NONNULL const char *in_key) {
rz_return_val_if_fail(core && from_key && to_key && in_key, NULL);
RzInterval interval;
ut64 from = rz_config_get_i(core->config, from_key);
ut64 to = rz_config_get_i(core->config, to_key);
const char *use_mode = rz_config_get(core->config, in_key);
interval.addr = from;
interval.size = to - from;
if (!strcmp(use_mode, "raw") || !strcmp(use_mode, "file")) {
return rz_core_get_boundaries_raw(core, interval);
} else if (!strcmp(use_mode, "block")) {
return rz_core_get_boundaries_block(core, interval);
} else if (!strcmp(use_mode, "dbg.map")) {
return rz_core_get_boundaries_current_debug_map(core, interval);
} else if (!strcmp(use_mode, "io.map")) {
return rz_core_get_boundaries_current_io_map(core, interval);
} else if (!strcmp(use_mode, "range") || !strcmp(use_mode, "io.maps")) {
return rz_core_get_boundaries_all_io_maps(core, interval);
} else if (!strcmp(use_mode, "io.sky")) {
return rz_core_get_boundaries_all_io_skyline(core, interval);
} else if (!strcmp(use_mode, "code")) {
return rz_core_get_boundaries_code_only(core, interval);
} else if (!strcmp(use_mode, "bin.segment")) {
return rz_core_get_boundaries_current_bin_segment(core, interval);
} else if (!strcmp(use_mode, "bin.section")) {
return rz_core_get_boundaries_current_bin_section(core, interval);
} else if (!strcmp(use_mode, "bin.segments")) {
return rz_core_get_boundaries_all_bin_segments(core, interval);
} else if (!strcmp(use_mode, "bin.sections")) {
return rz_core_get_boundaries_all_bin_sections(core, interval);
} else if (!strcmp(use_mode, "analysis.fcn")) {
return rz_core_get_boundaries_current_function(core, interval);
} else if (!strcmp(use_mode, "analysis.bb")) {
return rz_core_get_boundaries_current_function_bb(core, interval);
} else if (!strcmp(use_mode, "dbg.maps")) {
return rz_core_get_boundaries_all_debug_maps(core, interval);
} else if (!strcmp(use_mode, "dbg.heap")) {
return rz_core_get_boundaries_debug_heap(core, interval);
} else if (!strcmp(use_mode, "dbg.stack")) {
return rz_core_get_boundaries_debug_stack(core, interval);
} else if (!strcmp(use_mode, "dbg.program")) {
return rz_core_get_boundaries_debug_program(core, interval);
} else if (rz_str_startswith(use_mode, "dbg.maps.")) {
#define PARSE_PERMS(input, mode_name) rz_str_rwx(input + strlen(mode_name))
int perms = PARSE_PERMS(use_mode, "dbg.maps.");
return rz_core_get_boundaries_debug_maps(core, interval, perms, perms, false);
} else if (rz_str_startswith(use_mode, "io.sky.")) {
int perms = PARSE_PERMS(use_mode, "io.sky.");
return rz_core_get_boundaries_io_skyline(core, interval, perms, perms);
} else if (rz_str_startswith(use_mode, "io.maps.")) {
int perms = PARSE_PERMS(use_mode, "io.maps.");
return rz_core_get_boundaries_io_maps(core, interval, perms, perms);
} else if (rz_str_startswith(use_mode, "bin.segments.")) {
int perms = PARSE_PERMS(use_mode, "bin.segments.");
return rz_core_get_boundaries_bin_segments(core, interval, perms, perms);
} else if (rz_str_startswith(use_mode, "bin.sections.")) {
int perms = PARSE_PERMS(use_mode, "bin.sections.");
return rz_core_get_boundaries_bin_sections(core, interval, perms, perms);
#undef PARSE_PERMS
}
RZ_LOG_ERROR("core: unknown mode '%s' for %s\n", use_mode, in_key);
return NULL;
}

View file

@ -10,6 +10,11 @@
#include "core_private.h"
typedef struct config_opt_descr {
const char *option;
const char *description;
} ConfigOptDescr;
static bool boolify_var_cb(void *user, void *data) {
RzConfigNode *node = (RzConfigNode *)data;
if (node->i_value || rz_str_is_false(node->value)) {
@ -2623,41 +2628,72 @@ static bool cb_binprefix(void *user, void *data) {
return true;
}
static bool cb_searchin(void *user, void *data) {
static ConfigOptDescr search_in_opts[] = {
{ "raw", "all raw memory (behaves as 'file')" },
{ "file", "all the file" },
{ "block", "current read block" },
{ "range", "search only within the range" },
{ "analysis.bb", "current basic-block" },
{ "analysis.fcn", "current function" },
{ "bin.section", "current section" },
{ "bin.sections[.rwx]", "all bin sections (with matching perm)" },
{ "bin.segment", "current segment" },
{ "bin.segments[.rwx]", "all bin segments (with matching perm)" },
{ "dbg.heap", "debugger heap" },
{ "dbg.stack", "debugger stack" },
{ "dbg.program", "debugger program (exec only)" },
{ "dbg.map", "current debugger memory map" },
{ "dbg.maps[.rwx]", "all debugger memory maps (with matching perm)" },
{ "io.map", "current io map" },
{ "io.maps[.rwx]", "all io maps (with matching perm)" },
{ "io.sky[.rwx]", "all skyline segments (with matching perm)" },
};
static bool cb_search_in(void *user, void *data) {
RzConfigNode *node = (RzConfigNode *)data;
if (node->value[0] != '?') {
return true;
} else if (strlen(node->value) > 1 && node->value[1] == '?') {
rz_cons_printf("Valid values for search.in (depends on .from/.to and io.va):\n");
for (size_t i = 0; i < RZ_ARRAY_SIZE(search_in_opts); ++i) {
rz_cons_printf("%-18s - %s\n", search_in_opts[i].option, search_in_opts[i].description);
}
} else {
print_node_options(node);
}
return false;
}
static bool cb_analysis_in(void *user, void *data) {
RzCore *core = (RzCore *)user;
RzConfigNode *node = (RzConfigNode *)data;
if (node->value[0] == '?') {
if (strlen(node->value) > 1 && node->value[1] == '?') {
rz_cons_printf("Valid values for search.in (depends on .from/.to and io.va):\n"
"raw search in raw io (ignoring bounds)\n"
"block search in the current block\n"
"io.map search in current map\n"
"io.sky.[rwx] search in all skyline segments\n"
"io.maps search in all maps\n"
"io.maps.[rwx] search in all r-w-x io maps\n"
"bin.segment search in current mapped segment\n"
"bin.segments search in all mapped segments\n"
"bin.segments.[rwx] search in all r-w-x segments\n"
"bin.section search in current mapped section\n"
"bin.sections search in all mapped sections\n"
"bin.sections.[rwx] search in all r-w-x sections\n"
"dbg.stack search in the stack\n"
"dbg.heap search in the heap\n"
"dbg.map search in current memory map\n"
"dbg.maps search in all memory maps\n"
"dbg.maps.[rwx] search in all executable marked memory maps\n"
"analysis.fcn search in the current function\n"
"analysis.bb search in the current basic-block\n");
} else {
print_node_options(node);
}
return false;
}
// Set analysis.noncode if exec bit set in analysis.in
if (rz_str_startswith(node->name, "analysis")) {
if (node->value[0] != '?') {
core->analysis->opt.noncode = (strchr(node->value, 'x') == NULL);
return true;
} else if (strlen(node->value) > 1 && node->value[1] == '?') {
rz_cons_printf("Valid values for analysis.in (depends on .from/.to and io.va):\n");
for (size_t i = 0; i < RZ_ARRAY_SIZE(search_in_opts); ++i) {
rz_cons_printf("%-18s - %s\n", search_in_opts[i].option, search_in_opts[i].description);
}
} else {
print_node_options(node);
}
return true;
return false;
}
static bool cb_zoom_in(void *user, void *data) {
RzConfigNode *node = (RzConfigNode *)data;
if (node->value[0] != '?') {
return true;
} else if (strlen(node->value) > 1 && node->value[1] == '?') {
rz_cons_printf("Valid values for zoom.in (depends on .from/.to and io.va):\n");
for (size_t i = 0; i < RZ_ARRAY_SIZE(search_in_opts); ++i) {
rz_cons_printf("%-18s - %s\n", search_in_opts[i].option, search_in_opts[i].description);
}
} else {
print_node_options(node);
}
return false;
}
static int __dbg_swstep_getter(void *user, RzConfigNode *node) {
@ -2703,9 +2739,16 @@ static bool cb_analysis_gp(RzCore *core, RzConfigNode *node) {
static bool cb_analysis_from(RzCore *core, RzConfigNode *node) {
if (rz_config_get_i(core->config, "analysis.limits")) {
rz_analysis_set_limits(core->analysis,
rz_config_get_i(core->config, "analysis.from"),
rz_config_get_i(core->config, "analysis.to"));
ut64 to = rz_config_get_i(core->config, "analysis.to");
rz_analysis_set_limits(core->analysis, node->i_value, to);
}
return true;
}
static bool cb_analysis_to(RzCore *core, RzConfigNode *node) {
if (rz_config_get_i(core->config, "analysis.limits")) {
ut64 from = rz_config_get_i(core->config, "analysis.from");
rz_analysis_set_limits(core->analysis, from, node->i_value);
}
return true;
}
@ -2719,13 +2762,13 @@ static bool cb_analysis_limits(void *user, RzConfigNode *node) {
} else {
rz_analysis_unset_limits(core->analysis);
}
return 1;
return true;
}
static bool cb_analysis_rnr(void *user, RzConfigNode *node) {
RzCore *core = (RzCore *)user;
core->analysis->recursive_noreturn = node->i_value;
return 1;
return true;
}
static bool cb_analysis_jmptbl(void *user, void *data) {
@ -2986,9 +3029,9 @@ RZ_API int rz_core_config_init(RzCore *core) {
SETCB("analysis.limits", "false", (RzConfigCallback)&cb_analysis_limits, "Restrict analysis to address range [analysis.from:analysis.to]");
SETCB("analysis.rnr", "false", (RzConfigCallback)&cb_analysis_rnr, "Recursive no return checks (EXPERIMENTAL)");
SETCB("analysis.limits", "false", (RzConfigCallback)&cb_analysis_limits, "Restrict analysis to address range [analysis.from:analysis.to]");
SETICB("analysis.from", -1, (RzConfigCallback)&cb_analysis_from, "Lower limit on the address range for analysis");
SETICB("analysis.to", -1, (RzConfigCallback)&cb_analysis_from, "Upper limit on the address range for analysis");
n = NODECB("analysis.in", "io.maps.x", &cb_searchin);
SETICB("analysis.from", UT64_MAX, (RzConfigCallback)&cb_analysis_from, "Lower limit on the address range for analysis");
SETICB("analysis.to", UT64_MAX, (RzConfigCallback)&cb_analysis_to, "Upper limit on the address range for analysis");
n = NODECB("analysis.in", "io.maps.x", &cb_analysis_in);
SETDESC(n, "Specify search boundaries for analysis");
SETOPTIONS(n, "range", "block",
"bin.segment", "bin.segments", "bin.segments.x", "bin.segments.r", "bin.section", "bin.sections", "bin.sections.rwx", "bin.sections.r", "bin.sections.rw", "bin.sections.rx", "bin.sections.wx", "bin.sections.x",
@ -3710,8 +3753,9 @@ RZ_API int rz_core_config_init(RzCore *core) {
SETBPREF("search.flags", "true", "All search results are flagged, otherwise only printed");
SETBPREF("search.overlap", "false", "Look for overlapped search hits");
SETI("search.maxhits", 0, "Maximum number of hits (0: no limit)");
SETI("search.from", -1, "Search start address");
n = NODECB("search.in", "io.maps", &cb_searchin);
SETI("search.from", 0, "Search start address");
SETI("search.to", UT64_MAX, "Search end address");
n = NODECB("search.in", "io.maps", &cb_search_in);
SETDESC(n, "Specify search boundaries");
SETOPTIONS(n, "raw", "block",
"bin.section", "bin.sections", "bin.sections.rwx", "bin.sections.r", "bin.sections.rw", "bin.sections.rx", "bin.sections.wx", "bin.sections.x",
@ -3795,7 +3839,7 @@ RZ_API int rz_core_config_init(RzCore *core) {
SETI("zoom.from", 0, "Zoom start address");
SETI("zoom.maxsz", 512, "Zoom max size of block");
SETI("zoom.to", 0, "Zoom end address");
n = NODECB("zoom.in", "io.map", &cb_searchin);
n = NODECB("zoom.in", "io.map", &cb_zoom_in);
SETDESC(n, "Specify boundaries for zoom");
SETOPTIONS(n, "raw", "block",
"bin.section", "bin.sections", "bin.sections.rwx", "bin.sections.r", "bin.sections.rw", "bin.sections.rx", "bin.sections.wx", "bin.sections.x",

View file

@ -409,7 +409,7 @@ RZ_IPI int rz_core_analysis_set_reg(RzCore *core, const char *regname, ut64 val)
RZ_IPI void rz_core_analysis_esil_default(RzCore *core) {
RzIOMap *map;
RzListIter *iter;
RzList *list = rz_core_get_boundaries_prot(core, -1, NULL, "analysis");
RzList *list = rz_core_get_boundaries_select(core, "analysis.from", "analysis.to", "analysis.in");
if (!list) {
return;
}

View file

@ -6146,9 +6146,9 @@ RZ_IPI RzCmdStatus rz_analyze_all_consecutive_functions_in_section_handler(RzCor
ut64 old_offset = core->offset;
RzListIter *iter;
RzIOMap *map;
RzList *list = rz_core_get_boundaries_prot(core, RZ_PERM_X, NULL, "analysis");
RzList *list = rz_core_get_boundaries_select(core, "analysis.from", "analysis.to", "analysis.in");
if (!list) {
RZ_LOG_ERROR("Cannot find maps with exec permisions.\n");
RZ_LOG_ERROR("Cannot get boundaries when analysis.in=%s.\n", rz_config_get(core->config, "analysis.in"));
return RZ_CMD_STATUS_ERROR;
}

View file

@ -1354,8 +1354,7 @@ static void trace_traverse(RTree *t) {
}
static void do_debug_trace_calls(RzCore *core, ut64 from, ut64 to, ut64 final_addr) {
bool trace_libs = rz_config_get_i(core->config, "dbg.trace.libs");
bool shallow_trace = rz_config_get_i(core->config, "dbg.trace.inrange");
bool shallow_trace = rz_config_get_b(core->config, "dbg.trace.inrange");
HtUP *tracenodes = core->dbg->tracenodes;
RTree *tr = core->dbg->tree;
RzDebug *dbg = core->dbg;
@ -1364,13 +1363,6 @@ static void do_debug_trace_calls(RzCore *core, ut64 from, ut64 to, ut64 final_ad
ut64 addr = 0;
int n = 0;
if (!trace_libs) {
#if NOOP
RzList *bounds = rz_core_get_boundaries_prot(core, -1, "dbg.program", "search");
rz_list_free(bounds);
#endif
}
/* set root if not already present */
rz_tree_add_node(tr, NULL, NULL);
cur = tr->root;

View file

@ -30,13 +30,11 @@ static int rz_core_magic_at(RzCore *core, const char *file, ut64 addr, int depth
goto seek_exit;
}
if (addr != core->offset) {
#if 1
if (addr >= core->offset && (addr + NAH) < (core->offset + core->blocksize)) {
delta = addr - core->offset;
} else {
rz_core_seek(core, addr, true);
}
#endif
}
if (core->search->align) {
int mod = addr % core->search->align;

View file

@ -289,18 +289,42 @@ RZ_IPI RzCmdStatus rz_check_between_handler(RzCore *core, int argc, const char *
return RZ_CMD_STATUS_OK;
}
RZ_IPI RzCmdStatus rz_print_boundaries_prot_handler(RzCore *core, int argc, const char **argv) {
const char *mode = rz_str_trim_head_ro(argv[1]);
RzList *list = rz_core_get_boundaries_prot(core, -1, mode, "search");
RZ_IPI RzCmdStatus rz_print_boundaries_prot_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) {
RzList *list = rz_core_get_boundaries_select(core, "search.from", "search.to", "search.in");
if (!list) {
RZ_LOG_ERROR("Failed to get boundaries protection values in RzList\n");
return RZ_CMD_STATUS_ERROR;
}
rz_cmd_state_output_array_start(state);
rz_cmd_state_output_set_columnsf(state, "xxns", "from", "to", "size", "perms");
RzListIter *iter;
RzIOMap *map;
rz_list_foreach (list, iter, map) {
rz_cons_printf("0x%" PFMT64x " 0x%" PFMT64x "\n", map->itv.addr, rz_itv_end(map->itv));
ut64 from = map->itv.addr;
ut64 to = rz_itv_end(map->itv);
ut64 size = map->itv.size;
const char *perm = rz_str_rwx_i(map->perm);
switch (state->mode) {
default:
rz_cons_printf("0x%" PFMT64x " 0x%" PFMT64x "\n", from, to);
break;
case RZ_OUTPUT_MODE_JSON:
pj_o(state->d.pj);
pj_kn(state->d.pj, "from", from);
pj_kn(state->d.pj, "to", to);
pj_kn(state->d.pj, "size", size);
pj_ks(state->d.pj, "perms", perm);
pj_end(state->d.pj);
break;
case RZ_OUTPUT_MODE_TABLE:
rz_table_add_rowf(state->d.t, "xxns", from, to, size, perm);
break;
}
}
rz_cmd_state_output_array_end(state);
rz_list_free(list);
return RZ_CMD_STATUS_OK;
}

View file

@ -4764,7 +4764,7 @@ static RzCoreAnalysisStatsRange *analysis_stats_range(RzCore *core, int width) {
ut64 from = UT64_MAX;
ut64 to = 0;
RzList *list = rz_core_get_boundaries_prot(core, -1, NULL, "search");
RzList *list = rz_core_get_boundaries_select(core, "search.from", "search.to", "search.in");
if (rz_list_empty(list)) {
RZ_LOG_ERROR("No range to calculate stats for.\n");
rz_list_free(list);
@ -5286,7 +5286,7 @@ static CoreBlockRange *calculate_blocks_range(RzCore *core, ut64 from, ut64 to,
st64 blocksize = core->blocksize;
// If we are not in the debug mode - use only current mapped ranges
if (!rz_config_get_b(core->config, "cfg.debug")) {
RzList *boundaries = rz_core_get_boundaries_prot(core, -1, NULL, "zoom");
RzList *boundaries = rz_core_get_boundaries_select(core, "zoom.from", "zoom.to", "zoom.in");
if (!boundaries) {
free(brange);
return NULL;

View file

@ -346,10 +346,9 @@ RZ_API int rz_core_search_preludes(RzCore *core, bool log) {
int keyword_length = 0;
ut8 *keyword = NULL;
const char *prelude = rz_config_get(core->config, "analysis.prelude");
const char *where = rz_config_get(core->config, "analysis.in");
ut64 limit = rz_config_get_i(core->config, "analysis.prelude.limit");
RzList *list = rz_core_get_boundaries_prot(core, RZ_PERM_X, where, "search");
RzList *list = rz_core_get_boundaries_select(core, "search.from", "search.to", "search.in");
RzList *arch_preludes = NULL;
RzListIter *iter = NULL, *iter2 = NULL;
RzIOMap *p = NULL;
@ -552,428 +551,6 @@ static inline void print_search_progress(ut64 at, ut64 to, int n, struct search_
}
}
static void append_bound(RzList /*<RzIOMap *>*/ *list, RzIO *io, RzInterval search_itv, ut64 from, ut64 size, int perms) {
RzIOMap *map = RZ_NEW0(RzIOMap);
if (!map) {
return;
}
if (io && io->desc) {
map->fd = rz_io_fd_get_current(io);
}
map->perm = perms;
RzInterval itv = { from, size };
if (size == -1) {
RZ_LOG_ERROR("core: Invalid range. Use different search.in=? or analysis.in=dbg.maps.x\n");
free(map);
return;
}
// TODO UT64_MAX is a valid address. search.from and search.to are not specified
if (search_itv.addr == UT64_MAX && !search_itv.size) {
map->itv = itv;
rz_list_append(list, map);
} else if (rz_itv_overlap(itv, search_itv)) {
map->itv = rz_itv_intersect(itv, search_itv);
if (map->itv.size) {
rz_list_append(list, map);
} else {
free(map);
}
} else {
free(map);
}
}
static bool maskMatches(int perm, int mask, bool only) {
if (mask) {
if (only) {
return ((perm & 7) != mask);
}
return (perm & mask) != mask;
}
return false;
}
RZ_API RZ_OWN RzList /*<RzIOMap *>*/ *rz_core_get_boundaries_prot(RzCore *core, int perm, const char *mode, const char *prefix) {
rz_return_val_if_fail(core, NULL);
RzList *list = rz_list_newf(free); // XXX rz_io_map_free);
if (!list) {
return NULL;
}
char bound_in[32];
char bound_from[32];
char bound_to[32];
snprintf(bound_in, sizeof(bound_in), "%s.%s", prefix, "in");
snprintf(bound_from, sizeof(bound_from), "%s.%s", prefix, "from");
snprintf(bound_to, sizeof(bound_to), "%s.%s", prefix, "to");
const ut64 search_from = rz_config_get_i(core->config, bound_from),
search_to = rz_config_get_i(core->config, bound_to);
const RzInterval search_itv = { search_from, search_to - search_from };
if (!mode) {
mode = rz_config_get(core->config, bound_in);
}
if (!rz_config_get_b(core->config, "cfg.debug") && !core->io->va) {
append_bound(list, core->io, search_itv, 0, rz_io_size(core->io), 7);
} else if (!strcmp(mode, "file")) {
append_bound(list, core->io, search_itv, 0, rz_io_size(core->io), 7);
} else if (!strcmp(mode, "block")) {
append_bound(list, core->io, search_itv, core->offset, core->blocksize, 7);
} else if (!strcmp(mode, "io.map")) {
RzIOMap *m = rz_io_map_get(core->io, core->offset);
if (m) {
append_bound(list, core->io, search_itv, m->itv.addr, m->itv.size, m->perm);
}
} else if (!strcmp(mode, "io.maps")) { // Non-overlapping RzIOMap parts not overridden by others (skyline)
ut64 begin = UT64_MAX;
ut64 end = UT64_MAX;
#define USE_SKYLINE 0
#if USE_SKYLINE
const RzPVector *skyline = &core->io->map_skyline;
size_t i;
for (i = 0; i < rz_pvector_len(skyline); i++) {
const RzIOMapSkyline *part = rz_pvector_at(skyline, i);
ut64 from = rz_itv_begin(part->itv);
ut64 to = rz_itv_end(part->itv);
// XXX skyline's fake map perms are wrong
RzIOMap *m = rz_io_map_get(core->io, from);
int rwx = m ? m->perm : part->map->perm;
#else
void **it;
RzPVector *maps = rz_io_maps(core->io);
rz_pvector_foreach (maps, it) {
RzIOMap *map = *it;
ut64 from = rz_itv_begin(map->itv);
ut64 to = rz_itv_end(map->itv);
int rwx = map->perm;
#endif
// eprintf ("--------- %llx %llx (%llx %llx)\n", from, to, begin, end);
if (begin == UT64_MAX) {
begin = from;
}
if (end == UT64_MAX) {
end = to;
} else {
if (end == from) {
end = to;
} else {
append_bound(list, NULL, search_itv,
begin, end - begin, rwx);
begin = from;
end = to;
}
}
}
if (end != UT64_MAX) {
append_bound(list, NULL, search_itv, begin, end - begin, 7);
}
} else if (rz_str_startswith(mode, "io.maps.")) {
int len = strlen("io.maps.");
int mask = (mode[len - 1] == '.') ? rz_str_rwx(mode + len) : 0;
// bool only = (bool)(size_t)strstr (mode, ".only");
void **it;
RzPVector *maps = rz_io_maps(core->io);
rz_pvector_foreach (maps, it) {
RzIOMap *map = *it;
ut64 from = rz_itv_begin(map->itv);
// ut64 to = rz_itv_end (map->itv);
int rwx = map->perm;
if ((rwx & mask) != mask) {
continue;
}
append_bound(list, core->io, search_itv, from, rz_itv_size(map->itv), rwx);
}
} else if (rz_str_startswith(mode, "io.sky.")) {
int len = strlen("io.sky.");
int mask = (mode[len - 1] == '.') ? rz_str_rwx(mode + len) : 0;
bool only = (bool)(size_t)strstr(mode, ".only");
RzVector *skyline = &core->io->map_skyline.v;
ut64 begin = UT64_MAX;
ut64 end = UT64_MAX;
size_t i;
for (i = 0; i < rz_vector_len(skyline); i++) {
const RzSkylineItem *part = rz_vector_index_ptr(skyline, i);
ut64 from = part->itv.addr;
ut64 to = part->itv.addr + part->itv.size;
int perm = ((RzIOMap *)part->user)->perm;
if (maskMatches(perm, mask, only)) {
continue;
}
// eprintf ("--------- %llx %llx (%llx %llx)\n", from, to, begin, end);
if (begin == UT64_MAX) {
begin = from;
}
if (end == UT64_MAX) {
end = to;
} else {
if (end == from) {
end = to;
} else {
// eprintf ("[%llx - %llx]\n", begin, end);
append_bound(list, NULL, search_itv, begin, end - begin, perm);
begin = from;
end = to;
}
}
}
if (end != UT64_MAX) {
append_bound(list, NULL, search_itv, begin, end - begin, 7);
}
} else if (rz_str_startswith(mode, "bin.segments")) {
int len = strlen("bin.segments.");
int mask = (mode[len - 1] == '.') ? rz_str_rwx(mode + len) : 0;
bool only = (bool)(size_t)strstr(mode, ".only");
RzBinObject *obj = rz_bin_cur_object(core->bin);
if (obj) {
RzBinSection *s;
void **iter;
rz_pvector_foreach (obj->sections, iter) {
s = *iter;
if (!s->is_segment) {
continue;
}
if (maskMatches(s->perm, mask, only)) {
continue;
}
ut64 addr = core->io->va ? s->vaddr : s->paddr;
ut64 size = core->io->va ? s->vsize : s->size;
append_bound(list, core->io, search_itv, addr, size, s->perm);
}
}
} else if (rz_str_startswith(mode, "code")) {
RzBinObject *obj = rz_bin_cur_object(core->bin);
if (obj) {
ut64 from = UT64_MAX;
ut64 to = 0;
RzBinSection *s;
void **iter;
rz_pvector_foreach (obj->sections, iter) {
s = *iter;
if (s->is_segment) {
continue;
}
if (maskMatches(s->perm, 1, false)) {
continue;
}
ut64 addr = core->io->va ? s->vaddr : s->paddr;
ut64 size = core->io->va ? s->vsize : s->size;
from = RZ_MIN(addr, from);
to = RZ_MAX(to, addr + size);
}
if (from == UT64_MAX) {
int mask = 1;
void **it;
RzPVector *maps = rz_io_maps(core->io);
rz_pvector_foreach (maps, it) {
RzIOMap *map = *it;
ut64 from = rz_itv_begin(map->itv);
ut64 size = rz_itv_size(map->itv);
int rwx = map->perm;
if ((rwx & mask) != mask) {
continue;
}
append_bound(list, core->io, search_itv, from, size, rwx);
}
}
append_bound(list, core->io, search_itv, from, to - from, 1);
}
} else if (rz_str_startswith(mode, "bin.sections")) {
int len = strlen("bin.sections.");
int mask = (mode[len - 1] == '.') ? rz_str_rwx(mode + len) : 0;
bool only = (bool)(size_t)strstr(mode, ".only");
RzBinObject *obj = rz_bin_cur_object(core->bin);
if (obj) {
RzBinSection *s;
void **iter;
rz_pvector_foreach (obj->sections, iter) {
s = *iter;
if (s->is_segment) {
continue;
}
if (maskMatches(s->perm, mask, only)) {
continue;
}
ut64 addr = core->io->va ? s->vaddr : s->paddr;
ut64 size = core->io->va ? s->vsize : s->size;
append_bound(list, core->io, search_itv, addr, size, s->perm);
}
}
} else if (!strcmp(mode, "bin.segment")) {
RzBinObject *obj = rz_bin_cur_object(core->bin);
if (obj) {
RzBinSection *s;
void **iter;
rz_pvector_foreach (obj->sections, iter) {
s = *iter;
if (!s->is_segment) {
continue;
}
ut64 addr = core->io->va ? s->vaddr : s->paddr;
ut64 size = core->io->va ? s->vsize : s->size;
if (RZ_BETWEEN(addr, core->offset, addr + size)) {
append_bound(list, core->io, search_itv, addr, size, s->perm);
}
}
}
} else if (!strcmp(mode, "bin.section")) {
RzBinObject *obj = rz_bin_cur_object(core->bin);
if (obj) {
RzBinSection *s;
void **iter;
rz_pvector_foreach (obj->sections, iter) {
s = *iter;
if (s->is_segment) {
continue;
}
ut64 addr = core->io->va ? s->vaddr : s->paddr;
ut64 size = core->io->va ? s->vsize : s->size;
if (RZ_BETWEEN(addr, core->offset, addr + size)) {
append_bound(list, core->io, search_itv, addr, size, s->perm);
}
}
}
} else if (!strcmp(mode, "analysis.fcn") || !strcmp(mode, "analysis.bb")) {
RzAnalysisFunction *f = rz_analysis_get_fcn_in(core->analysis, core->offset,
RZ_ANALYSIS_FCN_TYPE_FCN | RZ_ANALYSIS_FCN_TYPE_SYM);
if (f) {
ut64 from = f->addr, size = rz_analysis_function_size_from_entry(f);
/* Search only inside the basic block */
if (!strcmp(mode, "analysis.bb")) {
void **iter;
RzAnalysisBlock *bb;
rz_pvector_foreach (f->bbs, iter) {
bb = (RzAnalysisBlock *)*iter;
ut64 at = core->offset;
if ((at >= bb->addr) && (at < (bb->addr + bb->size))) {
from = bb->addr;
size = bb->size;
break;
}
}
}
append_bound(list, core->io, search_itv, from, size, 5);
} else {
RZ_LOG_WARN("core: search.in = ( analysis.bb | analysis.fcn )"
"requires to seek into a valid function\n");
append_bound(list, core->io, search_itv, core->offset, 1, 5);
}
} else if (!strncmp(mode, "dbg.", 4)) {
if (core->bin->is_debugger) {
int mask = 0;
int add = 0;
bool heap = false;
bool stack = false;
bool all = false;
bool first = false;
RzListIter *iter;
RzDebugMap *map;
rz_debug_map_sync(core->dbg);
if (!strcmp(mode, "dbg.map")) {
int perm = 0;
ut64 from = core->offset;
ut64 to = core->offset;
rz_list_foreach (core->dbg->maps, iter, map) {
if (from >= map->addr && from < map->addr_end) {
from = map->addr;
to = map->addr_end;
perm = map->perm;
break;
}
}
if (perm) {
RzIOMap *nmap = RZ_NEW0(RzIOMap);
if (nmap) {
// nmap->fd = core->io->desc->fd;
nmap->itv.addr = from;
nmap->itv.size = to - from;
nmap->perm = perm;
nmap->delta = 0;
rz_list_append(list, nmap);
}
}
} else {
bool only = false;
mask = 0;
if (!strcmp(mode, "dbg.program")) {
first = true;
mask = RZ_PERM_X;
} else if (!strcmp(mode, "dbg.maps")) {
all = true;
} else if (rz_str_startswith(mode, "dbg.maps.")) {
mask = rz_str_rwx(mode + 9);
only = (bool)(size_t)strstr(mode, ".only");
} else if (!strcmp(mode, "dbg.heap")) {
heap = true;
} else if (!strcmp(mode, "dbg.stack")) {
stack = true;
}
ut64 from = UT64_MAX;
ut64 to = 0;
rz_list_foreach (core->dbg->maps, iter, map) {
if (!all && maskMatches(map->perm, mask, only)) {
continue;
}
add = (stack && strstr(map->name, "stack")) ? 1 : 0;
if (!add && (heap && (map->perm & RZ_PERM_W)) && strstr(map->name, "heap")) {
add = 1;
}
if ((mask && (map->perm & mask)) || add || all) {
if (!list) {
list = rz_list_newf(free);
}
RzIOMap *nmap = RZ_NEW0(RzIOMap);
if (!nmap) {
break;
}
nmap->itv.addr = map->addr;
nmap->itv.size = map->addr_end - map->addr;
if (nmap->itv.addr) {
from = RZ_MIN(from, nmap->itv.addr);
to = RZ_MAX(to - 1, rz_itv_end(nmap->itv) - 1) + 1;
}
nmap->perm = map->perm;
nmap->delta = 0;
rz_list_append(list, nmap);
if (first) {
break;
}
}
}
}
}
} else {
/* obey temporary seek if defined '/x 8080 @ addr:len' */
if (core->tmpseek) {
append_bound(list, core->io, search_itv, core->offset, core->blocksize, 5);
} else {
// TODO: repeat last search doesnt works for /a
ut64 from = rz_config_get_i(core->config, bound_from);
if (from == UT64_MAX) {
from = core->offset;
}
ut64 to = rz_config_get_i(core->config, bound_to);
if (to == UT64_MAX) {
if (core->io->va) {
/* TODO: section size? */
} else {
if (core->file) {
to = rz_io_fd_size(core->io, core->file->fd);
}
}
}
append_bound(list, core->io, search_itv, from, to - from, 5);
}
}
return list;
}
static bool esil_addrinfo(RzAnalysisEsil *esil) {
RzCore *core = (RzCore *)esil->cb.user;
ut64 num = 0;
@ -2100,8 +1677,7 @@ static void search_collisions(RzCore *core, const char *hashName, const ut8 *has
}
static void __core_cmd_search_asm_infinite(RzCore *core, const char *arg) {
const char *search_in = rz_config_get(core->config, "search.in");
RzList *boundaries = rz_core_get_boundaries_prot(core, -1, search_in, "search");
RzList *boundaries = rz_core_get_boundaries_select(core, "search.from", "search.to", "search.in");
RzListIter *iter;
RzIOMap *map;
RzAnalysisOp aop = { 0 };
@ -2213,7 +1789,7 @@ RZ_IPI int rz_cmd_search(void *data, const char *input) {
searchshow = rz_config_get_i(core->config, "search.show");
param.mode = rz_config_get(core->config, "search.in");
param.boundaries = rz_core_get_boundaries_prot(core, -1, param.mode, "search");
param.boundaries = rz_core_get_boundaries_select(core, "search.from", "search.to", "search.in");
/*
this introduces a bug until we implement backwards search

View file

@ -449,7 +449,6 @@ RZ_API RZ_OWN RzRopSearchContext *rz_core_rop_search_context_new(RZ_NONNULL cons
}
context->greparg = rz_str_dup(greparg);
context->search_addr = rz_config_get(core->config, "search.in");
context->arch = rz_config_get(core->config, "asm.arch");
context->regexp = regexp;
context->mask = mask;

View file

@ -122,7 +122,6 @@ static const RzCmdDescArg print_binary_args[2];
static const RzCmdDescArg base64_encode_args[2];
static const RzCmdDescArg base64_decode_args[2];
static const RzCmdDescArg check_between_args[4];
static const RzCmdDescArg print_boundaries_prot_args[2];
static const RzCmdDescArg print_djb2_hash_args[2];
static const RzCmdDescArg print_bitstring_args[3];
static const RzCmdDescArg eval_expr_print_octal_args[2];
@ -1763,8 +1762,8 @@ static const RzCmdDescHelp check_between_help = {
};
static const RzCmdDescDetailEntry print_boundaries_prot_Examples_detail_entries[] = {
{ .text = "%B ", .arg_str = "file", .comment = "Prints boundary of this file" },
{ .text = "%B ", .arg_str = "io.maps", .comment = "Prints boundaries of all io maps" },
{ .text = "%B ", .arg_str = "@e:search.in=file", .comment = "Prints boundary of this file" },
{ .text = "%Bt ", .arg_str = "@e:search.in=io.maps", .comment = "Prints boundaries of all io maps" },
{ 0 },
};
static const RzCmdDescDetail print_boundaries_prot_details[] = {
@ -1772,16 +1771,10 @@ static const RzCmdDescDetail print_boundaries_prot_details[] = {
{ 0 },
};
static const RzCmdDescArg print_boundaries_prot_args[] = {
{
.name = "mode",
.type = RZ_CMD_ARG_TYPE_STRING,
.flags = RZ_CMD_ARG_FLAG_LAST,
},
{ 0 },
};
static const RzCmdDescHelp print_boundaries_prot_help = {
.summary = "Get boundaries (start addr, stop addr) of different modes in Core.",
.summary = "Prints the search boundaries based on the search.in mode.",
.description = "There are multiple search modes in Rizin that can be listed using the command `e search.in=?`. This command can be used to get boundaries of those search modes.",
.details = print_boundaries_prot_details,
.args = print_boundaries_prot_args,
@ -19321,8 +19314,9 @@ RZ_IPI void rzshell_cmddescs_init(RzCore *core) {
RzCmdDesc *check_between_cd = rz_cmd_desc_argv_new(core->rcmd, cmd_math_cd, "%btw", rz_check_between_handler, &check_between_help);
rz_warn_if_fail(check_between_cd);
RzCmdDesc *print_boundaries_prot_cd = rz_cmd_desc_argv_new(core->rcmd, cmd_math_cd, "%B", rz_print_boundaries_prot_handler, &print_boundaries_prot_help);
RzCmdDesc *print_boundaries_prot_cd = rz_cmd_desc_argv_state_new(core->rcmd, cmd_math_cd, "%B", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_JSON | RZ_OUTPUT_MODE_TABLE, rz_print_boundaries_prot_handler, &print_boundaries_prot_help);
rz_warn_if_fail(print_boundaries_prot_cd);
rz_cmd_desc_set_default_mode(print_boundaries_prot_cd, RZ_OUTPUT_MODE_TABLE);
RzCmdDesc *print_djb2_hash_cd = rz_cmd_desc_argv_new(core->rcmd, cmd_math_cd, "%h", rz_print_djb2_hash_handler, &print_djb2_hash_help);
rz_warn_if_fail(print_djb2_hash_cd);

View file

@ -121,7 +121,7 @@ RZ_IPI RzCmdStatus rz_base64_decode_handler(RzCore *core, int argc, const char *
// "%btw"
RZ_IPI RzCmdStatus rz_check_between_handler(RzCore *core, int argc, const char **argv);
// "%B"
RZ_IPI RzCmdStatus rz_print_boundaries_prot_handler(RzCore *core, int argc, const char **argv);
RZ_IPI RzCmdStatus rz_print_boundaries_prot_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state);
// "%h"
RZ_IPI RzCmdStatus rz_print_djb2_hash_handler(RzCore *core, int argc, const char **argv);
// "%f"

View file

@ -78,23 +78,27 @@ commands:
- name: last
type: RZ_CMD_ARG_TYPE_RZNUM
- name: "%B"
summary: Get boundaries (start addr, stop addr) of different modes in Core.
summary: Prints the search boundaries based on the search.in mode.
description: >-
There are multiple search modes in Rizin that can be listed using the
command `e search.in=?`. This command can be used to get boundaries of
those search modes.
cname: print_boundaries_prot
args:
- name: mode
type: RZ_CMD_ARG_TYPE_STRING
type: RZ_CMD_DESC_TYPE_ARGV_STATE
default_mode: RZ_OUTPUT_MODE_TABLE
modes:
- RZ_OUTPUT_MODE_STANDARD
- RZ_OUTPUT_MODE_JSON
- RZ_OUTPUT_MODE_TABLE
args: []
details:
- name: Examples
entries:
- text: "%B "
arg_str: file
arg_str: "@e:search.in=file"
comment: Prints boundary of this file
- text: "%B "
arg_str: io.maps
- text: "%Bt "
arg_str: "@e:search.in=io.maps"
comment: Prints boundaries of all io maps
- name: "%h"
summary: Print hash value of string <str>

View file

@ -24,6 +24,7 @@ rz_core_sources = [
'casm.c',
'cautocmpl.c',
'cbin.c',
'cbounds.c',
'cconfig.c',
'ccrypto.c',
'cdebug.c',

View file

@ -1591,7 +1591,8 @@ RZ_API RzCmdStatus rz_core_rop_search(RZ_NONNULL RzCore *core, RZ_NONNULL RzRopS
status = handle_rop_search_address(core, context, rx_list);
goto cleanup;
}
RzList *boundaries = rz_core_get_boundaries_prot(core, -1, context->search_addr, "search");
RzList *boundaries = rz_core_get_boundaries_select(core, "search.from", "search.to", "search.in");
if (!boundaries && context->state) {
rz_cmd_state_output_array_end(context->state);
}

View file

@ -991,7 +991,8 @@ RZ_API void rz_bin_demangle_with_flags(RZ_NONNULL RzBin *bin, RzDemanglerFlag fl
RZ_API RZ_OWN char *rz_bin_demangle(RZ_NULLABLE RzBin *bin, RZ_NULLABLE const char *language, RZ_NULLABLE const char *mangled);
RZ_API const char *rz_bin_get_meth_flag_string(ut64 flag, bool compact);
RZ_API RZ_BORROW RzBinSection *rz_bin_get_section_at(RzBinObject *o, ut64 off, int va);
RZ_API RZ_BORROW RzBinSection *rz_bin_get_section_at(RZ_NONNULL RzBinObject *o, ut64 off, bool va);
RZ_API RZ_BORROW RzBinSection *rz_bin_get_segment_at(RZ_NONNULL RzBinObject *o, ut64 off, bool va);
/* filter.c */
RZ_API void rz_bin_load_filter(RzBin *bin, ut64 rules);

View file

@ -1084,7 +1084,39 @@ RZ_API int rz_core_rtr_gdb(RzCore *core, int launch, const char *path);
RZ_API int rz_core_search_preludes(RzCore *core, bool log);
RZ_API int rz_core_search_prelude(RzCore *core, ut64 from, ut64 to, const ut8 *buf, int blen, const ut8 *mask, int mlen);
RZ_API RZ_OWN RzList /*<RzIOMap *>*/ *rz_core_get_boundaries_prot(RzCore *core, int protection, const char *mode, const char *prefix);
#define RZ_CORE_BOUNDARIES_PERMS_ANY 0
#define RZ_CORE_BOUNDARIES_MASK_NONE 0
RZ_API RZ_OWN RzList /*<RzIOMap *>*/ *rz_core_get_boundaries_raw(RZ_NONNULL RzCore *core, const RzInterval interval);
RZ_API RZ_OWN RzList /*<RzIOMap *>*/ *rz_core_get_boundaries_block(RZ_NONNULL RzCore *core, const RzInterval interval);
RZ_API RZ_OWN RzList /*<RzIOMap *>*/ *rz_core_get_boundaries_current_function(RZ_NONNULL RzCore *core, const RzInterval interval);
RZ_API RZ_OWN RzList /*<RzIOMap *>*/ *rz_core_get_boundaries_current_function_bb(RZ_NONNULL RzCore *core, const RzInterval interval);
RZ_API RZ_OWN RzList /*<RzIOMap *>*/ *rz_core_get_boundaries_current_io_map(RZ_NONNULL RzCore *core, const RzInterval interval);
RZ_API RZ_OWN RzList /*<RzIOMap *>*/ *rz_core_get_boundaries_current_bin_section(RZ_NONNULL RzCore *core, const RzInterval interval);
RZ_API RZ_OWN RzList /*<RzIOMap *>*/ *rz_core_get_boundaries_current_bin_segment(RZ_NONNULL RzCore *core, const RzInterval interval);
#define rz_core_get_boundaries_range rz_core_get_boundaries_all_io_maps
#define rz_core_get_boundaries_all_io_maps(core, interval) \
rz_core_get_boundaries_io_maps(core, interval, RZ_CORE_BOUNDARIES_PERMS_ANY, RZ_CORE_BOUNDARIES_MASK_NONE)
RZ_API RZ_OWN RzList /*<RzIOMap *>*/ *rz_core_get_boundaries_io_maps(RZ_NONNULL RzCore *core, const RzInterval interval, int perms, int perms_mask);
#define rz_core_get_boundaries_all_io_skyline(core, interval) \
rz_core_get_boundaries_io_skyline(core, interval, RZ_CORE_BOUNDARIES_PERMS_ANY, RZ_CORE_BOUNDARIES_MASK_NONE)
RZ_API RZ_OWN RzList /*<RzIOMap *>*/ *rz_core_get_boundaries_io_skyline(RZ_NONNULL RzCore *core, const RzInterval interval, int perms, int perms_mask);
#define rz_core_get_boundaries_all_bin_segments(core, interval) \
rz_core_get_boundaries_bin_segments(core, interval, RZ_CORE_BOUNDARIES_PERMS_ANY, RZ_CORE_BOUNDARIES_MASK_NONE)
RZ_API RZ_OWN RzList /*<RzIOMap *>*/ *rz_core_get_boundaries_bin_segments(RZ_NONNULL RzCore *core, const RzInterval interval, int perms, int perms_mask);
#define rz_core_get_boundaries_all_bin_sections(core, interval) \
rz_core_get_boundaries_bin_sections(core, interval, RZ_CORE_BOUNDARIES_PERMS_ANY, RZ_CORE_BOUNDARIES_MASK_NONE)
RZ_API RZ_OWN RzList /*<RzIOMap *>*/ *rz_core_get_boundaries_bin_sections(RZ_NONNULL RzCore *core, const RzInterval interval, int perms, int perms_mask);
RZ_API RZ_OWN RzList /*<RzIOMap *>*/ *rz_core_get_boundaries_code_only(RZ_NONNULL RzCore *core, const RzInterval interval);
#define rz_core_get_boundaries_current_debug_map(core, interval) \
rz_core_get_boundaries_debug_maps(core, interval, RZ_CORE_BOUNDARIES_PERMS_ANY, RZ_CORE_BOUNDARIES_MASK_NONE, true)
#define rz_core_get_boundaries_all_debug_maps(core, interval) \
rz_core_get_boundaries_debug_maps(core, interval, RZ_CORE_BOUNDARIES_PERMS_ANY, RZ_CORE_BOUNDARIES_MASK_NONE, false)
RZ_API RZ_OWN RzList /*<RzIOMap *>*/ *rz_core_get_boundaries_debug_maps(RZ_NONNULL RzCore *core, const RzInterval interval, int perms, int perms_mask, bool current);
RZ_API RZ_OWN RzList /*<RzIOMap *>*/ *rz_core_get_boundaries_debug_heap(RZ_NONNULL RzCore *core, const RzInterval interval);
RZ_API RZ_OWN RzList /*<RzIOMap *>*/ *rz_core_get_boundaries_debug_stack(RZ_NONNULL RzCore *core, const RzInterval interval);
RZ_API RZ_OWN RzList /*<RzIOMap *>*/ *rz_core_get_boundaries_debug_program(RZ_NONNULL RzCore *core, const RzInterval interval);
RZ_API RZ_OWN RzList /*<RzIOMap *>*/ *rz_core_get_boundaries_select(RZ_NONNULL RzCore *core, RZ_NONNULL const char *from_key, RZ_NONNULL const char *to_key, RZ_NONNULL const char *in_key);
RZ_API void rz_core_hack_help(const RzCore *core);
RZ_API bool rz_core_hack(RzCore *core, const char *op);

View file

@ -106,7 +106,6 @@ typedef struct rz_rop_search_context_t {
ut8 subchain; ///< Display every length gadget from rop.len=X to 2 in /Rl.
ut8 crop; ///< Include conditional jump, calls and returns in ropsearch.
char *greparg; ///< Grep argument string.
const char *search_addr; ///< specify where to search stuff.
const char *arch; ///< Architecture of the binary.
bool regexp; ///< Regular expression argument flag.
bool cache; ///< Cache the search results.

View file

@ -4,13 +4,11 @@ CMDS=<<EOF
et asm.slow
et asm.bits
et asm.arch
et search.from
EOF
EXPECT=<<EOF
bool
int
str
addr
EOF
RUN

View file

@ -8,10 +8,9 @@ EXPECT=<<EOF
.-------------------------------------------------.
| offset | flags | funcs | cmts | syms | str |
)-------------------------------------------------(
| 0x100001000 | 3 | 0 | 1 | 0 | 0 |
| 0x100001010 | 2 | 0 | 1 | 0 | 0 |
)-------------------------------------------------(
| | 5 | 0 | 2 | 0 | 0 |
| | 2 | 0 | 1 | 0 | 0 |
`-------------------------------------------------'
EOF
RUN

View file

@ -33,7 +33,7 @@ FILE==
CMDS=<<EOF
b 2
wx 0xff
e zoom.in=raw
e zoom.in=block
p= 2 2@ 0
EOF
EXPECT=<<EOF

View file

@ -135,6 +135,7 @@ FILE=bins/elf/ioli/crackme0x00
CMDS=<<EOF
e io.va=false
s 0
e search.in=file
e search.from=0
e search.to=0x00000050
/ ELF
@ -150,6 +151,7 @@ CMDS=<<EOF
e scr.color=false
e io.va=false
s 0x1000
e search.in=file
e search.from=0
e search.to=0x50
/ ELF
@ -236,6 +238,7 @@ FILE=bins/elf/ioli/crackme0x00
CMDS=<<EOF
e io.va=false
s 0
e search.in=file
e search.from=0
e search.to=0x50
/a xor al, 0x80
@ -251,6 +254,7 @@ FILE=bins/elf/ioli/crackme0x00
CMDS=<<EOF
e io.va=false
s 0
e search.in=file
e search.from=0
e search.to=0x50
/a xor al, 0x80
@ -343,6 +347,7 @@ FILE=bins/elf/ioli/crackme0x00
CMDS=<<EOF
e io.va=false
s 0x1000
e search.in=file
e search.from=0
e search.to=0x00000050
/a xor al, 0x80
@ -358,6 +363,7 @@ FILE=bins/elf/ioli/crackme0x00
CMDS=<<EOF
e io.va=false
s 0x1000
e search.in=file
e search.from=0
e search.to=0x00000050
/x 3480
@ -387,6 +393,7 @@ FILE=bins/elf/ioli/crackme0x00
CMDS=<<EOF
e io.va=false
s 0
e search.in=file
e search.from=0
e search.to=0x00000050
/at xor
@ -402,6 +409,7 @@ FILE=bins/elf/ioli/crackme0x00
CMDS=<<EOF
e io.va=false
s 0x1000
e search.in=file
e search.from=0
e search.to=0x00000050
/at xor
@ -560,6 +568,7 @@ FILE=bins/pe/standard.exe
CMDS=<<EOF
e io.va=false
s 0
e search.in=file
e search.from=0
e search.to=0x10
/m
@ -574,6 +583,7 @@ FILE=bins/pe/standard.exe
CMDS=<<EOF
e io.va=false
s 0x1000
e search.in=file
e search.from=0
e search.to=0x10
/m
@ -619,6 +629,7 @@ FILE=malloc://1024
CMDS=<<EOF
w ABCD @ 0x100
s 0x1000
e search.in=raw
e search.from=0
e search.to=0x200
/x 41424344
@ -632,6 +643,7 @@ NAME=/m search seek
FILE=bins/pe/standard.exe
CMDS=<<EOF
e io.va=false
e search.in=file
s 0x1000
/m~[0]
s
@ -798,6 +810,7 @@ NAME=/x search seek
FILE=bins/pe/standard.exe
CMDS=<<EOF
e io.va=false
e search.in=file
s 0x1000
/x 9090cd80
s
@ -1237,3 +1250,47 @@ EXPECT=<<EOF
[{"offset":12,"type":"hexpair","data":"57006f0072006c006400"}]
EOF
RUN
NAME=Check boundaries via %B search.in
FILE=bins/elf/hello_world
CMDS=<<EOF
iSt:perm/str/x
%Bt @e:search.in=code
%Bt @e:search.in=bin.sections.x
%Bt @e:search.in=io.sky.x
%Bt @e:search.in=block @! 512
%Bt @e:search.in=raw
EOF
EXPECT=<<EOF
paddr size vaddr vsize align perm name type flags
-----------------------------------------------------------------------------
0x00000608 0x17 0x00000608 0x17 0x0 -r-x .init PROGBITS alloc,execute
0x00000620 0x70 0x00000620 0x70 0x0 -r-x .plt PROGBITS alloc,execute
0x00000690 0x8 0x00000690 0x8 0x0 -r-x .plt.got PROGBITS alloc,execute
0x000006a0 0x222 0x000006a0 0x222 0x0 -r-x .text PROGBITS alloc,execute
0x000008c4 0x9 0x000008c4 0x9 0x0 -r-x .fini PROGBITS alloc,execute
from to size perms
-----------------------
0x608 0x61f 23 r-x
0x620 0x690 112 r-x
0x690 0x698 8 r-x
0x6a0 0x8c2 546 r-x
0x8c4 0x8cd 9 r-x
from to size perms
-----------------------
0x608 0x61f 23 r-x
0x620 0x690 112 r-x
0x690 0x698 8 r-x
0x6a0 0x8c2 546 r-x
0x8c4 0x8cd 9 r-x
from to size perms
----------------------
0x0 0xa28 2600 r-x
from to size perms
-----------------------
0x6a0 0x8a0 512 rwx
from to size perms
-----------------------
0x0 0x2148 8520 rwx
EOF
RUN

View file

@ -1,7 +1,7 @@
NAME=t/va
FILE=bins/elf/analysis/x86-simple
CMDS=<<EOF
e search.in=io.section
e search.in=bin.section
/x 5b
pi 1 @ hit0_0
EOF