pyc文件(字节码)
如何生成pyc文件
https://www.cnblogs.com/zhangqunshi/p/6657208.html
https://blog.csdn.net/weixin_30614587/article/details/97230135
方1 命令行
python -m example.py
方2
import py_compile
py_compile.compile('example.py')
方3 将目录下的py文件都转为pyc文件
import compileall
compileall.compile_dir(r'/path')
方4 命令行 将目录下的py文件都转为pyc文件
python -m compileall <dir>
但发现直接运行代码后有一个__pycache__文件夹中会pyc文件,这和这几种方法的结果是一样的.
pyo文件 是 pyc文件的简化版
python -o -m example.py
python -oo -m example.py
-O参数表明要生成更加紧凑的优化后的字节码, 这样生成的字节码文件后缀名为.pyo文件。
-OO会进一步移除-O选项生成的优化后的字节码文件中的文档字符串,生成的文件后缀名仍然为.pyo文件。
如何运行pyc文件
https://www.pynote.net/archives/2342
方法
python example.cpython-39.pyc
如何再转为py文件
https://blog.csdn.net/duohuanxi/article/details/114799153
https://pypi.org/project/uncompyle6/
uncompyle6 -o example.py example.pyc
Error: uncompyle6 requires Python 2.6-3.8
我的是python3.9就无法演示了
字节码与机器码
https://blog.csdn.net/qq_35810838/article/details/99294636
字节码与机器码都是二进制文件即01组成的,但用notepad打开会发现是字母,这是notepad的问题.
python运行原理
源代码py文件
→
\rightarrow
→字节码pyc文件
→
\rightarrow
→结果, pyc文件通过解释器得到结果 python并不是每次都需要转换字节码,解释器在转换之前会判断代码文件的修改时间是否与上一次转换后的字节码pyc文件的修改时间一致,若不一致才会重新转换。即运行一遍后生成pyc文件,以后每次运行,进行的只是将pyc输入解释器得出结果
python将源代码翻译为字节码,字节码通过解释器获得结果,并不会生成机器码,但c语言会生成机器码即exe文件
从exe获取代码
https://reverseengineering.stackexchange.com/questions/160/how-do-you-reverse-engineer-an-exe-compiled-with-pyinstaller
PE文件的全称是Portable Executable,意为可移植的可执行的文件,常见的EXE、DLL、OCX、SYS、COM都是PE文件,PE文件是微软Windows操作系统上的程序文件(可能是间接被执行,如DLL)
非托管代码反编译后是汇编语言, 托管代码反编译是高级语言 非托管代码就是根据不同的系统,不同的cpu进行编程,用来适配cup和操作系统 托管代码,比如C# 通过编译器生成中间语言,但是中建语言仍然需要编译成本地cup能执行的机器代码,这部分功能由一个运行在特定软件系统来完成。这个软件系统被称之为虚拟机。只需要为每种操作系统和cpu架构提供一个虚拟机。就可以让一个应用程序不加修改的跑在不同操作系统上,拥有不同cpu架构的计算机上。运行在这种虚拟机上的代码成为托管代码
https://blog.csdn.net/m0_37552052/article/details/88093427
https://blog.csdn.net/tymatlab/article/details/80511709
https://blog.csdn.net/ZH013/article/details/105116715
https://pypi.org/project/pydecipher/
方1
通过 pydecipher 将 exe 转为 pyc
通过 uncompyle6 将 pyc 转为 py
方2
通过pyinstxtractor 将 exe 转为 pyc
通过 uncompyle6 将 pyc 转为 py
pip install pydecipher报错 error: command 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.28.29910\\bin\\HostX86\\x64\\cl.exe' failed with exit status 2
pydecipher有一句话:可以在mac与linux的python3.8上运行,但windows不清楚,理论应该可以。
实例(方2) 写一个test.py文件 下载pyinstxtractor.py https://codechina.csdn.net/mirrors/extremecoders-re/pyinstxtractor?utm_source=csdn_github_accelerator
打包py转为exe pyinstaller test.py 在生成的dist文件下的test文件夹下会有test.exe
exe转为pyc, 将生成的exe拿出来与pyinstxtractor.py放在同一级文件下 python pyinstxtractor.py test.exe 在生成的test.exe_extracted文件夹下会有test.pyc
pyc转为py,跳转到test.exe_extracted文件夹中 uncompyle6 -o test.py test.pyc
如何避免被反编译
http://dt.digitser.cn/zh-CN/applet/cython_file/index.html
https://www.jianshu.com/p/4a0be62ee3e2
https://blog.csdn.net/qq_39498924/article/details/101292339
https://www.zhihu.com/question/347425323/answer/834691490
http://yshblog.com/blog/117
混淆代码、加密代码(安装cython将py文件转为pyd文件) 但貌似pyd也就是一种dll,也可以被反编译。
pyd文件是dll文件吗?
https://docs.python.org/3/faq/windows.html#id6
Yes, .pyd files are dll’s, but there are a few differences. If you have a DLL named foo.pyd, then it must have a function PyInit_foo(). You can then write Python “import foo”, and Python will search for foo.pyd (as well as foo.py, foo.pyc) and if it finds it, will attempt to call PyInit_foo() to initialize it. You do not link your .exe with foo.lib, as that would cause Windows to require the DLL to be present.
Note that the search path for foo.pyd is PYTHONPATH, not the same as the path that Windows uses to search for foo.dll. Also, foo.pyd need not be present to run your program, whereas if you linked your program with a dll, the dll is required. Of course, foo.pyd is required if you want to say import foo. In a DLL, linkage is declared in the source code with __declspec(dllexport). In a .pyd, linkage is defined in a list of available functions.
是的,但还是有些区别。
foo.pyd必须有函数PyInit_foo()。import foo 将foo.pyd导入时,python会寻找foo.pyd(也会寻找foo.pyc或foo.py,假设只有foo.pyd文件),找到后导入就要调用PyInit_foo()对其进行初始化。
不要将exe与foo.lib链接,否则windows会要求foo.dll存在。
foo.pyd的搜寻路径与foo.dll是不同的。
dll的链接在源代码中的__declspec(dllexport),pyd的链接在函数中。
cpython与cython
https://zhuanlan.zhihu.com/p/65512422
https://www.tutorialspoint.com/what-is-the-difference-between-cython-and-cpython
https://cython.org/
cpython是用c实现的python,jython是java实现的python,IronPython是.NET实现的python,这些都是解释器。
cython是一个静态编译器,是cpython的一个扩展,可以编译cpython解释器下的代码,而不能用于编译其他解释器下如jython的代码。
LLVM
https://www.infoworld.com/article/3247799/what-is-llvm-the-power-behind-swift-rust-clang-and-more.html
Mozilla Rust Apple Swift Jetbrains Kotlin
LLVM是Swift language creator Chris Lattner创建的一个开源项目,LLVM使得创建一门新语言以及提升现有语言很容易。 Swift使用LLVM作为其编译器框架;Rust使用LLVM作为其工具链的核心组件;Clang编译器及C/C++编译器都有LLVM版本;Mono是.Net的一个开源实现,可以选择用LLVM编译;Kotlin是一种JVM语言,现在正在开发一种Kotlin Native使用LLVM编译。
编译原理
东北大学 编译原理
高级语言、汇编语言、机器语言之间的转换: 高级语言1
→
\rightarrow
→高级语言2 高级语言
→
\rightarrow
→机器语言 高级语言
→
\rightarrow
→汇编语言 汇编语言
→
\rightarrow
→高级语言 汇编语言
→
\rightarrow
→机器语言 机器语言
→
\rightarrow
→汇编语言
编译程序:高级语言翻译成等价低级语言 源语言——编译程序——目标语言——运行程序——结果,编译一次后,每次只需要运行目标语言即可,如c语言编译为exe 编译程序:高级语言直接运行得到结果 源语言——解释程序——结果(python有逐行解释与整体解释之分)
源语言——词法分析——语法分析——语义分析——优化处理——目标代码生成——目标语言,中间的五个程序会不断的与错误处理程序和符号表管理程序交互。 源语言——词法分析——单词串TOKEN——语法分析——语法树——语义分析——语义树——优化处理——优化语义树——目标代码生成——目标语言,目标语言可以用汇编语言或机器语言。 以语义树为界,将整个过程分为两部分,源语言——前端——中间代码——后端——目标语言
int a,b;
b = a+2*5;
词法分析:识别原程序中的单词并分类
关键字:int
标识符:a,b
常数:2,5
界符:, ;= + *
语法分析:组词成句及语法错误检查
语义分析:分析语法成分的语义特征
符号表
名字 类型 种类 地址
a int 变量 pointer1
b int 变量 pointer2
地址:指向符号在数据区存储的位置
四元式或语义树来描述语义信息
优化:提高目标程序的质量,降低存储空间。常数合并
目标代码:
|