解压python pyc文件时的模糊字节码

解压python pyc文件时的模糊字节码,python,python-3.6,decompiling,pyc,Python,Python 3.6,Decompiling,Pyc,我正在尝试用uncompyle6反编译pyc文件。该操作在偏移量966处出现解析错误,如此处所述 Parse error at or near `POP_TOP' instruction at offset 996 Uncompile打印其反编译的结果,从中我可以看到解析错误是在反编译代码的最后一行(root.mainloop())后抛出的,因为源代码是tkinter gui 如果有人能为初学者讲解如何修复字节码以及我应该从哪里开始,我将不胜感激。由于错误是在我的代码末尾抛出的,我觉得这个错误

我正在尝试用uncompyle6反编译pyc文件。该操作在偏移量966处出现解析错误,如此处所述

Parse error at or near `POP_TOP' instruction at offset 996
Uncompile打印其反编译的结果,从中我可以看到解析错误是在反编译代码的最后一行(root.mainloop())后抛出的,因为源代码是tkinter gui

如果有人能为初学者讲解如何修复字节码以及我应该从哪里开始,我将不胜感激。由于错误是在我的代码末尾抛出的,我觉得这个错误是可以纠正的。 下面是错误本身:

2295    6290  LOAD_NAME                'root'
        6292  LOAD_ATTR                'mainloop'
        6296  CALL_FUNCTION_0       0  ''
        6298  POP_TOP

Parse error at or near `POP_TOP' instruction at offset 996
下面是错误行周围的字节码

 966 LOAD_NAME               23 (ttk)
 968 LOAD_ATTR              110 (Button)
 970 LOAD_NAME              107 (iS1cols)
 972 LOAD_NAME              112 (tools_be_xl)
 974 LOAD_NAME               43 (tools_browse_xls)
 976 LOAD_CONST             126 (('textvariable', 'command'))
 978 CALL_FUNCTION_KW         3
 980 LOAD_ATTR              108 (grid)
 982 LOAD_CONST               0 (0)
 984 LOAD_CONST             121 (20)
 986 LOAD_CONST             117 (4)
 988 LOAD_CONST             127 (2)
 990 LOAD_NAME              109 (W)
 992 LOAD_CONST             128 (('row', 'padx', 'pady', 'column', 'sticky'))
 994 CALL_FUNCTION_KW         5
 996 POP_TOP

 998 LOAD_NAME               23 (ttk)
1000 LOAD_ATTR              113 (LabelFrame)
1002 LOAD_NAME               91 (tab3Int)
1004 LOAD_CONST             129 (' Bulk Edit ')
1006 LOAD_CONST             107 (('text',))
1008 CALL_FUNCTION_KW         2
1010 STORE_NAME             114 (imgStep1)

你的程序有几千行。在你把它削成更小的东西后,在

但请注意,您可能需要投入相当多的精力,将程序缩减为易于处理的内容。如果你不想花费精力,而是想让别人为你做这项工作,我会的。如果人们希望我在该文档中列出其他服务,请与我联系

我要说的是,根据我的经验,一旦一个bug被削减,除了控制流bug(这在这里似乎不相关)的情况外,通常会有一些小的更改,然后甚至会使这些巨大的文件正确地反编译

有两种方法可以缩短程序,以考虑如何修复uncompyle6错误

最简单的方法是猜测导致问题的代码类型。既然您对问题所在有了一些了解—您说它在tkinter gui循环的最后一行—编写一些类似的新代码,对其进行字节编译,然后查看反编译是否会产生同样的错误

也许您有一些与tkinter gui循环相同的旧源代码。试着把它拆开。然后把它削下来,使它不超过几十行

第二种方法是对包中的pydisasm使用
--asm
选项。这将为您提供更容易修改的Python汇编代码,并且在这样做之后,的
pyc xasm
可以返回到一个pyc文件中,您可以对其进行反编译

然而,
--xasm
选项中有一些缺陷,需要一段时间才能完全消除,所以。类似地,uncompyle6在修复Python3.6 bug方面也处于当前的剧变中,这与您的情况有关,因此也需要这样做

现在,我们来谈谈毫无疑问是一个非风格的bug
POP_TOP
从Python计算堆栈中丢弃一个值。例如,当不使用调用的返回值时,可能会发生这种情况—可能调用是它自己的语句。然而,这种未使用的值一直在发生,而且像大多数反编译器一样,解压程序也对此感到满意。更有可能的是,有一种非平凡的调用(带有关键字参数,*或**调用),Python3.6现在创建的字节码与3.5或任何其他早期版本中的非常不同

pycdc可能会给出一个答案,它可能会发出警告,警告:块堆栈不是空的

特别是对于Python3.6上的pycdc,请准备好进行大量的修复,特别是在函数定义和函数调用方面。您可能也必须对uncompyle6执行同样的操作,但它在语义上可能更为正确。因此,修正更多的是关于内容格式化的方式

在处理Python3.6时,uncompyle6还有一段路要走,因为Python3.6在调用函数(这里可能就是这种情况)和创建函数时彻底改变了堆栈项的语义。尽管Python3.6对3.5做了重大更改,但在3.7中还有另一个重大更改,因此这也需要一段时间才能使用。 (关于评分以及评分与我可能在项目上花费的工作量的关系,请参见下文)

至于
CALL\u FUNCTION
vs
CALL\u FUNCTION\u 0
,这是uncompyle6工作方式的产物。它使用上下文无关的语法分析器来构建程序的解析树。因此,某些作为指令操作数的信息有时会添加到操作码中,因为解析只是基于操作码进行的。本文描述了这一点,并描述了uncompyle6的工作原理

最后一点,当我有时间做一个项目时,我使用github项目的评级(或星级)来决定要做哪些项目。xasm、xdis的评级可以忽略不计,这部分解释了为什么您会在它们中发现bug。(当然,另一个原因是缺乏时间或其中一些项目的难度)


与其他(基本上被废弃的)Python反编译器相比,即使是uncompyle6也有相当低的评级,这些反编译器已经有一段时间没有工作了,而且工作也没有那么好

这个字节码来自哪里?另外,我不认为
CALL\u FUNCTION\u 0
是一条指令。如果删除
\u 0
,会发生什么情况?它来自pyinstaller提取器。最初,由于损坏,我丢失了源文件,因此我使用源代码的pyinstaller最近导出的exe将可执行文件反转回我的py源代码。我现在有了那个pyc文件。我怎样才能删除它呢?别介意最后一部分,我误解了一些东西。错误显示偏移量是966,而不是6290。你能展示一下这个部分的代码吗?我在错误之前用更多的内容编辑了这个问题。是的,这种差异对我来说也是很特殊的