关注论坛五六年,这是第一次(发帖)!大佬轻喷...
原由:
最近接触一个国外某app的协议软件,是python3.8写的,它把关键模块都编译成了pyd,然后使用pyinstaller打包发布给用户。软件启动后检查机器码,然后需要输入授权码才可使用,看着很是恼火,所以想尝试破解。其中关键应该是需要爆破pyd里的逻辑,修改汇编代码来实现绕过授权。
前提知识:
最近接触一个国外某app的协议软件,是python3.8写的,它把关键模块都编译成了pyd,然后使用pyinstaller打包发布给用户。软件启动后检查机器码,然后需要输入授权码才可使用,看着很是恼火,所以想尝试破解。其中关键应该是需要爆破pyd里的逻辑,修改汇编代码来实现绕过授权。
1.py、pyc、pyo、pyd
py: python 脚本文件(source code)
pyc: 脚本文件编译得到的字节码, 二进制文件,python文件经过编译器编译之后的文件。可以提高文件加载速度
pyo: 脚本文件开启优化编译选项(-O)编译得到的字节码,二进制文件,优化编译后的文件。可以通过python -O file.py生成。
pyd: 基本的Windows DLL文件, python的动态链接库。
2.编译pyd
py: python 脚本文件(source code)
pyc: 脚本文件编译得到的字节码, 二进制文件,python文件经过编译器编译之后的文件。可以提高文件加载速度
pyo: 脚本文件开启优化编译选项(-O)编译得到的字节码,二进制文件,优化编译后的文件。可以通过python -O file.py生成。
pyd: 基本的Windows DLL文件, python的动态链接库。
2.编译pyd
要编译的脚本:uitl1.py
def fun_hello(s):
if s == 1:
return 'hello world'
elif s == 2:
return '222222222'
提供编译脚本:setup.py
def fun_hello(s):
if s == 1:
return 'hello world'
elif s == 2:
return '222222222'
提供编译脚本:setup.py
from setuptools import setup
from Cython.Build import cythonize
setup(
name='test',
ext_modules=cythonize('util1.py')
)
在setup.py文件所在目录下进行如下命令
from setuptools import setup
from Cython.Build import cythonize
setup(
name='test',
ext_modules=cythonize('util1.py')
)
在setup.py文件所在目录下进行如下命令
python setup.py build_ext --inplace
这样就能看到同级目录下生成pyd文件了。32位的python生成pyd文件是32位的,64位的python生成的是64位的。
python setup.py build_ext --inplace
这样就能看到同级目录下生成pyd文件了。32位的python生成pyd文件是32位的,64位的python生成的是64位的。
3.使用pyd
test.py
import util1
if __name__ == '__main__':
print(util1.fun_hello(2))
4.pyinstaller打包py到exe
import util1
if __name__ == '__main__':
print(util1.fun_hello(2))
4.pyinstaller打包py到exe
pip install pyinstaller
pyinstaller test.py
5.解包pyinstaller打包的exe
pyinstxtractor.py即可。这个代码不长,可以调试看看,熟悉下打包的exe组成。需要注意的是,被打包的文件都是zlib.compress压缩过后,再按照固定格式组成exe的,所以直接修改打包后的exe的16进制码来爆破貌似不好操作。只能解包后修改pyd,然后找齐依赖的库,重新pyinstaller打包,实现爆破。
6.pyc反编译
uncompyle6支持python3.8的pyc的反编译
需要注意的是,如果是pyinstaller解包后取到的pyc文件,文件头部的magic被抹除过了,所以需要把对应版本python的magic加上来,可以装对应版本python,然后到安装目录下随便找个pyc文件,看一下头部,然后用010Editor复制到解包后的pyc,就可以正常反编译了。
下图是python3.8_32位的magic头
前面的前提知识,随便搜搜都能找到。但是如何才能直接修改pyd的汇编代码,实现python脚本流程的更改呢?
我百度谷歌搜了半天也没找到合适的资料,也许很少有人破解python编译打包的exe吧。
那么下面就是我做的工作了,也是本帖的价值所在了。
我自己写了一个python小脚本,然后编译成了pyd,它会生成一个中间的util1.c文件,代码大概有3000多行。只要花时间精力熟悉这个c文件,然后对照着ida就可以了解python脚本转成C然后编译成汇编指令,它们3者之间大概对应关系了。下面略过大概1天的工作量,直接给出我们拿到一个pyd后,怎么快速找到我们要找的关键python代码。然后直接爆破。
把要分析的pyd文件拖到对应32位或64位的IDA
大概所有的pyd都只有这个一个导出函数,当这个pyd模块被其他py脚本import时会调用这个导出函数进行模块初始化
跳转到dword_1000634C可以看到一个结构体,里面有一个关键的成员__pyx_moduledef_slots
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2020-4-25 09:23
被rushmaster编辑
,原因: