Last active
May 13, 2020 20:29
-
-
Save jas-/9534117 to your computer and use it in GitHub Desktop.
Memory scraping
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
python | |
sys.path.insert(0, '/path/to/module/dir') | |
import hexdump | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%> gdb -x memory.py --pid `ps xaf | grep <process-name> | awk '{ print $1 }'` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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