python反编译exe_实战 Python3.7+64位 Exe 反编译

记得有年在上海弘连培训,其中一个逆向题就是关于python的Exe,当时就想着写个文档,后来因为忙就拖延了下来;这里补上,而且是大补上:奉献一个干货,网上没有(我没发现)Python3.7的反编译教程,有的都是python2.7的,两者有一个关键的地方不同(一层窗户纸),花费了一些时间才明白,无私地分享给你,这里是不是应该有掌声。

smiley_13.png

一、生成python3.7+64位Exe程序

在反之前要先编一个。用文本工具写个几行的python代码,如图:

198e12e76b3c1c91a36fc9c03b901c19699.png

安装Pyinstaller是一个坑,我忙乎了半天,费了几次劲才成功,真是要看运气。安装成功后,用pyinstaller -F filename打包编译成exe。

拖进exeinfo查看,果然是64位的;

0f7e81ac9d41432e65b40b73e7b134a314c.jpg

运行下,可以运行,说明编译成功。

a652ea38b1b282884e230a39f18b01ef1f7.png

在开工前,先准备好相关的知识,为后面的顺利进行打下基础。(后面文字有点长,耐心点)

二、Pyc、Pyd、Pyo、Pyz介绍

(一)在实际开发中,Python作为解释型语言,在实际的代码分发过程中,有比较多的格式定义:.pyc\.pyd\.pyo\.pyz。

①.pyc文件是什么?python编译后的二进制文件

Python源码编译的结果就是PyCodeObject(简称“代码对象”),每个作用域会编译出一个对应的代码对象,其中名为co_code的PyStringObject保存着代码对象的字节码。

一个Python源文件就是一个模块。每个模块顶层的代码对象通过marshal序列化之后就得到了.pyc文件。marshal以little-endian字节序来序列化数据。

那嵌套于顶层作用域里面的那些作用域,例如函数、类的定义,它们对应的代码对象在哪里?它们每一个都乖乖的躺在上一层作用域的代码对象的co_const(常量池)域里,所以其实顶层代码对象已经嵌套包含了底下其它作用域的代码对象。

PyCodeObject的结构和marshal的序列化逻辑和我们反编译这块没有太大的关系,不介绍了,否则又是洋洋洒洒一大篇。

当导入一个模块时,类型为.pyc的文件将由解释器自动生成,这将加速该模块未来的导入。因此,这些文件仅在由另一个.py文件或模块导入时从.py文件创建。

注意,使用.pyc文件只会加快程序的加载速度,而不会加快程序的实际执行速度。这意味着您可以通过在一个模块中编写主程序来提高启动时间,这个模块由另一个更小的模块导入。

pyc主要写入三个内容:

1).Magic num

2).Pyc创建时间

3).PyCodeObject.(python/marshal.c)

于是pyc magic num的作用有三:

一是拒绝完全不可能是正常的.pyc的文件,例如普通文本,图片、音乐,或者别的二进制格式。检查文件的头4个字节已经能有效的筛掉许多无效文件;

二是拒绝不慎被文本编辑器编辑而破损的文件;

三是拒绝不对应的Python解释器生成的.pyc文件。

由于不同Python版本的marshal算法可能不同,虚拟机采用的字节码指令集也可能不同,所以保守起见不同版本的Python解释器生成的.pyc文件被认为是不兼容的。

Python在不同的版本,pyc的头部长度和内容是不同的:

3ae0133f7b926576714ac8bdb905f46b5f2.png

PEP 3147中指出:.pyc文件包含两个2字节Header(表示一个MagicNum和Timestamp),后面跟序列化的PyCodeObject。每当Python改变字节码格式时,Magic Num会改变。Timestamp用于确保pyc文件与用于创建它的py文件匹配。当Magic Num或Timestamp不匹配时,将重新编译py文件并写入新的pyc文件。

9a9ec8f4ca001cc64ec6f35ff2b68638ee8.png

