一、前言

前期我们已经对python的运行原理以及运行过程中产生的文件结构有了了解。本节,我们将结合具体的例子来实践python运行,编译,反编译的过程,并对前些章节中可能遗漏的具体细节进行补充。

二、Python编译

python在正常运行时,有时编译生成pyc文件,有时候没有pyc文件的生成。那么我们能不能手动将python程序编译成pyc文件呢?答案是可以的,不但可以编译,还可以直接运行pyc文件以实现程序运行的效率。

2.1、pyc文件的生成

命令行模式

python -m py_compile file.py  # 生成单个pyc文件
python -m py_compile /dir/{file1,file2}.py # 生成多个pyc文件
python -m compileall /dir/ # 生成目录下所有py文件对应的pyc文件

交互shell模式

>>> import py_compile  # 相当于命令行中的“-m py_compile”
>>> py_compile.compile('py file path')
>>> import compileall
>>> compileall.compile_dir("py files dir")

2.2、pyo文件生成

pyo文件是源代码文件经过优化编译后生成的文件,是pyc文件的优化版本。编译时需要使用-O和-OO选项来生成pyo文件。在Python3.5之后,不再使用.pyo文件名,而是生成文件名类似“test.opt-n.pyc的文件。

python -O -m py_compile file.py
python -O -m py_compile /dir/{file1,file2}.py
python -O -m compileall /dir/

2.3、直接运行编译好的pyc或者pyo文件

三、字节码文件反编译

经过编译的python文件可以提高程序的运行速度,一定程度上也对源代码起到了保护作用。然而如果我们只有编译过的python字节码文件,就给我们审查源码造成了一定的困难,这就引出了python字节码反编译的需求。

上一节我们介绍过pyc文件的结构,其实就是pyc文件头部加上PyCodeObject对象。文件头部的信息在python2中只占用固定8字节,用来携带一些版本类的信息,不是我们做反编译的重点,因此通过提取8字节之后的部门做反编译处理就可以了。

PyCodeObjectData就是我们需要提取的数据,根据python的编译原理我们知道PyCodeObjectData是python源文件作为一个实例化的类,通过python内置库函数marshal.dumps生成的二进制数据段,因此通过marshal.loads(PyCodeObjectData) ,我们可以得到PyCodeObjectData反序列化的对象。

可以看到PyObj对象包含了很多内置方法和属性,这些属性在第二节中我们已经有过介绍,各个字段的含义都已经知道了。通过对这些方法的引用可以直接看到相关字段反序列后的具体值。

使用python内置模块dis可以对PyCodeObject进行反编译,从而获取到python二进制字节码代码段的“汇编形式”。这样可以便于对字节码进行阅读。dis模块也可以单独对PyCodeObject中的co_data模块进行反编译,但是这样得到的是单纯的代码段字节码,缺少很多代码段中涉及的变量名字。如上图所示。

四、结语

本节我们对python源码编译生成字节码文件和从字节码文件反编译生成字节码代码段(python的汇编形式)进行介绍。下一章节我们将对dis模块的源码进行解读,以便于后续章节关于python代码混淆技术的涉及。

