Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: converting standard XML to Android Binary XML format (AXML)

Tags:

I want to convert a plaintext AndroidManifest.xml file into the binary format Android uses to package it inside the final APK.

I want to do this in Java, since I need to do it on the android device itself (which is why this question is NOT a duplicate of: How to convert XML to Android Binary XML. I know you can use AAPT, but I need a java method)

There's plenty of tools around to decode the binary xml into a readable file, but nothing on how to do the opposite, which is what I want.

Any info or hint on how this could be achieved is appreciated.

like image 499
Master_T Avatar asked Apr 16 '15 08:04

Master_T


People also ask

What is Android binary XML?

Android uses a special format to save XML and resource files. Also resource files are XML files in the source folder, but all resources are packed into a single resource file called resources. arsc . The underlying format is chunk based and is capable for storing several different information.

How do I find AndroidManifest XML?

Just open your APK and in treeview select "AndroidManifest. xml". It will be readable just like that. and to edit it (that single file) without extracting other files?

Which tool is used to extract the AndroidManifest file from the APK file?

- [Instructor] The file AndroidManifest. xml is used to describe the functionality and requirements of an Android application. And it's generated as part of the build process for that Android application. This is a compiled XML binary file and, to read it, we'll use a tool called Apktool.


1 Answers

You may find a lot of command-line tools that can be used to compile and decompile the xml files for Android. Those tools are combined of several build tools including aapt (Android Asset Packaging Tools) to view, create, and update Zip-compatible archives (zip, jar, apk). Since This tool is a part of the Android SDK, There's no native implementation of it in Java.

Fortunately, self-compile-Android repository has all the necessary files in Java Native Interface (JNI). They are ready to be used from inside an Android App and capable of self-compilation, mutation, and viral spreading.

Here a list of available native modules in the app:

aapt -> Platform_Framework_Base\tools\aapt aidl -> Platform_Framework_Base\tools\aidl androidfw -> Platform_Framework_Base\include\androidfw

zipalign -> Platform_Build\tools\zipalign host -> Platform_Build\lib\host

libpng -> Platform_External_Libpng expat -> Platform_External_Expat zlib -> Platform_External_Zlib

libcutils -> Platform_System_Core\libcutils cutils -> Platform_System_Core\include\cutils

liblog -> Platform_System_Core\liblog log -> Platform_System_Core\include\log

libutils -> Platform_System_Core\libutils utils -> Platform_System_Core\include\utils

log.h -> Platform_System_Core\include\android

asset_manager.h -> Platform_Framework_Native\include\android looper.h -> Platform_Framework_Native\include\android

zopfli -> zopfli\src

ld -> Tool_Chain_Utils\binutils-2.25\ld

If you look closely at the source you'll find the app executing aapt commands using the native jni files:

private void runAapt() throws Exception {
    Util.deleteRecursive(new File(S.dirRes, "drawable-xxhdpi"));

    Aapt aapt = new Aapt();
    int exitCode = aapt.fnExecute("aapt p -f -v -M " + S.xmlMan.getPath() + " -F " + S.ap_Resources.getPath()
            + " -I " + S.jarAndroid.getPath() + " -A " + S.dirAssets.getPath() + " -S " + S.dirRes.getPath()
            + " -J " + S.dirGen.getPath());

    if (exitCode != 0) {
        throw new Exception("AAPT exit(" + exitCode + ")");
    }
}

Now, go through the sample code to see how the functionalities are implemented. For example to change a value in manifest file,

private void modifyManifest() throws Exception {
        Document dom = Util.readXml(S.xmlMan);

        dom.getDocumentElement().getAttributes().getNamedItem("package").setNodeValue(userInput.appPackage);

        Transformer t = tf.newTransformer();
        t.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
        t.setOutputProperty(OutputKeys.INDENT, "yes");
        t.setOutputProperty(OutputKeys.METHOD, "xml");
        t.setOutputProperty(OutputKeys.VERSION, "1.0");
        t.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
        t.transform(new DOMSource(dom), new StreamResult(new FileOutputStream(xmlFile)));
    } 
like image 125
Prokash Sarkar Avatar answered Sep 21 '22 15:09

Prokash Sarkar