# 参考 https://github.com/radareorg/radare2/issues/18828
git clone https://github.com/radareorg/radare2
$ ./configure --prefix=$HOME/.local --with-rpath
$ make -j4
-Wl,-rpath,/home/ostest/.local/lib
$ make install
# libraries
/home/ostest/.local/lib/libr_anal.so.5.8.9 -> libr_anal.so.5.8 -> anal/libr_anal.so
$ r2
r2: error while loading shared libraries: libr_util.so: cannot open shared object file: No such file or directory
$ ldd ~/.local/bin/r2
linux-vdso.so.1 (0x00007fff000fc000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f204a251000)
libr_util.so => not found
libr_main.so => not found
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f204a05f000)
/lib64/ld-linux-x86-64.so.2 (0x00007f204a296000)
$ strace r2
execve("/home/ostest/.local/bin/r2", ["r2"], 0x7ffc234cb940 /* 31 vars */) = 0
brk(NULL) = 0x55b628952000
arch_prctl(0x3001 /* ARCH_??? */, 0x7ffcbb61bed0) = -1 EINVAL (无效的参数)
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (没有那个文件或目录)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=110580, ...}) = 0
mmap(NULL, 110580, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f92fb864000
close(3) = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\220q\0\0\0\0\0\0"..., 832) = 832
pread64(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0{E6\364\34\332\245\210\204\10\350-\0106\343="..., 68, 824) = 68
fstat(3, {st_mode=S_IFREG|0755, st_size=157224, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f92fb862000
pread64(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0{E6\364\34\332\245\210\204\10\350-\0106\343="..., 68, 824) = 68
mmap(NULL, 140408, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f92fb83f000
mmap(0x7f92fb845000, 69632, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x6000) = 0x7f92fb845000
mmap(0x7f92fb856000, 24576, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x17000) = 0x7f92fb856000
mmap(0x7f92fb85c000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1c000) = 0x7f92fb85c000
mmap(0x7f92fb85e000, 13432, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f92fb85e000
close(3) = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/tls/x86_64/x86_64/libr_util.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (没有那个文件或目录)
stat("/lib/x86_64-linux-gnu/tls/x86_64/x86_64", 0x7ffcbb61b100) = -1 ENOENT (没有那个文件或目录)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/tls/x86_64/libr_util.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (没有那个文件或目录)
stat("/lib/x86_64-linux-gnu/tls/x86_64", 0x7ffcbb61b100) = -1 ENOENT (没有那个文件或目录)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/tls/x86_64/libr_util.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (没有那个文件或目录)
stat("/lib/x86_64-linux-gnu/tls/x86_64", 0x7ffcbb61b100) = -1 ENOENT (没有那个文件或目录)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/tls/libr_util.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (没有那个文件或目录)
stat("/lib/x86_64-linux-gnu/tls", 0x7ffcbb61b100) = -1 ENOENT (没有那个文件或目录)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/x86_64/x86_64/libr_util.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (没有那个文件或目录)
stat("/lib/x86_64-linux-gnu/x86_64/x86_64", 0x7ffcbb61b100) = -1 ENOENT (没有那个文件或目录)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/x86_64/libr_util.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (没有那个文件或目录)
stat("/lib/x86_64-linux-gnu/x86_64", 0x7ffcbb61b100) = -1 ENOENT (没有那个文件或目录)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/x86_64/libr_util.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (没有那个文件或目录)
stat("/lib/x86_64-linux-gnu/x86_64", 0x7ffcbb61b100) = -1 ENOENT (没有那个文件或目录)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libr_util.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (没有那个文件或目录)
stat("/lib/x86_64-linux-gnu", {st_mode=S_IFDIR|0755, st_size=106496, ...}) = 0
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/tls/x86_64/x86_64/libr_util.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (没有那个文件或目录)
stat("/usr/lib/x86_64-linux-gnu/tls/x86_64/x86_64", 0x7ffcbb61b100) = -1 ENOENT (没有那个文件或目录)
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/tls/x86_64/libr_util.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (没有那个文件或目录)
stat("/usr/lib/x86_64-linux-gnu/tls/x86_64", 0x7ffcbb61b100) = -1 ENOENT (没有那个文件或目录)
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/tls/x86_64/libr_util.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (没有那个文件或目录)
stat("/usr/lib/x86_64-linux-gnu/tls/x86_64", 0x7ffcbb61b100) = -1 ENOENT (没有那个文件或目录)
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/tls/libr_util.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (没有那个文件或目录)
stat("/usr/lib/x86_64-linux-gnu/tls", 0x7ffcbb61b100) = -1 ENOENT (没有那个文件或目录)
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/x86_64/x86_64/libr_util.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (没有那个文件或目录)
stat("/usr/lib/x86_64-linux-gnu/x86_64/x86_64", 0x7ffcbb61b100) = -1 ENOENT (没有那个文件或目录)
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/x86_64/libr_util.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (没有那个文件或目录)
stat("/usr/lib/x86_64-linux-gnu/x86_64", 0x7ffcbb61b100) = -1 ENOENT (没有那个文件或目录)
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/x86_64/libr_util.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (没有那个文件或目录)
stat("/usr/lib/x86_64-linux-gnu/x86_64", 0x7ffcbb61b100) = -1 ENOENT (没有那个文件或目录)
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libr_util.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (没有那个文件或目录)
stat("/usr/lib/x86_64-linux-gnu", {st_mode=S_IFDIR|0755, st_size=106496, ...}) = 0
openat(AT_FDCWD, "/lib/tls/x86_64/x86_64/libr_util.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (没有那个文件或目录)
stat("/lib/tls/x86_64/x86_64", 0x7ffcbb61b100) = -1 ENOENT (没有那个文件或目录)
openat(AT_FDCWD, "/lib/tls/x86_64/libr_util.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (没有那个文件或目录)
stat("/lib/tls/x86_64", 0x7ffcbb61b100) = -1 ENOENT (没有那个文件或目录)
openat(AT_FDCWD, "/lib/tls/x86_64/libr_util.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (没有那个文件或目录)
stat("/lib/tls/x86_64", 0x7ffcbb61b100) = -1 ENOENT (没有那个文件或目录)
openat(AT_FDCWD, "/lib/tls/libr_util.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (没有那个文件或目录)
stat("/lib/tls", 0x7ffcbb61b100) = -1 ENOENT (没有那个文件或目录)
openat(AT_FDCWD, "/lib/x86_64/x86_64/libr_util.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (没有那个文件或目录)
stat("/lib/x86_64/x86_64", 0x7ffcbb61b100) = -1 ENOENT (没有那个文件或目录)
openat(AT_FDCWD, "/lib/x86_64/libr_util.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (没有那个文件或目录)
stat("/lib/x86_64", 0x7ffcbb61b100) = -1 ENOENT (没有那个文件或目录)
openat(AT_FDCWD, "/lib/x86_64/libr_util.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (没有那个文件或目录)
stat("/lib/x86_64", 0x7ffcbb61b100) = -1 ENOENT (没有那个文件或目录)
openat(AT_FDCWD, "/lib/libr_util.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (没有那个文件或目录)
stat("/lib", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
openat(AT_FDCWD, "/usr/lib/tls/x86_64/x86_64/libr_util.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (没有那个文件或目录)
stat("/usr/lib/tls/x86_64/x86_64", 0x7ffcbb61b100) = -1 ENOENT (没有那个文件或目录)
openat(AT_FDCWD, "/usr/lib/tls/x86_64/libr_util.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (没有那个文件或目录)
stat("/usr/lib/tls/x86_64", 0x7ffcbb61b100) = -1 ENOENT (没有那个文件或目录)
openat(AT_FDCWD, "/usr/lib/tls/x86_64/libr_util.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (没有那个文件或目录)
stat("/usr/lib/tls/x86_64", 0x7ffcbb61b100) = -1 ENOENT (没有那个文件或目录)
openat(AT_FDCWD, "/usr/lib/tls/libr_util.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (没有那个文件或目录)
stat("/usr/lib/tls", 0x7ffcbb61b100) = -1 ENOENT (没有那个文件或目录)
openat(AT_FDCWD, "/usr/lib/x86_64/x86_64/libr_util.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (没有那个文件或目录)
stat("/usr/lib/x86_64/x86_64", 0x7ffcbb61b100) = -1 ENOENT (没有那个文件或目录)
openat(AT_FDCWD, "/usr/lib/x86_64/libr_util.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (没有那个文件或目录)
stat("/usr/lib/x86_64", 0x7ffcbb61b100) = -1 ENOENT (没有那个文件或目录)
openat(AT_FDCWD, "/usr/lib/x86_64/libr_util.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (没有那个文件或目录)
stat("/usr/lib/x86_64", 0x7ffcbb61b100) = -1 ENOENT (没有那个文件或目录)
openat(AT_FDCWD, "/usr/lib/libr_util.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (没有那个文件或目录)
stat("/usr/lib", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
writev(2, [{iov_base="r2", iov_len=2}, {iov_base=": ", iov_len=2}, {iov_base="error while loading shared libra"..., iov_len=36}, {iov_base=": ", iov_len=2}, {iov_base="libr_util.so", iov_len=12}, {iov_base=": ", iov_len=2}, {iov_base="cannot open shared object file", iov_len=30}, {iov_base=": ", iov_len=2}, {iov_base="No such file or directory", iov_len=25}, {iov_base="\n", iov_len=1}], 10r2: error while loading shared libraries: libr_util.so: cannot open shared object file: No such file or directory
) = 114
exit_group(127) = ?
# 添加LDD 链接库位置
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${HOME}/.local/lib
typedef struct {
RLib *l;
RAsm *a;
RAnal *anal;
bool oneliner;
bool coutput;
bool json;
bool quiet;
} RAsmState;
typedef struct r_asm_t {
RArch *arch;
RArchConfig *config;
ut64 pc;
void *user;
RArchSession *ecur; // encode current
RArchSession *dcur; // decode current
RList *plugins;
RAnalBind analb; // Should be RArchBind instead, but first we need to move all the anal plugins.. well not really we can kill it imho
RParse *ifilter;
RParse *ofilter;
Sdb *pair;
RSyscall *syscall;
RNum *num;
int dataalign;
int codealign;
HtPP *flags;
bool pseudo; // should be implicit by RParse
RParse *parse;
} RAsm;
typedef struct r_anal_t {
RArchConfig *config;
int lineswidth; // asm.lines.width
int sleep; // anal.sleep, sleep some usecs before analyzing more (avoid 100% cpu usages)
RAnalCPPABI cxxabi; // anal.cpp.abi
void *user;
ut64 gp; // anal.gp, global pointer. used for mips. but can be used by other arches too in the future
RBTree bb_tree; // all basic blocks by address. They can overlap each other, but must never start at the same address.
RList *fcns;
HtUP *ht_addr_fun; // address => function
HtPP *ht_name_fun; // name => function
RReg *reg;
ut8 *last_disasm_reg;
int last_disasm_reg_size;
RSyscall *syscall;
int diff_ops;
double diff_thbb;
double diff_thfcn;
RIOBind iob;
RFlagBind flb;
RFlagSet flg_class_set;
RFlagGet flg_class_get;
RFlagSet flg_fcn_set;
RBinBind binb; // Set only from core when an analysis plugin is called.
RCoreBind coreb;
int maxreflines; // asm.lines.maxref
int esil_goto_limit; // esil.gotolimit
struct r_esil_t *esil; // R2_590 remove
struct r_anal_plugin_t *cur;
struct r_esil_plugin_t *esil_cur; // ???
RArch *arch;
RAnalRange *limit; // anal.from, anal.to
RList *plugins; // anal plugins
Sdb *sdb_types;
Sdb *sdb_fmts;
Sdb *sdb_zigns;
RefManager *rm;
RSpaces zign_spaces;
char *zign_path; // dir.zigns
PrintfCallback cb_printf;
RPrint *print;
//moved from RAnalFcn
Sdb *sdb; // root
Sdb *sdb_pins;
HtUP/*>*/ *addr_hints; // all hints that correspond to a single address
RBTree/**/ arch_hints;
RBTree/**/ bits_hints;
RHintCb hint_cbs;
RIntervalTree meta;
RSpaces meta_spaces;
Sdb *sdb_cc; // calling conventions
Sdb *sdb_classes;
Sdb *sdb_classes_attrs;
RAnalCallbacks cb;
RAnalOptions opt;
RList *reflines;
RListComparator columnSort;
int stackptr;
bool (*log)(struct r_anal_t *anal, const char *msg);
bool (*read_at)(struct r_anal_t *anal, ut64 addr, ut8 *buf, int len);
bool verbose;
RFlagGetAtAddr flag_get;
REvent *ev;
RList/**/ *imports; // global imports
SetU *visited;
RStrConstPool constpool;
RList *leaddrs;
char *pincmd;
/* private */
RThreadLock *lock;
ut64 cmpval;
ut64 lea_jmptbl_ip;
int cs_obits;
int cs_omode;
size_t cs_handle;
bool uses; // false = nothing, true = arch plugin
int thread; // see apt command
RList *threads;
RColor tracetagcolors[64]; // each trace color for each bit
/* end private */
R_DIRTY_VAR;
} RAnal;
typedef struct r_lib_t {
/* linked list with all the plugin handler */
/* only one handler per handler-id allowed */
/* this is checked in add_handler function */
char *symname;
char *symnamefunc;
RList /*RLibPlugin*/ *plugins;
RList /*RLibHandler*/ *handlers;
RLibHandler *handlers_bytype[R_LIB_TYPE_LAST];
bool ignore_version;
// hashtable plugname = &plugin
HtPP *plugins_ht;
} RLib;
gdb --args rasm2 -a arm -b 64 -d -A FD7BB9A9
b main
(gdb) s
r_main_rasm2 (argc=32767, argv=0x7fffffffdd50) at rasm2.c:712
712 R_API int r_main_rasm2(int argc, const char *argv[]) {
(gdb) n
908 bool canbebig = r_asm_set_big_endian (as->a, isbig);
(gdb) p *as->a->syscall
$10 = {fd = 0x0, arch = 0x555555583650 "arm", os = 0x55555559ef60 "linux", bits = 64, cpu = 0x555555583590 "arm", sysptr = 0x0,
sysport = 0x7ffff6149160 <sysport_x86>, db = 0x5555555d40e0, srdb = 0x5555555d13a0, refs = 0}
1013 } else if (opt.argv[opt.ind]) {
(gdb) p opt.argv[opt.ind]
$11 = 0x7fffffffe62f "FD7BB9A9"
(gdb) n
1075 ret = rasm_disasm (as, offset, (char *)usrstr, len,
// https://github.com/radareorg/radare2/blob/master/libr/main/rasm2.c#L441
rasm_disasm (as=0x5555555592a0, addr=0, buf=0x5555555a0ec0 "FD7BB9A9", len=8, bits=64, bin=0, hex=0) at rasm2.c:443
(gdb) n
450 int blen = is_binary (buf); // 0
// 进行反汇编
#0 r_asm_mdisassemble (a=0x5555555594e0, buf=0x5555555a0ea0 "\375{\271\251UU", len=4) at asm.c:561
(gdb) p /x *buf@4
$18 = {0xfd, 0x7b, 0xb9, 0xa9}
#0 r_asm_disassemble (a=0x5555555594e0, op=0x7fffffffd790, buf=0x5555555a0ea0 "\375{\271\251UU", len=4) at asm.c:373
394 ret = a->analb.decode (a->analb.anal, op, a->pc, buf, len, R_ARCH_OP_MASK_ESIL | R_ARCH_OP_MASK_DISASM);
#0 r_anal_op (anal=0x5555555599b0, op=0x7fffffffd790, addr=0, data=0x5555555a0ea0 "\375{\271\251UU", len=4, mask=17) at op.c:142
#0 decode (as=0x55555559ef10, op=0x7fffffffd790, mask=17) at p/arm/plugin_cs.c:4632
#1 0x00007ffff69098a2 in r_arch_decode (a=0x55555555a390, op=0x7fffffffd790, mask=17) at arch.c:287
(gdb) n
r_anal_op (anal=0x5555555599b0, op=0x7fffffffd790, addr=0, data=0x5555555a0ea0 "\375{\271\251UU", len=4, mask=17) at op.c:174
174 if (!r_arch_decode (anal->arch, op, mask) || op->size <= 0) {
(gdb) n
182 ret = op->size;
(gdb) n
195 op->addr = addr;
(gdb) n
197 if (op->nopcode < 1) {
(gdb) n
198 op->nopcode = 1;
(gdb) n
197 if (op->nopcode < 1) {
(gdb) n
224 if (!op->mnemonic && (mask & R_ARCH_OP_MASK_DISASM)) {
(gdb) n
229 if (mask & R_ARCH_OP_MASK_HINT) {
(gdb) n
236 if (ret == -1) {
(gdb) n
246 return ret;
执行结束
#0 r_asm_disassemble (a=0x5555555594e0, op=0x7fffffffd790, buf=0x5555555a0ea0 "\375{\271\251UU", len=4) at asm.c:433
(gdb) p *op
$32 = {mnemonic = 0x5555555a0fb0 "stp x29, x30, [sp, -0x70]!", addr = 0, t
// https://github.com/radareorg/radare2/blob/c28f2ba029492b46b7f567570402e61e6405d8cd/libr/arch/p/arm/plugin_cs.c#L4542
// 默认使用 capstone 解析
#0 AArch64_getInstruction (ud=93824992426848, code=0x5555555817d0 "\375{\271\251UU", code_len=4, instr=0x7fffffffd190, size=0x7fffffffcf16,
address=0, info=0x5555555982f0) at arch/AArch64/AArch64Disassembler.c:362
#1 0x00007ffff6c57689 in cs_disasm (ud=93824992426848, buffer=0x5555555817d0 "\375{\271\251UU", size=4, offset=0, count=1, insn=0x7fffffffd5a8)
at cs.c:933
op->mnemonic = r_str_newf ("%s%s%s",
insn->mnemonic,
insn->op_str[0]? " ": "",
insn->op_str);
(gdb) p *insn
$38 = {id = 1035, address = 0, size = 4, bytes = "\375{\271\251", '\000' <repeats 19 times>, mnemonic = "stp", '\000' <repeats 28 times>,
op_str = "x29, x30, [sp, #-0x70]!", '\000' <repeats 136 times>, detail = 0x5555555ae900}
// https://github.com/capstone-engine/capstone/blob/next/cs.c#L862
b cs.c:933
r = handle->disasm(ud, buffer, size, &mci, &insn_size, offset, handle->getinsn_info);
#0 AArch64_getInstruction (ud=93824992426848, code=0x5555555817d0 "\375{\271\251UU", code_len=4, instr=0x7fffffffd190, size=0x7fffffffcf16,
address=0, info=0x5555555982f0) at arch/AArch64/AArch64Disassembler.c:362
if (r) {
SStream ss;
SStream_Init(&ss);
mci.flat_insn->size = insn_size;
// map internal instruction opcode to public insn ID
handle->insn_id(handle, insn_cache, mci.Opcode);
handle->printer(&mci, &ss, handle->printer_info);
fill_insn(handle, insn_cache, ss.buffer, &mci, handle->post_printer, buffer);
// adjust for pseudo opcode (X86)
if (handle->arch == CS_ARCH_X86)
insn_cache->id += mci.popcode_adjust;
next_offset = insn_size;
}
Small and Lightweight ARM64/AArch64 Disassembly Framework.
rm -rf build && mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE
make -j
./tools/libarch-debug FD7BB9A9