Giter VIP home page Giter VIP logo

unapkm's Introduction

unapkm

2021.01 Update

This tool is now no longer required thankfully, as APKMirror is serving exclusively decrypted APKM files (these are just regular ZIP files)!

See illogical-robot/apkmirror-public#119 for more discussion.

I've added a check to test whether the file provided to UnApkm is a regular zip file; this tool will still work on any old downloads of .apkm's you have!

Old introduction

There's a new split apk file format in town (apkm - https://www.androidpolice.com/2020/03/24/apkmirror-installer-for-android-now-in-public-beta-lets-you-install-app-bundles-and-apks/), but it's encrypted.

This is not helpful for modding or anything else really. And the only installer for it makes you watch ads/pay a subcription just to install otherwise free apps (? even play store doesn't do this - it seems a bit spammy and these aren't even their own apps they're hosting!)

This tool decrypts them into a more standard APKS format that can be opened with 7zip so you can install it yourself with https://github.com/Aefyr/SAI or another open source tool - installing apps shouldn't be a proprietary feature!

Usage:
  java -jar unapkm.jar <path/to/apkm> <path/to/output>

Download

Here: https://github.com/souramoo/unapkm/releases

unapkm's People

Contributors

souramoo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

unapkm's Issues

Question: how come I can't re-use the header?

I remember that I was told here somewhere, that I can re-use the header so that it will be faster.

I've tried to do it, but it failed. Example:

                val inputFile = File("/storage/emulated/0/test.apkm")
                Log.d("AppLog", "getting header..")
                var header: UnApkm.Header? = null
                val lazySodium = LazySodiumAndroid(SodiumAndroid())
                FileInputStream(inputFile).use {
                    header = UnApkm.processHeader(it, lazySodium)
                }
                Log.d("AppLog", "getting into zip")
                FileInputStream(inputFile).use {
                    ZipInputStream(UnApkm.decryptStream(it, header!!, lazySodium)).use {
                        Log.d("AppLog", "got into zip stream")
                        while (true) {
                            val name = it.nextEntry?.name ?: break
                            Log.d("AppLog", "name:$name")
                        }
                    }
                }

It crashes when it reaches the part of the val name = it.nextEntry?.name ?: break as it fails to parse the file as a zip file :

 W/System.err: java.io.IOException: decrypto error
 W/System.err:     at com.lb.apkmtest.UnApkm$decryptStream$pipeWriter$1.run(UnApkm.kt:57)
 W/System.err:     at java.lang.Thread.run(Thread.java:919)

Using the normal method, it works fine:

ZipInputStream(UnApkm.decryptStream(FileInputStream(inputFile))).use {
    Log.d("AppLog", "got into zip stream")
    while (true) {
        val name = it.nextEntry?.name ?: break
        Log.d("AppLog", "name:$name")
    }
}

How come? I tried to re-create the instance of LazySodiumAndroid(SodiumAndroid()) . It didn't work.

Fdroid

Could you submit this to fdroid? :-)

Decrypto error

Hello!

I have this error:
java.io.IOException: decrypto error
at com.souramoo.unapkm.UnApkm$1.run(UnApkm.java:139)

when I want to unapkm this package: https://www.apkmirror.com/wp-content/themes/APKMirror/download.php?id=1509707
that can be found here: https://www.apkmirror.com/apk/picsart/picsart-picsart/picsart-picsart-15-5-0-release/picsart-photo-editor-pic-video-collage-maker-15-5-0-android-apk-download/

Is it a problem with the apkm or is it encrypted in a new way?

Thanks a lot for your work!
Xavier

Request: Make another module for Android

Seems all the difference from making it running is:

LazySodiumJava lazySodium = new LazySodiumJava(new SodiumJava());

which will be replaced to :

LazySodiumAndroid lazySodium = new LazySodiumAndroid(new SodiumAndroid());

Perhaps you could make an interface for its usages, and wrap it from outside.
According to the usage, the interface should have the functions cryptoPwHash, cryptoSecretStreamInitPull, and cryptoSecretStreamPull .

