Skip to content

Commit 753d043

Browse files
committed
Improve the success rate of force dlopen.
1 parent e295323 commit 753d043

File tree

6 files changed

+90
-64
lines changed

6 files changed

+90
-64
lines changed

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
![](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat)
44
![](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat)
5-
![](https://img.shields.io/badge/release-2.0.0-red.svg?style=flat)
6-
![](https://img.shields.io/badge/Android-4.1%20--%2013-blue.svg?style=flat)
5+
![](https://img.shields.io/badge/release-2.1.0-red.svg?style=flat)
6+
![](https://img.shields.io/badge/Android-4.1%20--%2014-blue.svg?style=flat)
77
![](https://img.shields.io/badge/arch-armeabi--v7a%20%7C%20arm64--v8a%20%7C%20x86%20%7C%20x86__64-blue.svg?style=flat)
88

99
xDL is an enhanced implementation of the Android DL series functions.
@@ -22,7 +22,7 @@ xDL is an enhanced implementation of the Android DL series functions.
2222
* Including linker / linker64 (for Android <= 8.x).
2323
* Return full pathname instead of basename (for Android 5.x).
2424
* Return app\_process32 / app\_process64 instead of package name.
25-
* Support Android 4.1 - 13 (API level 16 - 33).
25+
* Support Android 4.1 - 14 (API level 16 - 34).
2626
* Support armeabi-v7a, arm64-v8a, x86 and x86_64.
2727
* MIT licensed.
2828

@@ -53,7 +53,7 @@ android {
5353
}
5454
5555
dependencies {
56-
implementation 'io.github.hexhacking:xdl:2.0.0'
56+
implementation 'io.github.hexhacking:xdl:2.1.0'
5757
}
5858
```
5959

README.zh-CN.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
![](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat)
44
![](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat)
5-
![](https://img.shields.io/badge/release-2.0.0-red.svg?style=flat)
6-
![](https://img.shields.io/badge/Android-4.1%20--%2013-blue.svg?style=flat)
5+
![](https://img.shields.io/badge/release-2.1.0-red.svg?style=flat)
6+
![](https://img.shields.io/badge/Android-4.1%20--%2014-blue.svg?style=flat)
77
![](https://img.shields.io/badge/arch-armeabi--v7a%20%7C%20arm64--v8a%20%7C%20x86%20%7C%20x86__64-blue.svg?style=flat)
88

99
xDL 是 Android DL 系列函数的增强实现。
@@ -22,7 +22,7 @@ xDL 是 Android DL 系列函数的增强实现。
2222
* 在 Android <= 8.x 时,包含 linker / linker64。
2323
* 在 Android 5.x 中,返回完整的路径名(full pathname),而不是文件名(basename)。
2424
* 返回 app\_process32 / app\_process64,而不是包名。
25-
* 支持 Android 4.1 - 13 (API level 16 - 33)。
25+
* 支持 Android 4.1 - 14 (API level 16 - 34)。
2626
* 支持 armeabi-v7a, arm64-v8a, x86 和 x86_64。
2727
* 使用 MIT 许可证授权。
2828

@@ -53,7 +53,7 @@ android {
5353
}
5454
5555
dependencies {
56-
implementation 'io.github.hexhacking:xdl:2.0.0'
56+
implementation 'io.github.hexhacking:xdl:2.1.0'
5757
}
5858
```
5959

build.gradle

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,20 @@ task clean(type: Delete) {
99

1010
ext {
1111
minSdkVersion = 16
12-
compileSdkVersion = 33
13-
targetSdkVersion = 33
14-
buildToolsVersion = "33.0.2"
12+
compileSdkVersion = 34
13+
targetSdkVersion = 34
14+
buildToolsVersion = "34.0.0"
1515
javaVersion = JavaVersion.VERSION_1_8
1616
ndkVersion = "23.2.8568313"
1717
cmakeVersion = "3.22.1"
1818
abiFilters = "armeabi-v7a,arm64-v8a,x86,x86_64"
1919
useASAN = false
2020
dependencyOnLocalLibrary = true
21-
xdlVersion = "2.0.0"
21+
xdlVersion = "2.1.0"
2222

2323
POM_GROUP_ID = "io.github.hexhacking"
2424
POM_ARTIFACT_ID = "xdl"
25-
POM_VERSION_NAME = "2.0.0"
25+
POM_VERSION_NAME = "2.1.0"
2626

2727
POM_NAME = "xDL Android Lib"
2828
POM_DESCRIPTION = "xDL is an enhanced implementation of the Android DL series functions."

xdl/src/main/cpp/include/xdl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
// Created by caikelun on 2020-10-04.
2323

2424
//
25-
// xDL version: 2.0.0
25+
// xDL version: 2.1.0
2626
//
2727
// xDL is an enhanced implementation of the Android DL series functions.
2828
// For more information, documentation, and the latest version please check:

xdl/src/main/cpp/xdl_linker.c

Lines changed: 75 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -38,28 +38,50 @@
3838
#define XDL_LINKER_SYM_DLOPEN_O "__dl__Z8__dlopenPKciPKv"
3939
#define XDL_LINKER_SYM_LOADER_DLOPEN_P "__loader_dlopen"
4040

41+
#ifndef __LP64__
42+
#define LIB "lib"
43+
#else
44+
#define LIB "lib64"
45+
#endif
46+
4147
typedef void *(*xdl_linker_dlopen_n_t)(const char *, int, const void *, void *);
4248
typedef void *(*xdl_linker_dlopen_o_t)(const char *, int, const void *);
4349

4450
static pthread_mutex_t *xdl_linker_mutex = NULL;
4551
static void *xdl_linker_dlopen = NULL;
4652

47-
static void *xdl_linker_caller_addr[] = {
48-
NULL, // default
49-
NULL, // art
50-
NULL // vendor
51-
};
52-
53-
#ifndef __LP64__
54-
#define XDL_LINKER_LIB "lib"
55-
#else
56-
#define XDL_LINKER_LIB "lib64"
57-
#endif
58-
static const char *xdl_linker_vendor_path[] = {
59-
// order is important
60-
"/vendor/" XDL_LINKER_LIB "/egl/", "/vendor/" XDL_LINKER_LIB "/hw/",
61-
"/vendor/" XDL_LINKER_LIB "/", "/odm/" XDL_LINKER_LIB "/",
62-
"/vendor/" XDL_LINKER_LIB "/vndk-sp/", "/odm/" XDL_LINKER_LIB "/vndk-sp/"};
53+
typedef enum { MATCH_PREFIX, MATCH_SUFFIX } xdl_linker_match_type_t;
54+
55+
#pragma clang diagnostic push
56+
#pragma clang diagnostic ignored "-Wpadded"
57+
typedef struct {
58+
xdl_linker_match_type_t type;
59+
const char *value;
60+
} xdl_linker_match_t;
61+
#pragma clang diagnostic pop
62+
63+
typedef struct {
64+
void *addr;
65+
xdl_linker_match_t *matches;
66+
size_t matches_cursor;
67+
} xdl_linker_caller_t;
68+
69+
// https://source.android.com/docs/core/architecture/vndk/linker-namespace
70+
// The following rules are loose and incomplete, you can add more according to your needs.
71+
static xdl_linker_match_t xdl_linker_match_default[] = {{MATCH_SUFFIX, "/libc.so"}};
72+
static xdl_linker_match_t xdl_linker_match_art[] = {{MATCH_SUFFIX, "/libart.so"}};
73+
static xdl_linker_match_t xdl_linker_match_sphal[] = {{MATCH_PREFIX, "/vendor/" LIB "/egl/"},
74+
{MATCH_PREFIX, "/vendor/" LIB "/hw/"},
75+
{MATCH_PREFIX, "/vendor/" LIB "/"},
76+
{MATCH_PREFIX, "/odm/" LIB "/"}};
77+
static xdl_linker_match_t xdl_linker_match_vndk[] = {{MATCH_PREFIX, "/apex/com.android.vndk.v"},
78+
{MATCH_PREFIX, "/vendor/" LIB "/vndk-sp/"},
79+
{MATCH_PREFIX, "/odm/" LIB "/vndk-sp/"}};
80+
static xdl_linker_caller_t xdl_linker_callers[] = {
81+
{NULL, xdl_linker_match_default, sizeof(xdl_linker_match_default) / sizeof(xdl_linker_match_t)},
82+
{NULL, xdl_linker_match_art, sizeof(xdl_linker_match_art) / sizeof(xdl_linker_match_t)},
83+
{NULL, xdl_linker_match_sphal, sizeof(xdl_linker_match_sphal) / sizeof(xdl_linker_match_t)},
84+
{NULL, xdl_linker_match_vndk, sizeof(xdl_linker_match_vndk) / sizeof(xdl_linker_match_t)}};
6385

6486
static void xdl_linker_init_symbols_impl(void) {
6587
// find linker from: /proc/self/maps (API level < 18) or getauxval (API level >= 18)
@@ -121,41 +143,44 @@ static void *xdl_linker_get_caller_addr(struct dl_phdr_info *info) {
121143
return NULL;
122144
}
123145

124-
static int xdl_linker_get_caller_addr_cb(struct dl_phdr_info *info, size_t size, void *arg) {
125-
(void)size;
126-
127-
size_t *vendor_match = (size_t *)arg;
146+
static void xdl_linker_save_caller_addr(struct dl_phdr_info *info, xdl_linker_caller_t *caller,
147+
size_t cursor) {
148+
void *addr = xdl_linker_get_caller_addr(info);
149+
if (NULL != addr) {
150+
caller->addr = addr;
151+
caller->matches_cursor = cursor;
152+
}
153+
}
128154

155+
static int xdl_linker_get_caller_addr_cb(struct dl_phdr_info *info, size_t size, void *arg) {
156+
(void)size, (void)arg;
129157
if (0 == info->dlpi_addr || NULL == info->dlpi_name) return 0; // continue
130158

131-
if (NULL == xdl_linker_caller_addr[0] && xdl_util_ends_with(info->dlpi_name, "/libc.so"))
132-
xdl_linker_caller_addr[0] = xdl_linker_get_caller_addr(info);
133-
134-
if (NULL == xdl_linker_caller_addr[1] && xdl_util_ends_with(info->dlpi_name, "/libart.so"))
135-
xdl_linker_caller_addr[1] = xdl_linker_get_caller_addr(info);
136-
137-
if (0 != *vendor_match) {
138-
for (size_t i = 0; i < *vendor_match; i++) {
139-
if (xdl_util_starts_with(info->dlpi_name, xdl_linker_vendor_path[i])) {
140-
void *caller_addr = xdl_linker_get_caller_addr(info);
141-
if (NULL != caller_addr) {
142-
xdl_linker_caller_addr[2] = caller_addr;
143-
*vendor_match = i;
144-
}
159+
int ret = 1; // OK
160+
for (size_t i = 0; i < sizeof(xdl_linker_callers) / sizeof(xdl_linker_callers[0]); i++) {
161+
xdl_linker_caller_t *caller = &xdl_linker_callers[i];
162+
for (size_t j = 0; j < caller->matches_cursor; j++) {
163+
xdl_linker_match_t *match = &caller->matches[j];
164+
switch (match->type) {
165+
case MATCH_PREFIX:
166+
if (xdl_util_starts_with(info->dlpi_name, match->value)) {
167+
xdl_linker_save_caller_addr(info, caller, j);
168+
}
169+
break;
170+
case MATCH_SUFFIX:
171+
if (xdl_util_ends_with(info->dlpi_name, match->value)) {
172+
xdl_linker_save_caller_addr(info, caller, j);
173+
}
174+
break;
145175
}
146176
}
177+
if (NULL == caller->addr || 0 != caller->matches_cursor) ret = 0; // continue
147178
}
148-
149-
if (NULL != xdl_linker_caller_addr[0] && NULL != xdl_linker_caller_addr[1] && 0 == *vendor_match) {
150-
return 1; // finish
151-
} else {
152-
return 0; // continue
153-
}
179+
return ret;
154180
}
155181

156182
static void xdl_linker_init_caller_addr_impl(void) {
157-
size_t vendor_match = sizeof(xdl_linker_vendor_path) / sizeof(xdl_linker_vendor_path[0]);
158-
xdl_iterate_phdr_impl(xdl_linker_get_caller_addr_cb, &vendor_match, XDL_DEFAULT);
183+
xdl_iterate_phdr_impl(xdl_linker_get_caller_addr_cb, NULL, XDL_DEFAULT);
159184
}
160185

161186
static void xdl_linker_init_caller_addr(void) {
@@ -186,19 +211,20 @@ void *xdl_linker_force_dlopen(const char *filename) {
186211
if (__ANDROID_API_N__ == api_level || __ANDROID_API_N_MR1__ == api_level) {
187212
// == Android 7.x
188213
xdl_linker_lock();
189-
for (size_t i = 0; i < sizeof(xdl_linker_caller_addr) / sizeof(xdl_linker_caller_addr[0]); i++) {
190-
if (NULL != xdl_linker_caller_addr[i]) {
191-
handle =
192-
((xdl_linker_dlopen_n_t)xdl_linker_dlopen)(filename, RTLD_NOW, NULL, xdl_linker_caller_addr[i]);
214+
for (size_t i = 0; i < sizeof(xdl_linker_callers) / sizeof(xdl_linker_callers[0]); i++) {
215+
xdl_linker_caller_t *caller = &xdl_linker_callers[i];
216+
if (NULL != caller->addr) {
217+
handle = ((xdl_linker_dlopen_n_t)xdl_linker_dlopen)(filename, RTLD_NOW, NULL, caller->addr);
193218
if (NULL != handle) break;
194219
}
195220
}
196221
xdl_linker_unlock();
197222
} else {
198223
// >= Android 8.0
199-
for (size_t i = 0; i < sizeof(xdl_linker_caller_addr) / sizeof(xdl_linker_caller_addr[0]); i++) {
200-
if (NULL != xdl_linker_caller_addr[i]) {
201-
handle = ((xdl_linker_dlopen_o_t)xdl_linker_dlopen)(filename, RTLD_NOW, xdl_linker_caller_addr[i]);
224+
for (size_t i = 0; i < sizeof(xdl_linker_callers) / sizeof(xdl_linker_callers[0]); i++) {
225+
xdl_linker_caller_t *caller = &xdl_linker_callers[i];
226+
if (NULL != caller->addr) {
227+
handle = ((xdl_linker_dlopen_o_t)xdl_linker_dlopen)(filename, RTLD_NOW, caller->addr);
202228
if (NULL != handle) break;
203229
}
204230
}

xdl_sample/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ android {
5858

5959
dependencies {
6060
implementation 'androidx.appcompat:appcompat:1.6.1'
61-
implementation 'com.google.android.material:material:1.8.0'
61+
implementation 'com.google.android.material:material:1.11.0'
6262
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
6363

6464
if (rootProject.ext.dependencyOnLocalLibrary) {

0 commit comments

Comments
 (0)