基于代码下沉与残码解释的Android应用程序保护方法与流程

文档序号:15694670发布日期:2018-10-19 18:50阅读:996来源:国知局

本发明属于android应用程序中dex文件加固的技术领域,具体涉及基于java层代码反射下沉与多样性虚拟解释dex残码相结合的androidapp保护方法。



背景技术:

近年来,随着android手机市场占有率的不断提高,随之而来的安全问题也愈发严峻,其中二次打包的问题尤为严重。由二次打包引起的隐私泄露、资金窃取、流量耗费案例层出不穷,给开发厂商和广大用户带来了巨大的损失。

android程序大多是由java作为原生语言开发的,故而保护安卓应用程序中由java语言编译的classes.dex文件显得尤为重要,目前对于dex文件(apk中的classes.dex的简称,android应用中可执行文件)的保护方式有:dex整体加密技术、部分方法的类加载加密、虚拟化保护技术等。dex整体加密技术基于java虚拟机的动态加载技术,将原apk或dex进行加密,再加一层壳,壳通过自定义dexclassload在运行的时候进行动态加载解密原始dex文件,这种方法能够有效防止静态分析,但在解析dex时进行内存dump,攻击者便可得到完整的dex文件,随后进行二次打包;部分方法的类加载加密主要是通过抽离dex中的关键函数指令,保存到一个单独的文件中,运行时在内存中对dex关键函数进行指令还原,能够有效防止动态分析和内存被dump,目前可以通过修改android源码来自定义虚拟机进行攻击分析;虚拟机保护技术是使用自定义的语言翻译之前的语言,同时使用本地层自定义的解释器进行解释,加大了还原代码的难度。但由于dalvik指令集指令的有限性,有经验的攻击者可通过分析dalvik指令和自定义指令集之间的映射关系来攻击该技术。

因而亟需一种既防止内存dump又增加代码还原难度的保护dex文件的技术方案。因此本专利提出一种基于java层代码反射下沉与多样性虚拟解释dex残码相结合的androidapp保护方法。攻击测试实验表明,在牺牲可接受的性能开销情况下,我们提出的保护方法可以有效防止当前逆向工具的攻击,大多数的静态和动态逆向分析也起不到相应地效果和作用。



技术实现要素:

本发明提出并设计了一种基于代码反射下沉与多样性虚拟解释残码相结合的android应用程序保护方法,其核心是通过将dex文件部分方法native化和基于寄存器的dalvik指令多样性虚拟化来提高应用程序安全性。本发明方法可以有效防止dex文件内存被dump,从根源上杜绝二次打包。

为达到上述目的,本发明采用如下技术方案:

基于代码下沉与残码解释的android应用程序保护方法,包括以下步骤:

将android应用程序的安装包中的dex文件反汇编得到汇编指令,在汇编指令中指定待保护的关键方法,包括第一关键方法和第二关键方法;其中,第一关键方法为入口方法,第二关键方法为除了入口方法之外的其他方法;将第一关键方法、第二关键方法的属性均修改为native类型;

对所述的第一关键方法采用代码反射下沉的方式进行反射翻译,对所述的第二关键方法进行指令抽取,并对指令进行虚拟化保护,然后将处理结果存储至自定义文件中,重写形成新的dex文件;编译形成第一关键方法的解释器和第二关键方法的解释器;

将第一关键方法的解释器、第二关键方法的解释器、自定义文件以及重写形成的dex文件经打包、签名后生成新的安装包。

进一步地,所述的对第一关键方法采用代码反射下沉的方式进行反射翻译,包括:

将第一关键方法的所有指令逐条从dex文件中抽离,并进行控制流分析,依照控制流结构进行反射翻译,然后结合jni接口函数进行解释还原,同时生成cpp文件。

进一步地,对所述的第二关键方法进行指令抽取,并对指令进行虚拟化保护,包括:

将第二关键方法里的所有指令逐条从dex文件中抽离,并执行预处理操作;所述的预处理操作是根据指令类型提取相关信息及指令上下文;

自定义多套映射规则,然后随机选择一套映射规则对抽离的每条指令进行加密,以对指令进行虚拟化保护。

进一步地,所述的自定义文件包括文件头和文件体,其中,

所述的文件头包括魔术字、文件头大小、抽取结构总大小,抽取方法结构偏移、字符串大小,字符串偏移,类型信息大小,类型信息偏移,引用方法描述体大小,引用方法描述体偏移;

所述的文件体包括字符串区域,类型区域,引用方法描述体区域,抽取方法结构体区域;抽取方法结构体区域包括:当前方法id,当前方法大小,虚拟指令大小,虚拟指令。

进一步地,所述的编译形成第一关键方法的解释器和第二关键方法的解释器;包括:

将所述的第一关键方法采用代码反射下沉的方式进行反射翻译时生成的cpp文件生成第一关键方法的解释器,所述的第二关键方法进行指令抽取、虚拟化保护并将处理结果存储至自定义文件中的同时,生成包含签名信息的cpp文件,将该cpp文件与本地层已实现的包含解释器核心功能的cpp文件结合生成第二关键方法的解释器。

与现有技术相比,本发明具有以下技术效果:

1.本发明是在本地层实现了自定义文件中抽取指令的虚拟解释,并经过编译以动态库的形式绑定于受保护的apk,故而兼容性好,可以完美兼容安卓4.4之前的dalvik虚拟机和安卓4.4及之后的art虚拟机。

2.本发明中提出了多样性虚拟保护的概念,多套自定义映射规则多样性虚拟解释dex文件中的关键方法,在加固端对抽取指令的操作码、操作数随机选择一套转换规则进行映射,在解释器端直接根据变换之后的指令进行相应的解释而不需要指令还原的过程,且指令变化作为后台处理部分,其逻辑不会出现在受保护apk中,对于攻击者来说,这样的随机性和其余正确指令的干扰大大增强了逆向者去分析的时间开销和成本开销。

3.本发明设计的虚拟机可扩展性强、灵活性高。解释器可以对所有dalvik指令进行处理,对待保护的方法进行指令抽取、自定义转换、本地层解释可以有效的防止动态调试时内存dump得到真实指令。

4.由于java语义性较强,易被反编译,较为理解。我们采用dex文件中部分方法的native化技术,使待保护java层方法通过jni反射转换为本地层方法。native层代码较为底层,很多程序员不具备分析本地代码的能力。代码下沉大大增加了攻击者还原java层中关键逻辑的难度。

5.本发明设计中多重虚拟解释dex残码的引入为系统提供了灵活性及鲁棒性,用户可以根据需求自由选配多重虚拟模块的占比以及多重虚拟的处理函数。两种方法的结合从一定程度来讲再一次提升了攻击者攻击的门槛,攻击者需要同时对两种方式内部实现进行深入研究。

6.测试实验表明,在本发明中,保护前后应用程序安装包的大小体积有所增加,但变化不大;启动时间几乎没有差别;内存的消耗基本不变甚至减少,这是因为在本地层运行要比在虚拟机本身执行消耗的内存少。

附图说明

图1是本发明的流程图;

图2是本发明的整体系统框架图;

图3(a)是“oncreate”方法的反射下沉示例代码;图3(b)是“const_string”指令所对应的处理函数示例;

图4是对nop指令多样性虚拟的示例图;

图5是自定义nisl文件的结构示例图;

图6(a)是利用本发明方法保护前dex文件的伪java图;图6(b)是利用本发明方法保护后dex文件的伪java图。

图7(a)分别是两个android应用程序利用本发明方法保护前后内存消耗对比图、启动时间对比图;图7(b)是两个android应用程序利用本发明方法保护前后体积对比图。

具体实施方式

本实施例提出了一种基于代码下沉与残码解释的android应用程序保护方法,我们将从该套保护方法的加固过程和保护后安卓程序的执行过程两个方面来进行说明。在本发明中我们选择app中“mainactivity”类的“oncreate”方法作为native化的目标函数进行jni反射下沉,在本地层实现了“oncreate”方法的功能,编译生成解释性so文件,这是该保护方法的第一步。考虑到除了oncreate方法之外的一些方法可能含有重要逻辑,同时为了增大逆向分析的难度,本发明提出了多样性虚拟解释残码技术。该方案采用了代码虚拟化技术,即将dex文件中待保护的方法进行指令抽取,将抽取方法存放至特定格式的自定义nisl文件中,通过本地层自定义解释器的handler(处理函数)对该文件进行逐条解释。本文提出了多样性虚拟方案,即加固端和解释器之间存在多套映射关系,每次在加固过程中随机选择一套映射规则进行加固,故每次经过该系统保护后的同一应用程序中的关键方法段hex码不尽相同。这无疑增大了攻击者通过分析dalvik指令和自定义指令的映射关系来分析破解该虚拟机的难度,代码反射下沉与多样性虚拟解释残码相结合的方式极大的保护了本地层的解释器和java层的关键代码、逻辑。

基于代码下沉与残码解释的android应用程序保护方法,如图1所示,包括以下步骤:

将android应用程序的安装包中的dex文件反汇编得到汇编指令,在汇编指令中指定待保护的关键方法,包括第一关键方法和第二关键方法;其中,第一关键方法为入口方法,第二关键方法为除了入口方法之外的其他方法;将第一关键方法、第二关键方法的属性均修改为native类型;具体包括以下步骤:

步骤1,获取安卓程序安装包的dex文件中待保护的关键方法

步骤1.1,对于待保护的安卓程序安装包,解包安装包获取dex文件,并按照dex文件格式解析,将dex文件反汇编为smali汇编指令;

步骤1.2,指定需要保护的第一关键方法以及第二关键方法,并确定第一关键方法和第二关键方法的方法名以及所在类的类名。

其中,第一关键方法在后续处理过程中,利用代码反射下沉的方式进行保护;而第二关键方法则采用基于多样性虚拟解释残码保护的方式进行保护。本方案中,第一关键方法选择程序的入口方法,例如设定为“mainactivity”主类中的“oncreate”方法,原因是“oncreate”方法是安卓程序中的重要方法,程序中其他方法通过该方法进行调用,因此本方案中首先对第一关键方法,即入口函数进行代码反射下沉方式进行保护,以有效增强逆向分析的难度。第二关键方法可以是程序中除了入口函数之外的任意一个或多个方法,由用户指定,例如第二关键方法可以是包含数据调用、数据处理等重要逻辑的方法。本实施例中,为了便于说明,选择“mainactivity”主类中的“test”方法作为第二关键方法。

步骤1.3,获取所述smali汇编指令中所有类的入口,分别找到第一关键方法所在类、第二关键方法所在类的入口后,在两个类的smali汇编指令中遍历查找所有方法,由此来定位第一关键方法、第二关键方法的代码段。

该步骤中,可通过解析androidmanifest.xml文件来获取所有类的入口。

步骤1.4,找到待保护的第一关键方法、第二关键方法后,将第一关键方法、第二关键方法的属性均修改为native类型。

在后续处理过程中,第一关键方法“oncreate”函数经步骤2后按照步骤3代码反射下沉的方式进行处理;用户输入的方法经步骤2后按照步骤4进行处理,即基于多样性虚拟解释残码保护的方式进行保护。

步骤2,在第一关键方法、第二关键方法所在类的执行类构造器中分别插入生成第一关键方法的解释器、第二关键方法的解释器调用代码的smali指令语句,然后重写dex文件。

本实施例中,插入smali指令语句的作用是生成两条system.loadlibrary(“**.so”)代码。第一关键方法的解释器为“libdexvmp.so”,第二关键方法的解释器为“libdexvmp01.so”,步骤2中写入这两个解释器的调用代码后重写dex文件。

具体的示例为:

解释器调用代码为:

“system.loadlibrary(“libdexvmp.so”);system.loadlibrary(“libdexvmp01.so”);”。

插入的两条smali语句为:

“const-stringv1“libdexvmp”;

invoke-static{v1},ljava/lang/system;

->loadlibrary(ljava/lang/string;)v;”。

“const-stringv1“libdexvmp01”;

invoke-static{v2},ljava/lang/system;

->loadlibrary(ljava/lang/string;)v;”。

对所述的第一关键方法采用代码反射下沉的方式进行反射翻译,对所述的第二关键方法进行指令抽取,并对指令进行虚拟化保护,然后将处理结果存储至自定义文件中,重写形成新的dex文件;编译形成第一关键方法的解释器和第二关键方法的解释器,具体包括以下步骤:

步骤3,对第一关键方法采用代码反射下沉的方式进行保护

步骤3.1,将步骤2重写后的dex文件反汇编为smali汇编指令,循环读取反汇编后的第一关键方法,即“oncreate”方法里的smali语句,从而将第一关键方法中的所有smali语句逐条从dex文件中抽离;

步骤3.2,对循环读取的第一关键方法里的smali语句进行控制流分析,依照控制流结构进行反射翻译;所述的smali语句可分为调用语句、赋值语句,对于不同形式的语句结构利用不同的jni接口函数进行解释还原;解释还原的同时生成cpp文件。

解释还原后的c++代码如图3(b)所示,对于调用语句,此示例解释还原后的代码为获取对象实例的getobjectclass方法、获取其父类对象的

getsuperclass方法、构造函数jmethodid的getmethodid方法,调用执行的callnonvirtualvoidmethod方法。对于赋值语句,解释还原后的代码为加载对应类的findclass方法、类的初始化及返回静态域的id的getstaticfieldid方法,获得对象静态域值的getstaticintfield方法。

顺序读取至第一关键方法结束,此时抽空dex文件中的第一关键方法;其解释还原的cpp文件将在步骤5.1中被编译成“libdexvmp01.so”文件。

在本步骤中,jni(javanativeinterface)技术打通了android系统java层与c/c++层之间的调用关系,jni技术的出现屏蔽了不同平台之间的一个差异,使得java层和c/c++两个世界能够相互通信,将“oncreate”方法native化后,即使逆向时在内存中dump出一个dex文件,也是无效的。因此dex部分方法的本地化可以有效的防止内存dump。生成的c++代码在保护程序编译过程中产生了一个oncreate方法的解释性so文件,即:libdexvmp01.so。另外,生成的libdexvmp01.so文件与java层代码有着功能等价关系。

本实施例中,具体的示例为:我们选择“oncreate”方法中的一段代码来执行代码反射下沉操作,此代码段从super.oncreate(savedinstancestate)和this.setcontentview(r.layout.activity_main)反汇编而来,转换示例代码如图3(a)所示,包括了待保护的java层方法、反汇编后的smali代码、反射下沉后的c++代码。本例中c++代码段的jni方法按操作类型可以分为三类:类相关操作方法,获取类成员方法,执行实例方法。

步骤4,对第二关键方法采用基于多样性虚拟解释残码的方式进行保护

步骤4.1,将步骤2重写后的dex文件反汇编为smali汇编指令,将第二关键方法里的所有指令逐条从dex文件中抽离,并执行预处理操作;

所述的预处理操作是根据smali汇编指令的指令类型提取相关信息及指令上下文;其中相关信息即索引信息,而指令上下文则为数据信息。根据索引信息可以获得类名、方法名、参数名,根据数据信息可以获取数组内容。

在本步骤中,提取指令相关信息时,以引用类指令为例,根据不同的索引信息可以拿到相应的类名、方法名、参数名等信息。采用这样的方法,能够确保保护后程序在解释执行时能正确还原或构造对象,最终实现指令重构的目的。

步骤4.2,自定义多套映射规则,然后随机选择一套映射规则对第二关键方法每条指令所提取到的信息(即hex码形式)进行加密,具体来讲是对每条指令的操作码、操作数、指令长度中的一种或几种按某套映射规则进行加密。

在选择加固方案时,首先自定义多套映射规则,该映射规则用于将第二关键方法中的每条指令转换成自定义指令,以进行指令的虚拟化;多样性虚拟分为指令操作码多样性虚拟、指令操作数多样性虚拟、指令长度多样性虚拟三种类型。采用这样的方法,能够保证每个保护后应用程序关键方法段的编码不同,充分保障了该技术的抗逆向能力。映射规则的定义和指令的虚拟化在现有技术中多有应用,在此不赘述。

本实施例中,以一种映射规则为例进行说明:将256个操作码的opcode值作为一个数组,前128个数组元素与后128个数组元素进行整体交换,再将该数组元素循环右移77位。

步骤4.3,自定义文件nisl,将步骤4.2加密后的指令按照不同的字段信息写入到nisl文件中,同时生成包含签名信息和触发虚拟机解释器执行的cpp文件;将第二关键方法中的所有指令抽空并加密、写入到nisl文件中后,重写形成新的dex文件。在一个程序中,可指定一个或多个第二关键方法。

nisl的文件格式如图5所示,该自定义文件中的每个字段与dex文件中第二关键方法的信息结构有着对应关系。nisl包括文件头和文件体,其中:

所述的文件头包括魔术字、文件头大小、抽取结构总大小,抽取方法结构偏移、字符串大小,字符串偏移,类型信息大小,类型信息偏移,引用方法描述体大小,引用方法描述体偏移。在文件头中,各部分结构的说明如下:

魔术字是一段在定义nisl文件时生成的hex码,用于在解释器解释执行的过程中识别和定位nisl文件。

头文件大小:头文件的占用空间大小,头文件包括魔术字、头文件大小、方法个数、起始方法偏移。

抽取方法结构总大小:表示一共抽取/虚拟化保护了多少个第二关键方法。

抽取方法偏移:首个第二关键方法描述距离nisl文件的偏移地址。

字符串大小:nisl文件中存储的所有字符串的数量。

字符串偏移:所有字符串在nisl文件中的起始偏移地址。

类型信息大小:记录受到保护的第二关键方法中所有引用到的类型数量。

类型信息偏移:所有类型数据相对于nisl文件的偏移。

引用方法描述体大小:记录受到保护第二关键方法中所有引用到的方法对应的结构体数量。

引用方法描述体偏移:所有方法结构体的相对与nisl文件的起始地址偏移。

所述的文件体包括字符串区域,类型区域,引用方法描述体区域,抽取方法结构体区域(当前方法id,当前方法大小,虚拟指令大小,虚拟指令)。在文件体中,各部分结构的说明如下:

字符串区域:由字符串偏移字段引用/指向,对应第二关键方法所有引用到的字符串(和原始dex文件存在对应关系)。

类型区域:存储类型索引,索引内容指向字符串区域。

引用方法描述体区域:存储所有的方法结构体,结构体主要由三个部分组成:方法名称索引,方法签名索引,方法所属类名称索引。其中方法名称和方法签名索引都指向字符串区域,方法所属类索引指向类型区域。

抽取方法结构体区域:可能包含多个结构体副本,结构体副本数量依据“抽取方法结构总大小”而指定,每个结构体中包含:当前方法id,当前方法大小(当前方法结构体占用nisl文件的大小),虚拟指令大小,虚拟指令(对应原始指令变换后的指令,自定义解释器就是通过读取它进行解释执行的)。

本步骤在生成cpp文件和自定义nisl文件时,该cpp文件一方面能根据第二关键方法的签名信息来实现本地函数的动态注册,另一方面作为jni桥来触发虚拟解释器执行解释。另外,重写后的dex文件是不完整的,对于整个apk文件是无效的。

