All pastes #776867 Raw Edit

Anonymous

public python v1 · immutable
·published 2007-11-16 10:22 UTC
rendered paste body
import 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:])