BubblePig 发表于 2018-1-8 01:35

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

本帖最后由 BubblePig 于 2018-1-23 18:01 编辑


#0x00 前言
由于是对java语言的复习,所以进度会很快,而且会以smali为主,java只是顺便提一下,如果对java有兴趣详细研究的,可以下载pdf仔细的看。
这篇主要涉及到基本数据类型,int,float,char,以及运算。
链接:http://download.csdn.net/download/qq_36869808/10189220。
##下节链接:
Android逆向-java代码基础(3)
# 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进行编译,但是编译会出现一个问题。
![这里写图片描述](http://otufvq0ew.bkt.clouddn.com/%5BVHK%5DW$VSJ%291%60Q%5DJ@A44SRB.png-mylove)

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

解决方案:
用记事本打开java文件,另存为,编码选择ANSI即可解决。
![这里写图片描述](http://otufvq0ew.bkt.clouddn.com/V8%60QK%284~6RVUG6I%5BZX4J91C.png-mylove)
### 1.5 运行
![这里写图片描述](http://otufvq0ew.bkt.clouddn.com/SXZG6F5%25V9W4AN6UOL58IRD.png-mylove)
具体的使用方式,参考: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对应的类型图。
![这里写图片描述](http://otufvq0ew.bkt.clouddn.com/DCM~GCY4C$EW%7DCG%25$%7D2M30P.png-mylove)
接下来就边看二进制文件边进行分析了。
#### 1.6.2第一个cp_info
首先打开二进制文件,前四位魔数,4~8位版本号,8~10长度。从11开始就是第一个cp_info了。
首先是我们的tag标志:0A
![这里写图片描述](http://otufvq0ew.bkt.clouddn.com/C%251TR3Q%25DWP_JLN%5DZ_LDI%298.png-mylove)
这里我们根据上面的表进行判断类中的方法,cp_info的结构如下。
![这里写图片描述](http://otufvq0ew.bkt.clouddn.com/VPDOOBG21%25FXUU49K%7D8B@1R.png-mylove)
class_index: 00 0B,十进制就是11,这里应该提一下class_index的作用了。
class_index的作用就是指向CONSTANT_class_index,这里是11就是指向#11块。
顺便提一下,第一个cp_info就是#1
![这里写图片描述](http://otufvq0ew.bkt.clouddn.com/2NNHBQV%297KFMFQ%5DH%5BC%5B8%29%25Y.png-mylove)
name_and_type_index:00 14,十进制,20
name_and_type_index的作用就是指向CONSTANT_NameAndType_info。这里指向#20块
![这里写图片描述](http://otufvq0ew.bkt.clouddn.com/%29HSO0D%601SZ%5B%60WV2%29VN%29%5BL%25W.png-mylove)
最后总结下:

```
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的结构。
![这里写图片描述](http://otufvq0ew.bkt.clouddn.com/S5SP%7DJGQK$X5J4E$SFW8%5D%5D5.png-mylove)
感觉和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的结构。
![这里写图片描述](http://otufvq0ew.bkt.clouddn.com/BV9QG7YX@~ZX0G4K4K7%5BQ%291.png-mylove)
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的基本格式如下:
![这里写图片描述](http://otufvq0ew.bkt.clouddn.com/SS6%28W%7BB~B4%5D3H9F3BMHM4%7DC.png-mylove)
这里的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命令可以直接查看我们说的这些。
![这里写图片描述](http://otufvq0ew.bkt.clouddn.com/DU%291CVY5040UED@H%5BHJT%25%7B5.png-mylove)
这样就可以省很多时间,但是还是建议自己分析一下二进制文件进行测试。
###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文件的第一个段。
![这里写图片描述](http://otufvq0ew.bkt.clouddn.com/P%28C9HC2R4~S$%7D%28XARAXNW$F.png-mylove)
这段就是表示该类的不带参数缺省的构造方法,为main函数的传参做准备。
(2)然后最主要的就是这里的main函数里的内容了。
(3)先来看第一句。
![这里写图片描述](http://otufvq0ew.bkt.clouddn.com/3F9A3T_UMJ%7D%60@DIQ_%29S%7B_N8.png-mylove)

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 第二句分析
![这里写图片描述](http://otufvq0ew.bkt.clouddn.com/@X%5BHJ3A2%25U5A~EY%28DQQ~BP8.png-mylove)
新建一个StringBuilder 对象,new-instance
####1.7.2 第三句分析

![这里写图片描述](http://otufvq0ew.bkt.clouddn.com/X3@7LLHTG7HP%7D%28SGJ%60%7BUO%7DY.png-mylove)

invoke-direct:没有被覆盖方法的调用,即不用动态根据实例所引用的调用,编译时,静态确认的,一般是private或<init>方法;
#### 1.7.3 第四句分析
![这里写图片描述](http://otufvq0ew.bkt.clouddn.com/N9SXQWT$XCL1%5BU1IN31N8ZF.png-mylove)

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

这句话就是定义了一个寄存器用来存放这一串字符。
#### 1.7.4 第五句分析
![这里写图片描述](http://otufvq0ew.bkt.clouddn.com/%29Q64ZC6WELCQJ%25H3J7%60%5B5%28G.png-mylove)
invoke-virtual 虚方法调用,调用的方法运行时确认实际调用,和实例引用的实际对象有关,动态确认的,一般是带有修饰符protected或public的方法;
这里就是调用append方法,也就是拼接的意思。
####1.7.5第六句分析
![这里写图片描述](http://otufvq0ew.bkt.clouddn.com/_@WA460R%60TA%5BGSS8F%7D%28%25HG1.png-mylove)
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第七句分析
![这里写图片描述](http://otufvq0ew.bkt.clouddn.com/07K9L65%25KY_C$YA~JR~%25%5D1M.png-mylove)

```
invoke-virtual {v2, v0}, Ljava/lang/StringBuilder;->append(I)Ljava/lang/StringBuilder;
```
这句话就是调用append,连接v2和v0,v2就是上一个append的结果,v0就是数字520。
####1.7.7第八句分析
![这里写图片描述](http://otufvq0ew.bkt.clouddn.com/@Q_N%5DYIJ@801O16%29@%7D~G0%291.png-mylove)
上一句的结果给v0。
####1.7.8第九句分析
![这里写图片描述](http://otufvq0ew.bkt.clouddn.com/B0BB44%7DH@VT9Q87T~%60MYED2.png-mylove)
调用toString方法转化v0
####1.7.9第十一句分析
第十句很简单就是结果给了v0。
![这里写图片描述](http://otufvq0ew.bkt.clouddn.com/RARF7NH%28H_T$$E%7D_3SYK%298B.png-mylove)
调用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);//输出
      }
}
```
运行结果。
![这里写图片描述](http://otufvq0ew.bkt.clouddn.com/9OVF1_86Y%29FT%7DF%28DE%7D7N$6Q.png-mylove)
###2.4 class文件查看。
这里使用

```
javap -v floatbl
```

![这里写图片描述](http://otufvq0ew.bkt.clouddn.com/Z$037V9L%5DZ%60YWPU9G~7ISQW.png-mylove)
这里对比int型变量,发现多了一个东西就是
![这里写图片描述](http://otufvq0ew.bkt.clouddn.com/G67%7B$6DJ%60UEM%5DZD%5D1_171T1.png-mylove)
这里是为了给之后传参使用的存储数据的cp_info,为了更好的显示参数
### 1.5 smali文件查看
![这里写图片描述](http://otufvq0ew.bkt.clouddn.com/%7DZN$L5%5D%7B5XLR0%5B~5KNNTQ10.png-mylove)
我们对比一下float和int的smali代码,可以发现都有这一块的代码,我们猜测可能这就是每一个smali都有的一部分吧。在char的时候或许应该尝试一下自己写一个smali代码了。
![这里写图片描述](http://otufvq0ew.bkt.clouddn.com/K%5BB%60TP%28%7B~1K%5B$CM$%5BIGO3%5DS.png-mylove)
剩下的就非常简单了,在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);
      }
}
```
运行结果:
![这里写图片描述](http://otufvq0ew.bkt.clouddn.com/Q9ZP%5D_FE~N6%7DBN0OQP9E~97.png-mylove)
###3.4 class文件分析。
这里不赘述查看方式,和生成方式了。
![这里写图片描述](http://otufvq0ew.bkt.clouddn.com/3ZPO6FZ9%28EZ7E8%25%5D78%29%5B7PA.png-mylove)
这里是对常量池进行一个展示,有兴趣可以自己研究。
###3.5 smali文件分析。
先来看一下smali代码:
![这里写图片描述](http://otufvq0ew.bkt.clouddn.com/GH%7BUU2%28@E7%252%28HTWCGS5$YO.png-mylove)
这里面发现有一个地方不一样,全在图里,看图就好。
![这里写图片描述](http://otufvq0ew.bkt.clouddn.com/M%25%297$9XJ%25%5B%25IMVOS%25_Q%25_%7DR.png-mylove)
#0x03 结尾
##1.感悟
写博客会让你对一个只是更加的融会贯通,而且在写的同时也会进行思考,这对思路有一个提升,而且可以让你实战还有理论只是得到大幅度提升。
##2.结束
我是不是写的太啰嗦了,越学习越发现自己之前学的都不够用了。

BubblePig 发表于 2018-1-8 12:21

xwzj20170829 发表于 2018-1-8 03:07
这个是2 没找到1是哪个
就喜欢你这样啰嗦的 越详细越好

http://blog.csdn.net/qq_36869808/article/details/78986787

刮骨刀 发表于 2018-3-14 22:03

很详细谢谢楼主请问cp_info开始都是11位开始?而且是class文件吗?小白不是很懂请指导下谢谢

xwzj20170829 发表于 2018-1-8 03:07

这个是2 没找到1是哪个
就喜欢你这样啰嗦的 越详细越好   

hack_wangyu 发表于 2018-1-8 03:08

我是学java 的 但完全看不懂,,哈哈哈....

sdaza 发表于 2018-1-8 06:34

很详细。。

luli1111 发表于 2018-1-8 08:19

完全看不懂

影视专业 发表于 2018-1-8 08:29

很详细,不错不错:lol

岁月bm123 发表于 2018-1-8 08:40

可以可以这个应该学习一下

渊辰 发表于 2018-1-8 09:09

{:301_978:}很详细,但是有点看不懂

丶丿後宫 发表于 2018-1-8 09:15

学习了。谢大神

糖0穿 发表于 2018-1-8 12:00

很详细 但是我没有找到1的啊
页: [1] 2 3 4 5 6 7 8 9
查看完整版本: Android逆向-java代码基础(2)