Skip to content

Commit 33892d8

Browse files
committed
feat(r2): load symbols from file if possible
refactor r2._cmd() to allow optional r_core passed
1 parent aae2bb8 commit 33892d8

File tree

2 files changed

+22
-6
lines changed

2 files changed

+22
-6
lines changed

examples/extensions/r2/deflat_r2.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
# see source code at examples/src/linux/fla_test.c
1919
ql = R2Qiling(['rootfs/x86_linux/bin/test_fla_argv', '1'], 'rootfs/x86_linux', verbose=QL_VERBOSE.DEFAULT)
2020
r2 = ql.r2
21-
# now r2 has only rbuf but no symbol info
22-
fcn = r2.get_fcn_at(0x08049190)
21+
# now we can use r2 parsed symbol name instead of address
22+
fcn = r2.get_fcn_at(r2.where('target_function'))
2323
print(fcn)
2424
r2.deflat(fcn)
2525
ql.run()

qiling/extensions/r2/r2.py

+20-4
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,8 @@ def __init__(self, ql: 'R2Qiling', baseaddr=(1 << 64) - 1, loadaddr=0):
218218
self._r2c = libr.r_core.r_core_new()
219219
self._r2i = ctypes.cast(self._r2c.contents.io, ctypes.POINTER(libr.r_io.struct_r_io_t))
220220
self._setup_mem(ql)
221+
if ql.code is None: # ql is initialized with file
222+
self._load_symbol_from_file(ql.path)
221223

222224
def _qlarch2r(self, archtype: QL_ARCH) -> str:
223225
return {
@@ -251,13 +253,27 @@ def _setup_mem(self, ql: 'R2Qiling'):
251253
self._cmd(f"e,asm.arch={arch},asm.bits={ql.arch.bits}")
252254
self._cmd("oba") # load bininfo and update flags
253255

254-
def _cmd(self, cmd: str) -> str:
256+
def _load_symbol_from_file(self, path: str):
257+
r2c = libr.r_core.r_core_new()
258+
path = path.encode()
259+
fh = libr.r_core.r_core_file_open(r2c, path, UC_PROT_READ | UC_PROT_EXEC, self.loadaddr)
260+
libr.r_core.r_core_bin_load(r2c, path, self.baseaddr)
261+
symbols = self._cmdj("isj", r2c)
262+
for sym in symbols:
263+
name = sym['name'] # name is shoter, but starting with . causes error
264+
name = sym['flagname'] if name.startswith('.') else name
265+
if name: # add each symbol as flag if symbol name is not empty
266+
self._cmd(f"f {name} {sym['size']} @ {sym['vaddr']}")
267+
libr.r_core_free(r2c)
268+
269+
def _cmd(self, cmd: str, r2c = None) -> str:
270+
r2c = r2c or self._r2c
255271
r = libr.r_core.r_core_cmd_str(
256-
self._r2c, ctypes.create_string_buffer(cmd.encode("utf-8")))
272+
r2c, ctypes.create_string_buffer(cmd.encode("utf-8")))
257273
return ctypes.string_at(r).decode('utf-8')
258274

259-
def _cmdj(self, cmd: str) -> Union[Dict, List[Dict]]:
260-
return json.loads(self._cmd(cmd))
275+
def _cmdj(self, cmd: str, r2c = None) -> Union[Dict, List[Dict]]:
276+
return json.loads(self._cmd(cmd, r2c))
261277

262278
@property
263279
def offset(self) -> int:

0 commit comments

Comments
 (0)