Proxy transaction from system server service to application service
This commit is contained in:
parent
a628528cd8
commit
d3b0140230
|
|
@ -188,17 +188,25 @@ namespace lspd {
|
||||||
Context::OnNativeForkSystemServerPost(JNIEnv *env) {
|
Context::OnNativeForkSystemServerPost(JNIEnv *env) {
|
||||||
if (!skip_) {
|
if (!skip_) {
|
||||||
auto *instance = Service::instance();
|
auto *instance = Service::instance();
|
||||||
auto binder = instance->RequestBinderForSystemServer(env);
|
auto system_server_binder = instance->RequestSystemServerBinder(env);
|
||||||
// TODO: binder could be not available
|
if (!system_server_binder) {
|
||||||
auto dex = instance->RequestLSPDex(env, binder);
|
LOGF("Failed to get system server binder, system server initialization failed. ");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto application_binder = instance->RequestApplicationBinderFromSystemServer(env, system_server_binder);
|
||||||
|
|
||||||
|
// Call application_binder directly if application binder is available,
|
||||||
|
// or we proxy the request from system server binder
|
||||||
|
auto dex = instance->RequestLSPDex(env, application_binder ? application_binder : system_server_binder);
|
||||||
LoadDex(env, std::get<0>(dex), std::get<1>(dex));
|
LoadDex(env, std::get<0>(dex), std::get<1>(dex));
|
||||||
instance->HookBridge(*this, env);
|
instance->HookBridge(*this, env);
|
||||||
|
|
||||||
if (binder) {
|
if (application_binder) {
|
||||||
obfuscated_signature_ = std::move(std::get<2>(dex));
|
obfuscated_signature_ = std::move(std::get<2>(dex));
|
||||||
InstallInlineHooks();
|
InstallInlineHooks();
|
||||||
Init(env);
|
Init(env);
|
||||||
FindAndCall(env, "forkSystemServerPost", "(Landroid/os/IBinder;)V", binder);
|
FindAndCall(env, "forkSystemServerPost", "(Landroid/os/IBinder;)V", application_binder);
|
||||||
} else skip_ = true;
|
} else skip_ = true;
|
||||||
}
|
}
|
||||||
if (skip_) [[unlikely]] {
|
if (skip_) [[unlikely]] {
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
* along with LSPosed. If not, see <https://www.gnu.org/licenses/>.
|
* along with LSPosed. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020 EdXposed Contributors
|
* Copyright (C) 2020 EdXposed Contributors
|
||||||
* Copyright (C) 2021 LSPosed Contributors
|
* Copyright (C) 2021 - 2022 LSPosed Contributors
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
|
||||||
|
|
@ -253,7 +253,7 @@ namespace lspd {
|
||||||
return service;
|
return service;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScopedLocalRef<jobject> Service::RequestBinderForSystemServer(JNIEnv *env) {
|
ScopedLocalRef<jobject> Service::RequestSystemServerBinder(JNIEnv *env) {
|
||||||
if (!initialized_) [[unlikely]] {
|
if (!initialized_) [[unlikely]] {
|
||||||
LOGE("Service not initialized");
|
LOGE("Service not initialized");
|
||||||
return {env, nullptr};
|
return {env, nullptr};
|
||||||
|
|
@ -277,17 +277,20 @@ namespace lspd {
|
||||||
LOGW("Fail to get binder for system server");
|
LOGW("Fail to get binder for system server");
|
||||||
return {env, nullptr};
|
return {env, nullptr};
|
||||||
}
|
}
|
||||||
|
return binder;
|
||||||
|
}
|
||||||
|
|
||||||
|
ScopedLocalRef<jobject> Service::RequestApplicationBinderFromSystemServer(JNIEnv *env, const ScopedLocalRef<jobject> &system_server_binder) {
|
||||||
auto heart_beat_binder = JNI_NewObject(env, binder_class_, binder_ctor_);
|
auto heart_beat_binder = JNI_NewObject(env, binder_class_, binder_ctor_);
|
||||||
auto data = JNI_CallStaticObjectMethod(env, parcel_class_, obtain_method_);
|
auto data = JNI_CallStaticObjectMethod(env, parcel_class_, obtain_method_);
|
||||||
auto reply = 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_, getuid());
|
||||||
JNI_CallVoidMethod(env, data, write_int_method_, getpid());
|
JNI_CallVoidMethod(env, data, write_int_method_, getpid());
|
||||||
JNI_CallVoidMethod(env, data, write_string_method_, JNI_NewStringUTF(env, "android"));
|
JNI_CallVoidMethod(env, data, write_string_method_, JNI_NewStringUTF(env, "android"));
|
||||||
JNI_CallVoidMethod(env, data, write_strong_binder_method_, heart_beat_binder);
|
JNI_CallVoidMethod(env, data, write_strong_binder_method_, heart_beat_binder);
|
||||||
|
|
||||||
auto res = JNI_CallBooleanMethod(env, binder, transact_method_,
|
auto res = JNI_CallBooleanMethod(env, system_server_binder, transact_method_,
|
||||||
BRIDGE_TRANSACTION_CODE,
|
BRIDGE_TRANSACTION_CODE,
|
||||||
data,
|
data,
|
||||||
reply, 0);
|
reply, 0);
|
||||||
|
|
@ -297,14 +300,14 @@ namespace lspd {
|
||||||
JNI_CallVoidMethod(env, reply, read_exception_method_);
|
JNI_CallVoidMethod(env, reply, read_exception_method_);
|
||||||
app_binder = JNI_CallObjectMethod(env, reply, read_strong_binder_method_);
|
app_binder = JNI_CallObjectMethod(env, reply, read_strong_binder_method_);
|
||||||
} else {
|
} else {
|
||||||
LOGE("Service::RequestBinderForSystemServer binder.transact failed?");
|
LOGE("Service::RequestSystemServerBinder binder.transact failed?");
|
||||||
}
|
}
|
||||||
JNI_CallVoidMethod(env, data, recycleMethod_);
|
JNI_CallVoidMethod(env, data, recycleMethod_);
|
||||||
JNI_CallVoidMethod(env, reply, recycleMethod_);
|
JNI_CallVoidMethod(env, reply, recycleMethod_);
|
||||||
if (app_binder) {
|
if (app_binder) {
|
||||||
JNI_NewGlobalRef(env, heart_beat_binder);
|
JNI_NewGlobalRef(env, heart_beat_binder);
|
||||||
}
|
}
|
||||||
LOGD("Service::RequestBinderForSystemServer app_binder: %p", app_binder.get());
|
LOGD("Service::RequestSystemServerBinder app_binder: %p", app_binder.get());
|
||||||
return app_binder;
|
return app_binder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with LSPosed. If not, see <https://www.gnu.org/licenses/>.
|
* along with LSPosed. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2021 LSPosed Contributors
|
* Copyright (C) 2021 - 2022 LSPosed Contributors
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
@ -53,7 +53,9 @@ namespace lspd {
|
||||||
void HookBridge(const Context& context, JNIEnv *env);
|
void HookBridge(const Context& context, JNIEnv *env);
|
||||||
ScopedLocalRef<jobject> RequestBinder(JNIEnv *env, jstring nice_name);
|
ScopedLocalRef<jobject> RequestBinder(JNIEnv *env, jstring nice_name);
|
||||||
|
|
||||||
ScopedLocalRef<jobject> RequestBinderForSystemServer(JNIEnv *env);
|
ScopedLocalRef<jobject> RequestSystemServerBinder(JNIEnv *env);
|
||||||
|
|
||||||
|
ScopedLocalRef<jobject> RequestApplicationBinderFromSystemServer(JNIEnv *env, const ScopedLocalRef<jobject> &system_server_binder);
|
||||||
|
|
||||||
std::tuple<int, size_t, std::string> RequestLSPDex(JNIEnv *env, const ScopedLocalRef<jobject> &binder);
|
std::tuple<int, size_t, std::string> RequestLSPDex(JNIEnv *env, const ScopedLocalRef<jobject> &binder);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with LSPosed. If not, see <https://www.gnu.org/licenses/>.
|
* along with LSPosed. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2021 LSPosed Contributors
|
* Copyright (C) 2021 - 2022 LSPosed Contributors
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.lsposed.lspd.service;
|
package org.lsposed.lspd.service;
|
||||||
|
|
@ -40,7 +40,7 @@ import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
public class LSPApplicationService extends ILSPApplicationService.Stub {
|
public class LSPApplicationService extends ILSPApplicationService.Stub {
|
||||||
private final static int DEX_TRANSACTION_CODE = 1310096052;
|
final static int DEX_TRANSACTION_CODE = 1310096052;
|
||||||
// <uid, pid>
|
// <uid, pid>
|
||||||
private final static Set<Pair<Integer, Integer>> cache = ConcurrentHashMap.newKeySet();
|
private final static Set<Pair<Integer, Integer>> cache = ConcurrentHashMap.newKeySet();
|
||||||
private final static Map<Integer, IBinder> handles = new ConcurrentHashMap<>();
|
private final static Map<Integer, IBinder> handles = new ConcurrentHashMap<>();
|
||||||
|
|
@ -48,7 +48,7 @@ public class LSPApplicationService extends ILSPApplicationService.Stub {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws android.os.RemoteException {
|
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws android.os.RemoteException {
|
||||||
Log.i(TAG, "LSPApplicationService.onTransact: code=" + code);
|
Log.d(TAG, "LSPApplicationService.onTransact: code=" + code);
|
||||||
if (code == DEX_TRANSACTION_CODE) {
|
if (code == DEX_TRANSACTION_CODE) {
|
||||||
try {
|
try {
|
||||||
ParcelFileDescriptor pfd = ParcelFileDescriptor.fromFd(ObfuscationManager.preloadDex());
|
ParcelFileDescriptor pfd = ParcelFileDescriptor.fromFd(ObfuscationManager.preloadDex());
|
||||||
|
|
@ -60,9 +60,8 @@ public class LSPApplicationService extends ILSPApplicationService.Stub {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} else {
|
|
||||||
return super.onTransact(code, data, reply, flags);
|
|
||||||
}
|
}
|
||||||
|
return super.onTransact(code, data, reply, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean registerHeartBeat(int uid, int pid, IBinder handle) {
|
public boolean registerHeartBeat(int uid, int pid, IBinder handle) {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* <!--This file is part of LSPosed.
|
* This file is part of LSPosed.
|
||||||
*
|
*
|
||||||
* LSPosed is free software: you can redistribute it and/or modify
|
* LSPosed is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with LSPosed. If not, see <https://www.gnu.org/licenses/>.
|
* along with LSPosed. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2021 LSPosed Contributors-->
|
* Copyright (C) 2021 - 2022 LSPosed Contributors
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.lsposed.lspd.service;
|
package org.lsposed.lspd.service;
|
||||||
|
|
@ -88,29 +88,32 @@ public class LSPSystemServerService extends ILSPSystemServerService.Stub impleme
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
|
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
|
||||||
Log.i(TAG, "LSPSystemServerService.onTransact: code=" + code);
|
Log.d(TAG, "LSPSystemServerService.onTransact: code=" + code);
|
||||||
if (originService != null) {
|
if (originService != null) {
|
||||||
return originService.transact(code, data, reply, flags);
|
return originService.transact(code, data, reply, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (code == BridgeService.TRANSACTION_CODE) {
|
switch (code) {
|
||||||
// request application service with JNI
|
case BridgeService.TRANSACTION_CODE:
|
||||||
int uid = data.readInt();
|
int uid = data.readInt();
|
||||||
int pid = data.readInt();
|
int pid = data.readInt();
|
||||||
String processName = data.readString();
|
String processName = data.readString();
|
||||||
IBinder heartBeat = data.readStrongBinder();
|
IBinder heartBeat = data.readStrongBinder();
|
||||||
var service = requestApplicationService(uid, pid, processName, heartBeat);
|
var service = requestApplicationService(uid, pid, processName, heartBeat);
|
||||||
if (service != null) {
|
if (service != null) {
|
||||||
Log.d(TAG, "LSPSystemServerService.onTransact requestApplicationService granted: " + service);
|
Log.d(TAG, "LSPSystemServerService.onTransact requestApplicationService granted: " + service);
|
||||||
reply.writeNoException();
|
reply.writeNoException();
|
||||||
reply.writeStrongBinder(service.asBinder());
|
reply.writeStrongBinder(service.asBinder());
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
Log.d(TAG, "LSPSystemServerService.onTransact requestApplicationService rejected");
|
Log.d(TAG, "LSPSystemServerService.onTransact requestApplicationService rejected");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
case LSPApplicationService.DEX_TRANSACTION_CODE:
|
||||||
return super.onTransact(code, data, reply, flags);
|
// Proxy LSP dex transaction to Application Binder
|
||||||
|
return ServiceManager.getApplicationService().onTransact(code, data, reply, flags);
|
||||||
|
default:
|
||||||
|
return super.onTransact(code, data, reply, flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue