pyinstaller/bootloader/src/pyi_archive.h
/* Types of CArchive items. */
#define ARCHIVE_ITEM_BINARY 'b' /* binary */
#define ARCHIVE_ITEM_DEPENDENCY 'd' /* runtime option */
#define ARCHIVE_ITEM_PYZ 'z' /* zlib (pyz) - frozen Python code */
#define ARCHIVE_ITEM_ZIPFILE 'Z' /* zlib (pyz) - frozen Python code */
#define ARCHIVE_ITEM_PYPACKAGE 'M' /* Python package (__init__.py) */
#define ARCHIVE_ITEM_PYMODULE 'm' /* Python module */
#define ARCHIVE_ITEM_PYSOURCE 's' /* Python script (v3) */
#define ARCHIVE_ITEM_DATA 'x' /* data */
#define ARCHIVE_ITEM_RUNTIME_OPTION 'o' /* runtime option */
pyinstaller/bootloader/src/pyi_pythonlib.c
/*
* Import modules embedded in the archive - return 0 on success
*/
int
pyi_pylib_import_modules(ARCHIVE_STATUS *status)
{
PyObject *marshal;
PyObject *marshaldict;
PyObject *loadfunc;
TOC *ptoc;
PyObject *co;
PyObject *mod;
PyObject *meipass_obj;
VS("LOADER: setting sys._MEIPASS\n");
/* TODO extract function pyi_char_to_pyobject */
#ifdef _WIN32
meipass_obj = PI_PyUnicode_Decode(status->mainpath,
strlen(status->mainpath),
"utf-8",
"strict");
#else
meipass_obj = PI_PyUnicode_DecodeFSDefault(status->mainpath);
#endif
if (!meipass_obj) {
FATALERROR("Failed to get _MEIPASS as PyObject.\n");
return -1;
}
PI_PySys_SetObject("_MEIPASS", meipass_obj);
VS("LOADER: importing modules from CArchive\n");
/* Get the Python function marshall.load
* Here we collect some reference to PyObject that we don't dereference
* Doesn't matter because the objects won't be going away anyway.
*/
marshal = PI_PyImport_ImportModule("marshal");
marshaldict = PI_PyModule_GetDict(marshal);
loadfunc = PI_PyDict_GetItemString(marshaldict, "loads");
/* Iterate through toc looking for module entries (type 'm')
* this is normally just bootstrap stuff (archive and iu)
*/
ptoc = status->tocbuff;
while (ptoc < status->tocend) {
if (ptoc->typcd == ARCHIVE_ITEM_PYMODULE ||
ptoc->typcd == ARCHIVE_ITEM_PYPACKAGE) {
unsigned char *modbuf = pyi_arch_extract(status, ptoc);
VS("LOADER: extracted %s\n", ptoc->name);
/* .pyc/.pyo files have 8 bytes header. Skip it and load marshalled
* data form the right point.
*/
if (pyvers >= 37) {
/* Python >= 3.7 the header: size was changed to 16 bytes. */
co = PI_PyObject_CallFunction(loadfunc, "y#", modbuf + 16,
ntohl(ptoc->ulen) - 16);
}
else {
/* It looks like from python 3.3 the header */
/* size was changed to 12 bytes. */
co =
PI_PyObject_CallFunction(loadfunc, "y#", modbuf + 12, ntohl(
ptoc->ulen) - 12);
};
if (co != NULL) {
VS("LOADER: callfunction returned...\n");
mod = PI_PyImport_ExecCodeModule(ptoc->name, co);
}
else {
/* TODO callfunctions might return NULL - find yout why and foor what modules. */
VS("LOADER: callfunction returned NULL");
mod = NULL;
}
/* Check for errors in loading */
if (mod == NULL) {
FATALERROR("mod is NULL - %s", ptoc->name);
}
if (PI_PyErr_Occurred()) {
PI_PyErr_Print();
PI_PyErr_Clear();
}
free(modbuf);
}
ptoc = pyi_arch_increment_toc_ptr(status, ptoc);
}
return 0;
}
pyinstaller/PyInstaller/building/build_main.py
if cipher:
logger.info('Will encrypt Python bytecode with key: %s', cipher.key)
# Create a Python module which contains the decryption key which will
# be used at runtime by pyi_crypto.PyiBlockCipher.
pyi_crypto_key_path = os.path.join(CONF['workpath'], 'pyimod00_crypto_key.py')
with open_file(pyi_crypto_key_path, 'w', encoding='utf-8') as f:
f.write('# -*- coding: utf-8 -*-\n'
'key = %r\n' % cipher.key)
logger.info('Adding dependencies on pyi_crypto.py module')
self.hiddenimports.append(pyz_crypto.get_crypto_hiddenimports())