`
teamojiao
  • 浏览: 344241 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

How To Decompile Actionscript Code In Swf

阅读更多

 

H ow T o D ecompile Actionscript Code I n Swf

 

Author: xy7 [80sec]
EMail: xy7 #80sec.com /xuanmumu@gmail.com
Site: h ttp://www.80sec.com
Date: 2009- 7 -2 7

 

[ 目录 ]

0 x 00 前言
0 x 01 swf 文件头分析
0 x 02 swf 文件结构
0 x 03 swf tag类型
0 x 04 寻找Actionscript代码
0 x 05 还原带有变量的AS代码段
0 x 06 总结
0x07 代码示例

 

0x00 前言

 

随着 F lash 的应用越来越广泛,针对 F lash 的安全性问题也被人们所重视。 通过提取 Flash 文件中的 AS 代码,可以进行恶意行为检测(网马分析),代码安全性分析( HP SWFSCAN )或者针对 AS 代码中出现的 URL 进行进一步检测分析( APPSCAN )。本文只是一篇工作笔记,通过实现一个简单的 Swf Decompiler 来提取 SWF 文件中的 AS 代码。

 

0x01 swf 文件头分析

              首先新建一个 flash 文件,默认大小,背景,无任何其他元素,只添加一个 geturl 函数,里面随便写上一个链接 http:// 1.1.1 .1 。这个新创建的 flash 文件就作为我们的分析对象。

SWF 文件头格式如下 :

SWF File Header

Field Type Comment

Signature UI8 Signature byte:

F indicates uncompressed

C indicates compressed (SWF 6 and later only)

Signature UI8 Signature byte always W

Signature UI8 Sig nature byte always S

Version UI8 Single byte file version (for example, 0x06 for SWF 6)

FileLength UI32 Length of entire file in bytes

FrameSize RECT Frame size in twips

FrameRate UI16 Frame delay in 8.8 fixed number of frames per second

FrameCount UI16 Total number of frames in file

UE 打开 新建的 flash 文件,首先读前三个字节, 46 57 53 =FWS ,说明该文件是未经过 zlib 压缩

下一个字节是代表 flash 的版本, 0a = 10

继续后四个字节代表 flash 文件的大小 4E 05 00 00 ,这里需要转成大尾存储 0000054e=1385bytes

接下来是 flash 的尺寸,这里定义了一个 RECT 结构用来存储这些数据

RECT 结构如下:

RECT

Field Type Comment

Nbits UB[5] Bits in each rect value field

Xmin SB[Nbits] x minimum position for rect

Xmax SB[Nbits] x maximum position for rect

Ymin SB[Nbits] y minimum position for rect

Ymax SB[Nbits] y maximum position for rect

继续往后读 1 个字节 78 ,转换成 2 进制补齐 8 78=01111000 ,根据 RECT 的格式取前五位 01111=15 ,表示剩下的数据要按每 15 位进行划分,由于还剩下 4 组数据要表示,所以需要 60 位, 60 位至少需要读 8 个字节,所以 RECT 结构需要的字节数为 00000008h: 78 00 05 5F 00 00 0F A0 00 ,都转为 2 进制进行 15 位分割,最后不足 15 位的舍去,最后得出的结果为 twip 20twip=1 像素),所以最后输入应该是这样:

01111

000000000000000

010101011111000

000000000000000

001111101000000

RECT binary value:0

RECT binary value:550

RECT bi nary value:0

RECT binary value:400

接下来 2 个字节代表帧速 00 18 =>18 00 =>24

最后 2 个字节代表帧数 01 00 =>00 01 => 1

至此, swf 文件头就结束了。

 

0x02 swf 文件结构

 

              S wf 文件主体是由一连串的 tag 组成,最终以一个 end tag 为结尾。大概结构如下:

 

              [ 文件头 ]---[ FileAttributes ]---[tag]---[tag] [end tag]

                                                                                                    |                             |                            

                                                                                                  [tag typ e]               [tag type]

                                                                                                    |         |

                                                                                                  [tag data]  [tag data]

 

0x03 swf tag 类型

 

              根据 tag 头可以将 tag 分为短 tag 和长 tag ,具体格式如下:

RECORDHEADER (short)

Field Type Comment

TagCodeAndLength UI16 Upper 10 bits: tag type

Lower 6 bits: tag length

RECORDHEADER (long)

Field Typ e Comment

TagCodeAndLength UI16 Tag type and length of 0x 3F

Packed together as in short header

Length SI32 Length of tag

也就是说高 10 位都代表着 tag 类型,后 6 位如果长度大于等于 0x 3f 则为长 tag ,其余的则是短 tag

tag 类型来分, tag 也可分做 2 类: Definition tags Control tags 。其中 Definition tags 主要包含了 flash 中的文本,声音,图像等资源,而 Control tags 则包含了一些文件的处理流程等控制元素。

既然已经分清楚了 swf tag 类型,那么就可以进一步分析 tag 以寻找我们需要的 AS 代码。

文件头已经分析完毕,接下来就来分析第一个 tag FileAttributes 。继续上面的例子,到了分析 tag 的时候依次读 2 个字节: 44 11 =>11 44 => 0001000101000100 => 0001000101 ( 10 ) => 69, swf 文件格式中查找 Tag type = 69 ,正是 FileAttributes ,接着低 6 位代表 tag 长度: 000100 =>4 ,向后再读 4 个字节: 10 00 00 00 => 00 00 00 10 =>16 => 00010000 , 这段数据就是 FileAttributes tag 的数据内容了, FileAttributes tag 到此结束。数据可以对照着 FileAttributes 数据结构来看,结构比较长就不贴出来了,其中第 4 位是 1 ,表明这个 flash 中含有 matadata ,继续往后读 2 个字节 7F 13 ,按位 10 =77

Metadata

Field Type Comment

Heade r RECORDHEADER Tag type = 77

Metadata STRING XML Metadata

6 位全为 1 ,所以说 matadata 是第一个长 tag ,长 tag 需要 4 个字节来表示数据长度,这些数据对实际分析没有什么作用,所以分析出数据长度就可以跳过了。

 

0x04 寻找 Actionscript 代码

 

通过前面 2 tag 的分析,已经能够清楚的知道 swf tag 的固定格式以及取数据的方法了,那么我们定义的 AS2 geturl 函数到底存在哪里呢?继续读下 2 个字节: 3f 03 => 03 3f , 取高 10 0000001100 =>12 ,这个 12 是什么意思呢 , swf 文档:

DoAction

Field Type Comment

Header RECORDHEADER Tag type = 12

Actions ACTIONRECORD [zero or more] List of actions to perform (see

following table, ActionRecord)

ActionEndFlag UI8 = 0 Always set to 0

注意 ACTIONRECORD

Fie ld Type Comment

ActionCode UI8 An action code

Length If code >= 0x80, UI16 The number of bytes in the

ACTIONRECORDHEADER, not

counting the ActionCode

现在可以确定 ActionCode 是包含在 Actions ACTIONRECORD 中, Actions ACTIONRECORD 又是属于 DoAction 。判断低 6 位得知 DoAction 是长 tag ,继续读后面 4 个字节来确定 DoAction 的数据长度: 1A 00 00 00 =>26 。至此就可以判定我们之前建立的 AS 代码就包含在这 26 个字节中。接下来根据 ACTIONRECORD 的定义, 1 个字节代表 ActionCode ,继续读: 83 ,查找 swf 文档:

Field Type Comment

ActionGetURL ACTIONRECORDHEADER ActionCode = 0x83

UrlString STRING Target URL string

TargetString STRING Target string

找到了我们定义的 geturl 函数,所以继续读下面 2 个字节 16 00 =>00 16=>22 ,那么这 22 个字节就是 geturl</span

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics