python 字节码 汇编器_将反汇编的Python字节码转换回源代码

本文介绍了如何使用decompyle等工具从Python字节码生成源代码。通过字节码分析,解释了如何理解并转换字节码,特别是涉及到lambda函数和CALL_FUNCTION指令的使用。此外,还展示了如何验证字节码解释的正确性,并提供了一个通过字节码重组文本的示例代码。
摘要由CSDN通过智能技术生成

您确实希望自动化这一点,而不是手动执行;有一些工具,如decompyle和{}可以从字节码生成Python源代码。在

代码对象中的字节码有些混乱,我们缺少代码对象中的co_argcount和{}信息。不过,我很确定清单的理解应该是:YSay = [YSag(YSao, lambda s: s[x], x) for x in YSaP(0, YSaO)]

字节码

^{pr2}$

从上到下转换为具有x、lambda、YSao和{}的堆栈,CALL_FUNCTION按相反顺序将前3个传递给最后一个,因此调用YSag(YSao, , x)。在

lambda从第27行加载,其字节码为:27 0 LOAD_FAST 0 (s)

3 LOAD_GLOBAL 0 (x)

6 BINARY_SUBSCR

7 RETURN_VALUE

这意味着s是lambda的参数(它是一个加载了LOAD_FAST的局部变量),而{}是一个全局变量,所以这就转换成了lambda s: s[x]。在

注意,CALL_FUNCTION_VAR使用*args调用功能,因此您需要将第9行更正为:YSas = YSam(*[YSaN(l) for l in YSaW])

这是一种冗长的拼写max(len(l) for l in YSaW)的方法,但是列表理解扩展为单独的参数,而不是作为单个参数传入的生成器表达式。在

我发现使用^{} function和^{}来查看我对字节码的解释是否正确是很有帮助的;输入一个表达式或语句,输出应该与您的字节码大致匹配(使用行号和字节码编号偏移量):from dis import dis

dis(compile(string, '', 'exec'))

例如,对于最后一行,我用以下方法验证了结果:>>> dis(compile('YSas = YSam(*[YSaN(l) for l in YSaW])', '', 'exec'))

1 0 LOAD_NAME 0 (YSam)

3 BUILD_LIST 0

6 LOAD_NAME 1 (YSaW)

9 GET_ITER

>> 10 FOR_ITER 18 (to 31)

13 STORE_NAME 2 (l)

16 LOAD_NAME 3 (YSaN)

19 LOAD_NAME 2 (l)

22 CALL_FUNCTION 1

25 LIST_APPEND 2

28 JUMP_ABSOLUTE 10

>> 31 CALL_FUNCTION_VAR 0

34 STORE_NAME 4 (YSas)

37 LOAD_CONST 0 (None)

40 RETURN_VALUE

对于函数对象,您希望从给定的co_consts条目(compile(...).co_code.co_consts[an_index])中提取代码对象,或者先创建函数,然后将函数对象传递给dis.dis():>>> dis(lambda s: s[x])

1 0 LOAD_FAST 0 (s)

3 LOAD_GLOBAL 0 (x)

6 BINARY_SUBSCR

7 RETURN_VALUE

最后你得到了一个相当糟糕的软件,它把文件中的字符混在一起。我已经清除了混淆,并使用了更为惯用的Python来实现我认为会产生相同的输出:import sys

def rotn(s, n): return s[n:] + s[:n]

with open(sys.argv[1]) as inf:

lines = [l.strip().replace(' ', '.') for l in inf]

maxlength = max(len(l) for l in lines)

padded = (l.ljust(maxlength, '.') for l in lines)

swapped = [rotn(s, len(s) // 2) for s in padded]

cols = []

for x, col in enumerate(zip(*swapped)):

offset = (x % len(col)) * (-1 if x % 2 else 1)

cols.append(rotn(col, offset))

for row in zip(*cols):

print ''.join(row)

因此,用.将所有被剥离的行填充成相等的长度,交换行的开始和结束,然后将结果文本块中的每个列向上或向下旋转列号(每列交换方向),然后显示结果文本。在

我怀疑使用'.'代替空格在这里也不是真正必要的;放弃.replace()调用并留下{}使用默认的空格填充,结果基本相同,但空格保持不变。在

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值