Detected problems with app native libraries
(please consult log for detail):
libavcodec.so: text relocations
libavutil.so: text relocations
libswresample.so: text relocations
- Appium version (or git revision) that exhibits the issue: 1.19.1
- Last Appium version that did not exhibit the issue (if applicable): Not sure, but I didn’t see it before
- Desktop OS/version used to run Appium: Windows 10 Version 2004 (OS Build 19041.685)
- Node.js version (unless using Appium.app|exe): 12.8.1
- Npm or Yarn package manager: npm
- Mobile platform/version under test: Android 7.1.2
- Real device or emulator/simulator: emulator Bluestacks
- Appium CLI or Appium.app|exe: Appium.NET
The ultimate solution to the libxxx.so-text relocations problem
error or warning log
When targetSdkVersion>=23 and using debug signature, running the app on a 6.0+ Android device will output the following error Log:
E/linker: /data/app/packagename/lib/arm/libxxx.so: has text relocations
W/System.err: java.lang.UnsatisfiedLinkError: dlopen failed: /data/app/packagename/lib/arm/libxxx.so: has text relocations
Note: When targetSdkVersion>=23, it is normal to run on devices below 6.0. As for the reason, this article concludes.
When targetSdkVersion<23 and signature is used, it runs normally on 6.0+ Android devices, but it will output the following warning log:
W/linker: “/data/app/packagename/lib/arm/libxxx.so”: has W+E (writable and executable) load segments. This is a security risk shared libraries with W+E load segments will not be supported in a future Android release. Please fix the library.
W/linker: /data/app/packagename/lib/arm/libxxx.so has text relocations. This is wasting memory and prevents security hardening. Please fix.
popup reminder dialog when app launches
When targetSdkVersion<23 and APK signed with debug are run on a higher version system (here using native 7.0 test), a dialog will pop up each time you start it, as follows:
Detected problems with app native libraries (please consult log for detail) : libxxx.so: text relocations
The above various representations can be found to be caused by the same problem, namely libxxx.so: text relocations.
“libxxx.so: text relocations” is in the questionAndroid 6.0 official update instructionsMentioned in:
On previous versions of Android, if your app requested the system to load a shared library with text relocations, the system displayed a warning but still allowed the library to be loaded. Beginning in this release, the system rejects this library if your app’s target SDK version is 23 or higher. To help you detect if a library failed to load, your app should log the
dlopen(3)failure, and include the problem description text that the
dlerror(3)call returns. To learn more about handling text relocations, see this guide.
This problem will only generate a warning before 6.0, the system can still load the shared library containing text relocations, but from 6.0, ie SDK Version>=23, the system will Refuse to load the shared library containing text relocations and output the error log, which is the error log seen above.
In fact, the most fundamental cause of this problem is that the code of the so-called dynamic link library is not PIC (Position independent code), the concept of PIC can refer toWikipediaIntroduction. In the Android 6.0 update instructions, I just mentioned a simple solution:
To learn more about handling text relocations, see this guide.
This link is a guide to resolving text relocations (TEXTRELs).
When you search this online, you will find that more than 90% of the search results tell you to set targetSdkVersion to less than 23. It is true that this can avoid the above problems, but it is not the ultimate solution.
If the app wants to use the new features of 6.0 or even 7.0 (the Android O Developer Preview has been released a few days ago, this issue is even more urgent), you must increase the targetSdkVersion to 23 or above. So this problem must be completely solved, and you must never use a compromise scheme with targetSdkVersion set to less than 23.
The real solution is to solve the problem of text relocations (TEXTRELs) in so dynamic link libraries.
Fix text relocations in source code
According to the officially recommended program link, a document called “Hardened/Textrels Guide” will open, which will guide you through the problem of text relocations.
Let’s take a look at the directory of the document:
- 1 Introduction
- 2 Finding broken object code
- 2.1 “False” Positives
- 3 Dissecting broken object code
- 3.1 Dissect libsmpeg
- 3.2 Dissect libdv
- 3.3 Dissect libSDL
- 4 Finding the broken source code
- 4.1 libsmpeg source dive
- 4.2 libSDL source dive
- 5 How to write PIC (in theory)
- 5.1 Rules of thumb
- 5.2 PIC registers by architecture
- 6 Cookie cutter PIC fixes
- 6.1 Don’t use the PIC register
- 6.2 MMX/SSE masks
- 6.3 Let gcc worry about it
- 6.4 Thunk it in assembly
- 7 How to fix broken PIC (in practice)
- 7.1 Fix libsmpeg
- 7.2 Fix libSDL
- 8 External resources
From the documentation directory, we can first find the library with text relocations problem, and then you can locate the source code to modify the source code and solve the problem completely.
But this tutorial is costly to learn, and requires specific tools to be installed, which is not very good. In addition, if there is no source code of the so dynamic library, even if it is located, it cannot be modified.
compile time processing
Configure Android.mk when compiling with NDK, add PIC related configuration items, so the compiled so files will no longer have text relocations. The specific configuration is as follows:
LOCAL_LDFLAGS += -fPIC
PIC parameters are used to compile position-independent code and generate location-independent code that can be used for shared libraries. If you do not add -fPIC, when loading the code segment of the so file, the data object referenced by the code segment needs to be relocated, and the relocation will modify the content of the code segment, thus causing the use of the so file, the process of the code segment is in the kernel. A copy of this file will be generated.
About the syntax and configuration of Android.mk, you can refer toOfficial document。
Although there are two solutions mentioned above, there are some points to pay attention to in the implementation. The following is a summary of self-practice:
- locate which so file has text relocationsIn addition to the lookup methods mentioned in the “Hardened/Textrels Guide” document above, on Linux, you can use the readelf command line to view them. An example is as follows:
readelf -a path/to/yourlib.so | grep TEXTREL
If the shell command output above is similar to the following, it means that the so file is not PIC, there is a problem with text relocations.
0x00000016 (TEXTREL) 0x0
TEXTREL represents the code segment relocation table address, and the PIC shared object does not contain any code segment relocation table. So if the above command has no output, then there is no problem with the so file.
An App usually has multiple so files, which are written by yourself and also by third parties. You can use the above methods to determine if these so files have text relocations.
Also refer toAndroid changes for NDK developersThe “Text Relocations (Enforced since API 23)” section.
- without the source code of soSometimes our app uses third-party so, such as map positioning library, audio decoding library and so on. Once there is a problem with these so files, and we don’t have the source code, it won’t work. In this case, if you want to upgrade the targetSdkVersion to 23 or above, you can only find alternatives or the functions involved.
What we encountered in practice was a problem with a third-party audio decoding library, and the solution was to use a native multimedia API instead.
It is also recommended to check the presence of text relocations when using third-party so files.
- Modifying the invalid compilation parametersFor example, a function in so directly references the .s assembly file (passive file), and just the text relocations problem is in the .s file, then compile with the -fPIC parameter. It is invalid, the problem cannot be solved, and only an alternative implementation can be found.
At the beginning of this article, I left a question: When targetSdkVersion=23 and using debug signature, the error is run on the 6.0+ Android device, but it runs normally on the system below 6.0. Why is this?
There is no answer here. By the way, let me ask a few more questions and leave it to everyone to think about:
What are the meanings of compileSdkVersion, minSdkVersion, and targetSdkVersion and what are the relationships between them?
The Android device itself has a system version, so what is the final effect on the App? Is compileSdkVersion? Is targetSdkVersion? Or is it the version of the phone itself? or other?