I have developed android project using android studio.
It uses android native library which other developer built for speech recognization.
The APK works perfectly when i install on android devices.
I need to put this APK into AOSP because I am going to make android device only for our system. (I have already customized AOSP)
But after adding the APK into AOSP, the APK can not load library.
Error log:
java.lang.UnsatisfiedLinkError: dlopen failed: can't protect segments for "../libsengine.so": Permission denied
Please help me to fix this problem.
If you add your apk into AOSP system/app/ path as a prebuilt app, this might be of help:
Error adding prebuilt apk with shared libraries to AOSP
http://blog.csdn.net/a462533587/article/details/46380795
The problem is the shared library packaged in your apk has never been extracted to /data/app-lib directory, so it can't be linked.
It seems that the library you are using is utilizing some sort of dynamic code loading that is strictly prohibided on Android 26+ (Writable and Executable Segments Enforced for API level >= 26) .
You can read more about the security risk of TEXTREL on the following blog.
I assume that the reason the code works when compiling with Android Studio is because your build.gradle defines a minSdkVersion/targetSdkVersion that does not enforce the TEXTREL check. When compiling via the AOSP make, targetSdkVersion is most probably defined to be the 'current' version where the TEXTREL check is enforced.
These are only assumptions, so I guess you could check or alternatively provide more information such as the platform you are building and the Android.mk + build.gradle files.
I Think This is related to Marshmallow switching from OpenSSL to BoringSSL.
Your exception is occurring in the referenced library code. Contact the vendor for a fix or manually include the OpenSSL libraries to avoid the issue.
You can see this link: https://sourcedna.com/blog/20150806/predicting-app-crashes-on-android-m.html
Related
I recently built libssh2 for Android using OpenSSL as a crypto backend, I also built libcrypto.so and libssl.so myself using the NDK.
In my build process I generate a final libcustom.so linked with libssh2.a.
Google said "If you tried to use your own copy of OpenSSL but forgot to bundle it with your app's APK, the app may run normally on versions of Android platform that includes libcrypto.so. However, the app could crash on later versions of Android that do not include this library (such as, Android 6.0 and later)." that's why I package libcrypto.so, libssl.so and libcustom.so into my APK.
When running an Android app that loads the libcustom.so, my app crashes with the following error:
failed: dlopen failed: cannot locate symbol "EVP_cast5_cbc" referenced by "libcustom.so"... ONLY ON ANDROID 5.
It works well on Android 6 and above.
The symbol EVP_cast5_cbc is undefined but referenced in libssh2.a, but well defined in libcrypto.so.
I don't understand why it runs correctly on Android 6 and above and not on Android 5.
I thought that on Android 5, the libcrypto.so used was not the one I embed in the APK but the one from /system/lib ; so I tried to rename the libcrypto.so and build libssh2.a using the libcrypto renamed, but I am facing the same issue.
Does anybody have an idea ?
Thank's in advance.
Google has changed the use of private libraries for Marshmallow and above; this may be the case that you are experiencing.
Starting in Android 6.0, the system prevents apps from dynamically linking against non-NDK libraries, which may cause your app to crash.
According to this table: https://developer.android.com/about/versions/nougat/android-7.0-changes.html#ndk. You should be able to see logcat warnings when you are running Lollipop with private libraries. For example:
03-21 17:07:51.502 31234 31234 W linker : library "libandroid_runtime.so"
("/system/lib/libandroid_runtime.so") needed or dlopened by
"/data/app/com.popular-app.android-2/lib/arm/libapplib.so" is not accessible
for the namespace "classloader-namespace" - the access is temporarily granted
as a workaround for http://b/26394120
I can build openssl-1.0.2j successfully for android (libcrypto.so and libssl.so) using GitHub stdchpie/android-openssl:
Environment: Linux OS, (my case I use Mac OS)
Android NDK: 12b
On Android 5.x if using:
System.loadLibrary("crypto");
System.loadLibrary("ssl");
It will get conflict with native OS libs which also have same names. And unluckily, manually change their names didn't work. So that I want to compile them into different names , like libcryptox.so and libsslx.so
I try to play with Makefile.org all day but not lucky. So please someone tell me how to do.
The system has those libs loaded in the run-time environment, you can't use the System.loadLibrary
You can make small ndk code that will use native dload for those libs.
And eventually, I think its best to use the ssl api's through the common android API as you never know what they will do next version.
Should/does NDK9 work with android API19? (though it was released with API18).
Full story:
I was building an Android App using kivy, python-for-android and buildozer.
compiling with MDK9 (ie 9d) and api19 result in error:
E/AndroidRuntime( 1773): java.lang.UnsatisfiedLinkError: Cannot load library: soinfo_relocate(linker.cpp:975): cannot locate symbol "wait4" referenced by "libpython2.7.so"...
compiling with NDK9 (ie 9d) and API18 works. :)
Just in case anyone stumbles across this. I had the same issue, but building python from scratch using the platform tools, and with NDK r10 and r10b.
It's because google removed an inline wait4() declaration in the NDK platform android-19. The original problem was that wait4() was exposed in the headers but not declared anywhere, so if you tried to use wait4 on older NDKs, you'd probably crash (like you do now).
So they went in and added it to libc.so in API 18 I believe, but libc.so is shipped with the O/S, so devices with O/S older than 18 would not have wait4, so they patched it by adding an inlined wait4() method in NDK platforms up through android-18, then took it out in android-19 I'm not fully sure why yet, seems like it could have made more sense to leave it alone at that point, especially since it's considered an obsolete function. I was told I should not build against android-19 if I wanted the app to run on devices older than API 18, but others say to always use the latest NDK to match your build target. Here is a link to the problem.
https://code.google.com/p/android/issues/detail?id=19854
In my case, I went into the cpython Modules/posixmodule.c file, and added:
#if defined(__ANDROID__)
#undef HAVE_WAIT4
#endif
And in my case that's fine, because none of my python modules use wait4. Indeed, Linux deems the wait4 command obsolete (http://linux.die.net/man/2/wait4). You should instead use the waitpid.
So, even if you download some 3rd party python module that does use wait4, you have 2 options. 1) change that module to use waitpid, or 2) update the Modules/posixmodule.c file inside the "ifdef HAVE_WAIT4" section, and replace the wait4 call with waitpid. The downside is you lose the returned resource usage information, which waitpid doesn't provide, so then if your module needs that, you'd have to add something to retrieve resource usage for that pid separately.
Alternatively, you could remove "wait4" from your configure script if you never plan to use it, and any modules you add that needed it would break, at which point the new engineer working on the problem would have to rediscover all of this over again.
Android SDK are released more often that NDK. It happened more than once that if you use a too recent SDK, the NDK will not have the .h for it. Now i'm not sure this would be related to your issue at all.
I need to run a newer version of openssl in my app than the one that comes in the OS. I was able to patch and android source to compile a newer version and then extract the shared library to use in my app.
I was then able to compile and link my native code that requires a function only in newer versions of openssl against my new shared library (the patch to a newer openssl worked).
I was also able to create a few jni functions that work as expected but as soon as I added in the function that is only in the newer openssl shared library local to the app I get an unsatisfied link error.
My assumption is that the system version of libcrypto and libssl are overriding my local versions in /libs/armeabi/libcrypto.so and /libs/armeabi/libssl.so .... how to I fix this?
The system already ships with a library known as libcrypto, and that will be picked before your library will. The easiest solution is to give your library a different name, and use that in your System.loadLibrary(...) call.
Update
As you pointed out, you will need to rebuild the library with the new name, in stead of just renaming the file.
Yes JNI is picking up the system versions. It didn't use your patched versions at all. On standalone JVM you would say -Djava.library.path=/libs/armeabi or modify environment variable LD_LIBRARY_PATH. On Android i guess you can either look up the system property java.library.path and put your libs in some known place (but before the folder where the system versions are) or actually modify the property - prepend the path to your local versions. I do have some experience with Android but not specifically with NDK.
I wish to back port the Android RTP APIs introduced in version 3.1(Honeycomb) to earlier versions. I downloaded the source of version 4.0 and found that it these APIs had both java and native code. In order to build the native code with the NDK, certain shared libraries are required.
According the Android.mk file, these are libnativehelper, libcutils, libutils, and libmedia. Though the source of all of these are present in the source code, building them was difficult. Each required many other shared libraries. For eg, libmedia requires these shared libraries: libui, libcutils, libutils, libbinder, libsonivox, libicuuc, libexpat, libcamera_client, libstagefright_foundation, libgui and libdl.
So my question is, is there some way of obtaining the original 4 shared libs? Does it involve building the entire source?
Say I need to build a piece of native code which is going to use standard Android shared libraries such as libutils, libcutlis, libmedia. I would perform following steps:
Install AOSP repository with target version.
Add my source code to appropriate directories under ./frameworks/base. In your case it might be easier to create a separate folder and put proper Android.mk of course.
You might get compile errors if required functions from those standard shared libraries are not present in the previous version.
When you build the code as part of AOSP it will build required libraries and link them for you automatically.
P.S. To accomplish that you're better to use a Linux-based build host.
using cygwin terminal, build native part i.e. jni folder. To build using cygwin, goto jni folder using cygdrive command. Then type ndk-build. After successful completion, shared libraries i.e. .so files will be created in libs folder.
I can understand your problem, you can pull the libraries from /system/lib of device or emulator. But you need a system permission. But you can do it by installing application.
Otherwise build your source code on linux platfor. Building process is very easy, just using 2 or 3 command. First time it is needed long time to build. After that you need very short time to build, it will build only according to the timestamp of modified code.
Please have a look here