[DEV][PROOF OF CONCEPT] APK-Patcher - Easily Mod APKs from Recovery [Flashable Zip]

Search This thread

osm0sis

Senior Recognized Developer / Contributor
Mar 14, 2012
15,664
35,411
Halifax
GT-i9250
Google Nexus 4
Looks like java.nio.file.path is going to be added in Android O (API 26): https://developer.android.com/reference/java/nio/file/Path.html

Hmm, that's sort of good news, and provides a tiny bit of hope, but it'll unfortunately mean that the zips would only run on a system with an O ROM or above.. so full support would lapse from Lollipop to Nougat.

I guess we could include both sets of jars to make it work from ICS to KitKat and then O+. I have had reports that some things will work on Lollipop and Marshmallow (my PoC linked in the OP for example) with the old jars, so we could attempt to use them in those cases, but it seems like it's hardly full support for those releases without the newer jars - very hit-or-miss, which wasn't what I was hoping for with this project.

It also might solve the errors for bak/smali but not the ones with Apktool; as @iBotPeaches suggested they stemmed from a few things. I'll have to reevaluate things once I get an O ROM to test on.
 
Last edited:

osm0sis

Senior Recognized Developer / Contributor
Mar 14, 2012
15,664
35,411
Halifax
GT-i9250
Google Nexus 4
@osm0sis How can i use your script to decompile framework-res.apk ?
i edited envvar.sh file and added res to patch folder. anything missing?
Thanks in advance

Well, no guarantees with framework-res.apk since there've been issues with that specific APK before on-device, and this project is unmaintained and all-but-abandoned due to incompatibilities with the latest ApkTool and bak/smali (read back a couple pages), BUT, yeah, you're on the right track.

2b- Place any required/additional updated whole resource files in /patch under the name of the APK with "-res" and the relative path within the zip/resources.asrc file (including res)

So it should be patch/framework-res-res/ then the path to the file to replace. You're better off with script/framework-res-res.sh if it's something you can do with sed/awk; wider compatibility.
 
  • Like
Reactions: yshalsager
Apr 4, 2017
286
150
Hi @osm0sis
I found this zip lying around and so tried a quick script to make the nougat accents blue... Spent 30 mins on it, then a hour figuring out what went wrong. Then thought of seeing the thread and saw this sob story :crying:

I realise it might be fruitless now, but just for closure, I wanna figure out why there was a second error, updating classes failed, since there was no smali stuff and there was a resource script, so it shouldn't have went there in the first place. Yes, I did try it with the latest revision. Attached is the res script, envvar and recovery log.

Thank in advance.

Edit: BTW, you noticed the apktool app floating around last year? In case not,
https://androidfilehost.com/?w=files&flid=149532
http://code.google.com/p/apktool/
Yeah, I did notice he had to fit the whole apktool-supporting JNI in there.
 

Attachments

  • Frameworkres.zip
    13.8 KB · Views: 73
Last edited:
  • Like
Reactions: osm0sis

osm0sis

Senior Recognized Developer / Contributor
Mar 14, 2012
15,664
35,411
Halifax
GT-i9250
Google Nexus 4
Hi @osm0sis
I found this zip lying around and so tried a quick script to make the nougat accents blue... Spent 30 mins on it, then a hour figuring out what went wrong. Then thought of seeing the thread and saw this sob story :crying:

I realise it might be fruitless now, but just for closure, I wanna figure out why there was a second error, updating classes failed, since there was no smali stuff and there was a resource script, so it shouldn't have went there in the first place. Yes, I did try it with the latest revision. Attached is the res script, envvar and recovery log.

Thank in advance.

Edit: BTW, you noticed the apktool app floating around last year? In case not,
https://androidfilehost.com/?w=files&flid=149532
http://code.google.com/p/apktool/
Yeah, I did notice he had to fit the whole apktool-supporting JNI in there.

Your "sedit" function looks like it'll fail because you've got $1;$2 inside single quotes - ' - so they won't expand. Try sed -i "s;${1};${2};g"

Hadn't heard about that newer apktool. Worth a look I guess.
 
Apr 4, 2017
286
150
Your "sedit" function looks like it'll fail because you've got $1;$2 inside single quotes - ' - so they won't expand. Try sed -i "s;${1};${2};g"

Hadn't heard about that newer apktool. Worth a look I guess.
Oh. Thanks about that fix. But my point was that there is a resource script so it should never go to the updating classes part, since it is to do that only in case there is a smali mod and no resource mod.

EDIT: NVM. Looks like it fails with that error just for the heck of it. Removed the whole bak/smali portion and it succeeds but in the end does nothing.
Thanks and see ya around.
 
Last edited:

osm0sis

Senior Recognized Developer / Contributor
Mar 14, 2012
15,664
35,411
Halifax
GT-i9250
Google Nexus 4
Seems pretty much impossible to run dalvikvm in recovery on Android 10+ thanks to linkerconfig and namespace issues, especially now that it's relocated to /apex/com.android.art/bin/dalvikvm in Android 13 and using linker.config.pb.

So just to make it clear this thread and idea are currently dead, and it's been 5 years so I'm unsubscribing. 😛

If anyone in the future figures out how to get dalvikvm working in recovery again on modern Android, @ mention me and we'll see if we can get aapt, apktool and bak/smali to play more nicely at that time! 👍
 
Last edited:

Top Liked Posts

  • There are no posts matching your filters.
  • 29
    APK-Patcher -- Flashable Zip Template for Modifying System APKs On-Device from Recovery

    APK modification can be a tedious task. If you want to provide modified APKs you copy it to PC to decompile using Java applets like baksmali and apktool, make changes and recompile using another Java applet, smali (or apktool again). Then there's the pitfall of different recompiled APKs being required for the various different ROMs, etc., not to mention across Android versions. So, considering Android runs a version of Java runtime and the primary tools are Java-based I wondered why we couldn't do all of this on-device and on-the-fly so modifications could be applied via recovery, to whatever ROM APK was present, and take the constant update burden off of the modification creator.

    I have taken these commandline Java applets, dexed them to allow them to run on-device, and found/built static ARM compiles of zip, zipalign and aapt to run on the various Android versions and devices. These binaries would need to be recompiled for other architecture support. The zip is smart and automated, using the APK name to run all the various parts involved for complicated patches and is extensible to any number of APKs in a single zip. The modification creator needs to only add the APK name(s) to a list, figure out how to make the changes universally (i.e. sed, awk, etc.) then add the commands to scripts of the same name, and add any whole-file additions/changes in subdirectories of the same name.

    A proof-of-concept working script automating the long known Facebook Contacts Sync modifications to ContactsProvider.apk is included for reference.

    My development work on my many projects comes out of my free time, so if you enjoy this project or anything else I've done on xda, please consider sponsoring my ongoing work using my GitHub Sponsors profile. For a one-time donation you can hit the donate link from my profile. Thank you for your support!


    Source:
    https://github.com/osm0sis/APK-Patcher/

    Status: No Longer Updated


    Instructions

    1a) Place any required script to alter the decompiled APK classes.dex smali files in /script as a -smali.sh file with the name of the APK
    -b) Place any required/additional updated whole smali files in /patch under the name of the APK with "-smali" and the relative path within the classes.dex file (including com)
    2a) Place any required script to alter the decoded APK resources.asrc files in /script as a -res.sh file with the name of the APK
    -b) Place any required/additional updated whole resource files in /patch under the name of the APK with "-res" and the relative path within the zip/resources.asrc file (including res)
    3) Modify the envvar.sh to add your banner, apklist, backup and cleanup options
    4) Modify the extracmd.sh to add any additional commands to be performed at the end of the patching process that aren't patch-related (/data file changes, etc.)
    5) zip -r9 UPDATE-APK-Patcher.zip * -x README UPDATE-APK-Patcher.zip

    As a general rule, whole-file adding is best used only for including a file that doesn't already exist, and the more surgical script-work should be used to keep things more universal.

    If supporting a recovery that forces zip signature verification (like Cyanogen Recovery) then you will need to also sign your zip using the method I describe here:
    [DEV][TEMPLATE] Complete Shell Script Flashable Zip Replacement + Signing [SCRIPT]

    Enjoy!
    Questions, comments and feedback welcome.



    Credits & Thanks: JesusFreke for bak/smali, iBotPeaches for apktool, Surge1223 for help working out how to build zipalign and aapt, and all authors of the included binaries and those who ported them over for their amazing work.

    Disclaimer: Naturally, you take all the responsibility for what happens to your device when you start messing around with things.
    11
    Script/Patch Reference

    Properties / Variables (envvar.sh)

    Code:
    banner="Facebook Contacts Sync Enabler";
    apklist="ContactsProvider.apk";
    apkbak=/data/media/APK-Backup;
    backup=1;
    cleanup=1;

    banner is the name of your patch zip, usually suggestive of what it does, to be displayed at the beginning of the zip flash. You should include your name/handle here like "by osm0sis @ xda-developers" for credit purposes.

    apklist is a string containing the list of APKs to be patched included in the patch zip, separated by spaces between the quotes. Each APK is automatically found recursively in /system, then copied to the working directory to be decompiled and acted on, then copied back to /system.

    apkbak is the location to place backups of the untouched APKs in apklist if backup=1 is set.

    backup=1 will store backups of the untouched APKs in the location specified in apkbak.

    cleanup=0 will keep the zip from removing it's working directory in /tmp/apkpatcher or any of the files resulting from the smali process - this can be useful if trying to debug in adb shell whether the patches worked correctly. cleanup=1 is necessary on multi-APK patching zips to clean the baksmali classout directory for the next APK, so it's recommended each APK to be patched be tested on their own with cleanup=0 before combining into a single zip.
    7
    Did you happen to figure out how to cross compile jdk for arm? (different from the arm sources available from oracle etc)

    ..and nice work!

    Nah, just forced bak/smali and apktool to run by building/adding classes.dex for each of them and figuring out how to call a functional dalvikvm from recovery. :cowboy::cool:

    The first part was mentioned in passing (and quite awesomely) by JesusFreke back in 2011.

    That got it running in booted Android. Then running from recovery was a whole other issue, but I stumbled upon Jim Huang's work on executing dalvikvm on Linux, and that lead me to figuring out a solution.

    As it stands, apktool should technically be able to do both the classes and resources parts of things (since it incorporates baksmali and smali), but for some reason it bails in recovery on decompiling the classes.dex where baksmali standalone doesn't. So perhaps in future revisions apktool could be the only jar required.

    Similarly, apktool also bails when rebuilding resources.asrc because it can't call its internal(?) aapt, so I've included aapt compiled as PIE since that's the only working one I could find; in the future this could go too if apktool resolves it, or at the very least it would be more universal if we had a static compile of aapt to go with the other static binaries included.

    Other possible items on the to-do list would include adding zip re-signing (currently it uses the apktool /system APK trick of keeping META-INF the same), reflashing to revert to the backup APKs, and adding busybox to always have an expected execution environment like I recently did on AnyKernel2 to work around Cyanogen Recovery and toybox missing basic stuff like awk at the moment. These aren't something I'm going to be actively working on since it works and APK modding isn't really a focus for me, but since I figured out how to automate the process I wanted to provide the WIP template for the modding community. :good:
    6
    APK-Patcher: minor fixes, binary updates:
    - allow for recoveries without busybox
    - update tool compiles to my newer zipalign and static(!) aapt builds
    - strip zip binary to compensate for larger aapt and zipalign binaries
    - simplify aapt usage now that we have a static arm binary
    - configure zipalign for Marshmallow system APK handling

    https://github.com/osm0sis/APK-Patcher/commit/af24805f06e2e2b92f2bfeeb1490d6022073c4b5

    Thanks @Surge1223 for the help with figuring out compiling zipalign and aapt statically for arm. :) :highfive:
    4
    Properties / Variables (envvar.sh)

    Code:
    banner="Facebook Contacts Sync Enabler";
    apklist="ContactsProvider.apk";
    apkbak=/data/media/APK-Backup;
    backup=1;
    cleanup=1;

    banner is the name of your patch zip, usually suggestive of what it does, to be displayed at the beginning of the zip flash. You should include your name/handle here like "by osm0sis @ xda-developers" for credit purposes.

    apklist is a string containing the list of APKs to be patched included in the patch zip, separated by spaces between the quotes. Each APK is automatically found recursively in /system, then copied to the working directory to be decompiled and acted on, then copied back to /system.

    apkbak is the location to place backups of the untouched APKs in apklist if backup=1 is set.

    backup=1 will store backups of the untouched APKs in the location specified in apkbak.

    cleanup=0 will keep the zip from removing it's working directory in /tmp/apkpatcher or any of the files resulting from the smali process - this can be useful if trying to debug in adb shell whether the patches worked correctly. cleanup=1 is necessary on multi-APK patching zips to clean the baksmali classout directory for the next APK, so it's recommended each APK to be patched be tested on their own with cleanup=0 before combining into a single zip.

    Did you happen to figure out how to cross compile jdk for arm? (different from the arm sources available from oracle etc)

    ..and nice work!