Skip to content
This repository was archived by the owner on Feb 12, 2026. It is now read-only.

Commit 71a9dc3

Browse files
committed
fix: failed to find libc++ symbols in dex2oat bug
This commit fixes the issue where the system linker couldn't find some symbols by resetting the priority of the paths the linker should find, to force it to find the latest/correct libraries.
1 parent 202b71b commit 71a9dc3

File tree

6 files changed

+85
-18
lines changed

6 files changed

+85
-18
lines changed

.gitmodules

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,7 @@
1515
url = https://github.com/tukaani-project/xz-embedded
1616
[submodule "apache/commons-lang"]
1717
path = apache/commons-lang
18-
url = https://github.com/apache/commons-lang
18+
url = https://github.com/apache/commons-lang
19+
[submodule "external/lsplt"]
20+
path = external/lsplt
21+
url = https://github.com/PerformanC/LSPlt.git

dex2oat/src/main/cpp/CMakeLists.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@ project(dex2oat)
44
add_executable(dex2oat dex2oat.c)
55
add_library(oat_hook SHARED oat_hook.c)
66

7+
OPTION(LSPLT_BUILD_SHARED OFF)
8+
add_subdirectory(${EXTERNAL_ROOT}/lsplt/lsplt/src/main/jni external)
9+
710
target_link_libraries(dex2oat log)
8-
target_link_libraries(oat_hook log)
11+
target_link_libraries(oat_hook log lsplt_static)
912

1013
if (DEFINED DEBUG_SYMBOLS_PATH)
1114
message(STATUS "Debug symbols will be placed at ${DEBUG_SYMBOLS_PATH}")

dex2oat/src/main/cpp/dex2oat.c

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@
2828
#include <sys/socket.h>
2929
#include <sys/un.h>
3030
#include <unistd.h>
31+
#include <fcntl.h>
32+
#include <sys/stat.h>
33+
#include <errno.h>
34+
#include <limits.h>
35+
#include <dlfcn.h>
3136

3237
#include "logging.h"
3338

@@ -39,7 +44,8 @@
3944

4045
#define ID_VEC(is64, is_debug) (((is64) << 1) | (is_debug))
4146

42-
const char kSockName[] = "5291374ceda0aef7c5d86cd2a4f6a3ac\0";
47+
const char sock_name[] = "5291374ceda0aef7c5d86cd2a4f6a3ac\0";
48+
const char *linker_path = LP_SELECT("/apex/com.android.runtime/bin/linker", "/apex/com.android.runtime/bin/linker64");
4349

4450
static ssize_t xrecvmsg(int sockfd, struct msghdr *msg, int flags) {
4551
int rec = recvmsg(sockfd, msg, flags);
@@ -77,6 +83,7 @@ static int recv_fd(int sockfd) {
7783

7884
int result;
7985
memcpy(&result, data, sizeof(int));
86+
8087
return result;
8188
}
8289

@@ -118,13 +125,7 @@ static void write_string(int fd, const char *str, size_t len) {
118125

119126
int main(int argc, char **argv) {
120127
LOGD("dex2oat wrapper ppid=%d, uid=%d", getppid(), getuid());
121-
122-
if (getenv("LD_LIBRARY_PATH") == NULL) {
123-
char const *libenv = LP_SELECT(
124-
"LD_LIBRARY_PATH=/apex/com.android.art/lib:/apex/com.android.os.statsd/lib",
125-
"LD_LIBRARY_PATH=/apex/com.android.art/lib64:/apex/com.android.os.statsd/lib64");
126-
putenv((char *)libenv);
127-
}
128+
unsetenv("LD_LIBRARY_PATH");
128129

129130
int sock_fd = socket(AF_UNIX, SOCK_STREAM, 0);
130131
if (sock_fd < 0) {
@@ -137,7 +138,7 @@ int main(int argc, char **argv) {
137138
.sun_family = AF_UNIX,
138139
.sun_path = { 0 },
139140
};
140-
strlcpy(sock.sun_path + 1, kSockName, sizeof(sock.sun_path) - 1);
141+
strlcpy(sock.sun_path + 1, sock_name, sizeof(sock.sun_path) - 1);
141142

142143
size_t len = sizeof(sa_family_t) + strlen(sock.sun_path + 1) + 1;
143144
sock_fd = socket(AF_UNIX, SOCK_STREAM, 0);
@@ -158,8 +159,11 @@ int main(int argc, char **argv) {
158159

159160
return 1;
160161
}
162+
163+
char stock_fd_path[64];
164+
snprintf(stock_fd_path, sizeof(stock_fd_path), "/proc/%d/fd/%d", getpid(), stock_fd);
161165

162-
LOGI("stock dex2oat fd: %d", stock_fd);
166+
LOGI("stock dex2oat fd: %d (%s)", stock_fd, stock_fd_path);
163167

164168
close(sock_fd);
165169

@@ -187,9 +191,14 @@ int main(int argc, char **argv) {
187191
if (is_in_denylist) {
188192
LOGD("App is in denylist, exiting");
189193

190-
fexecve(stock_fd, (char **)argv, environ);
194+
char *new_argv[argc + 2];
195+
memset(new_argv, 0, sizeof(new_argv));
191196

192-
LOGE("fexecve failed");
197+
new_argv[0] = stock_fd_path;
198+
memcpy(&new_argv[1], &argv[1], sizeof(char *) * argc);
199+
200+
execve(linker_path, new_argv, environ);
201+
LOGE("execve failed");
193202

194203
close(stock_fd);
195204

@@ -229,11 +238,16 @@ int main(int argc, char **argv) {
229238
snprintf(liboat_fd_path, sizeof(liboat_fd_path), "/proc/%d/fd/%d", getpid(), hooker_fd);
230239

231240
setenv("LD_PRELOAD", liboat_fd_path, 1);
232-
LOGD("Set env LD_PRELOAD=%s", liboat_fd_path);
233241

234-
fexecve(stock_fd, (char **)argv, environ);
242+
char *new_argv[argc + 3];
243+
memset(new_argv, 0, sizeof(new_argv));
244+
245+
new_argv[0] = stock_fd_path;
246+
memcpy(&new_argv[1], &argv[1], sizeof(char *) * argc);
247+
248+
execve(linker_path, new_argv, environ);
235249

236-
PLOGE("fexecve failed");
250+
PLOGE("execve failed");
237251

238252
close(stock_fd);
239253

dex2oat/src/main/cpp/oat_hook.c

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
#include <stdlib.h>
2+
#include <string.h>
23
#include <dlfcn.h>
4+
#include <unistd.h>
5+
6+
#include <lsplt.h>
37

48
#include "logging.h"
59

@@ -28,9 +32,50 @@ void _ZN3art15CompilerOptionsC1Ev(void *self) {
2832
if (member != (void *)-1) continue;
2933

3034
*(void **)((void *)self + i) = 0;
31-
35+
3236
return;
3337
}
3438

3539
LOGE("Failed to find member with value -1 in CompilerOptions");
40+
}
41+
42+
__attribute__((constructor))
43+
static void oat_hook_init(void) {
44+
struct lsplt_map_info *maps = lsplt_scan_maps("self");
45+
if (!maps) {
46+
LOGE("Failed to scan maps");
47+
48+
return;
49+
}
50+
51+
dev_t dev = 0;
52+
ino_t inode = 0;
53+
54+
for (size_t i = 0; i < maps->length; i++) {
55+
struct lsplt_map_entry *map = &maps->maps[i];
56+
if (!map->path || !strstr(map->path, "bin/dex2oat")) continue;
57+
58+
dev = map->dev;
59+
inode = map->inode;
60+
61+
LOGD("Found target: %s (dev: %ju, inode: %ju)", map->path, (uintmax_t)dev, (uintmax_t)inode);
62+
63+
break;
64+
}
65+
66+
if (!dev || !inode) {
67+
LOGE("Failed to find dex2oat memory map");
68+
69+
lsplt_free_maps(maps);
70+
71+
return;
72+
}
73+
74+
lsplt_register_hook(dev, inode, "_ZN3art15CompilerOptionsC1Ev", _ZN3art15CompilerOptionsC1Ev, NULL);
75+
76+
if (!lsplt_commit_hook()) {
77+
LOGE("Failed to commit hook");
78+
}
79+
80+
LOGD("Hook registered successfully");
3681
}

external/lsplt

Submodule lsplt added at cab51dd

magisk-loader/magisk_module/sepolicy.rule

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
allow dex2oat dex2oat_exec file execute_no_trans
2+
allow dex2oat system_linker_exec file execute_no_trans
23

34
allow shell shell dir write
45

0 commit comments

Comments
 (0)