2024吾爱红包题逆向初级、中级难度复现
# 前言过年的时候忘了,没打.......现在来复现复现 应该还是可以学到很多东西的
被and中级题搞到心态了
# Windows
## 【2024春节】初级题1
!(./../image/1710399685939-36.png)
找到输入的函数,flag的长度大概是36位
111111111111111111111111111111111111
直接动调出来了,flag在v7
!(./../image/1710399685930-1.png)
fl@g{H@ppy_N3w_e@r!2o24!Fighting!!!}
# Android
## 【2024春节】初级题1
难度不高,秒的题
!(./../image/1710399685931-2.png)
在吾爱经常玩的小猫游戏,当然可以直接玩通关,但是出于逆向,还是逆一下吧
!(./../image/1710399685931-3.png)
extractDataFromFile()方法就是游戏通关之后拿到的flag函数,是在后一个文件下进行检索 flag{ 字符然后输出到 } 字符,应该是上面的一个mp4的视频,flag应该在哪个文件十六进制的末尾处
!(./../image/1710399685931-4.png)
hook代码
```JavaScript
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一样修改代码逻辑、数值从而达到想要的效果。下面是题目原图.....原神含量好足(虽然没玩过
!(./../image/1710399685931-5.png)
简单分析一下函数的逻辑,反正就是真·保底......
!(./../image/1710399685931-6.png)
再看一下flag生成的部分:
!(./../image/1710399685931-7.png)
所以大体函数分析完成,之后就是如何getflag
1、可以直接去修改爆率或者判断的smile代码直接get flag 注意不要改签名信息就好
2、找到签名信息然后自己去异或 getflag
我就偏向于第一种吧,但是也先简单说说第二组。签名信息存储在main-inf的文件夹下的一个.rsa文件中,用ida查看16进制信息即可
!(./../image/1710399685931-8.png)
mt做法:
0x50对应的是80,也就是上面的概率(假概率)本来是从80开始减,直接改成0,相当于直接百分百得到flag
!(./../image/1710399685931-9.png)
在修改保存的时候一定不要自动签名,不然会改变签名信息导致flag错误
!(./../image/1710399685932-10.png)
可以关掉签名校验安装,当然直接安也没什么问题
!(./../image/1710399685932-11.png)
然后一次直接拿到flag,还是可以的
!(./../image/1710399685932-12.png)
另外看佬的wp,发现了可以直接运行指定的activity
```JavaScript
adb shell su -c am start-activity -n com.kbtx.redpack_simple/.FlagActivity
```
!(./../image/1710399685932-13.png)
直接弹flag的activity了,两个初级题同理直接秒了
## 【2024春节】中级题
打开apk运行一下,是一个类似于锁屏的一个控件
!(./../image/1710399685932-14.png)
!(./../image/1710399685932-15.png)
下面是正己师傅对于这段代码的详细解读,非常的详细
```Java
public boolean checkPassword(String str) {
try {
// 打开assets目录下的"classes.dex"文件作为InputStream
InputStream open = getAssets().open("classes.dex");
// 创建一个字节数组,大小为可读取的字节数,即整个文件的大小
byte[] bArr = new byte;
// 从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, iArr, iArr, 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") = 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.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
!(./../image/1710399685932-16.png)
拖进010直接爆红,说明是文件头错误的dex,可以使用np修复,mt会修复全部的dex信息所以不太行
或者直接使用(https://github.com/luoyesiqiu/DexRepair)
java -jar DexRepair.jar /path/to/dex
!(./../image/1710399685932-17.png)
修复好了之后再压入到软件里面,最好是不要改变签名信息
!(./../image/1710399685932-18.png)
修复了之后就可以正常走程序流程了,但是我怎么hook都报错
!(./../image/1710399685933-19.png)
看报错貌似在so层有点问题
!(./../image/1710399685933-20.png)
一直hook不到
!(./../image/1710399685933-21.png)
!(./../image/1710399685933-22.png)
好好好,原来是在so层加了frida检测
!(./../image/1710399685933-23.png)
怪不得会有这个,自己找了找so,除此之外没找到什么so的作用,所以直接干脆不让他导入这个so得了 把这个so层的导入函数改成本地的空函数就行
!(./../image/1710399685933-24.png)
!(./../image/1710399685933-25.png)
变成了本地的空函数了,就不会再进行frida检测了
能hook上的(虽然但是...........捣鼓半天后用一个全新的附件来hook怎么也能hook上...........难道根本没调用吗?????逆天
算了无所谓,不去管了
!(./../image/1710399685933-26.png)
现在的问题重点在于他在生成了1.dex后又删除了,所以我也想通过mt来删掉这个函数,mt删掉这两个参数
!(./../image/1710399685933-27.png)
!(./../image/1710399685933-28.png)
原来是读取文件.....就离谱 刚刚记得生成的是1.dex,但是这里是decode.dex,很明显读取不到 因为我没有装as(在虚拟机里,but虚拟机寄了)如果装了as那么就可以直接查看日志信息了 再去mt里面改改导入的dex名字
!(./../image/1710399685933-29.png)
顺便把删除生成1.dex的方法给删掉
!(./../image/1710399685933-30.png)
然后运行一下apk程序,果然他俩没有被删,先看看1在了什么
!(./../image/1710399685934-31.png)
不用看了,搞不出来,好像题目一直有异常,都给我搞得怀疑人生了。。。。。
bmk佬说是题目附件的问题(真不知道是怎么一直触发异常的 于是借鉴了and_1师傅的思路-复现加密
以上可以忽略不看,是我个人的一些试错记录,我真不是水(bushi
### 复现加密
在idea单独起一个项目,用来复现加密流程,idea路径大致如下:
!(./../image/1710399685934-32.png)
!(./../image/1710399685934-33.png)
以下是代码:
```Java
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") = v2;
byte[] encodedClassData = D.encodeClassData(classData);
byteBuffer.position(classDataOffset);
byteBuffer.put(encodedClassData);
byteBuffer.position(0x20);
byte[] data = new byte;
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.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 =
//key =
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;
int i5 = calculateVar;
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 - v;
int v2 = arr_v;
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 - v;
int v2 = arr_v;
int v3 = arr_v;
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;
arr_b = D.merge(new byte[][]{arr_b, D.decode_field(arr_v, v1)});
v1 = arr_v;
++v;
}
}
if(arr2_v1.length > 0) {
int v2 = 0;
int v3 = 0;
while(v2 < arr2_v1.length) {
int[] arr_v1 = arr2_v1;
arr_b = D.merge(new byte[][]{arr_b, D.decode_field(arr_v1, v3)});
v3 = arr_v1;
++v2;
}
}
if(arr2_v2.length > 0) {
int v4 = 0;
int v5 = 0;
while(v4 < arr2_v2.length) {
int[] arr_v2 = arr2_v2;
arr_b = D.merge(new byte[][]{arr_b, D.decode_method(arr_v2, v5)});
v5 = arr_v2;
++v4;
}
}
if(arr2_v3.length > 0) {
int v6 = 0;
int v7 = 0;
while(v6 < arr2_v3.length) {
int[] arr_v3 = arr2_v3;
arr_b = D.merge(new byte[][]{arr_b, D.decode_method(arr_v3, v7)});
v7 = arr_v3;
++v6;
}
}
return arr_b;
}
private static int[] encode_field(ByteBuffer byteBuffer0) {
return new int[]{Utils.fromULEB128(byteBuffer0), Utils.fromULEB128(byteBuffer0)};
}
private static int[] encode_method(ByteBuffer byteBuffer0) {
return new int[]{Utils.fromULEB128(byteBuffer0), Utils.fromULEB128(byteBuffer0), Utils.fromULEB128(byteBuffer0)};
}
public static HashMap getClassData(ByteBuffer byteBuffer0, int v) {
byteBuffer0.position(v);
int v1 = Utils.fromULEB128(byteBuffer0);
int v2 = Utils.fromULEB128(byteBuffer0);
int v3 = Utils.fromULEB128(byteBuffer0);
int v4 = Utils.fromULEB128(byteBuffer0);
int[][] arr2_v = new int;
if(v1 > 0) {
int v5 = 0;
int v6 = 0;
while(v5 < v1) {
int[] arr_v = D.encode_field(byteBuffer0);
v6 = v5 == 0 ? arr_v : v6 + arr_v;
arr2_v = new int[]{v6, arr_v};
++v5;
}
}
int[][] arr2_v1 = new int;
if(v2 > 0) {
int v7 = 0;
int v8 = 0;
while(v7 < v2) {
int[] arr_v1 = D.encode_field(byteBuffer0);
v8 = v7 == 0 ? arr_v1 : v8 + arr_v1;
arr2_v1 = new int[]{v8, arr_v1};
++v7;
}
}
int[][] arr2_v2 = new int;
if(v3 > 0) {
int v9 = 0;
int v10 = 0;
while(v9 < v3) {
int[] arr_v2 = D.encode_method(byteBuffer0);
v10 = v9 == 0 ? arr_v2 : v10 + arr_v2;
arr2_v2 = new int[]{v10, arr_v2, arr_v2};
++v9;
}
}
int[][] arr2_v3 = new int;
if(v4 > 0) {
int v11 = 0;
int v12 = 0;
while(v11 < v2) {
int[] arr_v3 = D.encode_method(byteBuffer0);
v12 = v11 == 0 ? arr_v3 : v12 + arr_v3;
arr2_v3 = new int[]{v12, arr_v3, arr_v3};
++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.length;
++v;
}
ByteBuffer byteBuffer0 = ByteBuffer.allocate(v1);
int v2;
for(v2 = 0; v2 < arr2_b.length; ++v2) {
byteBuffer0.put(arr2_b);
}
byte[] arr_b = new byte;
byteBuffer0.position(0);
byteBuffer0.get(arr_b);
return arr_b;
}
}
```
(其实都是从安卓复制过来的然后修修报错能运行就问题不大了
!(./../image/1710399685934-34.png)
最后也是终于获得了机缘
!(./../image/1710399685934-35.png) @wenwenjiang 把图片上传到论坛本地吧,版主已经加优秀鼓励了,不然我们也没法制作精华集,大家也无法阅读,尽快修改一下。 不知道是不是我的原因,我这图片都加载不出来 学习一下,感谢分享!! 图片都挂了 像大神学习,谢谢分享! 这东西很不错,谢谢大师! 牛逼呀,看来我需要学习的还很多 正己 发表于 2024-3-24 21:09
不知道是不是我的原因,我这图片都加载不出来
图片地址都是本地文件的相对路径,没有作为附件上传到论坛/图床。 麻烦重新上传一下图片吧,访问不到了 我这图片都加载不出来