Remove win32 support (#535)
* Remove Windows support files * Remove Windows test files
This commit is contained in:
@@ -130,65 +130,9 @@ class Elf(Binary):
|
||||
def threads(self):
|
||||
yield(('Running', {'EIP': self.elf.header.e_entry}))
|
||||
|
||||
class Minidump(Binary):
|
||||
def __init__(self, filename):
|
||||
self.md = minidump.MiniDump(path)
|
||||
assert self.md.get_architecture() == "x86"
|
||||
self.arch = 'i386'
|
||||
|
||||
major, minor = map(int, self.md.version.split(' ')[0].split('.'))
|
||||
if major == 6:
|
||||
self.flavor = "Windows7SP%d"%minor
|
||||
elif major == 10:
|
||||
self.flavor = "Windows10SP%d"%minor
|
||||
else:
|
||||
raise NotImplemented() #"Windows version not supported")
|
||||
|
||||
super(Minidump, self).__init__(filename)
|
||||
|
||||
|
||||
|
||||
def maps(self):
|
||||
# Setting up memory maps
|
||||
query = self.md.get_memory_map()
|
||||
data = self.get_memory_data()
|
||||
|
||||
for addr in data:
|
||||
perms, size = query[addr]
|
||||
offsetofdatainminidump = 0
|
||||
yield((addr&0xffffffff, size, perms, self.path, offsetofdatainminidump, len(data[addr]) ) )
|
||||
|
||||
def threads(self):
|
||||
selectedThreadId = self.md.get_threads()[0].ThreadId
|
||||
|
||||
for thread in self.md.get_threads():
|
||||
cxt = md.get_register_context_by_tid(thread.ThreadId)
|
||||
#Let's just ignore all extra threads for now
|
||||
status = 'Sleeping'
|
||||
if selectedThreadId == thread.ThreadId:
|
||||
status = 'Running'
|
||||
registers = { 'EIP': cxt.Eip,
|
||||
'ESP': cxt.Esp,
|
||||
'EBP': cxt.Ebp,
|
||||
'EAX': cxt.Eax,
|
||||
'EBX': cxt.Ebx,
|
||||
'ECX': cxt.Ecx,
|
||||
'EDX': cxt.Edx,
|
||||
'ESI': cxt.Esi,
|
||||
'EDI': cxt.Edi,
|
||||
'FS': cxt.SegFs}
|
||||
|
||||
if (additional_context and 'registers' in additional_context):
|
||||
for name, value in additional_context['registers'].iteritems():
|
||||
registers[name]= value
|
||||
yield((status, registers))
|
||||
|
||||
|
||||
|
||||
|
||||
Binary.magics= { '\x7fCGC': CGCElf,
|
||||
'\x7fELF': Elf,
|
||||
'MDMP': Minidump}
|
||||
'\x7fELF': Elf }
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -1,680 +0,0 @@
|
||||
import struct
|
||||
from StringIO import StringIO
|
||||
class Structure(object):
|
||||
def __init__(self):
|
||||
if not hasattr(self, "_fields_"):
|
||||
raise NotImplementedError("No _fields_ in structure")
|
||||
|
||||
self.__size__ = 0
|
||||
self.__struct_fields__ = {}
|
||||
|
||||
for _, field_type in self._fields_:
|
||||
if type(field_type) == str:
|
||||
self.__size__ += struct.calcsize(field_type)
|
||||
else:
|
||||
obj = field_type()
|
||||
self.__size__ += len(obj)
|
||||
|
||||
def __getattr__(self, name):
|
||||
if name in self.__struct_fields__:
|
||||
return self.__struct_fields__[name]
|
||||
raise AttributeError(name)
|
||||
|
||||
def __len__(self):
|
||||
return self.__size__
|
||||
|
||||
def __repr__(self):
|
||||
return self.tree()
|
||||
|
||||
def parse(self, fd):
|
||||
for field_name, field_type in self._fields_:
|
||||
if type(field_type) == str:
|
||||
size = struct.calcsize(field_type)
|
||||
value = struct.unpack(field_type, fd.read(size))[0]
|
||||
self.__struct_fields__[field_name] = value
|
||||
else:
|
||||
obj = field_type()
|
||||
obj.parse(fd)
|
||||
self.__struct_fields__[field_name] = obj
|
||||
|
||||
|
||||
def tree(self, depth=0):
|
||||
def stringify(name):
|
||||
assert name in self.__struct_fields__
|
||||
value = self.__struct_fields__[name]
|
||||
if type(value) == int:
|
||||
return "0x%08x" % value
|
||||
elif type(value) == long:
|
||||
return "0x%016x" % value
|
||||
elif type(value) == str:
|
||||
return repr(value)
|
||||
else:
|
||||
return "%s\n%s" % (value.__class__.__name__, value.tree(depth + 2))
|
||||
|
||||
out = " " * depth
|
||||
if depth != 0: out += "+"
|
||||
out += "%s\n" % self.__class__.__name__
|
||||
|
||||
for field_name, field_type in self._fields_:
|
||||
out += " " * depth + " .%-32s = %s\n" % (field_name, stringify(field_name))
|
||||
|
||||
return out[ : -1]
|
||||
|
||||
class MINIDUMP_HEADER(Structure):
|
||||
_fields_ = [("Signature", "4s"), \
|
||||
("Version", "<I"), \
|
||||
("NumberOfStreams", "<I"), \
|
||||
("StreamDirectoryRva", "<I"), \
|
||||
("Checksum", "<I"), \
|
||||
("TimeDateStamp", "<I"), \
|
||||
("Flags", "<Q")]
|
||||
|
||||
class MINIDUMP_LOCATION_DESCRIPTOR(Structure):
|
||||
_fields_ = [("DataSize", "<I"), \
|
||||
("Rva", "<I")]
|
||||
|
||||
class MINIDUMP_EXCEPTION(Structure):
|
||||
_fields_ = [("ExceptionCode", "<I"), \
|
||||
("ExceptionFlags", "<I"), \
|
||||
("ExceptionRecord", "<Q"), \
|
||||
("ExceptionAddress", "<Q"), \
|
||||
("NumberOfParameters", "<I"), \
|
||||
("__unusedAlignment", "<I"), \
|
||||
("ExceptionInfomration0", "<Q"), \
|
||||
("ExceptionInfomration1", "<Q"), \
|
||||
("ExceptionInfomration2", "<Q"), \
|
||||
("ExceptionInfomration3", "<Q"), \
|
||||
("ExceptionInfomration4", "<Q"), \
|
||||
("ExceptionInfomration5", "<Q"), \
|
||||
("ExceptionInfomration6", "<Q"), \
|
||||
("ExceptionInfomration7", "<Q"), \
|
||||
("ExceptionInfomration8", "<Q"), \
|
||||
("ExceptionInfomration9", "<Q"), \
|
||||
("ExceptionInfomration10", "<Q"), \
|
||||
("ExceptionInfomration11", "<Q"), \
|
||||
("ExceptionInfomration12", "<Q"), \
|
||||
("ExceptionInfomration13", "<Q"), \
|
||||
("ExceptionInfomration14", "<Q")]
|
||||
|
||||
class MINIDUMP_EXCEPTION_STREAM(Structure):
|
||||
_fields_ = [("ThreadId", "<I"), \
|
||||
("__alignment", "<I"), \
|
||||
("ExceptionRecord", MINIDUMP_EXCEPTION), \
|
||||
("ThreadContext", MINIDUMP_LOCATION_DESCRIPTOR)]
|
||||
|
||||
class MINIDUMP_MEMORY_DESCRIPTOR64(Structure):
|
||||
_fields_ = [("StartOfMemory", "<Q"), \
|
||||
("DataSize", "<Q")]
|
||||
|
||||
class VS_FIXEDFILEINFO(Structure):
|
||||
_fields_ = [("dwSignature", "<I"), \
|
||||
("dwStrucVersion", "<I"), \
|
||||
("dwFileVersionMS", "<I"), \
|
||||
("dwFileVersionLS", "<I"), \
|
||||
("dwProductVersionMS", "<I"), \
|
||||
("dwProductVersionLS", "<I"), \
|
||||
("dwFileFlagsMask", "<I"), \
|
||||
("dwFileFlags", "<I"), \
|
||||
("dwFileOS", "<I"), \
|
||||
("dwFileType", "<I"), \
|
||||
("dwFileSubtype", "<I"), \
|
||||
("dwFileDateMS", "<I"), \
|
||||
("dwFileDateLS", "<I")]
|
||||
|
||||
class MINIDUMP_STRING(Structure):
|
||||
def __init__(self):
|
||||
self._fields_ = [("Length", "<I")]
|
||||
Structure.__init__(self)
|
||||
|
||||
def __len__(self):
|
||||
if self.__size__ == 0: raise Exception("Variadic Structure")
|
||||
return self.__size__
|
||||
|
||||
def parse(self, fd):
|
||||
count = struct.unpack("<I", fd.read(4))[0]
|
||||
bytes = fd.read(count)
|
||||
|
||||
self.__struct_fields__["Length"] = count
|
||||
self.__struct_fields__["Buffer"] = bytes
|
||||
|
||||
self._fields_.append(("Buffer", "%ds" % count))
|
||||
|
||||
class MINIDUMP_MODULE(Structure):
|
||||
_fields_ = [("BaseOfImage", "<Q"), \
|
||||
("SizeOfImage", "<I"), \
|
||||
("CheckSum", "<I"), \
|
||||
("TimeDateStamp", "<I"), \
|
||||
("ModuleNameRva", "<I"), \
|
||||
("VersionInfo", VS_FIXEDFILEINFO), \
|
||||
("CvRecord", MINIDUMP_LOCATION_DESCRIPTOR), \
|
||||
("MiscRecord", MINIDUMP_LOCATION_DESCRIPTOR), \
|
||||
("Reserved0", "<Q"), \
|
||||
("Reserved1", "<Q")]
|
||||
|
||||
class MINIDUMP_MODULE_LIST(Structure):
|
||||
def __init__(self):
|
||||
self._fields_ = [("NumberOfModules", "<I")]
|
||||
Structure.__init__(self)
|
||||
|
||||
def __len__(self):
|
||||
if self.__size__ == 0: raise Exception("Variadic Structure")
|
||||
return self.__size__
|
||||
|
||||
def parse(self, fd):
|
||||
count = struct.unpack("<I", fd.read(4))[0]
|
||||
self.__struct_fields__["NumberOfModules"] = count
|
||||
self.__struct_fields__["Modules"] = {}
|
||||
|
||||
for i in range(0, count):
|
||||
mm = MINIDUMP_MODULE()
|
||||
mm.parse(fd)
|
||||
|
||||
pos = fd.tell()
|
||||
fd.seek(mm.ModuleNameRva)
|
||||
|
||||
ms = MINIDUMP_STRING()
|
||||
ms.parse(fd)
|
||||
|
||||
self.__struct_fields__["Modules"][str(ms.Buffer)] = mm
|
||||
|
||||
fd.seek(pos)
|
||||
|
||||
def tree(self, depth=0):
|
||||
out = " " * depth
|
||||
if depth != 0: out += "+"
|
||||
out += "%s\n" % self.__class__.__name__
|
||||
|
||||
out += " " * depth + " .%-32s = 0x%08x\n" % ("NumberOfModules", self.__struct_fields__["NumberOfModules"])
|
||||
out += " " * depth + " .%-32s = MINIDUMP_MODULE[]\n" % "Modules"
|
||||
|
||||
i = 0
|
||||
for module_name in self.__struct_fields__["Modules"]:
|
||||
out += " " * depth + " [%02i] \"%s\" %s\n" % (i, module_name, \
|
||||
self.__struct_fields__["Modules"][module_name].tree(depth + 2))
|
||||
i += 1
|
||||
|
||||
return out[ : -1]
|
||||
|
||||
class MINIDUMP_MEMORY64_LIST(Structure):
|
||||
def __init__(self):
|
||||
self._fields_ = [("NumberOfMemoryRanges", "<Q"), \
|
||||
("BaseRva", "<Q")]
|
||||
Structure.__init__(self)
|
||||
|
||||
def __len__(self):
|
||||
if self.__size__ == 0: raise Exception("Variadic Structure")
|
||||
return self.__size__
|
||||
|
||||
def parse(self, fd):
|
||||
nitems, rva = struct.unpack("<QQ", fd.read(16))
|
||||
self.__struct_fields__["NumberOfMemoryRanges"] = nitems
|
||||
self.__struct_fields__["BaseRva"] = rva
|
||||
|
||||
obj = MINIDUMP_MEMORY_DESCRIPTOR64()
|
||||
self.__size__ = 16 + nitems * len(obj)
|
||||
|
||||
self.__struct_fields__["MemoryRanges"] = []
|
||||
for i in range(0, nitems):
|
||||
desc = MINIDUMP_MEMORY_DESCRIPTOR64()
|
||||
desc.parse(fd)
|
||||
|
||||
self.__struct_fields__["MemoryRanges"].append(desc)
|
||||
|
||||
def tree(self, depth=0):
|
||||
out = " " * depth
|
||||
if depth != 0: out += "+"
|
||||
out += "%s\n" % self.__class__.__name__
|
||||
|
||||
out += " " * depth + " .%-32s = 0x%016x\n" % ("NumberOfMemoryRanges", self.__struct_fields__["NumberOfMemoryRanges"])
|
||||
out += " " * depth + " .%-32s = 0x%016x\n" % ("BaseRva", self.__struct_fields__["BaseRva"])
|
||||
out += " " * depth + " .%-32s = MINIDUMP_MEMORY_DESCRIPTOR64[]\n" % "MemoryRanges"
|
||||
|
||||
i = 0
|
||||
for desc in self.__struct_fields__["MemoryRanges"]:
|
||||
out += " " * depth + " [%02i] %s\n" % (i, desc.tree(depth + 2))
|
||||
i += 1
|
||||
|
||||
return out[ : -1]
|
||||
|
||||
class MINIDUMP_DIRECTORY(Structure):
|
||||
_fields_ = [("StreamType", "<I"), \
|
||||
("Location", MINIDUMP_LOCATION_DESCRIPTOR)]
|
||||
|
||||
class MINIDUMP_MEMORY_INFO(Structure):
|
||||
_fields_ = [("BaseAddress", "<Q"), \
|
||||
("AllocationBase", "<Q"), \
|
||||
("AllocationProtect", "<I"), \
|
||||
("__alignment1", "<I"), \
|
||||
("RegionSize", "<Q"), \
|
||||
("State", "<I"), \
|
||||
("Protect", "<I"), \
|
||||
("Type", "<I"), \
|
||||
("__alignment2", "<I")]
|
||||
|
||||
class MINIDUMP_MEMORY_INFO_LIST(Structure):
|
||||
_fields_ = [("SizeOfHeader", "<I"), \
|
||||
("SizeOfEntry", "<I"), \
|
||||
("NumberOfEntries", "<Q")]
|
||||
|
||||
class MINIDUMP_SYSTEM_INFO(Structure):
|
||||
_fields_ = [("ProcessorArchitecture", "<H"), \
|
||||
("ProcessorLevel", "<H"), \
|
||||
("ProcessorRevision", "<H"), \
|
||||
("NumberOfProcessors", "B"), \
|
||||
("ProductType", "B"), \
|
||||
("MajorVersion", "<I"), \
|
||||
("MinorVersion", "<I"), \
|
||||
("BuildNumber", "<I"), \
|
||||
("PlatformId", "<I"), \
|
||||
("CSDVersionRva", "<I"), \
|
||||
("SuiteMask", "<H"), \
|
||||
("Reserved2", "<H"), \
|
||||
("VendorId", "12s"), \
|
||||
("VersionInformation", "<I"), \
|
||||
("FeatureInformation", "<I"), \
|
||||
("AMDExtendedCpuFeatures", "<I")]
|
||||
|
||||
class MINIDUMP_THREAD(Structure):
|
||||
_fields_ = [("ThreadId", "<I"), \
|
||||
("SuspendCount", "<I"), \
|
||||
("PriorityClass", "<I"), \
|
||||
("Priority", "<I"), \
|
||||
("Teb", "<Q"), \
|
||||
("Stack", MINIDUMP_MEMORY_DESCRIPTOR64), \
|
||||
("ThreadContext", MINIDUMP_LOCATION_DESCRIPTOR)]
|
||||
|
||||
def parse(self, fd):
|
||||
Structure.parse(self, fd)
|
||||
a = fd.tell()
|
||||
fd.seek(self.ThreadContext.Rva)
|
||||
self.__struct_fields__["Context"] = fd.read(self.ThreadContext.DataSize)
|
||||
fd.seek(a)
|
||||
|
||||
def getContext(self, architecture):
|
||||
if architecture == "x86":
|
||||
cxt = CONTEXT_x86()
|
||||
elif architecture == "amd64":
|
||||
cxt = CONTEXT_amd64()
|
||||
elif architecture == "arm32":
|
||||
cxt = CONTEXT_arm32()
|
||||
else:
|
||||
raise Exception("Unknown architecture for context parsing!")
|
||||
assert len(self.Context) == len(cxt)
|
||||
|
||||
cxt.parse(StringIO(self.Context))
|
||||
return cxt
|
||||
|
||||
class MINIDUMP_THREAD_LIST(Structure):
|
||||
def __init__(self):
|
||||
self._fields_ = [("NumberOfThreads", "<I")]
|
||||
Structure.__init__(self)
|
||||
|
||||
def __len__(self):
|
||||
if self.__size__ == 0: raise Exception("Variadic Structure")
|
||||
return self.__size__
|
||||
|
||||
def parse(self, fd):
|
||||
count = struct.unpack("<I", fd.read(4))[0]
|
||||
self.__struct_fields__["NumberOfThreads"] = count
|
||||
self.__struct_fields__["Threads"] = []
|
||||
|
||||
for i in range(0, count):
|
||||
mt = MINIDUMP_THREAD()
|
||||
mt.parse(fd)
|
||||
self.__struct_fields__["Threads"].append(mt)
|
||||
|
||||
def tree(self, depth=0):
|
||||
out = " " * depth
|
||||
if depth != 0: out += "+"
|
||||
out += "%s\n" % self.__class__.__name__
|
||||
|
||||
out += " " * depth + " .%-32s = 0x%08x\n" % ("NumberOfThreads", self.__struct_fields__["NumberOfThreads"])
|
||||
out += " " * depth + " .%-32s = MINIDUMP_THREAD[]\n" % "Threads"
|
||||
|
||||
i = 0
|
||||
for thread in self.__struct_fields__["Threads"]:
|
||||
out += " " * depth + " [%02i] %s\n" % (i, thread.tree(depth + 2))
|
||||
i += 1
|
||||
|
||||
return out[ : -1]
|
||||
|
||||
class FLOATING_SAVE_AREA_x86(Structure):
|
||||
_fields_ = [("ControlWord", "<I"), \
|
||||
("StatusWord", "<I"), \
|
||||
("TagWord", "<I"), \
|
||||
("ErrorOffset", "<I"), \
|
||||
("ErrorSelector", "<I"), \
|
||||
("DataOffset", "<I"), \
|
||||
("DataSelector", "<I"), \
|
||||
("RegisterArea", "80s"), \
|
||||
("Cr0NpxState", "<I")]
|
||||
|
||||
class CONTEXT_x86(Structure):
|
||||
_fields_ = [("ContextFlags", "<I"), \
|
||||
("Dr0", "<I"), \
|
||||
("Dr1", "<I"), \
|
||||
("Dr2", "<I"), \
|
||||
("Dr3", "<I"), \
|
||||
("Dr6", "<I"), \
|
||||
("Dr7", "<I"), \
|
||||
("FloatSave", FLOATING_SAVE_AREA_x86), \
|
||||
("SegGs", "<I"), \
|
||||
("SegFs", "<I"), \
|
||||
("SegEs", "<I"), \
|
||||
("SegDs", "<I"), \
|
||||
("Edi", "<I"), \
|
||||
("Esi", "<I"), \
|
||||
("Ebx", "<I"), \
|
||||
("Edx", "<I"), \
|
||||
("Ecx", "<I"), \
|
||||
("Eax", "<I"), \
|
||||
("Ebp", "<I"), \
|
||||
("Eip", "<I"), \
|
||||
("SegCs", "<I"), \
|
||||
("EFlags", "<I"), \
|
||||
("Esp", "<I"), \
|
||||
("SegSs", "<I"), \
|
||||
("ExtendedRegisters", "512s")]
|
||||
|
||||
class XMM_SAVE_AREA32(Structure):
|
||||
_fields_ = [("ControlWord", "<H"), \
|
||||
("StatusWord", "<H"), \
|
||||
("TagWord", "B"), \
|
||||
("Reserved1", "B"), \
|
||||
("ErrorOpcode", "<H"), \
|
||||
("ErrorOffset", "<I"), \
|
||||
("ErrorSelector", "<H"), \
|
||||
("Reserved2", "<H"), \
|
||||
("DataOffset", "<I"), \
|
||||
("DataSelector", "<H"), \
|
||||
("Reserved3", "<H"), \
|
||||
("MxCsr", "<I"), \
|
||||
("MxCsr_Mask", "<I"), \
|
||||
("FloatRegisters", "128s"), \
|
||||
("XmmRegisters", "256s"), \
|
||||
("Reserved4", "96s")]
|
||||
|
||||
class CONTEXT_amd64(Structure):
|
||||
_fields_ = [("P1Home", "<Q"), \
|
||||
("P2Home", "<Q"), \
|
||||
("P3Home", "<Q"), \
|
||||
("P4Home", "<Q"), \
|
||||
("P5Home", "<Q"), \
|
||||
("P6Home", "<Q"), \
|
||||
("ContextFlags", "<I"), \
|
||||
("MxCsr", "<I"), \
|
||||
("SegCs", "<H"), \
|
||||
("SegDs", "<H"), \
|
||||
("SegEs", "<H"), \
|
||||
("SegFs", "<H"), \
|
||||
("SegGs", "<H"), \
|
||||
("SegSs", "<H"), \
|
||||
("EFlags", "<I"), \
|
||||
("Dr0", "<Q"), \
|
||||
("Dr1", "<Q"), \
|
||||
("Dr2", "<Q"), \
|
||||
("Dr3", "<Q"), \
|
||||
("Dr6", "<Q"), \
|
||||
("Dr7", "<Q"), \
|
||||
("Rax", "<Q"), \
|
||||
("Rcx", "<Q"), \
|
||||
("Rdx", "<Q"), \
|
||||
("Rbx", "<Q"), \
|
||||
("Rsp", "<Q"), \
|
||||
("Rbp", "<Q"), \
|
||||
("Rsi", "<Q"), \
|
||||
("Rdi", "<Q"), \
|
||||
("R8", "<Q"), \
|
||||
("R9", "<Q"), \
|
||||
("R10", "<Q"), \
|
||||
("R11", "<Q"), \
|
||||
("R12", "<Q"), \
|
||||
("R13", "<Q"), \
|
||||
("R14", "<Q"), \
|
||||
("R15", "<Q"), \
|
||||
("Rip", "<Q"), \
|
||||
("FltSave", XMM_SAVE_AREA32), \
|
||||
("VectorRegister", "416s"), \
|
||||
("DebugControl", "<Q"), \
|
||||
("LastBranchToRip", "<Q"), \
|
||||
("LastBranchFromRip", "<Q"), \
|
||||
("LastExceptionToRip", "<Q"), \
|
||||
("LastExceptionFromRip", "<Q")]
|
||||
|
||||
class CONTEXT_arm32(Structure):
|
||||
# XXX: this structure is INCOMPLETE
|
||||
_fields_ = [("ContextFlags", "<I"), \
|
||||
("R0", "<I"), \
|
||||
("R1", "<I"), \
|
||||
("R2", "<I"), \
|
||||
("R3", "<I"), \
|
||||
("R4", "<I"), \
|
||||
("R5", "<I"), \
|
||||
("R6", "<I"), \
|
||||
("R7", "<I"), \
|
||||
("R8", "<I"), \
|
||||
("R9", "<I"), \
|
||||
("R10", "<I"), \
|
||||
("R11", "<I"), \
|
||||
("R12", "<I"), \
|
||||
("Sp", "<I"), \
|
||||
("Lr", "<I"), \
|
||||
("Pc", "<I"), \
|
||||
("Cpsr", "<I"), \
|
||||
("Fpscr", "<I"), \
|
||||
("Padding", "<I")]
|
||||
|
||||
class MiniDump(object):
|
||||
def __init__(self, path, autoparse=True):
|
||||
self.path = path
|
||||
self.fd = open(self.path, "rb")
|
||||
|
||||
self.memory_data = {}
|
||||
self.memory_query = {}
|
||||
self.context = None
|
||||
|
||||
self.processor = None
|
||||
self.architecture = None
|
||||
self.processor_level = None
|
||||
self.version = None
|
||||
|
||||
self.exception_info = None
|
||||
self.system_info = None
|
||||
self.module_map = {}
|
||||
self.threads = []
|
||||
|
||||
if autoparse: self.parse()
|
||||
|
||||
def __parse_memory_list64__(self, dirent):
|
||||
ml64 = MINIDUMP_MEMORY64_LIST()
|
||||
ml64.parse(self.fd)
|
||||
|
||||
self.fd.seek(ml64.BaseRva)
|
||||
|
||||
for desc in ml64.MemoryRanges:
|
||||
bytes = self.fd.read(desc.DataSize)
|
||||
self.memory_data[desc.StartOfMemory] = bytes
|
||||
|
||||
def __parse_exception_stream__(self, dirent):
|
||||
exc = MINIDUMP_EXCEPTION_STREAM()
|
||||
exc.parse(self.fd)
|
||||
|
||||
self.fd.seek(exc.ThreadContext.Rva)
|
||||
|
||||
if self.architecture == "x86":
|
||||
cxt = CONTEXT_x86()
|
||||
elif self.architecture == "amd64":
|
||||
cxt = CONTEXT_amd64()
|
||||
elif self.architecture == "arm32":
|
||||
cxt = CONTEXT_arm32()
|
||||
else:
|
||||
raise Exception("Unknown architecture for context parsing!")
|
||||
|
||||
cxt.parse(self.fd)
|
||||
self.context = cxt
|
||||
self.exception_info = exc
|
||||
|
||||
def __parse_memory_info__(self, dirent):
|
||||
PAGE_EXECUTE = 0x10
|
||||
PAGE_EXECUTE_READ = 0x20
|
||||
PAGE_EXECUTE_READWRITE = 0x40
|
||||
PAGE_EXECUTE_WRITECOPY = 0x80
|
||||
PAGE_NOACCESS = 0x01
|
||||
PAGE_READONLY = 0x02
|
||||
PAGE_READWRITE = 0x04
|
||||
PAGE_WRITECOPY = 0x08
|
||||
|
||||
def parse_perms(flags):
|
||||
if ((flags & 0xff) == PAGE_EXECUTE): return "x"
|
||||
if ((flags & 0xff) == PAGE_EXECUTE_READ): return "rx"
|
||||
if ((flags & 0xff) == PAGE_EXECUTE_READWRITE): return "rwx"
|
||||
if ((flags & 0xff) == PAGE_EXECUTE_WRITECOPY): return "rwx"
|
||||
if ((flags & 0xff) == PAGE_READONLY): return "r"
|
||||
if ((flags & 0xff) == PAGE_READWRITE): return "rw"
|
||||
if ((flags & 0xff) == PAGE_WRITECOPY): return "rw"
|
||||
if ((flags & 0xff) == PAGE_NOACCESS): return ""
|
||||
raise NotImplementedError
|
||||
|
||||
mil = MINIDUMP_MEMORY_INFO_LIST()
|
||||
mil.parse(self.fd)
|
||||
|
||||
for i in range(0, mil.NumberOfEntries):
|
||||
mi = MINIDUMP_MEMORY_INFO()
|
||||
mi.parse(self.fd)
|
||||
|
||||
if mi.Protect == 0:
|
||||
perms = parse_perms(mi.AllocationProtect)
|
||||
else:
|
||||
perms = parse_perms(mi.Protect)
|
||||
|
||||
self.memory_query[mi.BaseAddress] = (perms, mi.RegionSize)
|
||||
|
||||
def __parse_systeminfo__(self, dirent):
|
||||
PROCESSOR_ARCHITECTURE_AMD64 = 9
|
||||
PROCESSOR_ARCHITECTURE_ARM = 5
|
||||
PROCESSOR_ARCHITECTURE_IA64 = 6
|
||||
PROCESSOR_ARCHITECTURE_INTEL = 0
|
||||
PROCESSOR_ARCHITECTURE_UNKNOWN = 0xffff
|
||||
|
||||
msi = MINIDUMP_SYSTEM_INFO()
|
||||
msi.parse(self.fd)
|
||||
|
||||
self.system_info = msi
|
||||
self.processor = msi.VendorId
|
||||
|
||||
if msi.ProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64:
|
||||
self.architecture = "amd64"
|
||||
elif msi.ProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM:
|
||||
self.architecture = "arm32"
|
||||
elif msi.ProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64:
|
||||
self.architecture = "ia64"
|
||||
elif msi.ProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL:
|
||||
self.architecture = "x86"
|
||||
else:
|
||||
self.architecture = "unknown"
|
||||
|
||||
if self.architecture == "x86":
|
||||
if msi.ProcessorLevel == 3:
|
||||
self.processor_level = "i386"
|
||||
elif msi.ProcessorLevel == 4:
|
||||
self.processor_level = "i486"
|
||||
elif msi.ProcessorLevel == 5:
|
||||
self.processor_level = "pentium"
|
||||
elif msi.ProcessorLevel == 6:
|
||||
self.processor_level = "pentium2"
|
||||
else:
|
||||
self.processor_level = "unknown"
|
||||
|
||||
self.version = "%d.%d (build %d)" % (msi.MajorVersion, msi.MinorVersion, msi.BuildNumber)
|
||||
|
||||
def __parse_modulelist__(self, dirent):
|
||||
mml = MINIDUMP_MODULE_LIST()
|
||||
mml.parse(self.fd)
|
||||
|
||||
self.module_map = mml.Modules
|
||||
|
||||
def __parse_threadlist__(self, dirent):
|
||||
mtl = MINIDUMP_THREAD_LIST()
|
||||
mtl.parse(self.fd)
|
||||
|
||||
self.threads = mtl.Threads
|
||||
|
||||
def parse(self):
|
||||
try:
|
||||
hdr = MINIDUMP_HEADER()
|
||||
hdr.parse(self.fd)
|
||||
|
||||
assert hdr.Signature == "MDMP"
|
||||
self.fd.seek(hdr.StreamDirectoryRva)
|
||||
|
||||
streamTbl = {3: self.__parse_threadlist__, \
|
||||
4: self.__parse_modulelist__, \
|
||||
6: self.__parse_exception_stream__, \
|
||||
7: self.__parse_systeminfo__, \
|
||||
9: self.__parse_memory_list64__, \
|
||||
16: self.__parse_memory_info__}
|
||||
streams = {}
|
||||
for i in range(0, hdr.NumberOfStreams):
|
||||
dirent = MINIDUMP_DIRECTORY()
|
||||
dirent.parse(self.fd)
|
||||
|
||||
streams[dirent.StreamType] = dirent
|
||||
|
||||
if not 7 in streams: raise Exception("No SYSTEM_INFO stream found...context will not work correctly!")
|
||||
|
||||
# it is important we parse SYSTEM_INFO first
|
||||
parse_order = streams.keys()
|
||||
parse_order.remove(7)
|
||||
parse_order = [7] + parse_order
|
||||
|
||||
for item in parse_order:
|
||||
dirent = streams[item]
|
||||
if dirent.StreamType in streamTbl:
|
||||
self.fd.seek(dirent.Location.Rva)
|
||||
streamTbl[dirent.StreamType](dirent)
|
||||
|
||||
finally:
|
||||
self.close()
|
||||
|
||||
def get_exception_info(self):
|
||||
return self.exception_info
|
||||
|
||||
def get_thread_by_tid(self, tid):
|
||||
for thread in self.threads:
|
||||
if thread.ThreadId == tid: return thread
|
||||
raise Exception("No thread of TID %d" % tid)
|
||||
|
||||
def get_register_context_by_tid(self, tid):
|
||||
thread = self.get_thread_by_tid(tid)
|
||||
return thread.getContext(self.architecture)
|
||||
|
||||
def get_threads(self):
|
||||
return self.threads
|
||||
|
||||
def get_version(self):
|
||||
return self.version
|
||||
|
||||
def get_architecture(self):
|
||||
return self.architecture
|
||||
|
||||
def get_system_info(self):
|
||||
return self.system_info
|
||||
|
||||
def get_module_map(self):
|
||||
return self.module_map
|
||||
|
||||
def get_register_context(self):
|
||||
return self.context
|
||||
|
||||
def get_memory_data(self):
|
||||
return self.memory_data
|
||||
|
||||
def get_memory_map(self):
|
||||
return self.memory_query
|
||||
|
||||
def close(self):
|
||||
if not self.fd is None:
|
||||
self.fd.close()
|
||||
self.fd = None
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ from .core.parser import parse
|
||||
from .core.state import State, TerminateState
|
||||
from .core.smtlib import solver, ConstraintSet
|
||||
from .core.workspace import ManticoreOutput, Workspace
|
||||
from .platforms import linux, decree, windows, evm
|
||||
from .platforms import linux, decree, evm
|
||||
from .utils.helpers import issymbolic, is_binja_disassembler
|
||||
from .utils.nointerrupt import WithKeyboardInterruptAs
|
||||
from .utils.event import Eventful
|
||||
@@ -103,48 +103,6 @@ def make_linux(program, argv=None, env=None, symbolic_files=None, concrete_start
|
||||
return initial_state
|
||||
|
||||
|
||||
def make_windows(args, programs, context, data, offset, maxsymb, workspace, size=None, buffer=None, **kwargs):
|
||||
assert args.size is not None, "Need to specify buffer size"
|
||||
assert args.buffer is not None, "Need to specify buffer base address"
|
||||
logger.debug('Loading program %s (platform: Windows)', args.argv)
|
||||
additional_context = None
|
||||
if args.context:
|
||||
with open(args.context, "r") as addl_context_file:
|
||||
additional_context = cPickle.loads(addl_context_file.read())
|
||||
logger.debug('Additional context loaded with contents {}'.format(additional_context)) #DEBUG
|
||||
|
||||
constraints = ConstraintSet()
|
||||
platform = windows.SWindows(constraints, args.argv[0], additional_context, snapshot_folder=args.workspace)
|
||||
|
||||
#This will interpret the buffer specification written in INTEL ASM. (It may dereference pointers)
|
||||
data_size = parse(args.size, platform.current.read_bytes, platform.current.read_register)
|
||||
data_ptr = parse(args.buffer, platform.current.read_bytes, platform.current.read_register)
|
||||
|
||||
logger.debug('Buffer at %x size %d bytes)', data_ptr, data_size)
|
||||
buf_str = "".join(platform.current.read_bytes(data_ptr, data_size))
|
||||
logger.debug('Original buffer: %s', buf_str.encode('hex'))
|
||||
|
||||
offset = args.offset
|
||||
concrete_data = args.data.decode('hex')
|
||||
assert data_size >= offset + len(concrete_data)
|
||||
size = min(args.maxsymb, data_size - offset - len(concrete_data))
|
||||
symb = constraints.new_array(name='RAWMSG', index_max=size)
|
||||
|
||||
platform.current.write_bytes(data_ptr + offset, concrete_data)
|
||||
platform.current.write_bytes(data_ptr + offset + len(concrete_data), [symb[i] for i in xrange(size)] )
|
||||
|
||||
logger.debug('First %d bytes are left concrete', offset)
|
||||
logger.debug('followed by %d bytes of concrete start', len(concrete_data))
|
||||
hex_head = "".join(platform.current.read_bytes(data_ptr, offset+len(concrete_data)))
|
||||
logger.debug('Hexdump head: %s', hex_head.encode('hex'))
|
||||
logger.debug('Total symbolic characters inserted: %d', size)
|
||||
logger.debug('followed by %d bytes of unmodified concrete bytes at end.', (data_size-offset-len(concrete_data))-size )
|
||||
hex_tail = "".join(map(chr, platform.current.read_bytes(data_ptr+offset+len(concrete_data)+size, data_size-(offset+len(concrete_data)+size))))
|
||||
logger.debug('Hexdump tail: %s', hex_tail.encode('hex'))
|
||||
logger.info("Starting PC is: {:08x}".format(platform.current.PC))
|
||||
|
||||
return State(constraints, platform)
|
||||
|
||||
def make_initial_state(binary_path, **kwargs):
|
||||
if 'disasm' in kwargs:
|
||||
if kwargs.get('disasm') == "binja-il":
|
||||
|
||||
@@ -1,913 +0,0 @@
|
||||
import cgcrandom
|
||||
import weakref
|
||||
import sys, os, struct
|
||||
from ..core.memory import Memory, MemoryException, SMemory32, Memory32
|
||||
from ..core.smtlib import Expression, Operators, solver
|
||||
# TODO use cpu factory
|
||||
from ..core.cpu.x86 import I386Cpu, I386StdcallAbi, Syscall
|
||||
from ..core.cpu.abstractcpu import Interruption, Syscall
|
||||
from ..core.state import ForkState, TerminateState
|
||||
from ..utils.helpers import issymbolic
|
||||
from ..platforms.platform import *
|
||||
|
||||
from ..binary.pe import minidump
|
||||
|
||||
from contextlib import closing
|
||||
import StringIO
|
||||
import logging
|
||||
import random
|
||||
from windows_syscalls import syscalls_num
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SyscallNotImplemented(TerminateState):
|
||||
def __init__(self, message):
|
||||
super(SyscallNotImplemented,self).__init__(message, testcase=True)
|
||||
|
||||
class RestartSyscall(Exception):
|
||||
pass
|
||||
|
||||
class Deadlock(Exception):
|
||||
pass
|
||||
|
||||
class SymbolicAPIArgument(Exception):
|
||||
pass
|
||||
|
||||
#FIXME Consider moving this to executor.state?
|
||||
def toStr(state, value):
|
||||
if issymbolic(value):
|
||||
minmax = solver.get_all_values(state.constraints, value, maxcnt=2, silent=True)
|
||||
if len(minmax) > 1:
|
||||
return '?'*(value.size/8) + ' ' + repr(minmax)
|
||||
else:
|
||||
value = minmax[0]
|
||||
return '{:08x}'.format(value)
|
||||
|
||||
class Windows(Platform):
|
||||
'''
|
||||
A simple Windows Operating System platform.
|
||||
This class emulates some Windows system calls
|
||||
'''
|
||||
|
||||
STATUS_SUCCESS = 0x0
|
||||
|
||||
|
||||
# handles are always 4 byte aligned
|
||||
LATEST_HANDLE = 0x10000
|
||||
REG_KEY_HANDLE = 0x13370
|
||||
|
||||
def NT_SUCCESS(self, code):
|
||||
return code < 0x80000000
|
||||
|
||||
def _mk_memory(self):
|
||||
return Memory32()
|
||||
|
||||
def __init__(self, path, additional_context = None, snapshot_folder=None, **kwargs):
|
||||
'''
|
||||
Builds a Windows OS platform
|
||||
'''
|
||||
super(Windows, self).__init__(path,**kwargs)
|
||||
self.clocks = 0
|
||||
self.files = []
|
||||
self.syscall_trace = []
|
||||
|
||||
#This should be moved to a "load_dump" or "load_state" function
|
||||
md = minidump.MiniDump(path)
|
||||
assert md.get_architecture() == "x86"
|
||||
|
||||
major, minor = map(int, md.version.split(' ')[0].split('.'))
|
||||
if major == 6:
|
||||
self.flavor = "Windows7SP%d"%minor
|
||||
if minor >= 2:
|
||||
self.flavor = "Windows8"
|
||||
if minor > 2:
|
||||
self.flavor = "Windows8.%d"%(minor-2)
|
||||
elif major == 10:
|
||||
self.flavor = "Windows10SP%d"%minor
|
||||
else:
|
||||
raise NotImplementedError("Windows version {}.{} not supported".format(major, minor))
|
||||
logger.info('Initializing %s platform', self.flavor)
|
||||
|
||||
# Setting up memory maps
|
||||
memory = self._mk_memory()
|
||||
data = md.get_memory_data()
|
||||
query = md.get_memory_map()
|
||||
|
||||
|
||||
if snapshot_folder is None:
|
||||
for addr in sorted(data.keys()):
|
||||
perms, size = query[addr]
|
||||
memory.mmap(addr&0xffffffff, size, perms, data_init=data[addr])
|
||||
else:
|
||||
filename = os.path.join(snapshot_folder, 'memory.bin')
|
||||
with open(filename, 'w+') as f:
|
||||
pos = 0
|
||||
for addr in sorted(data.keys()):
|
||||
perms, size = query[addr]
|
||||
if pos & 0xfff !=0:
|
||||
pos = (pos & ~0xfff )+0x1000
|
||||
f.seek( pos )
|
||||
f.write(data[addr])
|
||||
pos+=size
|
||||
|
||||
pos = 0
|
||||
for addr in sorted(data.keys()):
|
||||
perms, size = query[addr]
|
||||
if pos & 0xfff !=0:
|
||||
pos = (pos & ~0xfff )+0x1000
|
||||
memory.mmapFile(addr&0xffffffff, size, perms, filename, offset=pos)
|
||||
pos+=size
|
||||
|
||||
|
||||
if (additional_context and 'memory' in additional_context):
|
||||
for address, value in additional_context['memory'].iteritems():
|
||||
t = iter(value.encode('hex'))
|
||||
decoded = " ".join(a+b for a,b in zip(t, t))
|
||||
logger.info('Overwriting memory at {:#08x} with bytes {}'.format(address, decoded))
|
||||
try:
|
||||
memory.write(address, value)
|
||||
except MemoryException as e:
|
||||
logger.info('Memory overwrite failed: {}'.format(e))
|
||||
logger.info('Total memory used: %d bytes', sum([size for (_, size) in query.values()]))
|
||||
|
||||
selectedThreadId = md.get_threads()[0].ThreadId
|
||||
exc = md.get_exception_info()
|
||||
if exc is not None:
|
||||
selectedThreadId = exc.ThreadId
|
||||
|
||||
#Load threads and setup waiting lists
|
||||
self.running = []
|
||||
self.procs = []
|
||||
for thread in md.get_threads():
|
||||
cxt = md.get_register_context_by_tid(thread.ThreadId)
|
||||
#Let's just ignore all extra threads for now
|
||||
if selectedThreadId != thread.ThreadId:
|
||||
continue
|
||||
|
||||
cpu = I386Cpu(memory)
|
||||
cpu.EIP=cxt.Eip
|
||||
cpu.ESP=cxt.Esp
|
||||
cpu.EBP=cxt.Ebp
|
||||
cpu.EAX=cxt.Eax
|
||||
cpu.EBX=cxt.Ebx
|
||||
cpu.ECX=cxt.Ecx
|
||||
cpu.EDX=cxt.Edx
|
||||
cpu.ESI=cxt.Esi
|
||||
cpu.EDI=cxt.Edi
|
||||
cpu.FS=cxt.SegFs
|
||||
if (additional_context and 'registers' in additional_context):
|
||||
for name, value in additional_context['registers'].iteritems():
|
||||
setattr(cpu, name, value)
|
||||
logger.info('Overriding register {} with new value {:#x}'.format(name, value)) #DEBUG
|
||||
|
||||
# Setting up segmentation for FS
|
||||
cpu.set_descriptor(cpu.FS, thread.Teb, 0x4000, 'rw')
|
||||
|
||||
self.procs.append(cpu)
|
||||
if selectedThreadId == thread.ThreadId:
|
||||
self.running.append(self.procs.index(cpu))
|
||||
|
||||
|
||||
# open standard files stdin, stdout, stderr
|
||||
logger.info("Not Opening any file")
|
||||
|
||||
nprocs = len(self.procs)
|
||||
assert nprocs > 0
|
||||
assert len(self.running) == 1, "For now lets consider only one thread running"
|
||||
self._current = self.running[0]
|
||||
|
||||
#Install event forwarders
|
||||
for proc in self.procs:
|
||||
self.forward_events_from(proc)
|
||||
|
||||
|
||||
@property
|
||||
def _function_abi(self):
|
||||
return I386StdcallAbi(self.procs[0])
|
||||
|
||||
@property
|
||||
def current(self):
|
||||
return self.procs[self._current]
|
||||
|
||||
def __getstate__(self):
|
||||
state = super(Windows, self).__getstate__()
|
||||
state['clocks'] = self.clocks
|
||||
state['procs'] = self.procs
|
||||
state['current'] = self._current
|
||||
state['running'] = self.running
|
||||
state['syscall_trace'] = self.syscall_trace
|
||||
state['files'] = self.files
|
||||
state['flavor'] = self.flavor
|
||||
|
||||
return state
|
||||
|
||||
def __setstate__(self, state):
|
||||
"""
|
||||
:todo: some asserts
|
||||
:todo: fix deps? (last line)
|
||||
"""
|
||||
super(Windows, self).__setstate__(state)
|
||||
self.procs = state['procs']
|
||||
self._current = state['current']
|
||||
self.running = state['running']
|
||||
self.clocks = state['clocks']
|
||||
self.syscall_trace = state['syscall_trace']
|
||||
self.files = state['files']
|
||||
self.flavor = state['flavor']
|
||||
|
||||
#Install event forwarders
|
||||
for proc in self.procs:
|
||||
self.forward_events_from(proc)
|
||||
|
||||
def _read_string(self, cpu, buf):
|
||||
"""
|
||||
Reads a null terminated concrete buffer form memory
|
||||
:todo: FIX. move to cpu or memory
|
||||
"""
|
||||
filename = ""
|
||||
for i in xrange(0,1024):
|
||||
c = Operators.CHR(cpu.read_int(buf+i,8))
|
||||
if c == '\x00':
|
||||
break
|
||||
filename += c
|
||||
return filename
|
||||
|
||||
|
||||
def load(self, cpu, filename):
|
||||
'''
|
||||
Loads PE program in memory and prepares the initial CPU state and the stack.
|
||||
:param filename: pathname of the file to be executed.
|
||||
'''
|
||||
raise Exception("Not Implementes")
|
||||
|
||||
def _open(self, f):
|
||||
'''
|
||||
It opens a file on the given a file descriptor
|
||||
:rtype: int
|
||||
:param filename: pathname of the file to open.
|
||||
:param mode: file permissions mode.
|
||||
:return: a file description of the opened file.
|
||||
'''
|
||||
if None in self.files:
|
||||
fd = self.files.index(None)
|
||||
self.files[fd]=f
|
||||
else:
|
||||
fd = len(self.files)
|
||||
self.files.append(f)
|
||||
return fd
|
||||
|
||||
def _close(self, fd):
|
||||
'''
|
||||
Closes a file descriptor
|
||||
:rtype: int
|
||||
:param fd: the file descriptor to close.
|
||||
:return: C{0} on success.
|
||||
'''
|
||||
self.files[fd] = None
|
||||
|
||||
def _dup(self, fd):
|
||||
'''
|
||||
Duplicates a file descriptor
|
||||
:rtype: int
|
||||
:param fd: the file descriptor to close.
|
||||
:return: C{0} on success.
|
||||
'''
|
||||
return self._open(self.files[fd])
|
||||
|
||||
def _is_open(self, fd):
|
||||
return fd >= 0 and fd < len(self.files) and self.files[fd] is not None
|
||||
|
||||
def sysenter(self, cpu):
|
||||
'''
|
||||
32 bit dispatcher.
|
||||
:param cpu: current CPU.
|
||||
_terminate, transmit, receive, fdwait, allocate, deallocate and random
|
||||
'''
|
||||
if not cpu.EAX in syscalls_num[self.flavor]:
|
||||
raise SyscallNotImplemented("32 bit %s WINDOWS system call number %s (UNKNOWN) Not Implemented" % (self.flavor, cpu.EAX))
|
||||
|
||||
syscall_name = syscalls_num[self.flavor][cpu.EAX]
|
||||
if not hasattr(self, syscall_name):
|
||||
raise SyscallNotImplemented("32 bit %s WINDOWS system call number %s (%s) Not Implemented" % (self.flavor, cpu.EAX, syscall_name))
|
||||
func = getattr(self, syscall_name)
|
||||
|
||||
logger.debug("SYSCALL32: %s (nargs: %d)", func.func_name, func.func_code.co_argcount)
|
||||
nargs = func.func_code.co_argcount
|
||||
args = [ ]
|
||||
for i in range(nargs-1):
|
||||
args.append(cpu.read_int(cpu.EDX+(i+2)*4, 32))
|
||||
cpu.EAX = func(*args)
|
||||
|
||||
|
||||
def sched(self):
|
||||
''' Yield CPU.
|
||||
This will choose another process from the RUNNNIG list and change
|
||||
current running process. May give the same cpu if only one running
|
||||
proccess.
|
||||
'''
|
||||
if len(self.procs)>1:
|
||||
logger.info("SCHED:")
|
||||
logger.info("\tProcess: %r", self.procs)
|
||||
logger.info("\tRunning: %r", self.running)
|
||||
logger.info("\tCurrent cpu: %d", self._current)
|
||||
|
||||
if len(self.running) == 0:
|
||||
logger.info("None running checking if there is some process waiting for a timeout")
|
||||
assert len(self.running) != 0, "DEADLOCK!"
|
||||
|
||||
next_index = (self.running.index(self._current) + 1) % len(self.running)
|
||||
next = self.running[ next_index ]
|
||||
if len(self.procs) > 1:
|
||||
logger.info("\tTransfer control from process %d to %d", self._current, next)
|
||||
self._current = next
|
||||
|
||||
def execute(self):
|
||||
"""
|
||||
Execute one cpu instruction in the current thread (only one supported).
|
||||
:rtype: bool
|
||||
:return: C{True}
|
||||
|
||||
:todo: This is where we could implement a simple schedule.
|
||||
"""
|
||||
try:
|
||||
self.current.execute()
|
||||
self.clocks += 1
|
||||
if self.clocks % 10000 == 0:
|
||||
self.sched()
|
||||
except Syscall as e:
|
||||
try:
|
||||
e = None
|
||||
self.sysenter(self.current)
|
||||
except RestartSyscall:
|
||||
pass
|
||||
|
||||
return True
|
||||
|
||||
def NtWriteFile(self, FileHandle, Event, ApcRoutine, ApcContext, IoStatusBlock, Buffer, Length, ByteOffset, Key):
|
||||
logger.info("NtWriteFile(%s, %s, %s, %s, %s, %s, %s, %s, %s)",
|
||||
toStr(self, FileHandle),
|
||||
toStr(self, Event),
|
||||
toStr(self, ApcRoutine),
|
||||
toStr(self, ApcContext),
|
||||
toStr(self, IoStatusBlock),
|
||||
toStr(self, Buffer),
|
||||
toStr(self, Length),
|
||||
toStr(self, ByteOffset),
|
||||
toStr(self, Key))
|
||||
return Windows.STATUS_SUCCESS
|
||||
|
||||
def NtReleaseKeyedEvent(self, KeyedEventHandle, Key, Alertable, Timeout):
|
||||
logger.info("NtReleaseKeyedEvent(%s, %s, %s, %s)",
|
||||
toStr(self, KeyedEventHandle),
|
||||
toStr(self, Key),
|
||||
toStr(self, Alertable),
|
||||
toStr(self, Timeout))
|
||||
return Windows.STATUS_SUCCESS
|
||||
|
||||
def NtQueryPerformanceCounter(self, PerformanceCounter, PerformanceFrequency):
|
||||
""" PerformanceCounter and PerformanceFrequency are 64-bit integers"""
|
||||
|
||||
logger.info("NtQueryPerformanceCounter(%s, %s)",
|
||||
toStr(self, PerformanceCounter),
|
||||
toStr(self, PerformanceFrequency))
|
||||
|
||||
cpu = self.current
|
||||
cpu.write_int(PerformanceCounter, self.clocks, 64)
|
||||
if PerformanceFrequency:
|
||||
cpu.write_int(PerformanceFrequency, 1000, 64)
|
||||
|
||||
return Windows.STATUS_SUCCESS
|
||||
|
||||
def NtClose(self, Handle):
|
||||
|
||||
logger.info("NtClose(%s)", toStr(self, Handle))
|
||||
|
||||
return Windows.STATUS_SUCCESS
|
||||
|
||||
def NtFreeVirtualMemory(self, ProcessHandle, BaseAddress, RegionSize, FreeType):
|
||||
logger.info("""ZwFreeVirtualMemory(
|
||||
_In_ HANDLE ProcessHandle: {},
|
||||
_Inout_ PVOID *BaseAddress: {},
|
||||
_Inout_ PSIZE_T RegionSize: {},
|
||||
_In_ ULONG FreeType: {});""".format(
|
||||
toStr(self, ProcessHandle),
|
||||
toStr(self, BaseAddress),
|
||||
toStr(self, RegionSize),
|
||||
toStr(self, FreeType)))
|
||||
|
||||
return Windows.STATUS_SUCCESS
|
||||
|
||||
def _fileHandle(self, filename):
|
||||
""" Get a file handle for a file name, or return a new fake handle"""
|
||||
self.LATEST_HANDLE += 4
|
||||
return self.LATEST_HANDLE
|
||||
|
||||
def _getRegHandle(self, regkey):
|
||||
r = self.REG_KEY_HANDLE
|
||||
self.REG_KEY_HANDLE += 4
|
||||
return r
|
||||
|
||||
def NtOpenFile(self, FileHandle, DesiredAccess, ObjectAttributes, IoStatusBlock, ShareAccess, OpenOptions):
|
||||
|
||||
#TODO: extract name from ObjectAttributes
|
||||
|
||||
logger.info("""NtOpenFile(
|
||||
_Out_ PHANDLE FileHandle: {},
|
||||
_In_ ACCESS_MASK DesiredAccess: {},
|
||||
_In_ POBJECT_ATTRIBUTES ObjectAttributes: {},
|
||||
_Out_ PIO_STATUS_BLOCK IoStatusBlock: {},
|
||||
_In_ ULONG ShareAccess: {},
|
||||
_In_ ULONG OpenOptions: {});""".format(
|
||||
toStr(self, FileHandle),
|
||||
toStr(self, DesiredAccess),
|
||||
toStr(self, ObjectAttributes),
|
||||
toStr(self, IoStatusBlock),
|
||||
toStr(self, ShareAccess),
|
||||
toStr(self, OpenOptions)))
|
||||
|
||||
fh = self._fileHandle(None)
|
||||
self.current.write_int(FileHandle, fh, 32)
|
||||
|
||||
return Windows.STATUS_SUCCESS
|
||||
|
||||
|
||||
############################################################################
|
||||
# Symbolic versions follows
|
||||
|
||||
class SWindows(Windows):
|
||||
'''
|
||||
A symbolic extension of a Decree Operating System platform.
|
||||
'''
|
||||
def __init__(self, constraints, path, additional_context=None, snapshot_folder=None):
|
||||
'''
|
||||
Builds a symbolic extension of a Decree OS
|
||||
:param constraints: a constraints set.
|
||||
:param path: path to minidump to load.
|
||||
:param additional_context: optional object for overriding data read from minidump, e.g., initial register values.
|
||||
'''
|
||||
self._constraints = constraints
|
||||
super(SWindows, self).__init__(path, additional_context, snapshot_folder)
|
||||
|
||||
@property
|
||||
def constraints(self):
|
||||
return self._constraints
|
||||
|
||||
@constraints.setter
|
||||
def constraints(self, constraints):
|
||||
self._constraints = constraints
|
||||
for proc in self.procs:
|
||||
proc.memory.constraints = constraints
|
||||
|
||||
|
||||
def _mk_memory(self):
|
||||
return SMemory32(self.constraints)
|
||||
|
||||
#marshaling/pickle
|
||||
def __getstate__(self):
|
||||
state = super(SWindows, self).__getstate__()
|
||||
state['constraints'] = self.constraints
|
||||
return state
|
||||
|
||||
def __setstate__(self, state):
|
||||
self._constraints = state['constraints']
|
||||
super(SWindows, self).__setstate__(state)
|
||||
|
||||
def readStringFromPointer(state, cpu, ptr, utf16, max_symbols=8):
|
||||
|
||||
if issymbolic(ptr):
|
||||
ptrs = solver.get_all_values(state.constraints, ptr, maxcnt=2, silent=True)
|
||||
if len(ptrs) == 1:
|
||||
ptr = ptrs[0]
|
||||
else:
|
||||
raise SymbolicAPIArgument()
|
||||
|
||||
if ptr == 0:
|
||||
# this happens a lot, just handle it
|
||||
return ""
|
||||
|
||||
concrete_str = ""
|
||||
i = 0
|
||||
|
||||
if utf16:
|
||||
width = 16
|
||||
else:
|
||||
width = 8
|
||||
|
||||
while True:
|
||||
# read a char
|
||||
value = cpu.read_int(ptr+i, width)
|
||||
|
||||
# ooh, a symbolic char
|
||||
if issymbolic(value):
|
||||
# how symbolic is it?
|
||||
vals = solver.get_all_values(state.constraints, value, maxcnt=max_symbols, silent=True)
|
||||
if len(vals) == 1:
|
||||
# effectively concrete
|
||||
value = vals[0]
|
||||
if value == 0:
|
||||
break
|
||||
concrete_str += Operators.CHR(value)
|
||||
elif len(vals) < max_symbols:
|
||||
concrete_str += '?'
|
||||
else:
|
||||
# this could be a bug!
|
||||
msg = "Detected Symbolic String (prefix: {})".format(concrete_str)
|
||||
raise MemoryException(msg, 0xFFFFFFFF)
|
||||
# if its null, bail
|
||||
elif value == 0:
|
||||
break
|
||||
else:
|
||||
concrete_str += Operators.CHR(value)
|
||||
|
||||
i += (width/8)
|
||||
|
||||
return concrete_str
|
||||
|
||||
class ntdll(object):
|
||||
|
||||
@staticmethod
|
||||
def NtWriteFile(platform, FileHandle, Event, ApcRoutine, ApcContext, IoStatusBlock, Buffer, Length, ByteOffset, Key):
|
||||
return platform.NtWriteFile(FileHandle, Event, ApcRoutine, ApcContext, IoStatusBlock, Buffer, Length, ByteOffset, Key)
|
||||
|
||||
@staticmethod
|
||||
def NtReleaseKeyedEvent(platform, KeyedEventHandle, Key, Alertable, Timeout):
|
||||
return platform.NtReleaseKeyedEvent(KeyedEventHandle, Key, Alertable, Timeout)
|
||||
|
||||
@staticmethod
|
||||
def NtQueryPerformanceCounter(platform, PerformanceCounter, PerformanceFrequency):
|
||||
return platform.NtQueryPerformanceCounter(PerformanceCounter, PerformanceFrequency)
|
||||
|
||||
@staticmethod
|
||||
def NtClose(platform, Handle):
|
||||
return platform.NtClose(Handle)
|
||||
|
||||
@staticmethod
|
||||
def RtlAllocateHeap(platform, handle, flags, size):
|
||||
if issymbolic(size):
|
||||
logger.info("RtlAllcoateHeap({}, {}, SymbolicSize); concretizing size".format(str(handle), str(flags)) )
|
||||
raise ConcretizeArgument(platform.current, 2)
|
||||
else:
|
||||
raise IgnoreAPI("RtlAllocateHeap({}, {}, {:08x})".format(str(handle), str(flags), size))
|
||||
|
||||
@staticmethod
|
||||
def RtlpReportHeapFailure(platform):
|
||||
raise MemoryException("Heap Failure Detected via RtlpReportHeapFailure!", 0xFFFFFFFF)
|
||||
|
||||
@staticmethod
|
||||
def RtlpLogHeapFailure(platform):
|
||||
raise MemoryException("Heap Failure Detected via RtlpLogHeapFailure!", 0xFFFFFFFE)
|
||||
|
||||
|
||||
class kernel32(object):
|
||||
|
||||
@staticmethod
|
||||
def RegOpenKeyExW(platform, hKey, lpSubKey, ulOptions, samDesired, phkResult):
|
||||
return kernel32._RegOpenKeyEx(platform, True, hKey, lpSubKey, ulOptions, samDesired, phkResult)
|
||||
|
||||
@staticmethod
|
||||
def RegOpenKeyExA(platform, hKey, lpSubKey, ulOptions, samDesired, phkResult):
|
||||
return kernel32._RegOpenKeyEx(platform, False, hKey, lpSubKey, ulOptions, samDesired, phkResult)
|
||||
|
||||
@staticmethod
|
||||
def _RegOpenKeyEx(platform, utf16, hKey, lpSubKey, ulOptions, samDesired, phkResult):
|
||||
"""LONG WINAPI RegOpenKeyEx(
|
||||
_In_ HKEY hKey,
|
||||
_In_opt_ LPCTSTR lpSubKey,
|
||||
_In_ DWORD ulOptions,
|
||||
_In_ REGSAM samDesired,
|
||||
_Out_ PHKEY phkResult
|
||||
);
|
||||
Detect symbolic registry access. Attempt to simulate fake registry opening """
|
||||
|
||||
cpu = platform.current
|
||||
myname = "RegOpenKeyEx{}".format(utf16 and "W" or "A")
|
||||
|
||||
try:
|
||||
key_str = readStringFromPointer(platform, cpu, lpSubKey, utf16)
|
||||
except MemoryException as me:
|
||||
raise MemoryException("{}: {}".format(myname, me.message), 0xFFFFFFFF)
|
||||
except SymbolicAPIArgument:
|
||||
raise ConcretizeArgument(platform.current, 1)
|
||||
|
||||
logger.info("{}({}, [{}], {}, {}, {})".format(
|
||||
myname,
|
||||
str(hKey), key_str, str(ulOptions), str(samDesired),
|
||||
str(phkResult)))
|
||||
|
||||
if issymbolic(phkResult):
|
||||
|
||||
#Check if the symbol has a single solution.
|
||||
values = solver.get_all_values(platform.constraints, phkResult, maxcnt=2, silent=True)
|
||||
if len(values) == 1:
|
||||
phkResult = values[0]
|
||||
|
||||
if issymbolic(phkResult):
|
||||
|
||||
if solver.can_be_true(platform.constraints, phkResult==0):
|
||||
raise ForkState(phkResult==0)
|
||||
else:
|
||||
cpu.write_int(phkResult, platform._getRegHandle(key_str), 32)
|
||||
return 0
|
||||
|
||||
elif phkResult != 0:
|
||||
cpu.write_int(phkResult, platform._getRegHandle(key_str), 32)
|
||||
return 0
|
||||
else:
|
||||
raise IgnoreAPI("{}({}, [{}], {}, {}, {})".format(myname,
|
||||
str(hKey), key_str, str(ulOptions), str(samDesired),
|
||||
str(phkResult)))
|
||||
|
||||
@staticmethod
|
||||
def RegCreateKeyExW(platform, hkey, lpSubKey, Reserved, lpClass, dwOptions,
|
||||
samDesired, lpSecurityAttributes, phkResult, lpdwDisposition):
|
||||
return kernel32._RegCreateKeyEx(platform, True, hkey, lpSubKey, Reserved, lpClass, dwOptions,
|
||||
samDesired, lpSecurityAttributes, phkResult, lpdwDisposition)
|
||||
|
||||
@staticmethod
|
||||
def RegCreateKeyExA(platform, hkey, lpSubKey, Reserved, lpClass, dwOptions,
|
||||
samDesired, lpSecurityAttributes, phkResult, lpdwDisposition):
|
||||
return kernel32._RegCreateKeyEx(platform, False, hkey, lpSubKey, Reserved, lpClass, dwOptions,
|
||||
samDesired, lpSecurityAttributes, phkResult, lpdwDisposition)
|
||||
|
||||
@staticmethod
|
||||
def _RegCreateKeyEx(platform, utf16, hKey, lpSubKey, Reserved, lpClass, dwOptions,
|
||||
samDesired, lpSecurityAttributes, phkResult, lpdwDisposition):
|
||||
""" LONG WINAPI RegCreateKeyEx(
|
||||
_In_ HKEY hKey,
|
||||
_In_ LPCTSTR lpSubKey,
|
||||
_Reserved_ DWORD Reserved,
|
||||
_In_opt_ LPTSTR lpClass,
|
||||
_In_ DWORD dwOptions,
|
||||
_In_ REGSAM samDesired,
|
||||
_In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
|
||||
_Out_ PHKEY phkResult,
|
||||
_Out_opt_ LPDWORD lpdwDisposition
|
||||
);"""
|
||||
cpu = platform.current
|
||||
myname = "RegCreateKeyEx{}".format(utf16 and "W" or "A")
|
||||
|
||||
try:
|
||||
key_str = readStringFromPointer(platform, cpu, lpSubKey, utf16)
|
||||
except MemoryException as me:
|
||||
raise MemoryException("{}: {}".format(myname, me.message), 0xFFFFFFFF)
|
||||
except SymbolicAPIArgument:
|
||||
raise ConcretizeArgument(platform.current, 1)
|
||||
|
||||
logger.info("{}({}, [{}], {}, {}, {}, {}, {}, {}, {})".format(myname,
|
||||
str(hKey), key_str, str(Reserved), str(lpClass), str(dwOptions),
|
||||
str(lpSecurityAttributes), str(samDesired), str(phkResult), str(lpdwDisposition)))
|
||||
|
||||
if issymbolic(phkResult):
|
||||
|
||||
#Check if the symbol has a single solution.
|
||||
values = solver.get_all_values(platform.constraints, phkResult, maxcnt=2, silent=True)
|
||||
if len(values) == 1:
|
||||
phkResult = values[0]
|
||||
|
||||
if issymbolic(phkResult):
|
||||
|
||||
if solver.can_be_true(platform.constraints, phkResult==0):
|
||||
raise ForkState(phkResult==0)
|
||||
else:
|
||||
cpu.write_int(phkResult, platform._getRegHandle(key_str), 32)
|
||||
return 0
|
||||
|
||||
elif phkResult != 0:
|
||||
cpu.write_int(phkResult, platform._getRegHandle(key_str), 32)
|
||||
return 0
|
||||
else:
|
||||
raise IgnoreAPI("{}({}, [{}], {}, {}, {}, {}, {}, {}, {})".format(myname,
|
||||
str(hKey), key_str, str(Reserved), str(lpClass), str(dwOptions),
|
||||
str(lpSecurityAttributes), str(samDesired), str(phkResult), str(lpdwDisposition)))
|
||||
|
||||
@staticmethod
|
||||
def HeapAlloc(platform, handle, flags, size):
|
||||
ntdll.RtlAllocateHeap(platform, handle, flags, size)
|
||||
|
||||
# TODO: move this to Windows class if we ever
|
||||
# implement a real handle table
|
||||
@staticmethod
|
||||
def GetStdHandle(platform, nStdHandle):
|
||||
logger.info("GetStdHandle(%x)", nStdHandle)
|
||||
# ignore nStdHandle -- just return a valid value
|
||||
STD_INPUT_HANDLE = -10
|
||||
STD_OUTPUT_HANDLE = -11
|
||||
STD_ERROR_HANDLE = -12
|
||||
|
||||
if issymbolic(nStdHandle):
|
||||
|
||||
#Check if the symbol has a single solution.
|
||||
values = solver.get_all_values(platform.constraints, nStdHandle, maxcnt=2, silent=True)
|
||||
if len(values) == 1:
|
||||
nStdHandle = values[0]
|
||||
else:
|
||||
#potentially multiple values. Fork on each one.
|
||||
if nStdHandle.solver.canBe(nStdHandle, STD_INPUT_HANDLE):
|
||||
raise ForkState(nStdHandle==STD_INPUT_HANDLE)
|
||||
|
||||
if nStdHandle.solver.canBe(nStdHandle, STD_OUTPUT_HANDLE):
|
||||
raise ForkState(nStdHandle==STD_OUTPUT_HANDLE)
|
||||
|
||||
if nStdHandle.solver.canBe(nStdHandle, STD_ERROR_HANDLE):
|
||||
raise ForkState(nStdHandle==STD_ERROR_HANDLE)
|
||||
#here nStdHandle is symbolic and not in [ STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, STD_ERROR_HANDLE ]
|
||||
#Symbolic value can be different from all STD_..._HANDLE
|
||||
return -1 # INVALID_HANDLE_VALUE
|
||||
|
||||
elif nStdHandle == STD_INPUT_HANDLE:
|
||||
return 0xFF4 # arbitrary valid handle
|
||||
elif nStdHandle == STD_OUTPUT_HANDLE:
|
||||
return 0xFF8 # arbitrary valid handle
|
||||
elif nStdHandle == STD_ERROR_HANDLE:
|
||||
return 0xFFC # arbitrary valid handle
|
||||
else:
|
||||
return -1 #INVALID_HANDLE_VALUE
|
||||
|
||||
@staticmethod
|
||||
def CloseHandle(platform, hObject):
|
||||
logger.info("CloseHandle(%x)", hObject)
|
||||
if platform.NT_SUCCESS(platform.NtClose(hObject)):
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
# TODO: possibly implement using NtCreateFile and/or use a handle table
|
||||
@staticmethod
|
||||
def CreateFileW(platform, lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile):
|
||||
return kernel32._CreateFile(platform, True, lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile)
|
||||
|
||||
@staticmethod
|
||||
def CreateFileA(platform, lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile):
|
||||
return kernel32._CreateFile(platform, False, lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile)
|
||||
|
||||
@staticmethod
|
||||
def _CreateFile(platform, utf16, lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile):
|
||||
'''https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx'''
|
||||
|
||||
cpu = platform.current
|
||||
try:
|
||||
filename = readStringFromPointer(platform, cpu, lpFileName, utf16)
|
||||
except MemoryException as me:
|
||||
msg = "CreateFile{}: {}".format(utf16 and "W" or "A", me.message)
|
||||
raise MemoryException(msg, 0xFFFFFFFF)
|
||||
except SymbolicAPIArgument:
|
||||
raise ConcretizeArgument(platform.current, 0)
|
||||
|
||||
|
||||
logger.info("""CreateFile%s(
|
||||
_In_ LPCTSTR lpFileName: [%s],
|
||||
_In_ DWORD dwDesiredAccess: %s,
|
||||
_In_ DWORD dwShareMode: %s,
|
||||
_In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes: %s,
|
||||
_In_ DWORD dwCreationDisposition: %s,
|
||||
_In_ DWORD dwFlagsAndAttributes: %s,
|
||||
_In_opt_ HANDLE hTemplateFile: %s
|
||||
);""" % (utf16 and "W" or "A",
|
||||
filename,
|
||||
toStr(platform, dwDesiredAccess),
|
||||
toStr(platform, dwShareMode),
|
||||
toStr(platform, lpSecurityAttributes),
|
||||
toStr(platform, dwCreationDisposition),
|
||||
toStr(platform, dwFlagsAndAttributes),
|
||||
toStr(platform, hTemplateFile),))
|
||||
|
||||
cpu = platform.current
|
||||
|
||||
return platform._fileHandle(lpFileName)
|
||||
|
||||
#TODO possibly implement via NtWriteFile
|
||||
@staticmethod
|
||||
def WriteFile(platform, hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped):
|
||||
'''https://msdn.microsoft.com/en-us/library/windows/desktop/aa365747(v=vs.85).aspx'''
|
||||
logger.info("""WriteFile(
|
||||
_In_ HANDLE hFile: %s,
|
||||
_In_ LPCVOID lpBuffer: %s,
|
||||
_In_ DWORD nNumberOfBytesToWrite: %s,
|
||||
_Out_opt_ LPDWORD lpNumberOfBytesWritten: %s,
|
||||
_Inout_opt_ LPOVERLAPPED lpOverlapped: %s
|
||||
);"""%(
|
||||
toStr(platform, hFile),
|
||||
toStr(platform, lpBuffer),
|
||||
toStr(platform, nNumberOfBytesToWrite),
|
||||
toStr(platform, lpNumberOfBytesWritten),
|
||||
toStr(platform, lpOverlapped))
|
||||
)
|
||||
|
||||
if issymbolic(lpNumberOfBytesWritten):
|
||||
|
||||
#Check if the symbol has a single solution.
|
||||
values = solver.get_all_values(platform.constraints, lpNumberOfBytesWritten, maxcnt=2, silent=True)
|
||||
if len(values) == 1:
|
||||
logger.info("ONE VALUE lpNumberOfBytesWritten: {}".format(lpNumberOfBytesWritten))
|
||||
lpNumberOfBytesWritten = values[0]
|
||||
|
||||
cpu = platform.current
|
||||
if issymbolic(lpNumberOfBytesWritten):
|
||||
|
||||
if solver.can_be_true(platform.constraints, lpNumberOfBytesWritten==0):
|
||||
raise ForkState(lpNumberOfBytesWritten==0)
|
||||
|
||||
logger.info("WRITING TO SYMB lpNumberOfBytesWritten: {}".format(lpNumberOfBytesWritten))
|
||||
cpu.write_int(lpNumberOfBytesWritten, nNumberOfBytesToWrite, 32)
|
||||
|
||||
elif lpNumberOfBytesWritten != 0:
|
||||
cpu.write_int(lpNumberOfBytesWritten, nNumberOfBytesToWrite, 32)
|
||||
|
||||
return 1
|
||||
|
||||
@staticmethod
|
||||
def CreateProcessW(platform, lpApplicationName, lpCommandLine, lpProcessAttributes,
|
||||
lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
|
||||
lpCurrentDirectory, lpStartupInfo, lpProcessInformation):
|
||||
return kernel32._CreateProcess(platform, True, lpApplicationName, lpCommandLine, lpProcessAttributes,
|
||||
lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
|
||||
lpCurrentDirectory, lpStartupInfo, lpProcessInformation)
|
||||
|
||||
@staticmethod
|
||||
def CreateProcessA(platform, lpApplicationName, lpCommandLine, lpProcessAttributes,
|
||||
lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
|
||||
lpCurrentDirectory, lpStartupInfo, lpProcessInformation):
|
||||
return kernel32._CreateProcess(platform, False, lpApplicationName, lpCommandLine, lpProcessAttributes,
|
||||
lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
|
||||
lpCurrentDirectory, lpStartupInfo, lpProcessInformation)
|
||||
|
||||
@staticmethod
|
||||
def _CreateProcess(platform, utf16, lpApplicationName, lpCommandLine, lpProcessAttributes,
|
||||
lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
|
||||
lpCurrentDirectory, lpStartupInfo, lpProcessInformation):
|
||||
"""BOOL WINAPI CreateProcess(
|
||||
_In_opt_ LPCTSTR lpApplicationName,
|
||||
_Inout_opt_ LPTSTR lpCommandLine,
|
||||
_In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
|
||||
_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||
_In_ BOOL bInheritHandles,
|
||||
_In_ DWORD dwCreationFlags,
|
||||
_In_opt_ LPVOID lpEnvironment,
|
||||
_In_opt_ LPCTSTR lpCurrentDirectory,
|
||||
_In_ LPSTARTUPINFO lpStartupInfo,
|
||||
_Out_ LPPROCESS_INFORMATION lpProcessInformation
|
||||
);"""
|
||||
|
||||
myname = "CreateProcess{}".format(utf16 and "W" or "A")
|
||||
cpu = platform.current
|
||||
|
||||
try:
|
||||
appname = readStringFromPointer(platform, cpu, lpApplicationName, utf16)
|
||||
except MemoryException as me:
|
||||
msg = "{}: {}".format(myname, me.message)
|
||||
raise MemoryException(msg, 0xFFFFFFFF)
|
||||
except SymbolicAPIArgument:
|
||||
raise ConcretizeArgument(platform.current, 0)
|
||||
|
||||
try:
|
||||
cmdline = readStringFromPointer(platform, cpu, lpCommandLine, utf16)
|
||||
except MemoryException as me:
|
||||
msg = "{}: {}".format(myname, me.message)
|
||||
raise MemoryException(msg, 0xFFFFFFFF)
|
||||
except SymbolicAPIArgument:
|
||||
raise ConcretizeArgument(platform.current, 1)
|
||||
|
||||
raise IgnoreAPI("{}([{}], [{}], {}, {}, {}, {}, {}, {}, {}, {})".format(myname,
|
||||
appname, cmdline, str(lpProcessAttributes),
|
||||
str(lpThreadAttributes), str(bInheritHandles), str(dwCreationFlags), str(lpEnvironment),
|
||||
str(lpCurrentDirectory), str(lpStartupInfo), str(lpProcessInformation)))
|
||||
|
||||
class KERNELBASE(kernel32):
|
||||
#has the same functions as kernel32, needed for windows forward exports
|
||||
# and namespacing
|
||||
pass
|
||||
|
||||
def Ignore0(self):
|
||||
cpu = self.current
|
||||
logger.info('Ignore0 at %x No arguments', cpu.PC)
|
||||
return 1
|
||||
|
||||
def Ignore1(self, arg1):
|
||||
cpu = self.current
|
||||
logger.info('Ignore1 at %x Arguments(%x)', cpu.PC, arg1)
|
||||
return 1
|
||||
|
||||
def Ignore2(self, arg1, arg2):
|
||||
cpu = self.current
|
||||
logger.info('Ignore2 at %x Arguments(%x, %x)', cpu.PC, arg1, arg2)
|
||||
return 1
|
||||
|
||||
def Ignore3(self, arg1, arg2, arg3):
|
||||
cpu = self.current
|
||||
logger.info('Ignore3 at %x Arguments(%x, %x, %x)', cpu.PC, arg1, arg2, arg3)
|
||||
return 1
|
||||
|
||||
def Ignore4(self, arg1, arg2, arg3, arg4):
|
||||
cpu = self.current
|
||||
logger.info('Ignore4 at %x Arguments(%x, %x, %x, %x)', cpu.PC, arg1, arg2, arg3, arg4)
|
||||
return 1
|
||||
|
||||
def Ignore5(self, arg1, arg2, arg3, arg4, arg5):
|
||||
cpu = self.current
|
||||
logger.info('Ignore5 at %x Arguments(%x, %x, %x, %x, %x)', cpu.PC, arg1, arg2, arg3, arg4, arg5)
|
||||
return 1
|
||||
|
||||
def Ignore6(self, arg1, arg2, arg3, arg4, arg5, arg6):
|
||||
cpu = self.current
|
||||
logger.info('Ignore6 at %x Arguments(%x, %x, %x, %x, %x, %x)', cpu.PC, arg1, arg2, arg3, arg4, arg5, arg6)
|
||||
return 1
|
||||
File diff suppressed because it is too large
Load Diff
@@ -45,13 +45,6 @@ if osname == "darwin" or osname.startswith("linux"):
|
||||
mmap = _mmap
|
||||
munmap = _munmap
|
||||
|
||||
elif osname == "win32":
|
||||
def _mmap(fd, offset, size):
|
||||
return MMAP.mmap(fd, size, offset=offset, access=MMAP.ACCESS_COPY)
|
||||
def _munmap(address, size):
|
||||
pass
|
||||
mmap = _mmap
|
||||
munmap = _munmap
|
||||
else:
|
||||
raise ValueError("Unsupported host OS: " + osname)
|
||||
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
Buffer: 0x00403018
|
||||
Length: 0x2E
|
||||
|
||||
python SymbolicExecutor/main.py --procs 1 --offset 0 --workspace apiint --buffer "0x00403018" --size "0x2E" tests/api_interception/api_interception.dmp --names tests/api_interception/api_names.txt --log apiint/manticore.log
|
||||
@@ -1,56 +0,0 @@
|
||||
// ConsoleApplication1.cpp : Defines the entry point for the console application.
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include <Windows.h>
|
||||
|
||||
//TCHAR buffer[] = _T("PC:\\windows\\notepad.exe");
|
||||
TCHAR buffer[] = _T("ZC:\\winodws\\notepad.exe");
|
||||
|
||||
int _tmain(int argc, _TCHAR* argv[])
|
||||
{
|
||||
__debugbreak();
|
||||
|
||||
TCHAR *buf = buffer;
|
||||
TCHAR op = buf[0];
|
||||
HKEY testkey = NULL;
|
||||
LSTATUS st = RegCreateKeyEx(HKEY_CURRENT_USER, L"Test", 0, NULL, 0, KEY_WRITE, NULL, &testkey, 0);
|
||||
if(st != ERROR_SUCCESS || testkey == NULL ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch(op) {
|
||||
case L'P':
|
||||
{
|
||||
PROCESS_INFORMATION psi;
|
||||
STARTUPINFO si;
|
||||
ZeroMemory(&si, sizeof(si));
|
||||
si.cb = sizeof(si);
|
||||
BOOL worked = CreateProcess(NULL, buf+1, NULL, NULL, FALSE, 0, NULL, NULL, &si, &psi);
|
||||
if(worked) {
|
||||
CloseHandle(psi.hThread);
|
||||
CloseHandle(psi.hProcess);
|
||||
}
|
||||
}
|
||||
case L'R':
|
||||
{
|
||||
HKEY key = NULL;
|
||||
LSTATUS s = RegOpenKeyEx(HKEY_CURRENT_USER, buf+1, 0, KEY_READ, &key);
|
||||
if(s == ERROR_SUCCESS && key != NULL) {
|
||||
RegCloseKey(key);
|
||||
}
|
||||
}
|
||||
case L'K':
|
||||
{
|
||||
HKEY key = NULL;
|
||||
LSTATUS s = RegCreateKeyEx(testkey, buf+1, 0, NULL, 0, KEY_WRITE, NULL, &key, 0);
|
||||
if(s == ERROR_SUCCESS && key != NULL) {
|
||||
RegCloseKey(key);
|
||||
}
|
||||
}
|
||||
default:
|
||||
printf("Unknown argument: %C\n", op);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -1,3 +0,0 @@
|
||||
0x754d204d stdcall windows.kernel32.CreateProcessW
|
||||
0x7551c189 stdcall windows.kernel32.RegOpenKeyExW
|
||||
0x75510d25 stdcall windows.kernel32.RegCreateKeyExW
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"--offset": "0",
|
||||
"--buffer": "0x00403018",
|
||||
"--size": "0x2E",
|
||||
"--procs": "1",
|
||||
"--names": "{dumpdir}/api_names.txt",
|
||||
"dump": "api_interception.dmp",
|
||||
"actual": "visited.txt",
|
||||
"expected": "api_interception_test_visited.txt"
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
How to run the test:
|
||||
|
||||
python SymbolicExecutor/main.py --replay tests/follow_trace/trace.log --offset 0 --workspace test --buffer "DWORD PTR [EBP-0x28]" --size "0x20" tests/follow_trace/simple_buffer_overflow.dmp
|
||||
Binary file not shown.
@@ -1,17 +0,0 @@
|
||||
How to run the test:
|
||||
|
||||
|
||||
No ignore APIs:
|
||||
python SymbolicExecutor/main.py --offset 0 --workspace test --buffer "DWORD PTR [EBP-0x28]" --size "0x20" tests/ignore_an_api/ignore_an_api.dmp
|
||||
|
||||
Ignore APIs:
|
||||
python SymbolicExecutor/main.py --offset 0 --workspace test --buffer "DWORD PTR [EBP-0x28]" --size "0x20" tests/ignore_an_api/ignore_an_api.dmp --names tests/ignore_an_api/api_names.txt --log tests/manticore.log
|
||||
|
||||
|
||||
APIs to Ignore:
|
||||
KERNELBASE!CloseHandle: 75438d60
|
||||
|
||||
Optional APIs (can ignore or not ignore):
|
||||
KERNELBASE!GetStdHandle: 75445190
|
||||
|
||||
76edc6b0 stdcall windows.ntdll.RtlFreeHeap
|
||||
@@ -1,3 +0,0 @@
|
||||
0x75438d60 stdcall windows.kernel32.CloseHandle
|
||||
0x75445190 stdcall windows.kernel32.GetStdHandle
|
||||
0x76edc6b0 stdcall windows.ntdll.RtlFreeHeap
|
||||
@@ -1,60 +0,0 @@
|
||||
// Exactly like the 'Simple Buffer Overflow' example
|
||||
// but with a CloseHandle call that must be ignored
|
||||
// to trigger the bug
|
||||
|
||||
// build with: cl /Fe:ignore_an_api.exe ignore_an_api.cpp
|
||||
|
||||
|
||||
#pragma once
|
||||
#include <tchar.h>
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
|
||||
typedef struct {
|
||||
DWORD a;
|
||||
DWORD b;
|
||||
DWORD c;
|
||||
VOID(*d)(VOID);
|
||||
} ITEM, *PITEM;
|
||||
|
||||
VOID greetings(VOID)
|
||||
{
|
||||
printf("Hello, world!\n");
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
PITEM pItem = NULL;
|
||||
DWORD dwBytesRead = 0;
|
||||
char buffer[32] = { 0 };
|
||||
|
||||
pItem = (PITEM)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pItem));
|
||||
if (!pItem) {
|
||||
printf("Failed to allocate memory\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
pItem->d = greetings;
|
||||
|
||||
if (!ReadFile(GetStdHandle(STD_INPUT_HANDLE), &buffer, 32, &dwBytesRead, NULL)) {
|
||||
printf("Failed to read STDIN\n");
|
||||
HeapFree(GetProcessHeap(), 0, pItem);
|
||||
return -1;
|
||||
}
|
||||
|
||||
strcpy((char *) pItem, buffer);
|
||||
// debug break to make taking memory dumps easier
|
||||
__debugbreak();
|
||||
|
||||
|
||||
if (pItem->d) {
|
||||
CloseHandle(GetStdHandle(STD_INPUT_HANDLE));
|
||||
pItem->d();
|
||||
}
|
||||
|
||||
if (pItem) {
|
||||
HeapFree(GetProcessHeap(), 0, pItem);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -1,3 +0,0 @@
|
||||
How to run the test:
|
||||
|
||||
python SymbolicExecutor/main.py --offset 0 --workspace test --buffer "EBP-4" --size "4" tests/index_code/index_code.dmp
|
||||
@@ -1,49 +0,0 @@
|
||||
// compile with
|
||||
// cl /Fe:index_code.exe index_code.c
|
||||
//
|
||||
// make memory dump with:
|
||||
// .dump /ma index_code.dmp
|
||||
//
|
||||
#include <stdio.h>
|
||||
|
||||
typedef int(*my_callback)(int);
|
||||
|
||||
int say_zero(int a) {
|
||||
printf("entry zero");
|
||||
return a;
|
||||
}
|
||||
int say_one(int a) {
|
||||
printf("entry one");
|
||||
return a;
|
||||
}
|
||||
int say_two(int a) {
|
||||
printf("entry two");
|
||||
return a;
|
||||
}
|
||||
int say_three(int a) {
|
||||
printf("entry three");
|
||||
return a;
|
||||
}
|
||||
|
||||
my_callback table[] = {
|
||||
say_zero,
|
||||
say_one,
|
||||
say_two,
|
||||
say_three};
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
int index = 0;
|
||||
printf("reading an index: ");
|
||||
scanf("%d", &index);
|
||||
// break for windbg
|
||||
__debugbreak();
|
||||
if(index > (int)(sizeof(table)/sizeof(table[0]))) {
|
||||
printf("Invalid index\n");
|
||||
} else {
|
||||
my_callback out = table[index];
|
||||
out(index);
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
Binary file not shown.
@@ -1,3 +0,0 @@
|
||||
How to run the test:
|
||||
|
||||
python SymbolicExecutor/main.py --offset 0 --workspace index_data --buffer "EBP-4" --size "4" tests/index_data/index_data.dmp
|
||||
@@ -1,25 +0,0 @@
|
||||
// compile with
|
||||
// cl /Fe:index_data.exe index_data.c
|
||||
//
|
||||
// make memory dump with:
|
||||
// .dump /ma index_data.dmp
|
||||
//
|
||||
#include <stdio.h>
|
||||
|
||||
const char *table[] = {
|
||||
"entry zero",
|
||||
"entry one",
|
||||
"entry two",
|
||||
"entry three"};
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
int index = 0;
|
||||
printf("reading an index: ");
|
||||
scanf("%d", &index);
|
||||
// break for windbg
|
||||
__debugbreak();
|
||||
const char *out = table[index];
|
||||
printf("output is: %s\n", out);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,8 +0,0 @@
|
||||
Run manticore on the Linux version of the Palindrome CB
|
||||
|
||||
Manticore's API interception skips expensive initiailzation that otherwise takes hours to emulate.
|
||||
|
||||
|
||||
Execute via:
|
||||
|
||||
python SymbolicExecutor/main.py --procs 4 --workspace palindrome_test --log palindrome_test/manticore.log tests/linux_palindrome/Palindrome --names tests/linux_palindrome/api_names.txt
|
||||
@@ -1,2 +0,0 @@
|
||||
0x08049cb0 cdecl linux.DecreeEmu.cgc_initialize_secret_page
|
||||
0x08049c50 cdecl linux.DecreeEmu.cgc_random
|
||||
@@ -1,3 +0,0 @@
|
||||
How to run the test:
|
||||
|
||||
python SymbolicExecutor/main.py --policy dicount --procs 4 --offset 0 --workspace many_ifs --buffer "DWORD PTR [EBP+0x8]" --size "DWORD PTR [EBP+0xC]" tests/many_ifs/many_ifs.dmp --log many_ifs/manticore.log --assertions tests/many_ifs/assertions.txt
|
||||
@@ -1 +0,0 @@
|
||||
01182ba7 0 == 1
|
||||
@@ -1,129 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// build via:
|
||||
// Linux:
|
||||
// clang -mno-sse -m32 -ggdb -Wall -O3 -o many_ifs many_ifs.c
|
||||
// Windows
|
||||
// cl.exe /arch:IA32 /Fe:many_ifs.exe many_ifs.c
|
||||
|
||||
#define __PASSWORD__ "passwordpasswordpasswordpasswordpasswordpasswordpasswordpassword"
|
||||
#define __PASSWORD_SIZE__ 32
|
||||
#define __BUF_SIZE__ 512
|
||||
|
||||
static float float_val = 1.0f;
|
||||
const char *password = __PASSWORD__;
|
||||
int cause_error[__PASSWORD_SIZE__];
|
||||
|
||||
static int do_checksum(char *start, char *end) {
|
||||
int ck = 0;
|
||||
for(; start != end; start++) {
|
||||
ck += (int)(*start);
|
||||
}
|
||||
return ck;
|
||||
}
|
||||
|
||||
#define ITER() do { \
|
||||
cur = buffer[location++]; \
|
||||
pwcur = password[pwloc++]; \
|
||||
if(cur == pwcur) { \
|
||||
float_val += 8.0f; \
|
||||
unsigned char to_read = buffer[location++]; \
|
||||
if(location+to_read > size) { \
|
||||
return 0; \
|
||||
} \
|
||||
checksum += do_checksum(buffer+location, buffer+location+to_read); \
|
||||
location += to_read; \
|
||||
} else {\
|
||||
return 0;\
|
||||
}\
|
||||
if(location > size || pwloc > pwlen) {\
|
||||
return 0;\
|
||||
}\
|
||||
}while(0);
|
||||
|
||||
int process_buffer(char *buffer, size_t size) {
|
||||
|
||||
#ifdef _WIN32
|
||||
__debugbreak();
|
||||
#endif
|
||||
|
||||
size_t location = 0;
|
||||
char cur;
|
||||
size_t pwlen = __PASSWORD_SIZE__;
|
||||
size_t pwloc = 0;
|
||||
char pwcur;
|
||||
int checksum = 0;
|
||||
|
||||
if(size < 1 || pwlen < 1 ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ITER();
|
||||
ITER();
|
||||
ITER();
|
||||
ITER();
|
||||
ITER();
|
||||
ITER();
|
||||
ITER();
|
||||
ITER();
|
||||
|
||||
ITER();
|
||||
ITER();
|
||||
ITER();
|
||||
ITER();
|
||||
ITER();
|
||||
ITER();
|
||||
ITER();
|
||||
ITER();
|
||||
|
||||
ITER();
|
||||
ITER();
|
||||
ITER();
|
||||
ITER();
|
||||
ITER();
|
||||
ITER();
|
||||
ITER();
|
||||
ITER();
|
||||
|
||||
ITER();
|
||||
ITER();
|
||||
ITER();
|
||||
ITER();
|
||||
ITER();
|
||||
ITER();
|
||||
ITER();
|
||||
ITER();
|
||||
|
||||
int index = (int)(float_val)*0x1000;
|
||||
cause_error[index] = checksum;
|
||||
return checksum;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
|
||||
//cause_error = (int*)malloc(__PASSWORD_SIZE__ * sizeof(int));
|
||||
void *buffer = malloc(__BUF_SIZE__);
|
||||
|
||||
// this will crash it
|
||||
//strcpy((char*)buffer,
|
||||
// "p\x01za\x01zs\x01zs\x01zw\x01zo\x01zr\x01zd\x01z"
|
||||
// "p\x01za\x01zs\x01zs\x01zw\x01zo\x01zr\x01zd\x01z"
|
||||
// "p\x01za\x01zs\x01zs\x01zw\x01zo\x01zr\x01zd\x01z"
|
||||
// "p\x01za\x01zs\x01zs\x01zw\x01zo\x01zr\x01zd\x01z"
|
||||
// );
|
||||
memset(buffer, 'Z', __BUF_SIZE__);
|
||||
|
||||
int ret = process_buffer(buffer, __BUF_SIZE__);
|
||||
|
||||
if(ret != 0 && ret != -1) {
|
||||
printf("success: %d\n", ret);
|
||||
} else {
|
||||
printf("fail\n");
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
return 0;
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,3 +0,0 @@
|
||||
How to run the test:
|
||||
|
||||
python SymbolicExecutor/main.py --offset 0 --workspace sbd --log sbd/output.log --buffer "EBP-1" --size "1" tests/simple_bad_deref/simple_bad_deref.dmp
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"--offset": "0",
|
||||
"--buffer": "EBP-1",
|
||||
"--size": "0x1",
|
||||
"--procs": "2",
|
||||
"dump": "simple_bad_deref.dmp",
|
||||
"actual": "visited.txt",
|
||||
"expected": "simple_bad_deref_visited.txt"
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
// compile with
|
||||
// cl /Fe:simple_bad_deref.exe simple_bad_deref.c
|
||||
//
|
||||
// make memory dump with:
|
||||
// .dump /ma simple_bad_deref.dmp
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
char foo = '\0';
|
||||
printf("reading a char: ");
|
||||
scanf("%c", &foo);
|
||||
// break for windbg
|
||||
__debugbreak();
|
||||
switch(foo) {
|
||||
case 'm':
|
||||
// error;
|
||||
*((char*)0xf00dbad0) = foo;
|
||||
printf("Should crash before here\n");
|
||||
break;
|
||||
case 'c':
|
||||
printf("Selected c\n");
|
||||
break;
|
||||
default:
|
||||
printf("Unknown option\n");
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Binary file not shown.
@@ -1,711 +0,0 @@
|
||||
0:008f1029
|
||||
0:008f102c
|
||||
0:008f102f
|
||||
0:008f1033
|
||||
0:008f1035
|
||||
0:008f1039
|
||||
0:008f103b
|
||||
0:008f103d
|
||||
0:008f1040
|
||||
0:008f1055
|
||||
0:008f105a
|
||||
0:008f1064
|
||||
0:008f1069
|
||||
0:008f108c
|
||||
0:008f108e
|
||||
0:008f1093
|
||||
0:008f1098
|
||||
0:008f109a
|
||||
0:008f109d
|
||||
0:008f109f
|
||||
0:008f10a2
|
||||
0:008f10a5
|
||||
0:008f10a7
|
||||
0:008f10be
|
||||
0:008f10c3
|
||||
0:008f10c6
|
||||
0:008f10c7
|
||||
0:008f10c9
|
||||
0:008f10ce
|
||||
0:008f10cf
|
||||
0:008f10d0
|
||||
0:008f10d3
|
||||
0:008f10d8
|
||||
0:008f10db
|
||||
0:008f10dc
|
||||
0:008f10e1
|
||||
0:008f10e2
|
||||
0:008f10e4
|
||||
0:008f10e7
|
||||
0:008f10e8
|
||||
0:008f10e9
|
||||
0:008f10ec
|
||||
0:008f10f1
|
||||
0:008f10f4
|
||||
0:008f10f5
|
||||
0:008f10fa
|
||||
0:008f10fc
|
||||
0:008f10ff
|
||||
0:008f1104
|
||||
0:008f1107
|
||||
0:008f1108
|
||||
0:008f1109
|
||||
0:008f1592
|
||||
0:008f1597
|
||||
0:008f15d7
|
||||
0:008f15d8
|
||||
0:008f15da
|
||||
0:008f15dd
|
||||
0:008f15e0
|
||||
0:008f15e2
|
||||
0:008f15e5
|
||||
0:008f15e6
|
||||
0:008f15eb
|
||||
0:008f15ee
|
||||
0:008f15ef
|
||||
0:008f15f6
|
||||
0:008f15f7
|
||||
0:008f166e
|
||||
0:008f166f
|
||||
0:008f1671
|
||||
0:008f1675
|
||||
0:008f1677
|
||||
0:008f1678
|
||||
0:008f167b
|
||||
0:008f1682
|
||||
0:008f1684
|
||||
0:008f1685
|
||||
0:008f169f
|
||||
0:008f16a0
|
||||
0:008f16a2
|
||||
0:008f16a3
|
||||
0:008f16a6
|
||||
0:008f16a7
|
||||
0:008f16ac
|
||||
0:008f16ad
|
||||
0:008f16b2
|
||||
0:008f16b3
|
||||
0:008f16b4
|
||||
0:008f16b6
|
||||
0:008f16bc
|
||||
0:008f16bd
|
||||
0:008f16c2
|
||||
0:008f16c5
|
||||
0:008f16c7
|
||||
0:008f16c9
|
||||
0:008f16cb
|
||||
0:008f16dc
|
||||
0:008f16e2
|
||||
0:008f16e9
|
||||
0:008f16eb
|
||||
0:008f16f3
|
||||
0:008f16f4
|
||||
0:008f16f9
|
||||
0:008f1720
|
||||
0:008f1727
|
||||
0:008f172a
|
||||
0:008f172c
|
||||
0:008f172f
|
||||
0:008f1732
|
||||
0:008f1739
|
||||
0:008f173b
|
||||
0:008f173c
|
||||
0:008f173d
|
||||
0:008f1741
|
||||
0:008f1742
|
||||
0:008f1743
|
||||
0:008f1744
|
||||
0:008f1745
|
||||
0:008f1746
|
||||
0:008f1748
|
||||
0:008f1749
|
||||
0:008f174b
|
||||
0:008f174e
|
||||
0:008f1752
|
||||
0:008f1754
|
||||
0:008f1756
|
||||
0:008f1757
|
||||
0:008f175c
|
||||
0:008f175e
|
||||
0:008f1761
|
||||
0:008f1764
|
||||
0:008f1766
|
||||
0:008f1769
|
||||
0:008f176c
|
||||
0:008f1772
|
||||
0:008f1785
|
||||
0:008f1788
|
||||
0:008f1789
|
||||
0:008f178f
|
||||
0:008f17a6
|
||||
0:008f17a9
|
||||
0:008f17ac
|
||||
0:008f17ae
|
||||
0:008f17b0
|
||||
0:008f17b3
|
||||
0:008f17b6
|
||||
0:008f17ba
|
||||
0:008f17bc
|
||||
0:008f17be
|
||||
0:008f17c0
|
||||
0:008f17c3
|
||||
0:008f17c6
|
||||
0:008f17c8
|
||||
0:008f17c9
|
||||
0:008f17ca
|
||||
0:008f17cd
|
||||
0:008f17ce
|
||||
0:008f17d0
|
||||
0:008f17d6
|
||||
0:008f17db
|
||||
0:008f17dd
|
||||
0:008f17e0
|
||||
0:008f17e3
|
||||
0:008f17e9
|
||||
0:008f17ea
|
||||
0:008f17eb
|
||||
0:008f17f1
|
||||
0:008f17f4
|
||||
0:008f17f5
|
||||
0:008f17f8
|
||||
0:008f17fb
|
||||
0:008f1801
|
||||
0:008f1803
|
||||
0:008f1805
|
||||
0:008f180b
|
||||
0:008f1811
|
||||
0:008f1813
|
||||
0:008f1819
|
||||
0:008f181f
|
||||
0:008f1825
|
||||
0:008f182b
|
||||
0:008f1831
|
||||
0:008f1837
|
||||
0:008f183d
|
||||
0:008f1842
|
||||
0:008f1847
|
||||
0:008f184d
|
||||
0:008f1853
|
||||
0:008f1855
|
||||
0:008f185b
|
||||
0:008f185f
|
||||
0:008f1861
|
||||
0:008f1862
|
||||
0:008f1867
|
||||
0:008f1868
|
||||
0:008f186a
|
||||
0:008f186d
|
||||
0:008f186f
|
||||
0:008f1872
|
||||
0:008f1874
|
||||
0:008f1876
|
||||
0:008f1879
|
||||
0:008f187c
|
||||
0:008f187f
|
||||
0:008f1886
|
||||
0:008f188d
|
||||
0:008f1891
|
||||
0:008f1897
|
||||
0:008f189a
|
||||
0:008f189c
|
||||
0:008f189f
|
||||
0:008f18a1
|
||||
0:008f18a3
|
||||
0:008f18a6
|
||||
0:008f18a9
|
||||
0:008f18ac
|
||||
0:008f18b3
|
||||
0:008f18ba
|
||||
0:008f18be
|
||||
0:008f18c4
|
||||
0:008f18ca
|
||||
0:008f18cc
|
||||
0:008f18d2
|
||||
0:008f18d4
|
||||
0:008f18d6
|
||||
0:008f18dc
|
||||
0:008f18de
|
||||
0:008f18e4
|
||||
0:008f18ea
|
||||
0:008f18f0
|
||||
0:008f18f6
|
||||
0:008f18fc
|
||||
0:008f18fe
|
||||
0:008f1904
|
||||
0:008f190a
|
||||
0:008f190b
|
||||
0:008f1911
|
||||
0:008f1913
|
||||
0:008f1919
|
||||
0:008f191c
|
||||
0:008f191e
|
||||
0:008f1920
|
||||
0:008f1923
|
||||
0:008f192a
|
||||
0:008f192d
|
||||
0:008f192f
|
||||
0:008f1931
|
||||
0:008f1937
|
||||
0:008f193f
|
||||
0:008f1941
|
||||
0:008f1947
|
||||
0:008f194d
|
||||
0:008f1950
|
||||
0:008f1956
|
||||
0:008f1959
|
||||
0:008f195f
|
||||
0:008f1b5e
|
||||
0:008f1b60
|
||||
0:008f1b66
|
||||
0:008f1b6c
|
||||
0:008f1b6d
|
||||
0:008f1b70
|
||||
0:008f1b71
|
||||
0:008f1b76
|
||||
0:008f1b77
|
||||
0:008f1b78
|
||||
0:008f1b7a
|
||||
0:008f1bb4
|
||||
0:008f1bba
|
||||
0:008f1bbb
|
||||
0:008f1bc1
|
||||
0:008f1bc7
|
||||
0:008f1bcc
|
||||
0:008f1bcf
|
||||
0:008f22d0
|
||||
0:008f22d6
|
||||
0:008f22dc
|
||||
0:008f22de
|
||||
0:008f22e4
|
||||
0:008f22ea
|
||||
0:008f22ec
|
||||
0:008f22f2
|
||||
0:008f22f4
|
||||
0:008f22fb
|
||||
0:008f22fc
|
||||
0:008f22fd
|
||||
0:008f22fe
|
||||
0:008f2300
|
||||
0:008f2306
|
||||
0:008f230a
|
||||
0:008f230d
|
||||
0:008f230f
|
||||
0:008f2314
|
||||
0:008f2316
|
||||
0:008f2317
|
||||
0:008f234d
|
||||
0:008f234e
|
||||
0:008f2350
|
||||
0:008f2353
|
||||
0:008f2357
|
||||
0:008f235f
|
||||
0:008f2362
|
||||
0:008f2364
|
||||
0:008f2366
|
||||
0:008f2369
|
||||
0:008f236b
|
||||
0:008f236d
|
||||
0:008f2370
|
||||
0:008f2381
|
||||
0:008f2384
|
||||
0:008f238e
|
||||
0:008f2391
|
||||
0:008f2393
|
||||
0:008f2394
|
||||
0:008f246d
|
||||
0:008f2472
|
||||
0:008f2474
|
||||
0:008f247c
|
||||
0:008f247f
|
||||
0:008f24d0
|
||||
0:008f24d5
|
||||
0:008f24dc
|
||||
0:008f24e0
|
||||
0:008f24e4
|
||||
0:008f24e8
|
||||
0:008f24ea
|
||||
0:008f24eb
|
||||
0:008f24ec
|
||||
0:008f24ed
|
||||
0:008f24f2
|
||||
0:008f24f5
|
||||
0:008f24f7
|
||||
0:008f24f8
|
||||
0:008f24fb
|
||||
0:008f24fe
|
||||
0:008f2501
|
||||
0:008f2508
|
||||
0:008f250b
|
||||
0:008f250e
|
||||
0:008f2514
|
||||
0:008f2515
|
||||
0:008f2518
|
||||
0:008f251f
|
||||
0:008f2520
|
||||
0:008f2521
|
||||
0:008f2522
|
||||
0:008f2523
|
||||
0:008f2524
|
||||
0:008f2526
|
||||
0:008f2527
|
||||
0:008f2528
|
||||
0:008f3bc2
|
||||
0:008f3bc3
|
||||
0:008f3bc8
|
||||
0:008f3bca
|
||||
0:008f3bcc
|
||||
0:008f3bd6
|
||||
0:008f3bd8
|
||||
0:008f3bd9
|
||||
0:008f3bda
|
||||
0:008f3bdb
|
||||
0:008f3bdc
|
||||
0:008f3be2
|
||||
0:008f3be8
|
||||
0:008f3bea
|
||||
0:008f3bef
|
||||
0:008f3bf1
|
||||
0:008f3bf2
|
||||
0:008f3bf4
|
||||
0:008f3c3d
|
||||
0:008f3c3e
|
||||
0:008f3c44
|
||||
0:008f3c45
|
||||
0:008f3c47
|
||||
0:008f3c48
|
||||
0:008f4a76
|
||||
0:008f4a77
|
||||
0:008f4a79
|
||||
0:008f4a7e
|
||||
0:008f4a84
|
||||
0:008f4a87
|
||||
0:008f4a89
|
||||
0:008f4a8b
|
||||
0:008f4a8c
|
||||
0:008f4dff
|
||||
0:008f4e05
|
||||
0:008f4e07
|
||||
0:008f4f83
|
||||
0:008f4f84
|
||||
0:008f4f86
|
||||
0:008f4f87
|
||||
0:008f4f88
|
||||
0:008f4f8b
|
||||
0:008f4f8d
|
||||
0:008f4f90
|
||||
0:008f4f92
|
||||
0:008f4f94
|
||||
0:008f4f96
|
||||
0:008f4f9d
|
||||
0:008f4f9f
|
||||
0:008f4fa0
|
||||
0:008f4fa2
|
||||
0:008f4fa5
|
||||
0:008f4fa7
|
||||
0:008f4fa9
|
||||
0:008f4faa
|
||||
0:008f4fad
|
||||
0:008f4fae
|
||||
0:008f4fb3
|
||||
0:008f4fb4
|
||||
0:008f4fb5
|
||||
0:008f50d4
|
||||
0:008f50d5
|
||||
0:008f50d7
|
||||
0:008f50d8
|
||||
0:008f50db
|
||||
0:008f50e3
|
||||
0:008f50f8
|
||||
0:008f50ff
|
||||
0:008f5105
|
||||
0:008f5106
|
||||
0:008f5107
|
||||
0:008f53b2
|
||||
0:008f53b3
|
||||
0:008f53b5
|
||||
0:008f53b8
|
||||
0:008f53ba
|
||||
0:008f53d1
|
||||
0:008f53d4
|
||||
0:008f53d5
|
||||
0:008f53d6
|
||||
0:008f53d7
|
||||
0:008f53d9
|
||||
0:008f53dc
|
||||
0:008f53df
|
||||
0:008f53ee
|
||||
0:008f53f0
|
||||
0:008f53f2
|
||||
0:008f53f8
|
||||
0:008f53fa
|
||||
0:008f53fc
|
||||
0:008f53ff
|
||||
0:008f5402
|
||||
0:008f5405
|
||||
0:008f540c
|
||||
0:008f5411
|
||||
0:008f5414
|
||||
0:008f5415
|
||||
0:008f5e74
|
||||
0:008f5e75
|
||||
0:008f5e77
|
||||
0:008f5e7a
|
||||
0:008f5e7d
|
||||
0:008f5e80
|
||||
0:008f5e85
|
||||
0:008f5e88
|
||||
0:008f5e8b
|
||||
0:008f5e8e
|
||||
0:008f5e94
|
||||
0:008f5e98
|
||||
0:008f5e9d
|
||||
0:008f5ea1
|
||||
0:008f5eaa
|
||||
0:008f5eac
|
||||
0:008f5ead
|
||||
0:008f7de3
|
||||
0:008f7de5
|
||||
0:008f7dea
|
||||
0:008f7def
|
||||
0:008f7df1
|
||||
0:008f7df4
|
||||
0:008f7df7
|
||||
0:008f7dfa
|
||||
0:008f7e13
|
||||
0:008f7e15
|
||||
0:008f7e1b
|
||||
0:008f7e21
|
||||
0:008f7e27
|
||||
0:008f7e29
|
||||
0:008f7e2c
|
||||
0:008f7e2e
|
||||
0:008f7e31
|
||||
0:008f7e34
|
||||
0:008f7e3b
|
||||
0:008f7e40
|
||||
0:008f7e43
|
||||
0:008f7e4f
|
||||
0:008f7e50
|
||||
0:008f7e55
|
||||
0:008f7e56
|
||||
0:008f7e5a
|
||||
0:008f7e61
|
||||
0:008f7e66
|
||||
0:008f7e68
|
||||
0:008f7e6b
|
||||
0:008f7e6e
|
||||
0:008f7e6f
|
||||
0:008f7ed2
|
||||
0:008f7ed3
|
||||
0:008f7ed5
|
||||
0:008f7eda
|
||||
0:008f7edf
|
||||
0:008f7ee4
|
||||
0:008f7ee6
|
||||
0:008f7ee9
|
||||
0:008f7ef0
|
||||
0:008f7ef3
|
||||
0:008f7ef6
|
||||
0:008f7ef7
|
||||
0:008f7ef9
|
||||
0:008f7eff
|
||||
0:008f7f00
|
||||
0:008f7f02
|
||||
0:008f7f08
|
||||
0:008f7f0e
|
||||
0:008f7f11
|
||||
0:008f7f1a
|
||||
0:008f7f1c
|
||||
0:008f7f3d
|
||||
0:008f7f3f
|
||||
0:008f7f41
|
||||
0:008f7f44
|
||||
0:008f7f47
|
||||
0:008f7f4a
|
||||
0:008f7f50
|
||||
0:008f7f51
|
||||
0:008f7f58
|
||||
0:008f7f5e
|
||||
0:008f7f62
|
||||
0:008f7f64
|
||||
0:008f7f66
|
||||
0:008f7f69
|
||||
0:008f7f6b
|
||||
0:008f7f6e
|
||||
0:008f7f9b
|
||||
0:008f7fa0
|
||||
0:008f7fb1
|
||||
0:008f7fb7
|
||||
0:008f7fbc
|
||||
0:008f7fbd
|
||||
0:008f7fbf
|
||||
0:008f7fc5
|
||||
0:008f7fcb
|
||||
0:008f7fd1
|
||||
0:008f7fd8
|
||||
0:008f7fdd
|
||||
0:008f7fe3
|
||||
0:008f7fe8
|
||||
0:008f7fea
|
||||
0:008f7fed
|
||||
0:008f7ff3
|
||||
0:008f7ff9
|
||||
0:008f7ffa
|
||||
0:008f8000
|
||||
0:008f8003
|
||||
0:008f8009
|
||||
0:008f800f
|
||||
0:008f8016
|
||||
0:008f8019
|
||||
0:008fa1ca
|
||||
0:008fa1cc
|
||||
0:008fa1d1
|
||||
0:008fa1d6
|
||||
0:008fa1d9
|
||||
0:008fa1db
|
||||
0:008fa1de
|
||||
0:008fa1e0
|
||||
0:008fa1e3
|
||||
0:008fa1e6
|
||||
0:008fa1ed
|
||||
0:008fa1ef
|
||||
0:008fa1f2
|
||||
0:008fa225
|
||||
0:008fa227
|
||||
0:008fa22a
|
||||
0:008fa22d
|
||||
0:008fa230
|
||||
0:008fa237
|
||||
0:008fa23a
|
||||
0:008fa23c
|
||||
0:008fa23d
|
||||
0:008fa243
|
||||
0:008fa245
|
||||
0:008fa246
|
||||
0:008fa24b
|
||||
0:008fa3b0
|
||||
0:008fa3b1
|
||||
0:008fa3b5
|
||||
0:008fa3b7
|
||||
0:008fa3b9
|
||||
0:008fa3bb
|
||||
0:008fa3bd
|
||||
0:008fa3bf
|
||||
0:008fa3c4
|
||||
0:008fa3c6
|
||||
0:008fa3c8
|
||||
0:008fa3ca
|
||||
0:008fa3cb
|
||||
0:008fa3cc
|
||||
0:008fa3ce
|
||||
0:008fa3d1
|
||||
0:008fa3d2
|
||||
0:008fa3d7
|
||||
0:008fa3d9
|
||||
0:75d46806
|
||||
0:75d4680c
|
||||
0:75d4680f
|
||||
0:75d46897
|
||||
0:75d46899
|
||||
0:75d4689a
|
||||
0:75d4689c
|
||||
0:75d4689f
|
||||
0:75d468a5
|
||||
0:75d468a8
|
||||
0:75d468ab
|
||||
0:75d468b1
|
||||
0:75d468b7
|
||||
0:75d468b9
|
||||
0:75d468bf
|
||||
0:75d468c3
|
||||
0:75d468c7
|
||||
0:75d468c8
|
||||
0:75ddbb08
|
||||
0:75ddbd05
|
||||
0:75ddbf00
|
||||
0:75de1292
|
||||
0:75de1294
|
||||
0:75de1295
|
||||
0:75de1297
|
||||
0:75de129e
|
||||
0:75de12a4
|
||||
0:75de12a7
|
||||
0:75de12aa
|
||||
0:75de12ad
|
||||
0:75de12ae
|
||||
0:75de12af
|
||||
0:75de12b2
|
||||
0:75de12b6
|
||||
0:75de12ba
|
||||
0:75de12bf
|
||||
0:75de12c0
|
||||
0:75de12c3
|
||||
0:75de12c5
|
||||
0:75de12c8
|
||||
0:75de12cb
|
||||
0:75de12cd
|
||||
0:75de12d3
|
||||
0:75de12d4
|
||||
0:75de12d5
|
||||
0:75de12db
|
||||
0:75de1e16
|
||||
0:75de1e18
|
||||
0:75de1e19
|
||||
0:75de1e1b
|
||||
0:75de1e1c
|
||||
0:75de1e23
|
||||
0:75de2412
|
||||
0:75de2414
|
||||
0:75de2415
|
||||
0:75de2417
|
||||
0:75de241d
|
||||
0:75de2422
|
||||
0:75de2424
|
||||
0:75de2427
|
||||
0:75de242a
|
||||
0:75de242b
|
||||
0:75de242e
|
||||
0:75de2430
|
||||
0:75de2432
|
||||
0:75de2435
|
||||
0:75de2437
|
||||
0:75de243d
|
||||
0:75de243e
|
||||
0:77c16458
|
||||
0:77c1645d
|
||||
0:77c16462
|
||||
0:77c170b0
|
||||
0:77c170b2
|
||||
0:77c177a0
|
||||
0:77c177a2
|
||||
0:77c177a3
|
||||
0:77c177a5
|
||||
0:77c177a8
|
||||
0:77c177a9
|
||||
0:77c177aa
|
||||
0:77c177ad
|
||||
0:77c177b0
|
||||
0:77c177b2
|
||||
0:77c177b7
|
||||
0:77c177bd
|
||||
0:77c177c3
|
||||
0:77c177c6
|
||||
0:77c177c9
|
||||
0:77c177d0
|
||||
0:77c177d1
|
||||
0:77c177d3
|
||||
0:77c177d4
|
||||
0:77c177d6
|
||||
0:77c177d7
|
||||
0:77c230fb
|
||||
0:77c230fd
|
||||
0:77c230fe
|
||||
0:77c23100
|
||||
0:77c23107
|
||||
0:77c2310c
|
||||
0:77c2310f
|
||||
0:77c23111
|
||||
0:77c23117
|
||||
0:77c2311a
|
||||
0:77c23120
|
||||
0:77c23121
|
||||
@@ -1,3 +0,0 @@
|
||||
How to run the test:
|
||||
|
||||
python SymbolicExecutor/main.py --offset 0 --workspace sbo --log sbo/output.log --buffer "DWORD PTR [EBP-0x28]" --size "0x20" tests/simple_buffer_overflow/simple_buffer_overflow.dmp
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"--offset": "0",
|
||||
"--buffer": "DWORD PTR [EBP-0x28]",
|
||||
"--size": "0x20",
|
||||
"--procs": "2",
|
||||
"dump": "simple_buffer_overflow.dmp",
|
||||
"actual": "visited.txt",
|
||||
"expected": "sbo_visited.txt"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,58 +0,0 @@
|
||||
// SimpleBufferOverflow.cpp : Defines the entry point for the console application.
|
||||
//
|
||||
|
||||
// build with: cl /Fesimple_buffer_overflow.exe simple_buffer_overflow.cpp
|
||||
|
||||
|
||||
#pragma once
|
||||
#include <tchar.h>
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
|
||||
typedef struct {
|
||||
DWORD a;
|
||||
DWORD b;
|
||||
DWORD c;
|
||||
VOID(*d)(VOID);
|
||||
} ITEM, *PITEM;
|
||||
|
||||
VOID greetings(VOID)
|
||||
{
|
||||
printf("Hello, world!\n");
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
PITEM pItem = NULL;
|
||||
DWORD dwBytesRead = 0;
|
||||
char buffer[32] = { 0 };
|
||||
|
||||
pItem = (PITEM)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pItem));
|
||||
if (!pItem) {
|
||||
printf("Failed to allocate memory\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
pItem->d = greetings;
|
||||
|
||||
if (!ReadFile(GetStdHandle(STD_INPUT_HANDLE), &buffer, 32, &dwBytesRead, NULL)) {
|
||||
printf("Failed to read STDIN\n");
|
||||
HeapFree(GetProcessHeap(), 0, pItem);
|
||||
return -1;
|
||||
}
|
||||
|
||||
strcpy((char *) pItem, buffer);
|
||||
// debug break to make taking memory dumps easier
|
||||
__debugbreak();
|
||||
|
||||
|
||||
if (pItem->d) {
|
||||
pItem->d();
|
||||
}
|
||||
|
||||
if (pItem) {
|
||||
HeapFree(GetProcessHeap(), 0, pItem);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -1,4 +0,0 @@
|
||||
How to run the test:
|
||||
|
||||
python SymbolicExecutor/main.py --offset 0 --workspace sfpu --context tests/simple_fpu/eip_context.pkl --buffer "EBP-8" --size "8" tests/simple_fpu/simple_fpu.dmp --log sfpu/manti.log
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"--offset": "0",
|
||||
"--buffer": "EBP-8",
|
||||
"--size": "0x8",
|
||||
"--procs": "2",
|
||||
"--context": "{dumpdir}/eip_context.pkl",
|
||||
"dump": "simple_fpu.dmp",
|
||||
"actual": "visited.txt",
|
||||
"expected": "simple_fpu_visited.txt"
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
// compile with
|
||||
// cl /arch:IA32 /Fe:simple_fpu.exe simple_fpu.c
|
||||
//
|
||||
// make memory dump with:
|
||||
// .dump /ma simple_fpu.dmp
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, const char* argv[])
|
||||
{
|
||||
|
||||
float foo = 0.0f;
|
||||
char ch ='\0';
|
||||
float *bar;
|
||||
printf("reading char, float: ");
|
||||
scanf("%c %f", &ch, &foo);
|
||||
// break for windbg
|
||||
__debugbreak();
|
||||
switch(ch) {
|
||||
case 'm':
|
||||
// error;
|
||||
*((float*)0xf00dbad0) = foo;
|
||||
printf("Should crash before here\n");
|
||||
break;
|
||||
case 'c':
|
||||
printf("Selected c\n");
|
||||
break;
|
||||
case 'b':
|
||||
printf("Selected c\n");
|
||||
bar = &foo;
|
||||
*bar = 1.23f;
|
||||
printf("float is: %f\n", foo);
|
||||
*bar = *((float*)0xf00dbadb);
|
||||
break;
|
||||
default:
|
||||
printf("Unknown option\n");
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
Binary file not shown.
@@ -1,3 +0,0 @@
|
||||
How to run the test:
|
||||
|
||||
python SymbolicExecutor/main.py --offset 0 --workspace test --buffer "EBP-88" --size "0x84" tests/simple_parse/simple_parse.dmp
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"--offset": "0",
|
||||
"--buffer": "EBP-88",
|
||||
"--size": "0x84",
|
||||
"--procs": "2",
|
||||
"dump": "simple_parse.dmp",
|
||||
"actual": "visited.txt",
|
||||
"expected": "simple_parse_visited.txt"
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
|
||||
// compile with
|
||||
// cl /Fe:simple_parse.exe simple_parse.c
|
||||
//
|
||||
// make memory dump with:
|
||||
// .dump /ma simple_parse.dmp
|
||||
//
|
||||
#include <stdio.h>
|
||||
|
||||
typedef int(*parse)(const char *s);
|
||||
|
||||
const char* string_table[] = {
|
||||
"zero",
|
||||
"one",
|
||||
"two",
|
||||
"three"};
|
||||
|
||||
int parse_zero(const char *s) {
|
||||
printf("parse zero\n");
|
||||
char c = s[0] - '0';
|
||||
if(c > sizeof(string_table)/sizeof(string_table[0])) {
|
||||
printf("invalid value\n");
|
||||
return -1;
|
||||
}
|
||||
printf("string table: %s\n", string_table[c]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int parse_one(const char *s) {
|
||||
printf("parse one\n");
|
||||
printf("not implemented\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int parse_two(const char *s) {
|
||||
printf("parse two\n");
|
||||
printf("%s", s);
|
||||
return 0;
|
||||
}
|
||||
int parse_three(const char *s) {
|
||||
char c = s[0];
|
||||
if((int)c > (int)(sizeof(string_table)/sizeof(string_table[0]))) {
|
||||
printf("invalid value\n");
|
||||
return -1;
|
||||
}
|
||||
const char *st = string_table[c];
|
||||
// ensure dereference
|
||||
char first_c = st[0];
|
||||
printf("parse three\nbroken string table: %c\n", first_c);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
parse ptable[] = {
|
||||
parse_zero,
|
||||
parse_one,
|
||||
parse_two,
|
||||
parse_three};
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
struct foo {
|
||||
int index;
|
||||
char s[128];
|
||||
} myvar;
|
||||
printf("reading an entry: ");
|
||||
scanf("%d %s", &(myvar.index), myvar.s);
|
||||
// break for windbg
|
||||
__debugbreak();
|
||||
if(myvar.index > (sizeof(ptable)/sizeof(ptable[0]))) {
|
||||
printf("Invalid parse index\n");
|
||||
} else {
|
||||
parse parser = ptable[myvar.index];
|
||||
parser(myvar.s);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Binary file not shown.
@@ -1,741 +0,0 @@
|
||||
0:01021000
|
||||
0:01021001
|
||||
0:01021003
|
||||
0:01021004
|
||||
0:01021009
|
||||
0:01021060
|
||||
0:01021061
|
||||
0:01021063
|
||||
0:01021068
|
||||
0:01021090
|
||||
0:01021091
|
||||
0:01021093
|
||||
0:01021098
|
||||
0:010210c0
|
||||
0:010210c1
|
||||
0:010210c3
|
||||
0:010210c6
|
||||
0:010210cb
|
||||
0:010210ce
|
||||
0:010210d1
|
||||
0:010210d4
|
||||
0:010210d7
|
||||
0:010210db
|
||||
0:010210de
|
||||
0:010210e0
|
||||
0:010210e5
|
||||
0:010210f2
|
||||
0:010210f6
|
||||
0:010210fd
|
||||
0:01021100
|
||||
0:01021105
|
||||
0:01021108
|
||||
0:0102110b
|
||||
0:0102116c
|
||||
0:01021173
|
||||
0:01021175
|
||||
0:0102117a
|
||||
0:01021184
|
||||
0:0102118a
|
||||
0:01021191
|
||||
0:01021197
|
||||
0:0102119d
|
||||
0:0102119e
|
||||
0:010211cc
|
||||
0:010211ce
|
||||
0:010211d3
|
||||
0:010211d8
|
||||
0:010211da
|
||||
0:010211dd
|
||||
0:010211df
|
||||
0:010211e2
|
||||
0:010211e5
|
||||
0:010211e7
|
||||
0:010211fe
|
||||
0:01021203
|
||||
0:01021206
|
||||
0:01021207
|
||||
0:01021209
|
||||
0:0102120e
|
||||
0:0102120f
|
||||
0:01021210
|
||||
0:01021213
|
||||
0:01021218
|
||||
0:0102121b
|
||||
0:0102121c
|
||||
0:01021221
|
||||
0:01021222
|
||||
0:01021224
|
||||
0:01021227
|
||||
0:01021228
|
||||
0:01021229
|
||||
0:0102122c
|
||||
0:01021231
|
||||
0:01021234
|
||||
0:01021235
|
||||
0:0102123a
|
||||
0:0102123c
|
||||
0:0102123f
|
||||
0:01021244
|
||||
0:01021247
|
||||
0:01021248
|
||||
0:01021249
|
||||
0:0102131b
|
||||
0:01021321
|
||||
0:01021323
|
||||
0:010216e1
|
||||
0:010216e6
|
||||
0:01021726
|
||||
0:01021727
|
||||
0:01021729
|
||||
0:0102172c
|
||||
0:0102172f
|
||||
0:01021731
|
||||
0:01021734
|
||||
0:01021735
|
||||
0:0102173a
|
||||
0:0102173d
|
||||
0:0102173e
|
||||
0:01021745
|
||||
0:01021746
|
||||
0:010217bd
|
||||
0:010217be
|
||||
0:010217c0
|
||||
0:010217c4
|
||||
0:010217c6
|
||||
0:010217c7
|
||||
0:010217ca
|
||||
0:010217d1
|
||||
0:010217d3
|
||||
0:010217d4
|
||||
0:010217ee
|
||||
0:010217ef
|
||||
0:010217f1
|
||||
0:010217f2
|
||||
0:010217f5
|
||||
0:010217f6
|
||||
0:010217fb
|
||||
0:010217fc
|
||||
0:01021801
|
||||
0:01021802
|
||||
0:01021803
|
||||
0:01021805
|
||||
0:0102180b
|
||||
0:0102180c
|
||||
0:01021811
|
||||
0:01021814
|
||||
0:01021816
|
||||
0:01021818
|
||||
0:0102181a
|
||||
0:0102182b
|
||||
0:01021831
|
||||
0:01021838
|
||||
0:0102183a
|
||||
0:01021842
|
||||
0:01021843
|
||||
0:01021848
|
||||
0:0102186f
|
||||
0:01021876
|
||||
0:01021879
|
||||
0:0102187b
|
||||
0:0102187e
|
||||
0:01021881
|
||||
0:01021888
|
||||
0:0102188a
|
||||
0:0102188b
|
||||
0:0102188c
|
||||
0:01021890
|
||||
0:01021891
|
||||
0:01021892
|
||||
0:01021893
|
||||
0:01021894
|
||||
0:01021895
|
||||
0:01021897
|
||||
0:01021898
|
||||
0:0102189a
|
||||
0:0102189d
|
||||
0:010218a1
|
||||
0:010218a3
|
||||
0:010218a5
|
||||
0:010218a6
|
||||
0:010218ab
|
||||
0:010218ad
|
||||
0:010218b0
|
||||
0:010218b3
|
||||
0:010218b5
|
||||
0:010218b8
|
||||
0:010218bb
|
||||
0:010218c1
|
||||
0:010218d4
|
||||
0:010218d7
|
||||
0:010218d8
|
||||
0:010218de
|
||||
0:010218f5
|
||||
0:010218f8
|
||||
0:010218fb
|
||||
0:010218fd
|
||||
0:010218ff
|
||||
0:01021902
|
||||
0:01021905
|
||||
0:01021909
|
||||
0:0102190b
|
||||
0:0102190d
|
||||
0:0102190f
|
||||
0:01021912
|
||||
0:01021915
|
||||
0:01021917
|
||||
0:01021918
|
||||
0:01021919
|
||||
0:0102191c
|
||||
0:0102191d
|
||||
0:0102191f
|
||||
0:01021925
|
||||
0:0102192a
|
||||
0:0102192c
|
||||
0:0102192f
|
||||
0:01021932
|
||||
0:01021938
|
||||
0:01021939
|
||||
0:0102193a
|
||||
0:01021940
|
||||
0:01021943
|
||||
0:01021944
|
||||
0:01021947
|
||||
0:0102194a
|
||||
0:01021950
|
||||
0:01021952
|
||||
0:01021954
|
||||
0:0102195a
|
||||
0:01021960
|
||||
0:01021962
|
||||
0:01021968
|
||||
0:0102196e
|
||||
0:01021974
|
||||
0:0102197a
|
||||
0:01021980
|
||||
0:01021986
|
||||
0:0102198c
|
||||
0:01021991
|
||||
0:01021996
|
||||
0:0102199c
|
||||
0:010219a2
|
||||
0:010219a4
|
||||
0:010219aa
|
||||
0:010219ae
|
||||
0:010219b0
|
||||
0:010219b1
|
||||
0:010219b6
|
||||
0:010219b7
|
||||
0:010219b9
|
||||
0:010219bc
|
||||
0:010219be
|
||||
0:010219c1
|
||||
0:010219c3
|
||||
0:010219c5
|
||||
0:010219c8
|
||||
0:010219cb
|
||||
0:010219ce
|
||||
0:010219d5
|
||||
0:010219dc
|
||||
0:010219e0
|
||||
0:010219e6
|
||||
0:010219e9
|
||||
0:010219eb
|
||||
0:010219ee
|
||||
0:010219f0
|
||||
0:010219f2
|
||||
0:010219f5
|
||||
0:010219f8
|
||||
0:010219fb
|
||||
0:01021a02
|
||||
0:01021a09
|
||||
0:01021a0d
|
||||
0:01021a13
|
||||
0:01021a19
|
||||
0:01021a1b
|
||||
0:01021a21
|
||||
0:01021a23
|
||||
0:01021a25
|
||||
0:01021a2b
|
||||
0:01021a2d
|
||||
0:01021a33
|
||||
0:01021a39
|
||||
0:01021a3f
|
||||
0:01021a45
|
||||
0:01021a4b
|
||||
0:01021a4d
|
||||
0:01021a53
|
||||
0:01021a59
|
||||
0:01021a5a
|
||||
0:01021a60
|
||||
0:01021a62
|
||||
0:01021a68
|
||||
0:01021a6b
|
||||
0:01021a6d
|
||||
0:01021a6f
|
||||
0:01021a72
|
||||
0:01021a79
|
||||
0:01021a7c
|
||||
0:01021a7e
|
||||
0:01021a80
|
||||
0:01021a86
|
||||
0:01021a8e
|
||||
0:01021a90
|
||||
0:01021a96
|
||||
0:01021a9c
|
||||
0:01021a9f
|
||||
0:01021aa5
|
||||
0:01021aa8
|
||||
0:01021aae
|
||||
0:01021cad
|
||||
0:01021caf
|
||||
0:01021cb5
|
||||
0:01021cbb
|
||||
0:01021cbc
|
||||
0:01021cbf
|
||||
0:01021cc0
|
||||
0:01021cc5
|
||||
0:01021cc6
|
||||
0:01021cc7
|
||||
0:01021cc9
|
||||
0:01021d03
|
||||
0:01021d09
|
||||
0:01021d0a
|
||||
0:01021d10
|
||||
0:01021d16
|
||||
0:01021d1b
|
||||
0:01021d1e
|
||||
0:0102241f
|
||||
0:01022425
|
||||
0:0102242b
|
||||
0:0102242d
|
||||
0:01022433
|
||||
0:01022439
|
||||
0:0102243b
|
||||
0:01022441
|
||||
0:01022443
|
||||
0:0102244a
|
||||
0:0102244b
|
||||
0:0102244c
|
||||
0:0102244d
|
||||
0:0102244f
|
||||
0:01022455
|
||||
0:01022459
|
||||
0:0102245c
|
||||
0:0102245e
|
||||
0:01022463
|
||||
0:01022465
|
||||
0:01022466
|
||||
0:0102249c
|
||||
0:0102249d
|
||||
0:0102249f
|
||||
0:010224a2
|
||||
0:010224a6
|
||||
0:010224ae
|
||||
0:010224b1
|
||||
0:010224b3
|
||||
0:010224b5
|
||||
0:010224b8
|
||||
0:010224ba
|
||||
0:010224bc
|
||||
0:010224bf
|
||||
0:010224d0
|
||||
0:010224d3
|
||||
0:010224dd
|
||||
0:010224e0
|
||||
0:010224e2
|
||||
0:010224e3
|
||||
0:010225bc
|
||||
0:010225c1
|
||||
0:010225c3
|
||||
0:010225cb
|
||||
0:010225ce
|
||||
0:01022610
|
||||
0:01022615
|
||||
0:0102261c
|
||||
0:01022620
|
||||
0:01022624
|
||||
0:01022628
|
||||
0:0102262a
|
||||
0:0102262b
|
||||
0:0102262c
|
||||
0:0102262d
|
||||
0:01022632
|
||||
0:01022635
|
||||
0:01022637
|
||||
0:01022638
|
||||
0:0102263b
|
||||
0:0102263e
|
||||
0:01022641
|
||||
0:01022648
|
||||
0:0102264b
|
||||
0:0102264e
|
||||
0:01022654
|
||||
0:01022655
|
||||
0:01022658
|
||||
0:0102265f
|
||||
0:01022660
|
||||
0:01022661
|
||||
0:01022662
|
||||
0:01022663
|
||||
0:01022664
|
||||
0:01022666
|
||||
0:01022667
|
||||
0:01022668
|
||||
0:01023e3a
|
||||
0:01023e3b
|
||||
0:01023e40
|
||||
0:01023e42
|
||||
0:01023e44
|
||||
0:01023e4e
|
||||
0:01023e50
|
||||
0:01023e51
|
||||
0:01023e52
|
||||
0:01023e53
|
||||
0:01023e54
|
||||
0:01023e5a
|
||||
0:01023e60
|
||||
0:01023e62
|
||||
0:01023e67
|
||||
0:01023e69
|
||||
0:01023e6a
|
||||
0:01023e6c
|
||||
0:01023eb5
|
||||
0:01023eb6
|
||||
0:01023ebc
|
||||
0:01023ebd
|
||||
0:01023ebf
|
||||
0:01023ec0
|
||||
0:01024cee
|
||||
0:01024cef
|
||||
0:01024cf1
|
||||
0:01024cf6
|
||||
0:01024cfc
|
||||
0:01024cff
|
||||
0:01024d01
|
||||
0:01024d03
|
||||
0:01024d04
|
||||
0:010251f3
|
||||
0:010251f4
|
||||
0:010251f6
|
||||
0:010251f7
|
||||
0:010251f8
|
||||
0:010251fb
|
||||
0:010251fd
|
||||
0:01025200
|
||||
0:01025202
|
||||
0:01025204
|
||||
0:01025206
|
||||
0:0102520d
|
||||
0:0102520f
|
||||
0:01025210
|
||||
0:01025212
|
||||
0:01025215
|
||||
0:01025217
|
||||
0:01025219
|
||||
0:0102521a
|
||||
0:0102521d
|
||||
0:0102521e
|
||||
0:01025223
|
||||
0:01025224
|
||||
0:01025225
|
||||
0:01025344
|
||||
0:01025345
|
||||
0:01025347
|
||||
0:01025348
|
||||
0:0102534b
|
||||
0:01025353
|
||||
0:01025368
|
||||
0:0102536f
|
||||
0:01025375
|
||||
0:01025376
|
||||
0:01025377
|
||||
0:01025622
|
||||
0:01025623
|
||||
0:01025625
|
||||
0:01025628
|
||||
0:0102562a
|
||||
0:01025641
|
||||
0:01025644
|
||||
0:01025645
|
||||
0:01025646
|
||||
0:01025647
|
||||
0:01025649
|
||||
0:0102564c
|
||||
0:0102564f
|
||||
0:0102565e
|
||||
0:01025660
|
||||
0:01025662
|
||||
0:01025668
|
||||
0:0102566a
|
||||
0:0102566c
|
||||
0:0102566f
|
||||
0:01025672
|
||||
0:01025675
|
||||
0:0102567c
|
||||
0:01025681
|
||||
0:01025684
|
||||
0:01025685
|
||||
0:010260e4
|
||||
0:010260e5
|
||||
0:010260e7
|
||||
0:010260ea
|
||||
0:010260ed
|
||||
0:010260f0
|
||||
0:010260f5
|
||||
0:010260f8
|
||||
0:010260fb
|
||||
0:010260fe
|
||||
0:01026104
|
||||
0:01026108
|
||||
0:0102610d
|
||||
0:01026111
|
||||
0:0102611a
|
||||
0:0102611c
|
||||
0:0102611d
|
||||
0:01027f1b
|
||||
0:01027f1d
|
||||
0:01027f22
|
||||
0:01027f27
|
||||
0:01027f29
|
||||
0:01027f2c
|
||||
0:01027f2f
|
||||
0:01027f32
|
||||
0:01027f4b
|
||||
0:01027f4d
|
||||
0:01027f53
|
||||
0:01027f59
|
||||
0:01027f5f
|
||||
0:01027f61
|
||||
0:01027f64
|
||||
0:01027f66
|
||||
0:01027f69
|
||||
0:01027f6c
|
||||
0:01027f73
|
||||
0:01027f78
|
||||
0:01027f7b
|
||||
0:01027f87
|
||||
0:01027f88
|
||||
0:01027f8d
|
||||
0:01027f8e
|
||||
0:01027f92
|
||||
0:01027f99
|
||||
0:01027f9e
|
||||
0:01027fa0
|
||||
0:01027fa3
|
||||
0:01027fa6
|
||||
0:01027fa7
|
||||
0:0102800a
|
||||
0:0102800b
|
||||
0:0102800d
|
||||
0:01028012
|
||||
0:01028017
|
||||
0:0102801c
|
||||
0:0102801e
|
||||
0:01028021
|
||||
0:01028028
|
||||
0:0102802b
|
||||
0:0102802e
|
||||
0:0102802f
|
||||
0:01028031
|
||||
0:01028037
|
||||
0:01028038
|
||||
0:0102803a
|
||||
0:01028040
|
||||
0:01028046
|
||||
0:01028049
|
||||
0:01028052
|
||||
0:01028054
|
||||
0:01028075
|
||||
0:01028077
|
||||
0:01028079
|
||||
0:0102807c
|
||||
0:0102807f
|
||||
0:01028082
|
||||
0:01028088
|
||||
0:01028089
|
||||
0:01028090
|
||||
0:01028096
|
||||
0:0102809a
|
||||
0:0102809c
|
||||
0:0102809e
|
||||
0:010280a1
|
||||
0:010280a3
|
||||
0:010280a6
|
||||
0:010280d3
|
||||
0:010280d8
|
||||
0:010280e9
|
||||
0:010280ef
|
||||
0:010280f4
|
||||
0:010280f5
|
||||
0:010280f7
|
||||
0:010280fd
|
||||
0:01028103
|
||||
0:01028109
|
||||
0:01028110
|
||||
0:01028115
|
||||
0:0102811b
|
||||
0:01028120
|
||||
0:01028122
|
||||
0:01028125
|
||||
0:0102812b
|
||||
0:01028131
|
||||
0:01028132
|
||||
0:01028138
|
||||
0:0102813b
|
||||
0:01028141
|
||||
0:01028147
|
||||
0:0102814e
|
||||
0:01028151
|
||||
0:0102a2fa
|
||||
0:0102a2fc
|
||||
0:0102a301
|
||||
0:0102a306
|
||||
0:0102a309
|
||||
0:0102a30b
|
||||
0:0102a30e
|
||||
0:0102a310
|
||||
0:0102a313
|
||||
0:0102a316
|
||||
0:0102a31d
|
||||
0:0102a31f
|
||||
0:0102a322
|
||||
0:0102a355
|
||||
0:0102a357
|
||||
0:0102a35a
|
||||
0:0102a35d
|
||||
0:0102a360
|
||||
0:0102a367
|
||||
0:0102a36a
|
||||
0:0102a36c
|
||||
0:0102a36d
|
||||
0:0102a373
|
||||
0:0102a375
|
||||
0:0102a376
|
||||
0:0102a37b
|
||||
0:0102a4e0
|
||||
0:0102a4e1
|
||||
0:0102a4e5
|
||||
0:0102a4e7
|
||||
0:0102a4e9
|
||||
0:0102a4eb
|
||||
0:0102a4ed
|
||||
0:0102a4ef
|
||||
0:0102a4f4
|
||||
0:0102a4f6
|
||||
0:0102a4f8
|
||||
0:0102a4fa
|
||||
0:0102a4fb
|
||||
0:0102a4fc
|
||||
0:0102a4fe
|
||||
0:0102a501
|
||||
0:0102a502
|
||||
0:0102a507
|
||||
0:0102a509
|
||||
0:75d46806
|
||||
0:75d4680c
|
||||
0:75d4680f
|
||||
0:75d46897
|
||||
0:75d46899
|
||||
0:75d4689a
|
||||
0:75d4689c
|
||||
0:75d4689f
|
||||
0:75d468a5
|
||||
0:75d468a8
|
||||
0:75d468ab
|
||||
0:75d468b1
|
||||
0:75d468b7
|
||||
0:75d468b9
|
||||
0:75d468bf
|
||||
0:75d468c3
|
||||
0:75d468c7
|
||||
0:75d468c8
|
||||
0:75ddbb08
|
||||
0:75ddbd05
|
||||
0:75ddbf00
|
||||
0:75de1292
|
||||
0:75de1294
|
||||
0:75de1295
|
||||
0:75de1297
|
||||
0:75de129e
|
||||
0:75de12a4
|
||||
0:75de12a7
|
||||
0:75de12aa
|
||||
0:75de12ad
|
||||
0:75de12ae
|
||||
0:75de12af
|
||||
0:75de12b2
|
||||
0:75de12b6
|
||||
0:75de12ba
|
||||
0:75de12bf
|
||||
0:75de12c0
|
||||
0:75de12c3
|
||||
0:75de12c5
|
||||
0:75de12c8
|
||||
0:75de12cb
|
||||
0:75de12cd
|
||||
0:75de12d3
|
||||
0:75de12d4
|
||||
0:75de12d5
|
||||
0:75de12db
|
||||
0:75de1e16
|
||||
0:75de1e18
|
||||
0:75de1e19
|
||||
0:75de1e1b
|
||||
0:75de1e1c
|
||||
0:75de1e23
|
||||
0:75de2412
|
||||
0:75de2414
|
||||
0:75de2415
|
||||
0:75de2417
|
||||
0:75de241d
|
||||
0:75de2422
|
||||
0:75de2424
|
||||
0:75de2427
|
||||
0:75de242a
|
||||
0:75de242b
|
||||
0:75de242e
|
||||
0:75de2430
|
||||
0:75de2432
|
||||
0:75de2435
|
||||
0:75de2437
|
||||
0:75de243d
|
||||
0:75de243e
|
||||
0:77c16458
|
||||
0:77c1645d
|
||||
0:77c16462
|
||||
0:77c170b0
|
||||
0:77c170b2
|
||||
0:77c177a0
|
||||
0:77c177a2
|
||||
0:77c177a3
|
||||
0:77c177a5
|
||||
0:77c177a8
|
||||
0:77c177a9
|
||||
0:77c177aa
|
||||
0:77c177ad
|
||||
0:77c177b0
|
||||
0:77c177b2
|
||||
0:77c177b7
|
||||
0:77c177bd
|
||||
0:77c177c3
|
||||
0:77c177c6
|
||||
0:77c177c9
|
||||
0:77c177d0
|
||||
0:77c177d1
|
||||
0:77c177d3
|
||||
0:77c177d4
|
||||
0:77c177d6
|
||||
0:77c177d7
|
||||
0:77c230fb
|
||||
0:77c230fd
|
||||
0:77c230fe
|
||||
0:77c23100
|
||||
0:77c23107
|
||||
0:77c2310c
|
||||
0:77c2310f
|
||||
0:77c23111
|
||||
0:77c23117
|
||||
0:77c2311a
|
||||
0:77c23120
|
||||
0:77c23121
|
||||
@@ -1,14 +0,0 @@
|
||||
Buffer: DWORD PTR [ DWORD PTR [EBP+0x0C] ]
|
||||
Length: 18
|
||||
|
||||
No ignore APIs:
|
||||
python SymbolicExecutor/main.py --offset 0 --workspace w32api --buffer "DWORD PTR [ DWORD PTR [EBP+0x0C] ]" --size "0x12" tests/win32_api_test/win32_api_test.dmp
|
||||
|
||||
Ignore APIs:
|
||||
python SymbolicExecutor/main.py --offset 0 --workspace w32api --buffer "DWORD PTR [ DWORD PTR [EBP+0x0C] ]" --size "0x12" tests/win32_api_test/win32_api_test.dmp --names tests/win32_api_test/api_names.txt --log w32api/manticore.log
|
||||
|
||||
|
||||
APIs:
|
||||
KERNELBASE!WriteFile: 75627525
|
||||
kernel32!WriteFile: 756c1400
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
0x75627525 stdcall windows.KERNELBASE.WriteFile
|
||||
0x756c1400 stdcall windows.kernel32.WriteFile
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"--offset": "0",
|
||||
"--buffer": "DWORD PTR [ DWORD PTR [EBP+0x0C] ]",
|
||||
"--size": "0x12",
|
||||
"--procs": "2",
|
||||
"--names": "{dumpdir}/api_names.txt",
|
||||
"dump": "win32_api_test.dmp",
|
||||
"actual": "visited.txt",
|
||||
"expected": "win32_api_test_visited.txt"
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
// Windows
|
||||
// cl.exe /arch:IA32 /Fe:win32_api_test.exe win32_api_test.c
|
||||
|
||||
void crash_me(HANDLE hFile, const char **inputs) {
|
||||
|
||||
|
||||
DWORD dwWritten;
|
||||
|
||||
int i = 0;
|
||||
const char *line = NULL;
|
||||
int length = 0;
|
||||
|
||||
DWORD *lengths[3] = {
|
||||
&dwWritten,
|
||||
(DWORD*)(0xAAAAAAAA),
|
||||
NULL,
|
||||
};
|
||||
|
||||
__debugbreak();
|
||||
|
||||
length = strlen(inputs[0]);
|
||||
|
||||
while(inputs[i] != NULL) {
|
||||
line = inputs[i];
|
||||
|
||||
// iteration 0: manticore should silently ignore this WriteFile
|
||||
// iteration 1: manticore should detect a crash, if the model is good enough
|
||||
if(FALSE == WriteFile(hFile, line, length, lengths[i], NULL)) {
|
||||
printf("WriteFile failed\n");
|
||||
}
|
||||
|
||||
// make symbolic stuff actually matter. Need to generate a 'Z' to get
|
||||
// to the crashing input
|
||||
if(line[0] != 'Z') {
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, const char *argv[])
|
||||
{
|
||||
const char *inputs[3] = {
|
||||
"write me to a file",
|
||||
"write me to zfiles",
|
||||
NULL};
|
||||
|
||||
const char fname[] = "C:\\delete_me.txt";
|
||||
|
||||
HANDLE hFile = CreateFile(fname, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if(hFile == INVALID_HANDLE_VALUE) {
|
||||
printf("CreateFile failed");
|
||||
}
|
||||
crash_me(hFile, inputs);
|
||||
|
||||
CloseHandle(hFile);
|
||||
DeleteFile(fname);
|
||||
return 0;
|
||||
}
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -1,114 +0,0 @@
|
||||
import unittest
|
||||
import sys
|
||||
import shutil
|
||||
import tempfile
|
||||
import os
|
||||
import hashlib
|
||||
import subprocess
|
||||
import json
|
||||
import time
|
||||
|
||||
#logging.basicConfig(filename = "test.log",
|
||||
# format = "%(asctime)s: %(name)s:%(levelname)s: %(message)s",
|
||||
# level = logging.DEBUG)
|
||||
|
||||
class IntegrationTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
# Create a temporary directory
|
||||
self.test_dir = tempfile.mkdtemp()
|
||||
|
||||
def tearDown(self):
|
||||
# Remove the directory after the test
|
||||
shutil.rmtree(self.test_dir)
|
||||
|
||||
def _getDumpParams(self, jsonf):
|
||||
self.assertTrue(os.path.exists(jsonf))
|
||||
|
||||
c = open(jsonf, 'r').read()
|
||||
return json.loads(c)
|
||||
|
||||
def _loadVisitedSet(self, visited):
|
||||
|
||||
self.assertTrue(os.path.exists(visited))
|
||||
vitems = open(visited, 'r').read().splitlines()
|
||||
|
||||
vitems = map(lambda x: int(x[2:], 16), vitems)
|
||||
|
||||
return set(vitems)
|
||||
|
||||
def _runWithTimeout(self, procargs, timeout=600):
|
||||
|
||||
with open(os.path.join(os.pardir, "logfile"), "w") as output:
|
||||
#with open(os.path.join(os.pardir, "/dev/stdout"), "w") as output:
|
||||
po = subprocess.Popen(procargs, stdout=output)
|
||||
secs_used = 0
|
||||
|
||||
while po.poll() is None and secs_used < timeout:
|
||||
time.sleep(1)
|
||||
sys.stderr.write("~")
|
||||
secs_used += 1
|
||||
|
||||
self.assertTrue(secs_used < timeout)
|
||||
sys.stderr.write("\n")
|
||||
|
||||
def _runManticore(self, dumpname):
|
||||
|
||||
dirname = os.path.dirname(__file__)
|
||||
dumpdir = os.path.abspath(os.path.join(dirname, 'memdumps', dumpname))
|
||||
|
||||
self.assertTrue(os.path.exists(dumpdir))
|
||||
|
||||
jsonfile = os.path.join(dumpdir, 'args.json')
|
||||
|
||||
params = self._getDumpParams(jsonfile)
|
||||
|
||||
workspace = os.path.join(self.test_dir, 'ws_{}'.format(dumpname))
|
||||
logfile = os.path.join(workspace, "output.log")
|
||||
|
||||
dumpfile = os.path.join(dumpdir, params['dump'])
|
||||
|
||||
args = ['python', '-m', 'manticore', '--timeout', '400', '--workspace', workspace, dumpfile]
|
||||
|
||||
os.mkdir(workspace)
|
||||
|
||||
for k,v in params.iteritems():
|
||||
if k.startswith("--"):
|
||||
args.extend([k, v.format(dumpdir=dumpdir, workspace=workspace)])
|
||||
self._runWithTimeout(args, logfile)
|
||||
|
||||
efile = os.path.join(dumpdir, params['expected'])
|
||||
expected = self._loadVisitedSet(efile)
|
||||
|
||||
afile = os.path.join(workspace, params['actual'])
|
||||
actual = self._loadVisitedSet(afile)
|
||||
|
||||
self.assertGreaterEqual(actual, expected)
|
||||
|
||||
@unittest.skip('Windows temporarily unmaintained')
|
||||
def testSimpleParse(self):
|
||||
self._runManticore("simple_parse")
|
||||
|
||||
@unittest.skip('Windows temporarily unmaintained')
|
||||
def testSimpleDeref(self):
|
||||
self._runManticore("simple_bad_deref")
|
||||
|
||||
@unittest.skip('Windows temporarily unmaintained')
|
||||
def testSimpleBufferOverflow(self):
|
||||
self._runManticore("simple_buffer_overflow")
|
||||
|
||||
# generate too many states on memory concretization
|
||||
#def testSimpleFpu(self):
|
||||
# self._runManticore("simple_fpu")
|
||||
|
||||
# too slow processing REP SCASD
|
||||
@unittest.skip('TODO')
|
||||
def testWin32API(self):
|
||||
self._runManticore("win32_api_test")
|
||||
|
||||
@unittest.skip('Windows temporarily unmaintained')
|
||||
def testAPIInterception(self):
|
||||
self._runManticore("api_interception")
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user