Android jni lib not found when moving app to system app - android

I've been not able to solve my problem, I look around and I couldn't find a good solution.
The things is that I have an Android app that must be system app. I have my own devices so I'm able to install them on system app.
I'm doing this using a pre-installed app on system app. This app takes the .apk file from assets save it on the data/data and the move it to system/app/ folder.
Everything goes good, except when I launch it, it gets an exception java.lang.ExceptionInInitializerError, this means that the jni lib is not found. Probably because it has not been installed in the /system/lib directory.
Anyone know how can I solve this?
I know one solution is to look for the jni lib in the system and move it to system/lib but I would like to avoid this.
thank you.

Related

How update a single file installed in the APK while developing an app on Android?

I am developing an Android application that has a NDK .so file which I need to iterate on and fix + improve.
The current workflow has me having to generate a APK and install it every iteration which updates a whole plethora of non NDK elements in the process really slowing things down.
The question is how could I access the installation folder of my own APK? I have both a rooted and unrooted device.
Is there some change I could make to install the app in an unprotected location for development purposes even. The installation data is my own application after all so feels like should be a way...
Help greatly appreciated :)
EDIT1:
I found Unity3D has some sort of patching mode, maybe this is a sign that with the correct ADB commands it may be possible... https://docs.unity3d.com/Manual/android-AppPatching.html
EDIT2: I found the location of the .so I am building in... checked on unrooted device and don't have permission.
If your app is not a native-only app (has a Java/Kotlin part) then your so library should be loaded at the moment using a call to System.loadlibrary(..).
What is interesting on this method is, that calls to this method are ignored if the library to be loaded has already been loaded. So if you modify the Java code of the development build of your app to manually load your library before the original loadLibrary call is executed you can end up with a different library loaded.
The only problem is that System.loadLibrary(..) does not accept a file-name or path as argument. But using System.load(..) which uses a full path as argument you should be able to specify a full path to a file e.g. in the app's data directory. That way you can replace the library as often as you want and then just restart the app to load the updated library.

How would I dump files from an APK?

I was looking to mod a game as I really felt like adding a few extra things. It is a mobile game so I got the APK and moved it onto my computer, and began to decompile it. I know it uses the Unity engile so I looked for the .dll files but I couldn't find them, so after reading I found out that they only appear during running the game so I have to dump the files. The problem is, I have no idea how to dump files from an APK. Any help?
Use a rooted device, and extract all the files you need in runtime.

Detecting /legacy/ directory as a symbolic link

I have a file util which detects if the file is a symbolic link. I more or less use the code presented here. It works fine for almost all files in Android. I run into problems, however, with a legacy folder. The legacy folder is a symbolic link to the file the user is actually on (This is for Android devices running 4.2.2 or higher which allows for multiple users). For example the path will be "storage/emulated/legacy/file" but when run through the isSymbolicLink method, I get false returned. This is because the file.getCanonicalPath() does not seem to resolve the symbolic link for the /legacy folder. Does anybody have an idea on how to detect /legacy as a symbolic link? I'm really trying to avoid just coding in "legacy folder is a symbolic link, deal with it". Let me know what you think.
Edit: It seems like I've run into the same problem as this question.

Android JNI: loadlibrary from install dir only

So, currently there is no way on Android, but to manually preload dependent shared libs. That's fine with me, not a big deal.
There is also some problem with android buildsystem (prebuild libraries feature), and for that reason I had to name differently different builds of my dependent shared library: libsal.so and libsal-slim.so. Depending on build settings one of these two makes it into the final apk. Then, on java side, I try to load libsal.so and if it fails, then I try to load libsal-slim.so.
It worked all fine, until we stumbled upon a phone that ships that libsal.so in default firmware installed into /system/lib. For that reason, my app stopped working on that phone if it's built with libsal-slim.so, since it tries to load libsal.so first and it loads wrong library from /system/lib.
Question: how can I ensure that only library from my install folder gets loaded? Maybe I can somehow retrieve install folder of my app and "calculate" full path of my shared lib? How can I do that java voodoo magic? I'm big time noob in java and android in general, if this questions looks too naive :) and yes, I don't speak English (or how they say), please rely in c++ [end-of-joke]
libsal.so isn't actual name, I used it only for example.
Using System.load(fullpath_of_the_lib)can probably solve your problem.
But your problem is to get the fullpath_of_the_lib. In fact the android API don't allow you to get the path of a resource. You can only get a stream to read it.
To workaround this limitation, what you can do is the following:
put your lib in your app assets folder.
open a InputStream on your lib : getAssets().open("libsal.so")
create a file named "libsal.so" (or whatever) in your sdcard
copy bytes from the inputstream to the file just created
get the absolute filepath of your "libsal.so" on the sdcard
call System.load(fullpath_of_the_lib_on_the_sd_card)
Of course you only need the last step in the lib is already on the sdcard.
An simpler alternative is maybe renaming your lib to something like libMyVeryUncommonLibraryName.so so that it won't conflict with another library name.

How to unpack some files from .apk to /data/data/<package> folder while installing the .apk?

My android application needs another NATIVE application executable to run before the android one, so that they can communicate through sockets. Android application has a JNI layer for handling the client-side communication.
Now i need to bundle up the native executable along with the apk file, so that when it is installed on a device it gets unzipped into either the phone memory or the memory card.
How do i do this?
I tried keeping the native executable in res/asset and in res/raw folders, but they still don't get unzipped in /data/data/ folder.
One way I could find is to use AssetManager and then with help of InputStream and OutputStream, i can write this file onto the device the first time it is run and then use it. But there is no point to write it manually on phone memory as it might eat up the memory. ( the case where if memory card is not present. )
Can anyone help me on how can i achieve this? It would be great if there is an option to unzip the necessary files automatically at the time of installation.
How do i do this?
You don't. You unpack it yourself on first run of your application.
One way I could find is to use AssetManager and then with help of InputStream and OutputStream, i can write this file onto the device the first time it is run and then use it.
Correct.
But there is no point to write it manually on phone memory as it might eat up the memory.
Then why did you want it automatically unpacked there in the first place?
It would be great if there is an option to unzip the necessary files automatically at the time of installation.
No, sorry, this is not possible.
We have the same issue ... the direction we are exploring is to have two separate installs - the first one is the app and the second one is the data-app. When the data-app installs it copies the binary files to the SD card. When we uninstall the data-app it frees up the internal storage.
We don't have this one completely licked yet, and would love to hear other input and maybe find someone to help us by writing a couple of skeletal sample applications for us.
There are so many people who are in this boat (based on my googling) that if this approach doesn't work I suggest we (or someone) set up a generic file delivery web server and generic file delivery Android service and make it available to developers for a very low cost.
This isn't a typical use of OBBs but why not use one? It would then be a file separate to your apk installed in a pre-determined location. It doesn't have to be compressed.

Categories

Resources