You've already forked TrickyStore
mirror of
https://github.com/5ec1cff/TrickyStore.git
synced 2025-09-06 06:37:07 +00:00
use plt hook
This commit is contained in:
6
.gitmodules
vendored
6
.gitmodules
vendored
@@ -1,6 +1,6 @@
|
||||
[submodule "module/src/main/cpp/external/libcxx"]
|
||||
path = module/src/main/cpp/external/libcxx
|
||||
url = https://github.com/topjohnwu/libcxx
|
||||
[submodule "module/src/main/cpp/external/dobby"]
|
||||
path = module/src/main/cpp/external/dobby
|
||||
url = https://github.com/LSPosed/dobby
|
||||
[submodule "module/src/main/cpp/external/LSPlt"]
|
||||
path = module/src/main/cpp/external/LSPlt
|
||||
url = https://github.com/LSPosed/LSPlt
|
||||
|
||||
@@ -10,20 +10,17 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_FLAGS}")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${LINKER_FLAGS}")
|
||||
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${LINKER_FLAGS}")
|
||||
|
||||
add_library(elf_util STATIC elf_util/elf_util.cpp)
|
||||
add_library(my_logging STATIC logging/logging.cpp)
|
||||
|
||||
add_subdirectory(external)
|
||||
link_libraries(cxx)
|
||||
|
||||
add_library(elf_util STATIC elf_util/elf_util.cpp)
|
||||
add_library(lspmparser STATIC lspmparser/lsplt.cpp)
|
||||
add_library(my_logging STATIC logging/logging.cpp)
|
||||
|
||||
target_include_directories(my_logging PUBLIC logging/include)
|
||||
target_include_directories(elf_util PUBLIC elf_util/include)
|
||||
target_include_directories(lspmparser PUBLIC lspmparser/include)
|
||||
|
||||
target_link_libraries(my_logging cxx log)
|
||||
target_link_libraries(elf_util cxx lspmparser my_logging)
|
||||
target_link_libraries(lspmparser cxx)
|
||||
target_link_libraries(elf_util cxx lsplt my_logging)
|
||||
|
||||
# libutils stub
|
||||
add_library(utils SHARED binder/stub_utils.cpp)
|
||||
@@ -35,11 +32,11 @@ target_include_directories(binder PUBLIC binder/include)
|
||||
target_link_libraries(binder utils)
|
||||
|
||||
add_executable(libinject.so inject/main.cpp inject/utils.cpp)
|
||||
target_link_libraries(libinject.so lspmparser my_logging)
|
||||
target_link_libraries(libinject.so lsplt my_logging)
|
||||
target_compile_options(libinject.so PRIVATE -fvisibility=hidden -fvisibility-inlines-hidden)
|
||||
|
||||
add_library(${MODULE_NAME} SHARED binder_interceptor.cpp)
|
||||
target_link_libraries(${MODULE_NAME} log binder utils dobby elf_util my_logging)
|
||||
target_link_libraries(${MODULE_NAME} log binder utils elf_util my_logging)
|
||||
target_compile_options(${MODULE_NAME} PRIVATE -fvisibility=hidden -fvisibility-inlines-hidden)
|
||||
|
||||
add_library(tszygisk SHARED zygisk/main.cpp)
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include <queue>
|
||||
|
||||
#include "logging.hpp"
|
||||
#include "dobby.h"
|
||||
#include "lsplt.hpp"
|
||||
#include "elf_util.h"
|
||||
|
||||
#include "hook_util/hook_helper.hpp"
|
||||
@@ -101,6 +101,7 @@ class BinderStub : public BBinder {
|
||||
|
||||
static sp<BinderStub> gBinderStub = nullptr;
|
||||
|
||||
// FIXME: when use ioctl hooking, some already blocked ioctl calls will not be hooked
|
||||
int (*old_ioctl)(int fd, int request, ...) = nullptr;
|
||||
int new_ioctl(int fd, int request, ...) {
|
||||
va_list list;
|
||||
@@ -242,52 +243,6 @@ BinderInterceptor::onTransact(uint32_t code, const android::Parcel &data, androi
|
||||
return UNKNOWN_TRANSACTION;
|
||||
}
|
||||
|
||||
|
||||
class HookHandler : public hook_helper::HookHandler {
|
||||
public:
|
||||
ElfImg img;
|
||||
|
||||
explicit HookHandler(ElfInfo info) : img{std::move(info)} {}
|
||||
|
||||
bool isValid() const {
|
||||
return img.isValid();
|
||||
}
|
||||
|
||||
void *get_symbol(const char *name) const override {
|
||||
auto addr = img.getSymbAddress(name);
|
||||
if (!addr) {
|
||||
LOGE("%s: symbol not found", name);
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
void *get_symbol_prefix(const char *prefix) const override {
|
||||
auto addr = img.getSymbPrefixFirstOffset(prefix);
|
||||
if (!addr) {
|
||||
LOGE("%s: prefix symbol not found", prefix);
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
void *hook(void *original, void *replacement) const override {
|
||||
void *result = nullptr;
|
||||
if (DobbyHook(original, (dobby_dummy_func_t) replacement, (dobby_dummy_func_t *) &result) ==
|
||||
0) {
|
||||
return result;
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<uintptr_t, size_t> get_symbol_info(const char *name) const override {
|
||||
auto p = img.getSymInfo(name);
|
||||
if (!p.first) {
|
||||
LOGE("%s: info not found", name);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
};
|
||||
|
||||
bool
|
||||
BinderInterceptor::handleIntercept(sp<BBinder> target, uint32_t code, const Parcel &data, Parcel *reply,
|
||||
uint32_t flags, status_t &result) {
|
||||
@@ -366,15 +321,26 @@ BinderInterceptor::handleIntercept(sp<BBinder> target, uint32_t code, const Parc
|
||||
}
|
||||
|
||||
bool hookBinder() {
|
||||
ElfImg img{ElfInfo::getElfInfoForName("libc.so")};
|
||||
if (!img.isValid()) {
|
||||
auto maps = lsplt::MapInfo::Scan();
|
||||
dev_t dev;
|
||||
ino_t ino;
|
||||
bool found = false;
|
||||
for (auto &m: maps) {
|
||||
if (m.path.ends_with("/libbinder.so")) {
|
||||
dev = m.dev;
|
||||
ino = m.inode;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
LOGE("libbinder not found!");
|
||||
return false;
|
||||
}
|
||||
gBinderInterceptor = sp<BinderInterceptor>::make();
|
||||
gBinderStub = sp<BinderStub>::make();
|
||||
auto ioctlAddr = img.getSymbAddress("ioctl");
|
||||
if (DobbyHook(ioctlAddr, (dobby_dummy_func_t) new_ioctl, (dobby_dummy_func_t*) &old_ioctl) != 0) {
|
||||
lsplt::RegisterHook(dev, ino, "ioctl", (void *) new_ioctl, (void **) &old_ioctl);
|
||||
if (!lsplt::CommitHook()) {
|
||||
LOGE("hook failed!");
|
||||
return false;
|
||||
}
|
||||
|
||||
17
module/src/main/cpp/external/CMakeLists.txt
vendored
17
module/src/main/cpp/external/CMakeLists.txt
vendored
@@ -1,17 +1,14 @@
|
||||
project(external)
|
||||
|
||||
# lsplt
|
||||
set(SOURCES lsplt/lsplt/src/main/jni/lsplt.cc lsplt/lsplt/src/main/jni/elf_util.cc)
|
||||
|
||||
# dobby
|
||||
macro(SET_OPTION option value)
|
||||
set(${option} ${value} CACHE INTERNAL "" FORCE)
|
||||
endmacro()
|
||||
add_library(lsplt STATIC ${SOURCES})
|
||||
target_include_directories(lsplt PUBLIC lsplt/lsplt/src/main/jni/include)
|
||||
target_include_directories(lsplt PRIVATE lsplt/lsplt/src/main/jni)
|
||||
|
||||
SET_OPTION(DOBBY_GENERATE_SHARED OFF)
|
||||
SET_OPTION(Plugin.SymbolResolver OFF)
|
||||
|
||||
add_subdirectory(dobby)
|
||||
target_link_libraries(dobby cxx)
|
||||
# end dobby
|
||||
target_link_libraries(lsplt PUBLIC my_logging cxx)
|
||||
# end lsplt
|
||||
|
||||
# cxx
|
||||
set(LIBCXX_SOURCES
|
||||
|
||||
1
module/src/main/cpp/external/LSPlt
vendored
Submodule
1
module/src/main/cpp/external/LSPlt
vendored
Submodule
Submodule module/src/main/cpp/external/LSPlt added at cef80a97a7
1
module/src/main/cpp/external/dobby
vendored
1
module/src/main/cpp/external/dobby
vendored
Submodule module/src/main/cpp/external/dobby deleted from 6813ca76dd
@@ -1,67 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
/// \namespace lsplt
|
||||
namespace lsplt {
|
||||
inline namespace v2 {
|
||||
/// \struct MapInfo
|
||||
/// \brief An entry that describes a line in /proc/self/maps. You can obtain a list of these entries
|
||||
/// by calling #Scan().
|
||||
struct MapInfo {
|
||||
/// \brief The start address of the memory region.
|
||||
uintptr_t start;
|
||||
/// \brief The end address of the memory region.
|
||||
uintptr_t end;
|
||||
/// \brief The permissions of the memory region. This is a bit mask of the following values:
|
||||
/// - PROT_READ
|
||||
/// - PROT_WRITE
|
||||
/// - PROT_EXEC
|
||||
uint8_t perms;
|
||||
/// \brief Whether the memory region is private.
|
||||
bool is_private;
|
||||
/// \brief The offset of the memory region.
|
||||
uintptr_t offset;
|
||||
/// \brief The device number of the memory region.
|
||||
/// Major can be obtained by #major()
|
||||
/// Minor can be obtained by #minor()
|
||||
dev_t dev;
|
||||
/// \brief The inode number of the memory region.
|
||||
ino_t inode;
|
||||
/// \brief The path of the memory region.
|
||||
std::string path;
|
||||
|
||||
/// \brief Scans /proc/self/maps and returns a list of \ref MapInfo entries.
|
||||
/// This is useful to find out the inode of the library to hook.
|
||||
/// \return A list of \ref MapInfo entries.
|
||||
[[maybe_unused, gnu::visibility("default")]]
|
||||
static std::vector<MapInfo> Scan(std::string proc = "self",
|
||||
std::function<bool(const MapInfo &)> filter = [](
|
||||
auto &map) -> bool { return true; });
|
||||
|
||||
virtual std::string display() const;
|
||||
};
|
||||
|
||||
struct SMapInfo : public MapInfo {
|
||||
ssize_t size;
|
||||
ssize_t rss;
|
||||
ssize_t pss;
|
||||
ssize_t shared_clean;
|
||||
ssize_t shared_dirty;
|
||||
ssize_t private_clean;
|
||||
ssize_t private_dirty;
|
||||
ssize_t referenced;
|
||||
ssize_t anonymous;
|
||||
|
||||
[[maybe_unused, gnu::visibility("default")]]
|
||||
static std::vector<SMapInfo> Scan(std::string proc = "self",
|
||||
std::function<bool(const MapInfo &)> filter = [](
|
||||
auto &map) -> bool { return true; });
|
||||
|
||||
std::string display() const override;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,199 +0,0 @@
|
||||
#include "lsplt.hpp"
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <sys/sysmacros.h>
|
||||
#include <array>
|
||||
#include <cinttypes>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
namespace lsplt {
|
||||
inline namespace v2 {
|
||||
[[maybe_unused]] std::vector<MapInfo>
|
||||
MapInfo::Scan(std::string proc, std::function<bool(const MapInfo &)> filter) {
|
||||
constexpr static auto kPermLength = 5;
|
||||
constexpr static auto kMapEntry = 7;
|
||||
std::vector<MapInfo> info;
|
||||
auto name = std::string("/proc/") + proc + "/maps";
|
||||
auto maps = std::unique_ptr<FILE, decltype(&fclose)>{fopen(name.c_str(), "r"),
|
||||
&fclose};
|
||||
if (maps) {
|
||||
char *line = nullptr;
|
||||
size_t len = 0;
|
||||
ssize_t read;
|
||||
while ((read = getline(&line, &len, maps.get())) > 0) {
|
||||
line[read - 1] = '\0';
|
||||
uintptr_t start = 0;
|
||||
uintptr_t end = 0;
|
||||
uintptr_t off = 0;
|
||||
ino_t inode = 0;
|
||||
unsigned int dev_major = 0;
|
||||
unsigned int dev_minor = 0;
|
||||
std::array<char, kPermLength> perm{'\0'};
|
||||
int path_off;
|
||||
if (sscanf(line, "%" PRIxPTR"-%"
|
||||
PRIxPTR
|
||||
" %4s %"
|
||||
PRIxPTR
|
||||
" %x:%x %lu %n%*s", &start,
|
||||
&end, perm.data(), &off, &dev_major, &dev_minor, &inode,
|
||||
&path_off) == kMapEntry) {
|
||||
while (path_off < read && isspace(line[path_off])) path_off++;
|
||||
MapInfo sm{};
|
||||
sm.start = start;
|
||||
sm.end = end;
|
||||
sm.perms = 0;
|
||||
sm.is_private = perm[3] == 'p';
|
||||
sm.offset = off;
|
||||
sm.dev = static_cast<dev_t>(makedev(dev_major, dev_minor));
|
||||
sm.inode = inode;
|
||||
sm.path = line + path_off;
|
||||
if (perm[0] == 'r') sm.perms |= PROT_READ;
|
||||
if (perm[1] == 'w') sm.perms |= PROT_WRITE;
|
||||
if (perm[2] == 'x') sm.perms |= PROT_EXEC;
|
||||
if (filter(sm)) info.emplace_back(sm);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
free(line);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
// https://cs.android.com/android/kernel/superproject/+/common-android-mainline:common/fs/proc/task_mmu.c;l=827;drc=08582d678fcf11fc86188f0b92239d3d49667d8e
|
||||
[[maybe_unused]] std::vector<SMapInfo>
|
||||
SMapInfo::Scan(std::string proc, std::function<bool(const MapInfo &)> filter) {
|
||||
constexpr static auto kPermLength = 5;
|
||||
constexpr static auto kMapEntry = 7;
|
||||
std::vector<SMapInfo> info;
|
||||
auto name = std::string("/proc/") + proc + "/smaps";
|
||||
auto maps = std::unique_ptr<FILE, decltype(&fclose)>{fopen(name.c_str(), "r"),
|
||||
&fclose};
|
||||
if (!maps) {
|
||||
return info;
|
||||
}
|
||||
char *line = nullptr;
|
||||
size_t len = 0;
|
||||
ssize_t read;
|
||||
while ((read = getline(&line, &len, maps.get())) > 0) {
|
||||
line[read - 1] = '\0';
|
||||
uintptr_t start = 0;
|
||||
uintptr_t end = 0;
|
||||
uintptr_t off = 0;
|
||||
ino_t inode = 0;
|
||||
unsigned int dev_major = 0;
|
||||
unsigned int dev_minor = 0;
|
||||
std::array<char, kPermLength> perm{'\0'};
|
||||
int path_off;
|
||||
if (sscanf(line, "%" PRIxPTR"-%"
|
||||
PRIxPTR
|
||||
" %4s %"
|
||||
PRIxPTR
|
||||
" %x:%x %lu %n%*s", &start,
|
||||
&end, perm.data(), &off, &dev_major, &dev_minor, &inode,
|
||||
&path_off) == kMapEntry) {
|
||||
while (path_off < read && isspace(line[path_off])) path_off++;
|
||||
SMapInfo sm{};
|
||||
sm.start = start;
|
||||
sm.end = end;
|
||||
sm.perms = 0;
|
||||
sm.is_private = perm[3] == 'p';
|
||||
sm.offset = off;
|
||||
sm.dev = static_cast<dev_t>(makedev(dev_major, dev_minor));
|
||||
sm.inode = inode;
|
||||
sm.path = line + path_off;
|
||||
if (perm[0] == 'r') sm.perms |= PROT_READ;
|
||||
if (perm[1] == 'w') sm.perms |= PROT_WRITE;
|
||||
if (perm[2] == 'x') sm.perms |= PROT_EXEC;
|
||||
if (filter(sm)) info.emplace_back(sm);
|
||||
continue;
|
||||
}
|
||||
if (info.empty()) continue;
|
||||
auto ¤t = *info.rbegin();
|
||||
ssize_t value;
|
||||
auto s = strstr(line, ":");
|
||||
if (s == nullptr) continue;
|
||||
*s = 0;
|
||||
if (sscanf(s + 1, "%zu", &value) != 1) continue;
|
||||
std::string_view ss{line};
|
||||
if (ss == "Size") current.size = value;
|
||||
else if (ss == "Rss") current.rss = value;
|
||||
else if (ss == "Pss") current.pss = value;
|
||||
else if (ss == "Shared_Clean") current.shared_clean = value;
|
||||
else if (ss == "Shared_Dirty") current.shared_dirty = value;
|
||||
else if (ss == "Private_Clean") current.private_clean = value;
|
||||
else if (ss == "Private_Dirty") current.private_dirty = value;
|
||||
else if (ss == "Referenced") current.referenced = value;
|
||||
else if (ss == "Anonymous") current.anonymous = value;
|
||||
}
|
||||
free(line);
|
||||
return info;
|
||||
}
|
||||
|
||||
std::string MapInfo::display() const {
|
||||
char buf[sizeof(long) * 2 + 1];
|
||||
std::string result;
|
||||
snprintf(buf, sizeof(buf), "%" PRIxPTR, start);
|
||||
result += buf;
|
||||
result += "-";
|
||||
snprintf(buf, sizeof(buf), "%" PRIxPTR, end);
|
||||
result += buf;
|
||||
result += ' ';
|
||||
result += (perms & PROT_READ) ? 'r' : '-';
|
||||
result += (perms & PROT_WRITE) ? 'w' : '-';
|
||||
result += (perms & PROT_EXEC) ? 'x' : '-';
|
||||
result += is_private ? 'p' : 's';
|
||||
result += ' ';
|
||||
snprintf(buf, sizeof(buf), "%08" PRIxPTR, offset);
|
||||
result += buf;
|
||||
result += ' ';
|
||||
snprintf(buf, sizeof(buf), "%02" PRIxPTR, major(dev));
|
||||
result += buf;
|
||||
result += ':';
|
||||
snprintf(buf, sizeof(buf), "%02" PRIxPTR, minor(dev));
|
||||
result += buf;
|
||||
result += ' ';
|
||||
snprintf(buf, sizeof(buf), "%lu", inode);
|
||||
result += buf;
|
||||
result += ' ';
|
||||
result += path;
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string SMapInfo::display() const {
|
||||
auto result = MapInfo::display();
|
||||
char buf[sizeof(long) * 2 + 1];
|
||||
result += '\n';
|
||||
result += "SZ:";
|
||||
snprintf(buf, sizeof(buf), "%zu", size);
|
||||
result += buf;
|
||||
result += " RSS:";
|
||||
snprintf(buf, sizeof(buf), "%zu", rss);
|
||||
result += buf;
|
||||
result += " PSS:";
|
||||
snprintf(buf, sizeof(buf), "%zu", pss);
|
||||
result += buf;
|
||||
result += " SC:";
|
||||
snprintf(buf, sizeof(buf), "%zu", shared_clean);
|
||||
result += buf;
|
||||
result += " SD:";
|
||||
snprintf(buf, sizeof(buf), "%zu", shared_dirty);
|
||||
result += buf;
|
||||
result += " PC:";
|
||||
snprintf(buf, sizeof(buf), "%zu", private_clean);
|
||||
result += buf;
|
||||
result += " PD:";
|
||||
snprintf(buf, sizeof(buf), "%zu", private_dirty);
|
||||
result += buf;
|
||||
result += " REF:";
|
||||
snprintf(buf, sizeof(buf), "%zu", referenced);
|
||||
result += buf;
|
||||
result += " ANON:";
|
||||
snprintf(buf, sizeof(buf), "%zu", anonymous);
|
||||
result += buf;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
allow keystore keystore process execmem
|
||||
allow keystore system_file unix_dgram_socket *
|
||||
allow system_file keystore unix_dgram_socket *
|
||||
allow keystore system_file file *
|
||||
|
||||
Reference in New Issue
Block a user