All pastes #631109 Raw Edit

Python

public python v1 · immutable
#631109 ·published 2007-07-23 18:49 UTC
rendered paste body
#!/usr/bin/env pythonfrom os import popenfrom sys import argv, stderr, exitdll = argv[1]#objdump = "~/xda/wince-cross/usr/local/wince/cross-tools/bin/arm-wince-pe-objdump"objdump = "~/src/oe/build/openmoko/cross/arm-linux/bin/objdump"section_name   = []section_size   = []section_vma    = []section_offset = []imagebase = 0## is this a branch with link instruction?#def isbl(inst):	return (inst[0:2] == 'bl') and ((len(inst) == 2) or (inst[2] != 's'))## is this a load or store instruction?#def isldrstr(inst):	return inst[0:3] in ["ldr", "str"]## extract the address from a string that optionally starts with '; '.# the address has optional '0x' prefix and optional appended '<symbol_name>'#def extract_address(s):	if s[:2] == '; ':		start = 2	else:		start = 0	if s[start:start+2] == '0x':		start += 2	end = s.find("<")	if end >= 0:		return int(s[start:end],16)	else:		return int(s[start:],16)## character representation of a word#def asciichar(c):	if c >= 32 and c < 128:		return chr(c)	else:		return '.'def fourcc(data):	return "%c%c%c%c" % (asciichar(data & 0xff), asciichar((data>>8) & 0xff),	                     asciichar((data>>16) & 0xff), asciichar((data>>24) & 0xff))## is this an executable with headers?#ftype = popen("file %s" % dll).readlines()[0].split(' ')[1].replace("\n","")if ftype != "data":	#	# parse section headers	#	for l in popen("%s -h %s | grep ' \.'" % (objdump, dll)).readlines():		t = l.split()		section_name   = section_name   + [t[1]]		section_size   = section_size   + [int(t[2],16)]		section_vma    = section_vma    + [int(t[3],16)]		section_offset = section_offset + [int(t[5],16)]else:	section_name   = ["none"]	section_size   = [256*1024]	section_vma    = [0]	section_offset = [0]## virtual memory address <--> file offset translation#def vma_to_offset(vma):	i=0	while i < len(section_size):		if (vma >= section_vma[i]) and (vma < section_vma[i]+section_size[i]):			return vma-section_vma[i]+section_offset[i]		i=i+1def offset_to_vma(offset):	i=0	while i < len(section_size):		if (offset >= section_offset[i]) and (offset < section_offset[i]+section_size[i]):			return offset-section_offset[i]+section_vma[i]		i=i+1def vma_in_section(vma):	i=0	while i < len(section_size):		if (vma >= section_vma[i]) and (vma < section_vma[i]+section_size[i]):			return True		i=i+1	return False## parse strings into a dictionary (0xADDR : "string")#strings = {}strlen = {}for l in popen("strings -tx %s" % dll).readlines():	l = l.split(None,1)	if len(l) != 2:		continue	addr = offset_to_vma(int(l[0],16))	text = l[1].replace("\n","")	strings[addr] = text	strlen[addr] = (len(text)-1)/4+1# unicode stringsfor l in popen("strings -tx -el %s" % dll).readlines():	l = l.split(None,1)	if len(l) != 2:		continue	addr = offset_to_vma(int(l[0],16))	text = l[1].replace("\n","")	if not strings.has_key(addr):		strings[addr] = text		strlen[addr] = len(text)/2+1#print "STRING TABLE"#print "vma      offset   string"#for k in strings.keys():#	print '%8x %8x %s' % (k, vma_to_offset(k), strings[k])## parse function table into a dictionary (0xADDR : "name")#pipe = popen("%s -T %s | grep '^[0-9a-f]\{8\}'" % (objdump, dll))ll=pipe.readlines()pipe.close()ftable = {}for l in ll:	addr = int(l[:8],16)	ftable[addr] = l[44:-1].strip()## custom function information#custom_ftable = []custom_ftable = file(dll+".ftable").readlines()for l in custom_ftable:	if l[0] == '#':		continue	t = l.split('\t')	if len(t) < 2:		continue	ftable[int(t[0],16)] = t[1]ftable[0x31ef0] = "DIS31ef0"#print "FUNCTION TABLE"#for k in ftable.keys():#	print "%8x %s" % (k, ftable[k])## disassemble#stderr.write("Disassembling...\n")if ftype == "data":	pipe = popen("%s -b binary -m arm -D %s" % (objdump, dll))else:	pipe = popen("%s -D %s" % (objdump, dll))	#pipe = popen("%s -d %s" % (objdump, dll))ll=pipe.readlines()pipe.close()datadict   = {}referenced = {}jumped_to  = {}stderr.write("Finding references...\n")i = 0while i+1 < len(ll):	i=i+1	l=ll[i]	if (l == '\t...') or (l == '\n'):		continue	t = l.split('\t')	if (len(t[0]) == 0) or (t[0][-1] != ':') or (len(t) < 3):		continue	addr = int(t[0][0:-1].strip(),16)	data = int(t[1],16)	datadict[addr] = data	# only evaluate references	inst = t[2][0:3]	if isldrstr(inst):		if t[len(t)-1][:2] == '; ':			ref = extract_address(t[len(t)-1])			if vma_in_section(ref):				referenced[ref] = 0	if isbl(inst):		target = extract_address(t[3])		if vma_in_section(target):			if target in jumped_to.keys():				jumped_to[target].append("0x%08x" % addr)			else:				jumped_to[target] = ["0x%08x" % addr]## resolve references#stderr.write("Resolving references...\n");for ref in referenced.keys():	if datadict.has_key(ref):		referenced[ref] = datadict[ref]		if datadict.has_key(referenced[ref]):			referenced[referenced[ref]] = datadict[referenced[ref]]	else:		referenced[ref] = 0## go! go! go!#stderr.write("Generating disassembled output...\n")armreg = { 'r0': 0, 'r1': 1, 'r2': 2, 'r3': 3, 'r4': 4, 'r5': 5, 'r6': 6, 'r7': 7,           'r8': 8, 'r9': 9, 'sl': 10, 'fp': 11, 'ip': 12, 'sp': 13, 'lr': 14, 'pc': 15 }r = [0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0]section = Nonei = 0while i+1 < len(ll):	i=i+1	l=ll[i].strip('\n')		if (l == '\t...') or (l == '\n'):		#print l		continue	t = l.split('\t')	if (len(t[0]) == 0) or (t[0][-1] != ':') or (len(t) < 3):		if t[0][:23] == "Disassembly of section ":			section = t[0][23:-1]			print "Section %s" % section		continue	addr = int(t[0][0:-1].strip(),16)	data = int(t[1],16)	inst = t[2]	section_list = [".text", ".rodata", ".data.rel.ro", ".data", ".bss"]		if not (section in section_list):		continue	#	# print function header comment	#	if ftable.has_key(addr):		print "\n/*\n * %s\n */" % ftable[addr]		if jumped_to.has_key(addr):			print "/*\n * %s\n */" % jumped_to[addr]	#	# interpret some instructions	#	r[15] = addr+8	intstr = ""	if inst == "ldr":		a = t[3][:2]		b = t[3][5:7]		if armreg.has_key(a) and armreg.has_key(b):			if t[3][4:10] == "[pc, #":				target_addr = extract_address(t[4])				if datadict.has_key(target_addr):					r[armreg[a]] = datadict[target_addr]					intstr = "%s = %x" % (a, r[armreg[a]])				else:					r[armreg[a]] = 0xbaadbaad			else:				c = t[3][9:]				if t[3][7] == ']':					target_addr = r[armreg[b]]				elif c[0] == '#':					if c[-1] == '!':						target_addr = r[armreg[b]] + int(c[1:-2])						r[armreg[b]] += int(c[1:-2])					else:						target_addr = r[armreg[b]] + int(c[1:-1])				elif armreg.has_key(c[:-1]):					target_addr = r[armreg[b]] + r[armreg[c[:-1]]]				else:					target_addr = 0xbaadbaad				if datadict.has_key(target_addr):					r[armreg[a]] = datadict[target_addr]					intstr = "%s = %x (<-- %x)" % (a, r[armreg[a]], target_addr)				else:					intstr = "ERR %x" % target_addr					r[armreg[a]] = 0xbaadbaad		else:			intstr = "FIXME"			if armreg.has_key(a):				r[armreg[a]] = 0xbaadbaad	if inst == "mov":		a = t[3][:2]		if armreg.has_key(a):			b = t[3][4:]			if b[0] == '#':				r[armreg[a]] = int(b[1:])				intstr = "%s = %x" % (a, r[armreg[a]])			elif armreg.has_key(b):				r[armreg[a]] = r[armreg[b]]				intstr = "%s = %x" % (a, r[armreg[a]])			else:				intstr = "FIXME"				r[armreg[a]] = 0xbaadbaad		else:			intstr = "ERR"	if inst == "add":		a = t[3][:2]		b = t[3][4:6]		if armreg.has_key(a) and armreg.has_key(b):			c = t[3][8:]			if c[0] == '#':				r[armreg[a]] = (r[armreg[b]] + int(c[1:])) & 0xffffffff				intstr = "%s = %x" % (a, r[armreg[a]])			elif armreg.has_key(c):				r[armreg[a]] = (r[armreg[b]] + r[armreg[c]]) & 0xffffffff				intstr = "%s = %x" % (a, r[armreg[a]])			else:				intstr = "FIXME"				r[armreg[a]] = 0xbaadbaad		else:			intstr = "FIXME"			if armreg.has_key(a):				r[armreg[a]] = 0xbaadbaad	if len(intstr) < 8:		intstr = intstr + "\t\t"	elif len(intstr) < 16:		intstr = intstr + "\t"	print intstr,	#	# print line	#	if strings.has_key(addr):		print "%8x:\t\"%s\"" % (addr, strings[addr])		if(strlen[addr]>1):			i += strlen[addr]-1			l = ll[i+1]			t = l.split('\t')			if len(t)>2:				next = int(ll[i+1].strip('\n').split('\t')[1],16)				if next in [0x0, 0xa]:					i += 1	elif referenced.has_key(addr):		if strings.has_key(data):			print "%8x:\t\"%s\"" % (addr, strings[data])			if(strlen[data]>1):				i += strlen[data]-1				l = ll[i+1]				t = l.split('\t')				if len(t)>2:					next = int(ll[i+1].strip('\n').split('\t')[1],16)					if next in [0x0, 0xa]:						i += 1		elif referenced.has_key(data):			if datadict.has_key(referenced[data]):				if strings.has_key(referenced[data]):					print "%8x:\t%08x --> \"%s\"" % (addr, data, strings[referenced[data]])				else:					print "%8x:\t%08x --> %08x" % (addr, data, datadict[referenced[data]])			else:				print "%8x:\t%08x --> ? (at %08x)" % (addr, data, referenced[data])		else:			if len(t) > 3:				print "%8x:\t%08x %s\t%s\t%s\t; (ref.d somewhere)" % (addr, data, fourcc(data), t[2], t[3])			else:				print "%8x:\t%08x %s\t%s\t; (ref.d somewhere)" % (addr, data, fourcc(data), t[2])	elif t[len(t)-1][0:4] == '; 0x':		ref = int(t[len(t)-1][4:],16)		if referenced.has_key(ref) and ref != 0:			if datadict.has_key(referenced[ref]):				if strings.has_key(referenced[ref]):					print "%s = 0x%08x --> \"%s\"" % (l, referenced[ref], strings[referenced[ref]])				else:					print "%s = 0x%08x --> %08x" % (l, referenced[ref], datadict[referenced[ref]])			else:				print "%s --> 0x%08x" % (l, referenced[ref])		else:			print l	elif addr in jumped_to.keys():		print "\n/*\n *",		print jumped_to[addr],		print "\n */\n%s" % l	elif isldrstr(inst):		if t[len(t)-1][:2] == '; ':			ref = extract_address(t[len(t)-1])			if referenced.has_key(ref):				if datadict.has_key(referenced[ref]):					if strings.has_key(referenced[ref]):						print "%s = 0x%08x --> \"%s\"" % (l, referenced[ref], strings[referenced[ref]])					else:						print "%s = 0x%08x --> %08x" % (l, referenced[ref], datadict[referenced[ref]])				else:					print "%s --> 0x%08x" % (l, referenced[ref])			else:				print "INTERNAL ERROR, REFERENCE SHOULD EXIST"				exit(1)		else:			print l	elif isbl(inst):		target = extract_address(t[3])		if ftable.has_key(target):			pos = l.rfind("<")			if pos >= 0:				print l[:pos],			else:				print l,			print "<%s>" % ftable[target],			if ftable[target] in ["printf", "puts", "fwrite"]:				print "r0 = 0x%x" % r[0],				if strings.has_key(r[0]):					print "--> \"%s\"" % strings[r[0]],			elif ftable[target] in ["sprintf, vsprintf", "fprintf"]:				print "r1 = 0x%x" % r[1],				if strings.has_key(r[1]):					print "--> \"%s\"" % strings[r[1]],			elif ftable[target] in ["putchar", "fputc"]:				print "r0 = 0x%x" % r[0]			elif ftable[target] == "fread":				print "r0 = 0x%x" % r[0]			elif ftable[target] == "DIS31ef0":				if strings.has_key(r[1]):					print "r0 = 0x%x, r1 = \"%s\"" % (r[0], strings[r[1]])				else:					print "r0 = 0x%x, r1 = 0x%x" % (r[0], r[1])			print		else:			print l	else:		if strings.has_key(data):			print "%s\t; --> \"%s\"" % (l, strings[data])		elif ftable.has_key(data):			print "%s\t; --> <%s>" % (l, ftable[data])		else:			print "%8x:\t%08x %s\t%s" % (addr, data, fourcc(data), '\t'.join(t[2:]))		continue