public void publicizeResources(File arscFile) throws AndrolibException { byte[] data = new byte[(int) arscFile.length()]; InputStream in = null; OutputStream out = null; try { in = new FileInputStream(arscFile); in.read(data); publicizeResources(data); out = new FileOutputStream(arscFile); out.write(data); } catch (IOException ex) { throw new AndrolibException(ex); } finally { if (in != null) { try { in.close(); } catch (IOException ex) { } } if (out != null) { try { out.close(); } catch (IOException ex) { } } } }
public void decodeSourcesSmali( File apkFile, File outDir, String filename, boolean debug, String debugLinePrefix, boolean bakdeb, int api) throws AndrolibException { try { File smaliDir; if (filename.equalsIgnoreCase("classes.dex")) { smaliDir = new File(outDir, SMALI_DIRNAME); } else { smaliDir = new File(outDir, SMALI_DIRNAME + "_" + filename.substring(0, filename.indexOf("."))); } OS.rmdir(smaliDir); smaliDir.mkdirs(); LOGGER.info("Baksmaling " + filename + "..."); SmaliDecoder.decode(apkFile, smaliDir, filename, debug, debugLinePrefix, bakdeb, api); } catch (BrutException ex) { throw new AndrolibException(ex); } }
private File getFrameworkDir() throws AndrolibException { File dir = new File( System.getProperty("user.home") + File.separatorChar + "apktool" + File.separatorChar + "framework"); if (!dir.exists()) { if (!dir.mkdirs()) { throw new AndrolibException("Can't create directory: " + dir); } } return dir; }
public boolean buildManifest(ExtFile appDir, Map<String, Object> usesFramework) throws BrutException { try { if (!new File(appDir, "AndroidManifest.xml").exists()) { return false; } if (!apkOptions.forceBuildAll) { LOGGER.info("Checking whether resources has changed..."); } File apkDir = new File(appDir, APK_DIRNAME); if (apkOptions.debugMode) { mAndRes.remove_application_debug(new File(apkDir, "AndroidManifest.xml").getAbsolutePath()); } if (apkOptions.forceBuildAll || isModified( newFiles(APK_MANIFEST_FILENAMES, appDir), newFiles(APK_MANIFEST_FILENAMES, apkDir))) { LOGGER.info("Building AndroidManifest.xml..."); File apkFile = File.createTempFile("APKTOOL", null); apkFile.delete(); File ninePatch = new File(appDir, "9patch"); if (!ninePatch.exists()) { ninePatch = null; } mAndRes.aaptPackage( apkFile, new File(appDir, "AndroidManifest.xml"), null, ninePatch, null, parseUsesFramework(usesFramework)); Directory tmpDir = new ExtFile(apkFile).getDirectory(); tmpDir.copyToDir(apkDir, APK_MANIFEST_FILENAMES); } return true; } catch (IOException | DirectoryException ex) { throw new AndrolibException(ex); } catch (AndrolibException ex) { LOGGER.warning("Parse AndroidManifest.xml failed, treat it as raw file."); return buildManifestRaw(appDir); } }
public boolean detectWhetherAppIsFramework(File appDir) throws AndrolibException { File publicXml = new File(appDir, "res/values/public.xml"); if (!publicXml.exists()) { return false; } Iterator<String> it; try { it = IOUtils.lineIterator(new FileReader(new File(appDir, "res/values/public.xml"))); } catch (FileNotFoundException ex) { throw new AndrolibException("Could not detect whether app is framework one", ex); } it.next(); it.next(); return it.next().contains("0x01"); }
public void buildLib(File appDir) throws AndrolibException { File working = new File(appDir, "lib"); if (!working.exists()) { return; } File stored = new File(appDir, APK_DIRNAME + "/lib"); if (apkOptions.forceBuildAll || isModified(working, stored)) { LOGGER.info("Copying libs..."); try { OS.rmdir(stored); OS.cpdir(working, stored); } catch (BrutException ex) { throw new AndrolibException(ex); } } }
public boolean buildSourcesJava(File appDir) throws AndrolibException { File javaDir = new File(appDir, "src"); if (!javaDir.exists()) { return false; } File dex = new File(appDir, APK_DIRNAME + "/classes.dex"); if (!apkOptions.forceBuildAll) { LOGGER.info("Checking whether sources has changed..."); } if (apkOptions.forceBuildAll || isModified(javaDir, dex)) { LOGGER.info("Building java sources..."); dex.delete(); new AndrolibJava().build(javaDir, dex); } return true; }
public boolean buildSourcesSmali(File appDir, String folder, String filename) throws AndrolibException { ExtFile smaliDir = new ExtFile(appDir, folder); if (!smaliDir.exists()) { return false; } File dex = new File(appDir, APK_DIRNAME + "/" + filename); if (!apkOptions.forceBuildAll) { LOGGER.info("Checking whether sources has changed..."); } if (apkOptions.forceBuildAll || isModified(smaliDir, dex)) { LOGGER.info("Smaling " + folder + " folder into " + filename + "..."); dex.delete(); SmaliBuilder.build(smaliDir, dex, apkOptions.debugMode); } return true; }
public boolean buildSourcesRaw(File appDir, String filename) throws AndrolibException { File working = new File(appDir, filename); if (!working.exists()) { return false; } File stored = new File(appDir, APK_DIRNAME + "/" + filename); if (apkOptions.forceBuildAll || isModified(working, stored)) { LOGGER.info("Copying " + appDir.toString() + " " + filename + " file..."); try { BrutIO.copyAndClose(new FileInputStream(working), new FileOutputStream(stored)); return true; } catch (IOException ex) { throw new AndrolibException(ex); } } return true; }
private void insertFile( Path apkPath, Map<String, String> zip_properties, File insert, String method, Path location) throws AndrolibException, IOException { // ZipFileSystem only writes at .close() // http://mail.openjdk.java.net/pipermail/nio-dev/2012-July/001764.html try (FileSystem fs = FileSystems.newFileSystem(apkPath, null)) { Path root = fs.getPath("/"); // in order to get the path relative to the zip, we strip off the absolute path, minus what we // already have in the zip. thus /var/files/apktool/apk/unknown/folder/file => /folder/file Path dest = fs.getPath(root.toString(), insert.getAbsolutePath().replace(location.toString(), "")); Path newFile = Paths.get(insert.getAbsolutePath()); Files.copy(newFile, dest, StandardCopyOption.REPLACE_EXISTING); fs.close(); } }
public File getFrameworkApk(int id, String frameTag) throws AndrolibException { File dir = getFrameworkDir(); File apk; if (frameTag != null) { apk = new File(dir, String.valueOf(id) + '-' + frameTag + ".apk"); if (apk.exists()) { return apk; } } apk = new File(dir, String.valueOf(id) + ".apk"); if (apk.exists()) { return apk; } if (id == 1) { InputStream in = null; OutputStream out = null; try { in = AndrolibResources.class.getResourceAsStream("/brut/androlib/android-framework.jar"); out = new FileOutputStream(apk); IOUtils.copy(in, out); return apk; } catch (IOException ex) { throw new AndrolibException(ex); } finally { if (in != null) { try { in.close(); } catch (IOException ex) { } } if (out != null) { try { out.close(); } catch (IOException ex) { } } } } throw new CantFindFrameworkResException(id); }
public void writeOriginalFiles(ExtFile apkFile, File outDir) throws AndrolibException { LOGGER.info("Copying original files..."); File originalDir = new File(outDir, "original"); if (!originalDir.exists()) { originalDir.mkdirs(); } try { Directory in = apkFile.getDirectory(); if (in.containsFile("AndroidManifest.xml")) { in.copyToDir(originalDir, "AndroidManifest.xml"); } if (in.containsDir("META-INF")) { in.copyToDir(originalDir, "META-INF"); } } catch (DirectoryException ex) { throw new AndrolibException(ex); } }
public void buildCopyOriginalFiles(File appDir) throws AndrolibException { if (apkOptions.copyOriginalFiles) { File originalDir = new File(appDir, "original"); if (originalDir.exists()) { try { LOGGER.info("Copy original files..."); Directory in = (new ExtFile(originalDir)).getDirectory(); if (in.containsFile("AndroidManifest.xml")) { LOGGER.info("Copy AndroidManifest.xml..."); in.copyToDir(new File(appDir, APK_DIRNAME), "AndroidManifest.xml"); } if (in.containsDir("META-INF")) { LOGGER.info("Copy META-INF..."); in.copyToDir(new File(appDir, APK_DIRNAME), "META-INF"); } } catch (DirectoryException ex) { throw new AndrolibException(ex); } } } }
public void buildApk(File appDir, File outApk) throws AndrolibException { LOGGER.info("Building apk file..."); if (outApk.exists()) { outApk.delete(); } else { File outDir = outApk.getParentFile(); if (outDir != null && !outDir.exists()) { outDir.mkdirs(); } } File assetDir = new File(appDir, "assets"); if (!assetDir.exists()) { assetDir = null; } mAndRes.aaptPackage(outApk, null, null, new File(appDir, APK_DIRNAME), assetDir, null); }
private void insertFolder( Path apkPath, Map<String, String> zip_properties, File insert, String method, Path location) throws AndrolibException, IOException { try (FileSystem fs = FileSystems.newFileSystem(apkPath, null)) { Path root = fs.getPath("/"); Path dest = fs.getPath(root.toString(), insert.getAbsolutePath().replace(location.toString(), "")); Path parent = dest.normalize(); // check for folder existing in apkFileSystem if (parent != null && Files.notExists(parent)) { if (!Files.isDirectory(parent, LinkOption.NOFOLLOW_LINKS)) { Files.createDirectories(parent); } } fs.close(); } }
public boolean buildResourcesFull(File appDir, Map<String, Object> usesFramework) throws AndrolibException { try { if (!new File(appDir, "res").exists()) { return false; } if (!apkOptions.forceBuildAll) { LOGGER.info("Checking whether resources has changed..."); } File apkDir = new File(appDir, APK_DIRNAME); if (apkOptions.forceBuildAll || isModified( newFiles(APP_RESOURCES_FILENAMES, appDir), newFiles(APK_RESOURCES_FILENAMES, apkDir))) { LOGGER.info("Building resources..."); File apkFile = File.createTempFile("APKTOOL", null); apkFile.delete(); File ninePatch = new File(appDir, "9patch"); if (!ninePatch.exists()) { ninePatch = null; } mAndRes.aaptPackage( apkFile, new File(appDir, "AndroidManifest.xml"), new File(appDir, "res"), ninePatch, null, parseUsesFramework(usesFramework)); Directory tmpDir = new ExtFile(apkFile).getDirectory(); tmpDir.copyToDir( apkDir, tmpDir.containsDir("res") ? APK_RESOURCES_FILENAMES : APK_RESOURCES_WITHOUT_RES_FILENAMES); // delete tmpDir apkFile.delete(); } return true; } catch (IOException | BrutException ex) { throw new AndrolibException(ex); } }
public void buildUnknownFiles(File appDir, File outFile, Map<String, Object> meta) throws AndrolibException { File file; Path globalPath = Paths.get(appDir.getPath() + File.separatorChar + UNK_DIRNAME); if (meta.containsKey("unknownFiles")) { LOGGER.info("Copying unknown files/dir..."); Map<String, String> files = (Map<String, String>) meta.get("unknownFiles"); try { // set our filesystem options Map<String, String> zip_properties = new HashMap<>(); zip_properties.put("create", "false"); zip_properties.put("encoding", "UTF-8"); // create filesystem Path path = Paths.get(outFile.getAbsolutePath()); // loop through files inside for (Map.Entry<String, String> entry : files.entrySet()) { file = new File(globalPath.toFile(), entry.getKey()); if (file.isFile() && file.exists()) { insertFolder( path, zip_properties, file.getParentFile(), entry.getValue(), globalPath.toAbsolutePath()); insertFile(path, zip_properties, file, entry.getValue(), globalPath.toAbsolutePath()); } } } catch (IOException ex) { throw new AndrolibException(ex); } } }
public void aaptPackage( File apkFile, File manifest, File resDir, File rawDir, File assetDir, File[] include, boolean update, boolean framework) throws AndrolibException { List<String> cmd = new ArrayList<String>(); cmd.add("aapt"); cmd.add("p"); cmd.add("-v"); // mega debug mode.@todo REMOVE ON FINAL if (update) { cmd.add("-u"); } if (mMinSdkVersion != null) { cmd.add("--min-sdk-version"); cmd.add(mMinSdkVersion); } if (mTargetSdkVersion != null) { cmd.add("--target-sdk-version"); cmd.add(mTargetSdkVersion); } if (mMaxSdkVersion != null) { cmd.add("--max-sdk-version"); cmd.add(mMaxSdkVersion); } cmd.add("-F"); cmd.add(apkFile.getAbsolutePath()); if (framework) { cmd.add("-x"); // cmd.add("-0"); // cmd.add("arsc"); } if (include != null) { for (File file : include) { cmd.add("-I"); cmd.add(file.getPath()); } } if (resDir != null) { cmd.add("-S"); cmd.add(resDir.getAbsolutePath()); } if (manifest != null) { cmd.add("-M"); cmd.add(manifest.getAbsolutePath()); } if (assetDir != null) { cmd.add("-A"); cmd.add(assetDir.getAbsolutePath()); } if (rawDir != null) { cmd.add(rawDir.getAbsolutePath()); } try { OS.exec(cmd.toArray(new String[0])); } catch (BrutException ex) { throw new AndrolibException(ex); } }
private boolean isModified(File working, File stored) { return !stored.exists() || BrutIO.recursiveModifiedTime(working) > BrutIO.recursiveModifiedTime(stored); }