You've already forked Zygisk-Assistant
mirror of
https://github.com/snake-4/Zygisk-Assistant.git
synced 2025-09-06 06:37:02 +00:00
Fixed companion NS and moved code to namespaces
This commit is contained in:
@@ -4,6 +4,8 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
namespace Parsers
|
||||||
|
{
|
||||||
class map_entry_t
|
class map_entry_t
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -26,3 +28,4 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
const std::vector<map_entry_t> &parseSelfMaps(bool cached = true);
|
const std::vector<map_entry_t> &parseSelfMaps(bool cached = true);
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,9 +2,10 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
#include <mntent.h>
|
#include <mntent.h>
|
||||||
|
|
||||||
|
namespace Parsers
|
||||||
|
{
|
||||||
class mount_entry_t
|
class mount_entry_t
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -24,3 +25,4 @@ private:
|
|||||||
|
|
||||||
const std::vector<mount_entry_t> &parseSelfMounts(bool cached = true);
|
const std::vector<mount_entry_t> &parseSelfMounts(bool cached = true);
|
||||||
std::unordered_map<std::string, std::string> parseMountOptions(const std::string &input);
|
std::unordered_map<std::string, std::string> parseMountOptions(const std::string &input);
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
|
namespace Parsers
|
||||||
|
{
|
||||||
class mountinfo_entry_t
|
class mountinfo_entry_t
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -31,3 +33,4 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
const std::vector<mountinfo_entry_t> &parseSelfMountinfo(bool cached = true);
|
const std::vector<mountinfo_entry_t> &parseSelfMountinfo(bool cached = true);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <functional>
|
||||||
#include "logging.hpp"
|
#include "logging.hpp"
|
||||||
#include "zygisk.hpp"
|
#include "zygisk.hpp"
|
||||||
|
|
||||||
@@ -8,13 +9,23 @@
|
|||||||
ret (*old_##func)(__VA_ARGS__) = nullptr; \
|
ret (*old_##func)(__VA_ARGS__) = nullptr; \
|
||||||
ret new_##func(__VA_ARGS__)
|
ret new_##func(__VA_ARGS__)
|
||||||
|
|
||||||
#define ASSERT_LOG(tag, expr) if(!(expr)) { \
|
#define ASSERT_LOG(tag, expr) \
|
||||||
LOGE("%s:%d Assertion %s failed. %d:%s", tag, __LINE__, #expr, errno, std::strerror(errno)); }
|
if (!(expr)) \
|
||||||
|
{ \
|
||||||
|
LOGE("%s:%d Assertion %s failed. %d:%s", #tag, __LINE__, #expr, errno, std::strerror(errno)); \
|
||||||
|
}
|
||||||
|
|
||||||
#define ASSERT_EXIT(tag, expr, ret) if(!(expr)) { \
|
#define ASSERT_DO(tag, expr, ret) \
|
||||||
LOGE("%s:%d Assertion %s failed. %d:%s", tag, __LINE__, #expr, errno, std::strerror(errno)); \
|
if (!(expr)) \
|
||||||
ret; }
|
{ \
|
||||||
|
LOGE("%s:%d Assertion %s failed. %d:%s", #tag, __LINE__, #expr, errno, std::strerror(errno)); \
|
||||||
|
ret; \
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Utils
|
||||||
|
{
|
||||||
bool switchMountNS(int pid);
|
bool switchMountNS(int pid);
|
||||||
int isUserAppUID(int uid);
|
int isUserAppUID(int uid);
|
||||||
bool hookPLTByName(zygisk::Api *api, const std::string &libName, const std::string &symbolName, void *hookFunc, void **origFunc);
|
bool hookPLTByName(zygisk::Api *api, const std::string &libName, const std::string &symbolName, void *hookFunc, void **origFunc);
|
||||||
|
int executeLambdaInFork(const std::function<void()> &lambda);
|
||||||
|
}
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ public:
|
|||||||
bool isRoot = (flags & zygisk::StateFlag::PROCESS_GRANTED_ROOT) != 0;
|
bool isRoot = (flags & zygisk::StateFlag::PROCESS_GRANTED_ROOT) != 0;
|
||||||
bool isOnDenylist = (flags & zygisk::StateFlag::PROCESS_ON_DENYLIST) != 0;
|
bool isOnDenylist = (flags & zygisk::StateFlag::PROCESS_ON_DENYLIST) != 0;
|
||||||
bool isChildZygote = args->is_child_zygote != NULL && *args->is_child_zygote;
|
bool isChildZygote = args->is_child_zygote != NULL && *args->is_child_zygote;
|
||||||
if (isRoot || !isOnDenylist || !isUserAppUID(args->uid))
|
if (isRoot || !isOnDenylist || !Utils::isUserAppUID(args->uid))
|
||||||
{
|
{
|
||||||
LOGD("Skipping ppid=%d uid=%d isChildZygote=%d", getppid(), args->uid, isChildZygote);
|
LOGD("Skipping ppid=%d uid=%d isChildZygote=%d", getppid(), args->uid, isChildZygote);
|
||||||
return;
|
return;
|
||||||
@@ -80,20 +80,20 @@ public:
|
|||||||
/*
|
/*
|
||||||
* Read the comment above unshare hook.
|
* Read the comment above unshare hook.
|
||||||
*/
|
*/
|
||||||
ASSERT_EXIT("preAppSpecialize", unshare(CLONE_NEWNS) != -1, return);
|
ASSERT_DO(preAppSpecialize, unshare(CLONE_NEWNS) != -1, return);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mount the app mount namespace's root as MS_SLAVE, so every mount/umount from
|
* Mount the app mount namespace's root as MS_SLAVE, so every mount/umount from
|
||||||
* Zygote shared pre-specialization namespace is propagated to this one.
|
* Zygote shared pre-specialization namespace is propagated to this one.
|
||||||
*/
|
*/
|
||||||
ASSERT_EXIT("preAppSpecialize", mount("rootfs", "/", NULL, (MS_SLAVE | MS_REC), NULL) != -1, return);
|
ASSERT_DO(preAppSpecialize, mount("rootfs", "/", NULL, (MS_SLAVE | MS_REC), NULL) != -1, return);
|
||||||
|
|
||||||
ASSERT_EXIT("preAppSpecialize", hookPLTByName("libandroid_runtime.so", "unshare", new_unshare, &old_unshare), return);
|
ASSERT_DO(preAppSpecialize, hookPLTByName("libandroid_runtime.so", "unshare", new_unshare, &old_unshare), return);
|
||||||
ASSERT_EXIT("preAppSpecialize", hookPLTByName("libandroid_runtime.so", "setresuid", new_setresuid, &old_setresuid), return);
|
ASSERT_DO(preAppSpecialize, hookPLTByName("libandroid_runtime.so", "setresuid", new_setresuid, &old_setresuid), return);
|
||||||
|
|
||||||
int companionFd = -1;
|
int companionFd = -1;
|
||||||
ASSERT_LOG("preAppSpecialize", (companionFd = api->connectCompanion()) != -1);
|
ASSERT_LOG(preAppSpecialize, (companionFd = api->connectCompanion()) != -1);
|
||||||
ASSERT_LOG("preAppSpecialize", companionFd != -1 && api->exemptFd(companionFd));
|
ASSERT_LOG(preAppSpecialize, companionFd != -1 && api->exemptFd(companionFd));
|
||||||
|
|
||||||
callbackFunction = [fd = companionFd]()
|
callbackFunction = [fd = companionFd]()
|
||||||
{
|
{
|
||||||
@@ -103,8 +103,8 @@ public:
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
pid_t pid = getpid();
|
pid_t pid = getpid();
|
||||||
ASSERT_EXIT("invokeZygiskCompanion", write(fd, &pid, sizeof(pid)) == sizeof(pid), break);
|
ASSERT_DO(invokeZygiskCompanion, write(fd, &pid, sizeof(pid)) == sizeof(pid), break);
|
||||||
ASSERT_EXIT("invokeZygiskCompanion", read(fd, &result, sizeof(result)) == sizeof(result), break);
|
ASSERT_DO(invokeZygiskCompanion, read(fd, &result, sizeof(result)) == sizeof(result), break);
|
||||||
} while (false);
|
} while (false);
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
@@ -133,15 +133,15 @@ public:
|
|||||||
void postAppSpecialize(const AppSpecializeArgs *args) override
|
void postAppSpecialize(const AppSpecializeArgs *args) override
|
||||||
{
|
{
|
||||||
if (old_unshare != nullptr)
|
if (old_unshare != nullptr)
|
||||||
ASSERT_LOG("postAppSpecialize", hookPLTByName("libandroid_runtime.so", "unshare", old_unshare));
|
ASSERT_LOG(postAppSpecialize, hookPLTByName("libandroid_runtime.so", "unshare", old_unshare));
|
||||||
if (old_setresuid != nullptr)
|
if (old_setresuid != nullptr)
|
||||||
ASSERT_LOG("postAppSpecialize", hookPLTByName("libandroid_runtime.so", "setresuid", old_setresuid));
|
ASSERT_LOG(postAppSpecialize, hookPLTByName("libandroid_runtime.so", "setresuid", old_setresuid));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool hookPLTByName(const std::string &libName, const std::string &symbolName, T *hookFunction, T **originalFunction = nullptr)
|
bool hookPLTByName(const std::string &libName, const std::string &symbolName, T *hookFunction, T **originalFunction = nullptr)
|
||||||
{
|
{
|
||||||
return ::hookPLTByName(api, libName, symbolName, (void *)hookFunction, (void **)originalFunction) && api->pltHookCommit();
|
return Utils::hookPLTByName(api, libName, symbolName, (void *)hookFunction, (void **)originalFunction) && api->pltHookCommit();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -154,18 +154,21 @@ void zygisk_companion_handler(int fd)
|
|||||||
bool result = [&]() -> bool
|
bool result = [&]() -> bool
|
||||||
{
|
{
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
ASSERT_EXIT("zygisk_companion_handler", read(fd, &pid, sizeof(pid)) == sizeof(pid), return false);
|
ASSERT_DO(zygisk_companion_handler, read(fd, &pid, sizeof(pid)) == sizeof(pid), return false);
|
||||||
ASSERT_EXIT("zygisk_companion_handler", unshare(CLONE_NEWNS) != -1, return false);
|
ASSERT_DO(zygisk_companion_handler, unshare(CLONE_NEWNS) != -1, return false);
|
||||||
ASSERT_EXIT("zygisk_companion_handler", switchMountNS(pid), return false);
|
ASSERT_DO(zygisk_companion_handler, Utils::switchMountNS(pid), return false);
|
||||||
LOGD("zygisk_companion_handler processing namespace of pid=%d", pid);
|
LOGD("zygisk_companion_handler processing namespace of pid=%d", pid);
|
||||||
|
|
||||||
|
// setns mount namespace is not effective until a fork(?)
|
||||||
|
return WIFEXITED(Utils::executeLambdaInFork(
|
||||||
|
[]()
|
||||||
|
{
|
||||||
doUnmount();
|
doUnmount();
|
||||||
doRemount();
|
doRemount();
|
||||||
|
}));
|
||||||
return true;
|
|
||||||
}();
|
}();
|
||||||
|
|
||||||
ASSERT_LOG("zygisk_companion_handler", write(fd, &result, sizeof(result)) == sizeof(result));
|
ASSERT_LOG(zygisk_companion_handler, write(fd, &result, sizeof(result)) == sizeof(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
REGISTER_ZYGISK_MODULE(ZygiskModule)
|
REGISTER_ZYGISK_MODULE(ZygiskModule)
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
#include "map_parser.hpp"
|
#include "map_parser.hpp"
|
||||||
#include "logging.hpp"
|
#include "logging.hpp"
|
||||||
|
|
||||||
|
using namespace Parsers;
|
||||||
|
|
||||||
map_entry_t::map_entry_t(uintptr_t address_start, uintptr_t address_end, uintptr_t offset, const std::string &perms, const std::string &pathname, dev_t device, ino_t inode)
|
map_entry_t::map_entry_t(uintptr_t address_start, uintptr_t address_end, uintptr_t offset, const std::string &perms, const std::string &pathname, dev_t device, ino_t inode)
|
||||||
: address_start(address_start), address_end(address_end), perms(perms),
|
: address_start(address_start), address_end(address_end), perms(perms),
|
||||||
offset(offset), device(device), inode(inode), pathname(pathname) {}
|
offset(offset), device(device), inode(inode), pathname(pathname) {}
|
||||||
@@ -19,7 +21,7 @@ dev_t map_entry_t::getDevice() const { return device; }
|
|||||||
ino_t map_entry_t::getInode() const { return inode; }
|
ino_t map_entry_t::getInode() const { return inode; }
|
||||||
const std::string &map_entry_t::getPathname() const { return pathname; }
|
const std::string &map_entry_t::getPathname() const { return pathname; }
|
||||||
|
|
||||||
const std::vector<map_entry_t> &parseSelfMaps(bool cached)
|
const std::vector<map_entry_t> &Parsers::parseSelfMaps(bool cached)
|
||||||
{
|
{
|
||||||
static std::vector<map_entry_t> parser_cache;
|
static std::vector<map_entry_t> parser_cache;
|
||||||
if (cached && !parser_cache.empty())
|
if (cached && !parser_cache.empty())
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ static const std::unordered_map<std::string, int> mount_flags_procfs = {
|
|||||||
{"relatime", MS_RELATIME},
|
{"relatime", MS_RELATIME},
|
||||||
{"nosymfollow", MS_NOSYMFOLLOW}};
|
{"nosymfollow", MS_NOSYMFOLLOW}};
|
||||||
|
|
||||||
static bool shouldUnmount(const mountinfo_entry_t &mount_info)
|
static bool shouldUnmount(const Parsers::mountinfo_entry_t &mount_info)
|
||||||
{
|
{
|
||||||
const auto &root = mount_info.getRoot();
|
const auto &root = mount_info.getRoot();
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ static bool shouldUnmount(const mountinfo_entry_t &mount_info)
|
|||||||
return root.starts_with("/adb/");
|
return root.starts_with("/adb/");
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool shouldUnmount(const mount_entry_t &mount)
|
static bool shouldUnmount(const Parsers::mount_entry_t &mount)
|
||||||
{
|
{
|
||||||
const auto &mountPoint = mount.getMountPoint();
|
const auto &mountPoint = mount.getMountPoint();
|
||||||
const auto &type = mount.getType();
|
const auto &type = mount.getType();
|
||||||
@@ -66,7 +66,7 @@ void doUnmount()
|
|||||||
std::vector<std::string> mountPoints;
|
std::vector<std::string> mountPoints;
|
||||||
|
|
||||||
// Check mounts first
|
// Check mounts first
|
||||||
for (const auto &mount : parseSelfMounts(false))
|
for (const auto &mount : Parsers::parseSelfMounts(false))
|
||||||
{
|
{
|
||||||
if (shouldUnmount(mount))
|
if (shouldUnmount(mount))
|
||||||
{
|
{
|
||||||
@@ -75,7 +75,7 @@ void doUnmount()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check mountinfos so that we can find bind mounts as well
|
// Check mountinfos so that we can find bind mounts as well
|
||||||
for (const auto &mount_info : parseSelfMountinfo(false))
|
for (const auto &mount_info : Parsers::parseSelfMountinfo(false))
|
||||||
{
|
{
|
||||||
if (shouldUnmount(mount_info))
|
if (shouldUnmount(mount_info))
|
||||||
{
|
{
|
||||||
@@ -102,7 +102,7 @@ void doUnmount()
|
|||||||
|
|
||||||
void doRemount()
|
void doRemount()
|
||||||
{
|
{
|
||||||
for (const auto &mount : parseSelfMounts(false))
|
for (const auto &mount : Parsers::parseSelfMounts(false))
|
||||||
{
|
{
|
||||||
if (mount.getMountPoint() == "/data")
|
if (mount.getMountPoint() == "/data")
|
||||||
{
|
{
|
||||||
@@ -146,7 +146,7 @@ void doHideZygisk()
|
|||||||
std::string filePath;
|
std::string filePath;
|
||||||
uintptr_t startAddress = 0, bssAddress = 0;
|
uintptr_t startAddress = 0, bssAddress = 0;
|
||||||
|
|
||||||
for (const auto &map : parseSelfMaps())
|
for (const auto &map : Parsers::parseSelfMaps())
|
||||||
{
|
{
|
||||||
if (map.getPathname().ends_with("/libnativebridge.so") && map.getPerms() == "r--p")
|
if (map.getPathname().ends_with("/libnativebridge.so") && map.getPerms() == "r--p")
|
||||||
{
|
{
|
||||||
@@ -157,8 +157,8 @@ void doHideZygisk()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT_EXIT("doHideZygisk", startAddress != 0, return);
|
ASSERT_DO(doHideZygisk, startAddress != 0, return);
|
||||||
ASSERT_EXIT("doHideZygisk", reader.load(filePath), return);
|
ASSERT_DO(doHideZygisk, reader.load(filePath), return);
|
||||||
|
|
||||||
size_t bssSize = 0;
|
size_t bssSize = 0;
|
||||||
for (const auto &sec : reader.sections)
|
for (const auto &sec : reader.sections)
|
||||||
@@ -171,7 +171,7 @@ void doHideZygisk()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT_EXIT("doHideZygisk", bssAddress != 0, return);
|
ASSERT_DO(doHideZygisk, bssAddress != 0, return);
|
||||||
LOGD("Found .bss for \"%s\" at 0x%" PRIxPTR " sized %" PRIuPTR " bytes.", filePath.c_str(), bssAddress, bssSize);
|
LOGD("Found .bss for \"%s\" at 0x%" PRIxPTR " sized %" PRIuPTR " bytes.", filePath.c_str(), bssAddress, bssSize);
|
||||||
|
|
||||||
uint8_t *pHadError = reinterpret_cast<uint8_t *>(memchr(reinterpret_cast<void *>(bssAddress), 0x01, bssSize));
|
uint8_t *pHadError = reinterpret_cast<uint8_t *>(memchr(reinterpret_cast<void *>(bssAddress), 0x01, bssSize));
|
||||||
|
|||||||
@@ -9,6 +9,8 @@
|
|||||||
#include "logging.hpp"
|
#include "logging.hpp"
|
||||||
#include "utils.hpp"
|
#include "utils.hpp"
|
||||||
|
|
||||||
|
using namespace Parsers;
|
||||||
|
|
||||||
mount_entry_t::mount_entry_t(::mntent *entry)
|
mount_entry_t::mount_entry_t(::mntent *entry)
|
||||||
: fsname(entry->mnt_fsname), dir(entry->mnt_dir), type(entry->mnt_type), freq(entry->mnt_freq), passno(entry->mnt_passno)
|
: fsname(entry->mnt_fsname), dir(entry->mnt_dir), type(entry->mnt_type), freq(entry->mnt_freq), passno(entry->mnt_passno)
|
||||||
{
|
{
|
||||||
@@ -22,7 +24,7 @@ const std::unordered_map<std::string, std::string> &mount_entry_t::getOptions()
|
|||||||
int mount_entry_t::getDumpFrequency() const { return freq; }
|
int mount_entry_t::getDumpFrequency() const { return freq; }
|
||||||
int mount_entry_t::getPassNumber() const { return passno; }
|
int mount_entry_t::getPassNumber() const { return passno; }
|
||||||
|
|
||||||
const std::vector<mount_entry_t> &parseSelfMounts(bool cached)
|
const std::vector<mount_entry_t> &Parsers::parseSelfMounts(bool cached)
|
||||||
{
|
{
|
||||||
static std::vector<mount_entry_t> parser_cache;
|
static std::vector<mount_entry_t> parser_cache;
|
||||||
if (cached && !parser_cache.empty())
|
if (cached && !parser_cache.empty())
|
||||||
@@ -32,7 +34,7 @@ const std::vector<mount_entry_t> &parseSelfMounts(bool cached)
|
|||||||
parser_cache.clear();
|
parser_cache.clear();
|
||||||
|
|
||||||
FILE *file;
|
FILE *file;
|
||||||
ASSERT_EXIT("parseSelfMounts", (file = setmntent("/proc/self/mounts", "r")) != NULL, return parser_cache);
|
ASSERT_DO(parseSelfMounts, (file = setmntent("/proc/self/mounts", "r")) != NULL, return parser_cache);
|
||||||
|
|
||||||
struct mntent *entry;
|
struct mntent *entry;
|
||||||
while ((entry = getmntent(file)) != NULL)
|
while ((entry = getmntent(file)) != NULL)
|
||||||
@@ -44,7 +46,7 @@ const std::vector<mount_entry_t> &parseSelfMounts(bool cached)
|
|||||||
return parser_cache;
|
return parser_cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unordered_map<std::string, std::string> parseMountOptions(const std::string &input)
|
std::unordered_map<std::string, std::string> Parsers::parseMountOptions(const std::string &input)
|
||||||
{
|
{
|
||||||
std::unordered_map<std::string, std::string> ret;
|
std::unordered_map<std::string, std::string> ret;
|
||||||
std::istringstream iss(input);
|
std::istringstream iss(input);
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
#include "mount_parser.hpp"
|
#include "mount_parser.hpp"
|
||||||
#include "logging.hpp"
|
#include "logging.hpp"
|
||||||
|
|
||||||
|
using namespace Parsers;
|
||||||
|
|
||||||
mountinfo_entry_t::mountinfo_entry_t(int mount_id, int parent_id, int major, int minor,
|
mountinfo_entry_t::mountinfo_entry_t(int mount_id, int parent_id, int major, int minor,
|
||||||
const std::string &root, const std::string &mount_point,
|
const std::string &root, const std::string &mount_point,
|
||||||
const std::string &mount_options, const std::string &optional_fields,
|
const std::string &mount_options, const std::string &optional_fields,
|
||||||
@@ -34,7 +36,7 @@ const std::string &mountinfo_entry_t::getFilesystemType() const { return filesys
|
|||||||
const std::string &mountinfo_entry_t::getMountSource() const { return mount_source; }
|
const std::string &mountinfo_entry_t::getMountSource() const { return mount_source; }
|
||||||
const std::unordered_map<std::string, std::string> &mountinfo_entry_t::getSuperOptions() const { return super_options; }
|
const std::unordered_map<std::string, std::string> &mountinfo_entry_t::getSuperOptions() const { return super_options; }
|
||||||
|
|
||||||
const std::vector<mountinfo_entry_t> &parseSelfMountinfo(bool cached)
|
const std::vector<mountinfo_entry_t> &Parsers::parseSelfMountinfo(bool cached)
|
||||||
{
|
{
|
||||||
static std::vector<mountinfo_entry_t> parser_cache;
|
static std::vector<mountinfo_entry_t> parser_cache;
|
||||||
if (cached && !parser_cache.empty())
|
if (cached && !parser_cache.empty())
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
#include <functional>
|
||||||
#include <format>
|
#include <format>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
@@ -10,9 +12,11 @@
|
|||||||
#include "zygisk.hpp"
|
#include "zygisk.hpp"
|
||||||
#include "logging.hpp"
|
#include "logging.hpp"
|
||||||
|
|
||||||
bool hookPLTByName(zygisk::Api *api, const std::string &libName, const std::string &symbolName, void *hookFunc, void **origFunc)
|
using namespace Utils;
|
||||||
|
|
||||||
|
bool Utils::hookPLTByName(zygisk::Api *api, const std::string &libName, const std::string &symbolName, void *hookFunc, void **origFunc)
|
||||||
{
|
{
|
||||||
for (const auto &map : parseSelfMaps())
|
for (const auto &map : Parsers::parseSelfMaps())
|
||||||
{
|
{
|
||||||
if (map.getPathname().ends_with("/" + libName))
|
if (map.getPathname().ends_with("/" + libName))
|
||||||
{
|
{
|
||||||
@@ -23,7 +27,7 @@ bool hookPLTByName(zygisk::Api *api, const std::string &libName, const std::stri
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int isUserAppUID(int uid)
|
int Utils::isUserAppUID(int uid)
|
||||||
{
|
{
|
||||||
int appid = uid % AID_USER_OFFSET;
|
int appid = uid % AID_USER_OFFSET;
|
||||||
if (appid >= AID_APP_START && appid <= AID_APP_END)
|
if (appid >= AID_APP_START && appid <= AID_APP_END)
|
||||||
@@ -33,7 +37,7 @@ int isUserAppUID(int uid)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool switchMountNS(int pid)
|
bool Utils::switchMountNS(int pid)
|
||||||
{
|
{
|
||||||
std::string path = std::string("/proc/") + std::to_string(pid) + "/ns/mnt";
|
std::string path = std::string("/proc/") + std::to_string(pid) + "/ns/mnt";
|
||||||
int ret, fd;
|
int ret, fd;
|
||||||
@@ -46,3 +50,23 @@ bool switchMountNS(int pid)
|
|||||||
close(fd);
|
close(fd);
|
||||||
return ret == 0;
|
return ret == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Utils::executeLambdaInFork(const std::function<void()> &lambda)
|
||||||
|
{
|
||||||
|
pid_t pid = fork();
|
||||||
|
ASSERT_DO(executeLambdaInFork, pid != -1, return -1);
|
||||||
|
|
||||||
|
if (pid == 0)
|
||||||
|
{
|
||||||
|
// Child process
|
||||||
|
lambda();
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Parent process
|
||||||
|
int status = -1;
|
||||||
|
waitpid(pid, &status, 0);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user