3.安卓逆向-java语言控制流和数据类型

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动!

内容参考于:图灵Python学院

上一个内容:2.安卓逆向-初识java语言

上一个内容里写了编写java语言代码的环境搭建,也就是下载jdk和安装jdk和下载idea和安装idea和创建一个写java语言代码的项目,还写了几个简单的java代码示例

要强调一件事,现在写的是java基础,然后主线是app逆向不是java开发,所以java基础不会写的很细有些概念省略,写什么就记什么不要细想,记不住后面逆向的时候再练,所以这里的java基础只能保证逆向时可以看懂代码可以看懂代码做了一件什么事情

接下来继续认识java语言

首先是一个逻辑运算符

如下图,现在只需要看一遍就行,后面通过java代码来理解它们

java 复制代码
public class Test {
public static void main(String[] args) {
  boolean a = true;
  boolean b = false;
  System.out.println("a && b = " + (a && b));
  System.out.println("a || b = " + (a || b) );
  System.out.println("!(a && b) = " + !(a && b));
}
}

true表示满足,false表示不满足

条件运算符:

示例:

java 复制代码
public class Test {
public static void main(String[] args){
 int a , b;
 a = 10;
 /**
 	 (a == 1) ? 20 : 30;是固定写法
 	 意思是 如果 a 等于 1 成立,则设置 b 为 20,否则为 30
 	 (a == 1)这样 == 表示a的值是否等于1,这里如果是等于就是true不等于就是
 	 false 也就是这里不能说等于要说满足不满足
 */ 
 b = (a == 1) ? 20 : 30;
 System.out.println( "Value of b is : " +  b );

 /**
 	 (a == 10) ? 20 : 30;是固定写法
 	 意思是 如果 a 等于 10 成立,则设置 b 为 20,否则为 30
 */
 b = (a == 10) ? 20 : 30;
 System.out.println( "Value of b is : " + b );
}
}

运行结果

条件语句:

示例:用来控制代码的走向

java 复制代码
int num = 10;

if (num > 0) {
 System.out.println("这个数是正数");
} else {
 System.out.println("这个数不是正数");
}

运行结果:

然后这个if和else还可以有如下的写法

java 复制代码
int score = 85;

if (score >= 90) {
 System.out.println("优秀");
} else if (score >= 80) {
 System.out.println("良好");
} else if (score >= 60) {
 System.out.println("及格");
} else {
 System.out.println("不及格");
}

运行结果:

循环:

循环就是字面意思,实际效果就是多次执行一段代码

示例:只要写了while这个单词就说明这是一个循环

java 复制代码
public class Hello {

 public static void main(String[] args) {
     int count = 0;
     /**
         * count < 3是循环的条件,只要满足它就会一直执行
         *      System.out.println("执行中..."+count);
         *      count += 1;
         *      这两段代码
         */
        while (count < 3) {
            System.out.println("执行中..."+count);
            count += 1;
        }
    }
}

运行效果:

java语言中有多种循环上面是第一种

还有一个do..while循环,这个循环不管满足不满足都会执行一次

示例:

c++ 复制代码
public class Hello {
    public static void main(String[] args) {

        int count = 0;
        do {
            System.out.println("执行中...");
            count += 1;
        } while (count < 3);

    }
}

运行结果:

然后还有一个for循环

java 复制代码
public class Hello {

    public static void main(String[] args) {

		// i++ 先赋值在运算
        //++i 先运算在赋值
        for (int i = 0; i < 10; i++) {
            System.out.println("哈哈哈");
        }

    }
}

运行结果:

for循环示例2:

java 复制代码
public class Hello {

    public static void main(String[] args) {

        /***
         * nameList变量是一个String类型的数组,String是字符串类型,字符串就是一
         	段文字
         * 下方它就有4段文字分别是苏苏、菲菲、莹莹、丽丽
         */
        String[] nameList = {"苏苏", "菲菲", "莹莹", "丽丽"};
        // nameList.length   4
        // nameList[0]
        /**
         * nameList.length的值是nameList它里面有几段文字
         * nameList[0]这样是取出第一段文字也就是苏苏
         * nameList[1]这样是取出第二段文字也就是菲菲
         * nameList[2]这样是取出第三段文字也就是莹莹
         * nameList[3]这样是取出第四段文字也就是丽丽
         */
        for (int idx = 0; idx < nameList.length; idx++) {
            String ele = nameList[idx];
            System.out.println(ele);
        }
    }
}

运行结果:

结束循环:

结束循环的方式有两种一种是break、一种continue,break意思是结束循环,continue意思是结束本次循环进入下一次循环

break示例:

java 复制代码
import java.util.Scanner;

public class d1 {
 public static void main(String[] args) {
     /***
         * nameList变量是一个String类型的数组,String是字符串类型,字符串就是一
         段文字
         * 下方它就有4段文字分别是苏苏、菲菲、莹莹、丽丽
         */
        String[] nameList = {"苏苏", "菲菲", "莹莹", "丽丽"};
        // nameList.length   4
        // nameList[0]
        /**
         * nameList.length的值是nameList它里面有几段文字
         * nameList[0]这样是取出第一段文字也就是苏苏
         * nameList[1]这样是取出第二段文字也就是菲菲
         * nameList[2]这样是取出第三段文字也就是莹莹
         * nameList[3]这样是取出第四段文字也就是丽丽
         */
        for (int idx = 0; idx < nameList.length; idx++) {
            String ele = nameList[idx];
            if (ele == "莹莹"){
                break;
            }
            System.out.println(ele);
        }
    }

}

运行结果:

continue示例:

java 复制代码
import java.util.Scanner;

public class d1 {
    public static void main(String[] args) {
        /***
         * nameList变量是一个String类型的数组,String是字符串类型,字符串就是一段文字
         * 下方它就有4段文字分别是苏苏、菲菲、莹莹、丽丽
         */
        String[] nameList = {"苏苏", "菲菲", "莹莹", "丽丽"};
        // nameList.length   4
        // nameList[0]
        /**
         * nameList.length的值是nameList它里面有几段文字
         * nameList[0]这样是取出第一段文字也就是苏苏
         * nameList[1]这样是取出第二段文字也就是菲菲
         * nameList[2]这样是取出第三段文字也就是莹莹
         * nameList[3]这样是取出第四段文字也就是丽丽
         */
        for (int idx = 0; idx < nameList.length; idx++) {
            String ele = nameList[idx];
            if (ele == "莹莹"){
                continue;
            }
            System.out.println(ele);
        }
    }

}

运行结果:

数据类型:

java语言里的数据类型分两类:基本数据类型 和 引用数据类型

java语言里的基本数据类型:byte、short、int、long、float、double、char、boolean

byte,字节 【1字节】表示范围:-128 ~ 127 即:-2^7 ~ 2^7 -1

short,短整型 【2字节】表示范围:-32768 ~ 32767

int,整型 【4字节】表示范围:-2147483648 ~ 2147483647

long,长整型 【8字节】表示范围:-9223372036854775808 ~ 9223372036854775807 最小负数到最大值

示例:

java 复制代码
public class Hello {

    public static void main(String[] args) {
        byte v1 = 32;
        short v2 = 10000;
        int v3 = 22221331;
        long v4 = 554534353424L;// long类型后面要加一个L
    }
}

这里补充一个编码的知识,电脑中只能存放二进制数怎么就能显示中文了?它是有一个编码表Windows的中文编码表是GBK,GBK编码一个文字是两个数字组成,但一般通用的是UTF-8(UTF8)编码,UTF8编码一个文字由三个数字组成,下方以UTF-8编码为例

java 复制代码
v1 = "夏洛"// 这是一个字符串,在逆向的时候它可能就直接显示中文了,但是也可能显示下方的数字,一个文字由3个数字组成,这个数字是编码表里文字所在的序号
v2 = [-27, -92, -113, -26, -76, -101]// 这6个数字就是夏洛这俩字的编码(所在编码表里的序号),所以这六个数字实际上和上面直接写夏洛是一样的,作用就是为了让我们不好分析的

编码转换

java 复制代码
import java.util.Arrays;

public class Demo {
    public static void main(String[] args) {
        // 1.字节数组(转换为字符串) [字节,字节,字节]
        byte[] dataList = {97, 105, 100, 61, 50, 52, 54, 51, 56, 55, 53, 55, 49, 38, 97, 117, 116, 111, 95, 112, 108, 97, 121, 61, 48, 38, 99, 105, 100, 61, 50, 56, 57, 48, 48, 56, 52, 52, 49, 38, 100, 105, 100, 61, 75, 82, 69, 104, 69, 83, 77, 85, 74, 104, 56, 116, 70, 67, 69, 86, 97, 82, 86, 112, 69, 50, 116, 97, 80, 81, 107, 55, 87, 67, 104, 67, 74, 103, 38, 101, 112, 105, 100, 61, 48, 38, 102, 116, 105, 109, 101, 61, 49, 54, 50, 55, 49, 48, 48, 57, 51, 55, 38, 108, 118, 61, 48, 38, 109, 105, 100, 61, 48, 38, 112, 97, 114, 116, 61, 49, 38, 115, 105, 100, 61, 48, 38, 115, 116, 105, 109, 101, 61, 49, 54, 50, 55, 49, 48, 52, 51, 55, 50, 38, 115, 117, 98, 95, 116, 121, 112, 101, 61, 48, 38, 116, 121, 112, 101, 61, 51};
        String dataString = new String(dataList);
        System.out.println("字符串是:" + dataString);

        // 2.字符串->字节数组
        try {
            /*
            Python中的  name.encode("gbk") 
            string = "夏洛"
            byte_list = list(string.encode("gbk"))
            signed_byte_list = [byte if byte < 128 else byte - 256 for byte in byte_list]
            print(signed_byte_list)
            */
            
            String name = "夏洛";
            byte[] v1 = name.getBytes("GBK");// GBK编码一个中文由两个数字组成
            System.out.println(Arrays.toString(v1)); //[-49, -60, -62, -27]
		
            // Python中的  name.encode("utf-8")
            byte[] v2 = name.getBytes("UTF-8");// UTF8编码一个中文由三个数字组成
            System.out.println(Arrays.toString(v2)); // [-27, -92, -113, -26, -76, -101]
        } catch (Exception e) {

        }
    }

}

运行结果:

引用类型:引用类型有很多,概念很抽象,现在这样理解 只要不是基本数据类型它就是引用类型

String就是一个引用类型,实例:下方的例子是通过构造函数来创建的字符串,不要关心构造函数是什么,先记着这俩字,后面会写

java 复制代码
import java.io.UnsupportedEncodingException;

public class Hello {

    public static void main(String[] args) throws UnsupportedEncodingException {
        String v1 = "夏洛";// 会默认有一个new String("夏洛")
        // 用构造函数创建字符串:
        String v2 = new String("夏洛");// 与 String v1 = "夏洛";一样
        String v4 = new String(new byte[]{-27, -92, -113, -26, -76, -101});// 默认utf8编码
        String v5 = new String(new byte[]{-49, -60, -62, -27}, "GBK");
        String v6 = new String(new char[]{'夏', '洛'}) ;
    }
}

处理字符串的函数

java 复制代码
public static void  demo2(){
    String origin = "请叫我靓仔AA";

    int len = origin.length();  // 长度
    for (int i = 0; i < len; i++) {
        char item = origin.charAt(i);
    }
    String v2 = origin.trim(); // 去除空白
    String v3 = origin.toLowerCase(); // 小写
    String v4 = origin.toUpperCase(); // 大写
    String[] v5 = origin.split("我"); // 分割
    String v6 = origin.replace("叫", "喊"); // 替换
    String v7 = origin.substring(2, 6);  // 子字符串=切片 [2:6]
    boolean v8 = origin.equals("请叫我"); // origin的值是一个字符串,equals的意思是origin的值是不是跟 请叫我 这三个字相等
    boolean v9 = origin.contains("el");// origin中是否包含el这俩字
    boolean v10 = origin.startsWith("请");
    String v11 = origin.concat("哈哈哈"); 
}

拼接字符串,就是多个文字进行合并

在java语言中字符串合并是通过StringBuilder类型或StringBuffer类型合并的,StringBuilder类型或StringBuffer类型它俩用法都一样,区别一句两句写不明白现记着StringBuilder类型或StringBuffer类型它俩用法都一样就行,String和它俩的区别,String a = "ass"; 这样就会发现如果还有个文字bbb,怎么放到a里?没办法放,想放就不能用String类型要使用StringBuilder类型或StringBuffer类型,它们俩有一个append函数,这个函数可以做合并操作

追加字符串:通过 append() 方法将字符串追加到 StringBuilder 的末尾。

  1. 插入字符串:使用 insert() 方法在指定位置插入字符串。
  2. 替换字符串:使用 replace() 方法替换指定范围内的字符串。
  3. 删除字符串:通过 delete() 方法删除指定范围内的字符。
  4. 反转字符串:使用 reverse() 方法将字符串反转。
  5. 获取字符串长度:通过 length() 方法获取当前字符串的长度。
  6. 转换为字符串:使用 toString() 方法将 StringBuilder 对象转换为普通字符串,也就是转成String类型字符串。
  7. 逆向的时候一般用来把请求参数和请求头拼接再一起进行加密
java 复制代码
import java.io.UnsupportedEncodingException;

public class Hello {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder();  // StringBuffer线程安全
        sb.append("name");
        sb.append("=");
        sb.append("xialuo");
        sb.append("&");
        sb.append("age");
        sb.append("=");
        sb.append("18");
        String dataString = sb.toString();
        System.out.println(dataString);
    }
}

运行结果:

数组:

数组可以理解一块内存空间,内存空间的大小由数组个数组成,这种一般称为容器

java 复制代码
import java.util.Arrays;

public class Hello {

    public static void main(String[] args) {
        /**
        	 int[] numArray = new int[3]; 数组声明,数组个数是3个
        	 个数是固定的声明了3个数组就只能放三个数据,多了不行
        */
        int[] numArray = new int[3];
        numArray[0] = 123;// 给数组中第一个位置赋值
        numArray[1] = 1;// 给数组中第二个位置赋值
        numArray[2] = 99;// 给数组中第三个位置赋值
        System.out.println(Arrays.toString(numArray));
			
        // 定义和初始化数组
        String[] names = new String[]{"夏洛", "aa", "bb"};
        System.out.println(Arrays.toString(names));
        
        String[] nameArray = {"夏洛", "aa", "bb"};	
        System.out.println(Arrays.toString(nameArray));
		
        // nameArray[0]
        // nameArray.length
        for (int idx = 0; idx < nameArray.length; idx++) {
            String item = nameArray[idx];
        }

    }
}

Object类

在java中所有引用类型都默认继承自Object类,不需要手动继承Object类它会自己隐藏式的继承Object类,类就是类型的意思,也就是java中所有引用类型都可以是Object类型

java 复制代码
import java.util.Arrays;

public class Hello {

    public static void main(String[] args) {
 		// String 使用 Object类型接收
        Object v1 = new String("xialuo");
        System.out.println(v1);
        System.out.println(v1.getClass());
		
        Object v2 = 123;
        System.out.println(v2);
        System.out.println(v2.getClass());
    }
}

实例2:

java 复制代码
import java.util.Arrays;

public class Hello {

    public static void main(String[] args) {
        // 声明数组,数组中元素必须int类型;
        int[] v1 = new int[3];

        // 声明数组,数组中元素必须String类型;
        String[] v2 = new String[3];

        // 声明数组,数组中可以是数组中存储任何类型的对象
        Object[] v3 = new Object[3];
        v3[0] = 123;// 这里的123是Integer类型,Integer类型本质是int这个基本类型,Integer和int会隐藏式的转换所以用起来会感知不到这件事
        v3[1] = "xialuo";

    }
}

如果Object的字符串想使用String类型里的函数:

java 复制代码
import java.util.Arrays;

public class Hello {

    public static void main(String[] args) {
        // v1是指上字符串对象;String
        String v1 = new String("xialuo");
        String res = v1.toUpperCase();
        System.out.println(res);

        // v2本质是字符串对象;Object
        Object v2 = new String("xialuo");
        String data = (String)v2; // (String)v2表示把v2这个Object类型强制转换成String类型
    }
}

对于类型进行判断:使用 instanceof 单词就可以比较两个数据类型是否一样了

java 复制代码
import java.util.Arrays;

public class Hello {

    public static void func(Object v1) {
        // aaaa 会进入到这里,然后往下执行,执行完再返回到 bbbb
        // System.out.println(v1);
        // System.out.println(v1.getClass());
        if (v1 instanceof Integer) {
            System.out.println("整型");
        } else if (v1 instanceof String) {
            System.out.println("字符串类型");
        } else {
            System.out.println("未知类型");
        }
    }

    public static void main(String[] args) {
        func(123);// 这里运行了会进入到 aaaa
		// 返回到 bbbb
        func("123"); 
    }
}

常用的引用类型

List类型,List是一个规范,java中ArrayList类型和LinkedList类型实现了这个规范,所以要使用List时要用ArrayList类型 或 LinkedList类型

List类型实际上是一个无限制的数组(比如它刚开始创建10个数组,然后10个数组用完了它会重新创建一个大于10的数组),它数组的大小取决于内存的大小

实例:

java 复制代码
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
/**
 * ArrayList和LinkedList查询和插入时间
 */
public class ListTest {
    public static void main(String[] args) {
        /**
	        <Integer>表示要存放Integer类型
	        如果不写<XX>这个东西默认存放Object类型,也就是任意类型数据
        */ 
        ArrayList<Integer> arrayList = new ArrayList<Integer>();
        LinkedList<Integer> linkedList = new LinkedList<Integer>();
        //插入十万数据
        for (int i = 0; i < 100000; i++) {
            arrayList.add(i);// add函数用来添加数据
            linkedList.add(i);
        }
        //记录时间
        //System.out.println("array查询时间:"+gettime(arrayList));
        //System.out.println("linked查询时间:"+gettime(linkedList));
        System.out.println("array插入时间:"+inserttime(arrayList));
        System.out.println("linked插入时间:"+inserttime(linkedList));


    }
    //插入数据
    private static long inserttime(List<Integer> list) {
        long number = 10000;//插入的数据量   10000  50000  80000
        int index = 10000;//从哪里开始插入   100   1000   10000
        long time = System.currentTimeMillis();
        for (int i = 0; i < number; i++) {
            list.add(index,i);
        }
        return System.currentTimeMillis()-time;
    }

    //查询数据
    public static long gettime(List<Integer> list){
        long time = System.currentTimeMillis();
        for (int i = 0; i < 100000; i++) {
            //根据索引值找到对应索引
            int search = Collections.binarySearch(list, list.get(i));//list.get(0)表示获取第一个数据list.get(2)表示获取第三个数据
            if (search!=i){
                System.out.println("索引值错误!");
            }
        }
        return System.currentTimeMillis()-time;
    }
}

上方的代码不全,只有手写的代码

完整代码:以 它的代码为基础进行修改

链接:百度网盘 请输入提取码

提取码:q9n5

复制这段内容后打开百度网盘手机App,操作更方便哦


相关推荐
励志成为嵌入式工程师7 分钟前
c语言简单编程练习9
c语言·开发语言·算法·vim
捕鲸叉37 分钟前
创建线程时传递参数给线程
开发语言·c++·算法
A charmer42 分钟前
【C++】vector 类深度解析:探索动态数组的奥秘
开发语言·c++·算法
Peter_chq44 分钟前
【操作系统】基于环形队列的生产消费模型
linux·c语言·开发语言·c++·后端
Yaml41 小时前
Spring Boot 与 Vue 共筑二手书籍交易卓越平台
java·spring boot·后端·mysql·spring·vue·二手书籍
小小小妮子~1 小时前
Spring Boot详解:从入门到精通
java·spring boot·后端
hong1616881 小时前
Spring Boot中实现多数据源连接和切换的方案
java·spring boot·后端
aloha_7892 小时前
从零记录搭建一个干净的mybatis环境
java·笔记·spring·spring cloud·maven·mybatis·springboot
记录成长java2 小时前
ServletContext,Cookie,HttpSession的使用
java·开发语言·servlet
前端青山2 小时前
Node.js-增强 API 安全性和性能优化
开发语言·前端·javascript·性能优化·前端框架·node.js