Skip to content

Instantly share code, notes, and snippets.

@tahadraidia
Last active September 14, 2021 08:18
Show Gist options
  • Save tahadraidia/9c57146c35f0ba0fced39b80883ab2d1 to your computer and use it in GitHub Desktop.
Save tahadraidia/9c57146c35f0ba0fced39b80883ab2d1 to your computer and use it in GitHub Desktop.
A Python module written in C that checks if a file is a valid PE using Windows API used to illustrate the idea on how to write a Python module in C because Hello words' are boring! Post: https://tahadraidia.com/lets-build-a-python-module-in-c.html
#include <Python.h>
#include <windows.h>
#pragma comment(lib,"kernel32.lib")
static PyObject* isValidPE(PyObject *self, PyObject* args)
{
LPSTR pfile = NULL;
if(!PyArg_ParseTuple(args, "s", &pfile))
{
return Py_None;
}
// Get file handler.
HANDLE hFile = CreateFileA(
pfile,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
// Error check.
if(hFile == INVALID_HANDLE_VALUE)
{
PyErr_SetString(PyExc_ValueError, "CreateFileA retuned INVALID_HANDLE_VALUE.");
return Py_None;
}
// Map the EXE file.
HANDLE hMapFile = CreateFileMapping(
hFile,
NULL,
PAGE_READONLY,
0,
0,
NULL
);
// Error check.
if(hMapFile == NULL)
{
PyErr_SetString(PyExc_ValueError, "CreateFileMapping retuned NULL.");
return Py_None;
}
// Get the base address.
LPVOID lpBase = MapViewOfFile(
hMapFile,
FILE_MAP_READ,
0, 0, 0);
// Error check.
if(lpBase == NULL)
{
PyErr_SetString(PyExc_ValueError, "MapViewOfFile retuned NULL.");
return Py_None;
}
PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)lpBase;
// Clean up.
UnmapViewOfFile(hMapFile);
CloseHandle(hMapFile);
CloseHandle(hFile);
// Either True or False.
return dosHeader->e_magic == IMAGE_DOS_SIGNATURE ? Py_True : Py_False;
}
static PyMethodDef pevalidator_module_methods[] = {
{"isValidPE", (PyCFunction)isValidPE, METH_VARARGS, "This method checks if a file is a valid PE."},
{NULL, NULL, 0, NULL}
};
static struct PyModuleDef pevalidator_module = {
PyModuleDef_HEAD_INIT,
"pevalidator",
"This module checks if a file is PE file.",
-1,
pevalidator_module_methods
};
PyMODINIT_FUNC PyInit_pevalidator(void)
{
return PyModule_Create(&pevalidator_module);
}
from distutils.core import setup, Extension
setup(name="pevalidator", version="1.0", ext_modules=[Extension('pevalidator',
['pevalidator.c'])])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment