. pyc文件包含元数据和^ { } ed代码对象。 加载和反汇编使用代码对象: import dis、marshal、sys
# headersizechangedin 3.3.itmightchangeagain,but as of this writing,it hasn't。
header _ size=12if sys.version _ info=(3,3 ) else 8
withopen(pycfile,' rb ' ) as f:
magic _ and _ timestamp=f.read (header _ size ) # first8or 12 bytes are元数据
代码=marshal.load (f ) # rest is a marshalled代码对象
dis.dis (代码)
使用bisect模块演示:导入bisect
import dis,marshal
导入系统
header _ size=12if sys.version _ info=(3,3 ) else 8
withopen(bisect.__file_,' rb ' ) as f:
. magic _ and _ timestamp=f.read (header _ size ) # first8or 12 bytes are元数据
. code=Marshal.load(f ) # rest is bytecode
.
dis.dis (代码)
1 load _ const0(bisectionalgorithms.' )。
3store_name0(_doc__ )
3load_const1(0)
9load_const8(none ) ) )。
12 LOAD_CONST 2()
15 MAKE_FUNCTION 2
18store_name2(insort_right )。
221load_name2(insort_right ) )
24store_name3(insort ) )。
2227load_const1(0)
30load_const8(none )
33 LOAD_CONST 3()
36 MAKE_FUNCTION 2
39store_name4(bisect_right )。
542load_name4(bisect_right ) ) ) ) ) ) ) ) )。
45store_name5(bisect )
是4448load_const1(0)
1load_const8(none ) ) )。
54 LOAD_CONST 4()。
57 MAKE_FUNCTION 2
60store_name6(insort_left ) )。
6763load_const1(0)
66load_const8(none )
69 LOAD_CONST 5()
72 MAKE_FUNCTION 2
75store_name7(bisect_left )。
是878setup_except14(to95 )
081load_const6(-1 )。
84load_const7() )、) )
87import_name8(bisect ) )。
90 IMPORT_STAR
91 POP_BLOCK
92jump_forward17(to112 )
91 95 DUP_TOP
96load_name9(importerror )。
99compare_op10(exceptionmatch ) )。
102 POP_JUMP_IF_FALSE 111
105 POP_TOP
106 POP_TOP
107 POP_TOP
2108jump_forward1(to112 ) ) ) ) ) ) ) ) ) ) )。
111 END_FINALLY
12load_const8(none ) ) )。
115 RETURN_VALUE
请注意,这只是定义模块的顶级代码对象。 要分析包含的函数,必须从顶级数组中加载嵌套代码对象。 例如,insort_right函数的代码对象是在LOAD_CONST 2中加载的,因此在该索引中搜索代码对象: code.co_consts[2]
dis.dis (代码. co _ consts [2] )
120load_fast2(lo )
3load_const1(0)
6 COMPARE_OP 0(
9 POP_JUMP_IF_FALSE 27
1312 load _ global0(值错误) )。
15 load _ const2(lomustbenon-negative ) )。
18 CALL_FUNCTION 1
21 RAISE_VARARGS 1
24jump_forward0(to27 )
1427load_fast3(hi )
30load_const5(none )
33compare_op8(is )
36 POP_JUMP_IF_FALSE 54
539load_global2(Len ) )
42加载_快速0 (a ) )。
45 CALL_FUNCTION 1
48store_fast3(hi ) )
1jump_forward0(to54 )
是1654setup_loop65(to122 )
57加载_快速2 (lo ) )。
60load_fast3(hi ) )。
63 COMPARE_OP 0(
66 POP_JUMP_IF_FALSE 121
是1769load_fast2(lo )
72load_fast3(hi ) )。
75 BINARY_ADD
76load_const3(2)
79 BINARY_FLOOR_DIVIDE
是80store_fast4(mid )
是1883load_fast1(x )
86load_fast0(a )
89load_fast4(mid ) ) )。
92 BINARY_SUBSCR
93 COMPARE_OP 0(
96 POP_JUMP_IF_FALSE 108
99load_fast4(mid ) )。
102store_fast3(hi ) )。
105 JUMP_ABSOLUTE 57
9108加载_快速4 (mid ) ) )。
11load_const4(1)
114 BINARY_ADD
15store_fast2(lo )
118 JUMP_ABSOLUTE 57
121 POP_BLOCK
0122加载_快速0 (a ) )。
是125load_attr3(insert )
128加载_快速2 (lo ) )。
131load_fast1(x )
134 CALL_FUNCTION 2
137 POP_TOP
是138load_const5(none )
141 RETURN_VALUE
我个人不尝试使用匹配的Python版本和marshal模块以外的其他模块分析. pyc文件。 marshal格式基本上是内部序列化格式,具体取决于Python本身的需求。 对于列表理解和with语句、async/await等新功能,必须添加除作为C source code发布以外不发布的格式。
如果您走在这条路上,并尝试以非模块方式运行read a ^{} object,则必须根据代码对象的各种属性分析反汇编。有关这种方法的详细信息,请参见^{} module source 例如,必须使用co_firstlineno和co_lnotab属性为行号映射创建字节码偏移。