From 1ac14a1082b8f5a016ee74d3f3d5a6f0521d0558 Mon Sep 17 00:00:00 2001 From: Ben Gruver Date: Wed, 7 Aug 2019 13:43:15 -0700 Subject: [PATCH] Add a workaround for the sym linked vdex files in api 28 In api 28, the vdex files in, e.g. the framework/arm directory are actually just sym links to a shared vdex file in the framework directory. However, the sym links use an absolute path, and so they don't resolve correctly in the loop mounted system image. As a simple workaround, we'll just search upward one directory in the path if the vdex file can't be resolved. --- .../java/org/jf/dexlib2/DexFileFactory.java | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/dexlib2/src/main/java/org/jf/dexlib2/DexFileFactory.java b/dexlib2/src/main/java/org/jf/dexlib2/DexFileFactory.java index e19eb528..ad2fbf02 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/DexFileFactory.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/DexFileFactory.java @@ -500,9 +500,22 @@ public final class DexFileFactory { @Nullable @Override public byte[] getVdex() { if (!loadedVdex) { - if (vdexFile.exists()) { + File candidateFile = vdexFile; + + if (!candidateFile.exists()) { + // On api 28, for framework files, the vdex file in the architecture-specific directory is just a + // symlink to a common vdex file in the framework directory. When loop-mounting a system image, that + // symlink won't resolve because it uses an absolute path. As a workaround, we'll just search upward + // one directory to see if it's there. + File parentDirectory = candidateFile.getParentFile().getParentFile(); + if (parentDirectory != null) { + candidateFile = new File(parentDirectory, vdexFile.getName()); + } + } + + if (candidateFile.exists()) { try { - buf = ByteStreams.toByteArray(new FileInputStream(vdexFile)); + buf = ByteStreams.toByteArray(new FileInputStream(candidateFile)); } catch (FileNotFoundException e) { buf = null; } catch (IOException ex) {