如何反编译Python代码


uncompyle6: 一个跨版本的 Python 字节码反编译器!

uncompyle6 是一个原生 python 的跨版本反编译器和 fragment 反编译器,是 decompyleuncompyleuncompyle2 等工具的接替者。uncompyle6 可将 python 字节码转换回等效的 python 源代码,它接受 python 1.0 版到 3.8 版的字节码,这其中跨越了 24 年的 python 版本,此外还包括 DropboxPython 2.5 字节码和一些 PyPy 字节码。

如何反编译Python代码


需要了解其实现原理,可以参考官方文档,进行学习。

  • [1] 安装工具
# 直接安装工具
$ pip install uncompyle6

# 安装最新版本
$ python setup.py instal
  • [2] 使用方式
# 基本语法结构
$ uncompyle6 *compiled-python-file-pyc-or-pyo*
# 帮助文档信息
$ uncompyle6 -h

Usage:
  uncompyle6 [OPTIONS]... [ FILE | DIR]...
  uncompyle6 [--help | -h | --V | --version]

Examples:
  uncompyle6      foo.pyc bar.pyc       # decompile foo.pyc, bar.pyc to stdout
  uncompyle6 -o . foo.pyc bar.pyc       # decompile to ./foo.pyc_dis and ./bar.pyc_dis
  uncompyle6 -o /tmp /usr/lib/python1.5 # decompile whole library

Options:
  -o <path>     output decompiled files to this path:
                if multiple input files are decompiled, the common prefix
                is stripped from these names and the remainder appended to
                <path>
                  uncompyle6 -o /tmp bla/fasel.pyc bla/foo.pyc
                    -> /tmp/fasel.pyc_dis, /tmp/foo.pyc_dis
                  uncompyle6 -o /tmp bla/fasel.pyc bar/foo.pyc
                    -> /tmp/bla/fasel.pyc_dis, /tmp/bar/foo.pyc_dis
                  uncompyle6 -o /tmp /usr/lib/python1.5
                    -> /tmp/smtplib.pyc_dis ... /tmp/lib-tk/FixTk.pyc_dis
  --compile | -c <python-file>
                attempts a decompilation after compiling <python-file>
  -d            print timestamps
  -p <integer>  use <integer> number of processes
  -r            recurse directories looking for .pyc and .pyo files
  --fragments   use fragments deparser
  --verify      compare generated source with input byte-code
  --verify-run  compile generated source, run it and check exit code
  --syntax-verify compile generated source
  --linemaps    generated line number correspondencies between byte-code
                and generated source output
  --encoding  <encoding>
                use <encoding> in generated source according to pep-0263
  --help        show this message

Debugging Options:
  --asm     | -a        include byte-code       (disables --verify)
  --grammar | -g        show matching grammar
  --tree={before|after}
  -t {before|after}     include syntax before (or after) tree transformation
                        (disables --verify)
  --tree++ | -T         add template rules to --tree=before when possible

Extensions of generated files:
  '.pyc_dis' '.pyo_dis'   successfully decompiled (and verified if --verify)
    + '_unverified'       successfully decompile but --verify failed
    + '_failed'           decompile failed (contact author for enhancement)
  • [3] 示例演示
# -o 参数是用来指定反编译的文件存储
$ uncompyle6 -o test.py test.pyc
# 批量反编译
import os

file_path = '/Users/escape/app/user_proxy'

for root, dirs, files in os.walk(file_path):
    for file in files:
        file_name, file_suffix = file.split(".")
        if file.endswith('pyc') or file.endswith('pyo'):
            print(f">>> filename: {filename} to do ...")
            os.system(f"uncompyle6 -o {os.path.join(root, file_name, 'py')} {filename}")

文章作者: Escape
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Escape !