So, there would be a main library module that has nothing that's related to LazySodiumJava and nothing that's related to LazySodiumAndroid. Instead, it would use your own interface LazySodiumInterface (or whatever name you wish, I'm bad with names), and there would be 2 tiny sample modules in the project. One for Java that provides the implementation via LazySodiumJava, and another for Android that provides the implementation via LazySodiumAndroid.

If you want, a working sample on Android is attached here, with minimal change to the UnApkm file:
ApkmTest.zip

If you do this, I suggest to also add annotations of @WorkerThread, @AnyThread, and @UiThread for the functions, based on the thread that it's supposed to run on. My guess is that all are on @WorkerThread

Cannot find tempfiles to properly work.

OS: Windows 10 Pro 64-bit
Build 18362 (Version 1909 Release)
Java version: AdoptOpenJDK 11 64-bit

The error is as follows (straight from CMD):

C:\Users\Owner\Desktop>java -jar unapkm.jar com.netflix.mediaclient_7.50.0_build_17_34771-34771_4arch_2dpi_15lang_7feat_38a1d11001d7d0aea2c238021ec8ec9b_apkmirror.com.apkm netflix.zip Exception in thread "main" java.lang.UnsatisfiedLinkError: Unable to load library 'C:\Users\Owner\AppData\Local\Temp\resource-loader13375745676964125581\windows64\libsodium.dll': The specified module could not be found. The specified module could not be found. Native library (win32-x86-64/C:\Users\Owner\AppData\Local\Temp\resource-loader13375745676964125581\windows64\libsodium.dll) not found in resource path (unapkm.jar) at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:302) at com.sun.jna.NativeLibrary.getInstance(NativeLibrary.java:455) at com.sun.jna.Native.register(Native.java:1722) at co.libly.resourceloader.SharedLibraryLoader.registerLibraryWithClasses(SharedLibraryLoader.java:74) at co.libly.resourceloader.SharedLibraryLoader.load(SharedLibraryLoader.java:57) at com.goterl.lazycode.lazysodium.utils.LibraryLoader.loadBundledLibrary(LibraryLoader.java:115) at com.goterl.lazycode.lazysodium.utils.LibraryLoader.loadLibrary(LibraryLoader.java:84) at com.goterl.lazycode.lazysodium.SodiumJava.(SodiumJava.java:34) at com.goterl.lazycode.lazysodium.SodiumJava.(SodiumJava.java:23) at org.example.UnApkm.(UnApkm.java:80) at org.example.UnApkm.main(UnApkm.java:155) Suppressed: java.lang.UnsatisfiedLinkError: The specified module could not be found. at com.sun.jna.Native.open(Native Method) at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:191) ... 10 more Suppressed: java.lang.UnsatisfiedLinkError: The specified module could not be found. at com.sun.jna.Native.open(Native Method) at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:204) ... 10 more Suppressed: java.io.IOException: Native library (win32-x86-64/C:\Users\Owner\AppData\Local\Temp\resource-loader13375745676964125581\windows64\libsodium.dll) not found in resource path (unapkm.jar) at com.sun.jna.Native.extractFromResourcePath(Native.java:1095) at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:276) ... 10 more

I get the exact same error in PowerShell. I'm going to test it in Linux Mint since I hate Windows for lots of reasons, and so I usually modify quite a few settings. However I never modify file permissions because doing so has a chance of rendering Windows dead, and I still need it in case I need to restore an Apple device to full health.

Please target JAVA version 52.0 instead of 53.0

Exception in thread "main" java.lang.UnsupportedClassVersionError:
com/souramoo/unapkm/UnApkm has been compiled by a more recent version of the Java Runtime (class file version 53.0), this version of the Java Runtime only recognizes class file versions up to 52.0

Request: apply some adjustments and suggestions from the IDE

  1. This :
            byte magic = getBytes(i, 1)[0];
            if (magic > 0xff) {
                throw new Exception("wrong version magic oops");
            }

