写在前面
一天 闲来无事,对SWF的内存提取产生了好奇,为什么要内存提取呢?因为很多游戏厂商或者私人作者会在自己的swf进行混淆、加密使得不能直接反编译,在几年前的一些网页游戏中还是使用了flash来做游戏,虽然现在大多数游戏都被h5给替换,但是技术不变。秉承着学习的态度,便写了这篇文章
0x01
首先我们要知道 SWF 是什么?
SWF 是 Small Web Format 的缩写,读作swiff 是Macromedia(现已被ADOBE公司收购)公司的动画设计软件Flash的专用格式,被广泛应用于网页设计、动画制作等领域,swf文件通常也被称为Flash文件。
代码文件 Adobe AcitonScript 3.0 简称AS3.0
运行SWF文件是需要 flash播放器
主要厂商的Flash“退役”时间表:
Mozilla:
2018 – Firefox 用户必须在每个要使用 Flash 的会话上启用 Flash。
2019 – 如果站点使用 Flash,Firefox 将向用户显示可见的警告。
2019 – 默认情况下禁用 Flash。
2020 – 从 Firefox 中删除 Flash支 持。
2021 – Firefox 将不再加载 Flash 插件
微软:
2018 – Microsoft Edge 将要求用户单独为每个会话启用 Flash。Internet Explorer 继续允许 Flash。
2019 – 默认在 Microsoft Edge 和 Internet Explorer 中禁用 Flash。
2020 – 删除 Flash
Google:Chrome 将于 2020 年底前删除 Flash,并无时间表。
Apple:Safari 默认关闭 Flash,并无时间表。
Facebook:内置 Flash 的游戏将能支持到 2020 年底。
缅怀一下
0x02
我们这篇主要讲的是《如何在内存中提取出加密的SWF》在开始之前我先给大家安利一下SWF的反编译软件。
主流的反编译工具
ASV(Action Script Viewer)
是一款付费的反编译软件,目前国内只能搜索到ASV2010的破解版,反编译FlashCC Achemy 有一家声称是代理商的 某某堂 也只是停留在 asv2013 版,其实ASV在国内是没有代理商的,而且一直有更新目前最新版本是 ASV2019 不但是私人会使用,连flash 团队的内部人员调试的时候 也会用到这个工具,所以功能之强大可想而知
JPEXS Free Flash Decompiler
这是一款由 Java 编写的免费开源的反编译软件,支持反编译FlashCC Achemy、多国语言、多个平台。我觉得是一款超良心,排名第一的免费反编译软件,可直接编辑修改 AS 代码,P-code,同时也支持内存提取swf
Sothink SWF Decompiler
硕思闪客是一款付费的软件,价格很贵,软件功能相比于上面两款来说,我个人认为是有点鸡肋了。支持将SWF转换为Fla/Flex/HTML 5。国内一些破解论坛有破解版,我在刚开始接触flash游戏的时候,使用的是这款软件来进行反编译。后来就慢慢的被JPEXS强大的功能吸引,也就没用硕思来反编译。
Swf Reader
swf reader 由 Java 编写的一款强大的内存提取、反编译SWF工具,最初内存提取swf时我所使用的就是这款工具。由于很多游戏厂商把swf进行加密处理,直接反编译是会报错,这个可以内存提取并无限制保存swf,比swf窗口吸血鬼要猛得多。
而且,更恐怖的是直接针对SWF Encrypt,DoSwf,SecureSWF等主流加密工具一键破解…
以前也是开源的,但是目前开源网站打不开了。只能从网上搜索出流传的版本SwfReaderFull_2.3_build47
还有一些反编译工具就不一一介绍了。
0x03
不管是什么类型的加密,在运行的时候都会将加密的swf进行解密然后才能运行,所以在内存里的swf文件是解密后的文件。
我们要想内存提取 swf 必须先了解 swf 的文件信息
swf文件格式说明文档 Adobe 官网连接已经消失了,只能从网上下载我推荐 swf_file_format_spec_v10.pdf
前3个字节为文件标识头,F代表为未压缩,C代表已压缩,使用的是zlib压缩。第四个字节代表版本号,第五个到第九个字节代表文件的长度(小端需要注意转换),第十个字节 swf的舞台大小,单位:twips 1px = 20twips ,第十一到十二字节代表帧率,
SWF File Header
U表示 unsigned 无符号 I 表示 Interger 后面的数字表示二进制 8位 16位 32位
Field | Type | Comment |
---|---|---|
Signature | UI8 | Signature byte: “F” 未压缩 “C” 压缩 |
Signature | UI8 | 固定为“W” |
Signature | UI8 | 固定为“S” |
Version | UI8 | 版本号 (如: 0x06 表示swf6) |
FileLength | UI32 | 该swf文件的长度,单位:字节 |
FrameSize | RECT | swf的舞台大小,单位:twips 1px = 20twips |
FrameRate | UI16 | 帧率,这里总共有16位,只有后面8位有效 |
FrameCount | UI16 | 总帧数 |
所以我们可以从内存里搜索 FWS 然后取出 版本号 和 长度 就可以取出内存里的Swf
至于使用什么类型的编程软件就看个人的喜好了。
我这边使用 中文编程软件 “易语言” 来编写例子,理由是比较方便,很多API可以直接拿来用。
首先枚举出所有的进程
然后 取出进程ID,接着内存搜索
将搜索出来的内容进行分析
使用 JPEXS 反编译
End