Python Uncompyle6 反编译工具使用 与 Magic Number 详解 您所在的位置:网站首页 三一重卡质量怎么样 Python Uncompyle6 反编译工具使用 与 Magic Number 详解

Python Uncompyle6 反编译工具使用 与 Magic Number 详解

2024-01-28 15:11| 来源: 网络整理| 查看: 265

Python Uncompyle6 反编译工具使用 与 Magic Number 详解

  最近在i春秋刷MISC题的时候,做到了好几道有pyc文件需要反编译的题,也了解到了一个非常神的Python反编译工具——Python Uncompyle6。虽然只用到了其中的一个功能,但它留给我的印象却十分友善。通过命令行调用,较为方便;支持Python编译器版本丰富,几乎涵盖了所有版本;最主要的优点是:不会卡Bug。(与Pycdc相比友善很多~~(可能只是我技术比较菜)~~)。   另外,在部分题目中,使用pyinstaller导出的pyc文件会将文件的Magic Number和时间戳信息抹去,反编译时工具会报错,我们需要手动添加Magic Number与时间戳,时间戳可以随便添加(全0也可以),但是每个版本Python编译的pyc文件Magic Number 都不同,需要我们手动查找与填充,下面将介绍一个方便获取Magic Number的方法(网上有关Magic Number对照的信息太少了)

Uncompyle6 介绍

  Uncompyle6,是一个Python原生的跨版本反编译器,是decompyle, uncompyle, uncompyle2的后继版本。   Uncompyle6能够将Python二进制文件pyc, pyo反编译为对应的源代码。支持Python 1.0-3.8版本的反编译,拥有较好的逻辑处理和解析能力。

Uncompyle6 安装与使用

安装不用多说,上pip完事

pip install uncompyle6

使用也非常简单,在命令行中,uncompyle6加上需要反编译的文件参数即可,注意使用-o 选项输出到文件中

uncompyle6 -o test.py test.pyc

这会将test.pyc文件反编译,并输出到test.py文件中

注:如果遇到错误,可能因为pyc文件生成时,头部的magic number被清理,需要另外补上,请看下一节内容

Magic Number in Python

一开始,因为不知道版本号对应的Magic Number,我以前将一些版本的Python环境下载,再编译,逐个对照,现在想来,笨办法实锤。

Magic Number

通过一个开源的Python虚拟机解包工具Pyinstxtractor的源码中关于Magic Number的内容,似乎找到了一点头绪。

importlib

Magic Number的生成和其他操作,似乎在importlib库中的util文件中,查看一下util文件

util

发现又是从.bootstrap_external中引用的,再跳一次

Magic Number

一些Magic Number的介绍注释

Known Values

Magic Number 已知列表,在文末附上

接下来就算找到了Magic Number的版本对照表。但是,我们知道的Magic Number是四字节二进制数据,应该如何转换?再往下找,在注释后面的代码里,我们找到了样例

MAGIC_NUMBER = (3413).to_bytes(2, 'little') + b'\r\n' _RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c

这里的3413就是Python 3.8b4版本的Magic Number,执行一下,就得到了四字节的二进制码0x0A0D0D55。其他版本的对应二进制码,可以按照上面步骤计算得到。 注意:四字节的Magic Number为小端序,注意区分

Pyc文件修复

我们已经得到了Magic Number 的二进制码,下面就可以修复pyc文件了

再次用到pyinstxtractor源码,找到输出pyc文件部分

WritePYC

在Python3.7及以上版本的编译后二进制文件中,头部除了四字节Magic Number,还有四个字节的空位和八个字节的时间戳+大小信息,后者对文件反编译没有影响,全部填充0即可;Python3.3 - Python3.7(包含3.3)版本中,只需要Magic Number和八位时间戳+大小信息Python3.3 以下的版本中,只有Magic Number和四位时间戳

用Winhex修复文件,在头部写入(非覆盖)上述格式的内容,就可以进行反编译了

