Optimize dex2oat wrapper (#1805)

This commit is contained in:
Nullptr 2022-04-03 11:30:15 +08:00 committed by GitHub
parent fc12f48034
commit 3ca1478a3a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 104 additions and 58 deletions

View File

@ -120,9 +120,14 @@ public class HomeFragment extends BaseFragment {
binding.warningSummary.setText(HtmlCompat.fromHtml(getString(R.string.system_inject_fail), HtmlCompat.FROM_HTML_MODE_LEGACY));
}
if (!ConfigManager.dex2oatFlagsLoaded()) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
binding.warningTitle.setText(R.string.dex2oat_service_crashed_summary);
binding.warningSummary.setText(HtmlCompat.fromHtml(getString(R.string.dex2oat_service_crashed), HtmlCompat.FROM_HTML_MODE_LEGACY));
} else {
binding.warningTitle.setText(R.string.system_prop_incorrect_summary);
binding.warningSummary.setText(HtmlCompat.fromHtml(getString(R.string.system_prop_incorrect), HtmlCompat.FROM_HTML_MODE_LEGACY));
}
}
} else {
binding.warningCard.setVisibility(View.GONE);
binding.statusTitle.setText(R.string.activated);

View File

@ -51,6 +51,8 @@
<string name="selinux_policy_not_loaded"><![CDATA[Modules that hook System Framework will not work.<br/>Please report this to <a href="https://github.com/topjohnwu/Magisk/issues"><b>Magisk</b></a> developer.]]></string>
<string name="system_inject_fail_summary">System Framework injection failed</string>
<string name="system_inject_fail"><![CDATA[This is rare and may be caused by <b>Magisk</b> or some low-quality Magisk modules.<br/>Please try to disable Magisk modules other than Riru and LSPosed or submit full log to developers.]]></string>
<string name="dex2oat_service_crashed_summary">Dex optimizer service crashed</string>
<string name="dex2oat_service_crashed"><![CDATA[LSPosed dex2oat wrapper crashed.<br/>Modules may invalidate occasionally or applications may become laggy.]]></string>
<string name="system_prop_incorrect_summary">System prop incorrect</string>
<string name="system_prop_incorrect"><![CDATA[Some necessary system properties deleted or modified.<br/>Modules may invalidate occasionally.]]></string>
<string name="need_update">Need to update</string>

View File

@ -31,7 +31,6 @@ 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;
@ -44,22 +43,11 @@ public class Dex2OatService {
private static final String DEX2OAT_64 = "/apex/com.android.art/bin/dex2oat64";
private Thread thread = null;
private LocalSocket serverSocket = null;
private LocalServerSocket server = null;
private FileDescriptor stockFd32 = null, stockFd64 = 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");
@ -68,14 +56,18 @@ public class Dex2OatService {
} else {
Log.e(TAG, "failed to set socket context");
}
var devPath = getDevPath();
var sockPath = devPath + "/dex2oat.sock";
var serverSocket = new LocalSocket(LocalSocket.SOCKET_STREAM);
Files.createDirectories(Paths.get(devPath));
Log.d(TAG, "dev path: " + devPath);
serverSocket = new LocalSocket(LocalSocket.SOCKET_STREAM);
serverSocket.bind(new LocalSocketAddress(sockPath, LocalSocketAddress.Namespace.FILESYSTEM));
var server = new LocalServerSocket(serverSocket.getFileDescriptor());
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();
@ -94,6 +86,12 @@ public class Dex2OatService {
thread.start();
}
public boolean isAlive() {
return thread.isAlive();
}
private static native String getDevPath();
private boolean setSocketCreateContext(String context) {
FileDescriptor fd = null;
try {

View File

@ -4,6 +4,7 @@ cmake_minimum_required(VERSION 3.4.1)
add_subdirectory(${EXTERNAL_ROOT} external)
set(SOURCES
dex2oat.c
logcat.cpp
obfuscation.cpp
)

View File

@ -0,0 +1,31 @@
/*
* 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/2.
//
#include <jni.h>
char kTmpDir[] = "placeholder_/dev/0123456789abcdef";
JNIEXPORT jstring JNICALL
Java_org_lsposed_lspd_service_Dex2OatService_getDevPath(JNIEnv *env, jclass clazz) {
return (*env)->NewStringUTF(env, kTmpDir + 12);
}

View File

@ -72,11 +72,6 @@ static void *recv_fds(int sockfd, char *cmsgbuf, size_t bufsz, int cnt) {
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))];
@ -89,6 +84,18 @@ static int recv_fd(int sockfd) {
return result;
}
static int read_int(int fd) {
int val;
if (read(fd, &val, sizeof(val)) != sizeof(val))
return -1;
return val;
}
static void write_int(int fd, int val) {
if (fd < 0) return;
write(fd, &val, sizeof(val));
}
int main(int argc, char **argv) {
LOGI("dex2oat wrapper");
struct sockaddr_un sock;
@ -101,6 +108,7 @@ int main(int argc, char **argv) {
}
write_int(sock_fd, LP_SELECT(32, 64));
int stock_fd = recv_fd(sock_fd);
read_int(sock_fd);
close(sock_fd);
LOGD("sock: %s %d", sock.sun_path, stock_fd);

View File

@ -88,31 +88,6 @@ extract "$ZIPFILE" 'daemon' "$MODPATH"
rm -f /data/adb/lspd/manager.apk
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"
if [ "$ARCH" = "arm" ] ; then
extract "$ZIPFILE" 'lib/armeabi-v7a/libdaemon.so' "$MODPATH" true
@ -184,6 +159,40 @@ elif [ "$FLAVOR" == "riru" ]; then
fi
fi
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
ui_print "- Patching binaries"
DEV_PATH=$(tr -dc 'a-f0-9' < /dev/urandom | head -c 16)
while [ -d "/dev/$DEV_PATH" ]; do
DEV_PATH=$(tr -dc 'a-f0-9' < /dev/urandom | head -c 16)
done
sed -i "s/placeholder_\/dev\/................/placeholder_\/dev\/$DEV_PATH/" "$MODPATH/libdaemon.so"
sed -i "s/placeholder_\/dev\/................/placeholder_\/dev\/$DEV_PATH/" "$MODPATH/bin/dex2oat32"
sed -i "s/placeholder_\/dev\/................/placeholder_\/dev\/$DEV_PATH/" "$MODPATH/bin/dex2oat64"
else
extract "$ZIPFILE" 'system.prop' "$MODPATH"
fi
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"

View File

@ -25,14 +25,6 @@ rm -f "/data/local/tmp/daemon.apk"
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