diff --git a/examples/extensions/r2/deflat_r2.py b/examples/extensions/r2/deflat_r2.py index 668cadf1e..2657d6749 100644 --- a/examples/extensions/r2/deflat_r2.py +++ b/examples/extensions/r2/deflat_r2.py @@ -18,8 +18,8 @@ # see source code at examples/src/linux/fla_test.c ql = R2Qiling(['rootfs/x86_linux/bin/test_fla_argv', '1'], 'rootfs/x86_linux', verbose=QL_VERBOSE.DEFAULT) r2 = ql.r2 - # now r2 has only rbuf but no symbol info - fcn = r2.get_fcn_at(0x08049190) + # now we can use r2 parsed symbol name instead of address + fcn = r2.get_fcn_at(r2.where('target_function')) print(fcn) r2.deflat(fcn) ql.run() diff --git a/qiling/extensions/r2/r2.py b/qiling/extensions/r2/r2.py index ee4def6dc..4f8fde813 100644 --- a/qiling/extensions/r2/r2.py +++ b/qiling/extensions/r2/r2.py @@ -218,6 +218,8 @@ def __init__(self, ql: 'R2Qiling', baseaddr=(1 << 64) - 1, loadaddr=0): self._r2c = libr.r_core.r_core_new() self._r2i = ctypes.cast(self._r2c.contents.io, ctypes.POINTER(libr.r_io.struct_r_io_t)) self._setup_mem(ql) + if ql.code is None: # ql is initialized with file + self._load_symbol_from_file(ql.path) def _qlarch2r(self, archtype: QL_ARCH) -> str: return { @@ -251,13 +253,27 @@ def _setup_mem(self, ql: 'R2Qiling'): self._cmd(f"e,asm.arch={arch},asm.bits={ql.arch.bits}") self._cmd("oba") # load bininfo and update flags - def _cmd(self, cmd: str) -> str: + def _load_symbol_from_file(self, path: str): + r2c = libr.r_core.r_core_new() + path = path.encode() + fh = libr.r_core.r_core_file_open(r2c, path, UC_PROT_READ | UC_PROT_EXEC, self.loadaddr) + libr.r_core.r_core_bin_load(r2c, path, self.baseaddr) + symbols = self._cmdj("isj", r2c) + for sym in symbols: + name = sym['name'] # name is shoter, but starting with . causes error + name = sym['flagname'] if name.startswith('.') else name + if name: # add each symbol as flag if symbol name is not empty + self._cmd(f"f {name} {sym['size']} @ {sym['vaddr']}") + libr.r_core_free(r2c) + + def _cmd(self, cmd: str, r2c = None) -> str: + r2c = r2c or self._r2c r = libr.r_core.r_core_cmd_str( - self._r2c, ctypes.create_string_buffer(cmd.encode("utf-8"))) + r2c, ctypes.create_string_buffer(cmd.encode("utf-8"))) return ctypes.string_at(r).decode('utf-8') - def _cmdj(self, cmd: str) -> Union[Dict, List[Dict]]: - return json.loads(self._cmd(cmd)) + def _cmdj(self, cmd: str, r2c = None) -> Union[Dict, List[Dict]]: + return json.loads(self._cmd(cmd, r2c)) @property def offset(self) -> int: