[core] send LSP main dex through binder

This commit is contained in:
kotori0 2022-02-01 22:05:18 +08:00 committed by LoveSy
parent 30d1c1b551
commit 4d5a4dcb27
17 changed files with 229 additions and 107 deletions

View File

@ -12,7 +12,6 @@
}
-keepclasseswithmembers class org.lsposed.lspd.service.BridgeService {
public static boolean *(android.os.IBinder, int, long, long, int);
public static android.os.IBinder getApplicationServiceForSystemServer(android.os.IBinder, android.os.IBinder);
}
-assumenosideeffects class android.util.Log {

View File

@ -43,11 +43,6 @@ namespace lspd {
LOGI("onModuleLoaded: version v%s (%d)", versionName, versionCode);
InitSymbolCache(nullptr);
Context::GetInstance()->Init();
if constexpr (isDebug) {
Context::GetInstance()->PreLoadDex("/system/" + kDexPath);
} else {
Context::GetInstance()->PreLoadDex(magiskPath + '/' + kDexPath);
}
}
void nativeForkAndSpecializePre(JNIEnv *env, jclass, jint *_uid, jint *,

View File

@ -290,7 +290,8 @@ namespace lspd {
if (int fd = -1, size = 0; (size = read_int(companion)) > 0 &&
(fd = recv_fd(companion)) != -1) {
Context::GetInstance()->PreLoadDex(fd, size);
// Context::GetInstance()->PreLoadDex(fd, size);
// TODO: remove me
close(fd);
} else {
LOGE("Failed to read dex fd");
@ -341,8 +342,8 @@ namespace lspd {
};
std::tuple<SharedMem, SharedMem> InitCompanion() {
LOGI("onModuleLoaded: welcome to LSPosed!");
LOGI("onModuleLoaded: version v%s (%d)", versionName, versionCode);
LOGI("ZygiskCompanion: welcome to LSPosed!");
LOGI("ZygiskCompanion: version v%s (%d)", versionName, versionCode);
std::string path = "/data/adb/modules/"s + lspd::moduleName + "/" + kDexPath;
int dex_fd = open(path.data(), O_RDONLY | O_CLOEXEC);

View File

@ -241,6 +241,18 @@ inline auto JNI_CallObjectMethod(JNIEnv *env, const Object &obj, Args &&... args
return JNI_SafeInvoke(env, &JNIEnv::CallObjectMethod, obj, std::forward<Args>(args)...);
}
template<ScopeOrObject Object, typename ...Args>
[[maybe_unused]]
inline auto JNI_CallIntMethod(JNIEnv *env, const Object &obj, Args &&... args) {
return JNI_SafeInvoke(env, &JNIEnv::CallIntMethod, obj, std::forward<Args>(args)...);
}
template<ScopeOrObject Object, typename ...Args>
[[maybe_unused]]
inline auto JNI_CallLongMethod(JNIEnv *env, const Object &obj, Args &&... args) {
return JNI_SafeInvoke(env, &JNIEnv::CallLongMethod, obj, std::forward<Args>(args)...);
}
template<ScopeOrObject Object, typename ...Args>
[[maybe_unused]]
inline auto JNI_CallVoidMethod(JNIEnv *env, const Object &obj, Args &&...args) {

View File

@ -68,60 +68,26 @@ namespace lspd {
}
Context::PreloadedDex::PreloadedDex(int fd, std::size_t size) {
auto *old = mmap(nullptr, size, PROT_READ, MAP_SHARED, fd, 0);
auto *addr = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
LOGD("Context::PreloadedDex::PreloadedDex: fd=%d, size=%zu", fd, size);
auto *addr = mmap(nullptr, size, PROT_READ, MAP_SHARED, fd, 0);
if (old != MAP_FAILED && addr != MAP_FAILED) {
memmove(addr, old, size);
if (addr != MAP_FAILED) {
addr_ = addr;
size_ = size;
} else {
if (old == MAP_FAILED) LOGE("Old failed");
if (addr == MAP_FAILED) LOGE("addr failed");
LOGE("Read dex failed: %s", strerror(errno));
}
munmap(old, size);
}
Context::PreloadedDex::~PreloadedDex() {
if (*this) munmap(addr_, size_);
}
void Context::ObfuscateDex() {
if (!dex_) [[unlikely]] return;
void Context::LoadDex(JNIEnv *env, int fd, size_t size) {
LOGD("Context::LoadDex: %d", fd);
// map fd to memory. fd should be created with ASharedMemory_create.
dex_ = PreloadedDex(fd, size); // for RAII...
auto dex = Obfuscation::obfuscateDex(dex_.data(), dex_.size());
// TODO: multiple memory copy prevention
auto *mem = mmap(nullptr, dex.size(), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
memmove(mem, dex.data(), dex.size());
PreloadedDex new_dex(mem, dex.size());
std::swap(dex_, new_dex);
LOGD("Context::ObfuscateDex: %p, size=%zu", reinterpret_cast<dex::u1*>(dex_.data()), dex.size());
}
void Context::PreLoadDex(int fd, std::size_t size) {
dex_ = PreloadedDex{fd, size};
ObfuscateDex();
}
void Context::PreLoadDex(std::string_view dex_path) {
if (dex_) [[unlikely]] return;
std::unique_ptr<FILE, decltype(&fclose)> f{fopen(dex_path.data(), "rb"), &fclose};
if (!f) {
LOGE("Fail to open dex from %s", dex_path.data());
return;
} else {
fseek(f.get(), 0, SEEK_END);
auto size = ftell(f.get());
rewind(f.get());
PreLoadDex(fileno(f.get()), size);
}
LOGD("Loaded %s with size %zu", dex_path.data(), dex_.size());
}
void Context::LoadDex(JNIEnv *env) {
auto classloader = JNI_FindClass(env, "java/lang/ClassLoader");
auto getsyscl_mid = JNI_GetStaticMethodID(
env, classloader, "getSystemClassLoader", "()Ljava/lang/ClassLoader;");
@ -134,8 +100,7 @@ namespace lspd {
auto initMid = JNI_GetMethodID(env, in_memory_classloader, "<init>",
"(Ljava/nio/ByteBuffer;Ljava/lang/ClassLoader;)V");
auto byte_buffer_class = JNI_FindClass(env, "java/nio/ByteBuffer");
auto dex = std::move(dex_);
auto dex_buffer = env->NewDirectByteBuffer(dex.data(), dex.size());
auto dex_buffer = env->NewDirectByteBuffer(dex_.data(), dex_.size());
if (auto my_cl = JNI_NewObject(env, in_memory_classloader, initMid,
dex_buffer, sys_classloader)) {
inject_class_loader_ = JNI_NewGlobalRef(env, my_cl);
@ -226,9 +191,13 @@ namespace lspd {
void
Context::OnNativeForkSystemServerPost(JNIEnv *env) {
if (!skip_) {
LoadDex(env);
Service::instance()->HookBridge(*this, env);
auto binder = Service::instance()->RequestBinderForSystemServer(env);
auto *instance = Service::instance();
auto binder = instance->RequestBinderForSystemServer(env);
// TODO: binder could be not available
auto dex = instance->RequestLSPDex(env, binder);
LoadDex(env, std::get<0>(dex), std::get<1>(dex));
instance->HookBridge(*this, env);
if (binder) {
InstallInlineHooks();
Init(env);
@ -284,11 +253,13 @@ namespace lspd {
Context::OnNativeForkAndSpecializePost(JNIEnv *env, jstring nice_name,
jstring app_data_dir) {
const JUTFString process_name(env, nice_name);
auto *instance = Service::instance();
auto binder = skip_ ? ScopedLocalRef<jobject>{env, nullptr}
: Service::instance()->RequestBinder(env, nice_name);
: instance->RequestBinder(env, nice_name);
if (binder) {
InstallInlineHooks();
LoadDex(env);
auto dex = instance->RequestLSPDex(env, binder);
LoadDex(env, std::get<0>(dex), std::get<1>(dex));
Init(env);
LOGD("Done prepare");
FindAndCall(env, "forkAndSpecializePost",

View File

@ -59,10 +59,6 @@ namespace lspd {
void OnNativeForkSystemServerPre(JNIEnv *env);
void PreLoadDex(std::string_view dex_paths);
void PreLoadDex(int fd, std::size_t size);
void Init();
private:
@ -115,11 +111,9 @@ namespace lspd {
PreloadedDex dex_{};
void ObfuscateDex();
Context() {}
void LoadDex(JNIEnv *env);
void LoadDex(JNIEnv *env, int fd, size_t size);
void Init(JNIEnv *env);

View File

@ -117,11 +117,22 @@ namespace lspd {
write_strong_binder_method_ = JNI_GetMethodID(env, parcel_class_, "writeStrongBinder",
"(Landroid/os/IBinder;)V");
read_exception_method_ = JNI_GetMethodID(env, parcel_class_, "readException", "()V");
read_long_method_ = JNI_GetMethodID(env, parcel_class_, "readLong", "()J");
read_strong_binder_method_ = JNI_GetMethodID(env, parcel_class_, "readStrongBinder",
"()Landroid/os/IBinder;");
read_file_descriptor_method_ = JNI_GetMethodID(env, parcel_class_, "readFileDescriptor",
"()Landroid/os/ParcelFileDescriptor;");
// createStringArray_ = env->GetMethodID(parcel_class_, "createStringArray",
// "()[Ljava/lang/String;");
if (auto parcel_file_descriptor_class = JNI_FindClass(env, "android/os/ParcelFileDescriptor")) {
parcel_file_descriptor_class_ = JNI_NewGlobalRef(env, parcel_file_descriptor_class);
} else {
LOGE("ParcelFileDescriptor not found");
return;
}
get_fd_method = JNI_GetMethodID(env, parcel_file_descriptor_class_, "getFd", "()I");
if (auto dead_object_exception_class = JNI_FindClass(env,
"android/os/DeadObjectException")) {
deadObjectExceptionClass_ = JNI_NewGlobalRef(env, dead_object_exception_class);
@ -202,6 +213,7 @@ namespace lspd {
return {env, nullptr};
}
// TODO: memory leak?
auto *bridge_service_name = env->NewStringUTF(BRIDGE_SERVICE_NAME.data());
auto bridge_service = JNI_CallStaticObjectMethod(env, service_manager_class_,
get_service_method_, bridge_service_name);
@ -241,10 +253,12 @@ namespace lspd {
}
ScopedLocalRef<jobject> Service::RequestBinderForSystemServer(JNIEnv *env) {
if (!initialized_ || !bridge_service_class_) [[unlikely]] {
if (!initialized_) [[unlikely]] {
LOGE("Service not initialized");
return {env, nullptr};
}
// Get Binder for LSPSystemServerService.
// The binder itself was inject into system service "serial"
auto *bridge_service_name = env->NewStringUTF(SYSTEM_SERVER_BRIDGE_SERVICE_NAME.data());
ScopedLocalRef<jobject> binder{env, nullptr};
for (int i = 0; i < 3; ++i) {
@ -262,15 +276,55 @@ namespace lspd {
LOGW("Fail to get binder for system server");
return {env, nullptr};
}
auto *method = JNI_GetStaticMethodID(env, bridge_service_class_,
"getApplicationServiceForSystemServer",
"(Landroid/os/IBinder;Landroid/os/IBinder;)Landroid/os/IBinder;");
auto heart_beat_binder = JNI_NewObject(env, binder_class_, binder_ctor_);
auto app_binder = JNI_CallStaticObjectMethod(env, bridge_service_class_, method, binder,
heart_beat_binder);
auto data = JNI_CallStaticObjectMethod(env, parcel_class_, obtain_method_);
auto reply = JNI_CallStaticObjectMethod(env, parcel_class_, obtain_method_);
JNI_CallVoidMethod(env, data, write_int_method_, getuid()); // data.writeInt(uid)
JNI_CallVoidMethod(env, data, write_int_method_, getpid());
JNI_CallVoidMethod(env, data, write_string_method_, env->NewStringUTF("android"));
JNI_CallVoidMethod(env, data, write_strong_binder_method_, heart_beat_binder);
auto res = JNI_CallBooleanMethod(env, binder, transact_method_,
BRIDGE_TRANSACTION_CODE,
data,
reply, 0);
ScopedLocalRef<jobject> app_binder = {env, nullptr};
if (res) {
JNI_CallVoidMethod(env, reply, read_exception_method_);
app_binder = JNI_CallObjectMethod(env, reply, read_strong_binder_method_);
} else {
LOGE("Service::RequestBinderForSystemServer binder.transact failed?");
}
JNI_CallVoidMethod(env, data, recycleMethod_);
JNI_CallVoidMethod(env, reply, recycleMethod_);
if (app_binder) {
JNI_NewGlobalRef(env, heart_beat_binder);
}
LOGD("Service::RequestBinderForSystemServer app_binder: %p", app_binder.get());
return app_binder;
}
std::tuple<int, size_t> Service::RequestLSPDex(JNIEnv *env, const ScopedLocalRef<jobject> &binder) {
auto data = JNI_CallStaticObjectMethod(env, parcel_class_, obtain_method_);
auto reply = JNI_CallStaticObjectMethod(env, parcel_class_, obtain_method_);
auto res = JNI_CallBooleanMethod(env, binder, transact_method_,
DEX_TRANSACTION_CODE,
data,
reply, 0);
if (!res) {
LOGE("Service::RequestLSPDex: transaction failed?");
return {-1, 0};
}
auto parcel_fd = JNI_CallObjectMethod(env, reply, read_file_descriptor_method_);
int fd = JNI_CallIntMethod(env, parcel_fd, get_fd_method);
auto size = JNI_CallLongMethod(env, reply, read_long_method_);
JNI_CallVoidMethod(env, data, recycleMethod_);
JNI_CallVoidMethod(env, reply, recycleMethod_);
LOGD("Service::RequestLSPDex fd=%d, size=%zu", fd, size);
return {fd, size};
}
} // namespace lspd

View File

@ -31,6 +31,7 @@ using namespace std::literals::string_view_literals;
namespace lspd {
class Service {
constexpr static jint DEX_TRANSACTION_CODE = 1310096052;
constexpr static jint BRIDGE_TRANSACTION_CODE = 1598837584;
constexpr static auto BRIDGE_SERVICE_DESCRIPTOR = "LSPosed"sv;
constexpr static auto BRIDGE_SERVICE_NAME = "activity"sv;
@ -54,6 +55,8 @@ namespace lspd {
ScopedLocalRef<jobject> RequestBinderForSystemServer(JNIEnv *env);
std::tuple<int, size_t> RequestLSPDex(JNIEnv *env, const ScopedLocalRef<jobject> &binder);
private:
inline static std::unique_ptr<Service> instance_ = std::make_unique<Service>();
bool initialized_ = false;
@ -93,6 +96,11 @@ namespace lspd {
jmethodID read_exception_method_ = nullptr;
jmethodID read_strong_binder_method_ = nullptr;
jmethodID write_strong_binder_method_ = nullptr;
jmethodID read_file_descriptor_method_ = nullptr;
jmethodID read_long_method_ = nullptr;
jclass parcel_file_descriptor_class_ = nullptr;
jmethodID get_fd_method = nullptr;
jclass deadObjectExceptionClass_ = nullptr;

View File

@ -214,17 +214,4 @@ public class BridgeService {
reply.recycle();
}
}
@SuppressWarnings("unused")
public static IBinder getApplicationServiceForSystemServer(IBinder binder, IBinder heartBeat) {
if (binder == null || heartBeat == null) return null;
try {
var service = ILSPSystemServerService.Stub.asInterface(binder);
var applicationService = service.requestApplicationService(Process.myUid(), Process.myPid(), "android", heartBeat);
if (applicationService != null) return applicationService.asBinder();
} catch (Throwable e) {
Log.e(TAG, Log.getStackTraceString(e));
}
return null;
}
}

View File

@ -2,8 +2,8 @@ LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := daemon
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../../../core/src/main/cpp/shared/
LOCAL_SRC_FILES := logcat.cpp obfuscation.cpp ../../../../core/src/main/cpp/shared/Obfuscation.cpp
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../../../core/src/main/cpp/shared/ $(LOCAL_PATH)../../../../core/src/main/cpp/main/include/
LOCAL_SRC_FILES := logcat.cpp obfuscation.cpp ../../../../core/src/main/cpp/shared/Obfuscation.cpp ../../../../core/src/main/cpp/main/api/config.cpp
LOCAL_STATIC_LIBRARIES := cxx dex_builder
LOCAL_ALLOW_UNDEFINED_SYMBOLS := true
LOCAL_LDLIBS := -llog -landroid

View File

@ -12,11 +12,73 @@
#include "slicer/reader.h"
#include "slicer/writer.h"
#include "Obfuscation.h"
#include <jni.h>
// TODO: BAD
#include "../../../../core/src/main/cpp/main/include/config.h"
static jobject lspdDex = nullptr;
jobject new_sharedmem(JNIEnv* env, jint size) {
jclass clazz = env->FindClass("android/os/SharedMemory");
auto *ref = env->NewGlobalRef(clazz);
jmethodID mid = env->GetStaticMethodID(clazz, "create", "(Ljava/lang/String;I)Landroid/os/SharedMemory;");
jstring empty_str = env->NewStringUTF("");
jobject new_mem = env->CallStaticObjectMethod(clazz, mid, empty_str, static_cast<jint>(size));
env->DeleteGlobalRef(ref);
env->DeleteLocalRef(empty_str);
return new_mem;
}
extern "C"
JNIEXPORT jint JNICALL
Java_org_lsposed_lspd_service_LSPApplicationService_preloadDex(JNIEnv *env, jclass ) {
using namespace std::string_literals;
// TODO: Lock?
if (lspdDex) return ASharedMemory_dupFromJava(env, lspdDex);
std::string dex_path = "/data/adb/modules/"s + lspd::moduleName + "/" + lspd::kDexPath;
std::unique_ptr<FILE, decltype(&fclose)> f{fopen(dex_path.data(), "rb"), &fclose};
if (!f) {
LOGE("Fail to open dex from %s", dex_path.data());
return -1;
}
fseek(f.get(), 0, SEEK_END);
auto size = ftell(f.get());
rewind(f.get());
LOGD("Loaded %s with size %zu", dex_path.data(), size);
auto *addr = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fileno(f.get()), 0);
if (addr == MAP_FAILED) {
LOGE("Read dex failed: %s", strerror(errno));
return -1;
}
auto new_dex = Obfuscation::obfuscateDex(addr, size);
LOGD("LSPApplicationService::preloadDex: %p, size=%zu", new_dex.data(), new_dex.size());
auto new_mem = new_sharedmem(env, new_dex.size());
lspdDex = env->NewGlobalRef(new_mem);
auto new_fd = ASharedMemory_dupFromJava(env, lspdDex);
auto new_addr = mmap(nullptr, new_dex.size(), PROT_READ | PROT_WRITE, MAP_SHARED, new_fd, 0);
memmove(new_addr, new_dex.data(), new_dex.size());
return new_fd;
}
extern "C"
JNIEXPORT jlong JNICALL
Java_org_lsposed_lspd_service_LSPApplicationService_getPreloadedDexSize(JNIEnv *env, jclass ) {
if (lspdDex) {
auto fd = ASharedMemory_dupFromJava(env, lspdDex);
return ASharedMemory_getSize(fd);
}
return 0;
}
extern "C"
JNIEXPORT jobject
Java_org_lsposed_lspd_service_ObfuscationService_obfuscateDex(JNIEnv *env, jclass /*clazz*/,
Java_org_lsposed_lspd_service_LSPApplicationService_obfuscateDex(JNIEnv *env, jclass /*clazz*/,
jobject memory) {
int fd = ASharedMemory_dupFromJava(env, memory);
auto size = ASharedMemory_getSize(fd);
@ -29,16 +91,9 @@ Java_org_lsposed_lspd_service_ObfuscationService_obfuscateDex(JNIEnv *env, jclas
auto new_dex = Obfuscation::obfuscateDex(mem, size);
// create new SharedMem since it cannot be resized
jclass clazz = env->FindClass("android/os/SharedMemory");
auto *ref = env->NewGlobalRef(clazz);
jmethodID mid = env->GetStaticMethodID(clazz, "create", "(Ljava/lang/String;I)Landroid/os/SharedMemory;");
jstring empty_str = env->NewStringUTF("");
jobject new_mem = env->CallStaticObjectMethod(clazz, mid, empty_str, static_cast<jint>(new_dex.size()));
auto new_mem = new_sharedmem(env, new_dex.size());
int new_fd = ASharedMemory_dupFromJava(env, new_mem);
env->DeleteGlobalRef(ref);
env->DeleteLocalRef(empty_str);
mem = mmap(nullptr, new_dex.size(), PROT_READ | PROT_WRITE, MAP_SHARED, new_fd, 0);
if (mem == MAP_FAILED) {
// LOGE("Failed to map new dex to memory?");

View File

@ -16,7 +16,7 @@ import java.util.Map;
public class BridgeService {
private static final int TRANSACTION_CODE = ('_' << 24) | ('L' << 16) | ('S' << 8) | 'P';
static final int TRANSACTION_CODE = ('_' << 24) | ('L' << 16) | ('S' << 8) | 'P'; // 1598837584
private static final String DESCRIPTOR = "LSPosed";
private static final String SERVICE_NAME = "activity";

View File

@ -296,7 +296,7 @@ public class ConfigFileManager {
var byteBuffer = memory.mapReadWrite();
Channels.newChannel(in).read(byteBuffer);
SharedMemory.unmap(byteBuffer);
memory = ObfuscationService.obfuscateDex(memory);
memory = LSPApplicationService.obfuscateDex(memory);
memory.setProtect(OsConstants.PROT_READ);
preLoadedDexes.add(memory);
} catch (IOException | ErrnoException e) {

View File

@ -23,13 +23,16 @@ import static org.lsposed.lspd.service.ServiceManager.TAG;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.os.SharedMemory;
import android.util.Log;
import android.util.Pair;
import org.lsposed.lspd.models.Module;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@ -37,11 +40,30 @@ import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
public class LSPApplicationService extends ILSPApplicationService.Stub {
private final static int DEX_TRANSACTION_CODE = 1310096052;
// <uid, pid>
private final static Set<Pair<Integer, Integer>> cache = ConcurrentHashMap.newKeySet();
private final static Map<Integer, IBinder> handles = new ConcurrentHashMap<>();
private final static Set<IBinder.DeathRecipient> recipients = ConcurrentHashMap.newKeySet();
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws android.os.RemoteException {
Log.i(TAG, "LSPApplicationService.onTransact: code=" + code);
if (code == DEX_TRANSACTION_CODE) {
try {
ParcelFileDescriptor pfd = ParcelFileDescriptor.fromFd(preloadDex());
reply.writeFileDescriptor(pfd.getFileDescriptor());
reply.writeLong(getPreloadedDexSize());
} catch (IOException ignored) {
Log.e(TAG, "LSPApplicationService.onTransact: ParcelFileDescriptor.fromFd failed");
return false;
}
return true;
} else {
return super.onTransact(code, data, reply, flags);
}
}
public boolean registerHeartBeat(int uid, int pid, IBinder handle) {
try {
var recipient = new DeathRecipient() {
@ -65,6 +87,14 @@ public class LSPApplicationService extends ILSPApplicationService.Stub {
}
}
static native SharedMemory obfuscateDex(SharedMemory memory);
// preload lspd dex only, on daemon startup.
// it will cache the result, so we could obtain it back on startup.
static native int preloadDex();
static native long getPreloadedDexSize();
@Override
public List<Module> getModulesList(String processName) throws RemoteException {
ensureRegistered();

View File

@ -47,11 +47,15 @@ public class LSPSystemServerService extends ILSPSystemServerService.Stub impleme
}
public LSPSystemServerService(int maxRetry) {
Log.d(TAG, "LSPSystemServerService::LSPSystemServerService");
requested = -maxRetry;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
// Registers a callback when system is registering an authentic "serial" service
// And we are proxying all requests to that system service
var serviceCallback = new IServiceCallback.Stub() {
@Override
public void onRegistration(String name, IBinder binder) {
Log.d(TAG, "LSPSystemServerService::LSPSystemServerService onRegistration: " + name + " " + binder);
if (name.equals(PROXY_SERVICE_NAME) && binder != null && binder != LSPSystemServerService.this) {
Log.d(TAG, "Register " + name + " " + binder);
originService = binder;
@ -74,6 +78,7 @@ public class LSPSystemServerService extends ILSPSystemServerService.Stub impleme
@Override
public ILSPApplicationService requestApplicationService(int uid, int pid, String processName, IBinder heartBeat) {
Log.d(TAG, "ILSPApplicationService.requestApplicationService: " + uid + " " + pid + " " + processName + " " + heartBeat);
requested = 1;
if (ConfigManager.getInstance().shouldSkipSystemServer() || uid != 1000 || heartBeat == null || !"android".equals(processName))
return null;
@ -83,11 +88,30 @@ public class LSPSystemServerService extends ILSPSystemServerService.Stub impleme
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
Log.i(TAG, "LSPSystemServerService.onTransact: code=" + code);
if (originService != null) {
return originService.transact(code, data, reply, flags);
}
return super.onTransact(code, data, reply, flags);
if (code == BridgeService.TRANSACTION_CODE) {
// request application service with JNI
int uid = data.readInt();
int pid = data.readInt();
String processName = data.readString();
IBinder heartBeat = data.readStrongBinder();
var service = requestApplicationService(uid, pid, processName, heartBeat);
if (service != null) {
Log.d(TAG, "LSPSystemServerService.onTransact requestApplicationService granted: " + service);
reply.writeNoException();
reply.writeStrongBinder(service.asBinder());
return true;
} else {
Log.d(TAG, "LSPSystemServerService.onTransact requestApplicationService rejected");
return false;
}
} else {
return super.onTransact(code, data, reply, flags);
}
}
public void linkToDeath() {

View File

@ -1,9 +0,0 @@
package org.lsposed.lspd.service;
import android.os.SharedMemory;
import java.nio.ByteBuffer;
public class ObfuscationService {
static native SharedMemory obfuscateDex(SharedMemory memory);
}

View File

@ -98,6 +98,7 @@ public class ServiceManager {
logcatService.start();
Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND);
LSPApplicationService.preloadDex();
Looper.prepareMainLooper();
mainService = new LSPosedService();
applicationService = new LSPApplicationService();