fix: ignore incorrect dex files in apk (#700)
This commit is contained in:
@@ -20,6 +20,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.android.dex.Dex;
|
||||
import com.android.dex.DexException;
|
||||
|
||||
import jadx.core.utils.AsmUtils;
|
||||
import jadx.core.utils.exceptions.DecodeException;
|
||||
@@ -52,7 +53,7 @@ public class InputFile {
|
||||
String fileName = file.getName();
|
||||
|
||||
if (fileName.endsWith(".dex")) {
|
||||
addDexFile(fileName, new Dex(file), file.toPath());
|
||||
addDexFile(fileName, file.toPath());
|
||||
return;
|
||||
}
|
||||
if (fileName.endsWith(".smali")) {
|
||||
@@ -60,12 +61,12 @@ public class InputFile {
|
||||
SmaliOptions options = new SmaliOptions();
|
||||
options.outputDexFile = output.toAbsolutePath().toString();
|
||||
Smali.assemble(options, file.getAbsolutePath());
|
||||
addDexFile("", new Dex(output.toFile()), output);
|
||||
addDexFile(fileName, output);
|
||||
return;
|
||||
}
|
||||
if (fileName.endsWith(".class")) {
|
||||
for (Path path : loadFromClassFile(file)) {
|
||||
addDexFile(path);
|
||||
addDexFile(fileName, path);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -80,7 +81,7 @@ public class InputFile {
|
||||
}
|
||||
if (fileName.endsWith(".jar")) {
|
||||
for (Path path : loadFromJar(file.toPath())) {
|
||||
addDexFile(path);
|
||||
addDexFile(fileName, path);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -96,18 +97,6 @@ public class InputFile {
|
||||
LOG.warn("No dex files found in {}", file);
|
||||
}
|
||||
|
||||
private void addDexFile(Path path) throws IOException {
|
||||
addDexFile(path.getFileName().toString(), path);
|
||||
}
|
||||
|
||||
private void addDexFile(String fileName, Path path) throws IOException {
|
||||
addDexFile(fileName, new Dex(Files.readAllBytes(path)), path);
|
||||
}
|
||||
|
||||
private void addDexFile(String fileName, Dex dexBuf, Path path) {
|
||||
dexFiles.add(new DexFile(this, fileName, dexBuf, path));
|
||||
}
|
||||
|
||||
private boolean loadFromZip(String ext) throws IOException, DecodeException {
|
||||
int index = 0;
|
||||
try (ZipFile zf = new ZipFile(file)) {
|
||||
@@ -127,9 +116,8 @@ public class InputFile {
|
||||
|| entryName.endsWith(instantRunDexSuffix)) {
|
||||
switch (ext) {
|
||||
case ".dex":
|
||||
Path path = makeDexBuf(entryName, inputStream);
|
||||
if (path != null) {
|
||||
addDexFile(entryName, path);
|
||||
Path path = copyToTmpDex(entryName, inputStream);
|
||||
if (addDexFile(entryName, path)) {
|
||||
index++;
|
||||
}
|
||||
break;
|
||||
@@ -163,8 +151,32 @@ public class InputFile {
|
||||
return index > 0;
|
||||
}
|
||||
|
||||
private boolean addDexFile(String entryName, @Nullable Path filePath) {
|
||||
if (filePath == null) {
|
||||
return false;
|
||||
}
|
||||
Dex dexBuf = loadDexBufFromPath(filePath, entryName);
|
||||
if (dexBuf == null) {
|
||||
return false;
|
||||
}
|
||||
dexFiles.add(new DexFile(this, entryName, dexBuf, filePath));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Path makeDexBuf(String entryName, InputStream inputStream) {
|
||||
private Dex loadDexBufFromPath(Path path, String entryName) {
|
||||
try {
|
||||
return new Dex(Files.readAllBytes(path));
|
||||
} catch (DexException e) {
|
||||
LOG.error("Failed to load dex file: {}, error: {}", entryName, e.getMessage());
|
||||
} catch (Exception e) {
|
||||
LOG.error("Failed to load dex file: {}, error: {}", entryName, e.getMessage(), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Path copyToTmpDex(String entryName, InputStream inputStream) {
|
||||
try {
|
||||
Path path = FileUtils.createTempFile(".dex");
|
||||
Files.copy(inputStream, path, StandardCopyOption.REPLACE_EXISTING);
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
package jadx.core.utils.files;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import jadx.core.utils.exceptions.DecodeException;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.hasSize;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
|
||||
class InputFileTest {
|
||||
private static final String TEST_SAMPLES_DIR = "test-samples/";
|
||||
|
||||
@Test
|
||||
public void testApkWithFakeDex() throws IOException, DecodeException {
|
||||
File sample = getFileFromSampleDir("app-with-fake-dex.apk");
|
||||
|
||||
List<InputFile> list = new ArrayList<>();
|
||||
InputFile.addFilesFrom(sample, list, false);
|
||||
assertThat(list, hasSize(1));
|
||||
InputFile inputFile = list.get(0);
|
||||
assertThat(inputFile.getDexFiles(), hasSize(1));
|
||||
}
|
||||
|
||||
private static File getFileFromSampleDir(String fileName) {
|
||||
URL resource = InputFileTest.class.getClassLoader().getResource(TEST_SAMPLES_DIR + fileName);
|
||||
assertThat(resource, notNullValue());
|
||||
String pathStr = resource.getFile();
|
||||
return new File(pathStr);
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Reference in New Issue
Block a user