Description
Attempting to decompile a tkinter script which was extracted from a PyInstaller executable. I got this error:
Traceback (most recent call last):
File "~/.local/bin/uncompyle6", line 10, in <module>
sys.exit(main_bin())
File "~/.local/lib/python3.6/site-packages/uncompyle6/bin/uncompile.py", line 194, in main_bin
**options)
File "~/.local/lib/python3.6/site-packages/uncompyle6/main.py", line 327, in main
do_fragments,
File "~/.local/lib/python3.6/site-packages/uncompyle6/main.py", line 225, in decompile_file
do_fragments=do_fragments,
File "~/.local/lib/python3.6/site-packages/uncompyle6/main.py", line 144, in decompile
co, out, bytecode_version, debug_opts=debug_opts, is_pypy=is_pypy
File "~/.local/lib/python3.6/site-packages/uncompyle6/semantics/pysource.py", line 2531, in code_deparse
co, code_objects=code_objects, show_asm=debug_opts["asm"]
File "~/.local/lib/python3.6/site-packages/uncompyle6/scanners/scanner38.py", line 106, in ingest
jump_back_index = self.offset2tok_index[jump_target] - 1
KeyError: 4416
It seemed like an interesting and simple-ish issue so I decided to investigate! With this code below line 101, I found the problem.
|
# jump target instruction. |
if token.attr == 4416:
print()
print(vars(token))
print({i: self.offset2tok_index[i] for i in self.offset2tok_index if '4416' in str(i)})
This was the output:
{'kind': 'JUMP_ABSOLUTE', 'has_arg': True, 'attr': 4416, 'pattr': 4416, 'offset': 2428, 'linestart': None, 'opc': <module 'xdis.opcodes.opcode_38' from '~/.local/lib/python3.6/site-packages/xdis/opcodes/opcode_38.py'>, 'op': 113}
{'4416_0': 2222, '4416_1': 2223, '4416_4418': 2224}
I noticed that there was no 4416 key - all of the keys had _... values. After a bit more digging I saw that it was being added by these lines:
|
j = tokens_append( |
|
j, |
|
Token( |
|
come_from_name, |
|
jump_offset, |
|
repr(jump_offset), |
|
offset="%s_%s" % (inst.offset, jump_idx), |
|
has_arg=True, |
|
opc=self.opc, |
|
has_extended_arg=False, |
|
), |
|
) |
I don't understand why this JUMP doesn't have the "base" 4416 key, but I found a simple solution. I printed some other JUMP values and noticed that in every case - regardless of 1 or 3+ jumps with the same offset, the jump_back_index is self.offset2tok_index[last_index] - 1 - so in this case, the last 4416 jump is '4416_4418' and thus jump_back_index = self.offset2tok_index['4416_4418'] - 1. I don't understand why, however. So, in short, I changed the code to get the jump_back_index in this way, and it fixed the problem:
From:
|
jump_back_index = self.offset2tok_index[jump_target] - 1 |
To:
offset_instances = [inst for inst in self.offset2tok_index if str(jump_target) in str(inst)]
jump_back_index = self.offset2tok_index[offset_instances[-1]] - 1
And that fixes this problem.
This issue also applies to https://github.com/rocky/python-decompile3.
How to Reproduce
$ uncompyle6 Main.pyc
Traceback (most recent call last):
File "~/.local/bin/uncompyle6", line 10, in <module>
sys.exit(main_bin())
File "~/.local/lib/python3.6/site-packages/uncompyle6/bin/uncompile.py", line 194, in main_bin
**options)
File "~/.local/lib/python3.6/site-packages/uncompyle6/main.py", line 327, in main
do_fragments,
File "~/.local/lib/python3.6/site-packages/uncompyle6/main.py", line 225, in decompile_file
do_fragments=do_fragments,
File "~/.local/lib/python3.6/site-packages/uncompyle6/main.py", line 144, in decompile
co, out, bytecode_version, debug_opts=debug_opts, is_pypy=is_pypy
File "~/.local/lib/python3.6/site-packages/uncompyle6/semantics/pysource.py", line 2531, in code_deparse
co, code_objects=code_objects, show_asm=debug_opts["asm"]
File "~/.local/lib/python3.6/site-packages/uncompyle6/scanners/scanner38.py", line 106, in ingest
jump_back_index = self.offset2tok_index[jump_target] - 1
KeyError: 4416
$
A link to the pyc file: https://gofile.io/?c=MV8jCW
Description
Attempting to decompile a tkinter script which was extracted from a PyInstaller executable. I got this error:
It seemed like an interesting and simple-ish issue so I decided to investigate! With this code below line 101, I found the problem.
python-uncompyle6/uncompyle6/scanners/scanner38.py
Line 101 in 451f0b5
This was the output:
{'kind': 'JUMP_ABSOLUTE', 'has_arg': True, 'attr': 4416, 'pattr': 4416, 'offset': 2428, 'linestart': None, 'opc': <module 'xdis.opcodes.opcode_38' from '~/.local/lib/python3.6/site-packages/xdis/opcodes/opcode_38.py'>, 'op': 113} {'4416_0': 2222, '4416_1': 2223, '4416_4418': 2224}I noticed that there was no
4416key - all of the keys had_...values. After a bit more digging I saw that it was being added by these lines:python-uncompyle6/uncompyle6/scanners/scanner37base.py
Lines 329 to 340 in 451f0b5
I don't understand why this
JUMPdoesn't have the "base"4416key, but I found a simple solution. I printed some otherJUMPvalues and noticed that in every case - regardless of 1 or 3+ jumps with the same offset, thejump_back_indexisself.offset2tok_index[last_index] - 1- so in this case, the last4416jump is'4416_4418'and thusjump_back_index = self.offset2tok_index['4416_4418'] - 1. I don't understand why, however. So, in short, I changed the code to get thejump_back_indexin this way, and it fixed the problem:From:
python-uncompyle6/uncompyle6/scanners/scanner38.py
Line 102 in 451f0b5
To:
And that fixes this problem.
This issue also applies to https://github.com/rocky/python-decompile3.
How to Reproduce
A link to the
pycfile: https://gofile.io/?c=MV8jCW