使用c語言調用python小結

來源:互聯網
上載者:User

標籤:函數   工作   類型轉換   attrs   module   結果   rewrite   void   content   

近期在做一個漏洞展示平台,攻擊實現部分使用python實現。c語言實現部分使用libcli庫做一個類似telnet的東東,回呼函數run的時候調用python模組。

針對c調用python,做個了小demo

python模組: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

分析:

1. print_arg定義了一個傳參的函數

2. add 定義了一個傳如多個參數。且有返回值的函數

3. Class_A定義了一個類及類的一個方法fun(傳參數。有返回值)

4. dedecms_get_webshell定一個了類及類的一個方法check(傳多個參數,返回值是個元組)

 

以下使用c語言調用demo.py檔案裡的函數。

 測試函數:

#include <Python.h>int main(int argc, char* argv[]){    test();    test1();    test2();    test3();    test4();    return 0;}

逐個分析:

//匯出當前環境變數

void getcurrent(){    PyRun_SimpleString("import sys");    PyRun_SimpleString("sys.path.append('./')");    return;}

1. 一個最主要的調用方式

void test(){    Py_Initialize();//初始化python    PyRun_SimpleString("print 'hello python'");//直接執行python代碼    Py_Finalize(); //釋放python    return;}

分析:直接執行python 代碼,在調用的時候必須先做初始化操作(Py_Initialize),調用完後做清理工作(Py_Finalize)

2. 調用模組中的一個普通函數

void test1(){    Py_Initialize();//初始化python    getcurrent();    PyObject *pModule = NULL, *pFunc = NULL, *pArg = NULL;    pModule = PyImport_ImportModule("demo");//引入模組    pFunc = PyObject_GetAttrString(pModule, "print_arg");//直接擷取模組中的函數    pArg = Py_BuildValue("(s)", "hello_python"); //參數類型轉換,傳遞一個字串。將c/c++類型的字串轉換為python類型。元組中的python類型查看python文檔    PyEval_CallObject(pFunc, pArg); //調用直接獲得的函數。並傳遞參數    Py_Finalize(); //釋放python    return;}

分析:先引用模組(PyImport_ImportModule)。然後擷取模組中的函數(PyObject_GetAttrString)。對c傳入python 的參數做類型轉換(Py_BuildValue("(s)","hello_python"))。最後直接調用函數並傳遞參數(PyEval_CallObject)。

3. 調用模組中的一個函數(多參數,帶返回值)

void test2(){    Py_Initialize();    getcurrent();    PyObject *pModule = NULL, *pDict = NULL, *pFunc = NULL, *pArg = NULL, *result = NULL;    pModule = PyImport_ImportModule("demo"); //引入模組    pDict = PyModule_GetDict(pModule); //擷取模組字典屬性 //相當於Python模組對象的__dict__ 屬性,得到模組名稱空間下的字典對象    pFunc = PyDict_GetItemString(pDict, "add"); //從字典屬性中擷取函數    pArg = Py_BuildValue("(i, i)", 1, 2); //參數類型轉換,傳遞兩個整型參數    result = PyEval_CallObject(pFunc, pArg); //調用函數。並得到python類型的傳回值    int sum;    PyArg_Parse(result, "i", &sum); //將python類型的傳回值轉換為c/c++類型    printf("sum=%d\n", sum);    Py_Finalize();}

4. 調用模組中簡單的一個類(單個返回值)

void test3(){    Py_Initialize();    getcurrent();    PyObject *pModule = NULL, *pDict = NULL, *pClass = NULL, *pInstance = NULL, *result = NULL;    pModule = PyImport_ImportModule("demo"); //引入模組    pDict = PyModule_GetDict(pModule); //擷取模組字典屬性    pClass = PyDict_GetItemString(pDict, "Class_A"); //通過字典屬性擷取模組中的類    pInstance = PyInstance_New(pClass, NULL, NULL);//執行個體化擷取的類    result = PyObject_CallMethod(pInstance, "fun", "(s)", "python_000"); //調用類的方法    char* name=NULL;    PyArg_Parse(result, "s", &name); //將python類型的傳回值轉換為c/c++類型    printf("%s\n", name);    Py_Finalize();}

5. 調用模組中一個簡單的類(返回值是個元組)

void test4()

{

    Py_Initialize();

    getcurrent();

 

    PyObject *pModule = NULL, *pDict = NULL,*pClass = NULL, *pInstance = NULL, *result = NULL;

    pModule =PyImport_ImportModule("demo"); //引入模組

    pDict = PyModule_GetDict(pModule); //擷取模組字典屬性

    pClass = PyDict_GetItemString(pDict,"dedecms_get_webshell"); //通過字典屬性擷取模組中的類

    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書寫:

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

針對python不同的版本號碼。使用2.5,2.6等,庫的路徑參照安裝的路徑。

 

本打算展開多寫些東西,結果草草完事。


使用c語言調用python小結

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.