前言

过年的时候忘了,没打…….现在来复现复现 应该还是可以学到很多东西的
被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代码

1
2
3
4
5
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

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

img

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

【2024春节】中级题

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

img

img

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
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

以下是代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
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