本实施例中,具体的示例为:我们以dalvik指令中的nop指令为例来对多样性虚拟进行说明,如图4所示,nop指令的dalvik字节码为0000h,映射规则1、6是对操作码进行多样性虚拟,操作码00h替换为操作码12h和0ah,最终生成0012h(const/4v0,#0)和000ah(move-resultv0)。逆向分析者即便找到虚拟机的入口点处,通过hex码分析语义,其语义完整,但结果错误。映射规则2、3是对操作码操作数同时进行多样性虚拟,将0000h替换为7312h(const/4v3,#7)和2112h(const/4v1,#2)。映射规则4、5是对操作码操作数进行填充多样性虚拟,增加了原始指令的长度,转换后为b3320066h(if-eqv3,v11,0080)和20240d530000h(filled-new-arrayv0,v0,type@0d53),另外,生成的自定义文件为nisl文件。

将第一关键方法的解释器、第二关键方法的解释器、自定义文件以及重写形成的dex文件经打包、签名后生成新的安装包,具体包括以下步骤:

步骤5,生成虚拟机解释器,打包形成保护后的apk文件

步骤5.1,将步骤3.2生成的cpp文件与含有打包so文件功能的cpp文件在保护程序编译执行过程中结合生成第一关键方法的解释器,即虚拟机解释器“libdexvmp01.so”;将步骤4.3生成的包含签名信息的cpp文件与本地层包含dalvik指令处理函数的解释(即已实现的包含解释器核心功能的)cpp文件在保护程序编译执行过程中结合生成第二关键方法的解释器,即虚拟机解释器“libdexvmp.so”。

步骤5.2,将步骤4.3生成的dex文件、两个解释性so文件(即第一关键方法的解释器、第二关键方法的解释器)、以及与libdexvmp.so文件配套的自定义nisl文件进行重打包、签名,最终生成一个与保护前安卓应用程序功能等效的安卓应用程序。

在本步骤中,其他本地层解释cpp文件包含了所有dalvik指令的handller(处理函数)和将所有cpp文件打包成“libdexvmp.so”文件的方法。图3(b)为数据定义指令const_string的handler,在保护程序执行过程中我们只是将所有handler打包进“libdexvmp.so”文件,并未执行handler,在保护后安卓程序的执行过程我们将会对handler内部结构进行详细说明。另外两个解释器在本地层通过编译形成,采用这样的方法,能够使得保护后的安卓程序完美兼容dalvik系统和art系统,能在基于arm、x86、mips体系结构的android手机上正常运行。

本实施例中,具体的示例为:我们将该套保护方法保护前后dex文件的伪java代码以附图形式进行说明,如图6(a)、6(b)所示。在测试保护效果方面,样本一为2048小游戏.apk,样本二为doublevmp01.apk,doublevmp01.apk是一款crackme算法应用程序。保护前后安卓应用程序的内存消耗、启动时间、体积如图7(a)、7(b)所示,图7(a)的横坐标为实验次数。在内存消耗方面,可以看到样本1、2中在保护后所消耗的内存在某个时刻比保护前消耗的少,这是由于在本地层运行比在虚拟机本身执行消耗的内存少;在启动时间方面,保护前后几乎没有差别;在体积大小方面,有所增加但变化不大,这是因为保护后的应用程序在结构上增加了两个解释性so文件和自定义nisl文件。

本实施例中,保护后安卓程序的执行过程主要包括以下步骤,如图2所示:

步骤1,程序以自然顺序正常执行,在执行到包含native关键字的“oncreate”方法时,通过load.library函数调用jni反射下沉所产生的定制解释器libdexvmp01.so;

步骤2,调用结束libdexvmp01.so,顺序执行至“test”方法,调用多样性解释残码所产生的libdexvmp.so;

步骤2.1,执行解释器libdexvmp01.so后,安卓应用程序执行到包含native关键字的“test”方法时,通过load.library函数调用定制的解释器libdexvmp.so;

步骤2.2,在调用该解释so文件开始时对自定义nisl文件进行读取,首先确定是哪套加固映射规则,根据加固映射规则选择相对应的解密规则,对虚拟指令操作码、操作数以及指令长度中的一种或几种进行解密后,进入相应handler原子操作中进行解释,直至解释器执行完成;

步骤2.3,执行结束、跳出虚拟机解释器,返回与初始函数返回类型一致的返回值;

步骤3,顺序执行代码至结束。

在本步骤中,在执行解释器libdexvmp.so时,这个定制解释器完全替代art或dalvik虚拟机的功能,程序执行时使用自定义虚拟机解释器来还原与目标代码等价的逻辑功能。在执行定制解释器libdexvmp01.so中相应的handler时,我们按照dalvik指令相关类型编写相应类型的handler,一方面是因为dalvik字节码有一套类型、方法及字段表示方法,其指令类型包括数据定义与操作指令、实例操作指令、方法调用指令等等,多达256条;另一方面也是为了防止保护时间过长、避免程序冗余。理论上讲不存在不可模拟指令。采用多样性虚拟的保护方法,攻击者若想攻击该套保护方法,必须先行分析虚拟解释器和虚拟指令集的语义和逻辑,多样性加大逻辑分析难度,从而大大增加逆向分析的难度。

本实施例中,具体的示例为:我们以libdexvmp01.so的oncreate本地方法为例进行说明。如图3(a)所示,首先getobjectclass获取当前对象的类,getsuperclass获取当前对象的超类。然后通过getmethodid获取具有特定名称方法对应的标识符,getstaticfieldid获取相应静态字段的标识符。最后是执行实例方法,该jni方法是根据方法的返回值类型、关键字确定的。例如,callvoidmethod是执行返回值类型为void的实例方法调用例程。若为static关键字int类型方法,则调用callstaticintmethod。另外,在libdexvmp.so的执行过程中,我们以数据定义指令const_string的handler为例进行说明,该条指令功能是通过字符串索引构造一个字符串并赋给目的寄存器,如图3(b)所示。handle_opcode(),inst_aa(),fetch(),set_register(),finish(),op_end()是宏定义。其中,handle_opcode标志处理程序的开始.inst_aa、fetch获取当前虚拟指令的偏移地址。inst_aa用于获取当前函数处理虚拟指令的低8位中的高4位,fetch用于获得给定偏移的单个字节。同时,inst_a,inst_b等具有类似的功能。set_register表示以默认方式设置相应的虚拟寄存器值,set_register_double,set_regitster_wide,set_register_object根据参数类型设置寄存器的值。finish起到调度的功能,它控制解释器指向下一个处理程序。op_end表示当前指令处理结束。获取当前指令的偏移地址,根据字段索引获取到字符串。进行压栈操作,设置目的寄存器的值。

当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1