附录 Magic Number 对照表 Known values: # Python 1.5: 20121 # Python 1.5.1: 20121 # Python 1.5.2: 20121 # Python 1.6: 50428 # Python 2.0: 50823 # Python 2.0.1: 50823 # Python 2.1: 60202 # Python 2.1.1: 60202 # Python 2.1.2: 60202 # Python 2.2: 60717 # Python 2.3a0: 62011 # Python 2.3a0: 62021 # Python 2.3a0: 62011 (!) # Python 2.4a0: 62041 # Python 2.4a3: 62051 # Python 2.4b1: 62061 # Python 2.5a0: 62071 # Python 2.5a0: 62081 (ast-branch) # Python 2.5a0: 62091 (with) # Python 2.5a0: 62092 (changed WITH_CLEANUP opcode) # Python 2.5b3: 62101 (fix wrong code: for x, in ...) # Python 2.5b3: 62111 (fix wrong code: x += yield) # Python 2.5c1: 62121 (fix wrong lnotab with for loops and # storing constants that should have been removed) # Python 2.5c2: 62131 (fix wrong code: for x, in ... in listcomp/genexp) # Python 2.6a0: 62151 (peephole optimizations and STORE_MAP opcode) # Python 2.6a1: 62161 (WITH_CLEANUP optimization) # Python 2.7a0: 62171 (optimize list comprehensions/change LIST_APPEND) # Python 2.7a0: 62181 (optimize conditional branches: # introduce POP_JUMP_IF_FALSE and POP_JUMP_IF_TRUE) # Python 2.7a0 62191 (introduce SETUP_WITH) # Python 2.7a0 62201 (introduce BUILD_SET) # Python 2.7a0 62211 (introduce MAP_ADD and SET_ADD) # Python 3000: 3000 # 3010 (removed UNARY_CONVERT) # 3020 (added BUILD_SET) # 3030 (added keyword-only parameters) # 3040 (added signature annotations) # 3050 (print becomes a function) # 3060 (PEP 3115 metaclass syntax) # 3061 (string literals become unicode) # 3071 (PEP 3109 raise changes) # 3081 (PEP 3137 make __file__ and __name__ unicode) # 3091 (kill str8 interning) # 3101 (merge from 2.6a0, see 62151) # 3103 (__file__ points to source file) # Python 3.0a4: 3111 (WITH_CLEANUP optimization). # Python 3.0b1: 3131 (lexical exception stacking, including POP_EXCEPT #3021) # Python 3.1a1: 3141 (optimize list, set and dict comprehensions: # change LIST_APPEND and SET_ADD, add MAP_ADD #2183) # Python 3.1a1: 3151 (optimize conditional branches: # introduce POP_JUMP_IF_FALSE and POP_JUMP_IF_TRUE #4715) # Python 3.2a1: 3160 (add SETUP_WITH #6101) # tag: cpython-32 # Python 3.2a2: 3170 (add DUP_TOP_TWO, remove DUP_TOPX and ROT_FOUR #9225) # tag: cpython-32 # Python 3.2a3 3180 (add DELETE_DEREF #4617) # Python 3.3a1 3190 (__class__ super closure changed) # Python 3.3a1 3200 (PEP 3155 __qualname__ added #13448) # Python 3.3a1 3210 (added size modulo 2**32 to the pyc header #13645) # Python 3.3a2 3220 (changed PEP 380 implementation #14230) # Python 3.3a4 3230 (revert changes to implicit __class__ closure #14857) # Python 3.4a1 3250 (evaluate positional default arguments before # keyword-only defaults #16967) # Python 3.4a1 3260 (add LOAD_CLASSDEREF; allow locals of class to override # free vars #17853) # Python 3.4a1 3270 (various tweaks to the __class__ closure #12370) # Python 3.4a1 3280 (remove implicit class argument) # Python 3.4a4 3290 (changes to __qualname__ computation #19301) # Python 3.4a4 3300 (more changes to __qualname__ computation #19301) # Python 3.4rc2 3310 (alter __qualname__ computation #20625) # Python 3.5a1 3320 (PEP 465: Matrix multiplication operator #21176) # Python 3.5b1 3330 (PEP 448: Additional Unpacking Generalizations #2292) # Python 3.5b2 3340 (fix dictionary display evaluation order #11205) # Python 3.5b3 3350 (add GET_YIELD_FROM_ITER opcode #24400) # Python 3.5.2 3351 (fix BUILD_MAP_UNPACK_WITH_CALL opcode #27286) # Python 3.6a0 3360 (add FORMAT_VALUE opcode #25483) # Python 3.6a1 3361 (lineno delta of code.co_lnotab becomes signed #26107) # Python 3.6a2 3370 (16 bit wordcode #26647) # Python 3.6a2 3371 (add BUILD_CONST_KEY_MAP opcode #27140) # Python 3.6a2 3372 (MAKE_FUNCTION simplification, remove MAKE_CLOSURE # #27095) # Python 3.6b1 3373 (add BUILD_STRING opcode #27078) # Python 3.6b1 3375 (add SETUP_ANNOTATIONS and STORE_ANNOTATION opcodes # #27985) # Python 3.6b1 3376 (simplify CALL_FUNCTIONs & BUILD_MAP_UNPACK_WITH_CALL #27213) # Python 3.6b1 3377 (set __class__ cell from type.__new__ #23722) # Python 3.6b2 3378 (add BUILD_TUPLE_UNPACK_WITH_CALL #28257) # Python 3.6rc1 3379 (more thorough __class__ validation #23722) # Python 3.7a1 3390 (add LOAD_METHOD and CALL_METHOD opcodes #26110) # Python 3.7a2 3391 (update GET_AITER #31709) # Python 3.7a4 3392 (PEP 552: Deterministic pycs #31650) # Python 3.7b1 3393 (remove STORE_ANNOTATION opcode #32550) # Python 3.7b5 3394 (restored docstring as the first stmt in the body; # this might affected the first line number #32911) # Python 3.8a1 3400 (move frame block handling to compiler #17611) # Python 3.8a1 3401 (add END_ASYNC_FOR #33041) # Python 3.8a1 3410 (PEP570 Python Positional-Only Parameters #36540) # Python 3.8b2 3411 (Reverse evaluation order of key: value in dict # comprehensions #35224) # Python 3.8b2 3412 (Swap the position of positional args and positional # only args in ast.arguments #37593) # Python 3.8b4 3413 (Fix "break" and "continue" in "finally" #37830)


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

      专题文章
        CopyRight 2018-2019 实验室设备网 版权所有