I want to script with python using r2pipe. Is there a way that when debugging I can break on each call function, thus I can get the parameter? What's more, I won't jump into system library. Or is there a way to do function trace, just in program's address space, not in system library?
1 Answer
Yes, you can do that. The python script doing that is attached below with appropriate comments.
#!/usr/bin/env python3
import r2pipe
r = r2pipe.open('programName', flags=['-d'])
r.cmd('aei')
modules = r.cmd('dmm') #list all modules along with start and end addresses
modules2 = [] #modules' start addresses
moduleNames = []
#since modules is just one big string, we need to extract relevant information from it
i = 0
j = 0
while i < len(modules):
modules2.append('')
while modules[i] != ' ':
modules2[j] += modules[i]
i += 1
while modules[i] == ' ':
i += 1
while modules[i] != ' ':
i += 1
while modules[i] == ' ':
i += 1
moduleNames.append('')
while modules[i] != '\n':
moduleNames[j] += modules[i]
i += 1
i += 1
j += 1
moduleNames = [x.split('/')[len(x.split('/')) - 1] for x in moduleNames]
systemModules = {} #put here all libraries you don't want breakpoints in
systemModules['ld-2.27.so'] = 1
for i in range(len(moduleNames)):
if moduleNames[i] not in systemModules:
r.cmd('s ' + modules2[i]) #go to start of module i
calls = r.cmd('/am call') #find all call instructions in this module; you can use other commands of type /a for more flexibility
calls2 = [] #all addresses in module i where we want to put breakpoints
k = 0
j = 0
while k < len(calls):
calls2.append('')
while calls[k] != ' ':
calls2[j] += calls[k]
k += 1
while calls[k] != '\n':
k += 1
k += 1
j += 1
for k in range(len(calls2)):
r.cmd('db ' + calls2[k]) #put breakpoint at given address
#all breakpoints set; you can now continue execution and do what you want to do at each breakpoint
print(r.cmd('db')) #list all breakpoints set
Not very elegant script, but gets the job done. It searches for all call
instructions in relevant modules and puts breakpoint at each one.
For more flexibility, instead of doing /am
, you can use other search commands available in radare2 (/a?
for more information).