initial commit

This commit is contained in:
2025-04-15 10:35:34 +08:00
commit 9e3709a30f
13 changed files with 530 additions and 0 deletions

View File

@@ -0,0 +1,133 @@
#define PY_SSIZE_T_CLEAN
#define Py_CPYTHON_FRAMEOBJECT_H
#include "Python.h"
#include "marshal.h"
// #include "internal/pycore_frame.h"
#include "cpython/frameobject.h"
#define ARGTYPE 1
#include "libtomcrypt/headers/tomcrypt.h"
static const int MAJOR_VERSION = PY_MAJOR_VERSION;
static const int MINOR_VERSION = PY_MINOR_VERSION;
const unsigned char *aes_key = "WAIT_TO_BE_FILLED";
// PyObject *CodeObject;
PyObject* PyHumorRuntime_HumorEnter(PyObject* self, PyObject* args) {
PyFrameObject *frame = PyEval_GetFrame();
PyCodeObject *f_code = frame->f_code;
// PyCodeObject *f_code = PyFrame_GetCode(PyEval_GetFrame());
PyObject *codearray = f_code->co_code;
Py_ssize_t size;
unsigned char *data;
PyBytes_AsStringAndSize(codearray, &data, &size);
if (data == NULL) {
return NULL;
}
if (size < 8 || size > 8192) {
return NULL;
}
int use_size = (size - 8) - (size - 8) % 16;
symmetric_key skey;
int err;
if ((err = aes_setup(aes_key + 1, 16, 0, &skey)) != CRYPT_OK) {
return NULL;
}
for (int i = 0; i < use_size; i += 16) {
if ((err = aes_ecb_decrypt(data + i + 8, data + i + 8, &skey)) != CRYPT_OK) {
return NULL;
}
}
aes_done(&skey);
return Py_None;
}
PyObject* PyHumorRuntime_RunCode(PyObject* self, PyObject* args) {
PyObject* name;
PyObject* file;
char* bytecode;
Py_ssize_t bytecodeSize;
if (!PyArg_ParseTuple(args, "OOy#", &name, &file, &bytecode, &bytecodeSize)) {
return NULL;
}
// Parse the code meta
if (bytecodeSize < 16) {
return NULL;
}
if (bytecode[9] != MAJOR_VERSION || bytecode[10] != MINOR_VERSION) {
return NULL;
}
if (*(int*)(bytecode + 12) != bytecodeSize - 16) {
return NULL;
}
// Decrypt the bytecode
symmetric_key skey;
unsigned char *plaintext = malloc(bytecodeSize - 16);
int err;
if ((err = aes_setup(aes_key, 16, 0, &skey)) != CRYPT_OK) {
return NULL;
}
for (int i = 0; i * 16 < bytecodeSize - 16; i++) {
if ((err = aes_ecb_decrypt(bytecode + 16 + i * 16, plaintext + i * 16, &skey)) != CRYPT_OK) {
return NULL;
}
}
aes_done(&skey);
// Load the code object
PyObject *codeObject = PyMarshal_ReadObjectFromString(plaintext, bytecodeSize - 16);
free(plaintext);
if (codeObject == NULL) {
return NULL;
}
// Add __humor_enter__ function to the globals
PyMethodDef humorEnterMethodDef =
{"__humor_enter__", PyHumorRuntime_HumorEnter, METH_VARARGS, NULL};
PyObject* humorEnterFunc = PyCFunction_New(&humorEnterMethodDef, NULL);
if (humorEnterFunc == NULL) {
return NULL;
}
PyObject* globals = PyEval_GetGlobals();
if (globals == NULL || PyDict_SetItemString(globals, "__humor_enter__", humorEnterFunc) < 0) {
Py_DECREF(humorEnterFunc);
return NULL;
}
Py_DECREF(humorEnterFunc); // Decrease reference count since it's now in the globals
// Run the code
PyObject* result = PyImport_ExecCodeModuleObject(name, codeObject, file, NULL);
Py_DECREF(codeObject);
// Remove __humor_enter__ function from the globals
PyDict_DelItemString(globals, "__humor_enter__");
return result;
}
static PyMethodDef PyHumorRuntime_Methods[] = {
{"__pyhumor__", PyHumorRuntime_RunCode, METH_VARARGS, NULL},
{NULL, NULL, 0, NULL}
};
static struct PyModuleDef PyHumorRuntime_Module = {
PyModuleDef_HEAD_INIT,
"pyhumor_runtime",
NULL,
-1,
PyHumorRuntime_Methods
};
PyMODINIT_FUNC PyInit_pyhumor_runtime(void) {
return PyModule_Create(&PyHumorRuntime_Module);
}

View File

@@ -0,0 +1,20 @@
from distutils.core import setup, Extension
module1 = Extension('pyhumor_runtime',
sources=[
'pyhumor_runtime.c',
'libtomcrypt/ciphers/aes/aes.c',
'libtomcrypt/ciphers/aes/aes_desc.c',
'libtomcrypt/ciphers/aes/aes_tab.c',
# 'libtomcrypt/misc/crypt/crypt_argchk.c',
'libtomcrypt/misc/zeromem.c',
'libtomcrypt/misc/compare_testvector.c',
],
include_dirs=['libtomcrypt/headers'],
define_macros=[('ARGTYPE', '1')],
)
setup (name = 'pyhumor_runtime',
version = '1.0',
description = '',
ext_modules = [module1])