forked from xxDark/JavaShellcodeInjector
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathJVM.java
More file actions
208 lines (168 loc) · 6.92 KB
/
JVM.java
File metadata and controls
208 lines (168 loc) · 6.92 KB
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
package one.helfy;
import me.xdark.shell.JVMUtil;
import me.xdark.shell.NativeLibrary;
import sun.misc.Unsafe;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.TreeSet;
public final class JVM {
private static final Unsafe unsafe = JVMUtil.UNSAFE;
private static final NativeLibrary JVM;
private final Map<String, Type> types = new LinkedHashMap<>();
private final Map<String, Number> constants = new LinkedHashMap<>();
public JVM() {
readVmTypes(readVmStructs());
readVmIntConstants();
readVmLongConstants();
}
private Map<String, Set<Field>> readVmStructs() {
long entry = getSymbol("gHotSpotVMStructs");
long typeNameOffset = getSymbol("gHotSpotVMStructEntryTypeNameOffset");
long fieldNameOffset = getSymbol("gHotSpotVMStructEntryFieldNameOffset");
long typeStringOffset = getSymbol("gHotSpotVMStructEntryTypeStringOffset");
long isStaticOffset = getSymbol("gHotSpotVMStructEntryIsStaticOffset");
long offsetOffset = getSymbol("gHotSpotVMStructEntryOffsetOffset");
long addressOffset = getSymbol("gHotSpotVMStructEntryAddressOffset");
long arrayStride = getSymbol("gHotSpotVMStructEntryArrayStride");
Map<String, Set<Field>> structs = new HashMap<>();
for (;; entry += arrayStride) {
String typeName = getStringRef(entry + typeNameOffset);
String fieldName = getStringRef(entry + fieldNameOffset);
if (fieldName == null) break;
String typeString = getStringRef(entry + typeStringOffset);
boolean isStatic = getInt(entry + isStaticOffset) != 0;
long offset = getLong(entry + (isStatic ? addressOffset : offsetOffset));
Set<Field> fields = structs.computeIfAbsent(typeName, k -> new TreeSet<>());
fields.add(new Field(fieldName, typeString, offset, isStatic));
}
return structs;
}
private void readVmTypes(Map<String, Set<Field>> structs) {
long entry = getSymbol("gHotSpotVMTypes");
long typeNameOffset = getSymbol("gHotSpotVMTypeEntryTypeNameOffset");
long superclassNameOffset = getSymbol("gHotSpotVMTypeEntrySuperclassNameOffset");
long isOopTypeOffset = getSymbol("gHotSpotVMTypeEntryIsOopTypeOffset");
long isIntegerTypeOffset = getSymbol("gHotSpotVMTypeEntryIsIntegerTypeOffset");
long isUnsignedOffset = getSymbol("gHotSpotVMTypeEntryIsUnsignedOffset");
long sizeOffset = getSymbol("gHotSpotVMTypeEntrySizeOffset");
long arrayStride = getSymbol("gHotSpotVMTypeEntryArrayStride");
for (;; entry += arrayStride) {
String typeName = getStringRef(entry + typeNameOffset);
if (typeName == null) break;
String superclassName = getStringRef(entry + superclassNameOffset);
boolean isOop = getInt(entry + isOopTypeOffset) != 0;
boolean isInt = getInt(entry + isIntegerTypeOffset) != 0;
boolean isUnsigned = getInt(entry + isUnsignedOffset) != 0;
int size = getInt(entry + sizeOffset);
Set<Field> fields = structs.get(typeName);
types.put(typeName, new Type(typeName, superclassName, size, isOop, isInt, isUnsigned, fields));
}
}
private void readVmIntConstants() {
long entry = getSymbol("gHotSpotVMIntConstants");
long nameOffset = getSymbol("gHotSpotVMIntConstantEntryNameOffset");
long valueOffset = getSymbol("gHotSpotVMIntConstantEntryValueOffset");
long arrayStride = getSymbol("gHotSpotVMIntConstantEntryArrayStride");
for (;; entry += arrayStride) {
String name = getStringRef(entry + nameOffset);
if (name == null) break;
int value = getInt(entry + valueOffset);
constants.put(name, value);
}
}
private void readVmLongConstants() {
long entry = getSymbol("gHotSpotVMLongConstants");
long nameOffset = getSymbol("gHotSpotVMLongConstantEntryNameOffset");
long valueOffset = getSymbol("gHotSpotVMLongConstantEntryValueOffset");
long arrayStride = getSymbol("gHotSpotVMLongConstantEntryArrayStride");
for (;; entry += arrayStride) {
String name = getStringRef(entry + nameOffset);
if (name == null) break;
long value = getLong(entry + valueOffset);
constants.put(name, value);
}
}
public byte getByte(long addr) {
return unsafe.getByte(addr);
}
public void putByte(long addr, byte val) {
unsafe.putByte(addr, val);
}
public short getShort(long addr) {
return unsafe.getShort(addr);
}
public void putShort(long addr, short val) {
unsafe.putShort(addr, val);
}
public int getInt(long addr) {
return unsafe.getInt(addr);
}
public void putInt(long addr, int val) {
unsafe.putInt(addr, val);
}
public long getLong(long addr) {
return unsafe.getLong(addr);
}
public void putLong(long addr, long val) {
unsafe.putLong(addr, val);
}
public long getAddress(long addr) {
return unsafe.getAddress(addr);
}
public void putAddress(long addr, long val) {
unsafe.putAddress(addr, val);
}
public String getString(long addr) {
if (addr == 0) {
return null;
}
char[] chars = new char[40];
int offset = 0;
for (byte b; (b = getByte(addr + offset)) != 0; ) {
if (offset >= chars.length) chars = Arrays.copyOf(chars, offset * 2);
chars[offset++] = (char) b;
}
return new String(chars, 0, offset);
}
public String getStringRef(long addr) {
return getString(getAddress(addr));
}
public long getSymbol(String name) {
long address = JVM.findEntry(name);
if (address == 0) {
throw new NoSuchElementException("No such symbol: " + name);
}
return getLong(address);
}
public Type type(String name) {
Type type = types.get(name);
if (type == null) {
throw new NoSuchElementException("No such type: " + name);
}
return type;
}
public Number constant(String name) {
Number constant = constants.get(name);
if (constant == null) {
throw new NoSuchElementException("No such constant: " + name);
}
return constant;
}
public int intConstant(String name) {
return constant(name).intValue();
}
public long longConstant(String name) {
return constant(name).longValue();
}
static {
try {
JVM = JVMUtil.findJvm();
} catch (Throwable t) {
throw new ExceptionInInitializerError(t);
}
}
}