Summary of using C language to call python
Recently, I am working on a vulnerability presentation platform. The attack implementation part is implemented using python, And the C language implementation part uses the libcli library for a telnet-like implementation. The python module is called when the callback function is run. I made a demo for calling python in c.
Python module: demo. py
def print_arg(str): print strdef add(a,b): print 'a=', a print 'b=', b return a + bclass Class_A: def __init__(self): print "init" def fun(self, str): print 'hello', str return strclass dedecms_get_webshell: def __init__(self): ''' ''' self._run = True #must rewrite function def check(self,site,port): ''' ''' print "Exploiting Host:%s,Port:(%d)......" % (site,port) flag = 1 if flag: content={"flag":1,"content":"POST http://www.baidu.com/shell.php (cmd)"} else: content={"flag":0,"content":"POST http://www.baidu.com/shell.php (cmd)"} return contentif __name__=="__main__": site="www.baidu.com" port=80 obj = dedecms_get_webshell() ret=obj.check(site,port)print ret
Analysis:
1. print_arg defines a function for passing parameters.
2. add defines a function that is passed as multiple parameters and has returned values.
3. Class_A defines a class and a method of the class fun (passing parameters with returned values)
4. dedecms_get_webshell defines a method check for the Class and Class (passing multiple parameters, and the returned value is a tuples)
The following uses the C language to call the functions in the demo. py file.
Test function:
#include
int main(int argc, char* argv[]){ test(); test1(); test2(); test3(); test4(); return 0;}
Analysis one by one:
// Export the current environment variable
void getcurrent(){ PyRun_SimpleString("import sys"); PyRun_SimpleString("sys.path.append('./')"); return;}
1. A basic call Method
Void test () {Py_Initialize (); // initialize python PyRun_SimpleString ("print 'Hello python'"); // directly run python code Py_Finalize (); // release python return ;}
Analysis: directly run the python code. You must initialize the code (Py_Initialize) before calling the code. after calling the code, clear the code (Py_Finalize)
2. Call a common function in the module.
Void test1 () {Py_Initialize (); // initialize python getcurrent (); PyObject * pModule = NULL, * pFunc = NULL, * pArg = NULL; pModule = PyImport_ImportModule ("demo"); // introduce the module pFunc = PyObject_GetAttrString (pModule, "print_arg"); // directly obtain the function pArg = Py_BuildValue ("(s) in the module) "," hello_python "); // convert the parameter type to pass a string. Convert the c/c ++ string to the python type. For the python type in the tuples, see the python document PyEval_CallObject (pFunc, pArg). // call the directly obtained function, and pass the parameter Py_Finalize (); // release python return ;}
Analysis: first reference the module (PyImport_ImportModule), then obtain the function (PyObject_GetAttrString) in the module, and perform type conversion (Py_BuildValue ("(s )", "hello_python"), and then directly call the function and pass the parameter (PyEval_CallObject ).
3. Call a function in the module (multiple parameters with return values)
Void test2 () {Py_Initialize (); getcurrent (); PyObject * pModule = NULL, * pDict = NULL, * pFunc = NULL, * pArg = NULL, * result = NULL; pModule = PyImport_ImportModule ("demo"); // import module pDict = PyModule_GetDict (pModule); // obtain the module dictionary attribute // equivalent to the _ dict _ attribute of the Python module object, obtain the dictionary object pFunc = PyDict_GetItemString (pDict, "add") in the module namespace. // obtain the pArg = Py_BuildValue ("(I, I )", 1, 2); // parameter type conversion, pass two Integer Parameters result = PyEval_CallObject (pFunc, pArg); // call the function and obtain the python-type return value int sum; pyArg_Parse (result, "I", & sum); // convert the return value of the python type to c/c ++ printf ("sum = % d \ n ", sum); Py_Finalize ();}
4. A simple class in the call module (a single return value)
Void test3 () {Py_Initialize (); getcurrent (); PyObject * pModule = NULL, * pDict = NULL, * pClass = NULL, * pInstance = NULL, * result = NULL; pModule = PyImport_ImportModule ("demo"); // import module pDict = PyModule_GetDict (pModule); // obtain module dictionary attributes pClass = PyDict_GetItemString (pDict, "Class_A "); // obtain the class pInstance = PyInstance_New (pClass, NULL, NULL) in the module by Using Dictionary attributes; // obtain the class result = PyObject_CallMethod (pInstance, "fun", "(s) Through instantiation) "," python_000 "); // call the class method char * name = NULL; PyArg_Parse (result," s ", & name ); // convert the return value of the python type to c/c ++ printf ("% s \ n", name); Py_Finalize ();}
5. A simple class in the call module (the returned value is a tuples)
Void test4 ()
{
Py_Initialize ();
Getcurrent ();
PyObject * pModule = NULL, * pDict = NULL, * pClass = NULL, * pInstance = NULL, * result = NULL;
PModule = PyImport_ImportModule ("demo"); // introduce the module
PDict = PyModule_GetDict (pModule); // obtain the module dictionary attribute
PClass = PyDict_GetItemString (pDict, "dedecms_get_webshell"); // obtain classes in the module by Using Dictionary attributes
PInstance = PyInstance_New (pClass, NULL, NULL );
Result = PyObject_CallMethod (pInstance, "check", "(s, I)", "www.baidu.com", 80 );
Int flag;
Char * content = NULL;
PyObject * obj_content = PyDict_GetItemString (result, "content ");
Content = PyString_AsString (obj_content );
PyObject * obj_flag = PyDict_GetItemString (result, "flag ");
Flag = PyInt_AsLong (obj_flag );
Printf ("content: % s, flag: % d \ n", content, flag );
Py_Finalize ();
}
Makefile writing:
all: testtest: pytest.o gcc -L/usr/lib/python2.7/ -lpython2.7 -ldl pytest.o -o testpytest.o: pytest.c gcc -g -std=gnu99 -Wall -c pytest.c -I/usr/include/python2.7/ clean: @rm -rf *.o *.pyc test
For different python versions, use 2.5, 2.6, and so on. For the library path, refer to the installation path.
I was going to start writing more things.