What is a .pyd file? A .pyd file is only a .dll (renamed in .pyd) that contains the necessary information to use it as a python module.
PS. The "main" function of this lib "_mydaemon" is "init_mydaemon", if you want to change the name to (es.) "smthelse" the relative "main" function should be "initsmthelse".
There are 2 ways to build a .pyd on windows:
- distutils (there are more issues with python22, vc++6 and another distutils's settings on recent windows OSes and current compilers=bad way)
- using directly a compiler such as vc++ (tested on vs2010)
The relative ways
I said there are 2 ways, no?
- The first way is the worst but if you don't care about this, here how to do it:
-Create a .bat with this inside: (if you want to use another compiler other than vc++6 you have to edit the relative details inside python22\lib\distutils\msvccompiler.py; NB. you can also use mingw! NB2. for this .bat I'm using vs100!)
And, into the relative .py:Code:call "%vs100comntools%vsvars32.bat" python .\_mydaemon\setup.py build -cmsvc --force pause
So, run the .bat and hope that everything will go well.Code:import distutils from distutils.core import setup, Extension setup(name = '_mydaemon', version = '1.8', author = 'martysama0134', description = 'MyDaemon Package', url = 'http://docs.python.org/extending/building', ext_modules = [Extension('_mydaemon', sources = [r'c:\Users\blablabla\_mydaemon\_mydaemon.cpp'],)] )
(you'll find the source of _mydaemon.cpp below) - Second way (tested on vs2010)
Create a project with this 2 files:
Code:// _mydaemon.h #pragma once //# pyd required BEGIN #include <Python.h>//<stdio.h>, <string.h>, <errno.h>, <stdlib.h> //# pyd required END //c++module #include <iostream>//std::cin/cout #include <windows.h> #include <tlhelp32.h>//module32 funcs #include <tchar.h>//unicode set //#include <stdio.h>
PS. I'm using unicode charset in my vs2010 project, so, if you want to use NoSet char you must remember to change the actual argument "u" to "s" of the Py_BuildValue function!Code:// _mydaemon.cpp #include "_mydaemon.h" static PyObject* MyDaemonError; /*START CODE*/ static PyObject* MyDaemon_DllView2(PyObject *self, PyObject *args) { DWORD dwPID; if(!PyArg_ParseTuple(args, "i", &dwPID)) return NULL; HANDLE hModuleSnap = INVALID_HANDLE_VALUE; MODULEENTRY32 me32; // Take a snapshot of all modules in the specified process. hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID); if(hModuleSnap == INVALID_HANDLE_VALUE) { return Py_BuildValue("i", 0); // CreateToolhelp32Snapshot (of modules) } // Set the size of the structure before using it. me32.dwSize = sizeof(MODULEENTRY32); // Retrieve information about the first module, // and exit if unsuccessful if(!Module32First(hModuleSnap, &me32)) { CloseHandle(hModuleSnap); return Py_BuildValue("i", 0);//Module32First } // Now walk the module list of the process, // and display information about each module int tuplemain_index = 0; do{tuplemain_index++;}while(Module32Next(hModuleSnap, &me32)); PyObject *DllTupleMain = PyTuple_New(tuplemain_index); PyObject *DllTupleChild; Module32First(hModuleSnap, &me32); tuplemain_index = 0; do { DllTupleChild = Py_BuildValue("(uuii)", me32.szModule, me32.szExePath, (DWORD) me32.modBaseAddr, me32.modBaseSize); PyTuple_SetItem(DllTupleMain, tuplemain_index, DllTupleChild); tuplemain_index++; }while(Module32Next(hModuleSnap, &me32)); CloseHandle(hModuleSnap); return DllTupleMain; } static PyObject* MyDaemon_System(PyObject *self, PyObject *args) { //ps. os.popen is better char* command; int sts; if(!PyArg_ParseTuple(args, "s", &command)) return NULL; sts = system(command); return Py_BuildValue("i", sts); } static PyObject* MyDaemon_LoadLib(PyObject *self, PyObject *args) { char* libname; if(!PyArg_ParseTuple(args, "s", &libname)) return NULL; //std::cout << libname << std::endl; HINSTANCE myH = LoadLibraryA(libname); return Py_BuildValue("i", myH != NULL); } static PyObject* MyDaemon_TaskList(PyObject *self, PyObject *args) { HANDLE hProcessSnap; HANDLE hProcess; PROCESSENTRY32 pe32; DWORD dwPriorityClass; hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if(hProcessSnap == INVALID_HANDLE_VALUE) { return Py_BuildValue("i", 0); // CreateToolhelp32Snapshot (of processes) } // Set the size of the structure before using it. pe32.dwSize = sizeof(PROCESSENTRY32); // Retrieve information about the first process, // and exit if unsuccessful if(!Process32First(hProcessSnap, &pe32)) { CloseHandle(hProcessSnap);// clean the snapshot object return Py_BuildValue("i", 0); // Process32First } int tuplemain_index = 0; do{tuplemain_index++;}while(Process32Next(hProcessSnap, &pe32)); PyObject *DllTupleMain = PyTuple_New(tuplemain_index); PyObject *DllTupleChild; Process32First(hProcessSnap, &pe32); tuplemain_index = 0; do { dwPriorityClass = 0; // Retrieve the priority class. hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID); //if(hProcess == NULL){} //else if(hProcess != NULL) { dwPriorityClass = GetPriorityClass(hProcess); CloseHandle(hProcess); } DllTupleChild = Py_BuildValue("(uiiiii)", pe32.szExeFile, pe32.th32ProcessID, pe32.cntThreads, pe32.th32ParentProcessID, pe32.pcPriClassBase, dwPriorityClass); PyTuple_SetItem(DllTupleMain, tuplemain_index, DllTupleChild); tuplemain_index++; } while(Process32Next(hProcessSnap, &pe32)); CloseHandle(hProcessSnap); return DllTupleMain; } /*METHODS_LIST*/ static PyMethodDef MyDaemonMethods[] = { {"dllview2", MyDaemon_DllView2, METH_VARARGS, "DllView in tuple return."}, {"loadlib", MyDaemon_LoadLib, METH_VARARGS, "Load a dll in memory."}, {"system", MyDaemon_System, METH_VARARGS, "Execute a shell command."}, {"tasklist", MyDaemon_TaskList, METH_VARARGS, "Show all active pc-process."}, {NULL, NULL, 0, NULL} }; /*INIT*/ DL_EXPORT(void) init_mydaemon(void) { PyObject *m, *d; m = Py_InitModule("_mydaemon", MyDaemonMethods); MyDaemonError = PyErr_NewException("_mydaemon.error", NULL, NULL); d = PyModule_GetDict(m); PyDict_SetItemString(d, "error", MyDaemonError); }
Now, you have to add this inside the (Project) Properties -> Configuration Properties -> Linker -> Command Line -> Additional Options:
Code:/export:init_mydaemon
Don't forget to add the python22 include path here:
(Project) Properties -> Configuration Properties -> C/C++ -> General -> Additional Include Directories
(you must install python22 on your os or, just download the python2.2.3 sources and compile them with vc++6 for the relative .lib files to include)
Now, build the project and you'll get the pyd!
Rename your .dll to .pyd and move it into the client\lib path (info
)To use this "new module" in python you just need to write something like this:
Code:
import _mydaemon
#you can also do this:
import _mydaemon as myd
#show me my module namespaces!
##print dir(myd)
#now it's time to test my defs!
_mydaemon.loadlib("mylib.dll")#load this library in memory
#
import os
dllloadedinmyclientbin=_mydaemon.dllview(os.get_pid())#tuple return
##for dllsnap in dllloadedinmyclientbin:
## print ", ".join([str(i) for i in dllsnap])
#
tasklist=_mydaemon.tasklist()
#
_mydaemon.system(r"echo this >> %userprofile%\desktop\this.txt")
- _mydaemon.dllview2(pid) // it returns a tuple of all the dll injected into the pid process
- _mydaemon.loadlib(libname) // it loads libname in memory
- _mydaemon.tasklist() // it returns a tuple containing all the active processes on your computer
- _mydaemon.system(cmd) // it invokes the shell to execute cmd
Other
- I used this example to make dllview&tasklist defs:

- You can read the relative python documentation
(this looks even better:
) - You should remember that this is only an example code, if you want to load a library or to show dlls/processes in another way it's your choice







