Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support python2.x on Linux #26

Open
w1nds opened this issue Oct 18, 2022 · 7 comments
Open

Support python2.x on Linux #26

w1nds opened this issue Oct 18, 2022 · 7 comments
Labels
enhancement New feature or request

Comments

@w1nds
Copy link

w1nds commented Oct 18, 2022

decrypt python 2.7 under Linux, hope it will be supported.

Injector:https://github.com/gaffe23/linux-inject
so:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
#include <link.h>
#include<pthread.h>
#include<unistd.h>
void my_init(void) __attribute__((constructor)); 
void my_fini(void) __attribute__((destructor)); 


void logfile(const char *szText)
{
    FILE *fp = fopen("/tmp/slog.txt","a+");
    if(fp)
    {
        fwrite(szText,strlen(szText),1,fp);
        fclose(fp);
    }
}

enum PyGILState_STATE{ 
    PyGILState_LOCKED, 
    PyGILState_UNLOCKED 
};

struct PyCompilerFlags{
	int cf_flags;  /* bitmask of CO_xxx flags relevant to future */
	int cf_feature_version;  /* minor Python version (PyCF_ONLY_AST) */
};

typedef void (*pPy_SetProgramName)(char*);
typedef void(* _PyEval_InitThreads)();
typedef PyGILState_STATE(* _PyGILState_Ensure)();
typedef void(* _PyGILState_Release)(PyGILState_STATE);
typedef int(* _PyRun_SimpleStringFlags)(const char*, PyCompilerFlags*);



void InitCPython()
{
    pPy_SetProgramName Py_SetProgramName = NULL;
    _PyEval_InitThreads PyEval_InitThreads;
    _PyGILState_Ensure PyGILState_Ensure;
    _PyGILState_Release PyGILState_Release;
    _PyRun_SimpleStringFlags PyRun_SimpleStringFlags;
    void * hPython  = dlopen("/usr/lib64/libpython2.7.so.1.0",RTLD_GLOBAL | RTLD_LAZY);
    if (hPython)
    {
        Py_SetProgramName = (pPy_SetProgramName)dlsym(hPython, "Py_SetProgramName");
        PyEval_InitThreads = (_PyEval_InitThreads)(dlsym(hPython, "PyEval_InitThreads"));
        PyGILState_Ensure = (_PyGILState_Ensure)(dlsym(hPython, "PyGILState_Ensure"));
        PyGILState_Release = (_PyGILState_Release)(dlsym(hPython, "PyGILState_Release"));
        PyRun_SimpleStringFlags = (_PyRun_SimpleStringFlags)(dlsym(hPython, "PyRun_SimpleStringFlags"));

        Py_SetProgramName("PyInjector");
        PyEval_InitThreads();
        PyGILState_STATE s = PyGILState_Ensure();
        PyRun_SimpleStringFlags("import os\nwith open(\"/wtest/code.py\",\"r\") as file:\n   data = file.read()\nexec(data)",0); // more easy to execute wanted code this way
        PyGILState_Release(s);
    }
    else
    {
        logfile("open libpython2 failed\n");
    }    
}

void* fun(void *arg)
{
    InitCPython();
}
void my_init(void)  
{  
    logfile("init\n");
    pthread_t id;
    pthread_create(&id,NULL,fun,NULL);
    // InitCPython();
}  
void my_fini(void)  
{  
}
@Svenskithesource
Copy link
Owner

Hey, thanks for making methods 1 and 2 work on Linux! Did you try both methods? Can you maybe include the build command you used to compile the library? Definitely interested in including this.

@Svenskithesource Svenskithesource changed the title unspport python2.x Support python2.x on Linux Oct 18, 2022
@Svenskithesource Svenskithesource added the enhancement New feature or request label Oct 18, 2022
@w1nds
Copy link
Author

w1nds commented Oct 18, 2022

Sorry, I haven't tried it on Linux python 3.x, I tried 2.x directly。
build the library command
gcc test.cpp -o test.so -fPIC -shared -ldl

@Svenskithesource
Copy link
Owner

Hey, I'm not asking to try it on Python 3.x, I was just wondering if you tried both method 1 and method 2. Since those are the methods that require injecting. Thanks for the build command btw!

@w1nds
Copy link
Author

w1nds commented Oct 18, 2022

Yes, I tried method 1 and 2, both suggest some syntax errors, I tried to modify some syntax errors in method 2, until suggest inspect module object has no attribute 'Signature' ,then I came to submit the issue, haha...

@Svenskithesource
Copy link
Owner

Ah, that wasn't clear in your first message. Currently, I'm not planning on supporting Python 2.x. You can try to figure out what functions I used are non-existing in Python 2.x and try to find alternatives for them. I'll gladly accept a pull request if you figure it out!

@w1nds
Copy link
Author

w1nds commented Oct 24, 2022

some questions, thx

  1. i used method 2 in linux for python2.7。 the py script import an package encryped by pyarmor,for example:
# -*- coding: utf-8 -*-
import re
import sys
from test.fuck.handle import main
if __name__ == '__main__':
    sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
    sys.exit(main())

everything under the test package is encrypted,i inject then run method2 ,but the dumped file is _usr_lib64_python2.7_threading.pyc,not the test.fuck.handle.main function I want。

  1. I rebuild libpython for python2.7,modifyed PyEval_EvalFrameEx function to dump the PyCodeObject,but I found that the dumped pyc is the same as the original file after decompiling,it's also__pyarmor__(__name__, __file__, 'v\xd0

sorry for my poor english ,I don't know if you understand my description O(∩_∩)O~

@Svenskithesource
Copy link
Owner

Is the test module importing any external libraries? If so you can create a .py file with the same name and put an input() which will give you time to dump it while Python is executing the test module. It could be possible that you'll have to change the script to make it find the test module in the threads, as the name of the frame will probably be the name of the module that you're hijacking. You could also just put the method 2 inside of the hijacked module so that when the script imports the module you can just do sys._getframe(1) to get the test's module.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants