remove grr snapshot support (#400)
This commit is contained in:
parent
344ade98ee
commit
74bd5ed832
@ -130,53 +130,6 @@ class Elf(Binary):
|
||||
def threads(self):
|
||||
yield(('Running', {'EIP': self.elf.header.e_entry}))
|
||||
|
||||
from grr.snapshot import Grr
|
||||
class CGCGrr(Binary):
|
||||
def __init__(self, filename):
|
||||
HEADERSIZE = 16384
|
||||
self.grr = Grr.from_buf(file(filename).read(HEADERSIZE))
|
||||
self.arch = 'i386'
|
||||
assert ''.join(self.grr.magic) == 'GRRS'
|
||||
assert self.grr.exe_num <= 16
|
||||
assert self.grr.ranges[0].fd_offs == 16384
|
||||
#TODO more asserts
|
||||
super(CGCGrr, self).__init__(filename)
|
||||
|
||||
def maps(self):
|
||||
for r in self.grr.ranges:
|
||||
assert r.end>=r.begin
|
||||
assert (r.end-r.begin)&0xfff == 0
|
||||
assert r.fd_offs&0xfff == 0
|
||||
if r.end-r.begin == 0:
|
||||
continue
|
||||
perms = ''
|
||||
perms += r.is_r and 'r'or' '
|
||||
perms += r.is_w and 'w'or' '
|
||||
perms += r.is_x and 'x'or' '
|
||||
if 'r' not in perms:
|
||||
raise Exception("Not readable map from grr snapshot elf not supported")
|
||||
|
||||
yield((r.begin, r.end-r.begin, perms, self.path, r.fd_offs, r.end-r.begin))
|
||||
|
||||
def threads(self):
|
||||
#Basic
|
||||
regs = ['r15','r14','r13','r12','rbp','rbx','r11','r10','r9','r8','rax',
|
||||
'rcx','rdx','rsi','rdi','rip','cs','eflags','rsp','ss','ds','es','fs','gs']
|
||||
registers = dict([(name.upper(), getattr(self.grr.gregs, name)) for name in regs])
|
||||
|
||||
#XMM
|
||||
for name in ['xmm0', 'xmm1', 'xmm2', 'xmm3', 'xmm4', 'xmm5', 'xmm6', 'xmm7', 'xmm8',
|
||||
'xmm9', 'xmm10', 'xmm11', 'xmm12', 'xmm13', 'xmm14', 'xmm15' ]:
|
||||
registers[name.upper()] = getattr(self.grr.fpregs.xmm_space, name).high << 64 | \
|
||||
getattr(self.grr.fpregs.xmm_space, name).low
|
||||
|
||||
#FPU
|
||||
for i in xrange(8):
|
||||
registers['FP%d'%i] = ( getattr(self.grr.fpregs.st_space,'st%d'%i).mantissa,
|
||||
getattr(self.grr.fpregs.st_space,'st%d'%i).exponent )
|
||||
|
||||
yield ('Running', registers)
|
||||
|
||||
class Minidump(Binary):
|
||||
def __init__(self, filename):
|
||||
self.md = minidump.MiniDump(path)
|
||||
@ -235,7 +188,6 @@ class Minidump(Binary):
|
||||
|
||||
Binary.magics= { '\x7fCGC': CGCElf,
|
||||
'\x7fELF': Elf,
|
||||
'GRRS': CGCGrr,
|
||||
'MDMP': Minidump}
|
||||
|
||||
|
||||
|
||||
@ -1,191 +0,0 @@
|
||||
import itertools, struct
|
||||
|
||||
class BinaryObject(object):
|
||||
_fields_ = []
|
||||
|
||||
def __init__(self):
|
||||
self._total_size = 0
|
||||
|
||||
def __len__(self):
|
||||
return self._total_size
|
||||
|
||||
def __repr__(self):
|
||||
result = ['{']
|
||||
for slot, fmt in self._fields_:
|
||||
if slot is None:
|
||||
continue
|
||||
if '[' in slot:
|
||||
slot = slot.split('[')[0]
|
||||
result.append(repr(slot)+':')
|
||||
result.append(repr(getattr(self,slot)))
|
||||
result.append('}')
|
||||
return ' '.join(result)
|
||||
|
||||
|
||||
def _initialize_slots(self, buf, offset, field_specs):
|
||||
total = self._total_size
|
||||
for slot, fmt in field_specs:
|
||||
reps = 1
|
||||
try:
|
||||
if '[' in slot:
|
||||
reps = slot.split('[')[1][:-1]
|
||||
slot = slot.split('[')[0]
|
||||
try:
|
||||
reps = int(reps)
|
||||
except Exception,e:
|
||||
reps = getattr(self, reps)
|
||||
except Exception,e:
|
||||
pass
|
||||
|
||||
x = []
|
||||
size = 0
|
||||
for i in range(reps):
|
||||
if isinstance(fmt, type):
|
||||
val = fmt.from_buf(buf, offset + total + size)
|
||||
assert isinstance(val, BinaryObject)
|
||||
x.append(val)
|
||||
size += len(val)
|
||||
else:
|
||||
try:
|
||||
x += struct.unpack_from(fmt, buf, offset + total+ size)
|
||||
except:
|
||||
raise Exception("Failed parsing %s from offset %d"%(fmt,offset + total))
|
||||
size += struct.calcsize(fmt)
|
||||
|
||||
#print "PARSING %s of type %s REP %d at offset %d of size %d"%(slot, fmt, i, offset + total, size)
|
||||
total += size
|
||||
|
||||
if reps == 1 and len(x) ==1:
|
||||
x = x[0]
|
||||
if slot is not None:
|
||||
setattr(self, slot, x)
|
||||
|
||||
self._total_size = total
|
||||
|
||||
@classmethod
|
||||
def from_buf(cls, buf, offset=0):
|
||||
# Determine our inheritance path back to BinaryObject
|
||||
inheritance_chain = []
|
||||
pos = cls
|
||||
while pos != BinaryObject:
|
||||
inheritance_chain.append(pos)
|
||||
bases = pos.__bases__
|
||||
assert len(bases) == 1
|
||||
pos = bases[0]
|
||||
inheritance_chain.reverse()
|
||||
|
||||
# Determine all the field names and specs that we need to read.
|
||||
all_field_specs = itertools.chain(*[c._fields_
|
||||
for c in inheritance_chain])
|
||||
|
||||
# Create the actual object and populate its fields.
|
||||
obj = cls()
|
||||
obj._initialize_slots(buf, offset, all_field_specs)
|
||||
return obj
|
||||
|
||||
|
||||
class UserRegsStruct(BinaryObject):
|
||||
_fields_ = [('r15', '<Q'),
|
||||
('r14', '<Q'),
|
||||
('r13', '<Q'),
|
||||
('r12', '<Q'),
|
||||
('rbp', '<Q'),
|
||||
('rbx', '<Q'),
|
||||
('r11', '<Q'),
|
||||
('r10', '<Q'),
|
||||
('r9', '<Q'),
|
||||
('r8', '<Q'),
|
||||
('rax', '<Q'),
|
||||
('rcx', '<Q'),
|
||||
('rdx', '<Q'),
|
||||
('rsi', '<Q'),
|
||||
('rdi', '<Q'),
|
||||
('orig_rax', '<Q'),
|
||||
('rip', '<Q'),
|
||||
('cs', '<Q'),
|
||||
('eflags', '<Q'),
|
||||
('rsp', '<Q'),
|
||||
('ss', '<Q'),
|
||||
('fs_base', '<Q'),
|
||||
('gs_base', '<Q'),
|
||||
('ds', '<Q'),
|
||||
('es', '<Q'),
|
||||
('fs', '<Q'),
|
||||
('gs', '<Q')]
|
||||
|
||||
class FPUStackElement(BinaryObject):
|
||||
_fields_ = [
|
||||
('mantissa', '<Q'),
|
||||
('exponent', '<H'),
|
||||
(None, '6c')]
|
||||
|
||||
class FPUStack(BinaryObject):
|
||||
_fields_ = [
|
||||
('st0', FPUStackElement),
|
||||
('st1', FPUStackElement),
|
||||
('st2', FPUStackElement),
|
||||
('st3', FPUStackElement),
|
||||
('st4', FPUStackElement),
|
||||
('st5', FPUStackElement),
|
||||
('st6', FPUStackElement),
|
||||
('st7', FPUStackElement),]
|
||||
|
||||
class XMMReg(BinaryObject):
|
||||
_fields_ = [
|
||||
('low', '<Q'),
|
||||
('high', '<Q')]
|
||||
|
||||
class XMMSpace(BinaryObject):
|
||||
_fields_ = [
|
||||
('xmm0', XMMReg),
|
||||
('xmm1', XMMReg),
|
||||
('xmm2', XMMReg),
|
||||
('xmm3', XMMReg),
|
||||
('xmm4', XMMReg),
|
||||
('xmm5', XMMReg),
|
||||
('xmm6', XMMReg),
|
||||
('xmm7', XMMReg),
|
||||
('xmm8', XMMReg),
|
||||
('xmm9', XMMReg),
|
||||
('xmm10', XMMReg),
|
||||
('xmm11', XMMReg),
|
||||
('xmm12', XMMReg),
|
||||
('xmm13', XMMReg),
|
||||
('xmm14', XMMReg),
|
||||
('xmm15', XMMReg),]
|
||||
|
||||
class UserFpregsStruct(BinaryObject):
|
||||
_fields_ = [('cwd', '<H'),
|
||||
('swd', '<H'),
|
||||
('ftw', '<H'),
|
||||
('fop', '<H'),
|
||||
('rip', '<Q'),
|
||||
('rdp', '<Q'),
|
||||
('mxcsr', '<L'),
|
||||
('mxcsr_mask', '<L'),
|
||||
('st_space', FPUStack),
|
||||
('xmm_space', XMMSpace),
|
||||
(None, '96c'),
|
||||
]
|
||||
|
||||
class MappedRange32(BinaryObject):
|
||||
_fields_ = [('fd_offs', '<Q'),
|
||||
('begin', '<L'),
|
||||
('end', '<L'),
|
||||
('is_r', 'B'),
|
||||
('is_w', 'B'),
|
||||
('is_x', 'B'),
|
||||
(None, '5c')]
|
||||
|
||||
class Grr(BinaryObject):
|
||||
_fields_ = [('magic', '4c'),
|
||||
('exe_num','<L'),
|
||||
('gregs', UserRegsStruct),
|
||||
('fpregs', UserFpregsStruct),
|
||||
('ranges[652]', MappedRange32) ]
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
mbb = Grr.from_buf(file(sys.argv[1]).read())
|
||||
print mbb
|
||||
|
||||
@ -10,7 +10,6 @@ from ..core.smtlib import *
|
||||
from ..core.executor import TerminateState
|
||||
from ..utils.helpers import issymbolic
|
||||
from ..binary import CGCElf
|
||||
from ..binary import CGCGrr
|
||||
from contextlib import closing
|
||||
import StringIO
|
||||
import logging
|
||||
@ -224,39 +223,6 @@ class Decree(object):
|
||||
|
||||
|
||||
def load(self, filename):
|
||||
magic = file(filename).read(4)
|
||||
if magic == '\x7fCGC':
|
||||
return self._load_cgc(filename)
|
||||
else:
|
||||
assert magic == 'GRRS'
|
||||
return self._load_grr(filename)
|
||||
|
||||
def _load_grr(self, filename):
|
||||
'''
|
||||
Loads a GRR CGC snapshot in memory and restores the CPU state.
|
||||
|
||||
:param filename: pathname of the file to be executed.
|
||||
'''
|
||||
grr = CGCGrr(filename)
|
||||
logger.info("Loading %s grr snapshot", filename)
|
||||
|
||||
#make cpu and memory (Only 1 thread in Grr)
|
||||
cpu = self._mk_proc()
|
||||
for (vaddr, memsz, perms, name, offset, filesz) in grr.maps():
|
||||
addr = cpu.memory.mmapFile(vaddr, memsz, perms, name, offset)
|
||||
assert addr == vaddr, "Overlapping maps!?"
|
||||
#Only one thread in Decree
|
||||
status, thread = next(grr.threads())
|
||||
assert status == 'Running'
|
||||
|
||||
logger.info("Restoring cpu state from snapshot")
|
||||
#set initial CPU state
|
||||
for reg in thread:
|
||||
cpu.write_register(reg, thread[reg])
|
||||
return [cpu]
|
||||
|
||||
|
||||
def _load_cgc(self, filename):
|
||||
'''
|
||||
Loads a CGC-ELF program in memory and prepares the initial CPU state
|
||||
and the stack.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user