千家信息网

python字节码手工还原python源码的示例分析

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,今天就跟大家聊聊有关python字节码手工还原python源码的示例分析,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。0x1.前言> Pyth
千家信息网最后更新 2026年11月01日python字节码手工还原python源码的示例分析

今天就跟大家聊聊有关python字节码手工还原python源码的示例分析,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。

0x1.前言

> Python 代码先被编译为字节码后,再由Python虚拟机来执行字节码, Python的字节码是一种类似汇编指令的中间语言, 一个Python语句会对应若干字节码指令,虚拟机一条一条执行字节码指令, 从而完成程序执行。Python dis 模块支持对Python代码进行反汇编, 生成字节码指令。dis.dis()将CPython字节码转为可读的伪代码(类似于汇编代码)。结构如下:

  7           0 LOAD_CONST               1 (0)              3 STORE_FAST               1 (local1)  8           6 LOAD_CONST               2 (101)              9 STORE_GLOBAL             0 (global1)  9          12 LOAD_FAST                1 (local1)             15 PRINT_ITEM             16 LOAD_FAST                0 (arg1)             19 PRINT_ITEM             20 LOAD_GLOBAL              0 (global1)             23 PRINT_ITEM             24 PRINT_NEWLINE             25 LOAD_CONST               0 (None)             28 RETURN_VALUE

其实就是这样的结构:

源码行号 | 指令在函数中的偏移 | 指令符号 | 指令参数 | 实际参数值

0x2.变量

1.const

LOAD_CONST加载const变量,比如数值、字符串等等,一般用于传给函数的参数

55       12 LOAD_GLOBAL              1 (test)         15 LOAD_FAST                0 (2) #读取2         18 LOAD_CONST               1 ('output')          21 CALL_FUNCTION            2

转为python代码就是:

test(2, 'output')

2.局部变量

LOAD_FAST一般加载局部变量的值,也就是读取值,用于计算或者函数调用传参等。STORE_FAST一般用于保存值到局部变量。

61          77 LOAD_FAST                0 (n)             80 LOAD_FAST                3 (p)             83 INPLACE_DIVIDE             84 STORE_FAST               0 (n)

这段bytecode转为python就是:

n = n / p

函数的形参也是局部变量,如何区分出是函数形参还是其他局部变量呢?形参没有初始化,也就是从函数开始到LOAD_FAST该变量的位置,如果没有看到STORE_FAST,那么该变量就是函数形参。而其他局部变量在使用之前肯定会使用STORE_FAST进行初始化。具体看下面的实例:

  4           0 LOAD_CONST               1 (0)              3 STORE_FAST               1 (local1)  5           6 LOAD_FAST                1 (local1)              9 PRINT_ITEM             10 LOAD_FAST                0 (arg1)             13 PRINT_ITEM             14 PRINT_NEWLINE             15 LOAD_CONST               0 (None)             18 RETURN_VALUE

对应的python代码如下,对比一下就一目了然。

def test(arg1):    local1 = 0    print local1, arg1

3.全局变量

LOAD_GLOBAL用来加载全局变量,包括指定函数名,类名,模块名等全局符号。STORE_GLOBAL用来给全局变量赋值。

  8           6 LOAD_CONST               2 (101)              9 STORE_GLOBAL             0 (global1)              20 LOAD_GLOBAL              0 (global1)              23 PRINT_ITEM

对应的python代码

def test():    global global1    global1 = 101    print global

0x3.常用数据类型

1.list

BUILD_LIST用于创建一个list结构。

 13           0 LOAD_CONST               1 (1)              3 LOAD_CONST               2 (2)              6 BUILD_LIST               2              9 STORE_FAST               0 (k)

对应python代码是:

k = [1, 2]

另外再看看一种常见的创建list的方式如下:

[x for x in xlist if x!=0 ]

一个实例bytecode如下:

 22         235 BUILD_LIST               0 //创建list,为赋值给某变量,这种时候一般都是语法糖结构了            238 LOAD_FAST                3 (sieve)            241 GET_ITER        >>  242 FOR_ITER                24 (to 269)            245 STORE_FAST               4 (x)            248 LOAD_FAST                4 (x)            251 LOAD_CONST               2 (0)            254 COMPARE_OP               3 (!=)            257 POP_JUMP_IF_FALSE      242 //不满足条件contine            260 LOAD_FAST                4 (x)//读取满足条件的x            263 LIST_APPEND              2 //把每个满足条件的x存入list            266 JUMP_ABSOLUTE          242        >>  269 RETURN_VALUE

转为python代码是:

[for x in sieve if x != 0]

2.dict

BUILD_MAP用于创建一个空的dict。STORE_MAP用于初始化dict的内容。

 13           0 BUILD_MAP                1              3 LOAD_CONST               1 (1)              6 LOAD_CONST               2 ('a')              9 STORE_MAP             10 STORE_FAST               0 (k)