PEP 552中指出:.pyc头文件目前由4个字节组成。第一个字节仍是magic number,对字节码和pyc格式进行版本控制。第二个字节为新增加的字段,将是一个位字段(bit field),对报头其余部分的解释和pyc的失效行为取决于位字段的内容。如果位字段(bit field)为0,则pyc是传统的基于时间戳的pyc;第三个和第四个字节分别是时间戳和文件大小,通过比较源文件的元数据和头文件中的元数据来进行无效判断。

如果位字段的最低位被设置,则pyc是基于哈希的pyc。我们将第二个最低位称为check_source标志,位字段之后是源文件的64位散列,我们将使用带有源文件内容硬编码密钥;另一个类似MD5或BLAKE2的快速散列也可以,我们选择SipHash是因为Python已经从PEP 456中获得了它的内置实现,尽管允许选择SipHash键的接口必须公开给Python。

以下是一些常见的Magic num:

361eea12a91a994bbe86075b955737a9ca1.png

②.pyo文件:文件类型也是由解释器在导入模块时创建的。但是,.pyo文件是在启用优化设置时运行解释器的结果。

当我们调用Python解释器时,通过添加“-O”标志来启用优化器。

③.pyd文件:文件类型是特定于Windows操作系统类平台的。因此,在个人版和企业版的Windows 10、Windows 7和其他版本中可能经常遇到这种情况。

在Windows生态系统中,.pyd文件是一个包含Python代码的库文件,可以被其他Python应用程序调用和使用。为了使这个库对其他Python程序可用,它被打包为一个动态链接库。

.pyd文件是一个动态链接库,它包含一个Python模块,或一组模块,由其他Python代码调用。要创建.pyd文件,需要创建一个名为example.pyd的模块。在这个模块中,需要创建一个名为PyInit_example()的函数。当程序调用这个库时,它们需要调用import foo, PyInit_example()函数将运行。

④.pyz文件:executable python zip archives,具体内容参见下面的ZlibArchive;

(二)Python打包文件

打包文件是包含其他文件的文件,例如.tar文件、.jar文件或.zip文件。PyInstaller中使用了两种存档。一个是ZlibArchive,它允许高效地存储Python模块,并通过一些导入钩子直接导入。另一个是CArchive,类似于.zip文件,这是一种打包(或压缩)任意数据块的通用方法。它的名字来源于这样一个事实,即它可以很容易地从C和Python中操作。这两个类都来自一个公共基类,这使得创建新类型的归档变得相当容易。

①ZlibArchive:包含压缩的.pyc或.pyo文件。spec文件中的PYZ类调用创建了一个ZlibArchive。ZlibArchive中的目录是一个Python字典,它的Key(import语句中给定的成员名)与ZlibArchive中的查找位置和长度相关联。ZlibArchive的所有部分都以编组格式存储,因此与平台无关。

ZlibArchive在运行时用于导入绑定的python模块。即使使用最大压缩,这也比正常导入快。而不是搜索系统。路径,在字典里有一个查找。没有目录操作,也没有要打开的文件(该文件已经打开)。只有一次搜索,一次读取和一次解压。

Python错误跟踪将指向创建归档条目的源文件(.pyc编译、捕获并保存到归档时的_file__属性)。这不会告诉您的用户任何有用的东西,但是如果他们向您发送Python错误跟踪,您可以理解它。

②CArchive:可以包含任何类型的文件。它很像一个.zip文件。它们很容易用Python创建,也很容易从C代码中解包。CArchive可以附加到另一个文件,比如ELF和COFF可执行文件。为了实现这一点,存档是在文件的末尾用它的目录创建的,后面只跟一个cookie,它告诉目录从哪里开始以及存档本身从哪里开始。

CArchive可以嵌入到另一个CArchive中。内部存档可以在适当的地方打开和使用,而不必提取它。

