-
Notifications
You must be signed in to change notification settings - Fork 58
/
SimpleApkV2.java
161 lines (144 loc) · 6.07 KB
/
SimpleApkV2.java
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
import java.io.IOException;
import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Arrays;
/**
* Created by thom on 2018/11/2.
*/
public class SimpleApkV2 {
private static final byte[] APK_V2_MAGIC = {'A', 'P', 'K', ' ', 'S', 'i', 'g', ' ',
'B', 'l', 'o', 'c', 'k', ' ', '4', '2'};
private static int[] getApkSignV2(String path) throws IOException {
try (
RandomAccessFile apk = new RandomAccessFile(path, "r")
) {
ByteBuffer buffer = ByteBuffer.allocate(0x10);
buffer.order(ByteOrder.LITTLE_ENDIAN);
apk.seek(apk.length() - 0x6);
apk.readFully(buffer.array(), 0x0, 0x6);
int offset = buffer.getInt();
if (buffer.getShort() != 0) {
throw new UnsupportedEncodingException("no zip");
}
apk.seek(offset - 0x10);
apk.readFully(buffer.array(), 0x0, 0x10);
if (!Arrays.equals(buffer.array(), APK_V2_MAGIC)) {
throw new UnsupportedEncodingException("no apk v2");
}
// Read and compare size fields
apk.seek(offset - 0x18);
apk.readFully(buffer.array(), 0x0, 0x8);
buffer.rewind();
int size = (int) buffer.getLong();
ByteBuffer block = ByteBuffer.allocate(size + 0x8);
block.order(ByteOrder.LITTLE_ENDIAN);
apk.seek(offset - block.capacity());
apk.readFully(block.array(), 0x0, block.capacity());
if (size != block.getLong()) {
throw new UnsupportedEncodingException("no apk v2");
}
while (block.remaining() > 24) {
size = (int) block.getLong();
if (block.getInt() == 0x7109871a) {
// signer-sequence length, signer length, signed data length
block.position(block.position() + 12);
size = block.getInt(); // digests-sequence length
// digests, certificates length
block.position(block.position() + size + 0x4);
size = block.getInt(); // certificate length
break;
} else {
block.position(block.position() + size - 0x4);
}
}
int hash = 1;
for (int i = 0; i < size; ++i) {
hash = 31 * hash + block.get();
}
return new int[] {size, hash};
}
}
private static String formatName(String name) {
int length = name.length();
StringBuilder sb = new StringBuilder();
sb.append("{");
for (int i = 0; i < length; ++i) {
int c = name.charAt(i) ^ ((i + length) % 20);
sb.append("0x");
sb.append(Integer.toHexString(c));
sb.append(", ");
}
sb.append("0x0");
sb.append("}");
return sb.toString();
}
public static void main(String[] args) throws IOException {
System.out.format("#define GENUINE_NAME %s%n", formatName(args[0]));
int[] sizeAndHash = getApkSignV2(args[1]);
System.out.format("#define GENUINE_SIZE 0x%04x%n", sizeAndHash[0]);
System.out.format("#define GENUINE_HASH 0x%04x%n", sizeAndHash[1] ^ 0x14131211);
String extra = "\n" +
"// #define GET_GENUINE_CLASS_NAME function_name_for_get_genuine_class_name\n" +
"// #define GET_GENUINE_PACKAGE_NAME function_name_for_get_genuine_package_name\n" +
"\n" +
"/* define to turn off maps check */\n" +
"// #define NO_CHECK_MAPS\n" +
"\n" +
"#ifndef NO_CHECK_MAPS\n" +
"/* define to anti odex */\n" +
"// #define ANTI_ODEX\n" +
"\n" +
"/* define to anti overlay */\n" +
"// #define ANTI_OVERLAY\n" +
"#endif\n" +
"\n" +
"/* define to check plt hook for jniRegisterNativeMethods */\n" +
"// #define CHECK_JNI_REGISTER_NATIVE_METHODS\n" +
"\n" +
"/* define to turn off xposed check */\n" +
"// #define NO_CHECK_XPOSED\n" +
"\n" +
"/* define to turn on xposed-epic check\n" +
" */\n" +
"// #define CHECK_XPOSED_EPIC\n" +
"\n" +
"/* genuine false handler */\n" +
"// #define GENUINE_FALSE_CRASH\n" +
"// #define GENUINE_FALSE_NATIVE\n" +
"\n" +
"/* genuine fake handler */\n" +
"// #define GENUINE_FAKE_CRASH\n" +
"#define GENUINE_FAKE_NATIVE\n" +
"\n" +
"/* genuine overlay handler */\n" +
"// #define GENUINE_OVERLAY_CRASH\n" +
"// #define GENUINE_OVERLAY_NATIVE\n" +
"\n" +
"/* genuine odex handler */\n" +
"// #define GENUINE_ODEX_CRASH\n" +
"// #define GENUINE_ODEX_NATIVE\n" +
"\n" +
"/* genuine dex handler */\n" +
"// #define GENUINE_DEX_CRASH\n" +
"// #define GENUINE_DEX_NATIVE\n" +
"\n" +
"/* genuine proxy handler */\n" +
"// #define GENUINE_PROXY_CRASH\n" +
"// #define GENUINE_PROXY_NATIVE\n" +
"\n" +
"/* genuine error handler */\n" +
"// #define GENUINE_ERROR_CRASH\n" +
"#define GENUINE_ERROR_NATIVE\n" +
"\n" +
"/* genuine fatal handler */\n" +
"// #define GENUINE_FATAL_CRASH\n" +
"#define GENUINE_FATAL_NATIVE\n" +
"\n" +
"/* genuine noapk handler */\n" +
"// #define GENUINE_NOAPK_CRASH\n" +
"#define GENUINE_NOAPK_NATIVE";
System.out.print(extra);
}
}