您好,欢迎访问三七文档
当前位置:首页 > 中学教育 > 初中教育 > Smali语法学习与DEX文件详解
Smali语言学习笔记Smali语法学习与DEX文件详解什么是Smali语言Smali代码是Android的Dalvik虚拟机的可执行文件DEX文件反汇编后的代码。所以Smali语言就是Dalvik的反汇编语言。使用Apktool反编译apk文件后,会在反编译工程目录下生成一个smali文件夹,里面存放着所有反编译出的smali文件,这些文件会根据程序包的层次结构生成相应的目录,程序中所有的类都会在相应的目录下生成独立的smali文件。Smali语法格式可参考网址:=11179631.Dalvik字节码Davlik字节码中,寄存器都是32位的,能够支持任何类型,64位类型(Long/Double)用2个寄存器表示;Dalvik字节码有两种类型:原始类型;引用类型(包括对象和数组)原始类型:vvoid只能用于返回值类型ZbooleanBbyteSshortCcharIintJlong(64位)FfloatDdouble(64位)对象类型:Lpackage/name/ObjectName;相当于java中的package.name.ObjectName;解释如下:L:表示这是一个对象类型package/name:该对象所在的包;:表示对象名称的结束2.数组的表示形式:[I:表示一个整形的一维数组,相当于java的int[];对于多维数组,只要增加[就行了,[[I=int[][];注:每一维最多255个;对象数组的表示形式:[Ljava/lang/String表示一个String的对象数组;3.方法的表示形式:Lpackage/name/ObjectName;——methodName(III)Z;详解如下:Lpackage/name/ObjectName表示类型methodName表示方法名III表示参数(这里表示为3个整型参数)说明:方法的参数是一个接一个的,中间没有隔开;4.字段的表示形式:Lpackage/name/ObjectName;——FieldName:Ljava/lang/String;即表示:包名,字段名Smali语言学习笔记和各字段类型5.寄存器指定有两种方式指定一个方法中有多少寄存器是可用的:.registers指令指定了方法中寄存器的总数.locals指令表明了方法中非参寄存器的总数,出现在方法中的第一行6.方法的表示方法有直接方法和虚方法两种,直接方法的声明格式如下:.method访问权限[修饰关键字]方法原型.locals[.parameter][.prologue][.line]代码体.endmethod访问权限有public、private等,修饰关键字有static、constructor等。方法原型描述了方法的名称、参数与返回值。..registers指定了方法中寄存器的总数.locals指定了方法中非参寄存器的总数(局部变量的个数);.parameter指定了方法的参数;.prologue指定了代码的开始处;.line指定了该处指令在源代码中的位置。7.方法的传参:当一个方法被调用的时候,方法的参数被置于最后N个寄存器中;例如:一个方法有2个参数,5个寄存器(v0~v4),那么,参数将置于最后2个寄存器(v3和v4)。非静态方法中的第一个参数总是调用该方法的对象。说明:对于静态方法除了没有隐含的this参数外,其他都一样8.寄存器的命名方式:V命名P命名第一个寄存器就是方法中的第一个参数寄存器。比较:使用P命名是为了防止以后如果在方法中增加寄存器,需要对参数寄存器重新进行编号的缺点。特别说明一下:Long和Double类型是64位的,需要2个寄存器例如:对于非静态方法LMyObject——myMethod(IJZ)V,有4个参数:LMyObject,int,long,bool需要5个寄存器来存储参数:P0thisP1I(int)P2,P3J(long)P4Z(bool)Smali操作指令大全英文版在线地址:中文版的需要翻译。Smali语言学习笔记invoke-directInvokesamethodwithparameterswithoutthevirtualmethodresolution.直接调用使用参数直接调用一个方法(不使用虚拟方法解析)const/4vx,lit4、const/16vx,lit16Putsthe4bitconstantintovx将后四位/16位设为lit4/lit16iputvx,vy,field_idPutsvxintoaninstancefield.Theinstanceisreferencedbyvy写入将VX写入一个实例字段,这个实例字段由VY引用。(VY=VX)new-instancevx,typeInstantiatesanobjecttypeandputsthereferenceofthenewlycreatedinstanceintovx新建一个实例实例化一个对象,并将对象的格式设为type(新建一个type实例)iput-objectvx,vy,field_idPutstheobjectreferenceinvxintoaninstancefield.Theinstanceisreferencedbyvy.初始化对象将VX引用的对象写入一个实例字段,这个实例字段由VY引用。(用VX中的数据初始化VY)return-void返回voidconst-stringvx,string_idPutsreferencetoastringconstantidentifiedbystring_idintovx.字符常量将String_ID引用的字符常量赋予VXsget-objectvx,field_idReadstheobjectreferencefieldidentifiedbythefield_idintovx.读取对象将field_ID标示的字段读入VXinvoke-virtual{parameters},methodtocallInvokesavirtualmethodwithparameters.调用虚方法带参数调用一个虚方法DEX文件结构:文件头(FileHeader)Dex文件头主要包括校验和以及其他结构的偏移地址和长度信息。字段名称偏移值长度描述magic0x08'Magic'值,即魔数字段,格式如”dex/n035/0”,其中的035表示结构的版本。checksum0x84校验码。signature0xC20SHA-1签名。file_size0x204Dex文件的总长度。header_size0x244文件头长度,009版本=0x5C,035版本=0x70。endian_tag0x284标识字节顺序的常量,根据这个常量可以判断文件是否交换了字节顺序,缺省情况下=0x78563412。link_size0x2C4连接段的大小,如果为0就表示是静态连接。link_off0x304连接段的开始位置,从本文件头开始算起。如果连接段的大小为0,这里也是0。map_off0x344map数据基地址。string_ids_size0x384字符串列表的字符串个数。Smali语言学习笔记string_ids_off0x3C4字符串列表表基地址。type_ids_size0x404类型列表里类型个数。type_ids_off0x444类型列表基地址。proto_ids_size0x484原型列表里原型个数。proto_ids_off0x4C4原型列表基地址。field_ids_size0x504字段列表里字段个数。field_ids_off0x544字段列表基地址。method_ids_size0x584方法列表里方法个数。method_ids_off0x5C4方法列表基地址。class_defs_size0x604类定义类表中类的个数。class_defs_off0x644类定义列表基地址。data_size0x684数据段的大小,必须以4字节对齐。data_off0x6C4数据段基地址魔数字段魔数字段,主要就是Dex文件的标识符,它占用4个字节,在目前的源码里是“dex\n”,它的作用主要是用来标识dex文件的,比如有一个文件也以dex为后缀名,仅此并不会被认为是Davlik虚拟机运行的文件,还要判断这四个字节。另外Davlik虚拟机也有优化的Dex,也是通过个字段来区分的,当它是优化的Dex文件时,它的值就变成”dey\n”了。根据这四个字节,就可以识别不同类型的Dex文件了。跟在“dex\n”后面的是版本字段,主要用来标识Dex文件的版本。目前支持的版本号为“035\0”,不管是否优化的版本,都是使用这个版本号。检验码字段主要用来检查从这个字段开始到文件结尾,这段数据是否完整,有没有人修改过,或者传送过程中是否有出错等等。通常用来检查数据是否完整的算法,有CRC32、有SHA128等,但这里采用并不是这两类,而采用一个比较特别的算法,叫做adler32,这是在开源zlib里常用的算法,用来检查文件是否完整性。该算法由MarkAdler发明,其可靠程度跟CRC32差不多,不过还是弱一点点,但它有一个很好的优点,就是使用软件来计算检验码时比较CRC32要快很多。可见Android系统,就算法上就已经为移动设备进行优化了。Java中可使用java.util.zip.Adler32类做校验操作SHA-1签名字段dex文件头里,前面已经有了面有一个4字节的检验字段码了,为什么还会有SHA-1签名字段呢?不是重复了吗?可是仔细考虑一下,这样设计自有道理。因为dex文件一般都不是很小,简单的应用程序都有几十K,这么多数据使用一个4字节的检验码,重复的机率还是有的,也就是说当文件里的数据修改了,还是很有可能检验不出来的。这时检验码就失去了作用,需要使用更加强大的检验码,这就是SHA-1。SHA-1校验码有20个字节,比前面的检验码多了16个字节,几乎不会不同的文件计算出来的检验是一样的。设计两个检验码的目的,就是先使用第一个检验码进行快速检查,这样可以先把简单出错的dex文件Smali语言学习笔记丢掉了,接着再使用第二个复杂的检验码进行复杂计算,验证文件是否完整,这样确保执行的文件完整和安全。SHA(SecureHashAlgorithm,安全散列算法)是美国国家安全局设计,美国国家标准与技术研究院发布的一系列密码散列函数。SHA-1看起来和MD5算法很像,也许是RonRivest在SHA-1的设计中起了一定的作用。SHA-1的内部比MD5更强,其摘要比MD5的16字节长4个字节,这个算法成功经受了密码分析专家的攻击,也因而受到密码学界的广泛推崇。这个算法在目前网络上的签名,BT软件里就有大量使用,比如在BT里要计算是否同一个种子时,就是利用文件的签名来判断的。同一份8G的电影从几千BT用户那里下载,也不会出现错误的数据,导致电影不播放。map_off字段这个字段主要保存map开始位置,就是从文件头开始到map数据的长度,通过这个索引就可以找到map数据。map的数据结构如下:名称大小说明size4字节map里项的个数list变长每一项定义为12字节,项的个数由上面项大小决定。map数据排列结构定义如下:/**Direct-mappedmap_list.*/typedefstructDexMapList{u4size;/*#ofentriesinlist*/DexMapItemlist[1];/*entries*/}DexMapList;每一个map项的结构定义如下:/**Direct-mappedmap_item.*/typ
本文标题:Smali语法学习与DEX文件详解
链接地址:https://www.777doc.com/doc-3191024 .html