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.
Related
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
Is there any way to determine what version of the NDK was used to compile an "aar" library? Either decompiling, or via code would be fine, just need to know.
I am trying to determine what version of the ndk one of my third party libraries was built using.
An "aar" file is not compiled with NDK, you probably mean one of the c++ libraries inside that file. There is no simple way, but you can rule out new ndk versions according to the library date.
Also, you might be able to find out by getting the compiler version - see if something like this can help: How to retrieve the GCC version used to compile a given ELF executable
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.
Android already has the PCRE shared library ("/system/lib/libpcre.so"), but it's compiled without Unicode support, so I've built my own version of PCRE for Android. My native code is linked to the PCRE shared library. However, when I run my app, it uses the system's version of PCRE, rather than the one I've built, even though my APK does include my version of PCRE. How do I make it use my version of PCRE rather than the system's? Generally in Linux I use "LD_LIBRARY_PATH" or "RPATH", but on Android I don't know how to use them, if that's at all possible.
You can load("your-path-to-lib") before you load the main library. With this API you can load a native library at arbitrary location. But the easiest way is to rely on the default behavior of build and installer, which will pack the native libraries (named libsomething.so) that it finds in libs/<ABI> folders, into the APK file, and unpack the ABI variant that matches the target into
getContext().getApplicationInfo().nativeLibraryDir
(this was added in API level 9)
If the library is pre-loaded, you cannot have your library side-by-side with the system one, due to a bug that invloved older versions of Android. Still, you may succeed to unload it manually, using dlclose():
handle = dlopen("<libname>", RTLD_NOLOAD);
dlclose(handle);
dlclose(handle); // twice, because dlopen() increments ref count
You will probably do these manipulations in a separate small dlclose_helper.so. Load this helper load before you load the main library, which needs the private version of <libname>.
A fix was introduced for API level 23 that lets us finally load both dir1/libx.so and dir2/libx.so (see the official doc).
Note that for API level 24, new restrictions have also been introduced that limits access to system libraries (you can only load white-listed ones).
I believe the only way is to rename the library (libpcre_myapp, for example).
Note that renaming just the file probably is not sufficient, but changing the SO_NAME ELF property.
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