Skip to content

Instantly share code, notes, and snippets.

@jas-
Last active May 13, 2020 20:29
Show Gist options
  • Save jas-/9534117 to your computer and use it in GitHub Desktop.
Save jas-/9534117 to your computer and use it in GitHub Desktop.
Memory scraping
python
sys.path.insert(0, '/path/to/module/dir')
import hexdump
end
import gdb
from curses.ascii import isgraph
def groups_of(iterable, size, first=0):
first = first if first != 0 else size
chunk, iterable = iterable[:first], iterable[first:]
while chunk:
yield chunk
chunk, iterable = iterable[:size], iterable[size:]
class HexDump(gdb.Command):
def __init__(self):
super (HexDump, self).__init__ ('hex-dump', gdb.COMMAND_DATA)
def invoke(self, arg, from_tty):
argv = gdb.string_to_argv(arg)
if len(argv) != 2:
raise gdb.GdbError('hex-dump takes exactly 2 arguments.')
addr = gdb.parse_and_eval(argv[0]).cast(
gdb.lookup_type('void').pointer())
try:
bytes = int(gdb.parse_and_eval(argv[1]))
except ValueError:
raise gdb.GdbError('Byte count numst be an integer value.')
inferior = gdb.selected_inferior()
align = gdb.parameter('hex-dump-align')
width = gdb.parameter('hex-dump-width')
if width == 0:
width = 16
mem = inferior.read_memory(addr, bytes)
pr_addr = int(str(addr), 16)
pr_offset = width
if align:
pr_offset = width - (pr_addr % width)
pr_addr -= pr_addr % width
for group in groups_of(mem, width, pr_offset):
print '0x%x: ' % (pr_addr,) + ' '*(width - pr_offset),
print ' '.join(['%02X' % (ord(g),) for g in group]) + \
' ' * (width - len(group) if pr_offset == width else 0) + ' ',
print ' '*(width - pr_offset) + ''.join(
[g if isgraph(g) or g == ' ' else '.' for g in group])
pr_addr += width
pr_offset = width
class HexDumpAlign(gdb.Parameter):
def __init__(self):
super (HexDumpAlign, self).__init__('hex-dump-align',
gdb.COMMAND_DATA,
gdb.PARAM_BOOLEAN)
set_doc = 'Determines if hex-dump always starts at an "aligned" address (see hex-dump-width'
show_doc = 'Hex dump alignment is currently'
class HexDumpWidth(gdb.Parameter):
def __init__(self):
super (HexDumpWidth, self).__init__('hex-dump-width',
gdb.COMMAND_DATA,
gdb.PARAM_INTEGER)
set_doc = 'Set the number of bytes per line of hex-dump'
show_doc = 'The number of bytes per line in hex-dump is'
HexDump()
HexDumpAlign()
HexDumpWidth()
%> gdb -x memory.py --pid `ps xaf | grep <process-name> | awk '{ print $1 }'`
import subprocess, sys, os, re, gdb
pid = sys.args[1]
fdout = "/tmp/mem.bin"
def memSnapshot():
global fdout
cmds = r"dd if=/dev/mem of="+fdout+" bs=1024"
a = subprocess.call(cmds, shell=True)
def gdbBt():
gdb.execute("bt")
def gdbInfo():
gdb.execute("maintenance info sections")
def gdbDis():
try:
gdb.execute("disassemble")
except RuntimeError as e:
print "Error: %s" % e
def gdbMem(addr):
a = str(addr)
c = "x/s "+a
try:
gdb.execute(c)
except RuntimeError as e:
print "Error: %s" % e
def gdbHex(addr, len):
a = str(addr)
l = str(len)
c = "hex-dump "+a+" "+l
try:
gdb.execute(c)
except RuntimeError as e:
print "Error: %s" % e
def gdbExamine(start, end):
s = str(start)
e = str(end)
c = "dump memory "+fdout+" "+s+" "+e
try:
gdb.execute(c)
except RuntimeError as e:
print "Error: %s" % e
while True:
if __name__ == '__main__':
gdbInfo()
memSnapshot()
maps_file = open("/proc/%s/maps" % pid, 'r')
mem_file = open("/proc/%s/mem" % pid, 'r')
for line in maps_file.readlines(): # for each mapped region
m = re.match(r'([0-9A-Fa-f]+)-([0-9A-Fa-f]+) ([-r])', line)
if m.group(3) == 'r': # if this is a readable region
start = int(m.group(1), 16)
end = int(m.group(2), 16)
print("Examining: {0} {1}".format(start, end))
gdbExamine(start, end)
gdbMem(start)
gdbHex(start, 1024)
gdbDis()
gdbBt()
maps_file.close()
mem_file.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment