Commit c3f7a049 authored by Skylot's avatar Skylot

fix: ignore incorrect dex files in apk (#700)

parent 3eee83c2
...@@ -20,6 +20,7 @@ import org.slf4j.Logger; ...@@ -20,6 +20,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import com.android.dex.Dex; import com.android.dex.Dex;
import com.android.dex.DexException;
import jadx.core.utils.AsmUtils; import jadx.core.utils.AsmUtils;
import jadx.core.utils.exceptions.DecodeException; import jadx.core.utils.exceptions.DecodeException;
...@@ -52,7 +53,7 @@ public class InputFile { ...@@ -52,7 +53,7 @@ public class InputFile {
String fileName = file.getName(); String fileName = file.getName();
if (fileName.endsWith(".dex")) { if (fileName.endsWith(".dex")) {
addDexFile(fileName, new Dex(file), file.toPath()); addDexFile(fileName, file.toPath());
return; return;
} }
if (fileName.endsWith(".smali")) { if (fileName.endsWith(".smali")) {
...@@ -60,12 +61,12 @@ public class InputFile { ...@@ -60,12 +61,12 @@ public class InputFile {
SmaliOptions options = new SmaliOptions(); SmaliOptions options = new SmaliOptions();
options.outputDexFile = output.toAbsolutePath().toString(); options.outputDexFile = output.toAbsolutePath().toString();
Smali.assemble(options, file.getAbsolutePath()); Smali.assemble(options, file.getAbsolutePath());
addDexFile("", new Dex(output.toFile()), output); addDexFile(fileName, output);
return; return;
} }
if (fileName.endsWith(".class")) { if (fileName.endsWith(".class")) {
for (Path path : loadFromClassFile(file)) { for (Path path : loadFromClassFile(file)) {
addDexFile(path); addDexFile(fileName, path);
} }
return; return;
} }
...@@ -80,7 +81,7 @@ public class InputFile { ...@@ -80,7 +81,7 @@ public class InputFile {
} }
if (fileName.endsWith(".jar")) { if (fileName.endsWith(".jar")) {
for (Path path : loadFromJar(file.toPath())) { for (Path path : loadFromJar(file.toPath())) {
addDexFile(path); addDexFile(fileName, path);
} }
return; return;
} }
...@@ -96,18 +97,6 @@ public class InputFile { ...@@ -96,18 +97,6 @@ public class InputFile {
LOG.warn("No dex files found in {}", file); 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 { private boolean loadFromZip(String ext) throws IOException, DecodeException {
int index = 0; int index = 0;
try (ZipFile zf = new ZipFile(file)) { try (ZipFile zf = new ZipFile(file)) {
...@@ -127,9 +116,8 @@ public class InputFile { ...@@ -127,9 +116,8 @@ public class InputFile {
|| entryName.endsWith(instantRunDexSuffix)) { || entryName.endsWith(instantRunDexSuffix)) {
switch (ext) { switch (ext) {
case ".dex": case ".dex":
Path path = makeDexBuf(entryName, inputStream); Path path = copyToTmpDex(entryName, inputStream);
if (path != null) { if (addDexFile(entryName, path)) {
addDexFile(entryName, path);
index++; index++;
} }
break; break;
...@@ -163,8 +151,32 @@ public class InputFile { ...@@ -163,8 +151,32 @@ public class InputFile {
return index > 0; 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 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 @Nullable
private Path makeDexBuf(String entryName, InputStream inputStream) { private Path copyToTmpDex(String entryName, InputStream inputStream) {
try { try {
Path path = FileUtils.createTempFile(".dex"); Path path = FileUtils.createTempFile(".dex");
Files.copy(inputStream, path, StandardCopyOption.REPLACE_EXISTING); Files.copy(inputStream, path, StandardCopyOption.REPLACE_EXISTING);
......
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);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment