fix: prevent collisions in method ids for java-input
This commit is contained in:
+12
-16
@@ -21,22 +21,22 @@ import jadx.api.plugins.utils.ZipSecurity;
|
||||
public class JavaFileLoader {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(JavaFileLoader.class);
|
||||
|
||||
public static final int MAX_MAGIC_SIZE = 4;
|
||||
public static final byte[] JAVA_CLASS_FILE_MAGIC = { (byte) 0xCA, (byte) 0xFE, (byte) 0xBA, (byte) 0xBE };
|
||||
public static final byte[] ZIP_FILE_MAGIC = { 0x50, 0x4B, 0x03, 0x04 };
|
||||
private static final int MAX_MAGIC_SIZE = 4;
|
||||
private static final byte[] JAVA_CLASS_FILE_MAGIC = { (byte) 0xCA, (byte) 0xFE, (byte) 0xBA, (byte) 0xBE };
|
||||
private static final byte[] ZIP_FILE_MAGIC = { 0x50, 0x4B, 0x03, 0x04 };
|
||||
|
||||
private static int classUniqId = 1;
|
||||
private int classUniqId = 1;
|
||||
|
||||
public static List<JavaClassReader> collectFiles(List<Path> inputFiles) {
|
||||
public List<JavaClassReader> collectFiles(List<Path> inputFiles) {
|
||||
return inputFiles.stream()
|
||||
.map(Path::toFile)
|
||||
.map(JavaFileLoader::loadFromFile)
|
||||
.map(this::loadFromFile)
|
||||
.filter(list -> !list.isEmpty())
|
||||
.flatMap(Collection::stream)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private static List<JavaClassReader> loadFromFile(File file) {
|
||||
private List<JavaClassReader> loadFromFile(File file) {
|
||||
try (InputStream inputStream = new BufferedInputStream(new FileInputStream(file))) {
|
||||
return loadReader(file, inputStream, file.getAbsolutePath());
|
||||
} catch (Exception e) {
|
||||
@@ -45,7 +45,7 @@ public class JavaFileLoader {
|
||||
}
|
||||
}
|
||||
|
||||
private static List<JavaClassReader> loadReader(File file, InputStream in, String inputFileName) throws IOException {
|
||||
private List<JavaClassReader> loadReader(File file, InputStream in, String inputFileName) throws IOException {
|
||||
byte[] magic = new byte[MAX_MAGIC_SIZE];
|
||||
if (in.read(magic) != magic.length) {
|
||||
return Collections.emptyList();
|
||||
@@ -61,7 +61,7 @@ public class JavaFileLoader {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
private static List<JavaClassReader> collectFromZip(File file) {
|
||||
private List<JavaClassReader> collectFromZip(File file) {
|
||||
List<JavaClassReader> result = new ArrayList<>();
|
||||
try {
|
||||
ZipSecurity.readZipEntries(file, (entry, in) -> {
|
||||
@@ -94,7 +94,7 @@ public class JavaFileLoader {
|
||||
int estimateSize = prefix.length + in.available();
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream(estimateSize);
|
||||
out.write(prefix);
|
||||
byte[] buffer = new byte[0xFFFF];
|
||||
byte[] buffer = new byte[8 * 1024];
|
||||
while (true) {
|
||||
int len = in.read(buffer);
|
||||
if (len == -1) {
|
||||
@@ -105,11 +105,7 @@ public class JavaFileLoader {
|
||||
return out.toByteArray();
|
||||
}
|
||||
|
||||
private static int getNextUniqId() {
|
||||
classUniqId++;
|
||||
if (classUniqId >= 0xFFFF) {
|
||||
classUniqId = 1;
|
||||
}
|
||||
return classUniqId;
|
||||
private int getNextUniqId() {
|
||||
return classUniqId++;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ public class JavaInputPlugin implements JadxInputPlugin {
|
||||
|
||||
@Override
|
||||
public ILoadResult loadFiles(List<Path> inputFiles) {
|
||||
List<JavaClassReader> readers = JavaFileLoader.collectFiles(inputFiles);
|
||||
List<JavaClassReader> readers = new JavaFileLoader().collectFiles(inputFiles);
|
||||
if (readers.isEmpty()) {
|
||||
return EmptyLoadResult.INSTANCE;
|
||||
}
|
||||
|
||||
+1
-1
@@ -78,7 +78,7 @@ public class ConstPoolReader {
|
||||
int descIdx = data.readU2();
|
||||
|
||||
JavaMethodRef mthRef = new JavaMethodRef();
|
||||
mthRef.initUniqId(clsReader, clsIdx, nameIdx, descIdx);
|
||||
mthRef.initUniqId(clsReader, idx, true);
|
||||
mthRef.setParentClassType(getClass(clsIdx));
|
||||
mthRef.setName(getUtf8(nameIdx));
|
||||
mthRef.setDescr(getUtf8(descIdx));
|
||||
|
||||
+3
-3
@@ -94,7 +94,7 @@ public class JavaClassData implements IClassData {
|
||||
methodRef.setParentClassType(classType);
|
||||
JavaMethodData method = new JavaMethodData(this, methodRef);
|
||||
for (int i = 0; i < methodsCount; i++) {
|
||||
parseMethod(reader, method, clsIdx);
|
||||
parseMethod(reader, method, i);
|
||||
mthConsumer.accept(method);
|
||||
}
|
||||
}
|
||||
@@ -112,7 +112,7 @@ public class JavaClassData implements IClassData {
|
||||
field.setAttributes(attributes);
|
||||
}
|
||||
|
||||
private void parseMethod(DataReader reader, JavaMethodData method, int clsIdx) {
|
||||
private void parseMethod(DataReader reader, JavaMethodData method, int id) {
|
||||
int accessFlags = reader.readU2();
|
||||
int nameIdx = reader.readU2();
|
||||
int descriptorIdx = reader.readU2();
|
||||
@@ -120,7 +120,7 @@ public class JavaClassData implements IClassData {
|
||||
|
||||
JavaMethodRef methodRef = method.getMethodRef();
|
||||
methodRef.reset();
|
||||
methodRef.initUniqId(clsReader, clsIdx, nameIdx, descriptorIdx);
|
||||
methodRef.initUniqId(clsReader, id, false);
|
||||
methodRef.setName(constPoolReader.getUtf8(nameIdx));
|
||||
methodRef.setDescr(constPoolReader.getUtf8(descriptorIdx));
|
||||
|
||||
|
||||
+9
-3
@@ -16,9 +16,15 @@ public class JavaMethodRef extends JavaMethodProto implements IMethodRef {
|
||||
return uniqId;
|
||||
}
|
||||
|
||||
public void initUniqId(JavaClassReader clsReader, int clsIdx, int nameIdx, int descIdx) {
|
||||
// TODO: check for id overlap
|
||||
this.uniqId = (clsReader.getId() & 0xFFF) << 20 | (clsIdx & 0xFF) << 12 | (nameIdx & 0xFF) << 4 | descIdx & 0xF;
|
||||
public void initUniqId(JavaClassReader clsReader, int id, boolean fromConstPool) {
|
||||
int readerId = clsReader.getId();
|
||||
if (readerId > 0xFFFF || id > 0x7FFF) {
|
||||
// loaded more than 65535 classes or more than 32767 methods in this class -> disable caching
|
||||
this.uniqId = 0;
|
||||
} else {
|
||||
int source = fromConstPool ? 0 : 0x8000;
|
||||
this.uniqId = (readerId & 0xFFFF) << 16 | source | id & 0x7FFF;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user