Python源码示例:gdb.execute()
示例1
def get_modules():
mods = []
# Get the binary currently being debugged
inferiors_output = gdb.execute("info inferiors", False, True)
mobjs = re.findall('\*?\s*(\w+)\s+(\w+ \d+)\s+([^\s]+)', inferiors_output)
for m in mobjs:
mods.append(m[2])
# Get the sharedlibrarys
sharedlibrary_output = gdb.execute("info sharedlibrary", False, True)
#mobjs = re.findall("(0x[a-zA-Z0-9]+)\s+(0x[a-zA-Z0-9]+)\s+(\w+)(\s+\(\*\))?\s+([^\s]+)", sharedlibrary_output)
mobjs = re.findall("(\/.*)", sharedlibrary_output)
for m in mobjs:
mods.append(m)
return mods
示例2
def Detach(self):
"""Detaches from the inferior. If not attached, this is a no-op."""
# We have to work around the python APIs weirdness :\
if not self.IsAttached():
return None
# Gdb doesn't drain any pending SIGINTs it may have sent to the inferior
# when it simply detaches. We can do this by letting the inferior continue,
# and gdb will intercept any SIGINT that's still to-be-delivered; as soon as
# we do so however, we may lose control of gdb (if we're running in
# synchronous mode). So we queue an interruption and continue gdb right
# afterwards, it will waitpid() for its inferior and collect all signals
# that may have been queued.
pid = gdb.selected_inferior().pid
self.Interrupt([pid, None, None])
self.Continue([pid, None, None])
result = gdb.execute('detach', to_string=True)
if not result:
return None
return result
示例3
def at(*arg):
"""Automatically attach process by filename."""
processname = arg[0] if len(arg) > 0 else pwndbg.proc.exe
try :
pidlist = map(int, subprocess.check_output('pidof $(basename {})'.format(processname), shell=True).decode('utf8').split())
for pid in pidlist:
if pid == pwndbg.proc.pid:
continue
print('attaching to {} ...'.format(processname))
gdb.execute("attach {}".format(pid))
getheapbase()
libcbase()
codeaddr()
ldbase()
return
print("already attached on {}".format(pwndbg.proc.pid))
except:
print("no such process")
示例4
def findsyscall(*arg):
""" ind the syscall gadget"""
vmmap = arg[0] if len(arg) > 0 else pwndbg.proc.exe
arch = pwndbg.arch.current
start, end = codeaddr()
if arch == "x86-64" :
gdb.execute("search -e -x 0f05 {}".format(vmmap))
elif arch == "i386":
gdb.execute("search -e -x cd80 {}".format(vmmap))
elif arch == "arm":
gdb.execute("search -e -x 00df80bc {}".format(vmmap))
elif arch == "aarch64":
gdb.execute("search -e -x 010000d4 {}".format(vmmap))
else :
print("arch not support")
示例5
def magic(self):
""" Print usefual variables or function in glibc """
getarch()
try :
print("========== function ==========")
for f in magic_function :
print("\033[34m" + f + ":" + "\033[33m" +hex(getoff(f)))
print("\033[00m========== variables ==========")
for v in magic_variable :
cmd = "x/" + word + "&" +v
content = gdb.execute(cmd,to_string=True).split(":")[1].strip()
offset = hex(getoff("&"+ v))
pad = 36 - len(v) - len(offset) - 2
print("\033[34m%s\033[33m(%s)\033[37m%s: \033[37m%s" % (v, offset, ' ' *pad, content))
except :
print("You need run the program first")
示例6
def at(self,*arg):
""" Attach by processname """
(processname,) = normalize_argv(arg,1)
if not processname :
processname = getprocname(relative=True)
if not processname :
print("Attaching program: ")
print("No executable file specified.")
print("Use the \"file\" or \"exec-file\" command.")
return
try :
print("Attaching to %s ..." % processname)
pidlist = subprocess.check_output("pidof " + processname,shell=True).decode('utf8').split()
gdb.execute("attach " + pidlist[0])
getheapbase()
libcbase()
codeaddr()
ldbase()
except :
print( "No such process" )
示例7
def bcall(self,*arg):
""" Set the breakpoint at some function call """
(sym,)= normalize_argv(arg,1)
call = searchcall(sym)
if "not found" in call :
print("symbol not found")
else :
if ispie():
codebaseaddr,codeend = codeaddr()
for callbase in call.split('\n')[:-1]:
addr = int(callbase.split(':')[0],16) + codebaseaddr
cmd = "b*" + hex(addr)
print(gdb.execute(cmd,to_string=True))
else:
for callbase in call.split('\n')[:-1]:
addr = int(callbase.split(':')[0],16)
cmd = "b*" + hex(addr)
print(gdb.execute(cmd,to_string=True))
示例8
def getoff(sym):
libc = libcbase()
if type(sym) is int :
return sym-libc
else :
try :
data = gdb.execute("x/x " + sym ,to_string=True)
if "No symbol" in data:
return 0
else :
data = re.search("0x.*[0-9a-f] ",data)
data = data.group()
symaddr = int(data[:-1] ,16)
return symaddr-libc
except :
return 0
示例9
def showfpchain():
getarch()
cmd = "x/" + word + "&_IO_list_all"
head = int(gdb.execute(cmd,to_string=True).split(":")[1].strip(),16)
print("\033[32mfpchain:\033[1;37m ",end = "")
chain = head
print("0x%x" % chain,end = "")
try :
while chain != 0 :
print(" --> ",end = "")
cmd = "x/" + word + "&((struct _IO_FILE_plus *)" + hex(chain) +").file._chain"
chain = int(gdb.execute(cmd,to_string=True).split(":")[1].strip(),16)
print("0x%x" % chain,end = "")
print("")
except :
print("Chain is corrupted")
示例10
def testfsop(addr=None):
getarch()
if addr :
cmd = "x/" + word + hex(addr)
else :
cmd = "x/" + word + "&_IO_list_all"
head = int(gdb.execute(cmd,to_string=True).split(":")[1].strip(),16)
chain = head
print("---------- fp : 0x%x ----------" % chain)
testorange(chain)
try :
while chain != 0 :
cmd = "x/" + word + "&((struct _IO_FILE_plus *)" + hex(chain) +").file._chain"
chain = int(gdb.execute(cmd,to_string=True).split(":")[1].strip(),16)
if chain != 0 :
print("---------- fp : 0x%x ----------" % chain)
testorange(chain)
except :
print("Chain is corrupted")
示例11
def procmap():
data = gdb.execute('info proc exe',to_string = True)
pid = re.search('process.*',data)
if pid :
pid = pid.group()
pid = pid.split()[1]
fpath = "/proc/" + pid + "/maps"
if os.path.isfile(fpath): # if file exist, read memory mapping directly from file
maps = open(fpath)
infomap = maps.read()
maps.close()
return infomap
else: # if file doesn't exist, use 'info proc map' to get the memory mapping
return infoprocmap()
else :
return "error"
示例12
def getoff(sym):
libc = libcbase()
if type(sym) is int :
return sym-libc
else :
try :
data = gdb.execute("x/x " + sym ,to_string=True)
if "No symbol" in data:
return 0
else :
data = re.search("0x.*[0-9a-f] ",data)
data = data.group()
symaddr = int(data[:-1] ,16)
return symaddr-libc
except :
return 0
示例13
def get_smallbin(arena=None):
global smallbin
if not arena :
arena = main_arena
smallbin = {}
if capsize == 0 :
arch = getarch()
max_smallbin_size = 512*int(capsize/4)
cmd = "x/" + word + "&((struct malloc_state *)" + hex(arena) + ").bins"
bins_addr = int(gdb.execute(cmd,to_string=True).split(":")[0].split()[0].strip(),16)
for size in range(capsize*4,max_smallbin_size,capsize*2):
chunkhead = {}
idx = int((size/(capsize*2)))-1
cmd = "x/" + word + hex(bins_addr + idx*capsize*2) # calc the smallbin index
chunkhead["addr"] = int(gdb.execute(cmd,to_string=True).split(":")[1].strip(),16)
try :
bins = trace_normal_bin(chunkhead,arena)
except:
corruptbin = True
bins = None
if bins and len(bins) > 0 :
smallbin[hex(size)] = copy.deepcopy(bins)
示例14
def get_largebin(arena=None):
global largebin
global corruptbin
if not arena :
arena = main_arena
largebin = {}
if capsize == 0 :
arch = getarch()
min_largebin = 512*int(capsize/4)
cmd = "x/" + word + "&((struct malloc_state *)" + hex(arena) + ").bins"
bins_addr = int(gdb.execute(cmd,to_string=True).split(":")[0].split()[0].strip(),16)
for idx in range(64,128):
chunkhead = {}
cmd = "x/" + word + hex(bins_addr + idx*capsize*2 - 2*capsize) # calc the largbin index
chunkhead["addr"] = int(gdb.execute(cmd,to_string=True).split(":")[1].strip(),16)
try :
bins = trace_normal_bin(chunkhead,arena)
except :
corruptbin = True
bins = None
if bins and len(bins) > 0 :
largebin[idx] = copy.deepcopy(bins)
示例15
def putarenainfo():
set_main_arena()
if capsize == 0 :
arch = getarch()
cur_arena = 0
if main_arena :
try :
if capsize == 4 :
nextoff = 0x10d*capsize + 0xc
else :
nextoff = 0x10d*capsize
count = 0
print(" Main Arena ".center(50,"="))
putheapinfo(main_arena)
cur_arena = int(gdb.execute("x/" + word + hex(main_arena+nextoff),to_string=True).split(":")[1].strip(),16)
while cur_arena != main_arena :
count +=1
print((" Arena " + str(count) + " ").center(50,"="))
putheapinfo(cur_arena)
cur_arena = int(gdb.execute("x/" + word + hex(cur_arena+nextoff),to_string=True).split(":")[1].strip(),16)
except :
print("Memory Error (heap)")
else :
print("Can't find heap info ")
示例16
def get_fake_fast(addr,size = None):
if capsize == 0 :
arch = getarch()
fast_max = int(gdb.execute("x/" + word + "&global_max_fast",to_string=True).split(":")[1].strip(),16)
if not fast_max :
fast_max = capsize*0x10
if size :
chunk_list = fake_fast(addr,size)
for fakechunk in chunk_list :
if len(chunk_list) > 0 :
print("\033[1;33mfake chunk : \033[1;0m0x{:<12x}\033[1;33m padding :\033[1;0m {:<8d}".format(fakechunk[0],fakechunk[1]))
else :
for i in range(int(fast_max/(capsize*2)-1)):
size = capsize*2*2 + i*capsize*2
chunk_list = fake_fast(addr,size)
if len(chunk_list) > 0 :
print("-- size : %s --" % hex(size))
for fakechunk in chunk_list :
print("\033[1;33mfake chunk :\033[1;0m 0x{:<12x}\033[1;33m padding :\033[1;0m {:<8d}".format(fakechunk[0],fakechunk[1]))
示例17
def end_of_level():
global source
try:
#avg_speed = gdb.execute("print (float)GetAvgRunSpeed()", to_string=True)
avg_speed = gdb.execute("printf \"%f\", (float)GetAvgRunSpeed()", to_string=True)
fail_cnt = gdb.execute("printf \"%d\", (int)CountRunsFailed()", to_string=True)
#partial = (fail_cnt, 25)
ele.enabled = True
print(">> source = {}".format(source))
print(">> avg_speed = {}".format(avg_speed))
print(">> fail_cnt = {}".format(fail_cnt))
gdb.execute("continue")
except Exception as e:
error = traceback.format_exc()
print(error)
示例18
def invoke (self, arg, from_tty):
if StepUser.finishBP and StepUser.finishBP.is_valid():
StepUser.finishBP.enabled = True
gdb.execute("continue")
else:
print('no previous stepu command found, or previous stepu was called from outermost frame')
示例19
def invoke(self, arg, from_tty):
result = gdb.execute('mo leak full', False, True)
while result.find('are definitely lost in loss record') is -1:
try:
gdb.execute('step', to_string = True) # QUIETLY step
except gdb.error:
print('error while stepping') # BOZO handle
break
result = gdb.execute('mo leak full', False, True)
print('loss report:\n%s'%result)
print('leak first noticed at:\n')
gdb.execute('bt')
示例20
def _get_pointers(block_addr):
"""For a given address, find all pointers to it from other blocks
Returns a dict of addresses (hex strings) to backtraces and internal
pointers, for each allocation
"""
wpatxt = gdb.execute('monitor who_points_at %s'%block_addr, to_string = True)
addr_re = re.compile('^ Address (0x[0-9A-Fa-f]+) is ([0-9]+) bytes inside a block.*')
trace_re = re.compile('(at|by) 0x[0-9A-Fa-f]+: ')
wpait = iter(wpatxt.splitlines())
result = {}
wpaln = next(wpait, None)
while wpaln is not None:
m = addr_re.match(wpaln)
if m:
ptr = m.group(1)
ofs = int(m.group(2))
# calculate the base of its block
base = '0x{:02X}'.format(int(ptr, 0)-ofs)
if base == block_addr:
wpaln = next(wpait, None)
continue
# suck in the backtrace associated with the allocation for this block
trace = ''
wpaln = next(wpait, None)
while wpaln is not None and trace_re.search(wpaln):
trace += wpaln + '\n'
wpaln = next(wpait, None)
result[base] = trace # TODO also store addresses
wpaln = next(wpait, None)
return result
# utility functions for the DFS
# we are doing an "implicit" graph here, i.e., we do not know all the vertices (blocks)
# in advance. Accordingly our Visitor needs a function to insert the neighbors of any
# newly arrived at vertices so the search can proceed.
# This serves that role by asking Valgrind for all blocks with pointers to us
示例21
def invoke(self, arg, from_tty):
leak_rpt = gdb.execute('monitor leak_check full any', to_string = True)
# extract the loss record number from the leak report
rx = re.compile('are (definitely|possibly) lost in loss record ([0-9]+) of')
m = rx.search(leak_rpt)
if not m:
print('no loops found')
return
# request block list for that record number
blockno = m.group(2)
bl_rpt = gdb.execute('monitor block_list %s'%blockno, to_string = True)
# get the allocation backtrace for this initial block
trace_re = re.compile('(at|by) 0x[0-9A-Fa-f]+: ')
backtrace = ''
for ln in bl_rpt.splitlines():
if trace_re.search(ln):
backtrace += ln + '\n'
# extract the first block and call "who_points_at" to get pointers
# key part is the single indentation - the first entry:
blre = re.compile('=+[0-9]+=+ (0x[0-9A-F]+)\[')
m = blre.search(bl_rpt)
g = PointerGraph(m.group(1))
g.backtraces = g.new_vertex_property('string')
g.backtraces[g.root] = backtrace
pred = g.new_vertex_property('int64_t')
vis = LoopFindVisitor(g, pred, PrintPtrLoop.expand_vertex, PrintPtrLoop.report_backedge)
dfs_search(g, g.root, vis)
示例22
def invoke(self, arg, from_tty):
frame = gdb.newest_frame()
while re.match('boost::', frame.name()):
gdb.execute('step', to_string=True)
frame = gdb.newest_frame()
示例23
def pattern_offset(arg):
ret = -1
sequence = None
full_pattern = pattern_create()
re_sequence = re.compile("[a-zA-Z0-9]{4}")
re_address = re.compile("0x[a-zA-Z0-9]{8}")
if re_sequence.match(arg):
sequence = arg
if arg in registers():
# Get the value of the register and set this to arg. Below we will parse out
#the sequence from an address format
command = "i r {:s}".format(arg)
output = gdb.execute(command, False, True)
arg = output.split()[1]
if re_address.match(arg):
# Note: [::-1] reverses the string, since data is little endian
try:
sequence = binascii.unhexlify(arg[2:].encode('utf-8')).decode("ascii")[::-1]
except:
sequence = None
if sequence != None:
match = re.search(re.escape(sequence), full_pattern)
if match:
ret = match.start()
return ret
示例24
def registers():
output = gdb.execute("i r", False, True)
lines = output.splitlines()
registers = []
for line in lines:
registers.append(line.split()[0])
return registers
示例25
def register_value(reg):
data = gdb.execute("i r {:s}".format(reg), False, True).split()[1]
return data
示例26
def register_ptr(reg):
data = None
try:
command = "x/1wx ${:s}".format(reg)
data = gdb.execute(command, False, True)
data = data.split(':')[1].strip()
except:
data = None
return data
示例27
def get_option_print_elements():
output = gdb.execute("show print elements", False, True)
num = int(output.split()[-1][:-1])
return num
示例28
def search_region(region, data):
command = "find /w {:s}, +{:s}, {:s}".format(region[0], region[2], data)
output = gdb.execute(command, False, True)
numfound = int(gdb.execute("print $numfound", False, True).split()[2])
if numfound > 0:
return output.splitlines()[:-1]
return []
# This function returns a list of tuples for each region of mapped memory
# Tuple contains: (start_addr, end_addr, size, offset, objfile)
# Thought: Should this data be stored in a class with convenience functions?
示例29
def info_mapping():
mapping = gdb.execute("info proc mapping", False, True)
map_list = []
for line in mapping.splitlines()[4:]:
map_list.append(line.split())
return map_list
示例30
def FuzzySymbolLookup(symbol_name):
try:
gdb.parse_and_eval(symbol_name)
return symbol_name
except gdb.error as err:
# No symbol in current context. We might be dealing with static symbol
# disambiguation employed by compilers. For example, on debian's current
# python build, the 'interp_head' symbol (which we need) has been renamed
# to 'interp_head.42174'. This mangling is of course compiler-specific.
# We try to get around it by using gdb's built-in regex support when
# looking up variables
# Format:
# All variables matching regular expression "<symbol_name>":
#
# File <source_file>:
# <Type><real_symbol_name>;
#
# Non-debugging symbols:
# 0x<address> <real_symbol_name>
# We're only interested in <real_symbol_name>. The latter part
# ('Non-debugging symbols') is only relevant if debugging info is partial.
listing = gdb.execute('info variables %s' % symbol_name, to_string=True)
# sigh... We want whatever was in front of ;, but barring any *s.
# If you are a compiler dev who mangles symbols using ';' and '*',
# you deserve this breakage.
mangled_name = (re.search(r'\**(\S+);$', listing, re.MULTILINE)
or re.search(r'^0x[0-9a-fA-F]+\s+(\S+)$', listing, re.MULTILINE))
if not mangled_name:
raise err
try:
gdb.parse_and_eval('\'%s\'' % mangled_name.group(1))
return '\'%s\'' % mangled_name.group(1)
except gdb.error:
# We could raise this, but the original exception will likely describe
# the problem better
raise err