Tuesday 11 July 2017

Deobfuscating PjOrion using bytecode simplifier

Bytecode simplifier is a tool to de-obfuscate PjOrion protected python scripts. This post is a short tutorial to show how to use this module to deobfuscate a protected python script.

I have used the sample code below to demonstrate its usage. This is a small program to calculate the factorial of a number.

``````# Python program to find the factorial of a number using recursion

def recur_factorial(n):
"""Function to return the factorial
of a number using recursion"""
if n == 1:
return n
else:
return n*recur_factorial(n-1)

# take input from the user
num = int(input("Enter a number: "))

# check is the number is negative
if num < 0:
print("Sorry, factorial does not exist for negative numbers")
elif num == 0:
print("The factorial of 0 is 1")
else:
print("The factorial of",num,"is",recur_factorial(num))
``````

I have first compiled the script and protected it as shown in Figure 1 & 2.

 Figure 1: Compiling the script
 Figure 2: Protecting the generated pyc file
After protection, we get a large file example.pyc about 27 KiB in size. This is the file we will be working on.

The stock python interpreter does not have bytecode tracing facilities inbuilt. Hence we have to use a modified version of Python which supports bytecode tracing. I have provided a precompiled version of Python 2.7.13 with bytecode tracing support at Github. The python27.dll file has to be copied to  C:\Windows\System32\. Make sure to backup the existing dll so that you can revert when finished.

Step - 1: Unwrapping the layers

The first step is to unwrap the protection layers to get hold of the actual obfuscated code object. For this, we will be using the pjunwrapper module as shown below.

``````C:\pj-dump>python pjunwrapper.py --ifile=example.pyc
XXX lineno: 1, opcode: 156
[*] Dumped 1 code object
XXX lineno: 1, opcode: 213
XXX lineno: 1, opcode: 184
XXX lineno: 1, opcode: 240
XXX lineno: 1, opcode: 240
XXX lineno: 1, opcode: 240
XXX lineno: 1, opcode: 240
[*] Dumped 1 code object
XXX lineno: 1, opcode: 7
XXX lineno: 1, opcode: 45
[*] Dumped 1 code object
XXX lineno: 1, opcode: 161
Enter a number: ^D
Error in module '__main__': unexpected EOF while parsing (<string>, line 1)
``````

PjUnwrapper requires the pystack extension module. Make sure that the extension is present in python path. Running this, some files having names of wrapper_ would be dumped. These are basically the wrapper layers over the actual obfuscated code. In our case, the obfuscated code has a file name wrapper_3.pyc as shown in Figure 3. In general, the highest numbered file contains the final obfuscated code.

 Figure 3: Unwrapping the protection layers

Step - 2: Deobfuscating

The final step is to run bytecode_simplifier over wrapper_3.pyc as shown below.

