ignore binder transactions flooding
This commit is contained in:
parent
779faeb5ee
commit
c5d7b32cc0
|
|
@ -59,8 +59,10 @@ namespace lspd {
|
||||||
# define LP_SELECT(lp32, lp64) lp32
|
# define LP_SELECT(lp32, lp64) lp32
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inline static constexpr auto kLibArtName = "libart.so"_tstr;
|
inline static constexpr auto kLibArtName = "libart.so";
|
||||||
inline static constexpr auto kLibFwName = "libandroidfw.so"_tstr;
|
inline static constexpr auto kLibBinderName = "libbinder.so";
|
||||||
|
inline static constexpr auto kLibFwName = "libandroidfw.so";
|
||||||
|
inline static constexpr auto kLinkerName = "/linker";
|
||||||
|
|
||||||
inline constexpr const char *BoolToString(bool b) {
|
inline constexpr const char *BoolToString(bool b) {
|
||||||
return b ? "true" : "false";
|
return b ? "true" : "false";
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,8 @@ namespace SandHook {
|
||||||
|
|
||||||
namespace lspd {
|
namespace lspd {
|
||||||
std::unique_ptr<const SandHook::ElfImg> &GetArt(bool release=false);
|
std::unique_ptr<const SandHook::ElfImg> &GetArt(bool release=false);
|
||||||
|
std::unique_ptr<const SandHook::ElfImg> &GetLibBinder(bool release=false);
|
||||||
|
std::unique_ptr<const SandHook::ElfImg> &GetLinker(bool release=false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //LSPOSED_SYMBOL_CACHE_H
|
#endif //LSPOSED_SYMBOL_CACHE_H
|
||||||
|
|
|
||||||
|
|
@ -40,4 +40,24 @@ namespace lspd {
|
||||||
}
|
}
|
||||||
return kArtImg;
|
return kArtImg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<const SandHook::ElfImg> &GetLibBinder(bool release) {
|
||||||
|
static std::unique_ptr<const SandHook::ElfImg> kImg = nullptr;
|
||||||
|
if (release) {
|
||||||
|
kImg.reset();
|
||||||
|
} else if (!kImg) {
|
||||||
|
kImg = std::make_unique<SandHook::ElfImg>(kLibBinderName);
|
||||||
|
}
|
||||||
|
return kImg;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<const SandHook::ElfImg> &GetLinker(bool release) {
|
||||||
|
static std::unique_ptr<const SandHook::ElfImg> kImg = nullptr;
|
||||||
|
if (release) {
|
||||||
|
kImg.reset();
|
||||||
|
} else if (!kImg) {
|
||||||
|
kImg = std::make_unique<SandHook::ElfImg>(kLinkerName);
|
||||||
|
}
|
||||||
|
return kImg;
|
||||||
|
}
|
||||||
} // namespace lspd
|
} // namespace lspd
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
#include <dobby.h>
|
#include <dobby.h>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
#include <atomic>
|
||||||
#include "loader.h"
|
#include "loader.h"
|
||||||
#include "service.h"
|
#include "service.h"
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
|
|
@ -36,6 +37,50 @@ using namespace lsplant;
|
||||||
namespace lspd {
|
namespace lspd {
|
||||||
std::unique_ptr<Service> Service::instance_ = std::make_unique<Service>();
|
std::unique_ptr<Service> Service::instance_ = std::make_unique<Service>();
|
||||||
|
|
||||||
|
std::atomic<uint64_t> last_failed_id = ~0;
|
||||||
|
|
||||||
|
class IPCThreadState {
|
||||||
|
static IPCThreadState* (*selfOrNullFn)();
|
||||||
|
static pid_t (*getCallingPidFn)(IPCThreadState*);
|
||||||
|
static uid_t (*getCallingUidFn)(IPCThreadState*);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
uint64_t getCallingId() {
|
||||||
|
if (getCallingUidFn != nullptr && getCallingPidFn != nullptr) [[likely]] {
|
||||||
|
auto pid = getCallingUidFn(this);
|
||||||
|
auto uid = getCallingPidFn(this);
|
||||||
|
return (static_cast<uint64_t>(uid) << 32) | pid;
|
||||||
|
}
|
||||||
|
return ~0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static IPCThreadState* selfOrNull() {
|
||||||
|
if (selfOrNullFn != nullptr) [[likely]] {
|
||||||
|
return selfOrNullFn();
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Init(const SandHook::ElfImg *binder) {
|
||||||
|
if (binder == nullptr) {
|
||||||
|
LOGE("libbinder not found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
selfOrNullFn = reinterpret_cast<decltype(selfOrNullFn)>(
|
||||||
|
binder->getSymbAddress("_ZN7android14IPCThreadState10selfOrNullEv"));
|
||||||
|
getCallingPidFn = reinterpret_cast<decltype(getCallingPidFn)>(
|
||||||
|
binder->getSymbAddress("_ZNK7android14IPCThreadState13getCallingPidEv"));
|
||||||
|
getCallingUidFn = reinterpret_cast<decltype(getCallingUidFn)>(
|
||||||
|
binder->getSymbAddress("_ZNK7android14IPCThreadState13getCallingUidEv"));
|
||||||
|
LOGI("libbinder selfOrNull {} getCallingPid {} getCallingUid {}", (void*) selfOrNullFn, (void*) getCallingPidFn, (void*) getCallingUidFn);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
IPCThreadState* (*IPCThreadState::selfOrNullFn)() = nullptr;
|
||||||
|
uid_t (*IPCThreadState::getCallingUidFn)(IPCThreadState*) = nullptr;
|
||||||
|
pid_t (*IPCThreadState::getCallingPidFn)(IPCThreadState*) = nullptr;
|
||||||
|
|
||||||
jboolean
|
jboolean
|
||||||
Service::exec_transact_replace(jboolean *res, JNIEnv *env, [[maybe_unused]] jobject obj,
|
Service::exec_transact_replace(jboolean *res, JNIEnv *env, [[maybe_unused]] jobject obj,
|
||||||
va_list args) {
|
va_list args) {
|
||||||
|
|
@ -51,6 +96,13 @@ namespace lspd {
|
||||||
*res = JNI_CallStaticBooleanMethod(env, instance()->bridge_service_class_,
|
*res = JNI_CallStaticBooleanMethod(env, instance()->bridge_service_class_,
|
||||||
instance()->exec_transact_replace_methodID_,
|
instance()->exec_transact_replace_methodID_,
|
||||||
obj, code, data_obj, reply_obj, flags);
|
obj, code, data_obj, reply_obj, flags);
|
||||||
|
if (!*res) {
|
||||||
|
auto self = IPCThreadState::selfOrNull();
|
||||||
|
if (self != nullptr) {
|
||||||
|
auto id = self->getCallingId();
|
||||||
|
last_failed_id.store(id, std::memory_order_relaxed);
|
||||||
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
} else if (SET_ACTIVITY_CONTROLLER_CODE != -1 &&
|
} else if (SET_ACTIVITY_CONTROLLER_CODE != -1 &&
|
||||||
code == SET_ACTIVITY_CONTROLLER_CODE) [[unlikely]] {
|
code == SET_ACTIVITY_CONTROLLER_CODE) [[unlikely]] {
|
||||||
|
|
@ -78,7 +130,13 @@ namespace lspd {
|
||||||
jboolean
|
jboolean
|
||||||
Service::call_boolean_method_va_replace(JNIEnv *env, jobject obj, jmethodID methodId,
|
Service::call_boolean_method_va_replace(JNIEnv *env, jobject obj, jmethodID methodId,
|
||||||
va_list args) {
|
va_list args) {
|
||||||
if (methodId == instance()->exec_transact_backup_methodID_) [[unlikely]] {
|
bool need_skip = false;
|
||||||
|
if (auto self = IPCThreadState::selfOrNull(); self != nullptr) {
|
||||||
|
auto last = last_failed_id.load(std::memory_order_relaxed);
|
||||||
|
auto current = self->getCallingId();
|
||||||
|
need_skip = last == current;
|
||||||
|
}
|
||||||
|
if (!need_skip && methodId == instance()->exec_transact_backup_methodID_) [[unlikely]] {
|
||||||
jboolean res = false;
|
jboolean res = false;
|
||||||
if (exec_transact_replace(&res, env, obj, args)) [[unlikely]] return res;
|
if (exec_transact_replace(&res, env, obj, args)) [[unlikely]] return res;
|
||||||
// else fallback to backup
|
// else fallback to backup
|
||||||
|
|
@ -221,6 +279,10 @@ namespace lspd {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto &binder = lspd::GetLibBinder(false);
|
||||||
|
IPCThreadState::Init(binder.get());
|
||||||
|
lspd::GetLibBinder(true);
|
||||||
|
|
||||||
LOGD("Done InitService");
|
LOGD("Done InitService");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue