吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 3076|回复: 21
收起左侧

[Android CTF] 2024吾爱红包题逆向初级、中级难度复现

[复制链接]
wenwenjiang 发表于 2024-3-23 17:05

前言

过年的时候忘了,没打.......现在来复现复现 应该还是可以学到很多东西的
被and中级题搞到心态了

Windows

【2024春节】初级题1

img

找到输入的函数,flag的长度大概是36位

111111111111111111111111111111111111

直接动调出来了,flag在v7

img

fl@g{H@ppy_N3w_e@r!2o24!Fighting!!!}

Android

【2024春节】初级题1

难度不高,秒的题

img

在吾爱经常玩的小猫游戏,当然可以直接玩通关,但是出于逆向,还是逆一下吧

img

extractDataFromFile()方法就是游戏通关之后拿到的flag函数,是在后一个文件下进行检索 flag{ 字符然后输出到 } 字符,应该是上面的一个mp4的视频,flag应该在哪个文件十六进制的末尾处

img

hook代码

Java.perform(function () {
    var YSQDActivity = Java.use("com.zj.wuaipojie2024_1.YSQDActivity");
    var mmm = YSQDActivity.extractDataFromFile("/data/user/0/com.zj.wuaipojie2024_1/files/ys.mp4")
    console.log("返回结果是:",mmm)
});

getflag:flag{happy_new_year_2024}

【2024春节】初级题2

也是一个类似的游戏题,达成某种条件后就可以getflag 这种题有一个通解就跟windows端的keypatch一样修改代码逻辑、数值从而达到想要的效果。下面是题目原图.....原神含量好足(虽然没玩过

img

简单分析一下函数的逻辑,反正就是真·保底......

img

再看一下flag生成的部分:

img

所以大体函数分析完成,之后就是如何getflag

1、可以直接去修改爆率或者判断的smile代码直接get flag 注意不要改签名信息就好

2、找到签名信息然后自己去异或 getflag

我就偏向于第一种吧,但是也先简单说说第二组。签名信息存储在main-inf的文件夹下的一个.rsa文件中,用ida查看16进制信息即可

img

mt做法:

0x50对应的是80,也就是上面的概率(假概率)本来是从80开始减,直接改成0,相当于直接百分百得到flag

img

在修改保存的时候一定不要自动签名,不然会改变签名信息导致flag错误

img

可以关掉签名校验安装,当然直接安也没什么问题

img

然后一次直接拿到flag,还是可以的

img

另外看佬的wp,发现了可以直接运行指定的activity

adb shell su -c am start-activity -n com.kbtx.redpack_simple/.FlagActivity

img

直接弹flag的activity了,两个初级题同理直接秒了

【2024春节】中级题

打开apk运行一下,是一个类似于锁屏的一个控件

img

img

下面是正己师傅对于这段代码的详细解读,非常的详细

public boolean checkPassword(String str) {
    try {
        // 打开assets目录下的"classes.dex"文件作为InputStream
        InputStream open = getAssets().open("classes.dex");
        // 创建一个字节数组,大小为可读取的字节数,即整个文件的大小
        byte[] bArr = new byte[open.available()];
        // 从InputStream中读取数据到字节数组中
        open.read(bArr);
        // 创建一个指向应用的内部目录("data"目录)中的"1.dex"文件的File对象
        File file = new File(getDir("data", 0), "1.dex");
        // 创建一个向该文件写入数据的FileOutputStream
        FileOutputStream fileOutputStream = new FileOutputStream(file);
        // 将字节数组bArr的内容写入到"1.dex"文件中
        fileOutputStream.write(bArr);
        // 关闭文件输出流
        fileOutputStream.close();
        // 关闭文件输入流
        open.close();
        // 使用DexClassLoader加载"1.dex"文件,并调用其中一个类的静态方法
        // "com.zj.wuaipojie2024_2.C"是类的全路径名
        // "isValidate"是方法名,它接收一个Context对象,一个String对象和一个int数组作为参数
        // 调用方法并传入当前Context(this),密码字符串str,以及一个从资源数组R.array.A_offset中获取的int数组
        String str2 = (String) new DexClassLoader(file.getAbsolutePath(), 
                                                  getDir("dex", 0).getAbsolutePath(), 
                                                  null, 
                                                  getClass().getClassLoader())
                                    .loadClass("com.zj.wuaipojie2024_2.C")
                                    .getDeclaredMethod("isValidate", Context.class, String.class, int[].class)
                                    .invoke(null, this, str, getResources().getIntArray(R.array.A_offset));
        // 检查返回的字符串是否为null或者不以"唉!"开头
        if (str2 == null || !str2.startsWith("唉!")) {
            // 如果是,则认为密码检查失败
            return false;
        }
        // 如果密码检查成功,则更新UI组件tvText的文本为返回的字符串,并将myunlock组件设为不可见
        this.tvText.setText(str2);
        this.myunlock.setVisibility(8);
        // 返回true表示密码检查成功
        return true;
    } catch (Exception e) {
        // 捕获到异常,打印异常堆栈信息,并返回false表示密码检查失败
        e.printStackTrace();
        return false;
    }
}

public static String isValidate(Context context, String str, int[] iArr) throws Exception {
    try {
        // 尝试从动态加载的DEX中获取并调用静态方法
        // getStaticMethod是一个自定义方法,用于根据给定参数动态获取特定的静态方法
        // 参数包括上下文(context),一个整型数组(iArr),类的全名("com.zj.wuaipojie2024_2.A"),方法名("d"),以及该方法的参数类型(Context.class, String.class)
        // 该方法预期返回一个Method对象,该对象代表了一个静态方法,可以被调用
        // invoke方法用于执行这个静态方法,传入的参数为null(因为是静态方法,所以不需要实例),上下文(context)和字符串(str)
        // 方法执行的结果被强制转换为String类型,并作为isValidate方法的返回值
        return (String) getStaticMethod(context, iArr, "com.zj.wuaipojie2024_2.A", "d", Context.class, String.class).invoke(null, context, str);
    } catch (Exception e) {
        // 如果在尝试获取或调用方法时发生异常,记录错误信息到日志,并打印堆栈跟踪
        Log.e(TAG, "咦,似乎是坏掉的dex呢!");
        e.printStackTrace();
        // 出现异常时,方法返回一个空字符串
        return "";
    }
}
private static Method getStaticMethod(Context context, int[] iArr, String str, String str2, Class<?>... clsArr) throws Exception {
    try {
        // read方法用于读取原始DEX文件,然后fix方法根据提供的iArr参数和上下文来处理数据。
        File fix = fix(read(context), iArr[0], iArr[1], iArr[2], context);

        // 获取应用的当前类加载器
        ClassLoader classLoader = context.getClass().getClassLoader();

        // 获取或创建一个名为"fixed"的目录,用于存放处理过的DEX文件
        File dir = context.getDir("fixed", 0);

        // 使用DexClassLoader动态加载修复后的DEX文件。
        // fix.getAbsolutePath()是DEX文件的路径,dir.getAbsolutePath()是优化后的DEX文件存放路径。
        // null是父类加载器,classLoader是应用的当前类加载器,作为新的类加载器的父加载器。
        Method declaredMethod = new DexClassLoader(fix.getAbsolutePath(), dir.getAbsolutePath(), null, classLoader)
                                .loadClass(str) // 加载指定的类
                                .getDeclaredMethod(str2, clsArr); // 获取指定的方法

        // 删除处理过的DEX文件和其在"fixed"目录下的优化版本,以清理临时文件
        fix.delete();
        new File(dir, fix.getName()).delete();

        // 返回找到的Method对象
        return declaredMethod;
    } catch (Exception e) {
        // 如果过程中发生任何异常,打印堆栈跟踪并返回null
        e.printStackTrace();
        return null;
    }
}
private static File fix(ByteBuffer byteBuffer, int i, int i2, int i3, Context context) throws Exception {
    try {
        // 获取或创建应用内"data"目录
        File dir = context.getDir("data", 0);
        // 使用自定义的D.getClassDefData方法获取类定义数据,然后从返回的HashMap中获取"class_data_off"的值
        int intValue = D.getClassDefData(byteBuffer, i).get("class_data_off").intValue();
        // 获取类数据,并根据给定的索引修改指定的直接方法的访问标志
        //已知i2是3,也就意味着访问的是直接方法列表中的第四个方法(因为数组索引是从0开始的)
        //i3则是方法的偏移,注意要转换成ULEB128格式
        HashMap<String, int[][]> classData = D.getClassData(byteBuffer, intValue);
        classData.get("direct_methods")[i2][2] = i3;
        // 使用自定义的D.encodeClassData方法将修改后的类数据编码回字节数组
        byte[] encodeClassData = D.encodeClassData(classData);
        // 将ByteBuffer的位置设置到类数据偏移处,并将修改后的类数据写回ByteBuffer
        byteBuffer.position(intValue);
        byteBuffer.put(encodeClassData);
        // 设置ByteBuffer的位置到32,从这个位置开始读取数据,用于SHA-1哈希计算
        byteBuffer.position(32);
        byte[] bArr = new byte[byteBuffer.capacity() - 32];
        byteBuffer.get(bArr);
        // 使用自定义的Utils.getSha1方法计算数据的SHA-1哈希
        byte[] sha1 = Utils.getSha1(bArr);
        // 将ByteBuffer的位置设置到12,并将计算出的SHA-1哈希写入ByteBuffer
        byteBuffer.position(12);
        byteBuffer.put(sha1);
        // 使用自定义的Utils.checksum方法计算校验和
        int checksum = Utils.checksum(byteBuffer);
        // 将ByteBuffer的位置设置到8,并将校验和写入ByteBuffer(注意校验和的字节顺序被反转以符合DEX文件格式)
        byteBuffer.position(8);
        byteBuffer.putInt(Integer.reverseBytes(checksum));
        // 获取ByteBuffer中的字节数组
        byte[] array = byteBuffer.array();
        // 创建一个新的DEX文件,并将修改后的数据写入该文件
        File file = new File(dir, "2.dex");
        FileOutputStream fileOutputStream = new FileOutputStream(file);
        fileOutputStream.write(array);
        fileOutputStream.close();
        // 返回新创建的DEX文件
        return file;
    } catch (Exception e) {
        // 在发生异常时打印堆栈跟踪并返回null
        e.printStackTrace();
        return null;
    }
}
修复后的代码:
public static String d(Context context, String str) {
    MainActivity.sSS(str);//frida检测
    String signInfo = Utils.getSignInfo(context);//签名校验
    if (signInfo == null || !signInfo.equals("fe4f4cec5de8e8cf2fca60a4e61f67bcd3036117")) {
        return "";
    }
        //输入的字符串与运算后的048531267进行对比
    StringBuffer stringBuffer = new StringBuffer();
    int i = 0;
    while (stringBuffer.length() < 9 && i < 40) {
        int i2 = i + 1;
        String substring = "0485312670fb07047ebd2f19b91e1c5f".substring(i, i2);
        if (!stringBuffer.toString().contains(substring)) {
            stringBuffer.append(substring);
        }
        i = i2;
    }

    return !str.equals(stringBuffer.toString().toUpperCase()) ? "" : "唉!哪有什么亿载沉睡的玄天帝,不过是一位被诅咒束缚的旧日之尊,在灯枯之际挣扎的南柯一梦罢了。有缘人,这份机缘就赠予你了。坐标在B.d";
}
public static String d(String str) {
    return "机缘是{" + Utils.md5(Utils.getSha1("password+你的uid".getBytes())) + "}";
}

函数大致逻辑如下: 首先加载组件,然后根据组件的密码正确与否,进行一个判断

如果正确的话那就只输出,没啥用 如果错误的话,那就会运行checkPassword()方法

checkPassword方法首先会使用classes.dex生成一个1.dex

使用DexClassLoader方法去调取1.dex里面的方法

显示dex损坏或读取不到dex 自主修复1.dex,然后命名为2.dex

根据修复后的代码,修复B.d

Getflag

大致的函数过程如此,要想解决这个问题第一步还是修复dex

img

拖进010直接爆红,说明是文件头错误的dex,可以使用np修复,mt会修复全部的dex信息所以不太行

或者直接使用DexRepair

java -jar DexRepair.jar /path/to/dex

img

修复好了之后再压入到软件里面,最好是不要改变签名信息

img

修复了之后就可以正常走程序流程了,但是我怎么hook都报错

img

看报错貌似在so层有点问题

img

一直hook不到

img

img

好好好,原来是在so层加了frida检测

img

怪不得会有这个,自己找了找so,除此之外没找到什么so的作用,所以直接干脆不让他导入这个so得了 把这个so层的导入函数改成本地的空函数就行

img

img

变成了本地的空函数了,就不会再进行frida检测了

能hook上的(虽然但是...........捣鼓半天后用一个全新的附件来hook怎么也能hook上...........难道根本没调用吗?????逆天

算了无所谓,不去管了

img

现在的问题重点在于他在生成了1.dex后又删除了,所以我也想通过mt来删掉这个函数,mt删掉这两个参数

img

img

原来是读取文件.....就离谱 刚刚记得生成的是1.dex,但是这里是decode.dex,很明显读取不到 因为我没有装as(在虚拟机里,but虚拟机寄了)如果装了as那么就可以直接查看日志信息了 再去mt里面改改导入的dex名字

img

顺便把删除生成1.dex的方法给删掉

img

然后运行一下apk程序,果然他俩没有被删,先看看1在了什么

img

不用看了,搞不出来,好像题目一直有异常,都给我搞得怀疑人生了。。。。。

bmk佬说是题目附件的问题(真不知道是怎么一直触发异常的 于是借鉴了and_1师傅的思路-复现加密

以上可以忽略不看,是我个人的一些试错记录,我真不是水(bushi

复现加密

在idea单独起一个项目,用来复现加密流程,idea路径大致如下:

img

img

以下是代码:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.util.HashMap;

public class Main {

    private static File fix(ByteBuffer byteBuffer, int v, int v1, int v2) throws Exception {
        File file = new File("./data");
        int classDataOffset = (int) (((Integer) D.getClassDefData(byteBuffer, v).get("class_data_off")));
        HashMap<String, int[][]> classData = D.getClassData(byteBuffer, classDataOffset);
        classData.get("direct_methods")[v1][2] = v2;
        byte[] encodedClassData = D.encodeClassData(classData);
        byteBuffer.position(classDataOffset);
        byteBuffer.put(encodedClassData);
        byteBuffer.position(0x20);
        byte[] data = new byte[byteBuffer.capacity() - 0x20];
        byteBuffer.get(data);
        byte[] sha1 = Utils.getSha1(data);
        byteBuffer.position(12);
        byteBuffer.put(sha1);
        int checksum = Utils.checksum(byteBuffer);
        byteBuffer.position(8);
        byteBuffer.putInt(Integer.reverseBytes(checksum));
        byte[] bufferData = byteBuffer.array();
        File outputFile = new File(file, "2.dex");
        FileOutputStream fileOutputStream = new FileOutputStream(outputFile);
        fileOutputStream.write(bufferData);
        fileOutputStream.close();
        return outputFile;
    }

    private static ByteBuffer readDex() {
        try {
            File inputFile = new File("./data/1.dex");
            if (!inputFile.exists()) {
                System.out.printf("File does not exist.");
                return null;
            }

            FileInputStream fileInputStream = new FileInputStream(inputFile);
            byte[] data = new byte[fileInputStream.available()];
            fileInputStream.read(data);
            ByteBuffer byteBuffer = ByteBuffer.wrap(data);
            fileInputStream.close();
            System.out.printf("\n File read successfully.");
            return byteBuffer;
        } catch (Exception ex) {
            return null;
        }
    }

    public static void main(String[] args) throws Exception {
        ByteBuffer buf = readDex();
        byte byteValue = buf.get(); // 读取一个字节
        char charValue = (char) byteValue;
        System.out.printf("%c", charValue);
        byteValue = buf.get(); //
        charValue = (char) byteValue;
        System.out.printf("%c", charValue);
        byteValue = buf.get(); //
        charValue = (char) byteValue;
        System.out.printf("%c", charValue);
        //key = [0,3,7908]
        //key = [1,1,8108]

        File fixed = fix(buf, 0, 3, 7908);
    }
}
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;

/* loaded from: assets/classes.dex */
public class Utils {
    public static final String SHA1 = "SHA1";

    public static byte[] toULEB128(int i) {
        int i2 = i >> 28;
        if (i2 > 0) {
            return new byte[]{(byte) ((i & 127) | 128), (byte) (((i >> 7) & 127) | 128), (byte) (((i >> 14) & 127) | 128), (byte) (((i >> 21) & 127) | 128), (byte) (i2 & 15)};
        }
        int i3 = i >> 21;
        if (i3 > 0) {
            return new byte[]{(byte) ((i & 127) | 128), (byte) (((i >> 7) & 127) | 128), (byte) (((i >> 14) & 127) | 128), (byte) (i3 & 127)};
        }
        int i4 = i >> 14;
        if (i4 > 0) {
            return new byte[]{(byte) ((i & 127) | 128), (byte) (((i >> 7) & 127) | 128), (byte) (i4 & 127)};
        }
        int i5 = i >> 7;
        return i5 > 0 ? new byte[]{(byte) ((i & 127) | 128), (byte) (i5 & 127)} : new byte[]{(byte) (i & 127)};
    }

    public static byte[] getSha1(byte[] bArr) {
        try {
            return MessageDigest.getInstance("SHA").digest(bArr);
        } catch (Exception unused) {
            return null;
        }
    }

    public static String md5(byte[] bArr) {
        try {
            String bigInteger = new BigInteger(1, MessageDigest.getInstance("md5").digest(bArr)).toString(16);
            for (int i = 0; i < 32 - bigInteger.length(); i++) {
                bigInteger = "0" + bigInteger;
            }
            return bigInteger;
        } catch (NoSuchAlgorithmException unused) {
            throw new RuntimeException("ops!!");
        }
    }

    public static int checksum(ByteBuffer byteBuffer) {
        byteBuffer.position(12);
        int capacity = byteBuffer.capacity();
        int i = 1;
        int i2 = 0;
        boolean z = false;
        while (byteBuffer.position() < capacity) {
            ArrayList arrayList = new ArrayList();
            int i3 = 0;
            while (true) {
                if (i3 < 1024) {
                    arrayList.add(Integer.valueOf(byteBuffer.get() & 255));
                    if (byteBuffer.position() == byteBuffer.limit()) {
                        z = true;
                        break;
                    }
                    i3++;
                } else {
                    break;
                }
            }
            int[] calculateVar = calculateVar(arrayList, i, i2);
            int i4 = calculateVar[0];
            int i5 = calculateVar[1];
            if (z) {
                return (i5 << 16) + i4;
            }
            i2 = i5;
            i = i4;
        }
        return 0;
    }

    private static int[] calculateVar(ArrayList<Integer> arrayList, int i, int i2) {
        int i3 = 0;
        while (i3 < arrayList.size()) {
            int intValue = (arrayList.get(i3).intValue() + i) % 65521;
            i2 = (i2 + intValue) % 65521;
            i3++;
            i = intValue;
        }
        return new int[]{i, i2};
    }

    public static int[] fromULEB128(ByteBuffer byteBuffer) {
        int i;
        int i2 = byteBuffer.get() & 255;
        if (i2 > 127) {
            int i3 = byteBuffer.get() & 255;
            i2 = (i2 & 127) | ((i3 & 127) << 7);
            if (i3 > 127) {
                int i4 = byteBuffer.get() & 255;
                i2 |= (i4 & 127) << 14;
                if (i4 > 127) {
                    int i5 = byteBuffer.get() & 255;
                    i2 |= (i5 & 127) << 21;
                    if (i5 > 127) {
                        i2 |= (byteBuffer.get() & 255) << 28;
                        i = 5;
                    } else {
                        i = 4;
                    }
                } else {
                    i = 3;
                }
            } else {
                i = 2;
            }
        } else {
            i = 1;
        }
        return new int[]{i2, i};
    }
}
import java.nio.ByteBuffer;
import java.util.HashMap;

public class D {
    private static byte[] decode_field(int[] arr_v, int v) {
        int v1 = arr_v[0] - v;
        int v2 = arr_v[1];
        return D.merge(new byte[][]{Utils.toULEB128(v1), Utils.toULEB128(v2)});
    }

    private static byte[] decode_method(int[] arr_v, int v) {
        int v1 = arr_v[0] - v;
        int v2 = arr_v[1];
        int v3 = arr_v[2];
        return D.merge(new byte[][]{Utils.toULEB128(v1), Utils.toULEB128(v2), Utils.toULEB128(v3)});
    }

    public static byte[] encodeClassData(HashMap hashMap0) {
        int[][] arr2_v = (int[][])hashMap0.get("static_fields");
        int[][] arr2_v1 = (int[][])hashMap0.get("instance_fields");
        int[][] arr2_v2 = (int[][])hashMap0.get("direct_methods");
        int[][] arr2_v3 = (int[][])hashMap0.get("virtual_methods");
        byte[] arr_b = D.merge(new byte[][]{Utils.toULEB128(arr2_v.length), Utils.toULEB128(arr2_v1.length), Utils.toULEB128(arr2_v2.length), Utils.toULEB128(arr2_v3.length)});
        if(arr2_v.length > 0) {
            int v = 0;
            int v1 = 0;
            while(v < arr2_v.length) {
                int[] arr_v = arr2_v[v];
                arr_b = D.merge(new byte[][]{arr_b, D.decode_field(arr_v, v1)});
                v1 = arr_v[0];
                ++v;
            }
        }

        if(arr2_v1.length > 0) {
            int v2 = 0;
            int v3 = 0;
            while(v2 < arr2_v1.length) {
                int[] arr_v1 = arr2_v1[v2];
                arr_b = D.merge(new byte[][]{arr_b, D.decode_field(arr_v1, v3)});
                v3 = arr_v1[0];
                ++v2;
            }
        }

        if(arr2_v2.length > 0) {
            int v4 = 0;
            int v5 = 0;
            while(v4 < arr2_v2.length) {
                int[] arr_v2 = arr2_v2[v4];
                arr_b = D.merge(new byte[][]{arr_b, D.decode_method(arr_v2, v5)});
                v5 = arr_v2[0];
                ++v4;
            }
        }

        if(arr2_v3.length > 0) {
            int v6 = 0;
            int v7 = 0;
            while(v6 < arr2_v3.length) {
                int[] arr_v3 = arr2_v3[v6];
                arr_b = D.merge(new byte[][]{arr_b, D.decode_method(arr_v3, v7)});
                v7 = arr_v3[0];
                ++v6;
            }
        }

        return arr_b;
    }

    private static int[] encode_field(ByteBuffer byteBuffer0) {
        return new int[]{Utils.fromULEB128(byteBuffer0)[0], Utils.fromULEB128(byteBuffer0)[0]};
    }

    private static int[] encode_method(ByteBuffer byteBuffer0) {
        return new int[]{Utils.fromULEB128(byteBuffer0)[0], Utils.fromULEB128(byteBuffer0)[0], Utils.fromULEB128(byteBuffer0)[0]};
    }

    public static HashMap getClassData(ByteBuffer byteBuffer0, int v) {
        byteBuffer0.position(v);
        int v1 = Utils.fromULEB128(byteBuffer0)[0];
        int v2 = Utils.fromULEB128(byteBuffer0)[0];
        int v3 = Utils.fromULEB128(byteBuffer0)[0];
        int v4 = Utils.fromULEB128(byteBuffer0)[0];
        int[][] arr2_v = new int[v1][2];
        if(v1 > 0) {
            int v5 = 0;
            int v6 = 0;
            while(v5 < v1) {
                int[] arr_v = D.encode_field(byteBuffer0);
                v6 = v5 == 0 ? arr_v[0] : v6 + arr_v[0];
                arr2_v[v5] = new int[]{v6, arr_v[1]};
                ++v5;
            }
        }

        int[][] arr2_v1 = new int[v2][2];
        if(v2 > 0) {
            int v7 = 0;
            int v8 = 0;
            while(v7 < v2) {
                int[] arr_v1 = D.encode_field(byteBuffer0);
                v8 = v7 == 0 ? arr_v1[0] : v8 + arr_v1[0];
                arr2_v1[v7] = new int[]{v8, arr_v1[1]};
                ++v7;
            }
        }

        int[][] arr2_v2 = new int[v3][3];
        if(v3 > 0) {
            int v9 = 0;
            int v10 = 0;
            while(v9 < v3) {
                int[] arr_v2 = D.encode_method(byteBuffer0);
                v10 = v9 == 0 ? arr_v2[0] : v10 + arr_v2[0];
                arr2_v2[v9] = new int[]{v10, arr_v2[1], arr_v2[2]};
                ++v9;
            }
        }

        int[][] arr2_v3 = new int[v4][3];
        if(v4 > 0) {
            int v11 = 0;
            int v12 = 0;
            while(v11 < v2) {
                int[] arr_v3 = D.encode_method(byteBuffer0);
                v12 = v11 == 0 ? arr_v3[0] : v12 + arr_v3[0];
                arr2_v3[v11] = new int[]{v12, arr_v3[1], arr_v3[2]};
                ++v11;
            }
        }

        HashMap hashMap0 = new HashMap();
        hashMap0.put("static_fields", arr2_v);
        hashMap0.put("instance_fields", arr2_v1);
        hashMap0.put("direct_methods", arr2_v2);
        hashMap0.put("virtual_methods", arr2_v3);
        return hashMap0;
    }

    public static HashMap getClassDefData(ByteBuffer byteBuffer0, int v) {
        if(byteBuffer0 != null) {
            byteBuffer0.position(100);
            byteBuffer0.position(v * 0x20 + Integer.reverseBytes(byteBuffer0.getInt()));
            HashMap hashMap0 = new HashMap();
            int v1 = Integer.reverseBytes(byteBuffer0.getInt());
            int v2 = Integer.reverseBytes(byteBuffer0.getInt());
            int v3 = Integer.reverseBytes(byteBuffer0.getInt());
            int v4 = Integer.reverseBytes(byteBuffer0.getInt());
            int v5 = Integer.reverseBytes(byteBuffer0.getInt());
            int v6 = Integer.reverseBytes(byteBuffer0.getInt());
            int v7 = Integer.reverseBytes(byteBuffer0.getInt());
            int v8 = Integer.reverseBytes(byteBuffer0.getInt());
            hashMap0.put("class_idx", Integer.valueOf(v1));
            hashMap0.put("access_flag", Integer.valueOf(v2));
            hashMap0.put("superclass_idx", Integer.valueOf(v3));
            hashMap0.put("interfaces_off", Integer.valueOf(v4));
            hashMap0.put("source_file_idx", Integer.valueOf(v5));
            hashMap0.put("annotation_off", Integer.valueOf(v6));
            hashMap0.put("class_data_off", Integer.valueOf(v7));
            hashMap0.put("static_values_off", Integer.valueOf(v8));
            return hashMap0;
        }

        throw new IllegalArgumentException("Buffer cannot be null");
    }

    private static byte[] merge(byte[][] arr2_b) {
        int v = 0;
        int v1 = 0;
        while(v < arr2_b.length) {
            v1 += arr2_b[v].length;
            ++v;
        }

        ByteBuffer byteBuffer0 = ByteBuffer.allocate(v1);
        int v2;
        for(v2 = 0; v2 < arr2_b.length; ++v2) {
            byteBuffer0.put(arr2_b[v2]);
        }

        byte[] arr_b = new byte[byteBuffer0.position()];
        byteBuffer0.position(0);
        byteBuffer0.get(arr_b);
        return arr_b;
    }
}

(其实都是从安卓复制过来的然后修修报错能运行就问题不大了

img

最后也是终于获得了机缘

img

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
miao2019 + 1 + 1 热心回复!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

Hmily 发表于 2024-3-25 17:53
@wenwenjiang 把图片上传到论坛本地吧,版主已经加优秀鼓励了,不然我们也没法制作精华集,大家也无法阅读,尽快修改一下。
正己 发表于 2024-3-24 21:09
不知道是不是我的原因,我这图片都加载不出来

点评

作者上线也并未修改文章图片,无法阅读,我取消优秀并撤销评分了,如果补上重新评分。  详情 回复 发表于 2024-4-7 11:47
图片地址都是本地文件的相对路径,没有作为附件上传到论坛/图床。  详情 回复 发表于 2024-3-25 07:56
duso 发表于 2024-3-24 22:22
erichyx 发表于 2024-3-24 22:50
图片都挂了
jujiaomubiao 发表于 2024-3-24 23:49
像大神学习,谢谢分享!
zjh889 发表于 2024-3-25 00:06
这东西很不错,谢谢大师!
cfantv 发表于 2024-3-25 00:16
牛逼呀,看来我需要学习的还很多
爱飞的猫 发表于 2024-3-25 07:56
正己 发表于 2024-3-24 21:09
不知道是不是我的原因,我这图片都加载不出来

图片地址都是本地文件的相对路径,没有作为附件上传到论坛/图床。
StackNoOverflow 发表于 2024-3-25 09:37
麻烦重新上传一下图片吧,访问不到了
cs_sunsky 发表于 2024-3-25 17:20
我这图片都加载不出来
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-1 07:38

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表