每个目录条目都有可变的长度。条目中的第一个字段给出了条目的长度。最后一个字段是相应打包文件的名称。名称以空结尾。压缩对于每个成员都是可选的。

还有一个与每个成员相关联的类型代码。类型代码由自提取的可执行程序使用。如果使用CArchive作为.zip文件,则不必担心代码。

ELF可执行格式允许将任意数据连接到可执行文件的末尾,而不影响其功能。因此,CArchive的目录在归档的最后。可执行文件可以以二进制文件的形式打开自己,查找到最后并“打开”CArchive。

三、反编译Exe过程

因为是64位程序,用x64dbg载入查看,如图:

e083269d15a5012435e7b7bb9590e0fcd98.png

发现PyInstaller等关键信息,可以确认是利用PyInstaller打包的python文件,所以我们要想办法把python文件dump出来。

从网上搜索下,发现有工具可以直接将pyinstaller打包的Exe直接反编译出来,拿来主义,直接用......,为了大家不走弯路,我直接给出正确途径,如果按照网上的教程,你要摸索半天。

我没用网上介绍的Pyinstxtractor.py,够麻烦;我用的是用来提取的py脚本叫archive_viewer.py,将这个脚本文件和Exe放置在同一个目录下,

python archive_viewer.py wei.exe

出现如下图:

e1bfb2c4a52e8cfe9a077e2237e04a4885d.png

在这图里,最重要的就是上面用红线标上的两个部分,现在我们将它们dump出来,如下图:

bd54e132bcf1b0799f66c2c803d3e69d5f4.png

用x 命令将两个结构体导出,

87c6f7716b14a94d3f138fd5dcdf0b2c1ec.png

会形成这两个文件,struct这个位置在0,所以是头部;

我们现在是将struct的头部嫁接到wei.pyc的头部,这里涉及到了pyc的头部格式问题,我花了不少时间,因为我是实战嫁接成功后才去找的原因(理论作支撑);对一个没接触过的东西摸索入门确实要花费很多时间,而且过程非常难以忍受,难怪路遥在写完《平凡的世界》后第一件就是推开窗将手中的笔狠狠地扔了出去,我也有同感。

我们来看下导出的struct和pyc文件,当我打开pyc文件时,010editor提示要安装pyc.bt这个识别脚本,如图:

408abcacc43f1171b8df57ad3c3ffc0e962.png

肯定是选择安装,我信任它;可就是这个脚本害苦了我,按这个脚本的格式头我怎么理解都相矛盾,且怎么嫁接都不成功,后来才发现这个脚本只能支持到python2.7,对后续的版本不支持,更别提3.7了,这也造成了我困惑很久。

0645eed5eb04890e10d8e74faab6cdf4adf.png

对比两个文件头部,我们只要将struct的格式头插入到wei.pyc的头部,从上面的pyc的格式头我们得知要插入16个字节的,当初没找到文件头的文档,导致走了不少弯路;插入完成后,如图:

a16e5935a53dbabfae2c882537fdf4174b7.png

现在成为了一个完整的pyc格式的文件了,下面我们要做的就是将pyc转换成py格式的,网上有很多的说明,这里我强调一下,不要用那个EasyPythonDecopiler,这个工具的效果并不好,其实有个网页提供了pyc在线反编译转换功能,挺好,

9d7ab068c47ef78ee9222d2db3fc1fdaf07.png

到这里,反编译过程结束了,有机会我来讲解下用IDA逆向python的exe文件,届时奉献给大家。

这段时间连轴转,也蛮辛苦的;想想疫情前线的医护人员,每时每刻都在同生死作搏斗,我就觉得我要努力抓紧时间多做些力所能及的事情,才够资格向她们看齐。码字虽累,但边码字边陪着孩子,倒也其乐融融;如果您觉得作者辛苦了,请看后点个赞,鼓励下!

smiley_63.png