``````C:\bytecode_simplifier\main.py --ifile=wrapper_3.pyc --ofile=wrapper_deobf.pyc
INFO:__main__:Opening file wrapper_3.pyc
DEBUG:__main__:Unmarshalling file
INFO:__main__:Processing code object \x0f\x1d\n\x00\x07\x0f\x0f
DEBUG:deobfuscator:Code entrypoint matched PjOrion signature v1
INFO:deobfuscator:Original code entrypoint at 269
INFO:deobfuscator:Starting control flow analysis...
DEBUG:disassembler:Constructing basic blocks...
DEBUG:disassembler:Creating basic block 0x24bd800 spanning from 5 to 6, both inclusive
DEBUG:disassembler:Creating basic block 0x24ca558 spanning from 14 to 17, both inclusive
DEBUG:disassembler:Creating basic block 0x24ca5d0 spanning from 25 to 28, both inclusive
DEBUG:disassembler:Creating basic block 0x24ca648 spanning from 33 to 33, both inclusive
DEBUG:disassembler:Creating basic block 0x24ca698 spanning from 36 to 36, both inclusive
DEBUG:disassembler:Creating basic block 0x24ca6e8 spanning from 44 to 44, both inclusive
DEBUG:disassembler:Creating basic block 0x24ca738 spanning from 51 to 51, both inclusive
DEBUG:disassembler:Creating basic block 0x24ca788 spanning from 57 to 60, both inclusive
DEBUG:disassembler:Creating basic block 0x24ca800 spanning from 68 to 71, both inclusive
DEBUG:disassembler:Creating basic block 0x24ca878 spanning from 79 to 82, both inclusive
DEBUG:disassembler:Creating basic block 0x24ca8f0 spanning from 93 to 94, end exclusive
DEBUG:disassembler:Creating basic block 0x24ca940 spanning from 94 to 94, both inclusive
DEBUG:disassembler:Creating basic block 0x24ca990 spanning from 102 to 105, both inclusive
DEBUG:disassembler:Creating basic block 0x24caa30 spanning from 114 to 117, both inclusive
DEBUG:disassembler:Creating basic block 0x24caaf8 spanning from 122 to 125, both inclusive
DEBUG:disassembler:Creating basic block 0x24cabc0 spanning from 131 to 134, both inclusive
DEBUG:disassembler:Creating basic block 0x24cac88 spanning from 141 to 142, both inclusive
DEBUG:disassembler:Creating basic block 0x24cad50 spanning from 152 to 155, both inclusive
DEBUG:disassembler:Creating basic block 0x24cae18 spanning from 162 to 165, both inclusive
DEBUG:disassembler:Creating basic block 0x24caee0 spanning from 174 to 177, both inclusive
DEBUG:disassembler:Creating basic block 0x24cafa8 spanning from 187 to 190, both inclusive
DEBUG:disassembler:Creating basic block 0x24ce0a8 spanning from 196 to 197, both inclusive
DEBUG:disassembler:Creating basic block 0x24ce170 spanning from 204 to 207, both inclusive
DEBUG:disassembler:Creating basic block 0x24ce238 spanning from 218 to 221, both inclusive
DEBUG:disassembler:Creating basic block 0x24ce300 spanning from 228 to 229, both inclusive
DEBUG:disassembler:Creating basic block 0x24ce3c8 spanning from 235 to 235, both inclusive
DEBUG:disassembler:Creating basic block 0x24ce468 spanning from 238 to 238, both inclusive
DEBUG:disassembler:Creating basic block 0x24ce508 spanning from 243 to 246, both inclusive
DEBUG:disassembler:Creating basic block 0x24ce5d0 spanning from 254 to 257, both inclusive
DEBUG:disassembler:Creating basic block 0x24ce698 spanning from 269 to 272, both inclusive
DEBUG:disassembler:Creating basic block 0x24ce760 spanning from 282 to 285, both inclusive
DEBUG:disassembler:Creating basic block 0x24ce828 spanning from 292 to 295, both inclusive
DEBUG:disassembler:Creating basic block 0x24ce8f0 spanning from 300 to 303, both inclusive
DEBUG:disassembler:Creating basic block 0x24ce9b8 spanning from 310 to 313, both inclusive
DEBUG:disassembler:Creating basic block 0x24cea80 spanning from 321 to 324, both inclusive
DEBUG:disassembler:Creating basic block 0x24ceb48 spanning from 332 to 332, both inclusive
DEBUG:disassembler:Creating basic block 0x24cebe8 spanning from 342 to 342, both inclusive
DEBUG:disassembler:Creating basic block 0x24cec88 spanning from 349 to 349, both inclusive
DEBUG:disassembler:Creating basic block 0x24ced28 spanning from 350 to 353, both inclusive
DEBUG:disassembler:Creating basic block 0x24cedf0 spanning from 360 to 361, both inclusive
DEBUG:disassembler:Creating basic block 0x24ceeb8 spanning from 366 to 369, both inclusive
DEBUG:disassembler:41 basic blocks created
DEBUG:disassembler:Constructing edges between basic blocks...
DEBUG:disassembler:Adding explicit edge from block 0x24bd800 to 0x24ca8f0
DEBUG:disassembler:Adding explicit edge from block 0x24ca800 to 0x24ca648
DEBUG:disassembler:Adding explicit edge from block 0x24ce828 to 0x24cec88
DEBUG:disassembler:Adding explicit edge from block 0x24ca878 to 0x24ca5d0
DEBUG:disassembler:Adding explicit edge from block 0x24ce0a8 to 0x24cedf0
DEBUG:disassembler:Adding explicit edge from block 0x24ca940 to 0x24ce828
DEBUG:disassembler:Adding explicit edge from block 0x24ca6e8 to 0x24ca940
DEBUG:disassembler:Adding explicit edge from block 0x24ce170 to 0x24ce238
DEBUG:disassembler:Adding explicit edge from block 0x24ca990 to 0x24cac88
DEBUG:disassembler:Adding explicit edge from block 0x24ce9b8 to 0x24ce508
DEBUG:disassembler:Adding explicit edge from block 0x24caa30 to 0x24ca878
DEBUG:disassembler:Adding explicit edge from block 0x24cea80 to 0x24cabc0
DEBUG:disassembler:Adding explicit edge from block 0x24ce300 to 0x24ca6e8
DEBUG:disassembler:Adding explicit edge from block 0x24ceb48 to 0x24ca940
DEBUG:disassembler:Adding implicit edge from block 0x24ce3c8 to 0x24ce468
DEBUG:disassembler:Adding explicit edge from block 0x24ce3c8 to 0x24ca738
DEBUG:disassembler:Adding explicit edge from block 0x24cabc0 to 0x24ceeb8
DEBUG:disassembler:Adding explicit edge from block 0x24cebe8 to 0x24ca558
DEBUG:disassembler:Adding explicit edge from block 0x24ce468 to 0x24ca990
DEBUG:disassembler:Adding explicit edge from block 0x24cac88 to 0x24ce300
DEBUG:disassembler:Adding explicit edge from block 0x24ce508 to 0x24ca800
DEBUG:disassembler:Adding explicit edge from block 0x24ced28 to 0x24ce8f0
DEBUG:disassembler:Adding explicit edge from block 0x24ce238 to 0x24cea80
DEBUG:disassembler:Adding explicit edge from block 0x24ca558 to 0x24ce5d0
DEBUG:disassembler:Adding explicit edge from block 0x24ce8f0 to 0x24cafa8
DEBUG:disassembler:Adding explicit edge from block 0x24ca5d0 to 0x24caee0
DEBUG:disassembler:Adding explicit edge from block 0x24ce5d0 to 0x24ce170
DEBUG:disassembler:Adding explicit edge from block 0x24cedf0 to 0x24ceb48
DEBUG:disassembler:Adding explicit edge from block 0x24cae18 to 0x24ced28
DEBUG:disassembler:Adding implicit edge from block 0x24ca648 to 0x24ca698
DEBUG:disassembler:Adding explicit edge from block 0x24ca648 to 0x24cebe8
DEBUG:disassembler:Adding explicit edge from block 0x24ca698 to 0x24ce760
DEBUG:disassembler:Adding explicit edge from block 0x24ceeb8 to 0x24bd800
DEBUG:disassembler:Adding explicit edge from block 0x24caee0 to 0x24caaf8
DEBUG:disassembler:Adding explicit edge from block 0x24ca738 to 0x24ce9b8
DEBUG:disassembler:Adding explicit edge from block 0x24ce760 to 0x24ce0a8
DEBUG:disassembler:Adding explicit edge from block 0x24ce698 to 0x24caa30
DEBUG:disassembler:Adding explicit edge from block 0x24ca788 to 0x24cae18
DEBUG:disassembler:Adding explicit edge from block 0x24cafa8 to 0x24ce3c8
INFO:deobfuscator:Control flow analysis completed.
INFO:deobfuscator:Starting simplication of basic blocks...
DEBUG:simplifier:Eliminating forwarders...
INFO:simplifier:Adding explicit edge from block 0x24ceb48 to 0x24ce828
INFO:simplifier:Adding explicit edge from block 0x24ca6e8 to 0x24ce828
INFO:simplifier:Adding implicit edge from block 0x24ca8f0 to 0x24ce828
DEBUG:simplifier:Forwarder basic block 0x24ca940 eliminated
INFO:simplifier:Adding explicit edge from block 0x24ce300 to 0x24ce828
DEBUG:simplifier:Forwarder basic block 0x24ca6e8 eliminated
INFO:simplifier:Adding explicit edge from block 0x24cedf0 to 0x24ce828
DEBUG:simplifier:Forwarder basic block 0x24ceb48 eliminated
INFO:simplifier:Adding explicit edge from block 0x24ca648 to 0x24ca558
DEBUG:simplifier:Forwarder basic block 0x24cebe8 eliminated
INFO:simplifier:Adding implicit edge from block 0x24ce3c8 to 0x24ca990
DEBUG:simplifier:Forwarder basic block 0x24ce468 eliminated
INFO:simplifier:Adding implicit edge from block 0x24ca648 to 0x24ce760
DEBUG:simplifier:Forwarder basic block 0x24ca698 eliminated
INFO:simplifier:Adding explicit edge from block 0x24ce3c8 to 0x24ce9b8
DEBUG:simplifier:Forwarder basic block 0x24ca738 eliminated
INFO:simplifier:7 basic blocks eliminated
DEBUG:simplifier:Merging basic blocks...
INFO:simplifier:Adding explicit edge from block 0x24ceeb8 to 0x24ca8f0
DEBUG:simplifier:Basic block 0x24bd800 merged with block 0x24ceeb8
INFO:simplifier:Adding explicit edge from block 0x24ce508 to 0x24ca648
DEBUG:simplifier:Basic block 0x24ca800 merged with block 0x24ce508
INFO:simplifier:Adding explicit edge from block 0x24caa30 to 0x24ca5d0
DEBUG:simplifier:Basic block 0x24ca878 merged with block 0x24caa30
INFO:simplifier:Adding explicit edge from block 0x24ce760 to 0x24cedf0
DEBUG:simplifier:Basic block 0x24ce0a8 merged with block 0x24ce760
INFO:simplifier:Adding implicit edge from block 0x24ceeb8 to 0x24ce828
DEBUG:simplifier:Basic block 0x24ca8f0 merged with block 0x24ceeb8
INFO:simplifier:Adding explicit edge from block 0x24ce5d0 to 0x24ce238
DEBUG:simplifier:Basic block 0x24ce170 merged with block 0x24ce5d0
INFO:simplifier:Adding explicit edge from block 0x24ce698 to 0x24ca5d0
DEBUG:simplifier:Basic block 0x24caa30 merged with block 0x24ce698
INFO:simplifier:Adding explicit edge from block 0x24ce238 to 0x24cabc0
DEBUG:simplifier:Basic block 0x24cea80 merged with block 0x24ce238
DEBUG:simplifier:Basic block 0x24caaf8 merged with block 0x24caee0
INFO:simplifier:Adding explicit edge from block 0x24cac88 to 0x24ce828
DEBUG:simplifier:Basic block 0x24ce300 merged with block 0x24cac88
DEBUG:simplifier:Basic block 0x24cec88 merged with block 0x24ce828
INFO:simplifier:Adding implicit edge from block 0x24cafa8 to 0x24ca990
INFO:simplifier:Adding explicit edge from block 0x24cafa8 to 0x24ce9b8
DEBUG:simplifier:Basic block 0x24ce3c8 merged with block 0x24cafa8
INFO:simplifier:Adding explicit edge from block 0x24ce238 to 0x24ceeb8
DEBUG:simplifier:Basic block 0x24cabc0 merged with block 0x24ce238
INFO:simplifier:Adding explicit edge from block 0x24ca990 to 0x24ce828
DEBUG:simplifier:Basic block 0x24cac88 merged with block 0x24ca990
INFO:simplifier:Adding explicit edge from block 0x24ce9b8 to 0x24ca648
DEBUG:simplifier:Basic block 0x24ce508 merged with block 0x24ce9b8
INFO:simplifier:Adding explicit edge from block 0x24cae18 to 0x24ce8f0
DEBUG:simplifier:Basic block 0x24ced28 merged with block 0x24cae18
INFO:simplifier:Adding explicit edge from block 0x24ce5d0 to 0x24ceeb8
DEBUG:simplifier:Basic block 0x24ce238 merged with block 0x24ce5d0
INFO:simplifier:Adding explicit edge from block 0x24cae18 to 0x24cafa8
DEBUG:simplifier:Basic block 0x24ce8f0 merged with block 0x24cae18
INFO:simplifier:Adding explicit edge from block 0x24ce698 to 0x24caee0
DEBUG:simplifier:Basic block 0x24ca5d0 merged with block 0x24ce698
INFO:simplifier:Adding explicit edge from block 0x24ca558 to 0x24ceeb8
DEBUG:simplifier:Basic block 0x24ce5d0 merged with block 0x24ca558
INFO:simplifier:Adding explicit edge from block 0x24ce760 to 0x24ce828
DEBUG:simplifier:Basic block 0x24cedf0 merged with block 0x24ce760
INFO:simplifier:Adding explicit edge from block 0x24ca788 to 0x24cafa8
DEBUG:simplifier:Basic block 0x24cae18 merged with block 0x24ca788
INFO:simplifier:Adding explicit edge from block 0x24ce9b8 to 0x24ca558
INFO:simplifier:Adding implicit edge from block 0x24ce9b8 to 0x24ce760
DEBUG:simplifier:Basic block 0x24ca648 merged with block 0x24ce9b8
INFO:simplifier:Adding implicit edge from block 0x24ca558 to 0x24ce828
DEBUG:simplifier:Basic block 0x24ceeb8 merged with block 0x24ca558
DEBUG:simplifier:Basic block 0x24caee0 merged with block 0x24ce698
DEBUG:simplifier:Basic block 0x24ca788 merged with block 0x24cad50
DEBUG:simplifier:Basic block 0x24cafa8 merged with block 0x24cad50
INFO:simplifier:Adding implicit edge from block 0x24ce698 to 0x24ca990
INFO:simplifier:Adding explicit edge from block 0x24ce698 to 0x24ce9b8
DEBUG:simplifier:Basic block 0x24cad50 merged with block 0x24ce698
INFO:simplifier:28 basic blocks merged.
INFO:deobfuscator:Simplication of basic blocks completed.
INFO:deobfuscator:Beginning verification of simplified basic block graph...
INFO:deobfuscator:Verification succeeded.
INFO:deobfuscator:Assembling basic blocks...
DEBUG:assembler:Performing a DFS on the graph to generate the layout of the blocks.
DEBUG:assembler:Morphing some JUMP_ABSOLUTE instructions to make file decompilable.
DEBUG:assembler:Verifying generated layout...
DEBUG:assembler:Successfully verified layout.
DEBUG:assembler:Calculating instruction operands.
DEBUG:assembler:Generating code...
INFO:deobfuscator:Successfully assembled.
INFO:__main__:Successfully deobfuscated code object \x0f\x1d\n\x00\x07\x0f\x0f
INFO:__main__:Collecting constants for code object \x0f\x1d\n\x00\x07\x0f\x0f
INFO:__main__:Code object \x0f\x1d\n\x00\x07\x0f\x0f contains embedded code object recur_factorial
INFO:__main__:Processing code object recur_factorial
DEBUG:deobfuscator:Code entrypoint matched PjOrion signature v2
INFO:deobfuscator:Original code entrypoint at 161
INFO:deobfuscator:Starting control flow analysis...
DEBUG:disassembler:Constructing basic blocks...
DEBUG:disassembler:Creating basic block 0x24ce3a0 spanning from 10 to 11, both inclusive
DEBUG:disassembler:Creating basic block 0x24bddc8 spanning from 19 to 19, both inclusive
DEBUG:disassembler:Creating basic block 0x24bda30 spanning from 22 to 22, both inclusive
DEBUG:disassembler:Creating basic block 0x24bdad0 spanning from 31 to 34, both inclusive
DEBUG:disassembler:Creating basic block 0x24bd9b8 spanning from 43 to 46, both inclusive
DEBUG:disassembler:Creating basic block 0x24bde68 spanning from 53 to 53, both inclusive
DEBUG:disassembler:Creating basic block 0x24bdc10 spanning from 63 to 66, both inclusive
DEBUG:disassembler:Creating basic block 0x24bdcb0 spanning from 84 to 87, both inclusive
DEBUG:disassembler:Creating basic block 0x24bd7d8 spanning from 92 to 93, both inclusive
DEBUG:disassembler:Creating basic block 0x24bdb98 spanning from 102 to 105, both inclusive
DEBUG:disassembler:Creating basic block 0x24bdf58 spanning from 110 to 113, both inclusive
DEBUG:disassembler:Creating basic block 0x24bdb48 spanning from 126 to 126, both inclusive
DEBUG:disassembler:Creating basic block 0x24ca8a0 spanning from 127 to 127, both inclusive
DEBUG:disassembler:Creating basic block 0x24caf58 spanning from 138 to 141, both inclusive
DEBUG:disassembler:Creating basic block 0x24ca7b0 spanning from 151 to 154, both inclusive
DEBUG:disassembler:Creating basic block 0x24ca670 spanning from 161 to 164, both inclusive
DEBUG:disassembler:16 basic blocks created
DEBUG:disassembler:Constructing edges between basic blocks...
DEBUG:disassembler:Adding explicit edge from block 0x24bdc10 to 0x24bdcb0
DEBUG:disassembler:Adding explicit edge from block 0x24ca7b0 to 0x24bdf58
DEBUG:disassembler:Adding explicit edge from block 0x24bda30 to 0x24bdb98
DEBUG:disassembler:Adding explicit edge from block 0x24ca670 to 0x24bd9b8
DEBUG:disassembler:Adding explicit edge from block 0x24ca8a0 to 0x24bdc10
DEBUG:disassembler:Adding explicit edge from block 0x24bdcb0 to 0x24ca7b0
DEBUG:disassembler:Adding explicit edge from block 0x24bdf58 to 0x24bd7d8
DEBUG:disassembler:Adding explicit edge from block 0x24bdb98 to 0x24bdb48
DEBUG:disassembler:Adding explicit edge from block 0x24ce3a0 to 0x24bde68
DEBUG:disassembler:Adding explicit edge from block 0x24bd9b8 to 0x24caf58
DEBUG:disassembler:Adding implicit edge from block 0x24bddc8 to 0x24bda30
DEBUG:disassembler:Adding explicit edge from block 0x24bddc8 to 0x24ca8a0
DEBUG:disassembler:Adding explicit edge from block 0x24caf58 to 0x24bddc8
INFO:deobfuscator:Control flow analysis completed.
INFO:deobfuscator:Starting simplication of basic blocks...
DEBUG:simplifier:Eliminating forwarders...
INFO:simplifier:Adding implicit edge from block 0x24bddc8 to 0x24bdb98
DEBUG:simplifier:Forwarder basic block 0x24bda30 eliminated
INFO:simplifier:Adding explicit edge from block 0x24bddc8 to 0x24bdc10
DEBUG:simplifier:Forwarder basic block 0x24ca8a0 eliminated
INFO:simplifier:2 basic blocks eliminated
DEBUG:simplifier:Merging basic blocks...
INFO:simplifier:Adding explicit edge from block 0x24bdcb0 to 0x24bdf58
DEBUG:simplifier:Basic block 0x24ca7b0 merged with block 0x24bdcb0
DEBUG:simplifier:Basic block 0x24bde68 merged with block 0x24ce3a0
INFO:simplifier:Adding explicit edge from block 0x24bdc10 to 0x24bdf58
DEBUG:simplifier:Basic block 0x24bdcb0 merged with block 0x24bdc10
INFO:simplifier:Adding explicit edge from block 0x24bd7d8 to 0x24ce3a0
DEBUG:simplifier:Basic block 0x24bdad0 merged with block 0x24bd7d8
DEBUG:simplifier:Basic block 0x24bdb48 merged with block 0x24bdb98
INFO:simplifier:Adding explicit edge from block 0x24bdc10 to 0x24bd7d8
DEBUG:simplifier:Basic block 0x24bdf58 merged with block 0x24bdc10
DEBUG:simplifier:Basic block 0x24ce3a0 merged with block 0x24bd7d8
INFO:simplifier:Adding explicit edge from block 0x24ca670 to 0x24caf58
DEBUG:simplifier:Basic block 0x24bd9b8 merged with block 0x24ca670
INFO:simplifier:Adding implicit edge from block 0x24caf58 to 0x24bdb98
INFO:simplifier:Adding explicit edge from block 0x24caf58 to 0x24bdc10
DEBUG:simplifier:Basic block 0x24bddc8 merged with block 0x24caf58
DEBUG:simplifier:Basic block 0x24bd7d8 merged with block 0x24bdc10
INFO:simplifier:Adding implicit edge from block 0x24ca670 to 0x24bdb98
INFO:simplifier:Adding explicit edge from block 0x24ca670 to 0x24bdc10
DEBUG:simplifier:Basic block 0x24caf58 merged with block 0x24ca670
INFO:simplifier:11 basic blocks merged.
INFO:deobfuscator:Simplication of basic blocks completed.
INFO:deobfuscator:Beginning verification of simplified basic block graph...
INFO:deobfuscator:Verification succeeded.
INFO:deobfuscator:Assembling basic blocks...
DEBUG:assembler:Performing a DFS on the graph to generate the layout of the blocks.
DEBUG:assembler:Morphing some JUMP_ABSOLUTE instructions to make file decompilable.
DEBUG:assembler:Verifying generated layout...
DEBUG:assembler:Successfully verified layout.
DEBUG:assembler:Calculating instruction operands.
DEBUG:assembler:Generating code...
INFO:deobfuscator:Successfully assembled.
INFO:__main__:Successfully deobfuscated code object recur_factorial
INFO:__main__:Collecting constants for code object recur_factorial
INFO:__main__:Generating new code object for recur_factorial
INFO:__main__:Generating new code object for \x0f\x1d\n\x00\x07\x0f\x0f
INFO:__main__:Writing deobfuscated code object to disk
INFO:__main__:Success
``````

Running this we get back the deobfuscated code in the file wrapper_deobf.pyc. We can now run a python decompiler on this to get back our deobfuscated code as shown in Figure 4.

 Figure 4: Decompiling the deobfuscated code

1. Please record video and send mee , pishey16@gmail.com
If you send me video tutioral, i sent you 200\$

1. Thanks for the comment but I do not plan to make a video at the moment. You can here write here in comments where you are stuck.

2. AnonymousJuly 17, 2017

Stuck on Step one. What I'm I doing wrong.

C:\PJOrion\Deobfuscate\pjunwrapper-master>python pjunwrapper.py --ifile=mod_updater.pyc
XXX lineno: 1, opcode: 206
[*] Dumped 1 code object
XXX lineno: 1, opcode: 8
XXX lineno: 1, opcode: 247
Traceback (most recent call last):
File "pjunwrapper.py", line 57, in
eval(co)
File "mod_updater", line 1, in
File "mod_updater", line 1, in
File "mod_updater", line 1, in

ImportError: No module named BigWorld

1. The script is protected using "Exec only in WOT" mode. For the moment you have to make sure that the script can import BigWorld module. Later I plan to figure out some way to fake the presence of that said module which will alleviate the need for this.

2. How do you import the BigWorld module to get round the"ImportError: No module named BigWorld" error?

Thanks

3. Maybe it is will help https://github.com/jhakonen/wot-teamspeak-mod/blob/master/futes/fakes/BigWorld.py

4. Yes, I am aware of the wot-teamspeak-mod. However it needs some changes to be useful.

3. AnonymousJuly 20, 2017

INFO:simplifier:564 basic blocks merged.
INFO:deobfuscator:Simplification of basic blocks completed.
INFO:deobfuscator:Beginning verification of simplified basic block graph...
INFO:deobfuscator:Verification succeeded.
INFO:deobfuscator:Assembling basic blocks...
DEBUG:assembler:Performing a DFS on the graph to generate the layout of the blocks.
DEBUG:assembler:Morphing some JUMP_ABSOLUTE instructions to make file decompilable.
DEBUG:assembler:Verifying generated layout...
INFO:assembler:Basic block 0x34e7648 uses a relative control transfer instruction to access block 0x34e7f08 located before it.
INFO:assembler:Basic block 0x303cb98 uses a relative control transfer instruction to access block 0x40865f8 located before it.
INFO:assembler:Basic block 0x3f44468 uses a relative control transfer instruction to access block 0x34ec080 located before it.
DEBUG:assembler:Successfully verified layout.
DEBUG:assembler:Calculating instruction operands.
DEBUG:assembler:Generating code...
INFO:deobfuscator:Successfully assembled.
INFO:__main__:Successfully deobfuscated code object \x11\x06\x11\x0f\x19\x0e
INFO:__main__:Collecting constants for code object \x11\x06\x11\x0f\x19\x0e
INFO:__main__:Generating new code object for \x11\x06\x11\x0f\x19\x0e
INFO:__main__:Code object \x17\x1b\x11\x17\x18\x16\x1b contains embedded code object 6q:s{~~h
INFO:__main__:Processing code object 6q:s{~~h
DEBUG:deobfuscator:Code entrypoint matched PjOrion signature v2
INFO:deobfuscator:Original code entrypoint at 22037
INFO:deobfuscator:Starting control flow analysis...
Traceback (most recent call last):
File "main.py", line 72, in
process(args.ifile, args.ofile)
File "main.py", line 58, in process
deob = parse_code_object(rootCodeObject)
File "main.py", line 37, in parse_code_object
mod_const.append(parse_code_object(const))
File "main.py", line 37, in parse_code_object
mod_const.append(parse_code_object(const))
File "main.py", line 20, in parse_code_object
co_codestring = deobfuscate(codeObject.co_code)
File "C:\Python27\prog\bytecode_simplifier-master\deobfuscator.py", line 67, in deobfuscate
File "C:\Python27\prog\bytecode_simplifier-master\disassembler.py", line 118, in find_leaders
File "C:\Python27\prog\bytecode_simplifier-master\decoder.py", line 15, in decode_at
assert offset < len(self.insBytes)
AssertionError

4. AnonymousJuly 21, 2017

pjunwrapper not working with pjorion 1.3.3

5. File "pjunwrapper.py", line 39, in trace
marshal.dump(pystack.getStackItem(frame, 2), f)
AttributeError: 'module' object has no attribute 'getStackItem'

1. fixed

but now I got this:

F:\pjunwrapper-master>python pjunwrapper.py --ifile=mod.pyc
XXX lineno: 1, opcode: 187
XXX lineno: 1, opcode: 241
XXX lineno: 1, opcode: 18

F:\pjunwrapper-master>

2. This comment has been removed by the author.

6. Hey,
Will I be able to do all this in Linux? I saw there is a requirement for some WoT library (BigWorld), I guess it's a python (i.e. cross-platform) library right? Which means I would be able to just it over from Windows

1. s/just it over/just copy it over/

7. Hi,
another anonymous, same problem: no module named BigWorld.
Am I right to assume that the only way to overcome this currently would be to buy a license of the BigWorld engine? - Or could there be some magic trick with the game running in the background (sorry for the ignorant question, its just a desperate guess)? Thanks.

1. I don't think a license of BigWorld is required. At runtime, PjOrion checks for the existence of BigWorld module before processing. So, it should be possible to create a fake BigWorld module to pass the check. Finding out how to do this is on my agenda, but again there are no promises when.

In case you decide to have a look, note that the check is a bit more deep than just checking for the module's existence. You may need to create some fake variables, classes, functions etc in the fake module to successfully override the check.

8. python pjunwrapper.py --ifile=mod.pyc
[*] Dumped 1 code object
Traceback (most recent call last):
File "pjunwrapper.py", line 57, in
eval(co)
File "hru-hru", line 2, in
File "hru-hru", line 10, in
File "hru-hru", line 14, in
File "hru-hru", line 16, in
File "hru-hru", line 5, in
File "hru-hru", line 55, in
File "hru-hru", line 55, in
File "hru-hru", line 55, in
File "hru-hru", line 55, in
File "hru-hru", line 55, in
ImportError: No module named BigWorld

9. I encountered the following error
'pystack' has no 'getStackItem' member
Please tell me which module to install?
i just run pip install pystack

1. pystack isn't available on PyPI. It's available at GitHub
https://github.com/extremecoders-re/pystack

2. thank u

10. So, is there a trick to import BigWorld module in the script?
It's sad to see this work stay as a proof of concept and not be able to use it for it's original purpose: deobfuscating pjorion protected wot mods...
Any help would be much apreciated :)

11. I'm getting this error..

I've installed the .pyd in "C:\Python27\Lib\site-packages" like I've seen to do online and I'm getting that error below. Any help is appreciated :)

Error in module '__main__': No module named ResMgr

12. AnonymousJune 14, 2018

Are there any news on the "BigWorld module" problem?
I would really love to have the possibility to deobfuscate WoT mods.

13. Hello, I followed what you said and I almost succeed until I faced with this problem, can you suggest me any solution or idea about what to do ?

INFO:deobfuscator:Successfully assembled.
INFO:__main__:Successfully deobfuscated code object \x02\x16\x1f\r\x1b\x10\x0c\x01\x0f\x13\x10
INFO:__main__:Collecting constants for code object \x02\x16\x1f\r\x1b\x10\x0c\x01\x0f\x13\x10
INFO:__main__:Generating new code object for \x02\x16\x1f\r\x1b\x10\x0c\x01\x0f\x13\x10
INFO:__main__:Code object \x18\r\x02\x05\x19\x0e\x18 contains embedded code object r7p~t#t{
INFO:__main__:Processing code object r7p~t#t{
WARNING:deobfuscator:Code entrypoint did not match PjOrion signature
INFO:deobfuscator:Original code entrypoint at 0
INFO:deobfuscator:Starting control flow analysis...
Traceback (most recent call last):
File "C:\Users\me\Desktop\bytecode_simplifier-master\main.py", line 72, in
process(args.ifile, args.ofile)
File "C:\Users\me\Desktop\bytecode_simplifier-master\main.py", line 58, in process
deob = parse_code_object(rootCodeObject)
File "C:\Users\me\Desktop\bytecode_simplifier-master\main.py", line 37, in parse_code_object
mod_const.append(parse_code_object(const))
File "C:\Users\me\Desktop\bytecode_simplifier-master\main.py", line 37, in parse_code_object
mod_const.append(parse_code_object(const))
File "C:\Users\me\Desktop\bytecode_simplifier-master\main.py", line 20, in parse_code_object
co_codestring = deobfuscate(codeObject.co_code)
File "C:\Users\me\Desktop\bytecode_simplifier-master\deobfuscator.py", line 67, in deobfuscate
File "C:\Users\me\Desktop\bytecode_simplifier-master\disassembler.py", line 118, in find_leaders
File "C:\Users\me\Desktop\bytecode_simplifier-master\decoder.py", line 15, in decode_at
assert offset < len(self.insBytes)
AssertionError

14. How to fix it?

15. >>> import pystack

Traceback (most recent call last):
File "", line 1, in
import pystack
ImportError: DLL load failed: %1 не является приложением Win32.

How to fix it?

16. Thanks for this blog post!

Though I've question, I get error "application was unable to start correctly (0xc0000007b)" when launching python after replacing python27.dll with yours. Why does this happen?

1. Ok I resolved this error by installing 32bit python. Now I can launch modified python but pjunrwapper doesnt work at all, no errors, but it doesnt generate files

2. Talking to myself yah, fixed this too on 64bit win10 machine by moving Author's DLL into SysWOW64 folder instead of System32

17. .......
.......
.......
DEBUG:assembler:Calculating instruction operands.
DEBUG:assembler:Generating code...
INFO:deobfuscator:Successfully assembled.
INFO:__main__:Successfully deobfuscated code object \x08\x00\x11\x1d
INFO:__main__:Collecting constants for code object \x08\x00\x11\x1d
INFO:__main__:Generating new code object for \x08\x00\x11\x1d
INFO:__main__:Code object \x07\x07\x01\x16\x02\x1a\x19 contains embedded code ob
ject .y-s1y7#
INFO:__main__:Processing code object .y-s1y7#
DEBUG:deobfuscator:Code entrypoint matched PjOrion signature v2
INFO:deobfuscator:Original code entrypoint at 23069
INFO:deobfuscator:Starting control flow analysis...
Traceback (most recent call last):
File "main.py", line 72, in
process(args.ifile, args.ofile)
File "main.py", line 58, in process
deob = parse_code_object(rootCodeObject)
File "main.py", line 37, in parse_code_object
mod_const.append(parse_code_object(const))
File "main.py", line 37, in parse_code_object
mod_const.append(parse_code_object(const))
File "main.py", line 20, in parse_code_object
co_codestring = deobfuscate(codeObject.co_code)
File "C:\Python27\deobfuscator.py", line 67, in deobfuscate
File "C:\Python27\disassembler.py", line 118, in find_leaders
File "C:\Python27\decoder.py", line 15, in decode_at
assert offset < len(self.insBytes)
AssertionError

---------------------------
how to fix the error ???
---------------------------

18. This comment has been removed by the author.

19. excatly the same to me!

also error message

ImportError: No module named ResMgr

arise some time

============================================================
Are there any news on the "BigWorld module" problem?
I would really love to have the possibility to deobfuscate WoT mods.