ignore binder transactions flooding

This commit is contained in:
5ec1cff 2024-01-24 23:31:47 +08:00 committed by JingMatrix
parent 779faeb5ee
commit c5d7b32cc0
4 changed files with 89 additions and 3 deletions

View File

@ -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";

View File

@ -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

View File

@ -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

View File

@ -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");
} }