How do I convert the following byte code to normal python code? I got this code by decompiling a pyc file. Some of the code was decompiled to its original code but the majority did not. Any idea how I can get this byte code to its source code?
L. 174 396 BUILD_LIST_0 0
398 STORE_FAST 'javascripts'
L. 177 400 SETUP_LOOP 490 'to 490'
402 LOAD_GLOBAL range
404 LOAD_CONST 0
406 LOAD_GLOBAL len
408 LOAD_FAST 'incident_tags'
410 CALL_FUNCTION_1 1 '1 positional argument'
412 CALL_FUNCTION_2 2 '2 positional arguments'
414 GET_ITER
416 FOR_ITER 488 'to 488'
418 STORE_FAST 'i'
L. 178 420 LOAD_GLOBAL str
422 LOAD_FAST 'incident_tags'
424 LOAD_FAST 'i'
426 BINARY_SUBSCR
428 LOAD_ATTR text
430 CALL_FUNCTION_1 1 '1 positional argument'
432 LOAD_GLOBAL list_of_incidents
434 COMPARE_OP not-in
436_438 POP_JUMP_IF_FALSE 462 'to 462'
L. 179 440 LOAD_FAST 'javascripts'
442 LOAD_METHOD append
444 LOAD_FAST 'incident_tags'
446 LOAD_FAST 'i'
448 BINARY_SUBSCR
450 LOAD_METHOD get_attribute
452 LOAD_STR 'href'
454 CALL_METHOD_1 1 '1 positional argument'
456 CALL_METHOD_1 1 '1 positional argument'
458 POP_TOP
460 JUMP_BACK 416 'to 416'
462_0 COME_FROM 436 '436'
L. 181 462 LOAD_GLOBAL print
464 LOAD_STR 'Ignore '
466 LOAD_FAST 'incident_tags'
468 LOAD_FAST 'i'
470 BINARY_SUBSCR
472 LOAD_ATTR text
474 BINARY_ADD
476 LOAD_STR '. It is already completed.'
478 BINARY_ADD
480 CALL_FUNCTION_1 1 '1 positional argument'
482 POP_TOP
484_486 JUMP_BACK 416 'to 416'
488 POP_BLOCK
490_0 COME_FROM_LOOP 400 '400'
L. 184 490_492 SETUP_LOOP 3694 'to 3694'
494 LOAD_GLOBAL range
496 LOAD_CONST 0
498 LOAD_GLOBAL len
500 LOAD_FAST 'javascripts'
502 CALL_FUNCTION_1 1 '1 positional argument'
504 CALL_FUNCTION_2 2 '2 positional arguments'
506 GET_ITER
508_0 COME_FROM 636 '636'
508_510 FOR_ITER 3692 'to 3692'
512 STORE_FAST 'i'
L. 187 514 LOAD_FAST 'self'
516 LOAD_ATTR driver
518 LOAD_METHOD execute_script
520 LOAD_FAST 'javascripts'
522 LOAD_FAST 'i'
524 BINARY_SUBSCR
526 CALL_METHOD_1 1 '1 positional argument'
528 POP_TOP
L. 189 530 LOAD_GLOBAL time
532 LOAD_METHOD sleep
534 LOAD_CONST 1
536 CALL_METHOD_1 1 '1 positional argument'
538 POP_TOP
-
It's not something available in standard Python, and I'm not aware of any 3rd-party tools that do this kind of conversion.chepner– chepner2021年09月20日 17:22:49 +00:00Commented Sep 20, 2021 at 17:22
-
Some potential tools are listed in this question: stackoverflow.com/questions/1149513/…match– match2021年09月20日 17:23:27 +00:00Commented Sep 20, 2021 at 17:23
-
This wouldn't be trivial, there's not just some built-in function that will do this. You'd be better off googling for projects that already exist. Of course, this is going to be very version dependent.juanpa.arrivillaga– juanpa.arrivillaga2021年09月20日 17:25:01 +00:00Commented Sep 20, 2021 at 17:25
-
This amount of bytecode is trivial to decompile by hand. Are you really asking about some larger, unspecified body of code?Davis Herring– Davis Herring2021年09月20日 22:49:13 +00:00Commented Sep 20, 2021 at 22:49
-
2@DavisHerring Yes. I just showed a snippet of the dataRiayad– Riayad2021年09月24日 19:50:45 +00:00Commented Sep 24, 2021 at 19:50
2 Answers 2
I suggest you use the uncompyle6 module. (You need the raw .pyc or .pyo file though). To install, run
~$ pip install uncompyle6
Then, to decompile any Python bytecode file, run
~$ uncompyle6 path/to/bytecode/file.pyc
For an overview of all available options, run
~$ uncompyle6 -h
It supports all Python versions from 2.4 to 3.8. You can find the project' homepage at https://github.com/rocky/python-uncompyle6.
Comments
I achieved this using by importing the dis module and using the dir() method to get the __code__ of each function, further used the dir() to get the co_code and finally using dis function to get the bytecodes.
The process is really tedious but it gave me the results I was looking for and can be automated if you understand the concept.
def add(a,b):
return a+b
# This displays all attributes available to the add function.
# There are tons of them but I'm only interested in the __code__.
dir(add)
my_object = add.__code__
# This displays a list of available attributes to the code object (my_object) but
# I'm only interested in the co_code attribute.
dir(my_object)
code = my_object.co_code
# Convert the co_code object to list. This displays the bytecode but to
# view it in human readable form use dis.opname
list(code)
import dis
# To view all available attributes. I'm interested in a only few of them.
dir(dis)
dis.opname() # supply the bytecode value.