1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
|
#!/usr/bin/env python2
# Mode: -*- python -*-
#
# Copyright (c) 2000-2002 by hartmut Goebel <hartmut@goebel.noris.de>
#
"""
Usage: decompyle [OPTIONS]... [ FILE | DIR]...
Examples:
decompyle foo.pyc bar.pyc # decompyle foo.pyc, bar.pyc to stdout
decompyle -o . foo.pyc bar.pyc # decompyle to ./foo.dis and ./bar.dis
decompyle -o /tmp /usr/lib/python1.5 # decompyle whole library
Options:
-o <path> output decompyled files to this path:
if multiple input files are decompyled, the common prefix
is stripped from these names and the remainder appended to
<path>
decompyle -o /tmp bla/fasel.pyc bla/foo.pyc
-> /tmp/fasel.dis, /tmp/foo.dis
decompyle -o /tmp bla/fasel.pyc bar/foo.pyc
-> /tmp/bla/fasel.dis, /tmp/bar/foo.dis
decompyle -o /tmp /usr/lib/python1.5
-> /tmp/smtplib.dis ... /tmp/lib-tk/FixTk.dis
--verify compare generated source with input byte-code
(requires -o)
--help show this message
Debugging Options:
--showasm include byte-code (disables --verify)
--showast include AST (abstract syntax tree) (disables --verify)
Extensions of generated files:
'.dis' successfully decompyled (and verified if --verify)
'.dis_unverified' successfully decompyled but --verify failed
'.nodis' decompyle failed (contact author for enhancement)
"""
Usage_short = \
"decomyple [--help] [--verify] [--showasm] [--showast] [-o <path>] FILE|DIR..."
import sys, string, getopt
from decompyle import decompyle_file, verify
import os, os.path, glob, time
showasm = showast = do_verify = 0
opto = 0; outfile = outdir = ''
def main(files, showasm=0, showast=0, do_verify=0,
opto=0, outfile=None, outdir=None):
pass
opts, args = getopt.getopt(sys.argv[1:], 'ho:',
['help', 'verify', 'showast', 'showasm'])
for opt, val in opts:
if opt in ('-h', '--help'):
print __doc__
sys.exit(0)
elif opt == '--verify':
do_verify = 1
elif opt == '--showasm':
showasm = 1
do_verify = 0
elif opt == '--showast':
showast = 1
do_verify = 0
elif opt == '-o':
outfile = val
else:
print Usage_short
sys.exit(1)
print args
sys.exit(0)
files = map(os.path.expanduser, args)
# argl, commonprefix works on strings, not on path parts,
# thus we must handle the case with files in 'some/classes'
# and 'some/cmds'
prefix = os.path.commonprefix(files)
if prefix[-1:] != os.sep:
prefix = os.path.join(os.path.dirname(prefix), '')
if len(files) > 1 and outfile:
outdir = outfile; outfile = ''
if not os.path.exists(outdir):
try:
os.makedirs(outdir)
except:
raise "Can't create output dir '%s'" % outdir
elif not os.path.isdir(outdir):
raise "Can't create output dir: '%s' exists" % outdir
elif os.path.isdir(outfile):
outdir = outfile; outfile = ''
prefix, dummy = os.path.split(files[0])
prefix = os.path.join(prefix, '')
print time.ctime(time.time()) #, args[0]
if sys.platform[:5] == 'linux' and os.uname()[2][:2] == '2.':
def __memUsage():
mi = open('/proc/%d/stat' % os.getpid(), 'r')
mu = string.split(mi.readline())[22]
mi.close()
return int(mu) / 1000000
else:
def __memUsage():
return ''
try:
for file in files:
#sys.stderr.write(file); sys.stderr.write('\n')
# build output filename depending on many possibilities
basename, ext = os.path.splitext(file)
if outdir:
basename = os.path.join(outdir, basename[len(prefix):])
dir = os.path.dirname(basename)
if not os.path.exists(dir):
try:
os.makedirs(dir)
except:
raise "Can't create output dir '%s'" % dir
of = basename + '.dis'
ff = basename + '.nodis'
elif outfile:
of = ff = outfile
elif opto:
of = basename + '.dis'
ff = basename + '.nodis'
else:
of = None
if of: # redirect to file
outstream = open(of, 'w')
if os.path.exists(ff): os.remove(ff)
else:
outstream = sys.stdout
# try to decomyple the input file
try:
decompyle_file(file, outstream, showasm, showast)
except KeyboardInterrupt:
if of:
outstream.close()
os.remove(of)
raise
except:
sys.stderr.write("### Can't decompyle %s\n" % file)
if of:
outstream.close()
os.rename(of, ff)
raise
else: # decompyle successfull
if of:
outstream.close()
if do_verify:
try:
verify.compare_code_with_srcfile(file, of)
print "+++ okay decompyling", file, __memUsage()
except verify.VerifyCmpError, e:
os.rename(of, '%s_unverified' % of)
sys.stderr.write("### Error Verifiying %s\n%s\n" % (file, e))
else:
print "+++ okay decompyling", file, __memUsage()
#time.sleep(12)
except KeyboardInterrupt, OSError:
pass
except verify.VerifyCmpError:
raise
print time.ctime(time.time())
|