Resolve dex2oat parameters for Android 10+ (#1803)
This commit is contained in:
parent
6afa054b1c
commit
2f9e0e07b0
|
|
@ -0,0 +1,152 @@
|
||||||
|
/*
|
||||||
|
* This file is part of LSPosed.
|
||||||
|
*
|
||||||
|
* LSPosed is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* LSPosed is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with LSPosed. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 LSPosed Contributors
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.lsposed.lspd.service;
|
||||||
|
|
||||||
|
import android.net.LocalServerSocket;
|
||||||
|
import android.net.LocalSocket;
|
||||||
|
import android.net.LocalSocketAddress;
|
||||||
|
import android.os.SELinux;
|
||||||
|
import android.system.ErrnoException;
|
||||||
|
import android.system.Os;
|
||||||
|
import android.system.OsConstants;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileDescriptor;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InterruptedIOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
public class Dex2OatService {
|
||||||
|
|
||||||
|
private static final String TAG = "Dex2OatService";
|
||||||
|
private static final String DEX2OAT_32 = "/apex/com.android.art/bin/dex2oat32";
|
||||||
|
private static final String DEX2OAT_64 = "/apex/com.android.art/bin/dex2oat64";
|
||||||
|
|
||||||
|
private Thread thread = null;
|
||||||
|
|
||||||
|
public void start() {
|
||||||
|
try {
|
||||||
|
var devPath = Files.readAllLines(Paths.get("/data/adb/lspd/dev_path")).get(0);
|
||||||
|
Log.d(TAG, "dev path: " + devPath);
|
||||||
|
daemon(devPath);
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e(TAG, "dex2oat daemon failed to start", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAlive() {
|
||||||
|
return thread.isAlive();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void daemon(String devPath) {
|
||||||
|
thread = new Thread(() -> {
|
||||||
|
try {
|
||||||
|
Log.i(TAG, "dex2oat daemon start");
|
||||||
|
if (setSocketCreateContext("u:r:dex2oat:s0")) {
|
||||||
|
Log.d(TAG, "set socket context to u:r:dex2oat:s0");
|
||||||
|
} else {
|
||||||
|
Log.e(TAG, "failed to set socket context");
|
||||||
|
}
|
||||||
|
var sockPath = devPath + "/dex2oat.sock";
|
||||||
|
var serverSocket = new LocalSocket(LocalSocket.SOCKET_STREAM);
|
||||||
|
serverSocket.bind(new LocalSocketAddress(sockPath, LocalSocketAddress.Namespace.FILESYSTEM));
|
||||||
|
var server = new LocalServerSocket(serverSocket.getFileDescriptor());
|
||||||
|
SELinux.setFileContext(sockPath, "u:object_r:magisk_file:s0");
|
||||||
|
FileDescriptor stockFd32 = null, stockFd64 = null;
|
||||||
|
if (new File(DEX2OAT_32).exists()) stockFd32 = Os.open(DEX2OAT_32, OsConstants.O_RDONLY, 0);
|
||||||
|
if (new File(DEX2OAT_64).exists()) stockFd64 = Os.open(DEX2OAT_64, OsConstants.O_RDONLY, 0);
|
||||||
|
while (true) {
|
||||||
|
var client = server.accept();
|
||||||
|
try (var is = client.getInputStream();
|
||||||
|
var os = client.getOutputStream()) {
|
||||||
|
var lp = is.read();
|
||||||
|
if (lp == 32) client.setFileDescriptorsForSend(new FileDescriptor[]{stockFd32});
|
||||||
|
else client.setFileDescriptorsForSend(new FileDescriptor[]{stockFd64});
|
||||||
|
os.write(1);
|
||||||
|
Log.d(TAG, "sent fd" + lp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "dex2oat daemon crashed", e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
thread.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean setSocketCreateContext(String context) {
|
||||||
|
FileDescriptor fd = null;
|
||||||
|
try {
|
||||||
|
fd = Os.open("/proc/thread-self/attr/sockcreate", OsConstants.O_RDWR, 0);
|
||||||
|
} catch (ErrnoException e) {
|
||||||
|
if (e.errno == OsConstants.ENOENT) {
|
||||||
|
int tid = Os.gettid();
|
||||||
|
try {
|
||||||
|
fd = Os.open(String.format(Locale.ENGLISH, "/proc/self/task/%d/attr/sockcreate", tid), OsConstants.O_RDWR, 0);
|
||||||
|
} catch (ErrnoException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fd == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] bytes;
|
||||||
|
int length;
|
||||||
|
int remaining;
|
||||||
|
if (!TextUtils.isEmpty(context)) {
|
||||||
|
byte[] stringBytes = context.getBytes();
|
||||||
|
bytes = new byte[stringBytes.length + 1];
|
||||||
|
System.arraycopy(stringBytes, 0, bytes, 0, stringBytes.length);
|
||||||
|
bytes[stringBytes.length] = '\0';
|
||||||
|
|
||||||
|
length = bytes.length;
|
||||||
|
remaining = bytes.length;
|
||||||
|
} else {
|
||||||
|
bytes = null;
|
||||||
|
length = 0;
|
||||||
|
remaining = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
try {
|
||||||
|
remaining -= Os.write(fd, bytes, length - remaining, remaining);
|
||||||
|
if (remaining <= 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (ErrnoException e) {
|
||||||
|
break;
|
||||||
|
} catch (InterruptedIOException e) {
|
||||||
|
remaining -= e.bytesTransferred;
|
||||||
|
}
|
||||||
|
} while (true);
|
||||||
|
|
||||||
|
try {
|
||||||
|
Os.close(fd);
|
||||||
|
} catch (ErrnoException e) {
|
||||||
|
Log.w(TAG, Log.getStackTraceString(e));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -688,7 +688,11 @@ public class LSPManagerService extends ILSPManagerService.Stub {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean dex2oatFlagsLoaded() {
|
public boolean dex2oatFlagsLoaded() {
|
||||||
return SystemProperties.get(PROP_NAME).contains(PROP_VALUE);
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
|
return ServiceManager.getDex2OatService().isAlive();
|
||||||
|
} else {
|
||||||
|
return SystemProperties.get(PROP_NAME).contains(PROP_VALUE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ package org.lsposed.lspd.service;
|
||||||
import android.app.ActivityThread;
|
import android.app.ActivityThread;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.ddm.DdmHandleAppName;
|
import android.ddm.DdmHandleAppName;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.IServiceManager;
|
import android.os.IServiceManager;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
|
|
@ -49,9 +50,14 @@ public class ServiceManager {
|
||||||
private static LSPManagerService managerService = null;
|
private static LSPManagerService managerService = null;
|
||||||
private static LSPSystemServerService systemServerService = null;
|
private static LSPSystemServerService systemServerService = null;
|
||||||
private static LogcatService logcatService = null;
|
private static LogcatService logcatService = null;
|
||||||
|
private static Dex2OatService dex2OatService = null;
|
||||||
|
|
||||||
private static final ExecutorService executorService = Executors.newCachedThreadPool();
|
private static final ExecutorService executorService = Executors.newCachedThreadPool();
|
||||||
|
|
||||||
|
public static Dex2OatService getDex2OatService() {
|
||||||
|
return dex2OatService;
|
||||||
|
}
|
||||||
|
|
||||||
public static ExecutorService getExecutorService() {
|
public static ExecutorService getExecutorService() {
|
||||||
return executorService;
|
return executorService;
|
||||||
}
|
}
|
||||||
|
|
@ -98,6 +104,11 @@ public class ServiceManager {
|
||||||
logcatService = new LogcatService();
|
logcatService = new LogcatService();
|
||||||
logcatService.start();
|
logcatService.start();
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
|
dex2OatService = new Dex2OatService();
|
||||||
|
dex2OatService.start();
|
||||||
|
}
|
||||||
|
|
||||||
Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND);
|
Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND);
|
||||||
Looper.prepareMainLooper();
|
Looper.prepareMainLooper();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
/build
|
||||||
|
/.cxx
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* This file is part of LSPosed.
|
||||||
|
*
|
||||||
|
* LSPosed is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* LSPosed is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with LSPosed. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 LSPosed Contributors
|
||||||
|
*/
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
id("com.android.library")
|
||||||
|
}
|
||||||
|
|
||||||
|
android {
|
||||||
|
namespace = "org.lsposed.dex2oat"
|
||||||
|
|
||||||
|
buildFeatures {
|
||||||
|
androidResources = false
|
||||||
|
buildConfig = false
|
||||||
|
prefab = true
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
minSdk = 29
|
||||||
|
}
|
||||||
|
|
||||||
|
externalNativeBuild {
|
||||||
|
cmake {
|
||||||
|
path("src/main/cpp/CMakeLists.txt")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
project(dex2oat)
|
||||||
|
cmake_minimum_required(VERSION 3.4.1)
|
||||||
|
|
||||||
|
add_subdirectory(${EXTERNAL_ROOT} external)
|
||||||
|
|
||||||
|
add_executable(dex2oat dex2oat.c)
|
||||||
|
|
||||||
|
target_link_libraries(dex2oat cxx log)
|
||||||
|
|
||||||
|
if (DEFINED DEBUG_SYMBOLS_PATH)
|
||||||
|
message(STATUS "Debug symbols will be placed at ${DEBUG_SYMBOLS_PATH}")
|
||||||
|
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E make_directory ${DEBUG_SYMBOLS_PATH}/${ANDROID_ABI}
|
||||||
|
COMMAND ${CMAKE_OBJCOPY} --only-keep-debug $<TARGET_FILE:${PROJECT_NAME}>
|
||||||
|
${DEBUG_SYMBOLS_PATH}/${ANDROID_ABI}/${PROJECT_NAME}.debug
|
||||||
|
COMMAND ${CMAKE_STRIP} --strip-all $<TARGET_FILE:${PROJECT_NAME}>
|
||||||
|
COMMAND ${CMAKE_OBJCOPY} --add-gnu-debuglink ${DEBUG_SYMBOLS_PATH}/${ANDROID_ABI}/${PROJECT_NAME}.debug
|
||||||
|
$<TARGET_FILE:${PROJECT_NAME}>)
|
||||||
|
endif()
|
||||||
|
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
* This file is part of LSPosed.
|
||||||
|
*
|
||||||
|
* LSPosed is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* LSPosed is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with LSPosed. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 LSPosed Contributors
|
||||||
|
*/
|
||||||
|
|
||||||
|
//
|
||||||
|
// Created by Nullptr on 2022/4/1.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "logging.h"
|
||||||
|
|
||||||
|
#if defined(__LP64__)
|
||||||
|
# define LP_SELECT(lp32, lp64) lp64
|
||||||
|
#else
|
||||||
|
# define LP_SELECT(lp32, lp64) lp32
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char kTmpDir[] = "placeholder_/dev/0123456789abcdef";
|
||||||
|
|
||||||
|
static ssize_t xrecvmsg(int sockfd, struct msghdr *msg, int flags) {
|
||||||
|
int rec = recvmsg(sockfd, msg, flags);
|
||||||
|
if (rec < 0) {
|
||||||
|
PLOGE("recvmsg");
|
||||||
|
}
|
||||||
|
return rec;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *recv_fds(int sockfd, char *cmsgbuf, size_t bufsz, int cnt) {
|
||||||
|
struct iovec iov = {
|
||||||
|
.iov_base = &cnt,
|
||||||
|
.iov_len = sizeof(cnt),
|
||||||
|
};
|
||||||
|
struct msghdr msg = {
|
||||||
|
.msg_iov = &iov,
|
||||||
|
.msg_iovlen = 1,
|
||||||
|
.msg_control = cmsgbuf,
|
||||||
|
.msg_controllen = bufsz
|
||||||
|
};
|
||||||
|
|
||||||
|
xrecvmsg(sockfd, &msg, MSG_WAITALL);
|
||||||
|
struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
|
||||||
|
|
||||||
|
if (msg.msg_controllen != bufsz ||
|
||||||
|
cmsg == NULL ||
|
||||||
|
cmsg->cmsg_len != CMSG_LEN(sizeof(int) * cnt) ||
|
||||||
|
cmsg->cmsg_level != SOL_SOCKET ||
|
||||||
|
cmsg->cmsg_type != SCM_RIGHTS) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CMSG_DATA(cmsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void write_int(int fd, int val) {
|
||||||
|
if (fd < 0) return;
|
||||||
|
write(fd, &val, sizeof(val));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int recv_fd(int sockfd) {
|
||||||
|
char cmsgbuf[CMSG_SPACE(sizeof(int))];
|
||||||
|
|
||||||
|
void *data = recv_fds(sockfd, cmsgbuf, sizeof(cmsgbuf), 1);
|
||||||
|
if (data == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
int result;
|
||||||
|
memcpy(&result, data, sizeof(int));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
LOGI("dex2oat wrapper");
|
||||||
|
struct sockaddr_un sock;
|
||||||
|
sock.sun_family = AF_UNIX;
|
||||||
|
snprintf(sock.sun_path, sizeof(sock.sun_path), "%s/dex2oat.sock", kTmpDir + 12);
|
||||||
|
int sock_fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
|
if (-1 == connect(sock_fd, (struct sockaddr *) &sock, sizeof(sock))) {
|
||||||
|
PLOGE("failed to connect to %s", sock.sun_path);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
write_int(sock_fd, LP_SELECT(32, 64));
|
||||||
|
int stock_fd = recv_fd(sock_fd);
|
||||||
|
close(sock_fd);
|
||||||
|
LOGD("sock: %s %d", sock.sun_path, stock_fd);
|
||||||
|
|
||||||
|
const char *new_argv[argc + 2];
|
||||||
|
for (int i = 0; i < argc; i++) new_argv[i] = argv[i];
|
||||||
|
new_argv[argc] = "--inline-max-code-units=0";
|
||||||
|
new_argv[argc + 1] = NULL;
|
||||||
|
fexecve(stock_fd, (char **) new_argv, environ);
|
||||||
|
PLOGE("fexecve failed");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <android/log.h>
|
||||||
|
|
||||||
|
#ifndef LOG_TAG
|
||||||
|
#define LOG_TAG "dex2oat-wrapper"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef LOG_DISABLED
|
||||||
|
#define LOGD(...)
|
||||||
|
#define LOGV(...)
|
||||||
|
#define LOGI(...)
|
||||||
|
#define LOGW(...)
|
||||||
|
#define LOGE(...)
|
||||||
|
#else
|
||||||
|
#ifndef NDEBUG
|
||||||
|
#define LOGD(fmt, ...) \
|
||||||
|
__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, \
|
||||||
|
"%s:%d#%s" \
|
||||||
|
": " fmt, \
|
||||||
|
__FILE_NAME__, __LINE__, __PRETTY_FUNCTION__ __VA_OPT__(, ) __VA_ARGS__)
|
||||||
|
#define LOGV(fmt, ...) \
|
||||||
|
__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, \
|
||||||
|
"%s:%d#%s" \
|
||||||
|
": " fmt, \
|
||||||
|
__FILE_NAME__, __LINE__, __PRETTY_FUNCTION__ __VA_OPT__(, ) __VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define LOGD(...)
|
||||||
|
#define LOGV(...)
|
||||||
|
#endif
|
||||||
|
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
|
||||||
|
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)
|
||||||
|
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
|
||||||
|
#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL, LOG_TAG, __VA_ARGS__)
|
||||||
|
#define PLOGE(fmt, args...) LOGE(fmt " failed with %d: %s", ##args, errno, strerror(errno))
|
||||||
|
#endif
|
||||||
|
|
@ -143,7 +143,8 @@ fun afterEval() = android.applicationVariants.forEach { variant ->
|
||||||
dependsOn(
|
dependsOn(
|
||||||
"assemble$variantCapped",
|
"assemble$variantCapped",
|
||||||
":app:package$buildTypeCapped",
|
":app:package$buildTypeCapped",
|
||||||
":daemon:package$buildTypeCapped"
|
":daemon:package$buildTypeCapped",
|
||||||
|
":dex2oat:merge${buildTypeCapped}NativeLibs"
|
||||||
)
|
)
|
||||||
into(magiskDir)
|
into(magiskDir)
|
||||||
from("${rootProject.projectDir}/README.md")
|
from("${rootProject.projectDir}/README.md")
|
||||||
|
|
@ -205,6 +206,11 @@ fun afterEval() = android.applicationVariants.forEach { variant ->
|
||||||
include("**/libdaemon.so")
|
include("**/libdaemon.so")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
into("bin") {
|
||||||
|
from("${project(":dex2oat").buildDir}/intermediates/cmake/$buildTypeLowered/obj") {
|
||||||
|
include("**/dex2oat")
|
||||||
|
}
|
||||||
|
}
|
||||||
val dexOutPath = if (buildTypeLowered == "release")
|
val dexOutPath = if (buildTypeLowered == "release")
|
||||||
"$buildDir/intermediates/dex/$variantCapped/minify${variantCapped}WithR8" else
|
"$buildDir/intermediates/dex/$variantCapped/minify${variantCapped}WithR8" else
|
||||||
"$buildDir/intermediates/dex/$variantCapped/mergeDex$variantCapped"
|
"$buildDir/intermediates/dex/$variantCapped/mergeDex$variantCapped"
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,6 @@ fi
|
||||||
ui_print "- Extracting module files"
|
ui_print "- Extracting module files"
|
||||||
|
|
||||||
extract "$ZIPFILE" 'module.prop' "$MODPATH"
|
extract "$ZIPFILE" 'module.prop' "$MODPATH"
|
||||||
extract "$ZIPFILE" 'system.prop' "$MODPATH"
|
|
||||||
extract "$ZIPFILE" 'post-fs-data.sh' "$MODPATH"
|
extract "$ZIPFILE" 'post-fs-data.sh' "$MODPATH"
|
||||||
extract "$ZIPFILE" 'service.sh' "$MODPATH"
|
extract "$ZIPFILE" 'service.sh' "$MODPATH"
|
||||||
extract "$ZIPFILE" 'uninstall.sh' "$MODPATH"
|
extract "$ZIPFILE" 'uninstall.sh' "$MODPATH"
|
||||||
|
|
@ -89,6 +88,31 @@ extract "$ZIPFILE" 'daemon' "$MODPATH"
|
||||||
rm -f /data/adb/lspd/manager.apk
|
rm -f /data/adb/lspd/manager.apk
|
||||||
extract "$ZIPFILE" 'manager.apk' '/data/adb/lspd'
|
extract "$ZIPFILE" 'manager.apk' '/data/adb/lspd'
|
||||||
|
|
||||||
|
if [ "$API" -ge 29 ]; then
|
||||||
|
ui_print "- Extracting dex2oat binaries"
|
||||||
|
mkdir "$MODPATH/bin"
|
||||||
|
|
||||||
|
if [ "$ARCH" = "arm" ] || [ "$ARCH" = "arm64" ]; then
|
||||||
|
extract "$ZIPFILE" "bin/armeabi-v7a/dex2oat" "$MODPATH/bin" true
|
||||||
|
mv "$MODPATH/bin/dex2oat" "$MODPATH/bin/dex2oat32"
|
||||||
|
|
||||||
|
if [ "$IS64BIT" = true ]; then
|
||||||
|
extract "$ZIPFILE" "bin/arm64-v8a/dex2oat" "$MODPATH/bin" true
|
||||||
|
mv "$MODPATH/bin/dex2oat" "$MODPATH/bin/dex2oat64"
|
||||||
|
fi
|
||||||
|
elif [ "$ARCH" == "x86" ] || [ "$ARCH" == "x64" ]; then
|
||||||
|
extract "$ZIPFILE" "bin/x86/dex2oat" "$MODPATH/bin" true
|
||||||
|
mv "$MODPATH/bin/dex2oat" "$MODPATH/bin/dex2oat32"
|
||||||
|
|
||||||
|
if [ "$IS64BIT" = true ]; then
|
||||||
|
extract "$ZIPFILE" "bin/x86_64/dex2oat" "$MODPATH/bin" true
|
||||||
|
mv "$MODPATH/bin/dex2oat" "$MODPATH/bin/dex2oat64"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
extract "$ZIPFILE" 'system.prop' "$MODPATH"
|
||||||
|
fi
|
||||||
|
|
||||||
ui_print "- Extracting daemon libraries"
|
ui_print "- Extracting daemon libraries"
|
||||||
if [ "$ARCH" = "arm" ] ; then
|
if [ "$ARCH" = "arm" ] ; then
|
||||||
extract "$ZIPFILE" 'lib/armeabi-v7a/libdaemon.so' "$MODPATH" true
|
extract "$ZIPFILE" 'lib/armeabi-v7a/libdaemon.so' "$MODPATH" true
|
||||||
|
|
@ -161,6 +185,7 @@ elif [ "$FLAVOR" == "riru" ]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
set_perm_recursive "$MODPATH" 0 0 0755 0644
|
set_perm_recursive "$MODPATH" 0 0 0755 0644
|
||||||
|
set_perm_recursive "$MODPATH/bin" 0 0 0755 0755 u:object_r:dex2oat_exec:s0
|
||||||
chmod 0744 "$MODPATH/daemon"
|
chmod 0744 "$MODPATH/daemon"
|
||||||
|
|
||||||
if [ "$(grep_prop ro.maple.enable)" == "1" ] && [ "$FLAVOR" == "zygisk" ]; then
|
if [ "$(grep_prop ro.maple.enable)" == "1" ] && [ "$FLAVOR" == "zygisk" ]; then
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#!/system/bin/sh
|
#!/system/bin/sh
|
||||||
|
|
||||||
dir=${0%/*}
|
dir=${0%/*}
|
||||||
|
magiskPath=$(magisk --path)
|
||||||
tmpLspdApk="/data/local/tmp/daemon.apk"
|
tmpLspdApk="/data/local/tmp/daemon.apk"
|
||||||
debug=@DEBUG@
|
debug=@DEBUG@
|
||||||
flavor=@FLAVOR@
|
flavor=@FLAVOR@
|
||||||
|
|
@ -38,5 +39,16 @@ if [ ! -S "/dev/socket/zygote" ]; then
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
$debug && log -p d -t "LSPosed" "start $flavor daemon $*"
|
$debug && log -p d -t "LSPosed" "start $flavor daemon $*"
|
||||||
|
|
||||||
|
if [ "$(getprop ro.build.version.sdk)" -ge 29 ]; then
|
||||||
|
umount /apex/com.android.art/bin/dex2oat*
|
||||||
|
mkdir "$magiskPath/dex2oat"
|
||||||
|
cp -p /apex/com.android.art/bin/dex2oat32 "$magiskPath/dex2oat/dex2oat32"
|
||||||
|
cp -p /apex/com.android.art/bin/dex2oat64 "$magiskPath/dex2oat/dex2oat64"
|
||||||
|
chcon -R u:object_r:magisk_file:s0 "$magiskPath/dex2oat"
|
||||||
|
mount --bind "$magiskPath/dex2oat/dex2oat32" /apex/com.android.art/bin/dex2oat32
|
||||||
|
mount --bind "$magiskPath/dex2oat/dex2oat64" /apex/com.android.art/bin/dex2oat64
|
||||||
|
fi
|
||||||
|
|
||||||
# shellcheck disable=SC2086
|
# shellcheck disable=SC2086
|
||||||
exec /system/bin/app_process $java_options /system/bin --nice-name=lspd org.lsposed.lspd.Main "$@" >/dev/null 2>&1
|
exec /system/bin/app_process $java_options /system/bin --nice-name=lspd org.lsposed.lspd.Main "$@" >/dev/null 2>&1
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,23 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
MODDIR=${0%/*}
|
MODDIR=${0%/*}
|
||||||
|
MODNAME=${MODDIR##*/}
|
||||||
|
MAGISK_PATH=$(magisk --path)
|
||||||
|
|
||||||
rm -f "/data/local/tmp/daemon.apk"
|
rm -f "/data/local/tmp/daemon.apk"
|
||||||
cd "$MODDIR"
|
cd "$MODDIR"
|
||||||
|
|
||||||
|
if [ "$(getprop ro.build.version.sdk)" -ge 29 ]; then
|
||||||
|
TMP=$($RANDOM | md5sum | head -c 16)
|
||||||
|
while [ -d "/dev/$TMP" ]; do
|
||||||
|
TMP=$($RANDOM | md5sum | head -c 16)
|
||||||
|
done
|
||||||
|
mkdir "/dev/$TMP"
|
||||||
|
echo "/dev/$TMP" > "/data/adb/lspd/dev_path"
|
||||||
|
sed -i "s/placeholder_\/dev\/................/placeholder_\/dev\/$TMP/" "$MODDIR/bin/dex2oat32"
|
||||||
|
sed -i "s/placeholder_\/dev\/................/placeholder_\/dev\/$TMP/" "$MODDIR/bin/dex2oat64"
|
||||||
|
mount --bind "$MAGISK_PATH/.magisk/modules/$MODNAME/bin/dex2oat32" "/apex/com.android.art/bin/dex2oat32"
|
||||||
|
mount --bind "$MAGISK_PATH/.magisk/modules/$MODNAME/bin/dex2oat64" "/apex/com.android.art/bin/dex2oat64"
|
||||||
|
fi
|
||||||
|
|
||||||
unshare -m sh -c "$MODDIR/daemon &"
|
unshare -m sh -c "$MODDIR/daemon &"
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ include(
|
||||||
":app",
|
":app",
|
||||||
":core",
|
":core",
|
||||||
":daemon",
|
":daemon",
|
||||||
|
":dex2oat",
|
||||||
":hiddenapi:stubs",
|
":hiddenapi:stubs",
|
||||||
":hiddenapi:bridge",
|
":hiddenapi:bridge",
|
||||||
":magisk-loader",
|
":magisk-loader",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue