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
Added cache for parsers
This commit is contained in:
@@ -25,4 +25,4 @@ private:
|
||||
ino_t inode;
|
||||
};
|
||||
|
||||
std::vector<map_entry_t> parseMapsFromPath(const char *path);
|
||||
const std::vector<map_entry_t> &parseSelfMaps(bool cached = true);
|
||||
|
||||
@@ -22,5 +22,5 @@ private:
|
||||
int freq, passno;
|
||||
};
|
||||
|
||||
std::vector<mount_entry_t> parseMountsFromPath(const char *path);
|
||||
const std::vector<mount_entry_t> &parseSelfMounts(bool cached = true);
|
||||
std::unordered_map<std::string, std::string> parseMountOptions(const std::string &input);
|
||||
|
||||
@@ -30,4 +30,4 @@ private:
|
||||
std::unordered_map<std::string, std::string> mount_options, super_options;
|
||||
};
|
||||
|
||||
std::vector<mountinfo_entry_t> parseMountinfosFromPath(const char *path);
|
||||
const std::vector<mountinfo_entry_t> &parseSelfMountinfo(bool cached = true);
|
||||
|
||||
@@ -19,15 +19,20 @@ dev_t map_entry_t::getDevice() const { return device; }
|
||||
ino_t map_entry_t::getInode() const { return inode; }
|
||||
const std::string &map_entry_t::getPathname() const { return pathname; }
|
||||
|
||||
std::vector<map_entry_t> parseMapsFromPath(const char *path)
|
||||
const std::vector<map_entry_t> &parseSelfMaps(bool cached)
|
||||
{
|
||||
std::vector<map_entry_t> ret;
|
||||
static std::vector<map_entry_t> parser_cache;
|
||||
if (cached && !parser_cache.empty())
|
||||
{
|
||||
return parser_cache;
|
||||
}
|
||||
parser_cache.clear();
|
||||
|
||||
std::ifstream ifs(path, std::ifstream::in);
|
||||
std::ifstream ifs("/proc/self/maps", std::ifstream::in);
|
||||
if (!ifs)
|
||||
{
|
||||
LOGE("parseMapsFromPath could not open file \"%s\"", path);
|
||||
return ret;
|
||||
LOGE("parseSelfMaps could not open /proc/self/maps");
|
||||
return parser_cache;
|
||||
}
|
||||
|
||||
for (std::string line; std::getline(ifs, line);)
|
||||
@@ -45,15 +50,15 @@ std::vector<map_entry_t> parseMapsFromPath(const char *path)
|
||||
|
||||
if (iss.fail())
|
||||
{
|
||||
LOGE("parseMapsFromPath failed to parse line: %s", line.c_str());
|
||||
LOGE("parseSelfMaps failed to parse line: %s", line.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
// This operation can fail, it doesn't matter as it's an optional field.
|
||||
std::getline(iss >> std::ws, pathname);
|
||||
|
||||
ret.emplace_back(map_entry_t(address_start, address_end, offset, perms, pathname, makedev(dev_major, dev_minor), inode));
|
||||
parser_cache.emplace_back(map_entry_t(address_start, address_end, offset, perms, pathname, makedev(dev_major, dev_minor), inode));
|
||||
}
|
||||
|
||||
return ret;
|
||||
return parser_cache;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ static bool shouldUnmount(const mount_entry_t &mount)
|
||||
const auto &options = mount.getOptions();
|
||||
|
||||
// Unmount everything mounted to /data/adb
|
||||
if (mountPoint.rfind("/data/adb", 0) == 0)
|
||||
if (mountPoint.starts_with("/data/adb"))
|
||||
return true;
|
||||
|
||||
// Unmount all module overlayfs and tmpfs
|
||||
@@ -66,7 +66,7 @@ void doUnmount()
|
||||
std::vector<std::string> mountPoints;
|
||||
|
||||
// Check mounts first
|
||||
for (auto &mount : parseMountsFromPath("/proc/self/mounts"))
|
||||
for (const auto &mount : parseSelfMounts(false))
|
||||
{
|
||||
if (shouldUnmount(mount))
|
||||
{
|
||||
@@ -75,7 +75,7 @@ void doUnmount()
|
||||
}
|
||||
|
||||
// Check mountinfos so that we can find bind mounts as well
|
||||
for (auto &mount_info : parseMountinfosFromPath("/proc/self/mountinfo"))
|
||||
for (const auto &mount_info : parseSelfMountinfo(false))
|
||||
{
|
||||
if (shouldUnmount(mount_info))
|
||||
{
|
||||
@@ -102,31 +102,33 @@ void doUnmount()
|
||||
|
||||
void doRemount()
|
||||
{
|
||||
std::vector<mount_entry_t> mounts = parseMountsFromPath("/proc/self/mounts");
|
||||
auto data_mount_it = std::find_if(mounts.begin(), mounts.end(), [](const mount_entry_t &mount)
|
||||
{ return mount.getMountPoint() == "/data"; });
|
||||
if (data_mount_it != mounts.end())
|
||||
for (const auto &mount : parseSelfMounts(false))
|
||||
{
|
||||
const auto &options = data_mount_it->getOptions();
|
||||
|
||||
// If errors=remount-ro, remount it with errors=continue
|
||||
if (options.contains("errors") && options.at("errors") == "remount-ro")
|
||||
if (mount.getMountPoint() == "/data")
|
||||
{
|
||||
unsigned long flags = MS_REMOUNT;
|
||||
for (const auto &flagName : mount_flags_procfs)
|
||||
const auto &options = mount.getOptions();
|
||||
|
||||
// If errors=remount-ro, remount it with errors=continue
|
||||
if (options.contains("errors") && options.at("errors") == "remount-ro")
|
||||
{
|
||||
if (options.contains(flagName.first))
|
||||
flags |= flagName.second;
|
||||
unsigned long flags = MS_REMOUNT;
|
||||
for (const auto &flagName : mount_flags_procfs)
|
||||
{
|
||||
if (options.contains(flagName.first))
|
||||
flags |= flagName.second;
|
||||
}
|
||||
|
||||
if (::mount(NULL, "/data", NULL, flags, "errors=continue") == 0)
|
||||
{
|
||||
LOGD("mount(NULL, \"/data\", NULL, 0x%lx, \"errors=continue\") returned 0", flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGW("mount(NULL, \"/data\", NULL, 0x%lx, \"errors=continue\") returned -1: %d (%s)", flags, errno, strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
if (mount(NULL, "/data", NULL, flags, "errors=continue") == 0)
|
||||
{
|
||||
LOGD("mount(NULL, \"/data\", NULL, 0x%lx, \"errors=continue\") returned 0", flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGW("mount(NULL, \"/data\", NULL, 0x%lx, \"errors=continue\") returned -1: %d (%s)", flags, errno, strerror(errno));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -144,7 +146,7 @@ void doHideZygisk()
|
||||
std::string filePath;
|
||||
uintptr_t startAddress = 0, bssAddress = 0;
|
||||
|
||||
for (const auto &map : parseMapsFromPath("/proc/self/maps"))
|
||||
for (const auto &map : parseSelfMaps())
|
||||
{
|
||||
if (map.getPathname().ends_with("/libnativebridge.so") && map.getPerms() == "r--p")
|
||||
{
|
||||
@@ -173,6 +175,9 @@ void doHideZygisk()
|
||||
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));
|
||||
ASSERT_EXIT("doHideZygisk", pHadError != nullptr, return);
|
||||
*pHadError = 0;
|
||||
if (pHadError != nullptr)
|
||||
{
|
||||
*pHadError = 0;
|
||||
LOGD("libnativebridge.so had_error was reset.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,21 +22,26 @@ const std::unordered_map<std::string, std::string> &mount_entry_t::getOptions()
|
||||
int mount_entry_t::getDumpFrequency() const { return freq; }
|
||||
int mount_entry_t::getPassNumber() const { return passno; }
|
||||
|
||||
std::vector<mount_entry_t> parseMountsFromPath(const char *path)
|
||||
const std::vector<mount_entry_t> &parseSelfMounts(bool cached)
|
||||
{
|
||||
std::vector<mount_entry_t> result;
|
||||
static std::vector<mount_entry_t> parser_cache;
|
||||
if (cached && !parser_cache.empty())
|
||||
{
|
||||
return parser_cache;
|
||||
}
|
||||
parser_cache.clear();
|
||||
|
||||
FILE *file;
|
||||
ASSERT_EXIT("parseMountsFromPath", (file = setmntent(path, "r")) != NULL, return result);
|
||||
ASSERT_EXIT("parseSelfMounts", (file = setmntent("/proc/self/mounts", "r")) != NULL, return parser_cache);
|
||||
|
||||
struct mntent *entry;
|
||||
while ((entry = getmntent(file)) != NULL)
|
||||
{
|
||||
result.emplace_back(mount_entry_t(entry));
|
||||
parser_cache.emplace_back(mount_entry_t(entry));
|
||||
}
|
||||
|
||||
endmntent(file);
|
||||
return result;
|
||||
return parser_cache;
|
||||
}
|
||||
|
||||
std::unordered_map<std::string, std::string> parseMountOptions(const std::string &input)
|
||||
|
||||
@@ -34,15 +34,20 @@ const std::string &mountinfo_entry_t::getFilesystemType() const { return filesys
|
||||
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; }
|
||||
|
||||
std::vector<mountinfo_entry_t> parseMountinfosFromPath(const char *path)
|
||||
const std::vector<mountinfo_entry_t> &parseSelfMountinfo(bool cached)
|
||||
{
|
||||
std::vector<mountinfo_entry_t> ret;
|
||||
static std::vector<mountinfo_entry_t> parser_cache;
|
||||
if (cached && !parser_cache.empty())
|
||||
{
|
||||
return parser_cache;
|
||||
}
|
||||
parser_cache.clear();
|
||||
|
||||
std::ifstream ifs(path, std::ifstream::in);
|
||||
std::ifstream ifs("/proc/self/mountinfo", std::ifstream::in);
|
||||
if (!ifs)
|
||||
{
|
||||
LOGE("parseMountinfosFromPath could not open file \"%s\"", path);
|
||||
return ret;
|
||||
LOGE("parseSelfMountinfo could not open /proc/self/mountinfo");
|
||||
return parser_cache;
|
||||
}
|
||||
|
||||
for (std::string line; std::getline(ifs, line);)
|
||||
@@ -57,7 +62,7 @@ std::vector<mountinfo_entry_t> parseMountinfosFromPath(const char *path)
|
||||
iss >> mount_id >> parent_id >> major >> colon >> minor >> root >> mount_point >> mount_options;
|
||||
if (iss.fail())
|
||||
{
|
||||
LOGE("parseMountinfosFromPath failed to parse the first 6 fields of line: %s", line.c_str());
|
||||
LOGE("parseSelfMountinfo failed to parse the first 6 fields of line: %s", line.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -69,22 +74,22 @@ std::vector<mountinfo_entry_t> parseMountinfosFromPath(const char *path)
|
||||
|
||||
if (iss.fail())
|
||||
{
|
||||
LOGE("parseMountinfosFromPath failed to parse the optional fields of line: %s", line.c_str());
|
||||
LOGE("parseSelfMountinfo failed to parse the optional fields of line: %s", line.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
iss >> filesystem_type >> mount_source >> super_options;
|
||||
if (iss.fail())
|
||||
{
|
||||
LOGE("parseMountinfosFromPath failed to parse the last 3 fields of line: %s", line.c_str());
|
||||
LOGE("parseSelfMountinfo failed to parse the last 3 fields of line: %s", line.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
ret.emplace_back(mountinfo_entry_t(mount_id, parent_id, major, minor,
|
||||
root, mount_point, mount_options,
|
||||
optional_fields, filesystem_type, mount_source,
|
||||
super_options));
|
||||
parser_cache.emplace_back(mountinfo_entry_t(mount_id, parent_id, major, minor,
|
||||
root, mount_point, mount_options,
|
||||
optional_fields, filesystem_type, mount_source,
|
||||
super_options));
|
||||
}
|
||||
|
||||
return ret;
|
||||
return parser_cache;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
bool hookPLTByName(zygisk::Api *api, const std::string &libName, const std::string &symbolName, void *hookFunc, void **origFunc)
|
||||
{
|
||||
for (const auto &map : parseMapsFromPath("/proc/self/maps"))
|
||||
for (const auto &map : parseSelfMaps())
|
||||
{
|
||||
if (map.getPathname().ends_with("/" + libName))
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user