rendered paste bodyimport glob, hashlib, os, syssys.path.append('..\\..')from PyStand import Structuint8 = Struct.uint8uint16 = Struct.uint16uint32 = Struct.uint32string = Struct.stringclass OptimisticObj(object): relocTypes = { 0x0006 : 4, 0x0007 : 4, 0x000A : 2, 0x000B : 4, 0x0014 : 4 } class ImageFileHeader(Struct): __endian__ = Struct.LE def __format__(self): self.machine, self.numberOfSections = uint16[2] self.timestamp, self.symtab, self.numsyms = uint32[3] self.optHdrSize, self.characteristics = uint16[2] class ImageSectionHeader(Struct): __endian__ = Struct.LE def __format__(self): self.Name = string(8, stripNulls=True) self.VirtualSize, self.VirtualAddress = uint32[2] self.SizeOfRawData, self.RawData = uint32[2] self.Relocations, self.Linenumbers = uint32[2] self.NumRelocations, self.NumLinenumbers = uint16[2] self.Characteristics = uint32 class ImageSymbol(Struct): __endian__ = Struct.LE def __format__(self): self.name = uint32[2] self.value = uint32 self.section = uint16 self.type = uint16 self.storageClass = uint8 self.numAuxSym = uint8 class ImageRelocation(Struct): __endian__ = Struct.LE def __format__(self): self.addr = uint32 self.symIndex = uint32 self.type = uint16 def __init__(self, data): self.signatures = [] self.data = data imgheader = self.ImageFileHeader(data) pos = len(imgheader) self.sections = [None] for i in xrange(imgheader.numberOfSections): sectheader = self.ImageSectionHeader() sectheader.unpack(data, pos) self.sections.append(sectheader) pos += len(sectheader) self.relocs = [None] for sectheader in self.sections: if sectheader == None: continue pos = sectheader.Relocations self.relocs.append({}) reloc = self.ImageRelocation() for i in xrange(sectheader.NumRelocations): reloc.unpack(data, pos) size = self.relocTypes[reloc.type] self.relocs[-1][reloc.addr] = size pos += len(reloc) imgsym = self.ImageSymbol() pos = imgheader.symtab symbols = [] for i in xrange(imgheader.numsyms): try: imgsym.unpack(data, pos) except: break if imgsym.name[0] != 0: name = data[pos:pos+8].rstrip('\0') else: temp = imgheader.symtab + (len(imgsym) * imgheader.numsyms) + imgsym.name[1] name = data[temp:].split('\0', 1)[0] pos += len(imgsym) if imgsym.storageClass == 2 and imgsym.type == 0x20 and imgsym.section != 0: if imgsym.numAuxSym == 1: size = uint32(data[pos+4:pos+8]) self.generateSignature(name, imgsym.section, imgsym.value, size) pos += 18 * imgsym.numAuxSym def generateSignature(self, name, sectionNum, addr, size): section = self.sections[sectionNum] pos = section.RawData + addr func = self.data[pos:pos+size] relocs = {} for relocAddr, relocSize in self.relocs[sectionNum].items(): if addr <= relocAddr < addr+size: relocAddr -= addr func = func[:relocAddr] + ('\0' * relocSize) + func[relocAddr+relocSize:] relocs[relocAddr] = relocSize blocks = [] cur = 0 i = 0 while i < size: if i in relocs: if cur != 0: blocks.append((i-cur, cur)) i += relocs[i] else: cur += 1 i += 1 if cur != 0: blocks.append((i-cur, cur)) if not len(blocks): return match = [] if blocks[0][0] == 0 and blocks[0][1] > 2: match.append(blocks[0]) blocks = blocks[1:] bigblocks = [block for block in blocks if block[1] >= 8] if len(bigblocks) > 0: match.append(bigblocks[0]) if len(bigblocks) > 1: match.append(bigblocks[-1]) if len(bigblocks) > 2: i = len(bigblocks) // 2 if i == 0: i += 1 match.append(bigblocks[i]) if len(match) != 4: blocks.sort(cmp=lambda x, y: cmp(y[1], x[1])) bigblocks += blocks for block in bigblocks: if block not in match: match.append(block) if len(match) == 4: break self.signatures.append((name, match, hash, relocs))class Optimistic(object): class AR_MemberHeader(Struct): __endian__ = Struct.LE def __format__(self): self.name = string(16) self.date = string(12) self.userID = string(6) self.groupID = string(6) self.mode = string(8) self.size = string(10) self.endHeader = string(2) self.data = string(0) def __init__(self, path): self.signatures = [] for fn in glob.glob(path + '\\*.lib'): self.splitLib(fn) print len(self.signatures) def splitLib(self, fn): fp = file(fn, 'rb') assert fp.read(8) == '!<arch>\n' print fn sigcount = 0 while True: member = self.readMember(fp) if not member: break if member.data[:2] == '\x4C\x01': obj = OptimisticObj(member.data) self.signatures += obj.signatures sigcount += len(obj.signatures) print sigcount def readMember(self, fp): member = self.AR_MemberHeader() try: member.unpack(fp.read(len(member))) except: return None assert member.endHeader == '`\n' member.data = fp.read(int(member.size)) if fp.tell() & 1: fp.read(1) return memberif __name__=='__main__': Optimistic(*sys.argv[1:])