脚本、模块的执行与解密执行 Python 代码的几种方式为了找到 Python 解释器执行 Python 代码时的所有入口 , 我们需要首先执行 Python 解释器都能以怎样的方式执行代码 。
直接运行脚本
python test.py
直接运行语句python -c "print 'hello'"
直接运行模块python -m test
导入、重载模块python>>> import test# 导入模块>>> reload(test)# 重载模块
直接运行语句的方式接收的就是明文的代码 , 我们也无需对这种方式做额外处理 。直接运行模块和 导入、重载模块 这两种方式在流程上是殊途同归的 , 所以接下来会一起来看 。
因此我们将分两种情况:运行脚本和加载模块来进一步探究各自的过程和解密方式 。
运行脚本时解密运行脚本的过程
Python 解释器在运行脚本时的代码调用逻辑如下:
mainWinMain[Modules/python.c] [PC/WinMain.c]/////Py_Main[Moduls/main.c]
Python 解释器运行脚本的入口函数因操作系统而异 , 在 linux/Unix 系统上 , 主入口函数是 Modules/python.c 中的 main 函数 , 在 Windows系统上 , 则是 PC/WinMain.c 中的 WinMain 函数 。不过这两个函数最终都会调用 Moduls/main.c 中的 Py_Main 函数 。我们不妨来看看 Py_Main 函数中的相关逻辑:
[Modules/Main.c]--------------------------------------intPy_Main(int argc, char **argv){if (command) {// 处理 python -c <command>} else if (module) {// 处理 python -m <module>}else {// 处理 python <file>...fp = fopen(filename, "r");...}}
处理 <command> 和 <module> 的部分我们暂且先不管 , 在处理文件(通过直接运行脚本的方式)的逻辑中 , 可以看到解释打开了文件 , 获得了文件指针 。那么如果我们把这里的 fopen 换成是自定义的 decrypt_open 函数 , 这个函数用来打开一个加密文件 , 然后进行解密 , 并返回一个文件指针 , 这个指针指向解密后的文件 。那么 , 不就可以实现解密脚本的目的了吗?自定义 decrypt_open
我们不妨新增一个 Modules/crypt.c 文件 , 用来存放一些自定义的加解密函数 。
decrypt_open 函数大概实现如下:
[Modules/crypt.c]--------------------------------------/* 以解密方式打开文件 */FILE *decrypt_open(const char *filename, const char *mode){int plainlen = -1;char *plaintext = NULL;FILE *fp = NULL;if (aes_passwd == NULL)fp = fopen(filename, "r");else {plainlen = aes_decrypt(filename, aes_passwd, &plaintext);// 如果无法解密 , 返回源文件描述符if (plainlen < 0)fp = fopen(filename, "r");// 否则 , 转换为内存文件描述符elsefp = fmemopen(plaintext, plainlen, "r");}return fp;}
这里的 aes_passwd 是一个全局变量 , 代表对称加密算法中的密钥 。我们暂时假定已经获取该密钥了 , 后文会说明如何获得 。而 aes_decrypt 是自定义的一个使用AES算法进行对称解密的函数 , 限于篇幅 , 此函数的实现不再贴出 。decrypt_open 逻辑如下:
- 判断是否获得了对称密钥 , 如果没获得 , 直接打开该文件并返回文件指针
- 如果获得了 , 则尝试使用对称算法进行解密如果解密失败 , 可能就是一段非加密的脚本 , 直接打开该文件并返回文件指针如果解密成功 , 我们通过解密后的内容创建一个内存文件对象 , 并返回该文件指针
加载模块时解密加载模块的过程
加载模块的逻辑主要实现在 Python/import.c 文件中 , 其过程如下:
Py_Main[Moduls/main.c]|builtin___import__RunModule||PyImport_ImportModuleLevel <----┐PyImport_ImportModule|||import_module_level└------- PyImport_Import|load_nextbuiltin_reload||import_submodulePyImport_ReloadModule||find_module <---------------------------┘
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Elasticsearch中数据是如何存储的?
- Windows 7用户必看 如何升级至Windows 10
- HTTP是如何使用TCP连接
- 如何将 Python 的一个类方法变为多个方法?
- 如何在Mac下生成ssh密钥?
- 这一次,让你完全理解 HTTPS 到底是如何做到数据传输安全的
- 程序员告诉你微信营销号如何防封、解封
- 黑客是如何控制你手机的?出现这几种情况,你的手机可能已中招
- 一文教会你如何申请ios开发者账号
- 更年期的女性 练太极对你的好处到底有多大