Android逆向-java代码基础(2)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_36869808/article/details/78999010


#0x00 前言
由于是对java语言的复习,所以进度会很快,而且会以smali为主,java只是顺便提一下,如果对java有兴趣详细研究的,可以下载pdf仔细的看。
这篇主要涉及到基本数据类型,int,float,char,以及运算。
链接:http://download.csdn.net/download/qq_36869808/10189220。

0x01 java数据类型

1.int型变量

###1.1 int定义
###1.2 int赋值
###1.3 int型输出

public class intbl
{
	public static void main(String[] args)
	{
		int a;//int定义
		a=520;//int赋值
		System.out.println("a所存储的是:"+a);//int输出

	}
}

1.4编译

使用javac进行编译,但是编译会出现一个问题。
这里写图片描述

intbl.java:6: 错误: 编码GBK的不可映射字符
                System.out.println("a鎵?瀛樺偍鐨勬槸锛?"+a);
                                      ^
intbl.java:6: 错误: 编码GBK的不可映射字符
                System.out.println("a鎵?瀛樺偍鐨勬槸锛?"+a);
                                              ^
2 个错误

解决方案:
用记事本打开java文件,另存为,编码选择ANSI即可解决。
这里写图片描述

1.5 运行

这里写图片描述
具体的使用方式,参考:http://blog.csdn.net/qq_36869808/article/details/78986787
###1.6 class文件分析
class文件产生:具体的使用方式,参考:http://blog.csdn.net/qq_36869808/article/details/78986787

1.6.1常量池说明。

这篇主要分析的是常量池。
常量池是由常量池项(cp_info)组成的。
常量池项类似于结构体,主要有两个元素。一个是tag,还有一个是info[]数组。tag用来判定info[]数组的类型。下表是tag对应的类型图。
这里写图片描述
接下来就边看二进制文件边进行分析了。

1.6.2第一个cp_info

首先打开二进制文件,前四位魔数,48位版本号,810长度。从11开始就是第一个cp_info了。
首先是我们的tag标志:0A
这里写图片描述
这里我们根据上面的表进行判断类中的方法,cp_info的结构如下。
这里写图片描述
class_index: 00 0B,十进制就是11,这里应该提一下class_index的作用了。
class_index的作用就是指向CONSTANT_class_index,这里是11就是指向#11块。
顺便提一下,第一个cp_info就是#1
这里写图片描述
name_and_type_index:00 14,十进制,20
name_and_type_index的作用就是指向CONSTANT_NameAndType_info。这里指向#20块
这里写图片描述
最后总结下:

tag=10;//CONSTANT_Methodref_info
class_index=11;//CONSTANT_class_index
name_and_type_index;//CONSTANT_NameAndType_index

1.6.3第二个cp_info(#2)

首先是tag,tag的大小是09,十进制也是09。
意味着这个cp_info的类型是 CONSTANT_Fieldref_info。
首先来看下CONSTANT_Fieldref_info的结构。
这里写图片描述
感觉和CONSTANT_Methodref_info很相似。
总结一下:

tag=9;//CONSTANT_Fieldref_info
class_index=21;//#21
name_and_type_index=22;//#22

####1.6.3第三个cp_info(#3)
这个就直接分析了:
tag=07,对照表就是CONSTANT_Class_info。
那么看看CONSTANT_Class_info的结构。
这里写图片描述
name_index:00 17,十进制就是23。
总结:

tag=07;CONSTANT_Class_info
name_index:0017;#23

####1.6.4第四个cp_info(#4)
tag是0A,二进制10,之前分析过。CONSTANT_Methodref_info。

tag=0A;CONSTANT_Methodref_info
name_index=03;#3
name_and_type_index=14;#20

这里方法类指向了#3也就是我们第三个块,但是第三个的name_index,可能需要到#23块,才能够知道#3 name_index的值。
####1.6.5第五个cp_info
tag=08,十进制就是08。这里对应的类型就是CONSTANT_String_index。
CONSTANT_String_index的基本格式如下:
这里写图片描述
这里的string_index指向的是CONSTANT_utf8_index,其实就是String的内容。
总结:

tag=08;//CONTSTANT_String_index
string_index=018;#24

####1.6.6 第六个cp_info
tag=0A,又是CONSTANT_Methodref_index。不啰嗦了。

tag=0A;CONSTANT_Methodref_index
name_index=03;#3
name_and_type_index=19;#25

####1.6.7结束语
到这里有没有对常量池有一个理解。剩下的可以自己分析了。不过这里还有一个偷懒的方法,就是使用javap -v命令可以直接查看我们说的这些。
这里写图片描述
这样就可以省很多时间,但是还是建议自己分析一下二进制文件进行测试。
###1.7 smali语句
首先把class代码转换成dex,然后反编译成smali文件。具体看http://blog.csdn.net/qq_36869808/article/details/78986787即可。
然后反编译dex。生成smali文件。

.class public Lintbl;
.super Ljava/lang/Object;
.source "intbl.java"


# direct methods
.method public constructor <init>()V
    .registers 1

    .prologue
    .line 1
    invoke-direct {p0}, Ljava/lang/Object;-><init>()V

    return-void
.end method

.method public static main([Ljava/lang/String;)V
    .registers 5

    .prologue
    .line 5
    const/16 v0, 0x208

    .line 6
    sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream;

    new-instance v2, Ljava/lang/StringBuilder;

    invoke-direct {v2}, Ljava/lang/StringBuilder;-><init>()V

    const-string v3, "a\u6240\u5b58\u50a8\u7684\u662f\uff1a"

    invoke-virtual {v2, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v2

    invoke-virtual {v2, v0}, Ljava/lang/StringBuilder;->append(I)Ljava/lang/StringBuilder;

    move-result-object v0

    invoke-virtual {v0}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

    move-result-object v0

    invoke-virtual {v1, v0}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V

    .line 8
    return-void
.end method

(1)首先我们来看smali文件的第一个段。
这里写图片描述
这段就是表示该类的不带参数缺省的构造方法,为main函数的传参做准备。
(2)然后最主要的就是这里的main函数里的内容了。
(3)先来看第一句。
这里写图片描述

sget-object 就是用来获取变量值并保存到紧接着的参数的寄存器中。
前面需要该变量所属的类的类型,后面需要加一个冒号和该成员变量的类型,中间是“->”表示所属关系。
那么这句话的意思就是,System.out的值保存在寄存器v1中。out的类型是Ljava/io/PrintStream;PrintStream是打印输出流。

2018年1月7日15:57:35。要去写作业。先暂停一下吧。

2018年1月7日23:05:57。作业写完了,我的假期也就是要正式开始了。为了之后开始努力。

1.7.1 第二句分析

这里写图片描述
新建一个StringBuilder 对象, new-instance
####1.7.2 第三句分析

这里写图片描述

invoke-direct:没有被覆盖方法的调用,即不用动态根据实例所引用的调用,编译时,静态确认的,一般是private或方法;

1.7.3 第四句分析

这里写图片描述

const-string v3, "a\u6240\u5b58\u50a8\u7684\u662f\uff1a"

这句话就是定义了一个寄存器用来存放这一串字符。

1.7.4 第五句分析

这里写图片描述
invoke-virtual 虚方法调用,调用的方法运行时确认实际调用,和实例引用的实际对象有关,动态确认的,一般是带有修饰符protected或public的方法;
这里就是调用append方法,也就是拼接的意思。
####1.7.5第六句分析
这里写图片描述
Move the object result of the most recent invoke-kind into the indicated register. This must be done as the instruction immediately after an invoke-kindor filled-new-array whose (object) result is not to be ignored; anywhere else is invalid.
move-result-object 就是将上一条指令的结果存放在v2寄存器中。
####1.7.6第七句分析
这里写图片描述

invoke-virtual {v2, v0}, Ljava/lang/StringBuilder;->append(I)Ljava/lang/StringBuilder;

这句话就是调用append,连接v2和v0,v2就是上一个append的结果,v0就是数字520。
####1.7.7第八句分析
这里写图片描述
上一句的结果给v0。
####1.7.8第九句分析
这里写图片描述
调用toString方法转化v0
####1.7.9第十一句分析
第十句很简单就是结果给了v0。
这里写图片描述
调用System.out.println输出v0的结果。

2.float型变量

###2.1 定义
###2.2 赋值
###2.3 输出

public class floatbl
{
	public static void main(String[] args)
	{
		float a;//定义
		a=1.1f;//赋值
		System.out.println(a);//输出
	}
}

运行结果。
这里写图片描述
###2.4 class文件查看。
这里使用

javap -v floatbl

这里写图片描述
这里对比int型变量,发现多了一个东西就是
这里写图片描述
这里是为了给之后传参使用的存储数据的cp_info,为了更好的显示参数

1.5 smali文件查看

这里写图片描述
我们对比一下float和int的smali代码,可以发现都有这一块的代码,我们猜测可能这就是每一个smali都有的一部分吧。在char的时候或许应该尝试一下自己写一个smali代码了。
这里写图片描述
剩下的就非常简单了,在int的时候已经非常详细的介绍过来。可能之后也要对dex文件进行一个分析和研究。该走的路还有很长的一段。

3.char

###3.1定义
###3.2赋值
###3.3输出

public class charbl{
	public static void main(String[]args)
	{
		char a;
		a='a';
		System.out.println(a);
	}
}

运行结果:
这里写图片描述
###3.4 class文件分析。
这里不赘述查看方式,和生成方式了。
这里写图片描述
这里是对常量池进行一个展示,有兴趣可以自己研究。
###3.5 smali文件分析。
先来看一下smali代码:
这里写图片描述
这里面发现有一个地方不一样,全在图里,看图就好。
这里写图片描述
#0x03 结尾
##1.感悟
写博客会让你对一个只是更加的融会贯通,而且在写的同时也会进行思考,这对思路有一个提升,而且可以让你实战还有理论只是得到大幅度提升。
##2.结束
我是不是写的太啰嗦了,越学习越发现自己之前学的都不够用了。

没有更多推荐了,返回首页