def parseSections(self): self.sections = [] off = int(self.IMAGE_DOS_HEADER.e_lfanew) + vstruct.calcsize(vs_pe.IMAGE_NT_HEADERS) secsize = vstruct.calcsize(vs_pe.IMAGE_SECTION_HEADER) sbytes = self.readAtOffset(off, secsize * int(self.IMAGE_NT_HEADERS.FileHeader.NumberOfSections)) while sbytes: self.sections.append(vs_pe.IMAGE_SECTION_HEADER(sbytes[:secsize])) sbytes = sbytes[secsize:]
def parseSections(self): self.sections = [] off = int(self.IMAGE_DOS_HEADER.e_lfanew) + vstruct.calcsize( vs_pe.IMAGE_NT_HEADERS) secsize = vstruct.calcsize(vs_pe.IMAGE_SECTION_HEADER) sbytes = self.readAtOffset( off, secsize * int(self.IMAGE_NT_HEADERS.FileHeader.NumberOfSections)) while sbytes: self.sections.append(vs_pe.IMAGE_SECTION_HEADER(sbytes[:secsize])) sbytes = sbytes[secsize:]
def parseResources(self): self.id_resources = [] self.name_resources = [] self.IMAGE_RESOURCE_DIRECTORY = None sec = self.getSectionByName(".rsrc") if sec == None: return irdsize = vstruct.calcsize(vs_pe.IMAGE_RESOURCE_DIRECTORY) irdbytes = self.readAtRva(int(sec.VirtualAddress), irdsize) self.IMAGE_RESOURCE_DIRECTORY = vs_pe.IMAGE_RESOURCE_DIRECTORY( irdbytes) namecount = int(self.IMAGE_RESOURCE_DIRECTORY.NumberOfNamedEntries) idcount = int(self.IMAGE_RESOURCE_DIRECTORY.NumberOfIdEntries) entsize = 8 rsrcbase = int(sec.VirtualAddress) namebytes = self.readAtRva(rsrcbase + irdsize, namecount * entsize) idbytes = self.readAtRva(rsrcbase + irdsize + (namecount * entsize), idcount * entsize) while idbytes: name, offset = struct.unpack("<LL", idbytes[:entsize]) offset = offset & 0x7fffffff # HUH? if name == 16: print self.readAtRva(rsrcbase + offset, 40).encode("hex") self.id_resources.append((name, offset)) idbytes = idbytes[entsize:] while namebytes: #FIXME parse out the names to be nice. name, offset = struct.unpack("<LL", namebytes[:entsize]) namebytes = namebytes[entsize:]
def parseResources(self): self.id_resources = [] self.name_resources = [] self.IMAGE_RESOURCE_DIRECTORY = None sec = self.getSectionByName(".rsrc") if sec == None: return irdsize = vstruct.calcsize(vs_pe.IMAGE_RESOURCE_DIRECTORY) irdbytes = self.readAtRva(int(sec.VirtualAddress), irdsize) self.IMAGE_RESOURCE_DIRECTORY = vs_pe.IMAGE_RESOURCE_DIRECTORY(irdbytes) namecount = int(self.IMAGE_RESOURCE_DIRECTORY.NumberOfNamedEntries) idcount = int(self.IMAGE_RESOURCE_DIRECTORY.NumberOfIdEntries) entsize = 8 rsrcbase = int(sec.VirtualAddress) namebytes = self.readAtRva(rsrcbase + irdsize, namecount * entsize) idbytes = self.readAtRva(rsrcbase + irdsize + (namecount*entsize), idcount * entsize) while idbytes: name,offset = struct.unpack("<LL", idbytes[:entsize]) offset = offset & 0x7fffffff # HUH? if name == 16: print self.readAtRva(rsrcbase + offset, 40).encode("hex") self.id_resources.append((name,offset)) idbytes = idbytes[entsize:] while namebytes: #FIXME parse out the names to be nice. name,offset = struct.unpack("<LL", namebytes[:entsize]) namebytes = namebytes[entsize:]
def parseExports(self): # Initialize our required locals. self.exports = [] self.forwarders = [] self.IMAGE_EXPORT_DIRECTORY = None edir = self.IMAGE_NT_HEADERS.OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT] poff = self.rvaToOffset(int(edir.VirtualAddress)) if poff == 0: # No exports... return esize = vstruct.calcsize(vs_pe.IMAGE_EXPORT_DIRECTORY) ebytes = self.readAtOffset(poff, esize) self.IMAGE_EXPORT_DIRECTORY = vs_pe.IMAGE_EXPORT_DIRECTORY(ebytes) funcoff = self.rvaToOffset( int(self.IMAGE_EXPORT_DIRECTORY.AddressOfFunctions)) funcsize = 4 * int(self.IMAGE_EXPORT_DIRECTORY.NumberOfFunctions) funcbytes = self.readAtOffset(funcoff, funcsize) nameoff = self.rvaToOffset( int(self.IMAGE_EXPORT_DIRECTORY.AddressOfNames)) namesize = 4 * int(self.IMAGE_EXPORT_DIRECTORY.NumberOfNames) namebytes = self.readAtOffset(nameoff, namesize) ordoff = self.rvaToOffset( int(self.IMAGE_EXPORT_DIRECTORY.AddressOfOrdinals)) ordsize = 2 * int(self.IMAGE_EXPORT_DIRECTORY.NumberOfNames) ordbytes = self.readAtOffset(ordoff, ordsize) funclist = struct.unpack("%dI" % (len(funcbytes) / 4), funcbytes) namelist = struct.unpack("%dI" % (len(namebytes) / 4), namebytes) ordlist = struct.unpack("%dH" % (len(ordbytes) / 2), ordbytes) base = int(self.IMAGE_NT_HEADERS.OptionalHeader.ImageBase) #for i in range(len(funclist)): for i in range(len(namelist)): ord = ordlist[i] nameoff = self.rvaToOffset(namelist[i]) funcoff = funclist[i] ffoff = self.rvaToOffset(funcoff) name = None if nameoff != 0: name = self.readAtOffset(nameoff, 256).split("\x00", 1)[0] else: name = "ord_%.4x" % ord if ffoff >= poff and ffoff < poff + int(edir.Size): fwdname = self.readAtOffset(ffoff, 260).split("\x00", 1)[0] self.forwarders.append((name, fwdname)) else: self.exports.append((base + funclist[i], ord, name))
def getStruct(self, sname, address): """ Retrieve a vstruct structure populated with memory from the specified address. Returns a standard vstruct object. """ cls = vstruct.getStructClass(sname) size = vstruct.calcsize(cls) bytes = self.readMemory(address, size) return cls(bytes)
def parseExports(self): # Initialize our required locals. self.exports = [] self.forwarders = [] self.IMAGE_EXPORT_DIRECTORY = None edir = self.IMAGE_NT_HEADERS.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT] poff = self.rvaToOffset(int(edir.VirtualAddress)) if poff == 0: # No exports... return esize = vstruct.calcsize(vs_pe.IMAGE_EXPORT_DIRECTORY) ebytes = self.readAtOffset(poff, esize) self.IMAGE_EXPORT_DIRECTORY = vs_pe.IMAGE_EXPORT_DIRECTORY(ebytes) funcoff = self.rvaToOffset(int(self.IMAGE_EXPORT_DIRECTORY.AddressOfFunctions)) funcsize = 4 * int(self.IMAGE_EXPORT_DIRECTORY.NumberOfFunctions) funcbytes = self.readAtOffset(funcoff, funcsize) nameoff = self.rvaToOffset(int(self.IMAGE_EXPORT_DIRECTORY.AddressOfNames)) namesize = 4 * int(self.IMAGE_EXPORT_DIRECTORY.NumberOfNames) namebytes = self.readAtOffset(nameoff, namesize) ordoff = self.rvaToOffset(int(self.IMAGE_EXPORT_DIRECTORY.AddressOfOrdinals)) ordsize = 2 * int(self.IMAGE_EXPORT_DIRECTORY.NumberOfNames) ordbytes = self.readAtOffset(ordoff, ordsize) funclist = struct.unpack("%dI" % (len(funcbytes) / 4), funcbytes) namelist = struct.unpack("%dI" % (len(namebytes) / 4), namebytes) ordlist = struct.unpack("%dH" % (len(ordbytes) / 2), ordbytes) base = int(self.IMAGE_NT_HEADERS.OptionalHeader.ImageBase) #for i in range(len(funclist)): for i in range(len(namelist)): ord = ordlist[i] nameoff = self.rvaToOffset(namelist[i]) funcoff = funclist[i] ffoff = self.rvaToOffset(funcoff) name = None if nameoff != 0: name = self.readAtOffset(nameoff, 256).split("\x00", 1)[0] else: name = "ord_%.4x" % ord if ffoff >= poff and ffoff < poff + int(edir.Size): fwdname = self.readAtOffset(ffoff, 260).split("\x00", 1)[0] self.forwarders.append((name,fwdname)) else: self.exports.append((base + funclist[i], ord, name))
def __init__(self, fd, inmem=False): """ Construct a PE object. use inmem=True if you are using a MemObjFile or other "memory like" image. """ object.__init__(self) self.inmem = inmem self.fd = fd self.fd.seek(0) dosbytes = fd.read(vstruct.calcsize(vs_pe.IMAGE_DOS_HEADER)) self.IMAGE_DOS_HEADER = vs_pe.IMAGE_DOS_HEADER(dosbytes) fd.seek(int(self.IMAGE_DOS_HEADER.e_lfanew)) ntbytes = fd.read(vstruct.calcsize(vs_pe.IMAGE_NT_HEADERS)) #FIXME if code offset != sizeof nt headers, maybe old PE... handle them too self.IMAGE_NT_HEADERS = vs_pe.IMAGE_NT_HEADERS(ntbytes) if int(self.IMAGE_NT_HEADERS.FileHeader.SizeOfOptionalHeader) != 224: print "ERROR: SizeOfOptionalHeader != 224"
def parseImports(self): self.imports = [] self.IMAGE_IMPORT_DIRECTORY = None idir = self.IMAGE_NT_HEADERS.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] poff = self.rvaToOffset(int(idir.VirtualAddress)) if poff == 0: return esize = vstruct.calcsize(vs_pe.IMAGE_IMPORT_DIRECTORY) ebytes = self.readAtOffset(poff, esize) self.IMAGE_IMPORT_DIRECTORY = vs_pe.IMAGE_IMPORT_DIRECTORY(ebytes)
def parseImports(self): self.imports = [] self.IMAGE_IMPORT_DIRECTORY = None idir = self.IMAGE_NT_HEADERS.OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_IMPORT] poff = self.rvaToOffset(int(idir.VirtualAddress)) if poff == 0: return esize = vstruct.calcsize(vs_pe.IMAGE_IMPORT_DIRECTORY) ebytes = self.readAtOffset(poff, esize) self.IMAGE_IMPORT_DIRECTORY = vs_pe.IMAGE_IMPORT_DIRECTORY(ebytes)