在2010年11月28日,我在盛大举办的WeDoSwf会议上,我做了一个演讲,主题就是关于Swf的文件格式和Abc文件的混淆。
最近一个多月的时间里面,各种零零总总的事情特别多,一直没有时间把这个东西整理好放到博客中。
首先呢,把我的演讲的视频的ppt放上来:
视频:
http://v.ku6.com/show/MwjMgfhEgUFoiZhx.html
PPT:
http://www.slideshare.net/swfsh/swfabc
然后呢,经过我们的努力,我们已经将这个东西做成了一个产品,有兴趣的朋友可以去我们的公司主页上下载试用:
http://www.orandea.com/product?lang=cn
回到正题。在上一篇博客中,我讲了Swf文件和Abc文件的基本结构,我也提到了Abc文件中非常重要的一个数据结构:常量池(Constant Pool)。
常量池主要包括两类常量:基本数据类型常量和符号常量。
双精度常量是64位,IEEE标准的双精度浮点数。
字符串常量采用的是UTF-8编码保存的,提供了很好的跨语言能力。
在基本数据类型的常量之间不存在相互的引用关系。
Namespace常量又包括:
所以,我们可以看到,Flash player是基于一系列的引用关系工作的,而不是具体的字符串常量工作的,这样就给我们提供了混淆代码的机会。
也就是说,如果我们修改了这些字符串常量,不会对程序的实际执行造成影响。
这也就成为了我们混淆的突破口,只要将那些类引用的Multiname常量所对应的字符串常量修改掉,那么反编译工具反编译出来的代码就变得难以阅读了。
最近一个多月的时间里面,各种零零总总的事情特别多,一直没有时间把这个东西整理好放到博客中。
首先呢,把我的演讲的视频的ppt放上来:
视频:
http://v.ku6.com/show/MwjMgfhEgUFoiZhx.html
PPT:
http://www.slideshare.net/swfsh/swfabc
然后呢,经过我们的努力,我们已经将这个东西做成了一个产品,有兴趣的朋友可以去我们的公司主页上下载试用:
http://www.orandea.com/product?lang=cn
回到正题。在上一篇博客中,我讲了Swf文件和Abc文件的基本结构,我也提到了Abc文件中非常重要的一个数据结构:常量池(Constant Pool)。
常量池
常量池,顾名思义就是保存Abc文件中用到的各种常量的地方。而在Abc文件的其他部分,需要使用常量的地方都采用一个uint型的索引指向常量池中的某个元素。常量池主要包括两类常量:基本数据类型常量和符号常量。
基本数据类型常量
Abc文件中的常量池中,主要包括四类基本数据类型的常量:- 无符号整形常量
- 有符号整形常量
- 双精度浮点常量
- 字符串常量
双精度常量是64位,IEEE标准的双精度浮点数。
字符串常量采用的是UTF-8编码保存的,提供了很好的跨语言能力。
在基本数据类型的常量之间不存在相互的引用关系。
符号常量
符号常量主要包括2个类别:Namespace常量和Multiname常量。Namespace常量又包括:
-
Namespace常量
主要是指向字符串常量的一个指针
-
Namespace Set常量
由一系列指向Namespace常量的指针组成
- 类的符号
[pk]com.orandea.utils:ArrayUtils 表示在Package:com.orandea.utils中的ArrayUtils类
- 类的方法或者属性
[pk]com.orandea.utils.ArrayUtils:wrapFunc 表示类com.orandea.utils.ArrayUtils的wrapFunc方法。
所以,我们可以看到,Flash player是基于一系列的引用关系工作的,而不是具体的字符串常量工作的,这样就给我们提供了混淆代码的机会。
也就是说,如果我们修改了这些字符串常量,不会对程序的实际执行造成影响。
这也就成为了我们混淆的突破口,只要将那些类引用的Multiname常量所对应的字符串常量修改掉,那么反编译工具反编译出来的代码就变得难以阅读了。
Namespace的种类
在Abc文件中Namespace被分为了几个不同的种类,主要对应于不同的访问控制修饰符(public, protected, private, static...),包括:- Namespace
主要是指Xml中的namespace
- PackageNamespace
主要是public修饰的package中的符号
- PackageInternalNs
- ProtectedNamespace
- ExplicitNamespace
- StaticProtectedNs
- PrivateNs
Multiname的种类
Multiname也有很多不同的类型,包括:- QName (Qualified Name)
就是完整的Multiname,由Namespace和Name组成,比如上文中提到的[pk]com.orandea.utils:ArrayUtils
- RTQName (Runtime Qualified Name)
跟QName相似,但是namespace由运行时决定
- RTQNameL (Runtime Qualified Name Late)
与RTQName类似,但是Name也由运行时决定
- Multiname (Multiple Namespace Name)
Adobe真是词穷啊,到处都是Multiname,还代表不同的意思。。。。这个和RTQName是一样的,但是用Namespace Set取代了Namespace
- MultinameL (Multiple Namespace Name Late)
这个和Multiname是一样的,但是Name字段由运行时决定