forked from Konloch/bytecode-viewer
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathClassFileUtil.java
More file actions
135 lines (111 loc) · 4.71 KB
/
ClassFileUtil.java
File metadata and controls
135 lines (111 loc) · 4.71 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
package jd.cli.util;
import jd.core.CoreConstants;
import jd.core.model.classfile.constant.Constant;
import jd.core.model.classfile.constant.ConstantClass;
import jd.core.model.classfile.constant.ConstantConstant;
import jd.core.model.classfile.constant.ConstantUtf8;
import jd.core.process.deserializer.ClassFormatException;
import jd.core.util.StringConstants;
import java.io.*;
public class ClassFileUtil {
private ClassFileUtil() {
}
/*
* Lecture rapide de la structure de la classe et extraction du nom du
* repoertoire de base.
*/
public static String ExtractDirectoryPath(String pathToClass) throws Exception {
DataInputStream dis = null;
String directoryPath = null;
try {
dis = new DataInputStream(
new BufferedInputStream(
new FileInputStream(pathToClass)));
int magic = dis.readInt();
if (magic != CoreConstants.JAVA_MAGIC_NUMBER)
throw new ClassFormatException("Invalid Java .class file");
/* int minor_version = */
dis.readUnsignedShort();
/* int major_version = */
dis.readUnsignedShort();
Constant[] constants = DeserializeConstants(dis);
/* int access_flags = */
dis.readUnsignedShort();
int this_class = dis.readUnsignedShort();
Constant c = constants[this_class];
if ((c == null) || (c.tag != ConstantConstant.CONSTANT_Class))
throw new ClassFormatException("Invalid contant pool");
c = constants[((ConstantClass) c).name_index];
if ((c == null) || (c.tag != ConstantConstant.CONSTANT_Utf8))
throw new ClassFormatException("Invalid contant pool");
String internalClassName = ((ConstantUtf8) c).bytes;
String pathSuffix = internalClassName.replace(
StringConstants.INTERNAL_PACKAGE_SEPARATOR, File.separatorChar) +
StringConstants.CLASS_FILE_SUFFIX;
int index = pathToClass.indexOf(pathSuffix);
if (index < 0)
throw new ClassFormatException("Invalid internal class name");
directoryPath = pathToClass.substring(0, index);
} finally {
if (dis != null)
try {
dis.close();
} catch (IOException e) {
}
}
return directoryPath;
}
public static String ExtractInternalPath(
String directoryPath, String pathToClass) {
if ((directoryPath == null) || (pathToClass == null) ||
!pathToClass.startsWith(directoryPath))
return null;
String s = pathToClass.substring(directoryPath.length());
return s.replace(File.separatorChar, StringConstants.INTERNAL_PACKAGE_SEPARATOR);
}
private static Constant[] DeserializeConstants(DataInputStream dis)
throws IOException {
int count = dis.readUnsignedShort();
if (count == 0)
return null;
Constant[] constants = new Constant[count];
for (int i = 1; i < count; i++) {
byte tag = dis.readByte();
switch (tag) {
case ConstantConstant.CONSTANT_Class:
constants[i] = new ConstantClass(tag, dis.readUnsignedShort());
break;
case ConstantConstant.CONSTANT_Utf8:
constants[i] = new ConstantUtf8(tag, dis.readUTF());
break;
case ConstantConstant.CONSTANT_Long:
case ConstantConstant.CONSTANT_Double:
dis.readInt();
dis.readInt();
i++;
break;
case ConstantConstant.CONSTANT_Fieldref:
case ConstantConstant.CONSTANT_Methodref:
case ConstantConstant.CONSTANT_InterfaceMethodref:
case ConstantConstant.CONSTANT_NameAndType:
dis.readUnsignedShort();
dis.readUnsignedShort();
break;
case ConstantConstant.CONSTANT_Integer:
case ConstantConstant.CONSTANT_Float:
dis.readInt();
break;
case ConstantConstant.CONSTANT_String:
dis.readUnsignedShort();
break;
case 15:
case 16:
case 18:
throw new IllegalArgumentException("JD-GUI does not support Java 8 as of yet");
default:
throw new ClassFormatException("Invalid constant pool entry");
}
}
return constants;
}
}