Python逆向(三)—— Python编译运行及反汇编的更多相关文章

  1. Python逆向(一)—— 前言及Python运行原理

    一.前言 最近在学习Python逆向相关,涉及到python字节码的阅读,编译及反汇编一些问题.经过长时间的学习有了一些眉目,为了方便大家交流,特地将学习过程整理,形成了这篇专题.专题对python逆 ...

  2. 使用Notepad++编译运行C/C++/Python程序

    对我来说,比较常用的是C/C++/Python. 使用Notepad++编译运行单个源文件的C/C++/Python,比使用复杂的IDE更加快捷. 想要让Notepad++能够做到编译运行C/C++/ ...

  3. EditPlus配置[C++] [Python] [Java] 编译运行环境

    以前一直用Codeblocks写C++,eclipse写Java,再在eclipse里面集成PyDev写Python,首先无法忍受代码自动补全功能(这个功能也许你万分喜欢),也无法忍受如此重量级的ID ...

  4. 使用NppExec插件让Notepad++编译运行Java、Python

    一直希望有一个轻量级的编辑器,既可以编辑代码,也可以一键运行.后来有了NotePad++,希望可以配置配置达到目的,配Java的时候上网搜了一堆,基本上互相抄,不解决实际问题,很郁闷.后来琢磨了出来, ...

  5. Python是编译运行的

    虽然Python被说成是一种解释型语言,但是实际上,Python源程序要先经过编译,然后才能运行. 与Java语言类似,Python源程序编译之后得到的是字节码,交由Python虚拟机来运行. 关于这 ...

  6. 02 sublime text3下配置Python的编译运行环境

    内容参考如下文章,加入了自己的干货: https://www.cnblogs.com/huluwahaha/p/7503930.html 在sublime中如何配置Python的编译环境呢? 打开Su ...

  7. mac学习Python第一天:安装、软件说明、运行python的三种方法

    一.Python安装 从Python官网下载Python 3.x的安装程序,下载后双击运行并安装即可: Python有两个版本,一个是2.x版,一个是3.x版,这两个版本是不兼容的. MAC 系统一般 ...

  8. ubuntu下c/c++/python/go编译运行

    C语言: .c文件 编译器gcc//my_code下hello.c文件 $sudo apt install gcc $gcc hello.c -o hello $./hello C++: .cpp文件 ...

  9. Python逆向(五)—— Python字节码解读

    一.前言 前些章节我们对python编译.反汇编的原理及相关模块已经做了解读.读者应该初步掌握了通过反汇编获取python程序可读字节码的能力.python逆向或者反汇编的目的就是在没有源码的基础上, ...

随机推荐

  1. bsd pkg install gcc gmake cmake gdb cgdb

    bsd pkg install gcc gmake cmake gdb cgdb 安装pkg帮助文档并查看文档# pkg help install# man pkg-install # pkg sea ...

  2. BUAAOO-Third-Summary

    目录 从DBC到JML SMT solver 使用 JML toolchain的可视化输出 和我的测试结果 规格的完善策略 架构设计 debug情况 心得体会 一.从DBC到JML 契约式设计(Des ...

  3. python 数据类型 常用法方

    python 数据类型 常用法方 upper() 大写 str lower() 小写 str strip() rstrip() lstrip() 去除字符两边的空格 去右边 左边空白 str repl ...

  4. 各种GAN的学习和总结

    GAN: https://www.cnblogs.com/kk17/p/10046884.html WGAN: https://www.cnblogs.com/Allen-rg/p/10305125. ...

  5. influxdb系列:一、influxdb概念

    根据influxdb的官方文档介绍,它是一个时间序列数据库,但是仅仅从名字却不知道它跟已有的关系型数据库有什么区别? 当学习一个新的东西的时候,我的习惯往往是想知道它和我已掌握的知识的对比关系,这样子 ...

  6. leetcode-45.跳跃游戏II(hard)

    给定一个非负整数数组,你最初位于数组的第一个位置. 数组中的每个元素代表你在该位置可以跳跃的最大长度. 你的目标是使用最少的跳跃次数到达数组的最后一个位置. 示例: 输入: [2,3,1,1,4]输出 ...

  7. python之编码与解码、is 与==的区别

    一.编码与解码 编码的过程其实就是采用一定的编码格式将unicode字符转换成str字符的过程 非ASCII码字符按字节为单位被编码成十六进制转义字符 解码采用的编码格式跟设置和环境有关 ascii ...

  8. 虚拟机搭建IKUAI软路由

    1.登录爱快软路由的官网下载镜像(支持ISO ,GHO),这里采用iso安装 2.选择好后开机(选择数字编号1,回车) 3.输入“y”回车,程序自动安装 4.安装成功后如图 5.设置IP 6.绑定网卡 ...

  9. Kubernetes-Istio之Gateway和VirtualService

    1: 确定入口IP和端口 执行以下命令以确定Kubernetes集群是否在支持外部负载均衡器的环境中运行: kubectl get svc istio-ingressgateway -n istio- ...

  10. cal of easter egg

    在Linux中用cal命令查看1752年9月,发现3到13日全都消失了……