对应的python代码是:

k = {'a': 1}

再看看修改dict的bytecode:

14          13 LOAD_CONST               3 (2)             16 LOAD_FAST                0 (k)             19 LOAD_CONST               4 ('b')             22 STORE_SUBSCR

对应的python代码是:

k['b'] = 2

3.slice

BUILD_SLICE用于创建slice。对于list、元组、字符串都可以使用slice的方式进行访问。但是要注意BUILD_SLICE用于[x:y:z]这种类型的slice,结合BINARY_SUBSCR读取slice的值,结合STORE_SUBSCR用于修改slice的值。另外SLICE+n用于[a:b]类型的访问,STORE_SLICE+n用于[a:b]类型的修改,其中n表示如下:

SLICE+0()Implements TOS = TOS[:].SLICE+1()Implements TOS = TOS1[TOS:].SLICE+2()Implements TOS = TOS1[:TOS].SLICE+3()Implements TOS = TOS2[TOS1:TOS].

下面看具体实例:

13           0 LOAD_CONST               1 (1)              3 LOAD_CONST               2 (2)              6 LOAD_CONST               3 (3)              9 BUILD_LIST               3             12 STORE_FAST               0 (k1) //k1 = [1, 2, 3] 14          15 LOAD_CONST               4 (10)             18 BUILD_LIST               1             21 LOAD_FAST                0 (k1)             24 LOAD_CONST               5 (0)             27 LOAD_CONST               1 (1)             30 LOAD_CONST               1 (1)             33 BUILD_SLICE              3             36 STORE_SUBSCR                    //k1[0:1:1] = [10] 15          37 LOAD_CONST               6 (11)             40 BUILD_LIST               1             43 LOAD_FAST                0 (k1)             46 LOAD_CONST               1 (1)             49 LOAD_CONST               2 (2)             52 STORE_SLICE+3                   //k1[1:2] = [11] 16          53 LOAD_FAST                0 (k1)             56 LOAD_CONST               1 (1)             59 LOAD_CONST               2 (2)             62 SLICE+3             63 STORE_FAST               1 (a)  //a = k1[1:2] 17          66 LOAD_FAST                0 (k1)             69 LOAD_CONST               5 (0)             72 LOAD_CONST               1 (1)             75 LOAD_CONST               1 (1)             78 BUILD_SLICE              3             81 BINARY_SUBSCR             82 STORE_FAST               2 (b) //b = k1[0:1:1]

0x4.循环

SETUP_LOOP用于开始一个循环。SETUP_LOOP 26 (to 35)中35表示循环退出点。

while循环

 23           0 LOAD_CONST               1 (0)              3 STORE_FAST               0 (i) // i=0 24           6 SETUP_LOOP              26 (to 35)        >>    9 LOAD_FAST                0 (i) //循环起点             12 LOAD_CONST               2 (10)             15 COMPARE_OP               0 (<)             18 POP_JUMP_IF_FALSE       34     //while i < 10: 25          21 LOAD_FAST                0 (i)             24 LOAD_CONST               3 (1)             27 INPLACE_ADD                                  28 STORE_FAST               0 (i) // i += 1             31 JUMP_ABSOLUTE            9    // 回到循环起点        >>   34 POP_BLOCK        >>   35 LOAD_CONST               0 (None)

对应python代码是:

i = 0    while i < 10:        i += 1

for in结构

            238 LOAD_FAST                3 (sieve)#sieve是个list            241 GET_ITER                    //开始迭代sieve        >>  242 FOR_ITER                24 (to 269) //继续iter下一个x            245 STORE_FAST               4 (x)            ...            266 JUMP_ABSOLUTE          242 //循环

这是典型的for+in结构,转为python代码就是:

for x in sieve:

0x5.if

POP_JUMP_IF_FALSE和JUMP_FORWARD一般用于分支判断跳转。POP_JUMP_IF_FALSE表示条件结果为FALSE就跳转到目标偏移指令。JUMP_FORWARD直接跳转到目标偏移指令。

 23           0 LOAD_CONST               1 (0)              3 STORE_FAST               0 (i) //i=0 24           6 LOAD_FAST                0 (i)              9 LOAD_CONST               2 (5)             12 COMPARE_OP               0 (<)             15 POP_JUMP_IF_FALSE       26 25          18 LOAD_CONST               3 ('i < 5')             21 PRINT_ITEM             22 PRINT_NEWLINE             23 JUMP_FORWARD            25 (to 51) 26     >>   26 LOAD_FAST                0 (i)             29 LOAD_CONST               2 (5)             32 COMPARE_OP               4 (>)             35 POP_JUMP_IF_FALSE       46 27          38 LOAD_CONST               4 ('i > 5')             41 PRINT_ITEM             42 PRINT_NEWLINE             43 JUMP_FORWARD             5 (to 51) 29     >>   46 LOAD_CONST               5 ('i = 5')             49 PRINT_ITEM             50 PRINT_NEWLINE        >>   51 LOAD_CONST               0 (None)

转为python代码是:

    i = 0    if i < 5:        print 'i < 5'    elif i > 5:        print 'i > 5'    else:        print 'i = 5'

0x6.分辨函数

1.函数范围

前面介绍第二列表示指令在函数中的偏移地址,所以看到0就是函数开始,下一个0前一条指令就是函数结束位置,当然也可以通过RETURN_VALUE来确定函数结尾

54         0 LOAD_FAST                1 (plist) //函数开始           3 LOAD_CONST               0 (None)           6 COMPARE_OP               2 (==)           9 POP_JUMP_IF_FALSE        3355         ...67     >>  139 LOAD_FAST              2 (fs)           142 RETURN_VALUE70         0 LOAD_CONST               1 ('FLAG') //另一个函数开始           3 STORE_FAST               0 (flag)

2.函数调用

函数调用类似于push+call的汇编结构,压栈参数从左到右依次压入(当然不是push,而是读取指令LOAD_xxxx来指定参数)。函数名一般通过LOAD_GLOBAL指令指定,如果是模块函数或者类成员函数通过LOAD_GLOBAL+LOAD_ATTR来指定。先指定要调用的函数,然后压参数,最后通过CALL_FUNCTION调用。CALL_FUNCTION后面的值表示有几个参数。支持嵌套调用:

6           0 LOAD_GLOBAL              0 (int) //int函数              3 LOAD_GLOBAL              1 (math)//math模块              6 LOAD_ATTR                2 (sqrt)//sqrt函数              9 LOAD_FAST                0 (n) //参数             12 CALL_FUNCTION            1             15 CALL_FUNCTION            1             18 STORE_FAST               2 (nroot)

这段bytecode转换成python代码就是

nroot = int(math.sqrt(n)) //其中n是一个局部变量或者函数参数,具体看上下文

0x7.其他指令

其他常见指令,一看就明白,就不具体分析了,更多详细内容请看官方文档。

INPLACE_POWER()Implements in-place TOS = TOS1 ** TOS.INPLACE_MULTIPLY()Implements in-place TOS = TOS1 * TOS.INPLACE_DIVIDE()Implements in-place TOS = TOS1 / TOS when from __future__ import division is not in effect.INPLACE_FLOOR_DIVIDE()Implements in-place TOS = TOS1 // TOS.INPLACE_TRUE_DIVIDE()Implements in-place TOS = TOS1 / TOS when from __future__ import division is in effect.INPLACE_MODULO()Implements in-place TOS = TOS1 % TOS.INPLACE_ADD()Implements in-place TOS = TOS1 + TOS.INPLACE_SUBTRACT()Implements in-place TOS = TOS1 - TOS.INPLACE_LSHIFT()Implements in-place TOS = TOS1 << TOS.INPLACE_RSHIFT()Implements in-place TOS = TOS1 >> TOS.INPLACE_AND()Implements in-place TOS = TOS1 & TOS.INPLACE_XOR()Implements in-place TOS = TOS1 ^ TOS.INPLACE_OR()Implements in-place TOS = TOS1 | TOS.

基础运算还有一套对应的BINARY_xxxx指令,两者区别很简单。

i += 1 //使用INPLACE_xxxi = i + 1 //使用BINARY_xxxx

看完上述内容,你们对python字节码手工还原python源码的示例分析有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注行业资讯频道,感谢大家的支持。

函数 指令 代码 变量 字节 参数 就是 局部 结构 循环 内容 全局 条件 模块 类型 形参 偏移 源码 分析 实例 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 南京欣网互联网络科技有限公司 苏州找大状互联网科技有限公司 互联网科技工作委员会毛军 互联网和科技技术 科技平台互联网 科技和互联网公司 互联网络科技有限公司 齐家互联网科技 狮子座互联网科技有限公司 睿民互联网科技 恒生科技互联网指数分析 银川新华互联网科技学校地址 中国航天科技大学国际工业互联网 互联网5g黑科技有哪些 广西互联网科技孵化中心 卓翼科技产业互联网合作 山东有哪些互联网科技公司 互联网金融运营模式中的金融科技 北京军民互联网科技公司 唐山双旺合互联网科技产业园 深圳九邦互联网科技有限公司 华服互联网科技怎么样 云信互联网科技有限公司 互联网科技与金融科技 为想互联网科技 哈尔滨秒房互联网科技有限公司 深圳市运趣互联网科技有限公司 互联网软件和科技 工业互联网山东科技大学 承德科技产业互联网平台
0