A byte can't be larger... The condition is useless.

  1. This:
            while (bytesRead != -1) {
                bytesRead = i.read(cipherChunk);
                if (bytesRead == -1) break;

No reason to check twice. The condition is enough. You can use while(true) instead.

  1. This:
                for (int j = 0; j < cipherChunk.length; j++) {
                    cipherChunk[j] = 0;
                }

You can use this instead:

Arrays.fill(cipherChunk, (byte) 0);
  1. This:
            if (fos != null) {
                fos.close();
            }

It's already not null. Also, it's recommended to close it in the finally-block, or better: using "try(...)" on it, to auto-close it, as if it's in the finally-block.

  1. This:
    public UnApkm(String filein, String fileout) {

On Java, functions are supposed to start with lower-case letter. Meaning:

    public unApkm(String filein, String fileout) {
  1. You can use Kotlin instead :)

Question: How come I can't run on Android itself ?

I tried to make a sample app to check it out.

To do this, I granted the storage permissions, and ran this:

        thread {
            val inputFile = File("/storage/emulated/0/test.apkm")
            val outputFile = File("/storage/emulated/0/test.zip")
            UnApkm(inputFile.absolutePath, outputFile.absolutePath)
        }

For some reason, while debugging, I noticed it crashed on this line:

            NativeLong memLimit = new NativeLong(thirdLong);

and the logs:

 FATAL EXCEPTION: Thread-2
    Process: com.lb.apkmtest, PID: 20358
    java.lang.UnsatisfiedLinkError: Native library (com/sun/jna/android-aarch64/libjnidispatch.so) not found in resource path (.)
        at com.sun.jna.Native.loadNativeDispatchLibraryFromClasspath(Native.java:1032)
        at com.sun.jna.Native.loadNativeDispatchLibrary(Native.java:988)
        at com.sun.jna.Native.<clinit>(Native.java:195)
        at com.sun.jna.NativeLong.<clinit>(NativeLong.java:35)
        at org.example.UnApkm.<init>(UnApkm.java:70)
        at com.lb.apkmtest.MainActivity$onGotPermissions$1.invoke(MainActivity.kt:43)
        at com.lb.apkmtest.MainActivity$onGotPermissions$1.invoke(MainActivity.kt:14)
        at kotlin.concurrent.ThreadsKt$thread$thread$1.run(Thread.kt:30)

Attached project here:

ApkmTest using dependency.zip

So I tried to copy the entire file into the project, including its dependencies, but then it crashed on this line:

            LazySodiumJava lazySodium = new LazySodiumJava(new SodiumJava());

And the logs:

FATAL EXCEPTION: Thread-2
    Process: com.lb.apkmtest, PID: 19869
    java.lang.NoClassDefFoundError: com.sun.jna.Native
        at com.goterl.lazycode.lazysodium.utils.LibraryLoader.getSodiumPathInResources(LibraryLoader.java:122)
        at com.goterl.lazycode.lazysodium.utils.LibraryLoader.loadBundledLibrary(LibraryLoader.java:114)
        at com.goterl.lazycode.lazysodium.utils.LibraryLoader.loadLibrary(LibraryLoader.java:84)
        at com.goterl.lazycode.lazysodium.SodiumJava.<init>(SodiumJava.java:34)
        at com.goterl.lazycode.lazysodium.SodiumJava.<init>(SodiumJava.java:23)
        at com.lb.apkmtest.UnApkm.<init>(UnApkm.java:81)
        at com.lb.apkmtest.MainActivity$onGotPermissions$1.invoke(MainActivity.kt:42)
        at com.lb.apkmtest.MainActivity$onGotPermissions$1.invoke(MainActivity.kt:13)
        at kotlin.concurrent.ThreadsKt$thread$thread$1.run(Thread.kt:30)
     Caused by: java.lang.UnsatisfiedLinkError: Native library (com/sun/jna/android-aarch64/libjnidispatch.so) not found in resource path (.)
        at com.sun.jna.Native.loadNativeDispatchLibraryFromClasspath(Native.java:1032)
        at com.sun.jna.Native.loadNativeDispatchLibrary(Native.java:988)
        at com.sun.jna.Native.<clinit>(Native.java:195)
        at com.sun.jna.Native.register(Native.java:1721)
        at co.libly.resourceloader.SharedLibraryLoader.registerLibraryWithClasses(SharedLibraryLoader.java:74)
        at co.libly.resourceloader.SharedLibraryLoader.loadSystemLibrary(SharedLibraryLoader.java:42)
        at com.goterl.lazycode.lazysodium.utils.LibraryLoader.loadSystemLibrary(LibraryLoader.java:99)
        at com.goterl.lazycode.lazysodium.utils.LibraryLoader.loadLibrary(LibraryLoader.java:81)
        at com.goterl.lazycode.lazysodium.SodiumJava.<init>(SodiumJava.java:34) 
        at com.goterl.lazycode.lazysodium.SodiumJava.<init>(SodiumJava.java:23) 
        at com.lb.apkmtest.UnApkm.<init>(UnApkm.java:81) 
        at com.lb.apkmtest.MainActivity$onGotPermissions$1.invoke(MainActivity.kt:42) 
        at com.lb.apkmtest.MainActivity$onGotPermissions$1.invoke(MainActivity.kt:13) 
        at kotlin.concurrent.ThreadsKt$thread$thread$1.run(Thread.kt:30) 

Attached here this project:

ApkmTest.zip

So why does it occur?
Any way to run it on Android itself?

Question: what is "memLimit" ?

I noticed this:

            int memLimit = byteToInt(getBytes(i, 8));

            if (memLimit < 0 || memLimit > 0x20000000) {
                throw new Exception("too much memory aaah");
            }

What is this? That's 536,870,912 bytes...
Does it mean the library can't handle an APKM file that's larger than that?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.