public static ResContainer resourceFileLink(ResourceFile resFile) { return new ResContainer(resFile.getName(), Collections.emptyList(), resFile, DataType.RES_LINK); }
private JCertificate getCertificate(List<ResourceFile> resources) { if (resources.isEmpty()) { return null; } for (ResourceFile rf : resources) { if (rf.getZipRef() != null) { String rfName = rf.getName().toUpperCase(); if (rfName.endsWith(".DSA") || rfName.endsWith(".RSA")) { return new JCertificate(rf); } } } return null; }
private static ResContainer decodeImage(ResourceFile rf, InputStream inputStream) { String name = rf.getName(); if (name.endsWith(".9.png")) { Res9patchStreamDecoder decoder = new Res9patchStreamDecoder(); ByteArrayOutputStream os = new ByteArrayOutputStream(); try { decoder.decode(inputStream, os); return ResContainer.decodedData(rf.getName(), os.toByteArray()); } catch (Exception e) { LOG.error("Failed to decode 9-patch png image, path: {}", name, e); } } return ResContainer.resourceFileLink(rf); }
public static ApkSignature getApkSignature(JadxWrapper wrapper) { // Only show the ApkSignature node if an AndroidManifest.xml is present. // Without a manifest the Google ApkVerifier refuses to work. if (wrapper.getResources().stream().noneMatch(r -> "AndroidManifest.xml".equals(r.getName()))) { return null; } File openFile = wrapper.getOpenFile(); return new ApkSignature(openFile); }
@Override public String getContent() { try { ResourceFile.ZipRef zipRef = rf.getZipRef(); if (zipRef == null) { File file = new File(rf.getName()); try (InputStream inputStream = new BufferedInputStream(new FileInputStream(file))) { return CertificateManager.decode(inputStream); } } else { try (ZipFile zipFile = new ZipFile(zipRef.getZipFile())) { ZipEntry entry = zipFile.getEntry(zipRef.getEntryName()); if (entry == null) { throw new IOException("Zip entry not found: " + zipRef); } if (!ZipSecurity.isValidZipEntry(entry)) { return null; } try (InputStream inputStream = new BufferedInputStream(zipFile.getInputStream(entry))) { return CertificateManager.decode(inputStream); } } } } catch (Exception e) { LOG.error("Certificate decode error: {}", rf.getName(), e); return "Decode error: " + e.getMessage(); } } }
public static <T> T decodeStream(ResourceFile rf, ResourceDecoder<T> decoder) throws JadxException { try { ZipRef zipRef = rf.getZipRef(); if (zipRef == null) { File file = new File(rf.getName()); try (InputStream inputStream = new BufferedInputStream(new FileInputStream(file))) { return decoder.decode(file.length(), inputStream); } } else { try (ZipFile zipFile = new ZipFile(zipRef.getZipFile())) { ZipEntry entry = zipFile.getEntry(zipRef.getEntryName()); if (entry == null) { throw new IOException("Zip entry not found: " + zipRef); } if (!ZipSecurity.isValidZipEntry(entry)) { return null; } try (InputStream inputStream = new BufferedInputStream(zipFile.getInputStream(entry))) { return decoder.decode(entry.getSize(), inputStream); } } } } catch (Exception e) { throw new JadxException("Error decode: " + rf.getName(), e); } }
@Override public String getSyntaxName() { if (resFile == null) { return null; } switch (resFile.getType()) { case CODE: return super.getSyntaxName(); case MANIFEST: case XML: return SyntaxConstants.SYNTAX_STYLE_XML; default: String syntax = getSyntaxByExtension(resFile.getName()); if (syntax != null) { return syntax; } return super.getSyntaxName(); } }
static ResContainer loadContent(JadxDecompiler jadxRef, ResourceFile rf) { try { return decodeStream(rf, (size, is) -> loadContent(jadxRef, rf, is)); } catch (JadxException e) { LOG.error("Decode error", e); CodeWriter cw = new CodeWriter(); cw.add("Error decode ").add(rf.getType().toString().toLowerCase()); cw.startLine(Utils.getStackTrace(e.getCause())); return ResContainer.textResource(rf.getName(), cw); } }
private static ResContainer loadContent(JadxDecompiler jadxRef, ResourceFile rf, InputStream inputStream) throws IOException { switch (rf.getType()) { case MANIFEST: case XML: CodeWriter content = jadxRef.getXmlParser().parse(inputStream); return ResContainer.textResource(rf.getName(), content); case ARSC: return new ResTableParser().decodeFiles(inputStream); case IMG: return decodeImage(rf, inputStream); default: return ResContainer.resourceFileLink(rf); } }