Change the "anal" abbreviation to "Analysis" in Code (#117)
This commit is contained in:
parent
e53e87d8c7
commit
041d73dce3
467 changed files with 15068 additions and 15068 deletions
|
|
@ -1,9 +1,9 @@
|
|||
* @wargio @XVilka @kazarmy @thestr4ng3r @ret2libc
|
||||
*.js @wargio
|
||||
CODEOWNERS @wargio @XVilka @kazarmy @thestr4ng3r @ret2libc
|
||||
librz/anal/ @thestr4ng3r
|
||||
librz/anal/esil* @wargio
|
||||
librz/anal/xrefs.c @ret2libc
|
||||
librz/analysis/ @thestr4ng3r
|
||||
librz/analysis/esil* @wargio
|
||||
librz/analysis/xrefs.c @ret2libc
|
||||
librz/arch/gb/ @wargio
|
||||
librz/asm/ @wargio
|
||||
librz/asm/p/x86_* @ret2libc
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ rules to make the git history more readable and consistent:
|
|||
|
||||
### Commit message hashtag list:
|
||||
|
||||
* ##anal - analysis related
|
||||
* ##analysis - analysis related
|
||||
* ##asm - assembler
|
||||
* ##bin - binary parsing
|
||||
* ##build - build fixes/changes
|
||||
|
|
|
|||
8
Makefile
8
Makefile
|
|
@ -14,7 +14,7 @@ BUILDSEC=$(shell date -u -d "@$(SOURCE_DATE_EPOCH)" "+__%H:%M:%S" 2>/dev/null ||
|
|||
else
|
||||
BUILDSEC=$(shell date "+__%H:%M:%S")
|
||||
endif
|
||||
DATADIRS=librz/cons/d librz/flag/d librz/bin/d librz/asm/d librz/syscall/d librz/magic/d librz/anal/d
|
||||
DATADIRS=librz/cons/d librz/flag/d librz/bin/d librz/asm/d librz/syscall/d librz/magic/d librz/analysis/d
|
||||
USE_ZIP=YES
|
||||
ZIP=zip
|
||||
|
||||
|
|
@ -141,7 +141,7 @@ windist:
|
|||
mkdir -p "${WINDIST}/share/rizin/${VERSION}/sysregs"
|
||||
cp -f librz/sysregs/d/*.sdb "${WINDIST}/share/rizin/${VERSION}/sysregs"
|
||||
mkdir -p "${WINDIST}/share/rizin/${VERSION}/fcnsign"
|
||||
cp -f librz/anal/d/*.sdb "${WINDIST}/share/rizin/${VERSION}/fcnsign"
|
||||
cp -f librz/analysis/d/*.sdb "${WINDIST}/share/rizin/${VERSION}/fcnsign"
|
||||
mkdir -p "${WINDIST}/share/rizin/${VERSION}/opcodes"
|
||||
cp -f librz/asm/d/*.sdb "${WINDIST}/share/rizin/${VERSION}/opcodes"
|
||||
mkdir -p "${WINDIST}/share/rizin/${VERSION}/flag"
|
||||
|
|
@ -294,7 +294,7 @@ deinstall uninstall:
|
|||
cd binrz && ${MAKE} uninstall
|
||||
cd shlr && ${MAKE} uninstall
|
||||
cd librz/syscall/d && ${MAKE} uninstall
|
||||
cd librz/anal/d && ${MAKE} uninstall
|
||||
cd librz/analysis/d && ${MAKE} uninstall
|
||||
@echo
|
||||
@echo "Run 'make purge' to also remove installed files from previous versions of rz"
|
||||
@echo
|
||||
|
|
@ -435,7 +435,7 @@ meson-symstall: symstall-sdb
|
|||
ln -fs $(PWD)/build/librz/parse/librz_parse.$(EXT_SO) ${L}/librz_parse.$(EXT_SO)
|
||||
ln -fs $(PWD)/build/librz/lang/librz_lang.$(EXT_SO) ${L}/librz_lang.$(EXT_SO)
|
||||
ln -fs $(PWD)/build/librz/asm/librz_asm.$(EXT_SO) ${L}/librz_asm.$(EXT_SO)
|
||||
ln -fs $(PWD)/build/librz/anal/librz_anal.$(EXT_SO) ${L}/librz_anal.$(EXT_SO)
|
||||
ln -fs $(PWD)/build/librz/analysis/librz_analysis.$(EXT_SO) ${L}/librz_analysis.$(EXT_SO)
|
||||
ln -fs $(PWD)/build/librz/egg/librz_egg.$(EXT_SO) ${L}/librz_egg.$(EXT_SO)
|
||||
ln -fs $(PWD)/build/librz/debug/librz_debug.$(EXT_SO) ${L}/librz_debug.$(EXT_SO)
|
||||
ln -fs $(PWD)/build/librz/core/librz_core.$(EXT_SO) ${L}/librz_core.$(EXT_SO)
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ LDFLAGS+=-L../../librz/asm -lrz_asm
|
|||
LDFLAGS+=-L../../librz/lang -lrz_lang
|
||||
LDFLAGS+=-L../../librz/egg -lrz_egg
|
||||
LDFLAGS+=-L../../librz/core -lrz_core
|
||||
LDFLAGS+=-L../../librz/anal -lrz_anal
|
||||
LDFLAGS+=-L../../librz/analysis -lrz_analysis
|
||||
LDFLAGS+=-L../../librz/crypto -lrz_crypto
|
||||
LDFLAGS+=-L../../librz/flag -lrz_flag
|
||||
LDFLAGS+=-L../../librz/parse -lrz_parse
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ ifeq ($(ISPPC),)
|
|||
BIN=librz
|
||||
ISLIB=1
|
||||
BINDEPS=rz_core rz_parse rz_search rz_cons rz_config
|
||||
BINDEPS+=rz_bin rz_debug rz_anal rz_reg rz_bp rz_io
|
||||
BINDEPS+=rz_bin rz_debug rz_analysis rz_reg rz_bp rz_io
|
||||
BINDEPS+=rz_lang rz_asm rz_syscall rz_hash rz_crypto
|
||||
BINDEPS+=rz_magic rz_socket rz_flag rz_util rz_egg
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
BIN=rizin
|
||||
BINDEPS=rz_core rz_parse rz_search rz_cons rz_config
|
||||
BINDEPS+=rz_bin rz_debug rz_anal rz_reg rz_bp rz_io
|
||||
BINDEPS+=rz_bin rz_debug rz_analysis rz_reg rz_bp rz_io
|
||||
BINDEPS+=rz_lang rz_asm rz_syscall rz_hash rz_main
|
||||
BINDEPS+=rz_magic rz_socket rz_flag rz_egg rz_crypto rz_util
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ executable('rizin', 'rizin.c',
|
|||
rz_bp_dep,
|
||||
rz_reg_dep,
|
||||
rz_syscall_dep,
|
||||
rz_anal_dep,
|
||||
rz_analysis_dep,
|
||||
rz_parse_dep,
|
||||
rz_egg_dep,
|
||||
rz_search_dep,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ executable('rz-asm', 'rz-asm.c',
|
|||
rz_main_dep,
|
||||
rz_util_dep,
|
||||
rz_asm_dep,
|
||||
rz_anal_dep,
|
||||
rz_analysis_dep,
|
||||
rz_crypto_dep,
|
||||
rz_syscall_dep,
|
||||
rz_hash_dep
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
BIN=rz-bin
|
||||
BINDEPS=rz_magic rz_core rz_bin rz_egg rz_cons rz_main
|
||||
BINDEPS+=rz_config rz_io rz_flag rz_asm
|
||||
BINDEPS+=rz_debug rz_hash rz_lang rz_anal rz_parse rz_bp rz_reg
|
||||
BINDEPS+=rz_debug rz_hash rz_lang rz_analysis rz_parse rz_bp rz_reg
|
||||
BINDEPS+=rz_search rz_syscall rz_socket rz_magic rz_crypto rz_util
|
||||
|
||||
include ../rules.mk
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
BIN=rz-diff
|
||||
|
||||
BINDEPS=rz_core rz_config rz_cons rz_search rz_anal
|
||||
BINDEPS=rz_core rz_config rz_cons rz_search rz_analysis
|
||||
BINDEPS+=rz_bin rz_debug rz_io rz_asm rz_hash rz_crypto
|
||||
BINDEPS+=rz_socket rz_flag rz_lang rz_reg rz_bp rz_parse
|
||||
BINDEPS+=rz_syscall rz_magic rz_util rz_parse rz_egg rz_main
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ executable('rz-diff', 'rz-diff.c',
|
|||
rz_cons_dep,
|
||||
rz_core_dep,
|
||||
rz_bin_dep,
|
||||
rz_anal_dep,
|
||||
rz_analysis_dep,
|
||||
rz_asm_dep,
|
||||
rz_hash_dep,
|
||||
rz_config_dep
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
BIN=rz-find
|
||||
|
||||
BINDEPS=rz_search rz_io rz_asm rz_anal rz_reg rz_cons rz_lang rz_crypto
|
||||
BINDEPS=rz_search rz_io rz_asm rz_analysis rz_reg rz_cons rz_lang rz_crypto
|
||||
BINDEPS+=rz_socket rz_parse rz_util rz_syscall rz_flag rz_hash rz_main
|
||||
|
||||
include ../rules.mk
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
BIN=rz-gg
|
||||
BINDEPS=rz_egg rz_syscall rz_asm
|
||||
BINDEPS+=rz_core rz_hash rz_debug rz_config rz_bp rz_crypto rz_cons
|
||||
BINDEPS+=rz_lang rz_parse rz_anal rz_reg rz_flag rz_crypto
|
||||
BINDEPS+=rz_lang rz_parse rz_analysis rz_reg rz_flag rz_crypto
|
||||
BINDEPS+=rz_bin rz_search rz_io rz_socket
|
||||
BINDEPS+=rz_magic rz_util rz_main
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
BIN=rz-sign
|
||||
BINDEPS=rz_anal rz_util rz_core rz_search rz_main
|
||||
BINDEPS=rz_analysis rz_util rz_core rz_search rz_main
|
||||
LDFLAGS+=$(LINK)
|
||||
|
||||
include ../../librz/main/deps.mk
|
||||
|
|
|
|||
2
configure
vendored
2
configure
vendored
|
|
@ -742,7 +742,7 @@ for A in ${ENVWORDS} ; do
|
|||
SEDFLAGS="${SEDFLAGS}s,@${A}@,${VAR},g;"
|
||||
done
|
||||
SEDFLAGS="${SEDFLAGS}'"
|
||||
for A in ./config-user.mk librz/include/rz_userconf.h pkgcfg/rz_io.pc pkgcfg/rz_magic.pc pkgcfg/rz_asm.pc pkgcfg/rz_bin.pc pkgcfg/rz_anal.pc pkgcfg/rz_hash.pc pkgcfg/rz_cons.pc pkgcfg/rz_core.pc pkgcfg/rz_lang.pc pkgcfg/rz_socket.pc pkgcfg/rz_debug.pc pkgcfg/rz_reg.pc pkgcfg/rz_config.pc pkgcfg/rz_flag.pc pkgcfg/rz_syscall.pc pkgcfg/rz_util.pc pkgcfg/rz_search.pc pkgcfg/rz_bp.pc pkgcfg/rz_parse.pc pkgcfg/rz_egg.pc pkgcfg/rz_crypto.pc ; do # SUBDIRS
|
||||
for A in ./config-user.mk librz/include/rz_userconf.h pkgcfg/rz_io.pc pkgcfg/rz_magic.pc pkgcfg/rz_asm.pc pkgcfg/rz_bin.pc pkgcfg/rz_analysis.pc pkgcfg/rz_hash.pc pkgcfg/rz_cons.pc pkgcfg/rz_core.pc pkgcfg/rz_lang.pc pkgcfg/rz_socket.pc pkgcfg/rz_debug.pc pkgcfg/rz_reg.pc pkgcfg/rz_config.pc pkgcfg/rz_flag.pc pkgcfg/rz_syscall.pc pkgcfg/rz_util.pc pkgcfg/rz_search.pc pkgcfg/rz_bp.pc pkgcfg/rz_parse.pc pkgcfg/rz_egg.pc pkgcfg/rz_crypto.pc ; do # SUBDIRS
|
||||
if [ -f "${VPATH}/${A}.acr" ]; then
|
||||
SD_TARGET=${A}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -253,7 +253,7 @@ SUBDIRS ./config-user.mk
|
|||
pkgcfg/rz_magic.pc
|
||||
pkgcfg/rz_asm.pc
|
||||
pkgcfg/rz_bin.pc
|
||||
pkgcfg/rz_anal.pc
|
||||
pkgcfg/rz_analysis.pc
|
||||
pkgcfg/rz_hash.pc
|
||||
pkgcfg/rz_cons.pc
|
||||
pkgcfg/rz_core.pc
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ Attribute list
|
|||
|
||||
Note that you will substitute `x` for the calling convention name you will use.
|
||||
|
||||
`default.cc=x` : used to set the default calling convention used for all functions in `RAnal` instance for which this key is set, string of this calling convention `"x"` will be returned for every call of `RZ_API const char *r_anal_cc_default(RAnal *anal)`.
|
||||
`default.cc=x` : used to set the default calling convention used for all functions in `RzAnalysis` instance for which this key is set, string of this calling convention `"x"` will be returned for every call of `RZ_API const char *r_analysis_cc_default(RzAnalysis *analysis)`.
|
||||
|
||||
`x=cc`: used to initialize calling convention (think of it as their is calling convention called x).
|
||||
|
||||
|
|
@ -32,8 +32,8 @@ File Path
|
|||
|
||||
In order to integrate the calling convention profile you created with the rizin source, few set of conventions should be followed:
|
||||
|
||||
- Store the unparsed sdb file in `path-to-rizin-source/librz/anal/d`.
|
||||
- Store the unparsed sdb file in `path-to-rizin-source/librz/analysis/d`.
|
||||
- If you want the sdb to be loaded for specific architecture the file name should follow this convention `cc-arch-bits`, for example to create profile that loads automatically for x86 arch with 16 bits call the file `cc-x86-16`
|
||||
- In the file `path-to-rizin-source/librz/anal/d/makefile` add entry `F+= cc-arch-bits` with desired arch and bits and you should be ready to go.
|
||||
- In the file `path-to-rizin-source/librz/analysis/d/makefile` add entry `F+= cc-arch-bits` with desired arch and bits and you should be ready to go.
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -29,10 +29,10 @@ well as setting up profiles. (??profiles??)
|
|||
The functionality lives in the following files:
|
||||
(?? why so many files? can this be simplified??)
|
||||
|
||||
librz/reg/arena.c // ?? used by anal and debugger
|
||||
librz/reg/arena.c // ?? used by analysis and debugger
|
||||
librz/reg/cond.c // condition registers
|
||||
librz/reg/double.c // support for double-precision floating point numbers
|
||||
librz/reg/profile.c // ?? used by anal and debugger
|
||||
librz/reg/profile.c // ?? used by analysis and debugger
|
||||
librz/reg/reg.c // top-level register specific code (all of rizin)
|
||||
librz/reg/value.c // dealing with register values
|
||||
librz/reg/t/p.c // test code for printing general-purpose registers
|
||||
|
|
@ -76,7 +76,7 @@ The main top-level debugger functionality lives here. It aims to abstract away
|
|||
the common code flow and integration into Rizin while delegating more nuanced
|
||||
system interactions to plug-ins.
|
||||
|
||||
librz/debug/arg.c // used by the anal engine (??)
|
||||
librz/debug/arg.c // used by the analysis engine (??)
|
||||
librz/debug/desc.c // code for handling file descriptors inside an inferior
|
||||
librz/debug/esil.c // ESIL related debugging code (??)
|
||||
librz/debug/map.c // top-level API for dealing with memory maps
|
||||
|
|
|
|||
|
|
@ -234,16 +234,16 @@ Disassembly example:
|
|||
│ │││ 0x100001147 48394a38 rdx,56,+,[8],rcx,==,cz,?=
|
||||
```
|
||||
|
||||
Rizin anal ESIL code example
|
||||
Rizin analysis ESIL code example
|
||||
==============================
|
||||
|
||||
As an example implementation of ESIL analysis for the AVR family of
|
||||
microcontrollers there is a `avr_op` function in `/librz/anal/p/anal_avr.c`
|
||||
microcontrollers there is a `avr_op` function in `/librz/analysis/p/analysis_avr.c`
|
||||
which contains information on how the instructions are expressed in ESIL and
|
||||
other opcode information such as cycle counts per instruction:
|
||||
|
||||
````
|
||||
static int avr_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int len) {
|
||||
static int avr_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len) {
|
||||
short ofst;
|
||||
int d, r, k;
|
||||
(...)
|
||||
|
|
|
|||
|
|
@ -1,725 +0,0 @@
|
|||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#include <rz_anal.h>
|
||||
#include <rz_util.h>
|
||||
#include <rz_list.h>
|
||||
#include <rz_io.h>
|
||||
#include <config.h>
|
||||
|
||||
RZ_LIB_VERSION(rz_anal);
|
||||
|
||||
static RzAnalPlugin *anal_static_plugins[] = {
|
||||
RZ_ANAL_STATIC_PLUGINS
|
||||
};
|
||||
|
||||
RZ_API void rz_anal_set_limits(RzAnal *anal, ut64 from, ut64 to) {
|
||||
free (anal->limit);
|
||||
anal->limit = RZ_NEW0 (RzAnalRange);
|
||||
if (anal->limit) {
|
||||
anal->limit->from = from;
|
||||
anal->limit->to = to;
|
||||
}
|
||||
}
|
||||
|
||||
RZ_API void rz_anal_unset_limits(RzAnal *anal) {
|
||||
RZ_FREE (anal->limit);
|
||||
}
|
||||
|
||||
static void meta_unset_for(RzEvent *ev, int type, void *user, void *data) {
|
||||
RzSpaces *s = (RzSpaces *)ev->user;
|
||||
RzAnal *anal = container_of (s, RzAnal, meta_spaces);
|
||||
RzSpaceEvent *se = (RzSpaceEvent *)data;
|
||||
rz_meta_space_unset_for (anal, se->data.unset.space);
|
||||
}
|
||||
|
||||
static void meta_count_for(RzEvent *ev, int type, void *user, void *data) {
|
||||
RzSpaces *s = (RzSpaces *)ev->user;
|
||||
RzAnal *anal = container_of (s, RzAnal, meta_spaces);
|
||||
RzSpaceEvent *se = (RzSpaceEvent *)data;
|
||||
se->res = rz_meta_space_count_for (anal, se->data.count.space);
|
||||
}
|
||||
|
||||
static void zign_unset_for(RzEvent *ev, int type, void *user, void *data) {
|
||||
RzSpaces *s = (RzSpaces *)ev->user;
|
||||
RzAnal *anal = container_of (s, RzAnal, zign_spaces);
|
||||
RzSpaceEvent *se = (RzSpaceEvent *)data;
|
||||
rz_sign_space_unset_for (anal, se->data.unset.space);
|
||||
}
|
||||
|
||||
static void zign_count_for(RzEvent *ev, int type, void *user, void *data) {
|
||||
RzSpaces *s = (RzSpaces *)ev->user;
|
||||
RzAnal *anal = container_of (s, RzAnal, zign_spaces);
|
||||
RzSpaceEvent *se = (RzSpaceEvent *)data;
|
||||
se->res = rz_sign_space_count_for (anal, se->data.count.space);
|
||||
}
|
||||
|
||||
static void zign_rename_for(RzEvent *ev, int type, void *user, void *data) {
|
||||
RzSpaces *s = (RzSpaces *)ev->user;
|
||||
RzAnal *anal = container_of (s, RzAnal, zign_spaces);
|
||||
RzSpaceEvent *se = (RzSpaceEvent *)data;
|
||||
rz_sign_space_rename_for (anal, se->data.rename.space,
|
||||
se->data.rename.oldname, se->data.rename.newname);
|
||||
}
|
||||
|
||||
void rz_anal_hint_storage_init(RzAnal *a);
|
||||
void rz_anal_hint_storage_fini(RzAnal *a);
|
||||
|
||||
static void rz_meta_item_fini(RzAnalMetaItem *item) {
|
||||
free (item->str);
|
||||
}
|
||||
|
||||
static void rz_meta_item_free(void *_item) {
|
||||
if (_item) {
|
||||
RzAnalMetaItem *item = _item;
|
||||
rz_meta_item_fini (item);
|
||||
free (item);
|
||||
}
|
||||
}
|
||||
|
||||
RZ_API RzAnal *rz_anal_new(void) {
|
||||
int i;
|
||||
RzAnal *anal = RZ_NEW0 (RzAnal);
|
||||
if (!anal) {
|
||||
return NULL;
|
||||
}
|
||||
if (!rz_str_constpool_init (&anal->constpool)) {
|
||||
free (anal);
|
||||
return NULL;
|
||||
}
|
||||
anal->bb_tree = NULL;
|
||||
anal->ht_addr_fun = ht_up_new0 ();
|
||||
anal->ht_name_fun = ht_pp_new0 ();
|
||||
anal->os = strdup (RZ_SYS_OS);
|
||||
anal->esil_goto_limit = RZ_ANAL_ESIL_GOTO_LIMIT;
|
||||
anal->opt.nopskip = true; // skip nops in code analysis
|
||||
anal->opt.hpskip = false; // skip `mov reg,reg` and `lea reg,[reg]`
|
||||
anal->gp = 0LL;
|
||||
anal->sdb = sdb_new0 ();
|
||||
anal->cpp_abi = RZ_ANAL_CPP_ABI_ITANIUM;
|
||||
anal->opt.depth = 32;
|
||||
anal->opt.noncode = false; // do not analyze data by default
|
||||
rz_spaces_init (&anal->meta_spaces, "CS");
|
||||
rz_event_hook (anal->meta_spaces.event, RZ_SPACE_EVENT_UNSET, meta_unset_for, NULL);
|
||||
rz_event_hook (anal->meta_spaces.event, RZ_SPACE_EVENT_COUNT, meta_count_for, NULL);
|
||||
|
||||
rz_spaces_init (&anal->zign_spaces, "zs");
|
||||
rz_event_hook (anal->zign_spaces.event, RZ_SPACE_EVENT_UNSET, zign_unset_for, NULL);
|
||||
rz_event_hook (anal->zign_spaces.event, RZ_SPACE_EVENT_COUNT, zign_count_for, NULL);
|
||||
rz_event_hook (anal->zign_spaces.event, RZ_SPACE_EVENT_RENAME, zign_rename_for, NULL);
|
||||
rz_anal_hint_storage_init (anal);
|
||||
rz_interval_tree_init (&anal->meta, rz_meta_item_free);
|
||||
anal->sdb_types = sdb_ns (anal->sdb, "types", 1);
|
||||
anal->sdb_fmts = sdb_ns (anal->sdb, "spec", 1);
|
||||
anal->sdb_cc = sdb_ns (anal->sdb, "cc", 1);
|
||||
anal->sdb_zigns = sdb_ns (anal->sdb, "zigns", 1);
|
||||
anal->sdb_classes = sdb_ns (anal->sdb, "classes", 1);
|
||||
anal->sdb_classes_attrs = sdb_ns (anal->sdb_classes, "attrs", 1);
|
||||
anal->zign_path = strdup ("");
|
||||
anal->cb_printf = (PrintfCallback) printf;
|
||||
(void)rz_anal_pin_init (anal);
|
||||
(void)rz_anal_xrefs_init (anal);
|
||||
anal->diff_thbb = RZ_ANAL_THRESHOLDBB;
|
||||
anal->diff_thfcn = RZ_ANAL_THRESHOLDFCN;
|
||||
anal->syscall = rz_syscall_new ();
|
||||
rz_io_bind_init (anal->iob);
|
||||
rz_flag_bind_init (anal->flb);
|
||||
anal->reg = rz_reg_new ();
|
||||
anal->last_disasm_reg = NULL;
|
||||
anal->stackptr = 0;
|
||||
anal->lineswidth = 0;
|
||||
anal->fcns = rz_list_newf (rz_anal_function_free);
|
||||
anal->leaddrs = NULL;
|
||||
anal->imports = rz_list_newf (free);
|
||||
rz_anal_set_bits (anal, 32);
|
||||
anal->plugins = rz_list_newf ((RzListFree) rz_anal_plugin_free);
|
||||
if (anal->plugins) {
|
||||
for (i = 0; anal_static_plugins[i]; i++) {
|
||||
rz_anal_add (anal, anal_static_plugins[i]);
|
||||
}
|
||||
}
|
||||
return anal;
|
||||
}
|
||||
|
||||
RZ_API void rz_anal_plugin_free (RzAnalPlugin *p) {
|
||||
if (p && p->fini) {
|
||||
p->fini (NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void __block_free_rb(RBNode *node, void *user);
|
||||
|
||||
RZ_API RzAnal *rz_anal_free(RzAnal *a) {
|
||||
if (!a) {
|
||||
return NULL;
|
||||
}
|
||||
/* TODO: Free anals here */
|
||||
rz_list_free (a->fcns);
|
||||
ht_up_free (a->ht_addr_fun);
|
||||
ht_pp_free (a->ht_name_fun);
|
||||
set_u_free (a->visited);
|
||||
rz_anal_hint_storage_fini (a);
|
||||
rz_interval_tree_fini (&a->meta);
|
||||
free (a->cpu);
|
||||
free (a->os);
|
||||
free (a->zign_path);
|
||||
rz_list_free (a->plugins);
|
||||
rz_rbtree_free (a->bb_tree, __block_free_rb, NULL);
|
||||
rz_spaces_fini (&a->meta_spaces);
|
||||
rz_spaces_fini (&a->zign_spaces);
|
||||
rz_anal_pin_fini (a);
|
||||
rz_syscall_free (a->syscall);
|
||||
rz_reg_free (a->reg);
|
||||
ht_up_free (a->dict_refs);
|
||||
ht_up_free (a->dict_xrefs);
|
||||
rz_list_free (a->leaddrs);
|
||||
sdb_free (a->sdb);
|
||||
if (a->esil) {
|
||||
rz_anal_esil_free (a->esil);
|
||||
a->esil = NULL;
|
||||
}
|
||||
free (a->last_disasm_reg);
|
||||
rz_list_free (a->imports);
|
||||
rz_str_constpool_fini (&a->constpool);
|
||||
free (a);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RZ_API void rz_anal_set_user_ptr(RzAnal *anal, void *user) {
|
||||
anal->user = user;
|
||||
}
|
||||
|
||||
RZ_API int rz_anal_add(RzAnal *anal, RzAnalPlugin *foo) {
|
||||
if (foo->init) {
|
||||
foo->init (anal->user);
|
||||
}
|
||||
rz_list_append (anal->plugins, foo);
|
||||
return true;
|
||||
}
|
||||
|
||||
RZ_API bool rz_anal_use(RzAnal *anal, const char *name) {
|
||||
RzListIter *it;
|
||||
RzAnalPlugin *h;
|
||||
|
||||
if (anal) {
|
||||
rz_list_foreach (anal->plugins, it, h) {
|
||||
if (!h->name || strcmp (h->name, name)) {
|
||||
continue;
|
||||
}
|
||||
#if 0
|
||||
// regression happening here for asm.emu
|
||||
if (anal->cur && anal->cur == h) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
anal->cur = h;
|
||||
rz_anal_set_reg_profile (anal);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
RZ_API char *rz_anal_get_reg_profile(RzAnal *anal) {
|
||||
return (anal && anal->cur && anal->cur->get_reg_profile)
|
||||
? anal->cur->get_reg_profile (anal) : NULL;
|
||||
}
|
||||
|
||||
// deprecate.. or at least reuse get_reg_profile...
|
||||
RZ_API bool rz_anal_set_reg_profile(RzAnal *anal) {
|
||||
bool ret = false;
|
||||
if (anal && anal->cur && anal->cur->set_reg_profile) {
|
||||
ret = anal->cur->set_reg_profile (anal);
|
||||
} else {
|
||||
char *p = rz_anal_get_reg_profile (anal);
|
||||
if (p && *p) {
|
||||
rz_reg_set_profile_string (anal->reg, p);
|
||||
ret = true;
|
||||
}
|
||||
free (p);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
RZ_API bool rz_anal_set_triplet(RzAnal *anal, const char *os, const char *arch, int bits) {
|
||||
rz_return_val_if_fail (anal, false);
|
||||
if (!os || !*os) {
|
||||
os = RZ_SYS_OS;
|
||||
}
|
||||
if (!arch || !*arch) {
|
||||
arch = anal->cur? anal->cur->arch: RZ_SYS_ARCH;
|
||||
}
|
||||
if (bits < 1) {
|
||||
bits = anal->bits;
|
||||
}
|
||||
free (anal->os);
|
||||
anal->os = strdup (os);
|
||||
rz_anal_set_bits (anal, bits);
|
||||
return rz_anal_use (anal, arch);
|
||||
}
|
||||
|
||||
// copypasta from core/cbin.c
|
||||
static void sdb_concat_by_path(Sdb *s, const char *path) {
|
||||
Sdb *db = sdb_new (0, path, 0);
|
||||
sdb_merge (s, db);
|
||||
sdb_close (db);
|
||||
sdb_free (db);
|
||||
}
|
||||
|
||||
RZ_API bool rz_anal_set_os(RzAnal *anal, const char *os) {
|
||||
Sdb *types = anal->sdb_types;
|
||||
const char *dir_prefix = rz_sys_prefix (NULL);
|
||||
const char *dbpath = sdb_fmt (RZ_JOIN_3_PATHS ("%s", RZ_SDB_FCNSIGN, "types-%s.sdb"),
|
||||
dir_prefix, os);
|
||||
if (rz_file_exists (dbpath)) {
|
||||
sdb_concat_by_path (types, dbpath);
|
||||
}
|
||||
return rz_anal_set_triplet (anal, os, NULL, -1);
|
||||
}
|
||||
|
||||
RZ_API bool rz_anal_set_bits(RzAnal *anal, int bits) {
|
||||
switch (bits) {
|
||||
case 8:
|
||||
case 16:
|
||||
case 27:
|
||||
case 32:
|
||||
case 64:
|
||||
if (anal->bits != bits) {
|
||||
anal->bits = bits;
|
||||
rz_anal_set_reg_profile (anal);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
RZ_API void rz_anal_set_cpu(RzAnal *anal, const char *cpu) {
|
||||
free (anal->cpu);
|
||||
anal->cpu = cpu ? strdup (cpu) : NULL;
|
||||
int v = rz_anal_archinfo (anal, RZ_ANAL_ARCHINFO_ALIGN);
|
||||
if (v != -1) {
|
||||
anal->pcalign = v;
|
||||
}
|
||||
}
|
||||
|
||||
RZ_API int rz_anal_set_big_endian(RzAnal *anal, int bigend) {
|
||||
anal->big_endian = bigend;
|
||||
anal->reg->big_endian = bigend;
|
||||
return true;
|
||||
}
|
||||
|
||||
RZ_API ut8 *rz_anal_mask(RzAnal *anal, int size, const ut8 *data, ut64 at) {
|
||||
RzAnalOp *op = NULL;
|
||||
ut8 *ret = NULL;
|
||||
int oplen, idx = 0;
|
||||
|
||||
if (!data) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (anal->cur && anal->cur->anal_mask) {
|
||||
return anal->cur->anal_mask (anal, size, data, at);
|
||||
}
|
||||
|
||||
if (!(op = rz_anal_op_new ())) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(ret = malloc (size))) {
|
||||
rz_anal_op_free (op);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset (ret, 0xff, size);
|
||||
|
||||
while (idx < size) {
|
||||
if ((oplen = rz_anal_op (anal, op, at, data + idx, size - idx, RZ_ANAL_OP_MASK_BASIC)) < 1) {
|
||||
break;
|
||||
}
|
||||
if ((op->ptr != UT64_MAX || op->jump != UT64_MAX) && op->nopcode != 0) {
|
||||
memset (ret + idx + op->nopcode, 0, oplen - op->nopcode);
|
||||
}
|
||||
idx += oplen;
|
||||
at += oplen;
|
||||
}
|
||||
|
||||
rz_anal_op_free (op);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
RZ_API void rz_anal_trace_bb(RzAnal *anal, ut64 addr) {
|
||||
RzAnalBlock *bbi;
|
||||
RzAnalFunction *fcni;
|
||||
RzListIter *iter2;
|
||||
fcni = rz_anal_get_fcn_in (anal, addr, 0);
|
||||
if (fcni) {
|
||||
rz_list_foreach (fcni->bbs, iter2, bbi) {
|
||||
if (addr >= bbi->addr && addr < (bbi->addr + bbi->size)) {
|
||||
bbi->traced = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RZ_API void rz_anal_colorize_bb(RzAnal *anal, ut64 addr, ut32 color) {
|
||||
RzAnalBlock *bbi;
|
||||
bbi = rz_anal_bb_from_offset (anal, addr);
|
||||
if (bbi) {
|
||||
bbi->colorize = color;
|
||||
}
|
||||
}
|
||||
|
||||
RZ_API RzList* rz_anal_get_fcns (RzAnal *anal) {
|
||||
// avoid received to free this thing
|
||||
anal->fcns->free = NULL;
|
||||
return anal->fcns;
|
||||
}
|
||||
|
||||
RZ_API RzAnalOp *rz_anal_op_hexstr(RzAnal *anal, ut64 addr, const char *str) {
|
||||
RzAnalOp *op = RZ_NEW0 (RzAnalOp);
|
||||
if (!op) {
|
||||
return NULL;
|
||||
}
|
||||
ut8 *buf = calloc (1, strlen (str) + 1);
|
||||
if (!buf) {
|
||||
free (op);
|
||||
return NULL;
|
||||
}
|
||||
int len = rz_hex_str2bin (str, buf);
|
||||
rz_anal_op (anal, op, addr, buf, len, RZ_ANAL_OP_MASK_BASIC);
|
||||
free (buf);
|
||||
return op;
|
||||
}
|
||||
|
||||
RZ_API bool rz_anal_op_is_eob(RzAnalOp *op) {
|
||||
if (op->eob) {
|
||||
return true;
|
||||
}
|
||||
switch (op->type) {
|
||||
case RZ_ANAL_OP_TYPE_JMP:
|
||||
case RZ_ANAL_OP_TYPE_UJMP:
|
||||
case RZ_ANAL_OP_TYPE_RJMP:
|
||||
case RZ_ANAL_OP_TYPE_IJMP:
|
||||
case RZ_ANAL_OP_TYPE_IRJMP:
|
||||
case RZ_ANAL_OP_TYPE_CJMP:
|
||||
case RZ_ANAL_OP_TYPE_RET:
|
||||
case RZ_ANAL_OP_TYPE_TRAP:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
RZ_API void rz_anal_purge(RzAnal *anal) {
|
||||
rz_anal_hint_clear (anal);
|
||||
rz_interval_tree_fini (&anal->meta);
|
||||
rz_interval_tree_init (&anal->meta, rz_meta_item_free);
|
||||
sdb_reset (anal->sdb_types);
|
||||
sdb_reset (anal->sdb_zigns);
|
||||
sdb_reset (anal->sdb_classes);
|
||||
sdb_reset (anal->sdb_classes_attrs);
|
||||
rz_anal_pin_fini (anal);
|
||||
rz_anal_pin_init (anal);
|
||||
sdb_reset (anal->sdb_cc);
|
||||
rz_list_free (anal->fcns);
|
||||
anal->fcns = rz_list_newf (rz_anal_function_free);
|
||||
rz_anal_purge_imports (anal);
|
||||
}
|
||||
|
||||
RZ_API int rz_anal_archinfo(RzAnal *anal, int query) {
|
||||
rz_return_val_if_fail (anal, -1);
|
||||
switch (query) {
|
||||
case RZ_ANAL_ARCHINFO_MIN_OP_SIZE:
|
||||
case RZ_ANAL_ARCHINFO_MAX_OP_SIZE:
|
||||
case RZ_ANAL_ARCHINFO_ALIGN:
|
||||
if (anal->cur && anal->cur->archinfo) {
|
||||
return anal->cur->archinfo (anal, query);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static bool __nonreturn_print_commands(void *p, const char *k, const char *v) {
|
||||
RzAnal *anal = (RzAnal *)p;
|
||||
if (!strncmp (v, "func", strlen ("func") + 1)) {
|
||||
char *query = sdb_fmt ("func.%s.noreturn", k);
|
||||
if (sdb_bool_get (anal->sdb_types, query, NULL)) {
|
||||
anal->cb_printf ("tnn %s\n", k);
|
||||
}
|
||||
}
|
||||
if (!strncmp (k, "addr.", 5)) {
|
||||
anal->cb_printf ("tna 0x%s %s\n", k + 5, v);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __nonreturn_print(void *p, const char *k, const char *v) {
|
||||
RzAnal *anal = (RzAnal *)p;
|
||||
if (!strncmp (k, "func.", 5) && strstr (k, ".noreturn")) {
|
||||
char *s = strdup (k + 5);
|
||||
char *d = strchr (s, '.');
|
||||
if (d) {
|
||||
*d = 0;
|
||||
}
|
||||
anal->cb_printf ("%s\n", s);
|
||||
free (s);
|
||||
}
|
||||
if (!strncmp (k, "addr.", 5)) {
|
||||
char *off;
|
||||
if (!(off = strdup (k + 5))) {
|
||||
return 1;
|
||||
}
|
||||
char *ptr = strstr (off, ".noreturn");
|
||||
if (ptr) {
|
||||
*ptr = 0;
|
||||
anal->cb_printf ("0x%s\n", off);
|
||||
}
|
||||
free (off);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
RZ_API void rz_anal_noreturn_list(RzAnal *anal, int mode) {
|
||||
switch (mode) {
|
||||
case 1:
|
||||
case '*':
|
||||
case 'r':
|
||||
sdb_foreach (anal->sdb_types, __nonreturn_print_commands, anal);
|
||||
break;
|
||||
default:
|
||||
sdb_foreach (anal->sdb_types, __nonreturn_print, anal);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#define K_NORET_ADDR(x) sdb_fmt ("addr.%"PFMT64x".noreturn", x)
|
||||
#define K_NORET_FUNC(x) sdb_fmt ("func.%s.noreturn", x)
|
||||
|
||||
RZ_API bool rz_anal_noreturn_add(RzAnal *anal, const char *name, ut64 addr) {
|
||||
const char *tmp_name = NULL;
|
||||
Sdb *TDB = anal->sdb_types;
|
||||
char *fnl_name = NULL;
|
||||
if (addr != UT64_MAX) {
|
||||
if (sdb_bool_set (TDB, K_NORET_ADDR (addr), true, 0)) {
|
||||
RzAnalFunction *fcn = rz_anal_get_function_at (anal, addr);
|
||||
if (fcn) {
|
||||
fcn->is_noreturn = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (name && *name) {
|
||||
tmp_name = name;
|
||||
} else {
|
||||
RzAnalFunction *fcn = rz_anal_get_fcn_in (anal, addr, -1);
|
||||
RzFlagItem *fi = anal->flb.get_at (anal->flb.f, addr, false);
|
||||
if (!fcn && !fi) {
|
||||
eprintf ("Can't find Function at given address\n");
|
||||
return false;
|
||||
}
|
||||
tmp_name = fcn ? fcn->name: fi->name;
|
||||
if (fcn) {
|
||||
fcn->is_noreturn = true;
|
||||
}
|
||||
}
|
||||
if (rz_type_func_exist (TDB, tmp_name)) {
|
||||
fnl_name = strdup (tmp_name);
|
||||
} else if (!(fnl_name = rz_type_func_guess (TDB, (char *)tmp_name))) {
|
||||
if (addr == UT64_MAX) {
|
||||
if (name) {
|
||||
sdb_bool_set (TDB, K_NORET_FUNC (name), true, 0);
|
||||
} else {
|
||||
eprintf ("Can't find prototype for: %s\n", tmp_name);
|
||||
}
|
||||
} else {
|
||||
eprintf ("Can't find prototype for: %s\n", tmp_name);
|
||||
}
|
||||
//return false;
|
||||
}
|
||||
if (fnl_name) {
|
||||
sdb_bool_set (TDB, K_NORET_FUNC (fnl_name), true, 0);
|
||||
free (fnl_name);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
RZ_API bool rz_anal_noreturn_drop(RzAnal *anal, const char *expr) {
|
||||
Sdb *TDB = anal->sdb_types;
|
||||
expr = rz_str_trim_head_ro (expr);
|
||||
const char *fcnname = NULL;
|
||||
if (!strncmp (expr, "0x", 2)) {
|
||||
ut64 n = rz_num_math (NULL, expr);
|
||||
sdb_unset (TDB, K_NORET_ADDR (n), 0);
|
||||
RzAnalFunction *fcn = rz_anal_get_fcn_in (anal, n, -1);
|
||||
if (!fcn) {
|
||||
// eprintf ("can't find function at 0x%"PFMT64x"\n", n);
|
||||
return false;
|
||||
}
|
||||
fcnname = fcn->name;
|
||||
} else {
|
||||
fcnname = expr;
|
||||
}
|
||||
sdb_unset (TDB, K_NORET_FUNC (fcnname), 0);
|
||||
#if 0
|
||||
char *tmp;
|
||||
// unnsecessary checks, imho the noreturn db should be pretty simple to allow forward and custom declarations without having to define the function prototype before
|
||||
if (rz_type_func_exist (TDB, fcnname)) {
|
||||
sdb_unset (TDB, K_NORET_FUNC (fcnname), 0);
|
||||
return true;
|
||||
} else if ((tmp = rz_type_func_guess (TDB, (char *)fcnname))) {
|
||||
sdb_unset (TDB, K_NORET_FUNC (fcnname), 0);
|
||||
free (tmp);
|
||||
return true;
|
||||
}
|
||||
eprintf ("Can't find prototype for %s in types database", fcnname);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool rz_anal_noreturn_at_name(RzAnal *anal, const char *name) {
|
||||
if (sdb_bool_get (anal->sdb_types, K_NORET_FUNC(name), NULL)) {
|
||||
return true;
|
||||
}
|
||||
char *tmp = rz_type_func_guess (anal->sdb_types, (char *)name);
|
||||
if (tmp) {
|
||||
if (sdb_bool_get (anal->sdb_types, K_NORET_FUNC (tmp), NULL)) {
|
||||
free (tmp);
|
||||
return true;
|
||||
}
|
||||
free (tmp);
|
||||
}
|
||||
if (rz_str_startswith (name, "reloc.")) {
|
||||
return rz_anal_noreturn_at_name (anal, name + 6);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
RZ_API bool rz_anal_noreturn_at_addr(RzAnal *anal, ut64 addr) {
|
||||
return sdb_bool_get (anal->sdb_types, K_NORET_ADDR (addr), NULL);
|
||||
}
|
||||
|
||||
static bool noreturn_recurse(RzAnal *anal, ut64 addr) {
|
||||
RzAnalOp op = {0};
|
||||
ut8 bbuf[0x10] = {0};
|
||||
ut64 recurse_addr = UT64_MAX;
|
||||
if (!anal->iob.read_at (anal->iob.io, addr, bbuf, sizeof (bbuf))) {
|
||||
eprintf ("Couldn't read buffer\n");
|
||||
return false;
|
||||
}
|
||||
if (rz_anal_op (anal, &op, addr, bbuf, sizeof (bbuf), RZ_ANAL_OP_MASK_BASIC | RZ_ANAL_OP_MASK_VAL) < 1) {
|
||||
return false;
|
||||
}
|
||||
switch (op.type & RZ_ANAL_OP_TYPE_MASK) {
|
||||
case RZ_ANAL_OP_TYPE_JMP:
|
||||
if (op.jump == UT64_MAX) {
|
||||
recurse_addr = op.ptr;
|
||||
} else {
|
||||
recurse_addr = op.jump;
|
||||
}
|
||||
break;
|
||||
case RZ_ANAL_OP_TYPE_UCALL:
|
||||
case RZ_ANAL_OP_TYPE_RCALL:
|
||||
case RZ_ANAL_OP_TYPE_ICALL:
|
||||
case RZ_ANAL_OP_TYPE_IRCALL:
|
||||
recurse_addr = op.ptr;
|
||||
break;
|
||||
case RZ_ANAL_OP_TYPE_CCALL:
|
||||
case RZ_ANAL_OP_TYPE_CALL:
|
||||
recurse_addr = op.jump;
|
||||
break;
|
||||
}
|
||||
if (recurse_addr == UT64_MAX || recurse_addr == addr) {
|
||||
return false;
|
||||
}
|
||||
return rz_anal_noreturn_at (anal, recurse_addr);
|
||||
}
|
||||
|
||||
RZ_API bool rz_anal_noreturn_at(RzAnal *anal, ut64 addr) {
|
||||
if (!addr || addr == UT64_MAX) {
|
||||
return false;
|
||||
}
|
||||
if (rz_anal_noreturn_at_addr (anal, addr)) {
|
||||
return true;
|
||||
}
|
||||
/* XXX this is very slow */
|
||||
RzAnalFunction *f = rz_anal_get_function_at (anal, addr);
|
||||
if (f) {
|
||||
if (rz_anal_noreturn_at_name (anal, f->name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
RzFlagItem *fi = anal->flag_get (anal->flb.f, addr);
|
||||
if (fi) {
|
||||
if (rz_anal_noreturn_at_name (anal, fi->realname ? fi->realname : fi->name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (anal->recursive_noreturn) {
|
||||
return noreturn_recurse (anal, addr);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
RZ_API void rz_anal_bind(RzAnal *anal, RzAnalBind *b) {
|
||||
if (b) {
|
||||
b->anal = anal;
|
||||
b->get_fcn_in = rz_anal_get_fcn_in;
|
||||
b->get_hint = rz_anal_hint_get;
|
||||
}
|
||||
}
|
||||
|
||||
RZ_API RzList *rz_anal_preludes(RzAnal *anal) {
|
||||
if (anal->cur && anal->cur->preludes ) {
|
||||
return anal->cur->preludes (anal);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RZ_API bool rz_anal_is_prelude(RzAnal *anal, const ut8 *data, int len) {
|
||||
RzList *l = rz_anal_preludes (anal);
|
||||
if (l) {
|
||||
RzSearchKeyword *kw;
|
||||
RzListIter *iter;
|
||||
rz_list_foreach (l, iter, kw) {
|
||||
int ks = kw->keyword_length;
|
||||
if (len >= ks && !memcmp (data, kw->bin_keyword, ks)) {
|
||||
rz_list_free (l);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
rz_list_free (l);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
RZ_API void rz_anal_add_import(RzAnal *anal, const char *imp) {
|
||||
RzListIter *it;
|
||||
const char *eimp;
|
||||
rz_list_foreach (anal->imports, it, eimp) {
|
||||
if (!strcmp (eimp, imp)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
char *cimp = strdup (imp);
|
||||
if (!cimp) {
|
||||
return;
|
||||
}
|
||||
rz_list_push (anal->imports, cimp);
|
||||
}
|
||||
|
||||
RZ_API void rz_anal_remove_import(RzAnal *anal, const char *imp) {
|
||||
RzListIter *it;
|
||||
const char *eimp;
|
||||
rz_list_foreach (anal->imports, it, eimp) {
|
||||
if (!strcmp (eimp, imp)) {
|
||||
rz_list_delete (anal->imports, it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RZ_API void rz_anal_purge_imports(RzAnal *anal) {
|
||||
rz_list_purge (anal->imports);
|
||||
}
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
int hexagon_anal_instruction(HexInsn *hi, RzAnalOp *op);
|
||||
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,9 +0,0 @@
|
|||
OBJ_6502=anal_6502.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_6502}
|
||||
TARGET_6502=anal_6502.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_6502}
|
||||
|
||||
${TARGET_6502}: ${OBJ_6502}
|
||||
${CC} $(call libname,anal_6502) ${LDFLAGS} ${CFLAGS} -o anal_6502.${EXT_SO} ${OBJ_6502}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
OBJ_6502_CS=anal_6502_cs.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_6502_CS}
|
||||
TARGET_6502_CS=anal_6502_cs.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_6502_CS}
|
||||
|
||||
${TARGET_6502_CS}: ${OBJ_6502_CS}
|
||||
${CC} $(call libname,anal_6502_cs) ${LDFLAGS} ${CFLAGS} -o anal_6502_cs.${EXT_SO} ${OBJ_6502_CS}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
OBJ_AMD29K=anal_amd29k.o ../../asm/arch/amd29k/amd29k.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_AMD29K}
|
||||
TARGET_AMD29K=anal_amd29k.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_AMD29K}
|
||||
|
||||
${TARGET_AMD29K}: ${OBJ_AMD29K}
|
||||
${CC} ${CFLAGS} $(call libname,anal_amd29k) $(CS_CFLAGS) \
|
||||
-o anal_amd29k.${EXT_SO} ${OBJ_AMD29K} $(CS_LDFLAGS)
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
OBJ_ARC=anal_arc.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_ARC}
|
||||
TARGET_ARC=anal_arc.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_ARC}
|
||||
|
||||
${TARGET_ARC}: ${OBJ_ARC}
|
||||
${CC} $(call libname,anal_arc) ${LDFLAGS} ${CFLAGS} -o anal_arc.${EXT_SO} ${OBJ_ARC}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
OBJ_AVR=anal_avr.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_AVR}
|
||||
TARGET_AVR=anal_avr.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_AVR}
|
||||
|
||||
${TARGET_AVR}: ${OBJ_AVR}
|
||||
${CC} $(call libname,anal_avr) ${CFLAGS} -o anal_avr.${EXT_SO} ${OBJ_AVR}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
OBJ_BF=anal_bf.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_BF}
|
||||
TARGET_BF=anal_bf.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_BF}
|
||||
|
||||
${TARGET_BF}: ${OBJ_BF}
|
||||
${CC} $(call libname,anal_bf) ${LDFLAGS} ${CFLAGS} -o anal_bf.${EXT_SO} ${OBJ_BF}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
OBJ_CHIP8=anal_chip8.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_CHIP8}
|
||||
TARGET_CHIP8=anal_chip8.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_CHIP8}
|
||||
|
||||
${TARGET_CHIP8}: ${OBJ_CHIP8}
|
||||
${CC} $(call libname,anal_chip8) ${CFLAGS} -o anal_chip8.${EXT_SO} ${OBJ_CHIP8}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
OBJ_CRIS=anal_cris.o
|
||||
|
||||
STATIC_OBJ+=$(OBJ_CRIS)
|
||||
TARGET_CRIS=anal_cris.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_CRIS}
|
||||
|
||||
${TARGET_CRIS}: ${OBJ_CRIS}
|
||||
${CC} ${CFLAGS} $(call libname,anal_cris) \
|
||||
-o anal_cris.${EXT_SO} ${OBJ_CRIS}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
OBJ_DALVIK=anal_dalvik.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_DALVIK}
|
||||
TARGET_DALVIK=anal_dalvik.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_DALVIK}
|
||||
|
||||
${TARGET_DALVIK}: ${OBJ_DALVIK}
|
||||
${CC} $(call libname,anal_dalvik) ${LDFLAGS} ${CFLAGS} -o anal_dalvik.${EXT_SO} ${OBJ_DALVIK}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
OBJ_I4004=anal_i4004.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_I4004}
|
||||
TARGET_I4004=anal_i4004.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_I4004}
|
||||
|
||||
${TARGET_I4004}: ${OBJ_I4004}
|
||||
${CC} $(call libname,anal_i4004) ${CFLAGS} -o anal_i4004.${EXT_SO} ${OBJ_I4004}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
OBJ_I8080=anal_i8080.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_I8080}
|
||||
TARGET_I8080=anal_i8080.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_I8080}
|
||||
|
||||
${TARGET_I8080}: ${OBJ_I8080}
|
||||
${CC} $(call libname,anal_z80) ${LDFLAGS} ${CFLAGS} -o anal_i8080.${EXT_SO} ${OBJ_I8080}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
OBJ_M680X_CS=anal_m680x_cs.o
|
||||
|
||||
include ${CURDIR}capstone.mk
|
||||
|
||||
STATIC_OBJ+=$(OBJ_M680X_CS)
|
||||
|
||||
TARGET_M680X_CS=anal_m680x_cs.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_M680X_CS}
|
||||
|
||||
${TARGET_M680X_CS}: ${OBJ_M680X_CS}
|
||||
${CC} ${CFLAGS} $(call libname,anal_m680x_cs) $(CS_CFLAGS) \
|
||||
-o anal_m680x_cs.${EXT_SO} ${OBJ_M680X_CS} $(CS_LDFLAGS)
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
OBJ_M68K_CS=anal_m68k_cs.o
|
||||
|
||||
include ${CURDIR}capstone.mk
|
||||
|
||||
STATIC_OBJ+=$(OBJ_M68K_CS)
|
||||
|
||||
TARGET_M68K_CS=anal_m68k_cs.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_M68K_CS}
|
||||
|
||||
${TARGET_M68K_CS}: ${OBJ_M68K_CS}
|
||||
${CC} ${CFLAGS} $(call libname,anal_m68k_cs) $(CS_CFLAGS) \
|
||||
-o anal_m68k_cs.${EXT_SO} ${OBJ_M68K_CS} $(CS_LDFLAGS)
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
OBJ_MALBOLGE=anal_malbolge.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_MALBOLGE}
|
||||
TARGET_MALBOLGE=anal_malbolge.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_MALBOLGE}
|
||||
|
||||
${TARGET_MALBOLGE}: ${OBJ_MALBOLGE}
|
||||
${CC} $(call libname,anal_malbolge) ${LDFLAGS} ${CFLAGS} -o anal_malbolge.${EXT_SO} ${OBJ_MALBOLGE}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
OBJ_MCORE=anal_mcore.o ../../asm/arch/mcore/mcore.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_MCORE}
|
||||
|
||||
TARGET_MCORE=anal_mcore.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_MCORE}
|
||||
|
||||
${TARGET_MCORE}: ${OBJ_MCORE}
|
||||
${CC} ${CFLAGS} $(call libname,anal_mcore) $(CS_LDFLAGS) \
|
||||
-o anal_mcore.${EXT_SO} ${OBJ_MCORE}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
OBJ_MIPS_CS=anal_mips_cs.o
|
||||
|
||||
include $(CURDIR)capstone.mk
|
||||
|
||||
STATIC_OBJ+=$(OBJ_MIPS_CS)
|
||||
TARGET_MIPS_CS=anal_mips_cs.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_MIPS_CS}
|
||||
|
||||
${TARGET_MIPS_CS}: ${OBJ_MIPS_CS}
|
||||
${CC} ${CFLAGS} $(call libname,anal_mips_cs) $(CS_CFLAGS) \
|
||||
-o anal_mips_cs.${EXT_SO} ${OBJ_MIPS_CS} $(CS_LDFLAGS)
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
OBJ_NIOS2=anal_nios2.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_NIOS2}
|
||||
TARGET_NIOS2=anal_nios2.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_NIOS2}
|
||||
|
||||
${TARGET_NIOS2}: ${OBJ_NIOS2}
|
||||
${CC} $(call libname,anal_nios2) ${LDFLAGS} ${CFLAGS} \
|
||||
-o anal_nios2.${EXT_SO} ${OBJ_NIOS2}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
OBJ_NULL=anal_null.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_NULL}
|
||||
TARGET_NULL=anal_null.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_NULL}
|
||||
|
||||
${TARGET_NULL}: ${OBJ_NULL}
|
||||
${CC} $(call libname,anal_null) ${LDFLAGS} \
|
||||
${CFLAGS} -o anal_null.${EXT_SO} ${OBJ_NULL}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
OBJ_OR1K=anal_or1k.o
|
||||
OBJ_OR1K+=../../asm/arch/or1k/or1k_disas.o
|
||||
CFLAGS+=-I../asm/arch/or1k
|
||||
|
||||
STATIC_OBJ+=${OBJ_OR1K}
|
||||
TARGET_OR1K=anal_or1k.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_OR1K}
|
||||
|
||||
${TARGET_OR1K}: ${OBJ_OR1K}
|
||||
${CC} $(call libname,anal_nios2) ${LDFLAGS} ${CFLAGS} \
|
||||
-o anal_or1k.${EXT_SO} ${OBJ_OR1K}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
OBJ_PIC=anal_pic.o
|
||||
|
||||
STATIC_OBJ+=$(OBJ_PIC)
|
||||
OBJ_PIC+=../../asm/arch/pic/pic_midrange.o
|
||||
TARGET_PIC=anal_pic.$(EXT_SO)
|
||||
|
||||
ALL_TARTGETS+=$(TARGET_PIC)
|
||||
|
||||
$(TARGET_PIC): $(OBJ_PIC)
|
||||
$(CC) $(call libname,anal_pic) ${LDFLAGS} ${CFLAGS} -o anal_pic.$(EXT_SO) $(OBJ_PIC)
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
OBJ_PPC_CS=anal_ppc_cs.o ../../asm/arch/ppc/libvle/vle.o
|
||||
|
||||
include $(CURDIR)capstone.mk
|
||||
|
||||
STATIC_OBJ+=${OBJ_PPC_CS}
|
||||
TARGET_PPC_CS=anal_ppc_cs.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_PPC_CS}
|
||||
|
||||
${TARGET_PPC_CS}: ${OBJ_PPC_CS}
|
||||
${CC} ${CFLAGS} $(call libname,anal_ppc_cs) $(CS_CFLAGS) \
|
||||
-o anal_ppc_cs.${EXT_SO} ${OBJ_PPC_CS} $(CS_LDFLAGS)
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
OBJ_PPC=anal_ppc_gnu.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_PPC}
|
||||
TARGET_PPC=anal_ppc_gnu.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_PPC}
|
||||
|
||||
${TARGET_PPC}: ${OBJ_PPC}
|
||||
${CC} $(call libname,anal_ppc_gnu) ${CFLAGS} \
|
||||
-o anal_ppc_gnu.${EXT_SO} ${OBJ_PPC}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
OBJ_RISCV=anal_riscv.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_RISCV}
|
||||
TARGET_RISCV=anal_riscv.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_RISCV}
|
||||
|
||||
${TARGET_RISCV}: ${OBJ_RISCV}
|
||||
${CC} $(call libname,anal_RISCV) ${LDFLAGS} ${CFLAGS} -o anal_riscv.${EXT_SO} ${OBJ_RISCV}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
OBJ_RISCV_CS=anal_riscv_cs.o
|
||||
|
||||
include $(CURDIR)capstone.mk
|
||||
|
||||
STATIC_OBJ+=$(OBJ_RISCV_CS)
|
||||
TARGET_RISCV_CS=anal_riscv_cs.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_RISCV_CS}
|
||||
|
||||
${TARGET_RISCV_CS}: ${OBJ_RISCV_CS}
|
||||
${CC} ${CFLAGS} $(call libname,anal_riscv_cs) $(CS_CFLAGS) \
|
||||
-o anal_riscv_cs.${EXT_SO} ${OBJ_RISCV_CS} $(CS_LDFLAGS)
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
OBJ_SH=anal_sh.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_SH}
|
||||
TARGET_SH=anal_sh.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_SH}
|
||||
|
||||
${TARGET_SH}: ${OBJ_SH}
|
||||
${CC} $(call libname,anal_sh) ${LDFLAGS} \
|
||||
${CFLAGS} -o anal_sh.${EXT_SO} ${OBJ_SH}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
OBJ_SNES=anal_snes.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_SNES}
|
||||
TARGET_SNES=anal_snes.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_SNES}
|
||||
|
||||
${TARGET_SNES}: ${OBJ_SNES}
|
||||
${CC} $(call libname,anal_snes) ${LDFLAGS} ${CFLAGS} -o anal_snes.${EXT_SO} ${OBJ_SNES}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
OBJ_SPARC_CS=anal_sparc_cs.o
|
||||
|
||||
include ${CURDIR}capstone.mk
|
||||
|
||||
STATIC_OBJ+=$(OBJ_SPARC_CS)
|
||||
TARGET_SPARC_CS=anal_sparc_cs.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_SPARC_CS}
|
||||
|
||||
${TARGET_SPARC_CS}: ${OBJ_SPARC_CS}
|
||||
${CC} ${CFLAGS} $(call libname,anal_sparc_cs) $(CS_CFLAGS) \
|
||||
-o anal_sparc_cs.${EXT_SO} ${OBJ_SPARC_CS} $(CS_LDFLAGS)
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
OBJ_SPARC=anal_sparc_gnu.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_SPARC}
|
||||
TARGET_SPARC=anal_sparc_gnu.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_SPARC}
|
||||
|
||||
${TARGET_SPARC}: ${OBJ_SPARC}
|
||||
${CC} $(call libname,anal_sparc_gnu) ${CFLAGS} -o anal_sparc_gnu.${EXT_SO} ${OBJ_SPARC}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
OBJ_SYSTEMZ_CS=anal_sysz.o
|
||||
|
||||
include p/capstone.mk
|
||||
|
||||
STATIC_OBJ+=${OBJ_SYSTEMZ_CS}
|
||||
|
||||
TARGET_SYSTEMZ_CS=anal_sysz.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_SYSTEMZ_CS}
|
||||
|
||||
${TARGET_SYSTEMZ_CS}: ${OBJ_SYSTEMZ_CS}
|
||||
${CC} ${CFLAGS} $(call libname,anal_sysz) $(CS_LDFLAGS) \
|
||||
-o anal_sysz.${EXT_SO} ${OBJ_SYSTEMZ_CS}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
OBJ_TMS3264C64X_CS=anal_tms320c64x.o
|
||||
|
||||
include ${CURDIR}capstone.mk
|
||||
|
||||
STATIC_OBJ+=$(OBJ_TMS3264C64X_CS)
|
||||
TARGET_TMS3264C64X_CS=anal_tms320c64x.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_TMS3264C64X_CS}
|
||||
|
||||
${TARGET_TMS3264C64X_CS}: ${OBJ_TMS3264C64X_CS}
|
||||
${CC} ${CFLAGS} $(call libname,anal_tms320c64x) $(CS_CFLAGS) \
|
||||
-o anal_tms320c64x.${EXT_SO} ${OBJ_TMS3264C64X_CS} $(CS_LDFLAGS)
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
OBJ_TRICORE=anal_tricore.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_TRICORE}
|
||||
TARGET_TRICORE=anal_tricore.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_TRICORE}
|
||||
|
||||
${TARGET_TRICORE}: ${OBJ_TRICORE}
|
||||
${CC} $(call libname,anal_tricore) ${LDFLAGS} ${CFLAGS} \
|
||||
-o $(TARGET_TRICORE) $(OBJ_TRICORE)
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
OBJ_VAX=anal_vax.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_VAX}
|
||||
TARGET_VAX=anal_vax.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_VAX}
|
||||
|
||||
${TARGET_VAX}: ${OBJ_VAX}
|
||||
${CC} $(call libname,anal_vax) ${CFLAGS} -o anal_vax.${EXT_SO} ${OBJ_VAX}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
OBJ_WS=anal_ws.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_WS}
|
||||
TARGET_WS=anal_ws.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_WS}
|
||||
|
||||
${TARGET_WS}: ${OBJ_WS}
|
||||
${CC} $(call libname,anal_ws) ${LDFLAGS} ${CFLAGS} \
|
||||
-o anal_ws.${EXT_SO} ${OBJ_WS}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
OBJ_X86_CS=anal_x86_cs.o
|
||||
|
||||
include $(CURDIR)capstone.mk
|
||||
|
||||
STATIC_OBJ+=$(OBJ_X86_CS)
|
||||
|
||||
TARGET_X86_CS=anal_x86_cs.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_X86_CS}
|
||||
|
||||
${TARGET_X86_CS}: ${OBJ_X86_CS}
|
||||
${CC} ${CFLAGS} $(call libname,anal_x86_cs) $(CS_CFLAGS) \
|
||||
-o anal_x86_cs.${EXT_SO} ${OBJ_X86_CS} $(CS_LDFLAGS)
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
OBJ_XAP=anal_xap.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_XAP}
|
||||
TARGET_XAP=anal_xap.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_XAP}
|
||||
|
||||
${TARGET_XAP}: ${OBJ_XAP}
|
||||
${CC} $(call libname,anal_xap) ${CFLAGS} -o anal_xap.${EXT_SO} ${OBJ_XAP}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
OBJ_XCORE_CS=anal_xcore_cs.o
|
||||
|
||||
include p/capstone.mk
|
||||
|
||||
STATIC_OBJ+=${OBJ_XCORE_CS}
|
||||
TARGET_XCORE_CS=anal_xcore_cs.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_XCORE_CS}
|
||||
|
||||
${TARGET_XCORE_CS}: ${OBJ_XCORE_CS}
|
||||
${CC} ${CFLAGS} $(call libname,anal_xcore_cs) $(CS_CFLAGS) \
|
||||
-o anal_xcore_cs.${EXT_SO} ${OBJ_XCORE_CS} $(CS_LDFLAGS)
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
OBJ_XTENSA=anal_xtensa.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_XTENSA}
|
||||
TARGET_XTENSA=anal_xtensa.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=$(TARGET_XTENSA)
|
||||
|
||||
$(TARGET_XTENSA): $(OBJ_XTENSA)
|
||||
$(CC) $(call libname,anal_xtensa) -I$(LTOP)/asm/arch/include/ \
|
||||
$(LDFLAGS) $(CFLAGS) -o anal_xtensa.$(EXT_SO) $(OBJ_XTENSA)
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
OBJ_Z80=anal_z80.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_Z80}
|
||||
TARGET_Z80=anal_z80.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_Z80}
|
||||
|
||||
${TARGET_Z80}: ${OBJ_Z80}
|
||||
${CC} $(call libname,anal_z80) ${LDFLAGS} ${CFLAGS} \
|
||||
-o anal_z80.${EXT_SO} ${OBJ_Z80}
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#include <rz_anal.h>
|
||||
|
||||
static RzAnalSwitchOp *__switch_op_new(void) {
|
||||
RzAnalSwitchOp * swop = RZ_NEW0 (RzAnalSwitchOp);
|
||||
if (swop) {
|
||||
swop->cases = rz_list_new ();
|
||||
if (!swop->cases) {
|
||||
free (swop);
|
||||
return NULL;
|
||||
}
|
||||
swop->cases->free = (void *)free;
|
||||
swop->min_val = swop->def_val = swop->max_val = 0;
|
||||
}
|
||||
return swop;
|
||||
}
|
||||
|
||||
RZ_API RzAnalSwitchOp *rz_anal_switch_op_new(ut64 addr, ut64 min_val, ut64 max_val, ut64 def_val) {
|
||||
RzAnalSwitchOp *swop = __switch_op_new ();
|
||||
if (swop) {
|
||||
swop->addr = addr;
|
||||
swop->min_val = min_val;
|
||||
swop->def_val = def_val;
|
||||
swop->max_val = max_val;
|
||||
}
|
||||
return swop;
|
||||
}
|
||||
|
||||
RZ_API RzAnalCaseOp * rz_anal_case_op_new(ut64 addr, ut64 val, ut64 jump) {
|
||||
RzAnalCaseOp *c = RZ_NEW0 (RzAnalCaseOp);
|
||||
if (c) {
|
||||
c->addr = addr;
|
||||
c->value = val;
|
||||
c->jump = jump;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
RZ_API void rz_anal_switch_op_free(RzAnalSwitchOp * swop) {
|
||||
if (swop) {
|
||||
rz_list_free (swop->cases);
|
||||
free (swop);
|
||||
}
|
||||
}
|
||||
|
||||
RZ_API RzAnalCaseOp* rz_anal_switch_op_add_case(RzAnalSwitchOp * swop, ut64 addr, ut64 value, ut64 jump) {
|
||||
rz_return_val_if_fail (swop && addr != UT64_MAX, NULL);
|
||||
RzAnalCaseOp * caseop = rz_anal_case_op_new (addr, value, jump);
|
||||
if (caseop) {
|
||||
rz_list_append (swop->cases, caseop);
|
||||
}
|
||||
return caseop;
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@ EXTRA_TARGETS+=do
|
|||
EXTRA_CLEAN=doclean
|
||||
CFLAGS+=-I..
|
||||
|
||||
NAME=rz_anal
|
||||
NAME=rz_analysis
|
||||
RZ_DEPS=rz_util rz_reg rz_syscall rz_search rz_cons rz_flag rz_hash rz_crypto rz_parse
|
||||
CFLAGS+=-DRZ_PLUGIN_INCORE -Iarch -I$(TOP)/shlr
|
||||
CFLAGS+=-I$(LTOP)/asm/arch/include
|
||||
|
|
@ -25,18 +25,18 @@ all: plugins
|
|||
plugins: ${LIBSO} ${LIBAR}
|
||||
@${MAKE} -C p all
|
||||
|
||||
include ${STATIC_ANAL_PLUGINS}
|
||||
include ${STATIC_ANALYSIS_PLUGINS}
|
||||
|
||||
STATIC_OBJS=$(addprefix $(LTOP)/anal/p/,$(STATIC_OBJ))
|
||||
STATIC_OBJS=$(addprefix $(LTOP)/analysis/p/,$(STATIC_OBJ))
|
||||
OBJLIBS=meta.o reflines.o op.o fcn.o bb.o var.o block.o
|
||||
OBJLIBS+=cond.o value.o cc.o class.o diff.o type.o type_pdb.o dwarf_process.o
|
||||
OBJLIBS+=hint.o anal.o data.o xrefs.o esil.o sign.o
|
||||
OBJLIBS+=hint.o analysis.o data.o xrefs.o esil.o sign.o
|
||||
OBJLIBS+=switch.o cycles.o esil_dfg.o
|
||||
OBJLIBS+=esil_sources.o esil_interrupt.o esil_cfg.o
|
||||
OBJLIBS+=esil_stats.o esil_trace.o flirt.o labels.o
|
||||
OBJLIBS+=esil2reil.o pin.o vtable.o rtti.o
|
||||
OBJLIBS+=rtti_msvc.o rtti_itanium.o jmptbl.o function.o
|
||||
OBJLIBS+=serialize_anal.o
|
||||
OBJLIBS+=serialize_analysis.o
|
||||
ASMOBJS+=$(LTOP)/asm/arch/xtensa/gnu/xtensa-modules.o
|
||||
ASMOBJS+=$(LTOP)/asm/arch/xtensa/gnu/xtensa-isa.o
|
||||
ASMOBJS+=$(LTOP)/asm/arch/xtensa/gnu/elf32-xtensa.o
|
||||
725
librz/analysis/analysis.c
Normal file
725
librz/analysis/analysis.c
Normal file
|
|
@ -0,0 +1,725 @@
|
|||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#include <rz_analysis.h>
|
||||
#include <rz_util.h>
|
||||
#include <rz_list.h>
|
||||
#include <rz_io.h>
|
||||
#include <config.h>
|
||||
|
||||
RZ_LIB_VERSION(rz_analysis);
|
||||
|
||||
static RzAnalysisPlugin *anal_static_plugins[] = {
|
||||
RZ_ANALYSIS_STATIC_PLUGINS
|
||||
};
|
||||
|
||||
RZ_API void rz_analysis_set_limits(RzAnalysis *analysis, ut64 from, ut64 to) {
|
||||
free (analysis->limit);
|
||||
analysis->limit = RZ_NEW0 (RzAnalysisRange);
|
||||
if (analysis->limit) {
|
||||
analysis->limit->from = from;
|
||||
analysis->limit->to = to;
|
||||
}
|
||||
}
|
||||
|
||||
RZ_API void rz_analysis_unset_limits(RzAnalysis *analysis) {
|
||||
RZ_FREE (analysis->limit);
|
||||
}
|
||||
|
||||
static void meta_unset_for(RzEvent *ev, int type, void *user, void *data) {
|
||||
RzSpaces *s = (RzSpaces *)ev->user;
|
||||
RzAnalysis *analysis = container_of (s, RzAnalysis, meta_spaces);
|
||||
RzSpaceEvent *se = (RzSpaceEvent *)data;
|
||||
rz_meta_space_unset_for (analysis, se->data.unset.space);
|
||||
}
|
||||
|
||||
static void meta_count_for(RzEvent *ev, int type, void *user, void *data) {
|
||||
RzSpaces *s = (RzSpaces *)ev->user;
|
||||
RzAnalysis *analysis = container_of (s, RzAnalysis, meta_spaces);
|
||||
RzSpaceEvent *se = (RzSpaceEvent *)data;
|
||||
se->res = rz_meta_space_count_for (analysis, se->data.count.space);
|
||||
}
|
||||
|
||||
static void zign_unset_for(RzEvent *ev, int type, void *user, void *data) {
|
||||
RzSpaces *s = (RzSpaces *)ev->user;
|
||||
RzAnalysis *analysis = container_of (s, RzAnalysis, zign_spaces);
|
||||
RzSpaceEvent *se = (RzSpaceEvent *)data;
|
||||
rz_sign_space_unset_for (analysis, se->data.unset.space);
|
||||
}
|
||||
|
||||
static void zign_count_for(RzEvent *ev, int type, void *user, void *data) {
|
||||
RzSpaces *s = (RzSpaces *)ev->user;
|
||||
RzAnalysis *analysis = container_of (s, RzAnalysis, zign_spaces);
|
||||
RzSpaceEvent *se = (RzSpaceEvent *)data;
|
||||
se->res = rz_sign_space_count_for (analysis, se->data.count.space);
|
||||
}
|
||||
|
||||
static void zign_rename_for(RzEvent *ev, int type, void *user, void *data) {
|
||||
RzSpaces *s = (RzSpaces *)ev->user;
|
||||
RzAnalysis *analysis = container_of (s, RzAnalysis, zign_spaces);
|
||||
RzSpaceEvent *se = (RzSpaceEvent *)data;
|
||||
rz_sign_space_rename_for (analysis, se->data.rename.space,
|
||||
se->data.rename.oldname, se->data.rename.newname);
|
||||
}
|
||||
|
||||
void rz_analysis_hint_storage_init(RzAnalysis *a);
|
||||
void rz_analysis_hint_storage_fini(RzAnalysis *a);
|
||||
|
||||
static void rz_meta_item_fini(RzAnalysisMetaItem *item) {
|
||||
free (item->str);
|
||||
}
|
||||
|
||||
static void rz_meta_item_free(void *_item) {
|
||||
if (_item) {
|
||||
RzAnalysisMetaItem *item = _item;
|
||||
rz_meta_item_fini (item);
|
||||
free (item);
|
||||
}
|
||||
}
|
||||
|
||||
RZ_API RzAnalysis *rz_analysis_new(void) {
|
||||
int i;
|
||||
RzAnalysis *analysis = RZ_NEW0 (RzAnalysis);
|
||||
if (!analysis) {
|
||||
return NULL;
|
||||
}
|
||||
if (!rz_str_constpool_init (&analysis->constpool)) {
|
||||
free (analysis);
|
||||
return NULL;
|
||||
}
|
||||
analysis->bb_tree = NULL;
|
||||
analysis->ht_addr_fun = ht_up_new0 ();
|
||||
analysis->ht_name_fun = ht_pp_new0 ();
|
||||
analysis->os = strdup (RZ_SYS_OS);
|
||||
analysis->esil_goto_limit = RZ_ANAL_ESIL_GOTO_LIMIT;
|
||||
analysis->opt.nopskip = true; // skip nops in code analysis
|
||||
analysis->opt.hpskip = false; // skip `mov reg,reg` and `lea reg,[reg]`
|
||||
analysis->gp = 0LL;
|
||||
analysis->sdb = sdb_new0 ();
|
||||
analysis->cpp_abi = RZ_ANAL_CPP_ABI_ITANIUM;
|
||||
analysis->opt.depth = 32;
|
||||
analysis->opt.noncode = false; // do not analyze data by default
|
||||
rz_spaces_init (&analysis->meta_spaces, "CS");
|
||||
rz_event_hook (analysis->meta_spaces.event, RZ_SPACE_EVENT_UNSET, meta_unset_for, NULL);
|
||||
rz_event_hook (analysis->meta_spaces.event, RZ_SPACE_EVENT_COUNT, meta_count_for, NULL);
|
||||
|
||||
rz_spaces_init (&analysis->zign_spaces, "zs");
|
||||
rz_event_hook (analysis->zign_spaces.event, RZ_SPACE_EVENT_UNSET, zign_unset_for, NULL);
|
||||
rz_event_hook (analysis->zign_spaces.event, RZ_SPACE_EVENT_COUNT, zign_count_for, NULL);
|
||||
rz_event_hook (analysis->zign_spaces.event, RZ_SPACE_EVENT_RENAME, zign_rename_for, NULL);
|
||||
rz_analysis_hint_storage_init (analysis);
|
||||
rz_interval_tree_init (&analysis->meta, rz_meta_item_free);
|
||||
analysis->sdb_types = sdb_ns (analysis->sdb, "types", 1);
|
||||
analysis->sdb_fmts = sdb_ns (analysis->sdb, "spec", 1);
|
||||
analysis->sdb_cc = sdb_ns (analysis->sdb, "cc", 1);
|
||||
analysis->sdb_zigns = sdb_ns (analysis->sdb, "zigns", 1);
|
||||
analysis->sdb_classes = sdb_ns (analysis->sdb, "classes", 1);
|
||||
analysis->sdb_classes_attrs = sdb_ns (analysis->sdb_classes, "attrs", 1);
|
||||
analysis->zign_path = strdup ("");
|
||||
analysis->cb_printf = (PrintfCallback) printf;
|
||||
(void)rz_analysis_pin_init (analysis);
|
||||
(void)rz_analysis_xrefs_init (analysis);
|
||||
analysis->diff_thbb = RZ_ANAL_THRESHOLDBB;
|
||||
analysis->diff_thfcn = RZ_ANAL_THRESHOLDFCN;
|
||||
analysis->syscall = rz_syscall_new ();
|
||||
rz_io_bind_init (analysis->iob);
|
||||
rz_flag_bind_init (analysis->flb);
|
||||
analysis->reg = rz_reg_new ();
|
||||
analysis->last_disasm_reg = NULL;
|
||||
analysis->stackptr = 0;
|
||||
analysis->lineswidth = 0;
|
||||
analysis->fcns = rz_list_newf (rz_analysis_function_free);
|
||||
analysis->leaddrs = NULL;
|
||||
analysis->imports = rz_list_newf (free);
|
||||
rz_analysis_set_bits (analysis, 32);
|
||||
analysis->plugins = rz_list_newf ((RzListFree) rz_analysis_plugin_free);
|
||||
if (analysis->plugins) {
|
||||
for (i = 0; anal_static_plugins[i]; i++) {
|
||||
rz_analysis_add (analysis, anal_static_plugins[i]);
|
||||
}
|
||||
}
|
||||
return analysis;
|
||||
}
|
||||
|
||||
RZ_API void rz_analysis_plugin_free (RzAnalysisPlugin *p) {
|
||||
if (p && p->fini) {
|
||||
p->fini (NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void __block_free_rb(RBNode *node, void *user);
|
||||
|
||||
RZ_API RzAnalysis *rz_analysis_free(RzAnalysis *a) {
|
||||
if (!a) {
|
||||
return NULL;
|
||||
}
|
||||
/* TODO: Free anals here */
|
||||
rz_list_free (a->fcns);
|
||||
ht_up_free (a->ht_addr_fun);
|
||||
ht_pp_free (a->ht_name_fun);
|
||||
set_u_free (a->visited);
|
||||
rz_analysis_hint_storage_fini (a);
|
||||
rz_interval_tree_fini (&a->meta);
|
||||
free (a->cpu);
|
||||
free (a->os);
|
||||
free (a->zign_path);
|
||||
rz_list_free (a->plugins);
|
||||
rz_rbtree_free (a->bb_tree, __block_free_rb, NULL);
|
||||
rz_spaces_fini (&a->meta_spaces);
|
||||
rz_spaces_fini (&a->zign_spaces);
|
||||
rz_analysis_pin_fini (a);
|
||||
rz_syscall_free (a->syscall);
|
||||
rz_reg_free (a->reg);
|
||||
ht_up_free (a->dict_refs);
|
||||
ht_up_free (a->dict_xrefs);
|
||||
rz_list_free (a->leaddrs);
|
||||
sdb_free (a->sdb);
|
||||
if (a->esil) {
|
||||
rz_analysis_esil_free (a->esil);
|
||||
a->esil = NULL;
|
||||
}
|
||||
free (a->last_disasm_reg);
|
||||
rz_list_free (a->imports);
|
||||
rz_str_constpool_fini (&a->constpool);
|
||||
free (a);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RZ_API void rz_analysis_set_user_ptr(RzAnalysis *analysis, void *user) {
|
||||
analysis->user = user;
|
||||
}
|
||||
|
||||
RZ_API int rz_analysis_add(RzAnalysis *analysis, RzAnalysisPlugin *foo) {
|
||||
if (foo->init) {
|
||||
foo->init (analysis->user);
|
||||
}
|
||||
rz_list_append (analysis->plugins, foo);
|
||||
return true;
|
||||
}
|
||||
|
||||
RZ_API bool rz_analysis_use(RzAnalysis *analysis, const char *name) {
|
||||
RzListIter *it;
|
||||
RzAnalysisPlugin *h;
|
||||
|
||||
if (analysis) {
|
||||
rz_list_foreach (analysis->plugins, it, h) {
|
||||
if (!h->name || strcmp (h->name, name)) {
|
||||
continue;
|
||||
}
|
||||
#if 0
|
||||
// regression happening here for asm.emu
|
||||
if (analysis->cur && analysis->cur == h) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
analysis->cur = h;
|
||||
rz_analysis_set_reg_profile (analysis);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
RZ_API char *rz_analysis_get_reg_profile(RzAnalysis *analysis) {
|
||||
return (analysis && analysis->cur && analysis->cur->get_reg_profile)
|
||||
? analysis->cur->get_reg_profile (analysis) : NULL;
|
||||
}
|
||||
|
||||
// deprecate.. or at least reuse get_reg_profile...
|
||||
RZ_API bool rz_analysis_set_reg_profile(RzAnalysis *analysis) {
|
||||
bool ret = false;
|
||||
if (analysis && analysis->cur && analysis->cur->set_reg_profile) {
|
||||
ret = analysis->cur->set_reg_profile (analysis);
|
||||
} else {
|
||||
char *p = rz_analysis_get_reg_profile (analysis);
|
||||
if (p && *p) {
|
||||
rz_reg_set_profile_string (analysis->reg, p);
|
||||
ret = true;
|
||||
}
|
||||
free (p);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
RZ_API bool rz_analysis_set_triplet(RzAnalysis *analysis, const char *os, const char *arch, int bits) {
|
||||
rz_return_val_if_fail (analysis, false);
|
||||
if (!os || !*os) {
|
||||
os = RZ_SYS_OS;
|
||||
}
|
||||
if (!arch || !*arch) {
|
||||
arch = analysis->cur? analysis->cur->arch: RZ_SYS_ARCH;
|
||||
}
|
||||
if (bits < 1) {
|
||||
bits = analysis->bits;
|
||||
}
|
||||
free (analysis->os);
|
||||
analysis->os = strdup (os);
|
||||
rz_analysis_set_bits (analysis, bits);
|
||||
return rz_analysis_use (analysis, arch);
|
||||
}
|
||||
|
||||
// copypasta from core/cbin.c
|
||||
static void sdb_concat_by_path(Sdb *s, const char *path) {
|
||||
Sdb *db = sdb_new (0, path, 0);
|
||||
sdb_merge (s, db);
|
||||
sdb_close (db);
|
||||
sdb_free (db);
|
||||
}
|
||||
|
||||
RZ_API bool rz_analysis_set_os(RzAnalysis *analysis, const char *os) {
|
||||
Sdb *types = analysis->sdb_types;
|
||||
const char *dir_prefix = rz_sys_prefix (NULL);
|
||||
const char *dbpath = sdb_fmt (RZ_JOIN_3_PATHS ("%s", RZ_SDB_FCNSIGN, "types-%s.sdb"),
|
||||
dir_prefix, os);
|
||||
if (rz_file_exists (dbpath)) {
|
||||
sdb_concat_by_path (types, dbpath);
|
||||
}
|
||||
return rz_analysis_set_triplet (analysis, os, NULL, -1);
|
||||
}
|
||||
|
||||
RZ_API bool rz_analysis_set_bits(RzAnalysis *analysis, int bits) {
|
||||
switch (bits) {
|
||||
case 8:
|
||||
case 16:
|
||||
case 27:
|
||||
case 32:
|
||||
case 64:
|
||||
if (analysis->bits != bits) {
|
||||
analysis->bits = bits;
|
||||
rz_analysis_set_reg_profile (analysis);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
RZ_API void rz_analysis_set_cpu(RzAnalysis *analysis, const char *cpu) {
|
||||
free (analysis->cpu);
|
||||
analysis->cpu = cpu ? strdup (cpu) : NULL;
|
||||
int v = rz_analysis_archinfo (analysis, RZ_ANAL_ARCHINFO_ALIGN);
|
||||
if (v != -1) {
|
||||
analysis->pcalign = v;
|
||||
}
|
||||
}
|
||||
|
||||
RZ_API int rz_analysis_set_big_endian(RzAnalysis *analysis, int bigend) {
|
||||
analysis->big_endian = bigend;
|
||||
analysis->reg->big_endian = bigend;
|
||||
return true;
|
||||
}
|
||||
|
||||
RZ_API ut8 *rz_analysis_mask(RzAnalysis *analysis, int size, const ut8 *data, ut64 at) {
|
||||
RzAnalysisOp *op = NULL;
|
||||
ut8 *ret = NULL;
|
||||
int oplen, idx = 0;
|
||||
|
||||
if (!data) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (analysis->cur && analysis->cur->analysis_mask) {
|
||||
return analysis->cur->analysis_mask (analysis, size, data, at);
|
||||
}
|
||||
|
||||
if (!(op = rz_analysis_op_new ())) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(ret = malloc (size))) {
|
||||
rz_analysis_op_free (op);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset (ret, 0xff, size);
|
||||
|
||||
while (idx < size) {
|
||||
if ((oplen = rz_analysis_op (analysis, op, at, data + idx, size - idx, RZ_ANAL_OP_MASK_BASIC)) < 1) {
|
||||
break;
|
||||
}
|
||||
if ((op->ptr != UT64_MAX || op->jump != UT64_MAX) && op->nopcode != 0) {
|
||||
memset (ret + idx + op->nopcode, 0, oplen - op->nopcode);
|
||||
}
|
||||
idx += oplen;
|
||||
at += oplen;
|
||||
}
|
||||
|
||||
rz_analysis_op_free (op);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
RZ_API void rz_analysis_trace_bb(RzAnalysis *analysis, ut64 addr) {
|
||||
RzAnalysisBlock *bbi;
|
||||
RzAnalysisFunction *fcni;
|
||||
RzListIter *iter2;
|
||||
fcni = rz_analysis_get_fcn_in (analysis, addr, 0);
|
||||
if (fcni) {
|
||||
rz_list_foreach (fcni->bbs, iter2, bbi) {
|
||||
if (addr >= bbi->addr && addr < (bbi->addr + bbi->size)) {
|
||||
bbi->traced = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RZ_API void rz_analysis_colorize_bb(RzAnalysis *analysis, ut64 addr, ut32 color) {
|
||||
RzAnalysisBlock *bbi;
|
||||
bbi = rz_analysis_bb_from_offset (analysis, addr);
|
||||
if (bbi) {
|
||||
bbi->colorize = color;
|
||||
}
|
||||
}
|
||||
|
||||
RZ_API RzList* rz_analysis_get_fcns (RzAnalysis *analysis) {
|
||||
// avoid received to free this thing
|
||||
analysis->fcns->free = NULL;
|
||||
return analysis->fcns;
|
||||
}
|
||||
|
||||
RZ_API RzAnalysisOp *rz_analysis_op_hexstr(RzAnalysis *analysis, ut64 addr, const char *str) {
|
||||
RzAnalysisOp *op = RZ_NEW0 (RzAnalysisOp);
|
||||
if (!op) {
|
||||
return NULL;
|
||||
}
|
||||
ut8 *buf = calloc (1, strlen (str) + 1);
|
||||
if (!buf) {
|
||||
free (op);
|
||||
return NULL;
|
||||
}
|
||||
int len = rz_hex_str2bin (str, buf);
|
||||
rz_analysis_op (analysis, op, addr, buf, len, RZ_ANAL_OP_MASK_BASIC);
|
||||
free (buf);
|
||||
return op;
|
||||
}
|
||||
|
||||
RZ_API bool rz_analysis_op_is_eob(RzAnalysisOp *op) {
|
||||
if (op->eob) {
|
||||
return true;
|
||||
}
|
||||
switch (op->type) {
|
||||
case RZ_ANAL_OP_TYPE_JMP:
|
||||
case RZ_ANAL_OP_TYPE_UJMP:
|
||||
case RZ_ANAL_OP_TYPE_RJMP:
|
||||
case RZ_ANAL_OP_TYPE_IJMP:
|
||||
case RZ_ANAL_OP_TYPE_IRJMP:
|
||||
case RZ_ANAL_OP_TYPE_CJMP:
|
||||
case RZ_ANAL_OP_TYPE_RET:
|
||||
case RZ_ANAL_OP_TYPE_TRAP:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
RZ_API void rz_analysis_purge(RzAnalysis *analysis) {
|
||||
rz_analysis_hint_clear (analysis);
|
||||
rz_interval_tree_fini (&analysis->meta);
|
||||
rz_interval_tree_init (&analysis->meta, rz_meta_item_free);
|
||||
sdb_reset (analysis->sdb_types);
|
||||
sdb_reset (analysis->sdb_zigns);
|
||||
sdb_reset (analysis->sdb_classes);
|
||||
sdb_reset (analysis->sdb_classes_attrs);
|
||||
rz_analysis_pin_fini (analysis);
|
||||
rz_analysis_pin_init (analysis);
|
||||
sdb_reset (analysis->sdb_cc);
|
||||
rz_list_free (analysis->fcns);
|
||||
analysis->fcns = rz_list_newf (rz_analysis_function_free);
|
||||
rz_analysis_purge_imports (analysis);
|
||||
}
|
||||
|
||||
RZ_API int rz_analysis_archinfo(RzAnalysis *analysis, int query) {
|
||||
rz_return_val_if_fail (analysis, -1);
|
||||
switch (query) {
|
||||
case RZ_ANAL_ARCHINFO_MIN_OP_SIZE:
|
||||
case RZ_ANAL_ARCHINFO_MAX_OP_SIZE:
|
||||
case RZ_ANAL_ARCHINFO_ALIGN:
|
||||
if (analysis->cur && analysis->cur->archinfo) {
|
||||
return analysis->cur->archinfo (analysis, query);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static bool __nonreturn_print_commands(void *p, const char *k, const char *v) {
|
||||
RzAnalysis *analysis = (RzAnalysis *)p;
|
||||
if (!strncmp (v, "func", strlen ("func") + 1)) {
|
||||
char *query = sdb_fmt ("func.%s.noreturn", k);
|
||||
if (sdb_bool_get (analysis->sdb_types, query, NULL)) {
|
||||
analysis->cb_printf ("tnn %s\n", k);
|
||||
}
|
||||
}
|
||||
if (!strncmp (k, "addr.", 5)) {
|
||||
analysis->cb_printf ("tna 0x%s %s\n", k + 5, v);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __nonreturn_print(void *p, const char *k, const char *v) {
|
||||
RzAnalysis *analysis = (RzAnalysis *)p;
|
||||
if (!strncmp (k, "func.", 5) && strstr (k, ".noreturn")) {
|
||||
char *s = strdup (k + 5);
|
||||
char *d = strchr (s, '.');
|
||||
if (d) {
|
||||
*d = 0;
|
||||
}
|
||||
analysis->cb_printf ("%s\n", s);
|
||||
free (s);
|
||||
}
|
||||
if (!strncmp (k, "addr.", 5)) {
|
||||
char *off;
|
||||
if (!(off = strdup (k + 5))) {
|
||||
return 1;
|
||||
}
|
||||
char *ptr = strstr (off, ".noreturn");
|
||||
if (ptr) {
|
||||
*ptr = 0;
|
||||
analysis->cb_printf ("0x%s\n", off);
|
||||
}
|
||||
free (off);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
RZ_API void rz_analysis_noreturn_list(RzAnalysis *analysis, int mode) {
|
||||
switch (mode) {
|
||||
case 1:
|
||||
case '*':
|
||||
case 'r':
|
||||
sdb_foreach (analysis->sdb_types, __nonreturn_print_commands, analysis);
|
||||
break;
|
||||
default:
|
||||
sdb_foreach (analysis->sdb_types, __nonreturn_print, analysis);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#define K_NORET_ADDR(x) sdb_fmt ("addr.%"PFMT64x".noreturn", x)
|
||||
#define K_NORET_FUNC(x) sdb_fmt ("func.%s.noreturn", x)
|
||||
|
||||
RZ_API bool rz_analysis_noreturn_add(RzAnalysis *analysis, const char *name, ut64 addr) {
|
||||
const char *tmp_name = NULL;
|
||||
Sdb *TDB = analysis->sdb_types;
|
||||
char *fnl_name = NULL;
|
||||
if (addr != UT64_MAX) {
|
||||
if (sdb_bool_set (TDB, K_NORET_ADDR (addr), true, 0)) {
|
||||
RzAnalysisFunction *fcn = rz_analysis_get_function_at (analysis, addr);
|
||||
if (fcn) {
|
||||
fcn->is_noreturn = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (name && *name) {
|
||||
tmp_name = name;
|
||||
} else {
|
||||
RzAnalysisFunction *fcn = rz_analysis_get_fcn_in (analysis, addr, -1);
|
||||
RzFlagItem *fi = analysis->flb.get_at (analysis->flb.f, addr, false);
|
||||
if (!fcn && !fi) {
|
||||
eprintf ("Can't find Function at given address\n");
|
||||
return false;
|
||||
}
|
||||
tmp_name = fcn ? fcn->name: fi->name;
|
||||
if (fcn) {
|
||||
fcn->is_noreturn = true;
|
||||
}
|
||||
}
|
||||
if (rz_type_func_exist (TDB, tmp_name)) {
|
||||
fnl_name = strdup (tmp_name);
|
||||
} else if (!(fnl_name = rz_type_func_guess (TDB, (char *)tmp_name))) {
|
||||
if (addr == UT64_MAX) {
|
||||
if (name) {
|
||||
sdb_bool_set (TDB, K_NORET_FUNC (name), true, 0);
|
||||
} else {
|
||||
eprintf ("Can't find prototype for: %s\n", tmp_name);
|
||||
}
|
||||
} else {
|
||||
eprintf ("Can't find prototype for: %s\n", tmp_name);
|
||||
}
|
||||
//return false;
|
||||
}
|
||||
if (fnl_name) {
|
||||
sdb_bool_set (TDB, K_NORET_FUNC (fnl_name), true, 0);
|
||||
free (fnl_name);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
RZ_API bool rz_analysis_noreturn_drop(RzAnalysis *analysis, const char *expr) {
|
||||
Sdb *TDB = analysis->sdb_types;
|
||||
expr = rz_str_trim_head_ro (expr);
|
||||
const char *fcnname = NULL;
|
||||
if (!strncmp (expr, "0x", 2)) {
|
||||
ut64 n = rz_num_math (NULL, expr);
|
||||
sdb_unset (TDB, K_NORET_ADDR (n), 0);
|
||||
RzAnalysisFunction *fcn = rz_analysis_get_fcn_in (analysis, n, -1);
|
||||
if (!fcn) {
|
||||
// eprintf ("can't find function at 0x%"PFMT64x"\n", n);
|
||||
return false;
|
||||
}
|
||||
fcnname = fcn->name;
|
||||
} else {
|
||||
fcnname = expr;
|
||||
}
|
||||
sdb_unset (TDB, K_NORET_FUNC (fcnname), 0);
|
||||
#if 0
|
||||
char *tmp;
|
||||
// unnsecessary checks, imho the noreturn db should be pretty simple to allow forward and custom declarations without having to define the function prototype before
|
||||
if (rz_type_func_exist (TDB, fcnname)) {
|
||||
sdb_unset (TDB, K_NORET_FUNC (fcnname), 0);
|
||||
return true;
|
||||
} else if ((tmp = rz_type_func_guess (TDB, (char *)fcnname))) {
|
||||
sdb_unset (TDB, K_NORET_FUNC (fcnname), 0);
|
||||
free (tmp);
|
||||
return true;
|
||||
}
|
||||
eprintf ("Can't find prototype for %s in types database", fcnname);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool rz_analysis_noreturn_at_name(RzAnalysis *analysis, const char *name) {
|
||||
if (sdb_bool_get (analysis->sdb_types, K_NORET_FUNC(name), NULL)) {
|
||||
return true;
|
||||
}
|
||||
char *tmp = rz_type_func_guess (analysis->sdb_types, (char *)name);
|
||||
if (tmp) {
|
||||
if (sdb_bool_get (analysis->sdb_types, K_NORET_FUNC (tmp), NULL)) {
|
||||
free (tmp);
|
||||
return true;
|
||||
}
|
||||
free (tmp);
|
||||
}
|
||||
if (rz_str_startswith (name, "reloc.")) {
|
||||
return rz_analysis_noreturn_at_name (analysis, name + 6);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
RZ_API bool rz_analysis_noreturn_at_addr(RzAnalysis *analysis, ut64 addr) {
|
||||
return sdb_bool_get (analysis->sdb_types, K_NORET_ADDR (addr), NULL);
|
||||
}
|
||||
|
||||
static bool noreturn_recurse(RzAnalysis *analysis, ut64 addr) {
|
||||
RzAnalysisOp op = {0};
|
||||
ut8 bbuf[0x10] = {0};
|
||||
ut64 recurse_addr = UT64_MAX;
|
||||
if (!analysis->iob.read_at (analysis->iob.io, addr, bbuf, sizeof (bbuf))) {
|
||||
eprintf ("Couldn't read buffer\n");
|
||||
return false;
|
||||
}
|
||||
if (rz_analysis_op (analysis, &op, addr, bbuf, sizeof (bbuf), RZ_ANAL_OP_MASK_BASIC | RZ_ANAL_OP_MASK_VAL) < 1) {
|
||||
return false;
|
||||
}
|
||||
switch (op.type & RZ_ANAL_OP_TYPE_MASK) {
|
||||
case RZ_ANAL_OP_TYPE_JMP:
|
||||
if (op.jump == UT64_MAX) {
|
||||
recurse_addr = op.ptr;
|
||||
} else {
|
||||
recurse_addr = op.jump;
|
||||
}
|
||||
break;
|
||||
case RZ_ANAL_OP_TYPE_UCALL:
|
||||
case RZ_ANAL_OP_TYPE_RCALL:
|
||||
case RZ_ANAL_OP_TYPE_ICALL:
|
||||
case RZ_ANAL_OP_TYPE_IRCALL:
|
||||
recurse_addr = op.ptr;
|
||||
break;
|
||||
case RZ_ANAL_OP_TYPE_CCALL:
|
||||
case RZ_ANAL_OP_TYPE_CALL:
|
||||
recurse_addr = op.jump;
|
||||
break;
|
||||
}
|
||||
if (recurse_addr == UT64_MAX || recurse_addr == addr) {
|
||||
return false;
|
||||
}
|
||||
return rz_analysis_noreturn_at (analysis, recurse_addr);
|
||||
}
|
||||
|
||||
RZ_API bool rz_analysis_noreturn_at(RzAnalysis *analysis, ut64 addr) {
|
||||
if (!addr || addr == UT64_MAX) {
|
||||
return false;
|
||||
}
|
||||
if (rz_analysis_noreturn_at_addr (analysis, addr)) {
|
||||
return true;
|
||||
}
|
||||
/* XXX this is very slow */
|
||||
RzAnalysisFunction *f = rz_analysis_get_function_at (analysis, addr);
|
||||
if (f) {
|
||||
if (rz_analysis_noreturn_at_name (analysis, f->name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
RzFlagItem *fi = analysis->flag_get (analysis->flb.f, addr);
|
||||
if (fi) {
|
||||
if (rz_analysis_noreturn_at_name (analysis, fi->realname ? fi->realname : fi->name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (analysis->recursive_noreturn) {
|
||||
return noreturn_recurse (analysis, addr);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
RZ_API void rz_analysis_bind(RzAnalysis *analysis, RzAnalysisBind *b) {
|
||||
if (b) {
|
||||
b->analysis = analysis;
|
||||
b->get_fcn_in = rz_analysis_get_fcn_in;
|
||||
b->get_hint = rz_analysis_hint_get;
|
||||
}
|
||||
}
|
||||
|
||||
RZ_API RzList *rz_analysis_preludes(RzAnalysis *analysis) {
|
||||
if (analysis->cur && analysis->cur->preludes ) {
|
||||
return analysis->cur->preludes (analysis);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RZ_API bool rz_analysis_is_prelude(RzAnalysis *analysis, const ut8 *data, int len) {
|
||||
RzList *l = rz_analysis_preludes (analysis);
|
||||
if (l) {
|
||||
RzSearchKeyword *kw;
|
||||
RzListIter *iter;
|
||||
rz_list_foreach (l, iter, kw) {
|
||||
int ks = kw->keyword_length;
|
||||
if (len >= ks && !memcmp (data, kw->bin_keyword, ks)) {
|
||||
rz_list_free (l);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
rz_list_free (l);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
RZ_API void rz_analysis_add_import(RzAnalysis *analysis, const char *imp) {
|
||||
RzListIter *it;
|
||||
const char *eimp;
|
||||
rz_list_foreach (analysis->imports, it, eimp) {
|
||||
if (!strcmp (eimp, imp)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
char *cimp = strdup (imp);
|
||||
if (!cimp) {
|
||||
return;
|
||||
}
|
||||
rz_list_push (analysis->imports, cimp);
|
||||
}
|
||||
|
||||
RZ_API void rz_analysis_remove_import(RzAnalysis *analysis, const char *imp) {
|
||||
RzListIter *it;
|
||||
const char *eimp;
|
||||
rz_list_foreach (analysis->imports, it, eimp) {
|
||||
if (!strcmp (eimp, imp)) {
|
||||
rz_list_delete (analysis->imports, it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RZ_API void rz_analysis_purge_imports(RzAnalysis *analysis) {
|
||||
rz_list_purge (analysis->imports);
|
||||
}
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#include <rz_io.h>
|
||||
#include <rz_anal.h>
|
||||
#include <rz_analysis.h>
|
||||
|
||||
void meta_gb_bankswitch_cmt(RzAnal *a, ut64 addr, ut16 ldarg) {
|
||||
void meta_gb_bankswitch_cmt(RzAnalysis *a, ut64 addr, ut16 ldarg) {
|
||||
if(0x1fff <ldarg && ldarg < 0x4000 && addr < 0x4000)
|
||||
rz_meta_set_string (a, RZ_META_TYPE_COMMENT, addr, "Bankswitch");
|
||||
if(0x6000 > ldarg && ldarg > 0x3fff)
|
||||
|
|
@ -3,11 +3,11 @@
|
|||
#include <rz_types.h>
|
||||
#include <rz_util.h>
|
||||
#include <rz_asm.h>
|
||||
#include <rz_anal.h>
|
||||
#include <rz_analysis.h>
|
||||
#include "hexagon.h"
|
||||
#include "hexagon_insn.h"
|
||||
|
||||
int hexagon_anal_instruction(HexInsn *hi, RzAnalOp *op) {
|
||||
int hexagon_analysis_instruction(HexInsn *hi, RzAnalysisOp *op) {
|
||||
switch (hi->instruction) {
|
||||
case HEX_INS_CALL__R22_2: {
|
||||
// call #r22:2
|
||||
2
librz/analysis/arch/hexagon/hexagon_anal.h
Normal file
2
librz/analysis/arch/hexagon/hexagon_anal.h
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
int hexagon_analysis_instruction(HexInsn *hi, RzAnalysisOp *op);
|
||||
|
||||
|
|
@ -1,19 +1,19 @@
|
|||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#include <rz_anal.h>
|
||||
#include <rz_analysis.h>
|
||||
#include <rz_util.h>
|
||||
#include <rz_list.h>
|
||||
#include <limits.h>
|
||||
|
||||
typedef struct {
|
||||
ut64 addr;
|
||||
RzAnalBlock *ret;
|
||||
RzAnalysisBlock *ret;
|
||||
} BBFromOffsetJmpmidCtx;
|
||||
|
||||
static bool bb_from_offset_jmpmid_cb(RzAnalBlock *block, void *user) {
|
||||
static bool bb_from_offset_jmpmid_cb(RzAnalysisBlock *block, void *user) {
|
||||
BBFromOffsetJmpmidCtx *ctx = user;
|
||||
// If an instruction starts exactly at the search addr, return that block immediately
|
||||
if (rz_anal_block_op_starts_at (block, ctx->addr)) {
|
||||
if (rz_analysis_block_op_starts_at (block, ctx->addr)) {
|
||||
ctx->ret = block;
|
||||
return false;
|
||||
}
|
||||
|
|
@ -24,28 +24,28 @@ static bool bb_from_offset_jmpmid_cb(RzAnalBlock *block, void *user) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool bb_from_offset_first_cb(RzAnalBlock *block, void *user) {
|
||||
RzAnalBlock **ret = user;
|
||||
static bool bb_from_offset_first_cb(RzAnalysisBlock *block, void *user) {
|
||||
RzAnalysisBlock **ret = user;
|
||||
*ret = block;
|
||||
return false;
|
||||
}
|
||||
|
||||
RZ_API RzAnalBlock *rz_anal_bb_from_offset(RzAnal *anal, ut64 off) {
|
||||
const bool x86 = anal->cur->arch && !strcmp (anal->cur->arch, "x86");
|
||||
if (anal->opt.jmpmid && x86) {
|
||||
RZ_API RzAnalysisBlock *rz_analysis_bb_from_offset(RzAnalysis *analysis, ut64 off) {
|
||||
const bool x86 = analysis->cur->arch && !strcmp (analysis->cur->arch, "x86");
|
||||
if (analysis->opt.jmpmid && x86) {
|
||||
BBFromOffsetJmpmidCtx ctx = { off, NULL };
|
||||
rz_anal_blocks_foreach_in (anal, off, bb_from_offset_jmpmid_cb, &ctx);
|
||||
rz_analysis_blocks_foreach_in (analysis, off, bb_from_offset_jmpmid_cb, &ctx);
|
||||
return ctx.ret;
|
||||
}
|
||||
|
||||
RzAnalBlock *ret = NULL;
|
||||
rz_anal_blocks_foreach_in (anal, off, bb_from_offset_first_cb, &ret);
|
||||
RzAnalysisBlock *ret = NULL;
|
||||
rz_analysis_blocks_foreach_in (analysis, off, bb_from_offset_first_cb, &ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* return the offset of the i-th instruction in the basicblock bb.
|
||||
* If the index of the instruction is not valid, it returns UT16_MAX */
|
||||
RZ_API ut16 rz_anal_bb_offset_inst(RzAnalBlock *bb, int i) {
|
||||
RZ_API ut16 rz_analysis_bb_offset_inst(RzAnalysisBlock *bb, int i) {
|
||||
if (i < 0 || i >= bb->ninstr) {
|
||||
return UT16_MAX;
|
||||
}
|
||||
|
|
@ -54,8 +54,8 @@ RZ_API ut16 rz_anal_bb_offset_inst(RzAnalBlock *bb, int i) {
|
|||
|
||||
/* return the address of the i-th instruction in the basicblock bb.
|
||||
* If the index of the instruction is not valid, it returns UT64_MAX */
|
||||
RZ_API ut64 rz_anal_bb_opaddr_i(RzAnalBlock *bb, int i) {
|
||||
ut16 offset = rz_anal_bb_offset_inst (bb, i);
|
||||
RZ_API ut64 rz_analysis_bb_opaddr_i(RzAnalysisBlock *bb, int i) {
|
||||
ut16 offset = rz_analysis_bb_offset_inst (bb, i);
|
||||
if (offset == UT16_MAX) {
|
||||
return UT64_MAX;
|
||||
}
|
||||
|
|
@ -63,7 +63,7 @@ RZ_API ut64 rz_anal_bb_opaddr_i(RzAnalBlock *bb, int i) {
|
|||
}
|
||||
|
||||
/* set the offset of the i-th instruction in the basicblock bb */
|
||||
RZ_API bool rz_anal_bb_set_offset(RzAnalBlock *bb, int i, ut16 v) {
|
||||
RZ_API bool rz_analysis_bb_set_offset(RzAnalysisBlock *bb, int i, ut16 v) {
|
||||
// the offset 0 of the instruction 0 is not stored because always 0
|
||||
if (i > 0 && v > 0) {
|
||||
if (i >= bb->op_pos_size) {
|
||||
|
|
@ -83,17 +83,17 @@ RZ_API bool rz_anal_bb_set_offset(RzAnalBlock *bb, int i, ut16 v) {
|
|||
|
||||
/* return the address of the instruction that occupy a given offset.
|
||||
* If the offset is not part of the given basicblock, UT64_MAX is returned. */
|
||||
RZ_API ut64 rz_anal_bb_opaddr_at(RzAnalBlock *bb, ut64 off) {
|
||||
RZ_API ut64 rz_analysis_bb_opaddr_at(RzAnalysisBlock *bb, ut64 off) {
|
||||
ut16 delta, delta_off, last_delta;
|
||||
int i;
|
||||
|
||||
if (!rz_anal_block_contains (bb, off)) {
|
||||
if (!rz_analysis_block_contains (bb, off)) {
|
||||
return UT64_MAX;
|
||||
}
|
||||
last_delta = 0;
|
||||
delta_off = off - bb->addr;
|
||||
for (i = 0; i < bb->ninstr; i++) {
|
||||
delta = rz_anal_bb_offset_inst (bb, i);
|
||||
delta = rz_analysis_bb_offset_inst (bb, i);
|
||||
if (delta > delta_off) {
|
||||
return bb->addr + last_delta;
|
||||
}
|
||||
|
|
@ -103,18 +103,18 @@ RZ_API ut64 rz_anal_bb_opaddr_at(RzAnalBlock *bb, ut64 off) {
|
|||
}
|
||||
|
||||
// returns the size of the i-th instruction in a basic block
|
||||
RZ_API ut64 rz_anal_bb_size_i(RzAnalBlock *bb, int i) {
|
||||
RZ_API ut64 rz_analysis_bb_size_i(RzAnalysisBlock *bb, int i) {
|
||||
if (i < 0 || i >= bb->ninstr) {
|
||||
return UT64_MAX;
|
||||
}
|
||||
ut16 idx_cur = rz_anal_bb_offset_inst (bb, i);
|
||||
ut16 idx_next = rz_anal_bb_offset_inst (bb, i + 1);
|
||||
ut16 idx_cur = rz_analysis_bb_offset_inst (bb, i);
|
||||
ut16 idx_next = rz_analysis_bb_offset_inst (bb, i + 1);
|
||||
return idx_next != UT16_MAX? idx_next - idx_cur: bb->size - idx_cur;
|
||||
}
|
||||
|
||||
/* returns the address of the basic block that contains addr or UT64_MAX if
|
||||
* there is no such basic block */
|
||||
RZ_API ut64 rz_anal_get_bbaddr(RzAnal *anal, ut64 addr) {
|
||||
RzAnalBlock *bb = rz_anal_bb_from_offset (anal, addr);
|
||||
RZ_API ut64 rz_analysis_get_bbaddr(RzAnalysis *analysis, ut64 addr) {
|
||||
RzAnalysisBlock *bb = rz_analysis_bb_from_offset (analysis, addr);
|
||||
return bb? bb->addr: UT64_MAX;
|
||||
}
|
||||
|
|
@ -1,16 +1,16 @@
|
|||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#include <rz_anal.h>
|
||||
#include <rz_anal.h>
|
||||
#include <rz_analysis.h>
|
||||
#include <rz_analysis.h>
|
||||
#include <rz_hash.h>
|
||||
#include <ht_uu.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#define unwrap(rbnode) container_of (rbnode, RzAnalBlock, _rb)
|
||||
#define unwrap(rbnode) container_of (rbnode, RzAnalysisBlock, _rb)
|
||||
|
||||
static void __max_end(RBNode *node) {
|
||||
RzAnalBlock *block = unwrap (node);
|
||||
RzAnalysisBlock *block = unwrap (node);
|
||||
block->_max_end = block->addr + block->size;
|
||||
int i;
|
||||
for (i = 0; i < 2; i++) {
|
||||
|
|
@ -25,7 +25,7 @@ static void __max_end(RBNode *node) {
|
|||
|
||||
static int __bb_addr_cmp(const void *incoming, const RBNode *in_tree, void *user) {
|
||||
ut64 incoming_addr = *(ut64 *)incoming;
|
||||
const RzAnalBlock *in_tree_block = container_of (in_tree, const RzAnalBlock, _rb);
|
||||
const RzAnalysisBlock *in_tree_block = container_of (in_tree, const RzAnalysisBlock, _rb);
|
||||
if (incoming_addr < in_tree_block->addr) {
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -35,23 +35,23 @@ static int __bb_addr_cmp(const void *incoming, const RBNode *in_tree, void *user
|
|||
return 0;
|
||||
}
|
||||
|
||||
#define D if (anal && anal->verbose)
|
||||
#define D if (analysis && analysis->verbose)
|
||||
|
||||
RZ_API void rz_anal_block_ref(RzAnalBlock *bb) {
|
||||
RZ_API void rz_analysis_block_ref(RzAnalysisBlock *bb) {
|
||||
assert (bb->ref > 0); // 0-refd must already be freed.
|
||||
bb->ref++;
|
||||
}
|
||||
|
||||
#define DFLT_NINSTR 3
|
||||
|
||||
static RzAnalBlock *block_new(RzAnal *a, ut64 addr, ut64 size) {
|
||||
RzAnalBlock *block = RZ_NEW0 (RzAnalBlock);
|
||||
static RzAnalysisBlock *block_new(RzAnalysis *a, ut64 addr, ut64 size) {
|
||||
RzAnalysisBlock *block = RZ_NEW0 (RzAnalysisBlock);
|
||||
if (!block) {
|
||||
return NULL;
|
||||
}
|
||||
block->addr = addr;
|
||||
block->size = size;
|
||||
block->anal = a;
|
||||
block->analysis = a;
|
||||
block->ref = 1;
|
||||
block->jump = UT64_MAX;
|
||||
block->fail = UT64_MAX;
|
||||
|
|
@ -62,20 +62,20 @@ static RzAnalBlock *block_new(RzAnal *a, ut64 addr, ut64 size) {
|
|||
block->cmpval = UT64_MAX;
|
||||
block->fcns = rz_list_new ();
|
||||
if (size) {
|
||||
rz_anal_block_update_hash (block);
|
||||
rz_analysis_block_update_hash (block);
|
||||
}
|
||||
return block;
|
||||
}
|
||||
|
||||
static void block_free(RzAnalBlock *block) {
|
||||
static void block_free(RzAnalysisBlock *block) {
|
||||
if (!block) {
|
||||
return;
|
||||
}
|
||||
rz_anal_cond_free (block->cond);
|
||||
rz_analysis_cond_free (block->cond);
|
||||
free (block->fingerprint);
|
||||
rz_anal_diff_free (block->diff);
|
||||
rz_analysis_diff_free (block->diff);
|
||||
free (block->op_bytes);
|
||||
rz_anal_switch_op_free (block->switch_op);
|
||||
rz_analysis_switch_op_free (block->switch_op);
|
||||
rz_list_free (block->fcns);
|
||||
free (block->op_pos);
|
||||
free (block->parent_reg_arena);
|
||||
|
|
@ -83,17 +83,17 @@ static void block_free(RzAnalBlock *block) {
|
|||
}
|
||||
|
||||
void __block_free_rb(RBNode *node, void *user) {
|
||||
RzAnalBlock *block = unwrap (node);
|
||||
RzAnalysisBlock *block = unwrap (node);
|
||||
block_free (block);
|
||||
}
|
||||
|
||||
RZ_API RzAnalBlock *rz_anal_get_block_at(RzAnal *anal, ut64 addr) {
|
||||
RBNode *node = rz_rbtree_find (anal->bb_tree, &addr, __bb_addr_cmp, NULL);
|
||||
RZ_API RzAnalysisBlock *rz_analysis_get_block_at(RzAnalysis *analysis, ut64 addr) {
|
||||
RBNode *node = rz_rbtree_find (analysis->bb_tree, &addr, __bb_addr_cmp, NULL);
|
||||
return node? unwrap (node): NULL;
|
||||
}
|
||||
|
||||
// This is a special case of what rz_interval_node_all_in() does
|
||||
static bool all_in(RzAnalBlock *node, ut64 addr, RzAnalBlockCb cb, void *user) {
|
||||
static bool all_in(RzAnalysisBlock *node, ut64 addr, RzAnalysisBlockCb cb, void *user) {
|
||||
while (node && addr < node->addr) {
|
||||
// less than the current node, but might still be contained further down
|
||||
node = unwrap (node->_rb.child[0]);
|
||||
|
|
@ -119,26 +119,26 @@ static bool all_in(RzAnalBlock *node, ut64 addr, RzAnalBlockCb cb, void *user) {
|
|||
return true;
|
||||
}
|
||||
|
||||
RZ_API bool rz_anal_blocks_foreach_in(RzAnal *anal, ut64 addr, RzAnalBlockCb cb, void *user) {
|
||||
return all_in (anal->bb_tree ? unwrap (anal->bb_tree) : NULL, addr, cb, user);
|
||||
RZ_API bool rz_analysis_blocks_foreach_in(RzAnalysis *analysis, ut64 addr, RzAnalysisBlockCb cb, void *user) {
|
||||
return all_in (analysis->bb_tree ? unwrap (analysis->bb_tree) : NULL, addr, cb, user);
|
||||
}
|
||||
|
||||
static bool block_list_cb(RzAnalBlock *block, void *user) {
|
||||
static bool block_list_cb(RzAnalysisBlock *block, void *user) {
|
||||
RzList *list = user;
|
||||
rz_anal_block_ref (block);
|
||||
rz_analysis_block_ref (block);
|
||||
rz_list_push (list, block);
|
||||
return true;
|
||||
}
|
||||
|
||||
RZ_API RzList *rz_anal_get_blocks_in(RzAnal *anal, ut64 addr) {
|
||||
RzList *list = rz_list_newf ((RzListFree)rz_anal_block_unref);
|
||||
RZ_API RzList *rz_analysis_get_blocks_in(RzAnalysis *analysis, ut64 addr) {
|
||||
RzList *list = rz_list_newf ((RzListFree)rz_analysis_block_unref);
|
||||
if (list) {
|
||||
rz_anal_blocks_foreach_in (anal, addr, block_list_cb, list);
|
||||
rz_analysis_blocks_foreach_in (analysis, addr, block_list_cb, list);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
static void all_intersect(RzAnalBlock *node, ut64 addr, ut64 size, RzAnalBlockCb cb, void *user) {
|
||||
static void all_intersect(RzAnalysisBlock *node, ut64 addr, ut64 size, RzAnalysisBlockCb cb, void *user) {
|
||||
ut64 end = addr + size;
|
||||
while (node && end <= node->addr) {
|
||||
// less than the current node, but might still be contained further down
|
||||
|
|
@ -158,46 +158,46 @@ static void all_intersect(RzAnalBlock *node, ut64 addr, ut64 size, RzAnalBlockCb
|
|||
all_intersect (unwrap (node->_rb.child[1]), addr, size, cb, user);
|
||||
}
|
||||
|
||||
RZ_API void rz_anal_blocks_foreach_intersect(RzAnal *anal, ut64 addr, ut64 size, RzAnalBlockCb cb, void *user) {
|
||||
all_intersect (anal->bb_tree ? unwrap (anal->bb_tree) : NULL, addr, size, cb, user);
|
||||
RZ_API void rz_analysis_blocks_foreach_intersect(RzAnalysis *analysis, ut64 addr, ut64 size, RzAnalysisBlockCb cb, void *user) {
|
||||
all_intersect (analysis->bb_tree ? unwrap (analysis->bb_tree) : NULL, addr, size, cb, user);
|
||||
}
|
||||
|
||||
RZ_API RzList *rz_anal_get_blocks_intersect(RzAnal *anal, ut64 addr, ut64 size) {
|
||||
RzList *list = rz_list_newf ((RzListFree)rz_anal_block_unref);
|
||||
RZ_API RzList *rz_analysis_get_blocks_intersect(RzAnalysis *analysis, ut64 addr, ut64 size) {
|
||||
RzList *list = rz_list_newf ((RzListFree)rz_analysis_block_unref);
|
||||
if (!list) {
|
||||
return NULL;
|
||||
}
|
||||
rz_anal_blocks_foreach_intersect (anal, addr, size, block_list_cb, list);
|
||||
rz_analysis_blocks_foreach_intersect (analysis, addr, size, block_list_cb, list);
|
||||
return list;
|
||||
}
|
||||
|
||||
RZ_API RzAnalBlock *rz_anal_create_block(RzAnal *anal, ut64 addr, ut64 size) {
|
||||
if (rz_anal_get_block_at (anal, addr)) {
|
||||
RZ_API RzAnalysisBlock *rz_analysis_create_block(RzAnalysis *analysis, ut64 addr, ut64 size) {
|
||||
if (rz_analysis_get_block_at (analysis, addr)) {
|
||||
return NULL;
|
||||
}
|
||||
RzAnalBlock *block = block_new (anal, addr, size);
|
||||
RzAnalysisBlock *block = block_new (analysis, addr, size);
|
||||
if (!block) {
|
||||
return NULL;
|
||||
}
|
||||
rz_rbtree_aug_insert (&anal->bb_tree, &block->addr, &block->_rb, __bb_addr_cmp, NULL, __max_end);
|
||||
rz_rbtree_aug_insert (&analysis->bb_tree, &block->addr, &block->_rb, __bb_addr_cmp, NULL, __max_end);
|
||||
return block;
|
||||
}
|
||||
|
||||
RZ_API void rz_anal_delete_block(RzAnalBlock *bb) {
|
||||
rz_anal_block_ref (bb);
|
||||
RZ_API void rz_analysis_delete_block(RzAnalysisBlock *bb) {
|
||||
rz_analysis_block_ref (bb);
|
||||
while (!rz_list_empty (bb->fcns)) {
|
||||
rz_anal_function_remove_block (rz_list_first (bb->fcns), bb);
|
||||
rz_analysis_function_remove_block (rz_list_first (bb->fcns), bb);
|
||||
}
|
||||
rz_anal_block_unref (bb);
|
||||
rz_analysis_block_unref (bb);
|
||||
}
|
||||
|
||||
RZ_API void rz_anal_block_set_size(RzAnalBlock *block, ut64 size) {
|
||||
RZ_API void rz_analysis_block_set_size(RzAnalysisBlock *block, ut64 size) {
|
||||
if (block->size == size) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the block's function's cached ranges
|
||||
RzAnalFunction *fcn;
|
||||
RzAnalysisFunction *fcn;
|
||||
RzListIter *iter;
|
||||
rz_list_foreach (block->fcns, iter, fcn) {
|
||||
if (fcn->meta._min != UT64_MAX && fcn->meta._max == block->addr + block->size) {
|
||||
|
|
@ -207,21 +207,21 @@ RZ_API void rz_anal_block_set_size(RzAnalBlock *block, ut64 size) {
|
|||
|
||||
// Do the actual resize
|
||||
block->size = size;
|
||||
rz_rbtree_aug_update_sum (block->anal->bb_tree, &block->addr, &block->_rb, __bb_addr_cmp, NULL, __max_end);
|
||||
rz_rbtree_aug_update_sum (block->analysis->bb_tree, &block->addr, &block->_rb, __bb_addr_cmp, NULL, __max_end);
|
||||
}
|
||||
|
||||
RZ_API bool rz_anal_block_relocate(RzAnalBlock *block, ut64 addr, ut64 size) {
|
||||
RZ_API bool rz_analysis_block_relocate(RzAnalysisBlock *block, ut64 addr, ut64 size) {
|
||||
if (block->addr == addr) {
|
||||
rz_anal_block_set_size (block, size);
|
||||
rz_analysis_block_set_size (block, size);
|
||||
return true;
|
||||
}
|
||||
if (rz_anal_get_block_at (block->anal, addr)) {
|
||||
if (rz_analysis_get_block_at (block->analysis, addr)) {
|
||||
// Two blocks at the same addr is illegle you know...
|
||||
return false;
|
||||
}
|
||||
|
||||
// Update the block's function's cached ranges
|
||||
RzAnalFunction *fcn;
|
||||
RzAnalysisFunction *fcn;
|
||||
RzListIter *iter;
|
||||
rz_list_foreach (block->fcns, iter, fcn) {
|
||||
if (fcn->meta._min != UT64_MAX) {
|
||||
|
|
@ -243,29 +243,29 @@ RZ_API bool rz_anal_block_relocate(RzAnalBlock *block, ut64 addr, ut64 size) {
|
|||
}
|
||||
}
|
||||
|
||||
rz_rbtree_aug_delete (&block->anal->bb_tree, &block->addr, __bb_addr_cmp, NULL, NULL, NULL, __max_end);
|
||||
rz_rbtree_aug_delete (&block->analysis->bb_tree, &block->addr, __bb_addr_cmp, NULL, NULL, NULL, __max_end);
|
||||
block->addr = addr;
|
||||
block->size = size;
|
||||
rz_anal_block_update_hash (block);
|
||||
rz_rbtree_aug_insert (&block->anal->bb_tree, &block->addr, &block->_rb, __bb_addr_cmp, NULL, __max_end);
|
||||
rz_analysis_block_update_hash (block);
|
||||
rz_rbtree_aug_insert (&block->analysis->bb_tree, &block->addr, &block->_rb, __bb_addr_cmp, NULL, __max_end);
|
||||
return true;
|
||||
}
|
||||
|
||||
RZ_API RzAnalBlock *rz_anal_block_split(RzAnalBlock *bbi, ut64 addr) {
|
||||
RzAnal *anal = bbi->anal;
|
||||
RZ_API RzAnalysisBlock *rz_analysis_block_split(RzAnalysisBlock *bbi, ut64 addr) {
|
||||
RzAnalysis *analysis = bbi->analysis;
|
||||
rz_return_val_if_fail (bbi && addr >= bbi->addr && addr < bbi->addr + bbi->size && addr != UT64_MAX, 0);
|
||||
if (addr == bbi->addr) {
|
||||
rz_anal_block_ref (bbi); // ref to be consistent with splitted return refcount
|
||||
rz_analysis_block_ref (bbi); // ref to be consistent with splitted return refcount
|
||||
return bbi;
|
||||
}
|
||||
|
||||
if (rz_anal_get_block_at (bbi->anal, addr)) {
|
||||
if (rz_analysis_get_block_at (bbi->analysis, addr)) {
|
||||
// can't have two bbs at the same addr
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// create the second block
|
||||
RzAnalBlock *bb = block_new (anal, addr, bbi->addr + bbi->size - addr);
|
||||
RzAnalysisBlock *bb = block_new (analysis, addr, bbi->addr + bbi->size - addr);
|
||||
if (!bb) {
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -274,36 +274,36 @@ RZ_API RzAnalBlock *rz_anal_block_split(RzAnalBlock *bbi, ut64 addr) {
|
|||
bb->parent_stackptr = bbi->stackptr;
|
||||
|
||||
// resize the first block
|
||||
rz_anal_block_set_size (bbi, addr - bbi->addr);
|
||||
rz_analysis_block_set_size (bbi, addr - bbi->addr);
|
||||
bbi->jump = addr;
|
||||
bbi->fail = UT64_MAX;
|
||||
rz_anal_block_update_hash (bbi);
|
||||
rz_analysis_block_update_hash (bbi);
|
||||
|
||||
// insert the second block into the tree
|
||||
rz_rbtree_aug_insert (&anal->bb_tree, &bb->addr, &bb->_rb, __bb_addr_cmp, NULL, __max_end);
|
||||
rz_rbtree_aug_insert (&analysis->bb_tree, &bb->addr, &bb->_rb, __bb_addr_cmp, NULL, __max_end);
|
||||
|
||||
// insert the second block into all functions of the first
|
||||
RzListIter *iter;
|
||||
RzAnalFunction *fcn;
|
||||
RzAnalysisFunction *fcn;
|
||||
rz_list_foreach (bbi->fcns, iter, fcn) {
|
||||
rz_anal_function_add_block (fcn, bb);
|
||||
rz_analysis_function_add_block (fcn, bb);
|
||||
}
|
||||
|
||||
// recalculate offset of instructions in both bb and bbi
|
||||
int i;
|
||||
i = 0;
|
||||
while (i < bbi->ninstr && rz_anal_bb_offset_inst (bbi, i) < bbi->size) {
|
||||
while (i < bbi->ninstr && rz_analysis_bb_offset_inst (bbi, i) < bbi->size) {
|
||||
i++;
|
||||
}
|
||||
int new_bbi_instr = i;
|
||||
if (bb->addr - bbi->addr == rz_anal_bb_offset_inst (bbi, i)) {
|
||||
if (bb->addr - bbi->addr == rz_analysis_bb_offset_inst (bbi, i)) {
|
||||
bb->ninstr = 0;
|
||||
while (i < bbi->ninstr) {
|
||||
ut16 off_op = rz_anal_bb_offset_inst (bbi, i);
|
||||
ut16 off_op = rz_analysis_bb_offset_inst (bbi, i);
|
||||
if (off_op >= bbi->size + bb->size) {
|
||||
break;
|
||||
}
|
||||
rz_anal_bb_set_offset (bb, bb->ninstr, off_op - bbi->size);
|
||||
rz_analysis_bb_set_offset (bb, bb->ninstr, off_op - bbi->size);
|
||||
bb->ninstr++;
|
||||
i++;
|
||||
}
|
||||
|
|
@ -312,8 +312,8 @@ RZ_API RzAnalBlock *rz_anal_block_split(RzAnalBlock *bbi, ut64 addr) {
|
|||
return bb;
|
||||
}
|
||||
|
||||
RZ_API bool rz_anal_block_merge(RzAnalBlock *a, RzAnalBlock *b) {
|
||||
if (!rz_anal_block_is_contiguous (a, b)) {
|
||||
RZ_API bool rz_analysis_block_merge(RzAnalysisBlock *a, RzAnalysisBlock *b) {
|
||||
if (!rz_analysis_block_is_contiguous (a, b)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -321,7 +321,7 @@ RZ_API bool rz_anal_block_merge(RzAnalBlock *a, RzAnalBlock *b) {
|
|||
if (rz_list_length (a->fcns) != rz_list_length (b->fcns)) {
|
||||
return false;
|
||||
}
|
||||
RzAnalFunction *fcn;
|
||||
RzAnalysisFunction *fcn;
|
||||
RzListIter *iter;
|
||||
rz_list_foreach (a->fcns, iter, fcn) {
|
||||
if (!rz_list_contains (b->fcns, fcn)) {
|
||||
|
|
@ -330,25 +330,25 @@ RZ_API bool rz_anal_block_merge(RzAnalBlock *a, RzAnalBlock *b) {
|
|||
}
|
||||
|
||||
// Keep a ref to b, but remove all references of b from its functions
|
||||
rz_anal_block_ref (b);
|
||||
rz_analysis_block_ref (b);
|
||||
while (!rz_list_empty (b->fcns)) {
|
||||
rz_anal_function_remove_block (rz_list_first (b->fcns), b);
|
||||
rz_analysis_function_remove_block (rz_list_first (b->fcns), b);
|
||||
}
|
||||
|
||||
// merge ops from b into a
|
||||
size_t i;
|
||||
for (i = 0; i < b->ninstr; i++) {
|
||||
rz_anal_bb_set_offset (a, a->ninstr++, a->size + rz_anal_bb_offset_inst (b, i));
|
||||
rz_analysis_bb_set_offset (a, a->ninstr++, a->size + rz_analysis_bb_offset_inst (b, i));
|
||||
}
|
||||
|
||||
// merge everything else into a
|
||||
a->size += b->size;
|
||||
a->jump = b->jump;
|
||||
a->fail = b->fail;
|
||||
rz_anal_block_update_hash (a);
|
||||
rz_analysis_block_update_hash (a);
|
||||
|
||||
// kill b completely
|
||||
rz_rbtree_aug_delete (&a->anal->bb_tree, &b->addr, __bb_addr_cmp, NULL, __block_free_rb, NULL, __max_end);
|
||||
rz_rbtree_aug_delete (&a->analysis->bb_tree, &b->addr, __bb_addr_cmp, NULL, __block_free_rb, NULL, __max_end);
|
||||
|
||||
// invalidate ranges of a's functions
|
||||
rz_list_foreach (a->fcns, iter, fcn) {
|
||||
|
|
@ -358,7 +358,7 @@ RZ_API bool rz_anal_block_merge(RzAnalBlock *a, RzAnalBlock *b) {
|
|||
return true;
|
||||
}
|
||||
|
||||
RZ_API void rz_anal_block_unref(RzAnalBlock *bb) {
|
||||
RZ_API void rz_analysis_block_unref(RzAnalysisBlock *bb) {
|
||||
if (!bb) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -366,13 +366,13 @@ RZ_API void rz_anal_block_unref(RzAnalBlock *bb) {
|
|||
bb->ref--;
|
||||
assert (bb->ref >= rz_list_length (bb->fcns)); // all of the block's functions must hold a reference to it
|
||||
if (bb->ref < 1) {
|
||||
RzAnal *anal = bb->anal;
|
||||
RzAnalysis *analysis = bb->analysis;
|
||||
assert (!bb->fcns || rz_list_empty (bb->fcns));
|
||||
rz_rbtree_aug_delete (&anal->bb_tree, &bb->addr, __bb_addr_cmp, NULL, __block_free_rb, NULL, __max_end);
|
||||
rz_rbtree_aug_delete (&analysis->bb_tree, &bb->addr, __bb_addr_cmp, NULL, __block_free_rb, NULL, __max_end);
|
||||
}
|
||||
}
|
||||
|
||||
RZ_API bool rz_anal_block_successor_addrs_foreach(RzAnalBlock *block, RzAnalAddrCb cb, void *user) {
|
||||
RZ_API bool rz_analysis_block_successor_addrs_foreach(RzAnalysisBlock *block, RzAnalysisAddrCb cb, void *user) {
|
||||
#define CB_ADDR(addr) do { \
|
||||
if (addr == UT64_MAX) { \
|
||||
break; \
|
||||
|
|
@ -386,7 +386,7 @@ RZ_API bool rz_anal_block_successor_addrs_foreach(RzAnalBlock *block, RzAnalAddr
|
|||
CB_ADDR (block->fail);
|
||||
if (block->switch_op && block->switch_op->cases) {
|
||||
RzListIter *iter;
|
||||
RzAnalCaseOp *caseop;
|
||||
RzAnalysisCaseOp *caseop;
|
||||
rz_list_foreach (block->switch_op->cases, iter, caseop) {
|
||||
CB_ADDR (caseop->jump);
|
||||
}
|
||||
|
|
@ -396,20 +396,20 @@ RZ_API bool rz_anal_block_successor_addrs_foreach(RzAnalBlock *block, RzAnalAddr
|
|||
#undef CB_ADDR
|
||||
}
|
||||
|
||||
typedef struct rz_anal_block_recurse_context_t {
|
||||
RzAnal *anal;
|
||||
RzPVector/*<RzAnalBlock>*/ to_visit;
|
||||
typedef struct rz_analysis_block_recurse_context_t {
|
||||
RzAnalysis *analysis;
|
||||
RzPVector/*<RzAnalysisBlock>*/ to_visit;
|
||||
HtUP *visited;
|
||||
} RzAnalBlockRecurseContext;
|
||||
} RzAnalysisBlockRecurseContext;
|
||||
|
||||
static bool block_recurse_successor_cb(ut64 addr, void *user) {
|
||||
RzAnalBlockRecurseContext *ctx = user;
|
||||
RzAnalysisBlockRecurseContext *ctx = user;
|
||||
if (ht_up_find_kv (ctx->visited, addr, NULL)) {
|
||||
// already visited
|
||||
return true;
|
||||
}
|
||||
ht_up_insert (ctx->visited, addr, NULL);
|
||||
RzAnalBlock *block = rz_anal_get_block_at (ctx->anal, addr);
|
||||
RzAnalysisBlock *block = rz_analysis_get_block_at (ctx->analysis, addr);
|
||||
if (!block) {
|
||||
return true;
|
||||
}
|
||||
|
|
@ -417,10 +417,10 @@ static bool block_recurse_successor_cb(ut64 addr, void *user) {
|
|||
return true;
|
||||
}
|
||||
|
||||
RZ_API bool rz_anal_block_recurse(RzAnalBlock *block, RzAnalBlockCb cb, void *user) {
|
||||
RZ_API bool rz_analysis_block_recurse(RzAnalysisBlock *block, RzAnalysisBlockCb cb, void *user) {
|
||||
bool breaked = false;
|
||||
RzAnalBlockRecurseContext ctx;
|
||||
ctx.anal = block->anal;
|
||||
RzAnalysisBlockRecurseContext ctx;
|
||||
ctx.analysis = block->analysis;
|
||||
rz_pvector_init (&ctx.to_visit, NULL);
|
||||
ctx.visited = ht_up_new0 ();
|
||||
if (!ctx.visited) {
|
||||
|
|
@ -431,12 +431,12 @@ RZ_API bool rz_anal_block_recurse(RzAnalBlock *block, RzAnalBlockCb cb, void *us
|
|||
rz_pvector_push (&ctx.to_visit, block);
|
||||
|
||||
while (!rz_pvector_empty (&ctx.to_visit)) {
|
||||
RzAnalBlock *cur = rz_pvector_pop (&ctx.to_visit);
|
||||
RzAnalysisBlock *cur = rz_pvector_pop (&ctx.to_visit);
|
||||
breaked = !cb (cur, user);
|
||||
if (breaked) {
|
||||
break;
|
||||
}
|
||||
rz_anal_block_successor_addrs_foreach (cur, block_recurse_successor_cb, &ctx);
|
||||
rz_analysis_block_successor_addrs_foreach (cur, block_recurse_successor_cb, &ctx);
|
||||
}
|
||||
|
||||
beach:
|
||||
|
|
@ -445,10 +445,10 @@ beach:
|
|||
return !breaked;
|
||||
}
|
||||
|
||||
RZ_API bool rz_anal_block_recurse_followthrough(RzAnalBlock *block, RzAnalBlockCb cb, void *user) {
|
||||
RZ_API bool rz_analysis_block_recurse_followthrough(RzAnalysisBlock *block, RzAnalysisBlockCb cb, void *user) {
|
||||
bool breaked = false;
|
||||
RzAnalBlockRecurseContext ctx;
|
||||
ctx.anal = block->anal;
|
||||
RzAnalysisBlockRecurseContext ctx;
|
||||
ctx.analysis = block->analysis;
|
||||
rz_pvector_init (&ctx.to_visit, NULL);
|
||||
ctx.visited = ht_up_new0 ();
|
||||
if (!ctx.visited) {
|
||||
|
|
@ -459,12 +459,12 @@ RZ_API bool rz_anal_block_recurse_followthrough(RzAnalBlock *block, RzAnalBlockC
|
|||
rz_pvector_push (&ctx.to_visit, block);
|
||||
|
||||
while (!rz_pvector_empty (&ctx.to_visit)) {
|
||||
RzAnalBlock *cur = rz_pvector_pop (&ctx.to_visit);
|
||||
RzAnalysisBlock *cur = rz_pvector_pop (&ctx.to_visit);
|
||||
bool b = !cb (cur, user);
|
||||
if (b) {
|
||||
breaked = true;
|
||||
} else {
|
||||
rz_anal_block_successor_addrs_foreach (cur, block_recurse_successor_cb, &ctx);
|
||||
rz_analysis_block_successor_addrs_foreach (cur, block_recurse_successor_cb, &ctx);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -475,20 +475,20 @@ beach:
|
|||
}
|
||||
|
||||
typedef struct {
|
||||
RzAnalBlock *bb;
|
||||
RzAnalysisBlock *bb;
|
||||
RzListIter *switch_it;
|
||||
} RecurseDepthFirstCtx;
|
||||
|
||||
RZ_API bool rz_anal_block_recurse_depth_first(RzAnalBlock *block, RzAnalBlockCb cb, RZ_NULLABLE RzAnalBlockCb on_exit, void *user) {
|
||||
RZ_API bool rz_analysis_block_recurse_depth_first(RzAnalysisBlock *block, RzAnalysisBlockCb cb, RZ_NULLABLE RzAnalysisBlockCb on_exit, void *user) {
|
||||
bool breaked = false;
|
||||
HtUP *visited = ht_up_new0 ();
|
||||
if (!visited) {
|
||||
goto beach;
|
||||
}
|
||||
RzAnal *anal = block->anal;
|
||||
RzAnalysis *analysis = block->analysis;
|
||||
RzVector path;
|
||||
rz_vector_init (&path, sizeof (RecurseDepthFirstCtx), NULL, NULL);
|
||||
RzAnalBlock *cur_bb = block;
|
||||
RzAnalysisBlock *cur_bb = block;
|
||||
RecurseDepthFirstCtx ctx = { cur_bb, NULL };
|
||||
rz_vector_push (&path, &ctx);
|
||||
ht_up_insert (visited, cur_bb->addr, NULL);
|
||||
|
|
@ -500,11 +500,11 @@ RZ_API bool rz_anal_block_recurse_depth_first(RzAnalBlock *block, RzAnalBlockCb
|
|||
RecurseDepthFirstCtx *cur_ctx = rz_vector_index_ptr (&path, path.len - 1);
|
||||
cur_bb = cur_ctx->bb;
|
||||
if (cur_bb->jump != UT64_MAX && !ht_up_find_kv (visited, cur_bb->jump, NULL)) {
|
||||
cur_bb = rz_anal_get_block_at (anal, cur_bb->jump);
|
||||
cur_bb = rz_analysis_get_block_at (analysis, cur_bb->jump);
|
||||
} else if (cur_bb->fail != UT64_MAX && !ht_up_find_kv (visited, cur_bb->fail, NULL)) {
|
||||
cur_bb = rz_anal_get_block_at (anal, cur_bb->fail);
|
||||
cur_bb = rz_analysis_get_block_at (analysis, cur_bb->fail);
|
||||
} else {
|
||||
RzAnalCaseOp *cop = NULL;
|
||||
RzAnalysisCaseOp *cop = NULL;
|
||||
if (cur_bb->switch_op && !cur_ctx->switch_it) {
|
||||
cur_ctx->switch_it = cur_bb->switch_op->cases->head;
|
||||
cop = rz_list_first (cur_bb->switch_op->cases);
|
||||
|
|
@ -517,7 +517,7 @@ RZ_API bool rz_anal_block_recurse_depth_first(RzAnalBlock *block, RzAnalBlockCb
|
|||
cop = NULL;
|
||||
}
|
||||
}
|
||||
cur_bb = cop ? rz_anal_get_block_at (anal, cop->jump) : NULL;
|
||||
cur_bb = cop ? rz_analysis_get_block_at (analysis, cop->jump) : NULL;
|
||||
}
|
||||
if (cur_bb) {
|
||||
RecurseDepthFirstCtx ctx = { cur_bb, NULL };
|
||||
|
|
@ -541,30 +541,30 @@ beach:
|
|||
return !breaked;
|
||||
}
|
||||
|
||||
static bool recurse_list_cb(RzAnalBlock *block, void *user) {
|
||||
static bool recurse_list_cb(RzAnalysisBlock *block, void *user) {
|
||||
RzList *list = user;
|
||||
rz_anal_block_ref (block);
|
||||
rz_analysis_block_ref (block);
|
||||
rz_list_push (list, block);
|
||||
return true;
|
||||
}
|
||||
|
||||
RZ_API RzList *rz_anal_block_recurse_list(RzAnalBlock *block) {
|
||||
RzList *ret = rz_list_newf ((RzListFree)rz_anal_block_unref);
|
||||
RZ_API RzList *rz_analysis_block_recurse_list(RzAnalysisBlock *block) {
|
||||
RzList *ret = rz_list_newf ((RzListFree)rz_analysis_block_unref);
|
||||
if (ret) {
|
||||
rz_anal_block_recurse (block, recurse_list_cb, ret);
|
||||
rz_analysis_block_recurse (block, recurse_list_cb, ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
RZ_API void rz_anal_block_add_switch_case(RzAnalBlock *block, ut64 switch_addr, ut64 case_value, ut64 case_addr) {
|
||||
RZ_API void rz_analysis_block_add_switch_case(RzAnalysisBlock *block, ut64 switch_addr, ut64 case_value, ut64 case_addr) {
|
||||
if (!block->switch_op) {
|
||||
block->switch_op = rz_anal_switch_op_new (switch_addr, 0, 0, 0);
|
||||
block->switch_op = rz_analysis_switch_op_new (switch_addr, 0, 0, 0);
|
||||
}
|
||||
rz_anal_switch_op_add_case (block->switch_op, case_addr, case_value, case_addr);
|
||||
rz_analysis_switch_op_add_case (block->switch_op, case_addr, case_value, case_addr);
|
||||
}
|
||||
|
||||
RZ_API bool rz_anal_block_op_starts_at(RzAnalBlock *bb, ut64 addr) {
|
||||
if (!rz_anal_block_contains (bb, addr)) {
|
||||
RZ_API bool rz_analysis_block_op_starts_at(RzAnalysisBlock *bb, ut64 addr) {
|
||||
if (!rz_analysis_block_contains (bb, addr)) {
|
||||
return false;
|
||||
}
|
||||
ut64 off = addr - bb->addr;
|
||||
|
|
@ -573,7 +573,7 @@ RZ_API bool rz_anal_block_op_starts_at(RzAnalBlock *bb, ut64 addr) {
|
|||
}
|
||||
size_t i;
|
||||
for (i = 0; i < bb->ninstr; i++) {
|
||||
ut16 inst_off = rz_anal_bb_offset_inst (bb, i);
|
||||
ut16 inst_off = rz_analysis_bb_offset_inst (bb, i);
|
||||
if (off == inst_off) {
|
||||
return true;
|
||||
}
|
||||
|
|
@ -582,11 +582,11 @@ RZ_API bool rz_anal_block_op_starts_at(RzAnalBlock *bb, ut64 addr) {
|
|||
}
|
||||
|
||||
typedef struct {
|
||||
RzAnal *anal;
|
||||
RzAnalBlock *cur_parent;
|
||||
RzAnalysis *analysis;
|
||||
RzAnalysisBlock *cur_parent;
|
||||
ut64 dst;
|
||||
RzPVector/*<RzAnalBlock>*/ *next_visit; // accumulate block of the next level in the tree
|
||||
HtUP/*<RzAnalBlock>*/ *visited; // maps addrs to their previous block (or NULL for entry)
|
||||
RzPVector/*<RzAnalysisBlock>*/ *next_visit; // accumulate block of the next level in the tree
|
||||
HtUP/*<RzAnalysisBlock>*/ *visited; // maps addrs to their previous block (or NULL for entry)
|
||||
} PathContext;
|
||||
|
||||
static bool shortest_path_successor_cb(ut64 addr, void *user) {
|
||||
|
|
@ -596,7 +596,7 @@ static bool shortest_path_successor_cb(ut64 addr, void *user) {
|
|||
return true;
|
||||
}
|
||||
ht_up_insert (ctx->visited, addr, ctx->cur_parent);
|
||||
RzAnalBlock *block = rz_anal_get_block_at (ctx->anal, addr);
|
||||
RzAnalysisBlock *block = rz_analysis_get_block_at (ctx->analysis, addr);
|
||||
if (block) {
|
||||
rz_pvector_push (ctx->next_visit, block);
|
||||
}
|
||||
|
|
@ -604,10 +604,10 @@ static bool shortest_path_successor_cb(ut64 addr, void *user) {
|
|||
}
|
||||
|
||||
|
||||
RZ_API RZ_NULLABLE RzList/*<RzAnalBlock *>*/ *rz_anal_block_shortest_path(RzAnalBlock *block, ut64 dst) {
|
||||
RZ_API RZ_NULLABLE RzList/*<RzAnalysisBlock *>*/ *rz_analysis_block_shortest_path(RzAnalysisBlock *block, ut64 dst) {
|
||||
RzList *ret = NULL;
|
||||
PathContext ctx;
|
||||
ctx.anal = block->anal;
|
||||
ctx.analysis = block->analysis;
|
||||
ctx.dst = dst;
|
||||
|
||||
// two vectors to swap cur_visit/next_visit
|
||||
|
|
@ -630,9 +630,9 @@ RZ_API RZ_NULLABLE RzList/*<RzAnalBlock *>*/ *rz_anal_block_shortest_path(RzAnal
|
|||
while (!rz_pvector_empty (cur_visit)) {
|
||||
void **it;
|
||||
rz_pvector_foreach (cur_visit, it) {
|
||||
RzAnalBlock *cur = *it;
|
||||
RzAnalysisBlock *cur = *it;
|
||||
ctx.cur_parent = cur;
|
||||
rz_anal_block_successor_addrs_foreach (cur, shortest_path_successor_cb, &ctx);
|
||||
rz_analysis_block_successor_addrs_foreach (cur, shortest_path_successor_cb, &ctx);
|
||||
}
|
||||
RzPVector *tmp = cur_visit;
|
||||
cur_visit = ctx.next_visit;
|
||||
|
|
@ -642,14 +642,14 @@ RZ_API RZ_NULLABLE RzList/*<RzAnalBlock *>*/ *rz_anal_block_shortest_path(RzAnal
|
|||
|
||||
// reconstruct the path
|
||||
bool found = false;
|
||||
RzAnalBlock *prev = ht_up_find (ctx.visited, dst, &found);
|
||||
RzAnalBlock *dst_block = rz_anal_get_block_at (block->anal, dst);
|
||||
RzAnalysisBlock *prev = ht_up_find (ctx.visited, dst, &found);
|
||||
RzAnalysisBlock *dst_block = rz_analysis_get_block_at (block->analysis, dst);
|
||||
if (found && dst_block) {
|
||||
ret = rz_list_newf ((RzListFree)rz_anal_block_unref);
|
||||
rz_anal_block_ref (dst_block);
|
||||
ret = rz_list_newf ((RzListFree)rz_analysis_block_unref);
|
||||
rz_analysis_block_ref (dst_block);
|
||||
rz_list_prepend (ret, dst_block);
|
||||
while (prev) {
|
||||
rz_anal_block_ref (prev);
|
||||
rz_analysis_block_ref (prev);
|
||||
rz_list_prepend (ret, prev);
|
||||
prev = ht_up_find (ctx.visited, prev->addr, NULL);
|
||||
}
|
||||
|
|
@ -662,16 +662,16 @@ beach:
|
|||
return ret;
|
||||
}
|
||||
|
||||
RZ_API bool rz_anal_block_was_modified(RzAnalBlock *block) {
|
||||
RZ_API bool rz_analysis_block_was_modified(RzAnalysisBlock *block) {
|
||||
rz_return_val_if_fail (block, false);
|
||||
if (!block->anal->iob.read_at) {
|
||||
if (!block->analysis->iob.read_at) {
|
||||
return false;
|
||||
}
|
||||
ut8 *buf = malloc (block->size);
|
||||
if (!buf) {
|
||||
return false;
|
||||
}
|
||||
if (!block->anal->iob.read_at (block->anal->iob.io, block->addr, buf, block->size)) {
|
||||
if (!block->analysis->iob.read_at (block->analysis->iob.io, block->addr, buf, block->size)) {
|
||||
free (buf);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -680,16 +680,16 @@ RZ_API bool rz_anal_block_was_modified(RzAnalBlock *block) {
|
|||
return block->bbhash != cur_hash;
|
||||
}
|
||||
|
||||
RZ_API void rz_anal_block_update_hash(RzAnalBlock *block) {
|
||||
RZ_API void rz_analysis_block_update_hash(RzAnalysisBlock *block) {
|
||||
rz_return_if_fail (block);
|
||||
if (!block->anal->iob.read_at) {
|
||||
if (!block->analysis->iob.read_at) {
|
||||
return;
|
||||
}
|
||||
ut8 *buf = malloc (block->size);
|
||||
if (!buf) {
|
||||
return;
|
||||
}
|
||||
if (!block->anal->iob.read_at (block->anal->iob.io, block->addr, buf, block->size)) {
|
||||
if (!block->analysis->iob.read_at (block->analysis->iob.io, block->addr, buf, block->size)) {
|
||||
free (buf);
|
||||
return;
|
||||
}
|
||||
|
|
@ -698,30 +698,30 @@ RZ_API void rz_anal_block_update_hash(RzAnalBlock *block) {
|
|||
}
|
||||
|
||||
typedef struct {
|
||||
RzAnalBlock *block;
|
||||
RzAnalysisBlock *block;
|
||||
bool reachable;
|
||||
} NoreturnSuccessor;
|
||||
|
||||
static void noreturn_successor_free(HtUPKv *kv) {
|
||||
NoreturnSuccessor *succ = kv->value;
|
||||
rz_anal_block_unref (succ->block);
|
||||
rz_analysis_block_unref (succ->block);
|
||||
free (succ);
|
||||
}
|
||||
|
||||
static bool noreturn_successors_cb(RzAnalBlock *block, void *user) {
|
||||
static bool noreturn_successors_cb(RzAnalysisBlock *block, void *user) {
|
||||
HtUP *succs = user;
|
||||
NoreturnSuccessor *succ = RZ_NEW0 (NoreturnSuccessor);
|
||||
if (!succ) {
|
||||
return false;
|
||||
}
|
||||
rz_anal_block_ref (block);
|
||||
rz_analysis_block_ref (block);
|
||||
succ->block = block;
|
||||
succ->reachable = false; // reset for first iteration
|
||||
ht_up_insert (succs, block->addr, succ);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool noreturn_successors_reachable_cb(RzAnalBlock *block, void *user) {
|
||||
static bool noreturn_successors_reachable_cb(RzAnalysisBlock *block, void *user) {
|
||||
HtUP *succs = user;
|
||||
NoreturnSuccessor *succ = ht_up_find (succs, block->addr, NULL);
|
||||
if (succ) {
|
||||
|
|
@ -731,10 +731,10 @@ static bool noreturn_successors_reachable_cb(RzAnalBlock *block, void *user) {
|
|||
}
|
||||
|
||||
static bool noreturn_remove_unreachable_cb(void *user, const ut64 k, const void *v) {
|
||||
RzAnalFunction *fcn = user;
|
||||
RzAnalysisFunction *fcn = user;
|
||||
NoreturnSuccessor *succ = (NoreturnSuccessor *)v;
|
||||
if (!succ->reachable && rz_list_contains (succ->block->fcns, fcn)) {
|
||||
rz_anal_function_remove_block (fcn, succ->block);
|
||||
rz_analysis_function_remove_block (fcn, succ->block);
|
||||
}
|
||||
succ->reachable = false; // reset for next iteration
|
||||
return true;
|
||||
|
|
@ -743,17 +743,17 @@ static bool noreturn_remove_unreachable_cb(void *user, const ut64 k, const void
|
|||
static bool noreturn_get_blocks_cb(void *user, const ut64 k, const void *v) {
|
||||
RzList *blocks = user;
|
||||
NoreturnSuccessor *succ = (NoreturnSuccessor *)v;
|
||||
rz_anal_block_ref (succ->block);
|
||||
rz_analysis_block_ref (succ->block);
|
||||
rz_list_push (blocks, succ->block);
|
||||
return true;
|
||||
}
|
||||
|
||||
RZ_API RzAnalBlock *rz_anal_block_chop_noreturn(RzAnalBlock *block, ut64 addr) {
|
||||
RZ_API RzAnalysisBlock *rz_analysis_block_chop_noreturn(RzAnalysisBlock *block, ut64 addr) {
|
||||
rz_return_val_if_fail (block, NULL);
|
||||
if (!rz_anal_block_contains (block, addr) || addr == block->addr) {
|
||||
if (!rz_analysis_block_contains (block, addr) || addr == block->addr) {
|
||||
return block;
|
||||
}
|
||||
rz_anal_block_ref (block);
|
||||
rz_analysis_block_ref (block);
|
||||
|
||||
// Cache all recursive successors of block here.
|
||||
// These are the candidates that we might have to remove from functions later.
|
||||
|
|
@ -761,24 +761,24 @@ RZ_API RzAnalBlock *rz_anal_block_chop_noreturn(RzAnalBlock *block, ut64 addr) {
|
|||
if (!succs) {
|
||||
return block;
|
||||
}
|
||||
rz_anal_block_recurse (block, noreturn_successors_cb, succs);
|
||||
rz_analysis_block_recurse (block, noreturn_successors_cb, succs);
|
||||
|
||||
// Chop the block. Resize and remove all destination addrs
|
||||
rz_anal_block_set_size (block, addr - block->addr);
|
||||
rz_analysis_block_set_size (block, addr - block->addr);
|
||||
block->jump = UT64_MAX;
|
||||
block->fail = UT64_MAX;
|
||||
rz_anal_switch_op_free (block->switch_op);
|
||||
rz_analysis_switch_op_free (block->switch_op);
|
||||
block->switch_op = NULL;
|
||||
|
||||
// Now, for each fcn, check which of our successors are still reachable in the function remove and the ones that are not.
|
||||
RzListIter *it;
|
||||
RzAnalFunction *fcn;
|
||||
RzAnalysisFunction *fcn;
|
||||
// We need to clone the list because block->fcns will get modified in the loop
|
||||
RzList *fcns_cpy = rz_list_clone (block->fcns);
|
||||
rz_list_foreach (fcns_cpy, it, fcn) {
|
||||
RzAnalBlock *entry = rz_anal_get_block_at (block->anal, fcn->addr);
|
||||
RzAnalysisBlock *entry = rz_analysis_get_block_at (block->analysis, fcn->addr);
|
||||
if (entry && rz_list_contains (entry->fcns, fcn)) {
|
||||
rz_anal_block_recurse (entry, noreturn_successors_reachable_cb, succs);
|
||||
rz_analysis_block_recurse (entry, noreturn_successors_reachable_cb, succs);
|
||||
}
|
||||
ht_up_foreach (succs, noreturn_remove_unreachable_cb, fcn);
|
||||
}
|
||||
|
|
@ -788,21 +788,21 @@ RZ_API RzAnalBlock *rz_anal_block_chop_noreturn(RzAnalBlock *block, ut64 addr) {
|
|||
// Prepare to merge blocks with their predecessors if possible
|
||||
RzList merge_blocks;
|
||||
rz_list_init (&merge_blocks);
|
||||
merge_blocks.free = (RzListFree)rz_anal_block_unref;
|
||||
merge_blocks.free = (RzListFree)rz_analysis_block_unref;
|
||||
ht_up_foreach (succs, noreturn_get_blocks_cb, &merge_blocks);
|
||||
|
||||
// Free/unref BEFORE doing the merge!
|
||||
// Some of the blocks might not be valid anymore later!
|
||||
rz_anal_block_unref (block);
|
||||
rz_analysis_block_unref (block);
|
||||
ht_up_free (succs);
|
||||
|
||||
ut64 block_addr = block->addr; // save the addr to identify the block. the automerge might free it so we must not use the pointer!
|
||||
|
||||
// Do the actual merge
|
||||
rz_anal_block_automerge (&merge_blocks);
|
||||
rz_analysis_block_automerge (&merge_blocks);
|
||||
|
||||
// No try to recover the pointer to the block if it still exists
|
||||
RzAnalBlock *ret = NULL;
|
||||
RzAnalysisBlock *ret = NULL;
|
||||
for (it = merge_blocks.head; it && (block = it->data, 1); it = it->n) {
|
||||
if (block->addr == block_addr) {
|
||||
// block is still there
|
||||
|
|
@ -818,9 +818,9 @@ RZ_API RzAnalBlock *rz_anal_block_chop_noreturn(RzAnalBlock *block, ut64 addr) {
|
|||
typedef struct {
|
||||
HtUP *predecessors; // maps a block to its predecessor if it has exactly one, or NULL if there are multiple or the predecessor has multiple successors
|
||||
HtUP *visited_blocks; // during predecessor search, mark blocks whose successors we already checked. Value is void *-casted count of successors
|
||||
HtUP *blocks; // adresses of the blocks we might want to merge with their predecessors => RzAnalBlock *
|
||||
HtUP *blocks; // adresses of the blocks we might want to merge with their predecessors => RzAnalysisBlock *
|
||||
|
||||
RzAnalBlock *cur_pred;
|
||||
RzAnalysisBlock *cur_pred;
|
||||
size_t cur_succ_count;
|
||||
} AutomergeCtx;
|
||||
|
||||
|
|
@ -833,13 +833,13 @@ static bool count_successors_cb(ut64 addr, void *user) {
|
|||
static bool automerge_predecessor_successor_cb(ut64 addr, void *user) {
|
||||
AutomergeCtx *ctx = user;
|
||||
ctx->cur_succ_count++;
|
||||
RzAnalBlock *block = ht_up_find (ctx->blocks, addr, NULL);
|
||||
RzAnalysisBlock *block = ht_up_find (ctx->blocks, addr, NULL);
|
||||
if (!block) {
|
||||
// we shouldn't merge this one so GL_DONT_CARE
|
||||
return true;
|
||||
}
|
||||
bool found;
|
||||
RzAnalBlock *pred = ht_up_find (ctx->predecessors, (ut64)block, &found);
|
||||
RzAnalysisBlock *pred = ht_up_find (ctx->predecessors, (ut64)block, &found);
|
||||
if (found) {
|
||||
if (pred) {
|
||||
// only one predecessor found so far, but we are the second so there are multiple now
|
||||
|
|
@ -854,9 +854,9 @@ static bool automerge_predecessor_successor_cb(ut64 addr, void *user) {
|
|||
|
||||
static bool automerge_get_predecessors_cb(void *user, const ut64 k, const void *v) {
|
||||
AutomergeCtx *ctx = user;
|
||||
const RzAnalFunction *fcn = (const RzAnalFunction *)k;
|
||||
const RzAnalysisFunction *fcn = (const RzAnalysisFunction *)k;
|
||||
RzListIter *it;
|
||||
RzAnalBlock *block;
|
||||
RzAnalysisBlock *block;
|
||||
rz_list_foreach (fcn->bbs, it, block) {
|
||||
bool already_visited;
|
||||
ht_up_find (ctx->visited_blocks, (ut64)block, &already_visited);
|
||||
|
|
@ -865,7 +865,7 @@ static bool automerge_get_predecessors_cb(void *user, const ut64 k, const void *
|
|||
}
|
||||
ctx->cur_pred = block;
|
||||
ctx->cur_succ_count = 0;
|
||||
rz_anal_block_successor_addrs_foreach (block, automerge_predecessor_successor_cb, ctx);
|
||||
rz_analysis_block_successor_addrs_foreach (block, automerge_predecessor_successor_cb, ctx);
|
||||
ht_up_insert (ctx->visited_blocks, (ut64)block, (void *)ctx->cur_succ_count);
|
||||
}
|
||||
return true;
|
||||
|
|
@ -873,7 +873,7 @@ static bool automerge_get_predecessors_cb(void *user, const ut64 k, const void *
|
|||
|
||||
// Try to find the contiguous predecessors of all given blocks and merge them if possible,
|
||||
// i.e. if there are no other blocks that have this block as one of their successors
|
||||
RZ_API void rz_anal_block_automerge(RzList *blocks) {
|
||||
RZ_API void rz_analysis_block_automerge(RzList *blocks) {
|
||||
rz_return_if_fail (blocks);
|
||||
AutomergeCtx ctx = {
|
||||
.predecessors = ht_up_new0 (),
|
||||
|
|
@ -889,10 +889,10 @@ RZ_API void rz_anal_block_automerge(RzList *blocks) {
|
|||
|
||||
// Get all the functions and prepare ctx.blocks
|
||||
RzListIter *it;
|
||||
RzAnalBlock *block;
|
||||
RzAnalysisBlock *block;
|
||||
rz_list_foreach (blocks, it, block) {
|
||||
RzListIter *fit;
|
||||
RzAnalFunction *fcn;
|
||||
RzAnalysisFunction *fcn;
|
||||
rz_list_foreach (block->fcns, fit, fcn) {
|
||||
ht_up_insert (relevant_fcns, (ut64)fcn, NULL);
|
||||
}
|
||||
|
|
@ -905,7 +905,7 @@ RZ_API void rz_anal_block_automerge(RzList *blocks) {
|
|||
// Now finally do the merging
|
||||
RzListIter *tmp;
|
||||
rz_list_foreach_safe (blocks, it, tmp, block) {
|
||||
RzAnalBlock *predecessor = ht_up_find (ctx.predecessors, (ut64)block, NULL);
|
||||
RzAnalysisBlock *predecessor = ht_up_find (ctx.predecessors, (ut64)block, NULL);
|
||||
if (!predecessor) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -919,19 +919,19 @@ RZ_API void rz_anal_block_automerge(RzList *blocks) {
|
|||
// However if there are other blocks that have block as the predecessor,
|
||||
// we would uaf after the merge since block will be freed.
|
||||
RzListIter *bit;
|
||||
RzAnalBlock *clock;
|
||||
RzAnalysisBlock *clock;
|
||||
for (bit = it->n; bit && (clock = bit->data, 1); bit = bit->n) {
|
||||
RzAnalBlock *fixup_pred = ht_up_find (ctx.predecessors, (ut64)clock, NULL);
|
||||
RzAnalysisBlock *fixup_pred = ht_up_find (ctx.predecessors, (ut64)clock, NULL);
|
||||
if (fixup_pred == block) {
|
||||
rz_list_push (fixup_candidates, clock);
|
||||
}
|
||||
}
|
||||
|
||||
if (rz_anal_block_merge (predecessor, block)) { // rz_anal_block_merge() does checks like contiguous, to that's fine
|
||||
if (rz_analysis_block_merge (predecessor, block)) { // rz_analysis_block_merge() does checks like contiguous, to that's fine
|
||||
// block was merged into predecessor, it is now freed!
|
||||
// Update number of successors of the predecessor
|
||||
ctx.cur_succ_count = 0;
|
||||
rz_anal_block_successor_addrs_foreach (predecessor, count_successors_cb, &ctx);
|
||||
rz_analysis_block_successor_addrs_foreach (predecessor, count_successors_cb, &ctx);
|
||||
ht_up_update (ctx.visited_blocks, (ut64)predecessor, (void *)ctx.cur_succ_count);
|
||||
rz_list_foreach (fixup_candidates, bit, clock) {
|
||||
// Make sure all previous pointers to block now go to predecessor
|
||||
|
|
@ -2,10 +2,10 @@
|
|||
|
||||
/* Universal calling convention implementation based on sdb */
|
||||
|
||||
#include <rz_anal.h>
|
||||
#define DB anal->sdb_cc
|
||||
#include <rz_analysis.h>
|
||||
#define DB analysis->sdb_cc
|
||||
|
||||
RZ_API void rz_anal_cc_del(RzAnal *anal, const char *name) {
|
||||
RZ_API void rz_analysis_cc_del(RzAnalysis *analysis, const char *name) {
|
||||
size_t i;
|
||||
RzStrBuf sb;
|
||||
sdb_unset (DB, rz_strbuf_initf (&sb, "%s", name), 0);
|
||||
|
|
@ -19,7 +19,7 @@ RZ_API void rz_anal_cc_del(RzAnal *anal, const char *name) {
|
|||
rz_strbuf_fini (&sb);
|
||||
}
|
||||
|
||||
RZ_API bool rz_anal_cc_set(RzAnal *anal, const char *expr) {
|
||||
RZ_API bool rz_analysis_cc_set(RzAnalysis *analysis, const char *expr) {
|
||||
char *e = strdup (expr);
|
||||
char *p = strchr (e, '(');
|
||||
if (!p) {
|
||||
|
|
@ -68,7 +68,7 @@ RZ_API bool rz_anal_cc_set(RzAnal *anal, const char *expr) {
|
|||
return true;
|
||||
}
|
||||
|
||||
RZ_API char *rz_anal_cc_get(RzAnal *anal, const char *name) {
|
||||
RZ_API char *rz_analysis_cc_get(RzAnalysis *analysis, const char *name) {
|
||||
int i;
|
||||
// get cc by name and print the expr
|
||||
if (rz_str_cmp (sdb_const_get (DB, name, 0), "cc", -1)) {
|
||||
|
|
@ -81,7 +81,7 @@ RZ_API char *rz_anal_cc_get(RzAnal *anal, const char *name) {
|
|||
return NULL;
|
||||
}
|
||||
RzStrBuf *sb = rz_strbuf_new (NULL);
|
||||
const char *self = rz_anal_cc_self (anal, name);
|
||||
const char *self = rz_analysis_cc_self (analysis, name);
|
||||
rz_strbuf_appendf (sb, "%s %s%s%s (", ret, self? self: "", self? ".": "", name);
|
||||
bool isFirst = true;
|
||||
for (i = 0; i < RZ_ANAL_CC_MAXARG; i++) {
|
||||
|
|
@ -99,7 +99,7 @@ RZ_API char *rz_anal_cc_get(RzAnal *anal, const char *name) {
|
|||
}
|
||||
rz_strbuf_append (sb, ")");
|
||||
|
||||
const char *error = rz_anal_cc_error (anal, name);
|
||||
const char *error = rz_analysis_cc_error (analysis, name);
|
||||
if (error) {
|
||||
rz_strbuf_appendf (sb, " %s", error);
|
||||
}
|
||||
|
|
@ -108,14 +108,14 @@ RZ_API char *rz_anal_cc_get(RzAnal *anal, const char *name) {
|
|||
return rz_strbuf_drain (sb);
|
||||
}
|
||||
|
||||
RZ_API bool rz_anal_cc_exist(RzAnal *anal, const char *convention) {
|
||||
rz_return_val_if_fail (anal && convention, false);
|
||||
RZ_API bool rz_analysis_cc_exist(RzAnalysis *analysis, const char *convention) {
|
||||
rz_return_val_if_fail (analysis && convention, false);
|
||||
const char *x = sdb_const_get (DB, convention, 0);
|
||||
return x && *x && !strcmp (x, "cc");
|
||||
}
|
||||
|
||||
RZ_API const char *rz_anal_cc_arg(RzAnal *anal, const char *convention, int n) {
|
||||
rz_return_val_if_fail (anal, NULL);
|
||||
RZ_API const char *rz_analysis_cc_arg(RzAnalysis *analysis, const char *convention, int n) {
|
||||
rz_return_val_if_fail (analysis, NULL);
|
||||
rz_return_val_if_fail (n >= 0, NULL);
|
||||
if (!convention) {
|
||||
return NULL;
|
||||
|
|
@ -127,44 +127,44 @@ RZ_API const char *rz_anal_cc_arg(RzAnal *anal, const char *convention, int n) {
|
|||
query = sdb_fmt ("cc.%s.argn", convention);
|
||||
ret = sdb_const_get (DB, query, 0);
|
||||
}
|
||||
return ret? rz_str_constpool_get (&anal->constpool, ret): NULL;
|
||||
return ret? rz_str_constpool_get (&analysis->constpool, ret): NULL;
|
||||
}
|
||||
|
||||
RZ_API const char *rz_anal_cc_self(RzAnal *anal, const char *convention) {
|
||||
rz_return_val_if_fail (anal && convention, NULL);
|
||||
RZ_API const char *rz_analysis_cc_self(RzAnalysis *analysis, const char *convention) {
|
||||
rz_return_val_if_fail (analysis && convention, NULL);
|
||||
const char *query = sdb_fmt ("cc.%s.self", convention);
|
||||
const char *self = sdb_const_get (DB, query, 0);
|
||||
return self? rz_str_constpool_get (&anal->constpool, self): NULL;
|
||||
return self? rz_str_constpool_get (&analysis->constpool, self): NULL;
|
||||
}
|
||||
|
||||
RZ_API void rz_anal_cc_set_self(RzAnal *anal, const char *convention, const char *self) {
|
||||
if (!rz_anal_cc_exist (anal, convention)) {
|
||||
RZ_API void rz_analysis_cc_set_self(RzAnalysis *analysis, const char *convention, const char *self) {
|
||||
if (!rz_analysis_cc_exist (analysis, convention)) {
|
||||
return;
|
||||
}
|
||||
RzStrBuf sb;
|
||||
sdb_set (anal->sdb_cc, rz_strbuf_initf (&sb, "cc.%s.self", convention), self, 0);
|
||||
sdb_set (analysis->sdb_cc, rz_strbuf_initf (&sb, "cc.%s.self", convention), self, 0);
|
||||
rz_strbuf_fini (&sb);
|
||||
}
|
||||
|
||||
RZ_API const char *rz_anal_cc_error(RzAnal *anal, const char *convention) {
|
||||
rz_return_val_if_fail (anal && convention, NULL);
|
||||
RZ_API const char *rz_analysis_cc_error(RzAnalysis *analysis, const char *convention) {
|
||||
rz_return_val_if_fail (analysis && convention, NULL);
|
||||
const char *query = sdb_fmt ("cc.%s.error", convention);
|
||||
const char *error = sdb_const_get (DB, query, 0);
|
||||
return error? rz_str_constpool_get (&anal->constpool, error): NULL;
|
||||
return error? rz_str_constpool_get (&analysis->constpool, error): NULL;
|
||||
}
|
||||
|
||||
RZ_API void rz_anal_cc_set_error(RzAnal *anal, const char *convention, const char *error) {
|
||||
if (!rz_anal_cc_exist (anal, convention)) {
|
||||
RZ_API void rz_analysis_cc_set_error(RzAnalysis *analysis, const char *convention, const char *error) {
|
||||
if (!rz_analysis_cc_exist (analysis, convention)) {
|
||||
return;
|
||||
}
|
||||
RzStrBuf sb;
|
||||
sdb_set (anal->sdb_cc, rz_strbuf_initf (&sb, "cc.%s.error", convention), error, 0);
|
||||
sdb_set (analysis->sdb_cc, rz_strbuf_initf (&sb, "cc.%s.error", convention), error, 0);
|
||||
rz_strbuf_fini (&sb);
|
||||
}
|
||||
|
||||
RZ_API int rz_anal_cc_max_arg(RzAnal *anal, const char *cc) {
|
||||
RZ_API int rz_analysis_cc_max_arg(RzAnalysis *analysis, const char *cc) {
|
||||
int i = 0;
|
||||
rz_return_val_if_fail (anal && DB && cc, 0);
|
||||
rz_return_val_if_fail (analysis && DB && cc, 0);
|
||||
static void *oldDB = NULL;
|
||||
static char *oldCC = NULL;
|
||||
static int oldArg = 0;
|
||||
|
|
@ -185,20 +185,20 @@ RZ_API int rz_anal_cc_max_arg(RzAnal *anal, const char *cc) {
|
|||
return i;
|
||||
}
|
||||
|
||||
RZ_API const char *rz_anal_cc_ret(RzAnal *anal, const char *convention) {
|
||||
rz_return_val_if_fail (anal && convention, NULL);
|
||||
RZ_API const char *rz_analysis_cc_ret(RzAnalysis *analysis, const char *convention) {
|
||||
rz_return_val_if_fail (analysis && convention, NULL);
|
||||
char *query = sdb_fmt ("cc.%s.ret", convention);
|
||||
return sdb_const_get (DB, query, 0);
|
||||
}
|
||||
|
||||
RZ_API const char *rz_anal_cc_default(RzAnal *anal) {
|
||||
rz_return_val_if_fail (anal, NULL);
|
||||
RZ_API const char *rz_analysis_cc_default(RzAnalysis *analysis) {
|
||||
rz_return_val_if_fail (analysis, NULL);
|
||||
return sdb_const_get (DB, "default.cc", 0);
|
||||
}
|
||||
|
||||
RZ_API const char *rz_anal_cc_func(RzAnal *anal, const char *func_name) {
|
||||
rz_return_val_if_fail (anal && func_name, NULL);
|
||||
RZ_API const char *rz_analysis_cc_func(RzAnalysis *analysis, const char *func_name) {
|
||||
rz_return_val_if_fail (analysis && func_name, NULL);
|
||||
const char *query = sdb_fmt ("func.%s.cc", func_name);
|
||||
const char *cc = sdb_const_get (anal->sdb_types, query, 0);
|
||||
return cc ? cc : rz_anal_cc_default (anal);
|
||||
const char *cc = sdb_const_get (analysis->sdb_types, query, 0);
|
||||
return cc ? cc : rz_analysis_cc_default (analysis);
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,8 +1,8 @@
|
|||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#include <rz_anal.h>
|
||||
#include <rz_analysis.h>
|
||||
|
||||
RZ_API const char *rz_anal_cond_tostring(int cc) {
|
||||
RZ_API const char *rz_analysis_cond_tostring(int cc) {
|
||||
switch (cc) {
|
||||
case RZ_ANAL_COND_EQ: return "eq";
|
||||
case RZ_ANAL_COND_NV: return "nv";
|
||||
|
|
@ -24,38 +24,38 @@ RZ_API const char *rz_anal_cond_tostring(int cc) {
|
|||
return "??";
|
||||
}
|
||||
|
||||
RZ_API RzAnalCond *rz_anal_cond_new(void) {
|
||||
return RZ_NEW0 (RzAnalCond);
|
||||
RZ_API RzAnalysisCond *rz_analysis_cond_new(void) {
|
||||
return RZ_NEW0 (RzAnalysisCond);
|
||||
}
|
||||
|
||||
RZ_API void rz_anal_cond_fini (RzAnalCond *c) {
|
||||
RZ_API void rz_analysis_cond_fini (RzAnalysisCond *c) {
|
||||
if (!c) {
|
||||
return;
|
||||
}
|
||||
rz_anal_value_free (c->arg[0]);
|
||||
rz_anal_value_free (c->arg[1]);
|
||||
rz_analysis_value_free (c->arg[0]);
|
||||
rz_analysis_value_free (c->arg[1]);
|
||||
c->arg[0] = c->arg[1] = NULL;
|
||||
}
|
||||
|
||||
RZ_API void rz_anal_cond_free (RzAnalCond *c) {
|
||||
RZ_API void rz_analysis_cond_free (RzAnalysisCond *c) {
|
||||
if (!c) {
|
||||
return;
|
||||
}
|
||||
rz_anal_cond_fini (c);
|
||||
rz_analysis_cond_fini (c);
|
||||
free (c);
|
||||
}
|
||||
|
||||
// XXX?
|
||||
RZ_API RzAnalCond *rz_anal_cond_clone(RzAnalCond *cond) {
|
||||
RzAnalCond *c = RZ_NEW (RzAnalCond);
|
||||
RZ_API RzAnalysisCond *rz_analysis_cond_clone(RzAnalysisCond *cond) {
|
||||
RzAnalysisCond *c = RZ_NEW (RzAnalysisCond);
|
||||
if (!c) {
|
||||
return NULL;
|
||||
}
|
||||
memcpy (c, cond, sizeof (RzAnalCond));
|
||||
memcpy (c, cond, sizeof (RzAnalysisCond));
|
||||
return c;
|
||||
}
|
||||
|
||||
static inline const char *condstring(RzAnalCond *cond) {
|
||||
static inline const char *condstring(RzAnalysisCond *cond) {
|
||||
const char *condstr_single[] = { "!", "", "0<", "0<=", "0>", "0>=" };
|
||||
const char *condstr[] = { "==", "!=", ">=", ">", "<=", "<" };
|
||||
if (cond) {
|
||||
|
|
@ -68,11 +68,11 @@ static inline const char *condstring(RzAnalCond *cond) {
|
|||
return "";
|
||||
}
|
||||
|
||||
RZ_API int rz_anal_cond_eval(RzAnal *anal, RzAnalCond *cond) {
|
||||
RZ_API int rz_analysis_cond_eval(RzAnalysis *analysis, RzAnalysisCond *cond) {
|
||||
// XXX: sign issue here?
|
||||
st64 arg0 = (st64) rz_anal_value_to_ut64 (anal, cond->arg[0]);
|
||||
st64 arg0 = (st64) rz_analysis_value_to_ut64 (analysis, cond->arg[0]);
|
||||
if (cond->arg[1]) {
|
||||
st64 arg1 = (st64) rz_anal_value_to_ut64 (anal, cond->arg[1]);
|
||||
st64 arg1 = (st64) rz_analysis_value_to_ut64 (analysis, cond->arg[1]);
|
||||
switch (cond->type) {
|
||||
case RZ_ANAL_COND_EQ: return arg0 == arg1;
|
||||
case RZ_ANAL_COND_NE: return arg0 != arg1;
|
||||
|
|
@ -95,15 +95,15 @@ RZ_API int rz_anal_cond_eval(RzAnal *anal, RzAnalCond *cond) {
|
|||
}
|
||||
|
||||
// XXX conflict naming with tostring()
|
||||
RZ_API char *rz_anal_cond_to_string(RzAnalCond *cond) {
|
||||
RZ_API char *rz_analysis_cond_to_string(RzAnalysisCond *cond) {
|
||||
char *val0, *val1, *out = NULL;
|
||||
const char *cnd;
|
||||
if (!cond) {
|
||||
return NULL;
|
||||
}
|
||||
cnd = condstring (cond);
|
||||
val0 = rz_anal_value_to_string (cond->arg[0]);
|
||||
val1 = rz_anal_value_to_string (cond->arg[1]);
|
||||
val0 = rz_analysis_value_to_string (cond->arg[0]);
|
||||
val1 = rz_analysis_value_to_string (cond->arg[1]);
|
||||
if (val0) {
|
||||
if (RZ_ANAL_COND_SINGLE (cond)) {
|
||||
int val0len = strlen (val0) + 10;
|
||||
|
|
@ -124,9 +124,9 @@ RZ_API char *rz_anal_cond_to_string(RzAnalCond *cond) {
|
|||
return out? out: strdup ("?");
|
||||
}
|
||||
|
||||
RZ_API RzAnalCond *rz_anal_cond_new_from_op(RzAnalOp *op) {
|
||||
RzAnalCond *cond;
|
||||
if (!(cond = rz_anal_cond_new ())) {
|
||||
RZ_API RzAnalysisCond *rz_analysis_cond_new_from_op(RzAnalysisOp *op) {
|
||||
RzAnalysisCond *cond;
|
||||
if (!(cond = rz_analysis_cond_new ())) {
|
||||
return NULL;
|
||||
}
|
||||
//v->reg[0] = op->src[0];
|
||||
|
|
@ -140,8 +140,8 @@ RZ_API RzAnalCond *rz_anal_cond_new_from_op(RzAnalOp *op) {
|
|||
return cond;
|
||||
}
|
||||
|
||||
RZ_API RzAnalCond *rz_anal_cond_new_from_string(const char *str) {
|
||||
RzAnalCond *cond = RZ_NEW (RzAnalCond);
|
||||
RZ_API RzAnalysisCond *rz_analysis_cond_new_from_string(const char *str) {
|
||||
RzAnalysisCond *cond = RZ_NEW (RzAnalysisCond);
|
||||
// TODO: find '<','=','>','!'...
|
||||
return cond;
|
||||
}
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#include <rz_anal.h>
|
||||
#include <rz_analysis.h>
|
||||
#include <rz_list.h>
|
||||
#include <rz_types.h>
|
||||
|
||||
RZ_API RzAnalCycleFrame *rz_anal_cycle_frame_new(void) {
|
||||
RzAnalCycleFrame *cf = RZ_NEW0 (RzAnalCycleFrame);
|
||||
RZ_API RzAnalysisCycleFrame *rz_analysis_cycle_frame_new(void) {
|
||||
RzAnalysisCycleFrame *cf = RZ_NEW0 (RzAnalysisCycleFrame);
|
||||
if (cf) {
|
||||
if (!(cf->hooks = rz_list_new ())) {
|
||||
RZ_FREE (cf);
|
||||
|
|
@ -14,7 +14,7 @@ RZ_API RzAnalCycleFrame *rz_anal_cycle_frame_new(void) {
|
|||
return cf;
|
||||
}
|
||||
|
||||
RZ_API void rz_anal_cycle_frame_free(RzAnalCycleFrame *cf) {
|
||||
RZ_API void rz_analysis_cycle_frame_free(RzAnalysisCycleFrame *cf) {
|
||||
if (!cf) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -121,7 +121,7 @@ install: ${F_SDB}
|
|||
CWD=$(shell pwd)
|
||||
symstall install-symlink: ${F_SDB}
|
||||
cd ../../.. && mkdir -p "${FCNSIGNPATH}" && \
|
||||
for FILE in $(shell cd $(TOP)/librz/anal/d ; ls *.sdb); do \
|
||||
for FILE in $(shell cd $(TOP)/librz/analysis/d ; ls *.sdb); do \
|
||||
ln -fs "$(CWD)/$$FILE" "$(FCNSIGNPATH)/$$FILE" ; \
|
||||
done
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue