加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

[转]as3的abc文件及as3代码混淆的一点方法

发布时间:2020-12-15 18:07:16 所属栏目:百科 来源:网络整理
导读:首先先说说as的abc文件 从下面的am2 框架 图可以看出abc 文件 所处的位置 ? abc文件 abc文件就是 flash ? player 可以直接解释执行的的字节码,该文件中的内容会直接嵌入到 swf 文件的doABC标签下。 源码 的asc包就是处理abc格式的。通常在编译AS 项目 时,

首先先说说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 FilesAdobeAdobe Flash?Builder?4sdks4.0.0lib
? ? * 在控制台中输入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:worksdksrcmodulesascabcbuiltin.abc -import E:worksdksrcmodulesascabcplayerglobal.abc Hello.as
? ?? ?可以看到编译成功。

ABC文件的格式

abcFile?
{
u16 minor_version
u16 major_version
cpool_info constant_pool
u30 method_count
method_info method[method_count]
u30 metadata_count
metadata_info metadata[metadata_count]
u30 class_count
instance_info instance[class_count]
class_info class[class_count]
u30 script_count
script_info script[script_count]
u30 method_body_count
method_body_info method_body[method_body_count]
}



常量池

cpool_info
{
u30 int_count
s32 integer[int_count]
u30 uint_count
u32 uinteger[uint_count]
u30 double_count
d64 double[double_count]
u30 string_count
string_info string[string_count]
u30 namespace_count
namespace_info namespace[namespace_count]
u30 ns_set_count
ns_set_info ns_set[ns_set_count]
u30 multiname_count
multiname_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)即为字符串赋值操作,根据该操作码后的字符串索引即可在字符串池中找到该字符串,将此字符串加入到排除列表即可。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读