1.反编译apk高频出现指令
const/4 v1, #int 2 表示存入int型常量2到v1,目的寄存器在第二个自己的低4位,常量2在更高的4位。
const/16 v0, #int 10 表示存入int型常量10到v0中。
move-object/from16 v1, v21 表示将v21寄存器中的对象引用到v1上。
check-cast v4 Test3 检查v4寄存器中的对象引用是否可以转换为Test3的实例。
Instance-of v0, v4, Test3 检查V4寄存器中的对象引用是否是Test3的实例,如果是V0存入非0值,否则v0存入0。
array-length v0, v1 计算v1寄存器中数组引用的元素长度并将长度存入V0。
cmpl-float v0, v6, v7 比较v6和v7的float值,并在v0存入int型的返回值。非数值默认为小于,如果参数为非数值将返回-1。
cmpg-float v0, v6, v7 比较v6和v7的float值,并在v0存入int型的返回值。非数值默认为大于,如果参数为非数值将返回1。
age v7,v3,v6 从数组获取一个int型值到v7,对象数组的引用位于v3,需获取的元素的索引位于v6。
age-byte v0, v0,v1 从byte数组获取一个byte值到v0,数组的引用位于v0,徐获取的元素的的索引位于v1。
aput v0, v3,v5 将v0的int值作为元素存入int数组,数组的引用位于v3,元素的索引位于v5。
move-result v0 移动上一次方法调用的返回值到v0。
move-result-wide v2 移动上一次方法调用的long/double型返回值到v2,v3。
new-array v2,v1, char[] 新建一个char数组,v1存入数组的长度,v2存入数组的引用。
invoke-virtual{v4,v0,v1,v2,v3}, Test.method:(IIII)V 表示调用Test的method方法,该指令共有5个参数,参数v4是this实例,v0,v1,v2,v3 是method方法的参数,返回值为Void
sput-object v0, test3.os1:Ljava/lang/object 将v0寄存器中的对象引用赋值到Test3的对象引用静态字段os1上。
iget-object v1,v2, LineReader.fis:Ljava/io/FileInputStream 读取FileInputStream对象引用字段fis到v1,v2寄存器中是LineReader实例的引用。
invoke-direct, java.lang.object.:()V 表示java.lang.object 的方法,参数v1是this的实例,()V表示方法没有参数,v是返回值为void。
intvoke-direct{0}, Landroid/app/TabActivity;->()v 这里init()就是定义TabActivity中的一个private函数。
iput-object v0, v2,LineRader.bis:Ljava/io/BufferedInputStream 将V0寄存器的值存入实例的对象引用字段bis,v2寄存器中是BufferedInputStream实例的引用。
rem-int v0 v2,v3计算v3%v2并将结果存入v0
add-int/lit8 v0, v0, 0x1 表示 v0++的意思
2.高频的结构
.method public constructor ()V #这是class的构造函数实现。
.registers 1 #这个方法所使用的寄存器数量。
invoke-direct {p0}, Ljava/lang/Object;->()V#调用Object的构造方法,p0相当于"this" 指针。
invoke-virtual {p0}, Ljava/lang/Object;->toString()Ljava/lang/String;#调用toString()函数。
其中for循环跟while循环的识别方法是for循环的加加放在后面(add-int/lit8 v0, v0, 0x1),而while循环的加加放在判断语句的后面。
new-instance v5, Ljava/lang/StringBuilder; 表示新建一个临时的StringBuilder对象,并将其引用赋值给v5寄存器。
invoke-direct {v1}, Ljava/lang/StringBuilder;->()V 调用stringBuilder中的构造方法。
invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; 表示{v1, v2}大括号中v1寄存器中存储的是StringBuilder对象的引用,调用StringBuilder中的append(String, str)方法,v2寄存器则是参数寄存器。
3.反编译的出现高频语法数据解析
#创建StringBuilder对象,并将其引用赋值给v1寄存器 new-instance v1, Ljava/lang/StringBuilder;
#调用StringBuilder中的构造方法 invoke-direct {v1}, Ljava/lang/StringBuilder;->()V
#v2寄存器中赋值为ther result: const-string v2, "the result:" #{v1,v2}大括号中v1寄存器中存储的是StringBuilder对象的引用.
#调用StringBuilder中的append(String str)方法,v2寄存器则是参数寄存器. invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
#获取上一个方法的执行结果,此时v1中存储的是append()方法执行后的结果,此处之所以仍然返回v1的#原因在与append()方法返回的就是自身的引用 move-result-object v1
#继续调用append方法(),p0表示第一个参数寄存器,即上面提到的result参数 invoke-virtual {v1, p0}, Ljava/lang/StringBuilder;->append(I)Ljava/lang/StringBuilder;
#同上
move-result-object v1
#调用StringBuilder对象的toString()方法 invoke-virtual {v1}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
#获取上一个方法执行结果,toString()方法返回了一个新的String对象,因此v1中此时存储了String对象的引用 move-result-object v1
new-instance 表示java类中的new语句 例如: new-instance v1, Lcom/nd/tq/GameEntity; invoke-direct {v1}, Lcom/nd/tq/GameEntity;->()V iput-object v1, p0, Lcom/nd/tq/MainActivity;->entity:Lcom/nd/tq/GameEntity; java代码 entity =new GameEntity();
内部类格式:[外部类]内部类.smali,如果是匿名的内部类那么格式:[外部类]内部类.smali ,如果是匿名的内部类那么格式:[外部类]内部类.smali,如果是匿名的内部类那么格式:[外部类]NUM.smali。其中NUM代表从1开的数字。 对于Java文件中的每一个内部类,都会产生一个单独的smali文件,比如ActivityThread1.smali。这些文件的命名规范是如果是匿名内部类,则命名规则是外部类+1.smali。这些文件的命名规范是如果是匿名内部类,则命名规则是外部类+1.smali。这些文件的命名规范是如果是匿名内部类,则命名规则是外部类++数字,否则的话是外部类++内部类的名字例如:classOuterclassInner反编译上述代码后会生成两个文件:Outer.smali与Outer+内部类的名字 例如: class Outer { class Inner{} } 反编译上述代码后会生成两个文件:Outer.smali 与Outer+内部类的名字例如:classOuterclassInner反编译上述代码后会生成两个文件:Outer.smali与OuterInner.smali
静态方法中没有this指针,也就是p0不再是this指针,而是第一个参数, 非静态方法p0表示this指针。 invoke-virtual {p0} 这个p0就是this参数: invoke-virtual {p0}, Lcom/nd/tq/NDSecDataType;->toString()Ljava/lang/String; 这个表示 NDSecDataTyep.toString() invoke-static {p1} 这个p1表示具体的参数非this 。 invoke-static {p1}, Ljava/lang/Integer;->parseInt(Ljava/lang/String;)I 表示 Integer.parseInt(p1)
long和double型的值占用两个寄存器。例如:一个在v0寄存器的double值实际占用V0、v1两个寄存器。 boolean的值实际是转成int型的值进行操作,存储实际是1和0.
mov-object vx,vy:移动对象引用,从vy到vx。mov-result-wide vx 移动上一次方法调用的long/double型返回值到vx,vx+1。const-class vx,类型ID:存入类对象常量到vx,通过类型id或类型例如:const-class v0,test3 表示存入test3.class的引用到v0。check-cast vx,类型ID:检查vx寄存器中的对象引用是否可以转换城类型ID对应类型的实例。 如不可转换,抛出ClassCastException异常,否则继续执行。 check-cast vx4,test3 检查v4寄存器中的对象引用是否可以转换为test3的实例new-array vx,vy 根据类型id或者类型新建一个数组,vy存入数组的长度,vx存入数组的引用:例如 new-array v1,v2, char[]:表示 char v1[v2]
age开头的都跟数组获取有关系的 比如: aget vx,vy,vz 从int数组获取一个int型值到vx中,其中对象数组引用是vy,数组元素索引是vzage后面-跟的条件 只不过是获取值的对一个条件,比如 aget-object vx,vy,xz 表示的是从对象引用数组获取一个对象引用到vx,对象数组的的引用位于vy获取元素的索引位于vz。
aput开头的都跟数组存入有关系的的 比如: aput vx,vy,vz 表示将vx的int值作为元素存入int数组,数组的引用位于vy,元素的索引位于vz。
iget开头的对寄存器实例引用的赋值 比如: iget vx,vy,字段ID 根据字段ID读取实例的int型字段到vx,vy寄存器中是该实例的引用,例如: iget v0,v1 test2.i6:I表示读取int型字段i6到v0中,其中v1寄存器是test2实例的引用。iput开头的是将寄存器的值存入实例中:比如 iput vx,vy,字段ID 根据字段ID将Vx寄存器的值存入实例的int型字段,vy寄存器是该实例的引用。例如: iput v0,v2 test2.i6:I 将v0寄存器的值存入实例的int型字段i6,v2寄存器中是test2实例的引用。
sget开头的是读取静态相关字段信息 sget vx 字段ID 根据字段ID读取静态int型字段到vx sput开头的是将寄存器的值赋值到静态字段中。例如: sput vx,字段id 根据字段ID将vx寄存器中的值赋值到int型静态字段。
neg开头的表示相减的neg后面跟的是类型和寄存器 neg-int vx,vy 计算vx= -vy并将结果存入vx。
int-to-long vx,vy 转换vy寄存器中的int型值为long型值存入vx,vx+1 其中字段中间有个-to-的表示类型值的转换。
网络安全入门学习路线
其实入门网络安全要学的东西不算多,也就是网络基础+操作系统+中间件+数据库,四个流程下来就差不多了。
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】网络安全从入门到精通资料包,需要的小伙伴可以点击链接领取哦!