另,有些人给我留言,希望能用上我写的那些个工具软件,我说可以,但有两个条件:一是我要认识你嘛,好歹你要找个熟悉人介绍吧;二是你必须是网安的,在(一)的基础上找我吧。

1c0d9ded807ef2549c9dd6e5e137a329471.jpg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/266273.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

树莓派外设开发之接入语音模块

参考:树莓派接入语音模块控制继电器组 作者:糯米啊啊 发布时间: 2021-04-18 17:07:08 网址:https://blog.csdn.net/weixin_43732386/article/details/115834317?spm1001.2014.3001.5501 目录1.前言2.思路3.材料4.二次开发语音模块…

图片圆角

2019独角兽企业重金招聘Python工程师标准>>> //切图为圆角 public static Bitmap removeYuanjiao(Bitmap bitmap,int pixels){ int width bitmap.getWidth(); int height bitmap.getHeight(); Bitmap creBitmap Bitmap.createBitmap(width, height, android.grap…

python测试用例管理模块_python-selenium并发执行测试用例(方法一 各模块每一条并发执行)...

总执行代码: # codingutf-8 import unittest,os,time import HTMLTestRunner import threading import sys sys.path.append(C:/Users/Dell/Desktop/CARE/program)#使用编辑器,要指定当前目录,不然无法执行第20行代码 def creatsuite(): casedir [] lis…

input 赋值_FPGA基础设计:Verilog行为级建模(过程赋值)

来源:CSDN文章使用逻辑门和连续赋值对电路建模,是相对详细的描述硬件的方法。使用过程块可以从更高层次的角度描述一个系统,称作行为级建模(behavirol modeling)。1. 过程赋值阻塞赋值和非阻塞赋值的区别都很熟悉了。这里记录两个特性。1.1 特…

本地配置DNS服务器(MAC版)

转自https://www.cnblogs.com/skylor/p/7483959.html作为一个前端开发者,会遇到使用cookie的情况,常见的如:登录,权限控制,视频播放,图形验证码等,这时候本地开发者在PC上会使用修改hosts的方式…

mme设备内部错误_华为拟安装“俄版安卓”;百度回应内部贪腐;Android Studio 3.5 RC2 发布 | 极客头条...

快来收听极客头条音频版吧,智能播报由标贝科技提供技术支持。「CSDN 极客头条」,是从 CSDN 网站延伸至官方微信公众号的特别栏目,专注于一天业界事报道。风里雨里,我们将每天为朋友们,播报最新鲜有料的新闻资讯&#x…

[spring mvc]Hello World入门

1.新建项目 File->New->Other,选择Dynamic web project&#xff1a; 项目建好之后&#xff0c;目录结构如下&#xff1a; 2.WEB-INF/web.xml 中配置 dispatcherServlet <?xml version"1.0" encoding"UTF-8"?> <web-app xmlns:xsi"ht…

Mysql日期函数使用大全

为什么80%的码农都做不了架构师&#xff1f;>>> 1.1 获得当前日期时间&#xff08;date time&#xff09;函数&#xff1a;now() 除了 now() 函数能获得当前的日期时间外&#xff0c;MySQL 中还有下面的函数&#xff1a; current_timestamp() current_timestamp …

input点击事件不能用_用js简单写一个计算器

嗨&#xff0c;大家好&#xff0c;今天给大家带来的是一个计算器首先要知道我们常用的计算器都有哪些按键&#xff0c;有0~9&#xff0c; , - , *, /&#xff0c;还有 和.&#xff0c;基本是这些按键&#xff0c;然后我们去创建一些按键。之后我们去设置样式&#xff0c;设置完…

php判断信用卡,php校验信用卡卡号代码

[php]代码库// This function will take a credit card number and check to make sure it// contains the right amount of digits and uses the Luhn Algorithm to// weed out made up numbersfunction validateCreditcard_number($credit_card_number){// Get the first dig…

python list长度_python的入门阶段 编程思维100题 我跟罗志祥没关系

