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
|
||||
#endif
|
||||
|
||||
inline static constexpr auto kLibArtName = "libart.so"_tstr;
|
||||
inline static constexpr auto kLibFwName = "libandroidfw.so"_tstr;
|
||||
inline static constexpr auto kLibArtName = "libart.so";
|
||||
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) {
|
||||
return b ? "true" : "false";
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@ namespace SandHook {
|
|||
|
||||
namespace lspd {
|
||||
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
|
||||
|
|
|
|||
|
|
@ -40,4 +40,24 @@ namespace lspd {
|
|||
}
|
||||
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
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include <dobby.h>
|
||||
#include <thread>
|
||||
#include <atomic>
|
||||
#include "loader.h"
|
||||
#include "service.h"
|
||||
#include "context.h"
|
||||
|
|
@ -36,6 +37,50 @@ using namespace lsplant;
|
|||
namespace lspd {
|
||||
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
|
||||
Service::exec_transact_replace(jboolean *res, JNIEnv *env, [[maybe_unused]] jobject obj,
|
||||
va_list args) {
|
||||
|
|
@ -51,6 +96,13 @@ namespace lspd {
|
|||
*res = JNI_CallStaticBooleanMethod(env, instance()->bridge_service_class_,
|
||||
instance()->exec_transact_replace_methodID_,
|
||||
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;
|
||||
} else if (SET_ACTIVITY_CONTROLLER_CODE != -1 &&
|
||||
code == SET_ACTIVITY_CONTROLLER_CODE) [[unlikely]] {
|
||||
|
|
@ -78,7 +130,13 @@ namespace lspd {
|
|||
jboolean
|
||||
Service::call_boolean_method_va_replace(JNIEnv *env, jobject obj, jmethodID methodId,
|
||||
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;
|
||||
if (exec_transact_replace(&res, env, obj, args)) [[unlikely]] return res;
|
||||
// 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");
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue