首先先说说as的abc文件
从下面的am2框架图可以看出abc文件所处的位置
abc文件abc文件就是flash player可以直接解释执行的的字节码,该文件中的内容会直接嵌入到swf文件的doABC标签下。源码的asc包就是处理abc格式的。通常在编译AS项目时,as3脚本文件都会被编译成abc文件然后再生成doABC标签。手工编译as3到abc文件在flash sdk的lib目录下,有个asc.jar,该文件就是用来生成abc文件的java程序,机器上要安装java运行时。 * 新建一个文件Hello.as,并写上一行代码 print("Hello"); * 在控制台中输入cd C:\Program Files\Adobe\Adobe Flash Builder 4\sdks\4.0.0\lib * 在控制台中输入java -jar asc.jar Hello.as, 编译成功,输出Hello.abc, 79 bytes written察看Hello.as文件所在目录会发现新生成一个Hello.abc文件。继续上面,把Hello.as文件改为一个class看看; * 把的代码改成 package { import flash.display.Sprite; public class Hello extends Sprite { public function Hello() { trace("Hello"); } } } * 编译,出现[Compiler] Error #1017: The definition of base class Sprite was not found.提示,这是由于缺少Sprite类的定义 * 导入as基本库:在asc源码包下有个abc文件,里面有builtin.abc,playerglobal.abc,toplevel.abc三个文件,他们就是flash的基本库。asc的命令行参数可以直接用java -jar asc.jar来查看。 重新输入命令 java -jar asc.jar -import E:\work\sdksrc\modules\asc\abc\builtin.abc -import E:\work\sdksrc\modules\asc\abc\playerglobal.abc Hello.as 可以看到编译成功。ABC文件的格式abcFile {u16 minor_versionu16 major_versioncpool_info constant_poolu30 method_countmethod_info method[method_count]u30 metadata_countmetadata_info metadata[metadata_count]u30 class_countinstance_info instance[class_count]class_info class[class_count]u30 script_countscript_info script[script_count]u30 method_body_countmethod_body_info method_body[method_body_count]}常量池cpool_info{u30 int_counts32 integer[int_count]u30 uint_countu32 uinteger[uint_count]u30 double_countd64 double[double_count]u30 string_countstring_info string[string_count]u30 namespace_countnamespace_info namespace[namespace_count]u30 ns_set_countns_set_info ns_set[ns_set_count]u30 multiname_countmultiname_info multiname[multiname_count] }
在abc文件(参考“flash sdk开源相关的一些东西”)中,所有的字符串值都会保存到常量池的字符常量string_info string[string_count] 段中,因此要混淆代码,只要把该段中的字符串值进行混淆就可以了。
但flash中的api中的类和方法以及代码中使用的字符串常量,还有导出类(SymbolClass标签中的)等是不能混淆的。实际上,需要混淆的只是自己定义的类和类的属性、方法。用户自己定义的类及属性方法可以在
u30 class_count instance_info instance[class_count]
class_info class[class_count]
段中找到。class_count 是所有用户定义的类的总数。段的定义结构如下:
instance_info { u30 name u30 super_name u8 flags u30 protectedNs u30 intrf_count u30 interface[intrf_count] u30 iinit u30 trait_count traits_info trait[trait_count] }
class_info { u30 cinit u30 trait_count traits_info traits[trait_count] }
另一个问题,在abc文件中,所有相同的字符串都会保存为同一个字符串值常量,当类或方法名根代码中的字符串相同时,则不能混淆。如下例子:
class Test {
public function Test() {
var str:String = "Test";
trace(str);
}
}
这时候,如果将Test类名混淆为a,那么str的值也会变为a,这样会改变str的值,因此混淆时还需要排出跟代码中字符串相同的类、方法或属性。
想要找出代码中使用的字符串,需要分析方法体内容,即
u30 method_body_count method_body_info method_body[method_body_count] 段内容。方法体定义如下:
method_body_info { u30 method u30 max_stack u30 local_count u30 init_scope_depth u30 max_scope_depth u30 code_length u8 code[code_length] u30 exception_count exception_info exception[exception_count] u30 trait_count traits_info trait[trait_count] }
方法体的
u30 code_length u8 code[code_length]
段记录了方法中的所有操作,只要找到其中的OP_pushstring(操作码0x2C)即为字符串赋值操作,根据该操作码后的字符串索引即可在字符串池中找到该字符串,将此字符串加入到排除列表即可。
转载于:https://www.cnblogs.com/pelephone/articles/as3-abc-mixup.html