"""python的入门阶段 编程思维100题&#xff08;适合学习了1周--1个月的新人&#xff09; 第五题&#xff1a;我跟罗志祥没关系 朋友圈大家每天都看&#xff0c;那用python如何实现它那&#xff1f; 很简单&#xff0c;朋友的信息&#xff08;名字&#xff0c;头…

Android ----中文Api 百度地图

Android中文API最新中文版 [复制链接] kupekupe当前离线在线时间1 小时e望0 点最后登录2011-2-17注册时间2011-2-17积分12阅读权限10UID1341171 主题 0 好友 12 积分No.1 开发小菜鸟 No.1 开发小菜鸟, 积分 12, 距离下一级还需 88 积分升级 12% 当前用户组为 No.1 开发小菜鸟 …

android之多媒体篇(一)

2019独角兽企业重金招聘Python工程师标准>>> Android 4.0.3(Api Level 15&#xff09;支持的多媒体格式。 注意&#xff1a;有些设备可能支持其他的文件格式。 1.Audio AAC LC/LTP、HE-AACv1(AAC)、AMR-NB、AMR-WB、MP3、MIDI、Ogg Vorbis、PCM/WAVE、FLAC&#…

java定时器_拾遗Timer定时器

一 Timer 介绍在开发中我们经常会遇到一些简单定时任务的需求&#xff0c;而不需要量级较重的定时任务就可以采取java定时器&#xff1b;java.util.Timer工具类中的Timer 是定时器&#xff0c;但定时任务写在java.util.TimerTask 中&#xff0c;由 Timer 执行 TimerTask &#…

逻辑门电路的知识点归纳

1.半导体二极管与MOS管的开关特性 二极管&#xff1a;正向导通&#xff0c;反向截止&#xff0c;但是要注意的是从反向截止到正向导通的时间极其短&#xff0c;但是从正向导通到反向截止要经过反向恢复&#xff08;电荷存储效应&#xff09;的过程&#xff0c;这个过程实际上就…

善心

2019独角兽企业重金招聘Python工程师标准>>> 一个穷苦学生郝武德.凯礼&#xff0c;为了付学费&#xff0c;挨家挨户地推销货品。 到了晚上&#xff0c;发现自己的肚子很饿&#xff0c;而口袋里只剩下一个小钱。他在大街上犹豫徘徊了半天&#xff0c;终于鼓起勇气&a…

python 清屏_Python学前准备如果你知道要去哪,那么全世界都给你让路

一、Python 已来 AI 不远在当今&#xff0c;人工智能已经渗透到了智能手机、网络搜索&#xff0c;广告分发&#xff0c;人脸识别&#xff0c;语音识别&#xff0c;自动驾驶&#xff0c;智能医疗&#xff0c;无人银行等日常生活领域。人工智能的生活化是不可避免的&#xff0c;它…

js判断用户是否离开当前页面

简介 VisibilityChange 事件&#xff1b;用于判断用户是否离开当前页面 Code // 页面的 visibility 属性可能返回三种状态 // prerender&#xff0c;visible 和 hidden let pageVisibility document.visibilityState; // 监听 visibility change 事件 document.addEventLi…

记一次B站答题经历

第一题部分&#xff1a;社区规范卷 --------- ------------ 第二题&#xff1a;社区规范第二部分 -------------------- 第三部分自由选择题 ---------------------- -------------------------------- 最后答题成绩得分 -------------- ------------- 答完题后的感受&#xff…

linux 安装程序丢失链接动态库,Linux安装软件过程中提示缺少动态链接库.so的解决方法...

Linux在安装软件的时候有时会出现错误&#xff0c;提示缺少动态链接库.so&#xff0c;该问题是由什么原因导致的呢?情况分析&#xff1a;1.缺少动态连接库.so-cannot open shared object file:No such file or directory2.缺少动态连接库.so.0-cannot open shared object file…