Skip to content

Instantly share code, notes, and snippets.

@physacco
Created June 18, 2013 02:37
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save physacco/5802259 to your computer and use it in GitHub Desktop.
Save physacco/5802259 to your computer and use it in GitHub Desktop.
Dump a .pyc file to XML, with decompilation.
import pdb
import cgi
import dis
import time
import struct
import marshal
def dump_code_object(code, ident=0):
print '%s<code_object>' % (' '*ident,)
ident += 2
print '%s<co_argcount type="int">%d</co_argcount>' % (' '*ident, code.co_argcount)
print '%s<co_cellvars type="tuple">' % (' '*ident)
for cellvar in code.co_cellvars:
print '%s<co_cellvar>%s</co_cellvar>' % (' '*(ident+2), cellvar)
print '%s</co_cellvars>' % (' '*ident)
print '%s<co_code>' % (' '*ident)
print '%s<disassemble>' % (' '*(ident+2))
print '<![CDATA['
dis.dis(code)
print ']]>'
print '%s</disassemble>' % (' '*(ident+2))
print '%s<binary>' % (' '*(ident+2))
print '%s%r' % (' '*(ident+4), code.co_code)
print '%s</binary>' % (' '*(ident+2))
print '%s</co_code>' % (' '*ident)
print '%s<co_consts type="tuple">' % (' '*ident)
for const in code.co_consts:
if type(const) == type(code):
print '%s<co_const>' % (' '*(ident+2),)
dump_code_object(const, ident+4)
print '%s</co_const>' % (' '*(ident+2),)
#print '%s<co_const>%s</co_const>' % (' '*(ident+2), cgi.escape(str(const)))
else:
print '%s<co_const>%s</co_const>' % (' '*(ident+2), const)
print '%s</co_consts>' % (' '*ident)
print '%s<co_filename>%s</co_filename>' % (' '*ident, code.co_filename)
print '%s<co_firstlineno type="int">%s</co_firstlineno>' % (' '*ident, code.co_firstlineno)
print '%s<co_flags>%s</co_flags>' % (' '*ident, code.co_flags)
print '%s<co_freevars type="tuple">' % (' '*ident)
for freevar in code.co_freevars:
print '%s<co_freevar>%s</co_freevar>' % (' '*(ident+2), freevar)
print '%s</co_freevars>' % (' '*ident)
print '%s<co_lnotab>%s</co_lnotab>' % (' '*ident, `code.co_lnotab`)
print '%s<co_name type="str">%r</co_name>' % (' '*ident, cgi.escape(code.co_name))
print '%s<co_names type="tuple">' % (' '*ident)
for name in code.co_names:
print '%s<co_name type="str">%r</co_name>' % (' '*(ident+2), cgi.escape(name))
print '%s</co_names>' % (' '*ident)
print '%s<co_nlocals type="int">%d</co_nlocals>' % (' '*ident, code.co_nlocals)
print '%s<co_stacksize type="int">%d</co_stacksize>' % (' '*ident, code.co_stacksize)
print '%s<co_varnames type="tuple">' % (' '*ident)
for varname in code.co_varnames:
print '%s<co_varname>%r</co_varname>' % (' '*(ident+2), varname)
print '%s</co_varnames>' % (' '*ident)
ident -= 2
print '%s</code_object>' % (' '*ident,)
def dump_pyc(data):
ident = 0
print '<?xml version="1.0" encoding="UTF-8" ?>'
print '%s<pyc>' % (' '*ident,)
ident += 2
magic_s = pycdata[0:4]
magic = struct.unpack('=l', magic_s)[0] & 0xffff
print '%s<magic type="int">%d</magic>' % (' '*ident, magic)
time_s = pycdata[4:8]
time_i = struct.unpack('=l', time_s)[0]
ctime = time.ctime(time_i)
print '%s<timestamp>' % (' '*ident,)
print '%s<time>%s</time>' % (' '*(ident+2), time_i)
print '%s<ctime>%s</ctime>' % (' '*(ident+2), ctime)
print '%s</timestamp>' % (' '*ident,)
code = marshal.loads(pycdata[8:])
dump_code_object(code, ident)
ident -= 2
print '%s</pyc>' % (' '*ident,)
if __name__ == '__main__':
pycdata = open('test.pyc').read()
dump_pyc(pycdata)
#######################################################
# ['co_argcount', 'co_cellvars', 'co_code', 'co_consts', 'co_filename',
# 'co_firstlineno', 'co_flags', 'co_freevars', 'co_lnotab', 'co_name',
# 'co_names', 'co_nlocals', 'co_stacksize', 'co_varnames']
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment