用户
搜索
  • TA的每日心情
    慵懒
    5 天前
  • 签到天数: 120 天

    连续签到: 1 天

    [LV.7]常住居民III

    i春秋作家

    推荐小组成员

    Rank: 7Rank: 7Rank: 7

    110

    主题

    260

    帖子

    579

    魔法币
    收听
    0
    粉丝
    16
    注册时间
    2017-7-24

    幽默灌水王突出贡献春秋文阁i春秋签约作者i春秋推荐小组积极活跃奖春秋游侠秦

    HAI_ i春秋作家 推荐小组成员 幽默灌水王 突出贡献 春秋文阁 i春秋签约作者 i春秋推荐小组 积极活跃奖 春秋游侠 秦 楼主
    发表于 2018-1-8 01:31:10 24503

    [TOC]

    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

    首先打开二进制文件,前四位魔数,4~8位版本号,8~10长度。从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或<init>方法;

    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.结束

    我是不是写的太啰嗦了,越学习越发现自己之前学的都不够用了。

    本帖被以下淘专辑推荐:

    破解的目的是为了更好的开发
    发表于 2018-1-9 10:35:58
    那个CSDN的地址失效了表哥
    使用道具 举报 回复
    发表于 2018-1-9 15:11:31
    破解的目的是为了更好的开发
    使用道具 举报 回复
    发新帖
    您需要登录后才可以回帖 登录 | 立即注册