Skip to content

Instantly share code, notes, and snippets.

@ktf
Created July 19, 2010 10:13
Show Gist options
  • Save ktf/481231 to your computer and use it in GitHub Desktop.
Save ktf/481231 to your computer and use it in GitHub Desktop.
Symbol information for callq and similar instructions
#!/usr/bin/env python
from optparse import OptionParser
from commands import getstatusoutput
from sys import exit
if __name__ == "__main__":
parser = OptionParser(usage="%prog <pid>")
parser.add_option("--json", "-j", dest="json", help="dump output as JSON dictionary", action="store_true", default=False)
opts, args = parser.parse_args()
if len(args) != 1:
parser.error("PID not specified.")
exit(1)
# Get the loaded libraries and the address at which they where loaded.
addrs = {}
vmbases = {}
symbols = []
callsites = []
error, output = getstatusoutput('pmap %s | grep -v -e "[[][ ].*[ ][]]" | grep -e "r.x--" | sort -u -k 4' % args[0])
if error:
parser.error("Cannot run pmap on PID %s\n%s " % (args[0], output))
exit(1)
# Get the load address for all the loaded libraries.
for line in output.splitlines():
addr, size, perm, filename = (x for x in line.split(" ") if x)
addrs[filename] = int(addr, 16)
# Get the vmbase for the executable section of each loaded library.
for filename in addrs.keys():
error, output = getstatusoutput("objdump -p %s | grep LOAD | head -1" % filename)
if error:
print "Error while parsing the VMBASE for %s" % filename
# Format:
# LOAD off 0x0000000000000000 vaddr 0x00000036d2000000 paddr 0x00000036d2000000 align 2**21
d1, d2, offset, d3, vmbase, d4, paddr, d5, d6 = (x for x in output.split(" ") if x)
vmbases[filename] = int(vmbase, 16)
# Parse the disassembly and get the symbols and the call / callq addresses.
symbols.append("<unknown>")
currentSymbolIndex = 0
for filename in addrs.keys():
error, output = getstatusoutput('objdump -D %s | grep "\(call\|>:\)"' % filename)
if error:
print "Error while disassebling."
currentOffset = addrs[filename]
currentBase = vmbases[filename]
for line in output.splitlines():
if line.startswith(" "):
address = int([x for x in line.split(":", 1) if x][0], 16)
# This is the code which calculates the actual virtual address.
vaddress = address - currentBase + currentOffset
callsites.append((vaddress, currentSymbolIndex))
if not opts.json:
print "%s, %s" % (vaddress, symbols[currentSymbolIndex])
elif line.endswith(":"):
symbol = line.rstrip(">:").split("<")[1]
symbols.append(symbol)
currentSymbolIndex += 1
if opts.json:
print "["
print symbols, ","
print dict(callsites)
print "]"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment