Svenskithesource / PyArmor-Unpacker

A deobfuscator for PyArmor.
GNU General Public License v3.0
536 stars 75 forks source link

sorry, i can't understand `"Now you can run the partially unpacked program using run.py"`. #37

Closed Open-AGI closed 1 year ago

Open-AGI commented 1 year ago

sorry, i can't understand "Now you can run the partially unpacked program using run.py". I'm not sure if this is related to the error reported earlier that.

After I injected the "PyInjector dll", the terminal showed

Traceback (most recent call last):
  File "<string>", line 4, in <module>
  File "<string>", line 10, in <module>
NameError: name 'code' is not defined

So, i chuange the code.py file to:

import sys, marshal

for frame in sys._current_frames().values(): # Loop all the threads running in the process
    #if "frozen" in frame.f_code.co_filename: # Find the correct thread (when injecting this code it also creates a new thread so we need to find the main one)
    while frame.f_back.f_back != None: # NOTE the frame before None is the obfuscated one
        frame = frame.f_back # Keep going one frame back until we find the main frame (see NOTE above on how we identify it)
    code = frame.f_code
    break

open("dumped.marshal", "wb").write(marshal.dumps(code))

Thank you very much for any helps.

Svenskithesource commented 1 year ago

Is there any reason you chose method 1? This error will occur with the other methods as well but they are better in general. Are you injecting it while it's waiting for input?

Open-AGI commented 1 year ago

Thank you very much for your reply. I saw you say:

IMPORTANT: USE THE SAME PYTHON VERSION EVERYWHERE, LOOK AT WHAT THE PROGRAM YOU ARE UNPACKING IS COMPILED WITH. If you don't you will face issues.

The obfuscated .py file requires python3.6.6 to run, so I chose the method 1.

My main.py :

from pytransform import pyarmor_runtime
pyarmor_runtime()
__pyarmor__(__name__, __file__, b'\x50\x59\x41\x52\x4d\x4f\x52\x00...\x3d\x3c\x1c\x55\xbe', 2)

If I add input() to the main.py file, and then run python main.py , the result is:

Check bootstrap restrict mode failed

So I add input() in .\pytransform\__init__.py

# These module alos are used by protection code, so that protection
# code needn't import anything
import os
import platform
import sys
import struct
input()
# Because ctypes is new from Python 2.5, so pytransform doesn't work
# before Python 2.5

And then, i run python main.py , the result is:

Traceback (most recent call last):
  File "<string>", line 4, in <module>
  File "<string>", line 10, in <module>
NameError: name 'code' is not defined

So, i removed the if "frozen" in frame.f_code.co_filename: from the code.py file(method 1).

And then, i run python main.py ,the program starts and runs normally.

And then I double-clicked to run method_1.py, and then run run.py, but I don't know how to get the deobfuscated source code.

Svenskithesource commented 1 year ago

Right now you're waiting for input before the program has been ran, which causes the code object to not exist. You need to find a way to make the program wait while it's running, perhaps it does this automatically or you can hijack a different package that it imports.

Open-AGI commented 1 year ago

Sorry, I still don't understand, can you give me a specific example?

Svenskithesource commented 1 year ago

Let's say program x has an obfuscated module y. If module y imports an external module requests, then you could create requests.py in the same directory. That way when you run program x it will trigger the unpacker in the fake requests package. You'll need to modify the script to grab the right code object (using sys._getframe). Or you can put input() in the fake package and inject.

Open-AGI commented 1 year ago

Thank you very much, I understand what to do, thank you for your patience guidance.