How to add assets to android apk file

2 minute read

I need to update a firmware binary which was packaged into apk file, unfortunately I do not have the source code of this apk, so I cannot just do mm to regenerate a new one, I can file a request to ask whom have the source code to do so for me, but it takes time, and what if I need to do this kind of job frequently.

Here is how to do this, in simple two steps:

Add assets to apk with aapt

aapt was shipped with android sdk, you can find it in build-tools/28.0.2, for this step only two subcommands are used:

$ aapt r[emove] [-v] file.{zip,jar,apk} file1 [file2 ...]
   Delete specified files from Zip-compatible archive.

$ aapt a[dd] [-v] file.{zip,jar,apk} file1 [file2 ...]
   Add specified files to Zip-compatible archive.

I need to remove the previous one, or aapt will report file alrady exists issue, do this with:

$ aapt remove -v test.apk assets/fw/bootcode.bin

Now, I can add asset with below command:

$ aapt add -v test.apk assets/fw/bootcode.bin
 'assets/fw/bootcode.bin'...

Check with aapt list to see the asset file that has been added:

$ aapt list -v test-signed.apk
Archive:  test-signed.apk
 Length   Method    Size  Ratio   Offset      Date  Time  CRC-32    Name
--------  ------  ------- -----  -------      ----  ----  ------    ----
    9193  Stored     9193   0%         0  01-01-09 00:00  5f8a1eb4  res/mipmap-hdpi-v4/ic_launcher.png
    5057  Stored     5057   0%      9269  01-01-09 00:00  ffffffffa5bfa0ca  res/mipmap-mdpi-v4/ic_launcher.png
   14068  Stored    14068   0%     14397  01-01-09 00:00  ffffffffc9c090e8  res/mipmap-xhdpi-v4/ic_launcher.png
   23292  Stored    23292   0%     28536  01-01-09 00:00  668d571e  res/mipmap-xxhdpi-v4/ic_launcher.png
    2348  Stored     2348   0%     51900  01-01-09 00:00  47e2fab3  resources.arsc
    2316  Deflate     848  63%     54300  01-01-09 00:00  1be07718  AndroidManifest.xml
   52116  Deflate   28943  44%     55213  01-01-09 00:00  ffffffff8e8f907e  assets/fw/bootcode.bin
   25944  Deflate   12881  50%     84224  01-01-09 00:00  ffffffffe12c80d9  classes.dex
    2636  Deflate     851  68%     97162  01-01-09 00:00  ffffffffe66386d2  res/layout/activity_main.xml
     848  Deflate     462  46%     98087  01-01-09 00:00  3b233fe5  META-INF/CERT.SF
    1714  Deflate    1154  33%     98611  01-01-09 00:00  1977455b  META-INF/CERT.RSA
     786  Deflate     416  47%     99828  01-01-09 00:00  fffffffff05ab7c6  META-INF/MANIFEST.MF
--------          -------  ---                            -------
  140318            99513  29%                            12 files

Re-sign apk with platform key/certificate pair

The apk file was signed with platform signature, as apk signing was file based, so I need to sign it, as we’ve added asset, or it will report below message when doing pm -r install:

Failure [INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING: Failed to collect certificates from /data/app/vmdl1616860685.tmp/base.apk: android.content.pm.PackageParser$PackageParserException: Package /data/app/vmdl1616860685.tmp/base.apk has no certificates at entry assets/fw/bootcode.bin: Package /data/app/vmdl1616860685.tmp/base.apk has no certificates at entry assets/fw/bootcode.bin]

To do apk signing, you need to get these files from android source tree:

files directory
libconscrypt_openjdk_jni.so prebuilts/sdk/tools/linux/lib64
signapk.jar prebuilts/sdk/tools/lib/signapk.jar
platform.x509.pem build/target/product/security
platform.pk8 build/target/product/security

Copy these files to your workspace and sign with:

java -Djava.library.path=. -jar signapk.jar \
			 platform.x509.pem platform.pk8 \
			 test.apk test-signed.apk

Before install to the system, verify with jarsigner:

$ jarsigner -verify -verbose -certs test-signed.apk

The signed files will be tagged with sm:

sm     52116 Thu Jan 01 00:00:00 CST 2009 assets/fw/bootcode.bin

Check out the meanings of sm at the end of jarsigner output:

  s = signature was verified
  m = entry is listed in manifest

Now you can install this signed apk.

References

Updated: