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
|
package com.boss;
import com.github.unidbg.AndroidEmulator;
import com.github.unidbg.Emulator;
import com.github.unidbg.Module;
import com.github.unidbg.file.FileResult;
import com.github.unidbg.file.IOResolver;
import com.github.unidbg.linux.android.AndroidEmulatorBuilder;
import com.github.unidbg.linux.android.AndroidResolver;
import com.github.unidbg.linux.android.dvm.*;
import com.github.unidbg.linux.android.dvm.array.ArrayObject;
import com.github.unidbg.linux.android.dvm.array.ByteArray;
import com.github.unidbg.memory.Memory;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
//必须继承AbstractJni
public class YZWG extends AbstractJni implements IOResolver {
public static AndroidEmulator emulator; // 静态属性,以后对象和类都可以直接使用
public static Memory memory;
public static VM vm;
public static Module module;
// 1 构造方法--》用来初始化
public YZWG() {
// 1.创建设备(32位或64位模拟器), 具体看so文件在哪个目录。 在armeabi-v7a就选择32位
// 传进设备时,如果是32位,后面so文件就要用32位,同理需要用64位的
// 这个名字可以随便写,一般写成app的包名 以后可能会动
emulator = AndroidEmulatorBuilder.for64Bit().setProcessName("com.hpbr.bosszhipin").build();
// 2.获取内存对象(可以操作内存)
memory = emulator.getMemory();
//3.设置安卓sdk版本(只支持19、23)
memory.setLibraryResolver(new AndroidResolver(23));
// 4.创建虚拟机(运行安卓代码需要虚拟机,就想运行py代码需要python解释器一样) 以后会动
vm = emulator.createDalvikVM(new File("apks/boss/boss.apk"));
vm.setJni(this); // 后期补环境会用,把要补的环境,写在当前这个类中,执行这个代码即可,但是必须继承AbstractJni
vm.setVerbose(true); //是否展示调用过程的细节
// 5.加载so文件
DalvikModule dm = vm.loadLibrary("yzwg", true); // 以后会动
dm.callJNI_OnLoad(emulator); // jni开发动态注册,会执行JNI_OnLoad,如果是动态注册,需要执行一下这个,如果静态注册,这个不需要执行,车智赢案例是静态注册
// 6.dm代表so文件,dm.getModule()得到module对象,基于module对象可以访问so中的成员。
module = dm.getModule(); // 把so文件加载到内存后,后期可以获取基地址,偏移量等,该变量代指so文件
}
@Override
public DvmObject<?> getStaticObjectField(BaseVM vm, DvmClass dvmClass, String signature) {
switch (signature) {
case "com/twl/signer/YZWG->gContext:Landroid/content/Context;": {
return vm.resolveClass("android/content/Context").newObject(null);
}
}
return super.getStaticObjectField(vm, dvmClass, signature);
}
@Override
public DvmObject<?> callObjectMethod(BaseVM vm, DvmObject<?> dvmObject, String signature, VarArg varArg) {
switch (signature) {
case "android/content/pm/PackageManager->getPackagesForUid(I)[Ljava/lang/String;": {
int arg = varArg.getIntArg(0);
System.out.println("uid==>" + arg);
System.out.println("包名==>" + vm.getPackageName());
return new ArrayObject(new StringObject(vm, vm.getPackageName()));
}
}
return super.callObjectMethod(vm, dvmObject, signature, varArg);
}
@Override
public int callIntMethod(BaseVM vm, DvmObject<?> dvmObject, String signature, VarArg varArg) {
switch (signature) {
case "java/lang/String->hashCode()I": {
String str = (String) dvmObject.getValue();
return str.hashCode();
}
}
return super.callIntMethod(vm, dvmObject, signature, varArg);
}
//2 sign 成员方法--》主要用来解密
public void get_sp() {
ArrayList<Object> list = new ArrayList<>(10);
list.add(vm.getJNIEnv());
list.add(0);
String arg1 = "client_info=%7B%22version%22%3A%2210%22%2C%22os%22%3A%22Android%22%2C%22start_time%22%3A%221772188217563%22%2C%22resume_time%22%3A%221772188217563%22%2C%22channel%22%3A%2228%22%2C%22model%22%3A%22google%7C%7CPixel+2%22%2C%22dzt%22%3A0%2C%22loc_per%22%3A0%2C%22uniqid%22%3A%22809b4bb9-33e9-4d7c-b59b-0a7d6f0ef0ee%22%2C%22oaid%22%3A%2200000000-0000-0000-0000-000000000000%22%2C%22oaid_honor%22%3A%2200000000-0000-0000-0000-000000000000%22%2C%22did%22%3A%22DUlRWq6jQRU_Glo4HL5qAwwsy7zpPrAM1600RFVsUldxNmpRUlVfR2xvNEhMNXFBd3dzeTd6cFByQU0xNjAwc2h1%22%2C%22tinker_id%22%3A%22Prod-arm64-v8a-release-13.141.1314110_0812-10-06-09%22%2C%22is_bg_req%22%3A0%2C%22network%22%3A%22wifi%22%2C%22operator%22%3A%22UNKNOWN%22%2C%22abi%22%3A1%7D&curidentity=0&data=%5B%7B%22action%22%3A%22app-active%22%2C%22time%22%3A1772188217717%2C%22p4%22%3A%22%22%2C%22p5%22%3A%221%22%2C%22p9%22%3A%22Prod-arm64-v8a-release-13.141.1314110_0812-10-06-09%22%7D%5D&req_time=1772188217741&uniqid=809b4bb9-33e9-4d7c-b59b-0a7d6f0ef0ee&v=13.141";
ByteArray byteArray = new ByteArray(vm, arg1.getBytes(StandardCharsets.UTF_8));
list.add(vm.addLocalObject(byteArray));
list.add(vm.addLocalObject(null));
Number number = module.callFunction(emulator, 0x209a4, list.toArray());
String result = vm.getObject(number.intValue()).getValue().toString();
System.out.println(result);
}
public void get_sig() {
ArrayList<Object> list = new ArrayList<>(10);
list.add(vm.getJNIEnv());
list.add(0);
String arg1 = "/api/zpCommon/batch/unloginStatisticsclient_info=%7B%22version%22%3A%2210%22%2C%22os%22%3A%22Android%22%2C%22start_time%22%3A%221772188217563%22%2C%22resume_time%22%3A%221772188217563%22%2C%22channel%22%3A%2228%22%2C%22model%22%3A%22google%7C%7CPixel+2%22%2C%22dzt%22%3A0%2C%22loc_per%22%3A0%2C%22uniqid%22%3A%22809b4bb9-33e9-4d7c-b59b-0a7d6f0ef0ee%22%2C%22oaid%22%3A%2200000000-0000-0000-0000-000000000000%22%2C%22oaid_honor%22%3A%2200000000-0000-0000-0000-000000000000%22%2C%22did%22%3A%22DUlRWq6jQRU_Glo4HL5qAwwsy7zpPrAM1600RFVsUldxNmpRUlVfR2xvNEhMNXFBd3dzeTd6cFByQU0xNjAwc2h1%22%2C%22tinker_id%22%3A%22Prod-arm64-v8a-release-13.141.1314110_0812-10-06-09%22%2C%22is_bg_req%22%3A0%2C%22network%22%3A%22wifi%22%2C%22operator%22%3A%22UNKNOWN%22%2C%22abi%22%3A1%7D&curidentity=0&data=%5B%7B%22action%22%3A%22app-active%22%2C%22time%22%3A1772188217717%2C%22p4%22%3A%22%22%2C%22p5%22%3A%221%22%2C%22p9%22%3A%22Prod-arm64-v8a-release-13.141.1314110_0812-10-06-09%22%7D%5D&req_time=1772188217741&uniqid=809b4bb9-33e9-4d7c-b59b-0a7d6f0ef0ee&v=13.141";
ByteArray byteArray = new ByteArray(vm, arg1.getBytes(StandardCharsets.UTF_8));
list.add(vm.addLocalObject(byteArray));
list.add(vm.addLocalObject(null));
Number number = module.callFunction(emulator, 0x21864, list.toArray());
DvmObject<?> retObj = vm.getObject(number.intValue());
byte[] resultBytes = (byte[]) retObj.getValue();
String result = new String(resultBytes, StandardCharsets.UTF_8);
System.out.println("结果: " + result);
}
public void decodeContent() {
byte[] encryptedData = new byte[]{
-10, 114, 76, 25, 44, -37, 100, 101, -124, -69, 64, -18, -101, -32, -119, 121, -125, -10, -36, 42, 125, 34, -68, -48, 102, 107, 91, 107, 88, -42, -125, -19, 69, -95, 90, -127, 56, -28, -108, -69, -101, -78, 1, -2, -70, -84, 12, -91, -106, 98, 27, 89, 71, -37, -87, -37, 71, 110, 111, -65, -22, 71, -16, 15, 111, -106, -30, -1, 8, 31, 46, -60, 38, -110, -21, 71, 126, 34, -16, 62, -106, -40, 16, -107, 2, 64, -65, -56, 71, -36, 85, 40, -3, 69, -71, -65, 24, -20, 4, 125, -114, -112, 126, 17, -28, -63, -100, 61, 58, -24, 6, -55, 87, -59, 124, -112, -26, 50, -41, 26, 25, -9, 33, -48, 80, 22, 46, -119, 112, 78, 5, 24, 96, -86, 36, 68, -71, -7, -90, -71, 111, 76, 87, 116, 56, -19, 2
};
ArrayList<Object> list = new ArrayList<>(10);
list.add(vm.getJNIEnv());
list.add(0);
ByteArray dataArray = new ByteArray(vm, encryptedData);
list.add(vm.addLocalObject(dataArray));
list.add(null);
list.add(0);
list.add(1);
list.add(0);
Number number = module.callFunction(emulator, 0x24dc8, list.toArray());
DvmObject<?> retObj = vm.getObject(number.intValue());
byte[] resultBytes = (byte[]) retObj.getValue();
String result = new String(resultBytes, StandardCharsets.UTF_8);
System.out.println("解密结果: " + result);
}
// 3 main方法---》右键直接运行
public static void main(String[] args) {
YZWG yzwg = new YZWG();
yzwg.get_sp();
yzwg.get_sig();
yzwg.decodeContent();
}
@Override
public FileResult resolve(Emulator emulator, String pathname, int oflags) {
System.out.println("pathname open:" + pathname);
return null;
}
}
// zwp_NCTRJTSwi3DewMDkHB6GvU2BAYbyceqJ44s9CxuyL65jv20XaVYg1XpFLNVaF7LolNJtanuLr-ARNMt36qI3RFO3xe8JyDZtt-TQVeh_TOtTgNw-LeFjEs8hx0tJoj7v9ncKmYZWKNui4mO4EMBKqCp54Wi6L8MQyX1JatkuDl9Ec4gZFqDhg7Z1SBl0Q5EvXDZ9Hpb4hZrrp1qpTkEGTjmODhup8HF6VZa0VcxsMFLprFD40lIaRNgU9G7mUIMTy2f0MKwht_lGzm2bw9GnXzCQyGB8Lr9XYvIqmMmmQ8DHWVid8LshMJ0kV52zxZ2rg44Dxcb_cjVfYQd3k5ucb_MgYgZLVJLM4QfkktgfBS3MfS4m3TyKtzi7q5zNIHc52z2fsjpoSrdhmQzh6Bu6-ZMzHJWJ_nbibMppOwVp0HgqJSYdAgYwSwgrTFyUbxw15pDCp830uxCbGNwcHSQjXxi2QgRWAPNLA5ueAa07KMmuMDBrn66vKAqzehxbIFtE4CcoTGstb34UnWCQZ9CHK-DZwfQSrZu_B5i2KIvvFqQG5Fq-ycwEKSZhUmhQJuvLzl5vd6wwh08SdOWSVXsdhHdJaBhEITwc3qRr9K--K8P1fbqdFwd92GQtBdMYqXao5TbaeXuTB0nPAKVcLm67Itr35_UjlCnqciQ_D1gHezlwHiz9xMIosw5DE4hmRLXi_2s6Qm-ohQH9ooezUsQlaPNOPcYqGYA7kqAwhU1qnbISOAhNHjNNCrD-KeWeWb1UJPyg1CE5GJ5KPfTztHGY6zfoJWP7ZKkxM9aOiLMEueJjsCVuE3BpE8h-EMCAeXo_4EXFkeLihAkaNhC9wsphUwZIIS6wTUNQ8yYBBw~~
// zwp_NCTRJTSwi3DewMDkHB6GvU2BAYbyceqJ44s9CxuyL65jv20XaVYg1XpFLNVaF7LolNJtanuLr-ARNMt36qI3RFO3xe8JyDZtt-TQVeh_TOtTgNw-LeFjEs8hx0tJoj7v9ncKmYZWKNui4mO4EMBKqCp54Wi6L8MQyX1JatkuDl9Ec4gZFqDhg7Z1SBl0Q5EvXDZ9Hpb4hZrrp1qpTkEGTjmODhup8HF6VZa0VcxsMFLprFD40lIaRNgU9G7mUIMTy2f0MKwht_lGzm2bw9GnXzCQyGB8Lr9XYvIqmMmmQ8DHWVid8LshMJ0kV52zxZ2rg44Dxcb_cjVfYQd3k5ucb_MgYgZLVJLM4QfkktgfBS3MfS4m3TyKtzi7q5zNIHc52z2fsjpoSrdhmQzh6Bu6-ZMzHJWJ_nbibMppOwVp0HgqJSYdAgYwSwgrTFyUbxw15pDCp830uxCbGNwcHSQjXxi2QgRWAPNLA5ueAa07KMmuMDBrn66vKAqzehxbIFtE4CcoTGstb34UnWCQZ9CHK-DZwfQSrZu_B5i2KIvvFqQG5Fq-ycwEKSZhUmhQJuvLzl5vd6wwh08SdOWSVXsdhHdJaBhEITwc3qRr9K--K8P1fbqdFwd92GQtBdMYqXao5TbaeXuTB0nPAKVcLm67Itr35_UjlCnqciQ_D1gHezlwHiz9xMIosw5DE4hmRLXi_2s6Qm-ohQH9ooezUsQlaPNOPcYqGYA7kqAwhU1qnbISOAhNHjNNCrD-KeWeWb1UJPyg1CE5GJ5KPfTztHGY6zfoJWP7ZKkxM9aOiLMEueJjsCVuE3BpE8h-EMCAeXo_4EXFkeLihAkaNhC9wsphUwZIIS6wTUNQ8yYBBw~~
|