Unpacking PyArmor with CPython
				
				
			
			 Some people think that PyArmor is the obfuscator gold standard for python, but you can easly mess with CPython API, here is what we gonna see it this little article. 
			
			
			
				
The Genesis - Injecting Python Code
				
				
			
			The fondation of unpacking PyArmor is injecting python code, he can be easly done with CPython API combined with DLL Injection, for starting you will create a new dll project in visual studio.
			
			
			
			Once you have your project ready it's time to import some CPython libs, simply go in Properties,VC++ Directory,Include Directory add CPython Include, and in Lib Directory add CPython libs.
			
			
			 
			
			
			If you successfully included CPython into your project you should have no problem including Python.h.
			
			
			So there here is a simple code for testing CPython Injection, we will use PyRun_SimpleString function.
			
DWORD WINAPI MainThread(HMODULE hModule)
{
    Py_SetProgramName(L"pyinject");
    PyEval_InitThreads(); // in newest version of python is not really necessary
    PyGILState_STATE s = PyGILState_Ensure(); /* Ensure that the current thread is ready to call the Python
C API, regardless of the current state of Python, or of its
thread lock.*/
    PyRun_SimpleString("print('Injected !')");
    PyGILState_Release(s);
    CloseHandle(hModule);
    FreeLibraryAndExitThread(hModule, 0);
    return 0;
}
			Now you can hit compile and test this out, i have created a little script wich print "Waiting for inject..." everytime i hit any key
			
while True:
	print("Waiting for inject...")
	input()So if we inject the dll into python.exe we should get "Injected !" message
			
			
			 
			
			
			Now that we know the CPython api is working let's unpack pyarmor !
			
			
			
				
The Actual unpacking part
			
				
				
				When you can inject python code into any python script it become really easy to unpack or crack any type of python program, i have created a simple python script wich looks like that
				
def auth():
	return False
while True:
	input("user> ")
	if(auth()):
		print("Welcome Admin !")
	else:
		print("You are not authorized.")
				The goal is to unpack the auth function this can be easly do with dis lib.
				
				
				Here is the result
				 
				
				
				As you can see this is a huge mess just for a return False function, why ?
				
				
				This is the downside of this method, pyarmor encrypt all functions,bytecodes,etc.. and only decrypt them at runtime when the function is used.
				
				
				But ! You can still replace the function or call it, and that's pretty interesting if your plan is to crack a python program.
				
				
				
					
End
				
				
				
				As you can see is not an easy task to unpack/crack a python script protected with PyArmor but with some works you can get it !