Python源码示例:gdb.parse_and_eval()
示例1
def Refresh():
"""looks up symbols within the inferior and caches their names / values.
If debugging information is only partial, this method does its best to
find as much information as it can, validation can be done using
IsSymbolFileSane.
"""
try:
GdbCache.DICT = gdb.lookup_type('PyDictObject').pointer()
GdbCache.TYPE = gdb.lookup_type('PyTypeObject').pointer()
except gdb.error as err:
# The symbol file we're using doesn't seem to provide type information.
pass
interp_head_name = GdbCache.FuzzySymbolLookup('interp_head')
if interp_head_name:
GdbCache.INTERP_HEAD = gdb.parse_and_eval(interp_head_name)
else:
# As a last resort, ask the inferior about it.
GdbCache.INTERP_HEAD = gdb.parse_and_eval('PyInterpreterState_Head()')
GdbCache.PENDINGBUSY = GdbCache.FuzzySymbolLookup('pendingbusy')
GdbCache.PENDINGCALLS_TO_DO = GdbCache.FuzzySymbolLookup('pendingcalls_to_do')
示例2
def Call(self, position, function_call):
"""Perform a function call in the inferior.
WARNING: Since Gdb's concept of threads can't be directly identified with
python threads, the function call will be made from what has to be assumed
is an arbitrary thread. This *will* interrupt the inferior. Continuing it
after the call is the responsibility of the caller.
Args:
position: the context of the inferior to call the function from.
function_call: A string corresponding to a function call. Format:
'foo(0,0)'
Returns:
Thre return value of the called function.
"""
self.EnsureGdbPosition(position[0], None, None)
if not gdb.selected_thread().is_stopped():
self.Interrupt(position)
result_value = gdb.parse_and_eval(function_call)
return self._UnpackGdbVal(result_value)
示例3
def run(self, args):
if not args.asm:
try:
print(gdb.parse_and_eval(args.what))
except gxf.GdbError as e:
exit(e)
return
fakei = "test %s" % args.what
disass = gxf.disassembly.DisassemblyBlock(fakei)
expression = disass.lines[0].get_expression()
print(expression.format())
try:
print(expression.eval())
except gxf.GdbError as e:
exit(e)
示例4
def stop(self):
rcx_val_raw = gdb.parse_and_eval('$rcx').cast(self.long_int)
rcx_val = int(rcx_val_raw) & 0xffffffffffffffff
fix = 2**64
if rcx_val == self.sysenter_esp:
print("[+] Reading RAX...")
rax_val_raw = gdb.parse_and_eval('$rax').cast(self.long_int)
rax_val = int(rax_val_raw) & 0xffffffffffffffff
print("[+] Copy Chain initial ptr: %x " % rax_val)
rax_val_str = "0x%x" % rax_val
print("-----")
memory_raw = gdb.execute("x/10g %s" % rax_val_str, to_string = True)
content = memory_raw.split('\n')
for row in content:
if row:
data = row.split('\t')
print("%s\t%s\t%s" % (data[0], hex(int(data[1]) + fix), hex(int(data[2]) + fix)))
print("-----")
return True
return False
示例5
def get_reg(self, name):
if name == "efl" or name == "eflags":
value = 0
for f in self.efl_map:
if f in str(gdb.parse_and_eval("$eflags")):
value |= self.efl_map[f]
return value
else:
reg_val = gdb.parse_and_eval("$" + name)
if reg_val.type.code == gdb.TYPE_CODE_UNION: #SSE
value = 0
for i in range(8):
try:
v = int(reg_val["v8_int32"][i].cast(self.long_type)) << i * 32
except gdb.error:
break
value |= v
return value
else:
return int(reg_val.cast(self.long_type))
示例6
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
示例7
def _Inject(self, position, call):
"""Injects evaluation of 'call' in a safe location in the inferior.
Due to the way these injected function calls work, gdb must not be killed
until the call has returned. If that happens, the inferior will be sent
SIGTRAP upon attempting to return from the dummy frame gdb constructs for
us, and will most probably crash.
Args:
position: array of pid, tid, framedepth specifying the requested position.
call: Any expression gdb can evaluate. Usually a function call.
Raises:
RuntimeError: if gdb is not being run in synchronous exec mode.
"""
self.EnsureGdbPosition(position[0], position[1], None)
self.ClearBreakpoints()
self._AddThreadSpecificBreakpoint(position)
gdb.parse_and_eval('%s = 1' % GdbCache.PENDINGCALLS_TO_DO)
gdb.parse_and_eval('%s = 1' % GdbCache.PENDINGBUSY)
try:
# We're "armed", risk the blocking call to Continue
self.Continue(position)
# Breakpoint was hit!
if not gdb.selected_thread().is_stopped():
# This should not happen. Depending on how gdb is being used, the
# semantics of self.Continue change, so I'd rather leave this check in
# here, in case we ever *do* end up changing to async mode.
raise RuntimeError('Gdb is not acting as expected, is it being run in '
'async mode?')
finally:
gdb.parse_and_eval('%s = 0' % GdbCache.PENDINGBUSY)
self.Call(position, call)
示例8
def __call__(self, arg):
try:
value = gdb.parse_and_eval(arg)
except Exception as e:
raise argparse.ArgumentTypeError(e)
if value.address is not None:
value = value.address
return value
示例9
def __call__(self, arg):
try:
value = gdb.parse_and_eval(arg)
except Exception as e:
raise argparse.ArgumentTypeError(e)
if value.address is not None:
value = value.address
return value
示例10
def parse_and_eval(*args, **kwargs):
if debug:
print("[debug] pae: %s %s" % (args, kwargs))
try:
return gdb.parse_and_eval(*args, **kwargs)
except gdb.MemoryError as e:
raise gxf.MemoryError(e)
示例11
def eval(self):
return parse_and_eval(self.text)
示例12
def try_eval(self, expr):
try:
return gdb.parse_and_eval(expr)
except:
#print("Unable to parse expression: {}".format(expr))
return expr
示例13
def try_eval(self, expr):
try:
return gdb.parse_and_eval(expr)
except:
#print("Unable to parse expression: {}".format(expr))
return expr
示例14
def get_sp(self):
rsp_raw = gdb.parse_and_eval('$rsp').cast(self.long_int)
return int(rsp_raw) & 0xffffffffffffffff
示例15
def get_ip(self):
rip_val_raw = gdb.parse_and_eval('$rip').cast(self.long_int)
return int(rip_val_raw) & 0xffffffffffffffff
示例16
def _to_int(x):
try:
return int(gdb.parse_and_eval(x).cast(gdb.lookup_type("long")))
except BaseException as e:
print (e)
return None
示例17
def print_stackframe(self, frame, index, is_c=False):
if not is_c and self.is_python_function(frame):
pyframe = libpython.Frame(frame).get_pyop()
if pyframe is None or pyframe.is_optimized_out():
# print this python function as a C function
return self.print_stackframe(frame, index, is_c=True)
func_name = pyframe.co_name
func_cname = 'PyEval_EvalFrameEx'
func_args = []
elif self.is_cython_function(frame):
cyfunc = self.get_cython_function(frame)
func_name = cyfunc.name
func_cname = cyfunc.cname
func_args = []
else:
func_name = frame.name()
func_cname = func_name
func_args = []
try:
gdb_value = gdb.parse_and_eval(func_cname)
except (RuntimeError, TypeError):
func_address = 0
else:
func_address = int(str(gdb_value.address).split()[0], 0)
out = '#%-2d 0x%016x' % (index, func_address)
try:
a = ', '.join('%s=%s' % (name, val) for name, val in func_args)
out += ' in %s (%s)' % (func_name or "??", a)
source_desc, lineno = self.get_source_desc(frame)
if source_desc.filename is not None:
out += ' at %s:%s' % (source_desc.filename, lineno)
except Exception:
return
finally:
print(out)
try:
source = source_desc.get_source(lineno - 5, lineno + 5,
mark_line=lineno, lex_entire=True)
print(source)
except gdb.GdbError:
pass
示例18
def boundary(self, symbols):
'''
Usage:
a) run chuckgetcopyptr
b) set a breakpoint on POP RSP: 0xffffffff81423f82
c) once the breakpoint is triggered run this script
'''
print("[+] Chasing the dispatcher chain...")
finish = 0
x = 0
rsp_val_raw = gdb.parse_and_eval('$rsp').cast(self.long_int)
rsp_val = int(rsp_val_raw) & 0xffffffffffffffff
rsp_val_str = "0x%x" % rsp_val
last_sp = rsp_val_str
try:
while True:
# stack pointer check
x += 1
rsp_val_raw = gdb.parse_and_eval('$rsp').cast(self.long_int)
rsp_val = int(rsp_val_raw) & 0xffffffffffffffff
rsp_val_str = "0x%x" % rsp_val
print("%d) %s - %s" % (x, rsp_val_str, last_sp))
if rsp_val - int(last_sp, 16) > self.THRESHOLD:
print("[+] last_sp: %s - current_sp: %s" % (last_sp, rsp_val_str))
print("[+] %d instructions executed!" % x)
break
# we do not want to step into in a function call.
rip_val_raw = gdb.parse_and_eval('$rip').cast(self.long_int)
rip_val = int(rip_val_raw) & 0xffffffffffffffff
rip_val_str = "0x%x" % rip_val
if hex(rip_val).strip("L")[2:] in symbols.keys():
print(">>> %s:%s" % (rip_val_str, symbols[hex(rip_val).strip("L")[2:]]))
print(">>> instr %d invoking 'finish'" % x)
gdb.execute('finish')
continue
last_sp = rsp_val_str
gdb.execute('si')
except Exception as why:
print("[--- Exception ---]")
print(why)
print("[--- Exception ---]")
return