一文带你深入android的smali的指令解析
iget-object vAA,vBB,filed_id: 表示读取vAA寄存器中的对象中的filed_id对象的引用值给VBB寄存器。iget_boolean vAA,vBB,filed_id: 表示读取vAA寄存器中的对象中的filed_id的值给vBB寄存器。iget_wide vAA,vBB,filed_id :表示读取vAA寄存器中对象中的filed_id的值给vBB寄存器。iget v
1.普通字段读写操作
iget-object vAA,vBB,filed_id: 表示读取vAA寄存器中的对象中的filed_id对象的引用值给VBB寄存器。iget_boolean vAA,vBB,filed_id: 表示读取vAA寄存器中的对象中的filed_id的值给vBB寄存器。iget_wide vAA,vBB,filed_id :表示读取vAA寄存器中对象中的filed_id的值给vBB寄存器。 iget vAA,vBB,filed_id:表示vAA寄存器中对象的filed_id值给vBB寄存器。
iput-object vAA,vBB,filed_id:表示把vAA寄存器指向的对象的引用赋值给vBB寄存器中的filed_id。 iput-boolean vAA,vBB,filed_id:表示把vAA寄存器的值给vBB寄存器中的boolean类型。iput_wide vAA,vBB,filed_id:表示把vAA寄存器的值给vBB寄存器的wide类型。iput vAA,vBB,filed_id: 表示把vAA寄存器的值给vBB寄存器的int类型。
aget vx,vy,vz 表示从int数组获取一个int型的值到vx,对象数组的引用位于vy,需获取的元素的索引位于vz。age-wide vx,vy,vz 表示从long/double数组获取一个long/double值到vx,vx+1,数组的引用位于vy,需获取元素的索引位于vz。
2.静态字段的读写操作
sget-object vAA,vBB,filed_id: 表示读取vAA寄存器中的对象中的filed_id对象的引用值给VBB寄存器。sget_boolean vAA,vBB,filed_id: 表示读取vAA寄存器中的对象中的filed_id的值给vBB寄存器。sget_wide vAA,vBB,filed_id :表示读取vAA寄存器中对象中的filed_id的值给vBB寄存器。 sget vAA,vBB,filed_id:表示vAA寄存器中对象的filed_id值给vBB寄存器。
sput-object vAA,vBB,filed_id:表示把vAA寄存器指向的对象的引用赋值给vBB寄存器中的filed_id。sput-boolean vAA,vBB,filed_id:表示把vAA寄存器的值给vBB寄存器中的boolean类型。sput_wide vAA,vBB,filed_id:表示把vAA寄存器的值给vBB寄存器的wide类型。sput vAA,vBB,filed_id: 表示把vAA寄存器的值给vBB寄存器的int类型。
3.跳转指令
dalvik指令中有三种跳转指令:无条件跳转(goto),分支跳转(switch),条件跳转(if)
goto +AA:无条件跳转到指定偏移处,偏移量AA不能为0。
goto/16 +AAAA:无条件跳转到指定偏移处,偏量AAAA不能为0。
goto/32 +AAAAAAAA:无条件跳转到指定偏移处。
packed-switch vAA, +BBBBBBBB:分支跳转指令。vAA寄存器为switch分支中需要判断的值,BBBBBBBB指向一个packed-switch-payload格式的偏移表,表中的值是有规律递增的。
sparse-switch vAA, +BBBBBBBB:分支跳转指令。vAA寄存器为switch分支中需要判断的值,BBBBBBBB指向一个sparse-switch-payload格式的偏移表,表中的值是无规律的偏移量。
if-test vA, vB, +CCCC:条件跳转指令。比较vA寄存器与vB寄存器的值,如果比较结果满足就跳转到CCCC指定的偏移处。偏移量CCCC不能为0。
if-test类型的指令有以下几条:
if-eq:如果vA等于vB则跳转。Java语法表示为“if(vA == vB)”
if-ne:如果vA不等于vB则跳转。Java语法表示为“if(vA != vB)”
if-lt:如果vA小于vB则跳转。Java语法表示为“if(vA < vB)”
if-ge:如果vA大于等于vB则跳转。Java语法表示为“if(vA >= vB)”
if-gt:如果vA大于vB则跳转。Java语法表示为“if(vA > vB)”
if-le:如果vA小于等于vB则跳转。Java语法表示为“if(vA <= vB)”
if-testz vAA, +BBBB:条件跳转指令。拿vAA寄存器与0比较,如果比较结果满足或值为0时就跳转到BBBB指定的偏移处。偏移量BBBB不能为0。 if-testz类型的指令有以下几条:
if-eqz:如果vAA为0则跳转。Java语法表示为“if(vAA == 0)”
if-nez:如果vAA不为0则跳转。Java语法表示为“if(vAA != 0)”
if-ltz:如果vAA小于0则跳转。Java语法表示为“if(vAA < 0)”
if-gez:如果vAA大于等于0则跳转。Java语法表示为“if(vAA >= 0)”
if-gtz:如果vAA大于0则跳转。Java语法表示为“if(vAA > 0)”
if-lez:如果vAA小于等于0则跳转。Java语法表示为“if(vAA <= 0)”
4.比较指令
它的格式: cmpkind vAA, vBB, vCC :其中vBB寄存器与vCC寄存器是需要比较两个寄存器,比较结果放到vAA寄存器中。
Dalvik指令集共有5个比较指令 cmpl-float vAA, vBB, vCC: 比较两个单精度浮点数,如果vBB寄存器大于vCC寄存器,结果为-1,相等则结果为0,小于的话结果为1。cmpg-float vAA, vBB,vCC :比较两个单精度浮点数,如果vBB寄存器大于VCC寄存器,结果为1,相等结果为0,小于的话结果为-1。cmpl-double vAA, vBB,vCC: 比较两个双精度浮点数,如果VBB寄存器大于VCC寄存器,结果为-1,相等结果为0,小于的话为1。cmpg-double vAA, vBB,vCC: 比较两个双精度浮点数,如果VBB寄存器大于VCC寄存器,结果为1,相等结果为0,小于的话为-1。cmp-long vAA, vBB, vCC:比较两个长整型,如果vBB寄存器大于vCC寄存器,结果为1,相等结果为0,小于结果为-1。
5.数据转换指令
它的格式: unop vA,vB:vB寄存器转换到对应数据并将结果放到vA寄存器上。
.“neg-int”:对整型数求补。
.“not-int”:对整型数求反。
.“neg-long”:对长整型数求补。
.“not-long”:对长整型数求反
.“neg-float”:对单精度浮点型数求补。
.“neg-double”:对双精度浮点型数求补。
.“int-to-long”:将整型数转换为长整型。
.“int-to-float”:将整型数转换为单精度浮点型数。
.“int-to-dobule”:将整型数转换为双精度浮点数。
.“long-to-int”:将长整型数转换为整型。
.“long-to-float”:将长整型数转换为单精度浮点型。
.“long-to-double”:将长整型数转换为双精度浮点型。
.“float-to-int”:将单精度浮点数转换为整型。
.“float-to-long”:将单精度浮点数转换为长整型数。
.“float-to-double”:将单精度浮点数转换为双精度浮点型数。
.“double-to-int”:将双精度浮点数转换为整型。
.“double-to-long”:将双精度浮点数转换为长整型。
.“double-to-float”:将双精度浮点数转换为单精度浮点型。
.“int-to-byte”:将整型转换为字节型。
.“int-to-char”:将整型转换为字符型。
.“int-to-short”:将整型转换为短整型。
6.数据运行指令
数据运算指令包括算术运算指令与逻辑运算指令。算术运算指令主要进行数值间如加,减,乘,除,模,移位等运算。逻辑运算指令主要进行数值间与,或,非,抑或等运算。数据运算指令有如下四类(数据运算时可能是在寄存器或寄存器对间进行,下面的指令作用讲解时使用寄存器来描述):
.“binop vAA, vBB, vCC”:将vBB寄存器与vCC寄存器进行运算,结果保存到vAA寄存器。
.“binop/2addr vA, vB”:将vA寄存器与vB寄存器进行运算,结果保存到vA寄存器。
.“binop/lit16 vA, vB, #+CCCC”:将vB寄存器与常量 CCCC进行运算,结果保存到vA寄存器。
.“binop/lit8 vAA, vBB, #+CC”:将vBB寄存器与常量CC进行运算,结果保存到vAA寄存器。
后面3类指令比第1类指令分别多出了2addr,lit16,lit8等指令后缀。四类指令中基础字节码相同的指令执行的运算操作是类似的,第1类指令中,根据数据的类型不同会在基础字节码后面加上数据类型后缀,如 -int 或 -long 分别表示操作的数据类型为整型与长整型。
第1类指令可归类如下:
.“add-type”:vBB寄存器与vCC寄存器值进行加法运算(vBB + vCC)
.”sub-type”:vBB寄存器与vCC寄存器值进行减法运算(vBB - vCC)
.”mul-type”:vBB寄存器与vCC寄存器值进行乘法运算(vBB * vCC)
.”div-type”:vBB寄存器与vCC寄存器值进行除法运算(vBB / vCC)
.”rem-type”:vBB寄存器与vCC寄存器值进行模运算(vBB % vCC)
.”and-type”:vBB寄存器与vCC寄存器值进行与运算(vBB & vCC)
.”or-type”:vBB寄存器与vCC寄存器值进行或运算(vBB | vCC)
.”xor-type”:vBB寄存器与vCC寄存器值进行异或运算(vBB ^ vCC)
.”shl-type”:vBB寄存器值(有符号数)左移vCC位(vBB << vCC )
.”shr-type”:vBB寄存器值(有符号)右移vCC位(vBB >> vCC)
.”ushr-type”:vBB寄存器值(无符号数)右移vCC位(vBB >>> vCC)
7.方法调用指令
.invoke-virtual或 invoke-virtual/range调用实例的虚方法。 .invoke-super或”invoke-super/range调用实例的父类方法。 .invoke-direct或“invoke-direct/range调用实例的直接方法。 .invoke-static或invoke-static/range调用实例的静态方法。 .invoke-interface或invoke-interface/range调用实例的接口方法
8.异常处理指令
.throw vAA:抛出vAA寄存器中指定类型的异常。
9.返回指令
.return-void: 表示函数从一个void返回 .return vAA: 表示函数返回一个32位非对象类型的值,返回值寄存器为8位的寄存器vAA .return-wide vAA: 表示函数返回一个64位飞对象类型的值,反黑值为8位的寄存器对vAA .return-object vAA:表示函数返回一个对象类型的值,返回值为8位寄存器vAA。
10.数据操作指令
.move vA, vB:将vB寄存器的值赋给vA寄存器,A源寄存器与目的寄存器都为4位。.move/from16 vAA, vBBBB:将vBBBB寄存器的值赋给vAA寄存器,源寄存器为16位,目的寄存器为8位。.move/16 vAAAA, vBBBB:将vBBBB寄存器的值赋给vAAAA寄存器,源寄存器与目的寄存器都为16位。
.move-wide vA, vB:为4位的寄存器对赋值。源寄存器与目的寄存器都为4位。.move-wide/from16 vAA, vBBBB 与“move-wide/16 vAAAA, vBBBB”实现与“move-wide”相同。.move-object vA, vB:为对象赋值。源寄存器与目的寄存器都为4位。.move-object/from16 vAA, vBBBB:为对象赋值。源寄存器为16位,目的寄存器为8位。.move-object/16 vAA, vBBBB:为对象赋值。源寄存器与目的寄存器都为16位。
.move-result vAA:将上一个invoke类型指令操作的单字非对象结果赋给vAA寄存器。
.move-result-wide vAA:将上一个invoke类型指令操作的双字非对象结果赋给vAA寄存器。
.move-result-object vAA:将上一个invoke类型指令操作的对象结果赋给vAA寄存器。
.move-exception vAA:保存一个运行时发生的异常到vAA寄存器,这条指令必须是异常发生时的异常处理器的一条指令。否则的话,指令无效。
.registers指令指定了在这个方法中有多少个可用寄存器。.locals指明了在这个方法中非参寄存器的数量。
网络安全入门学习路线
其实入门网络安全要学的东西不算多,也就是网络基础+操作系统+中间件+数据库,四个流程下来就差不多了。
1.网络安全法和了解电脑基础
其中包括操作系统Windows基础和Linux基础,标记语言HTML基础和代码JS基础,以及网络基础、数据库基础和虚拟机使用等...
别被这些看上去很多的东西给吓到了,其实都是很简单的基础知识,同学们看完基本上都能掌握。计算机专业的同学都应该接触了解过,这部分可以直接略过。没学过的同学也不要慌,可以去B站搜索相关视频,你搜关键词网络安全工程师会出现很多相关的视频教程,我粗略的看了一下,排名第一的视频就讲的很详细。 当然你也可以看下面这个视频教程仅展示部分截图: 学到http和https抓包后能读懂它在说什么就行。
2.网络基础和编程语言
3.入手Web安全
web是对外开放的,自然成了的重点关照对象,有事没事就来入侵一波,你说不管能行吗! 想学好Web安全,咱首先得先弄清web是怎么搭建的,知道它的构造才能精准打击。所以web前端和web后端的知识多少要了解点,然后再学点python,起码得看懂部分代码吧。
最后网站开发知识多少也要了解点,不过别紧张,只是学习基础知识。
等你用几周的时间学完这些,基本上算是具备了入门合格渗透工程师的资格,记得上述的重点要重点关注哦! 再就是,要正式进入web安全领域,得学会web渗透,OWASP TOP 10等常见Web漏洞原理与利用方式需要掌握,像SQL注入/XSS跨站脚本攻击/Webshell木马编写/命令执行等。
这个过程并不枯燥,一边打怪刷级一边成长岂不美哉,每个攻击手段都能让你玩得不亦乐乎,而且总有更猥琐的方法等着你去实践。
学完web渗透还不算完,还得掌握相关系统层面漏洞,像ms17-010永恒之蓝等各种微软ms漏洞,所以要学习后渗透。可能到这里大家已经不知所云了,不过不要紧,等你学会了web渗透再来看会发现很简单。
其实学会了这几步,你就正式从新手小白晋升为入门学员了,真的不算难,你上你也行。
4.安全体系
不过我们这个水平也就算个渗透测试工程师,也就只能做个基础的安全服务,而这个领域还有很多业务,像攻防演练、等保测评、风险评估等,我们的能力根本不够看。
所以想要成为一名合格的网络工程师,想要拿到安全公司的offer,还得再掌握更多的网络安全知识,能力再更上一层楼才行。即便以后进入企业,也需要学习很多新知识,不充实自己的技能就会被淘汰。
从时代发展的角度看,网络安全的知识是学不完的,而且以后要学的会更多,同学们要摆正心态,既然选择入门网络安全,就不能仅仅只是入门程度而已,能力越强机会才越多。
尾言
因为入门学习阶段知识点比较杂,所以我讲得比较笼统,最后联合CSDN整理了一套【282G】网络安全从入门到精通资料包,需要的小伙伴可以点击链接领取哦!
更多推荐
所有评论(0)