Skip to content

Commit

Permalink
clean up remapper
Browse files Browse the repository at this point in the history
  • Loading branch information
lico-n committed Mar 14, 2024
1 parent 3e35763 commit 6235122
Show file tree
Hide file tree
Showing 8 changed files with 118 additions and 140 deletions.
2 changes: 1 addition & 1 deletion module/src/jni/Android.mk
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ XDL_FILES := $(wildcard $(LOCAL_PATH)/xdl/*.c)
APP_STL=none
LOCAL_MODULE := zygiskfrida
LOCAL_C_INCLUDES := $(LOCAL_PATH)/xdl/include $(LOCAL_PATH)/include
LOCAL_SRC_FILES := inject.cpp config.cpp riru_config.cpp child_gating.cpp $(XDL_FILES:$(LOCAL_PATH)/%=%)
LOCAL_SRC_FILES := inject.cpp config.cpp riru_config.cpp child_gating.cpp remapper.cpp $(XDL_FILES:$(LOCAL_PATH)/%=%)
LOCAL_STATIC_LIBRARIES := cxx dobby
LOCAL_LDLIBS := -llog

Expand Down
23 changes: 10 additions & 13 deletions module/src/jni/inject.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "inject.h"

#include <unistd.h>

#include <chrono>
#include <cinttypes>
#include <filesystem>
Expand All @@ -14,11 +16,9 @@
#include "log.h"
#include "child_gating.h"
#include "xdl.h"
#include "process.h"
#include "remapper.h"

static std::string get_process_name()
{
static std::string get_process_name() {
auto path = "/proc/self/cmdline";

std::ifstream file(path);
Expand Down Expand Up @@ -65,23 +65,20 @@ static void delay_start_up(uint64_t start_up_delay_ms) {
}
}

void inject_lib(std::string const &lib_path, std::string const &logContext)
{
void inject_lib(std::string const &lib_path, std::string const &logContext) {
auto *handle = xdl_open(lib_path.c_str(), XDL_TRY_FORCE_LOAD);
if (handle)
{
if (handle) {
LOGI("%sInjected %s with handle %p", logContext.c_str(), lib_path.c_str(), handle);
remap_lib("libgadget.so", get_pid_of_self());
remap_lib(lib_path);
return;
}

auto xdl_err = dlerror();

handle = dlopen(lib_path.c_str(), RTLD_NOW);
if (handle)
{
if (handle) {
LOGI("%sInjected %s with handle %p (dlopen)", logContext.c_str(), lib_path.c_str(), handle);
remap_lib("libgadget.so", get_pid_of_self());
remap_lib(lib_path);
return;
}

Expand Down Expand Up @@ -110,7 +107,7 @@ static void inject_libs(target_config const &cfg) {
}
}

bool check_and_inject(std::string const &app_name, int pid) {
bool check_and_inject(std::string const &app_name) {
std::string module_dir = std::string("/data/local/tmp/re.zyg.fri");

std::optional<target_config> cfg = load_config(module_dir, app_name);
Expand All @@ -119,7 +116,7 @@ bool check_and_inject(std::string const &app_name, int pid) {
}

LOGI("App detected: %s", app_name.c_str());
LOGI("PID: %s", get_pid_of_self().c_str());
LOGI("PID: %d", getpid());


auto target_config = cfg.value();
Expand Down
2 changes: 1 addition & 1 deletion module/src/jni/inject.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
#include <string>

void inject_lib(std::string const& lib_path, std::string const& logContext);
bool check_and_inject(std::string const& app_name, int pid);
bool check_and_inject(std::string const& app_name);

#endif // ZYGISKFRIDA_INJECT_H
2 changes: 1 addition & 1 deletion module/src/jni/main_riru.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ static void forkAndSpecializePost(JNIEnv *env, jclass clazz, jint res) {
return;
}

if (check_and_inject(app_name, 0)) {
if (check_and_inject(app_name)) {
riru_set_unload_allowed(false);
}
}
Expand Down
2 changes: 1 addition & 1 deletion module/src/jni/main_zygisk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class MyModule : public zygisk::ModuleBase {
std::string app_name = std::string(raw_app_name);
this->env->ReleaseStringUTFChars(args->nice_name, raw_app_name);

if (!check_and_inject(app_name, args->uid)) {
if (!check_and_inject(app_name)) {
this->api->setOption(zygisk::Option::DLCLOSE_MODULE_LIBRARY);
}
}
Expand Down
27 changes: 0 additions & 27 deletions module/src/jni/process.h

This file was deleted.

103 changes: 103 additions & 0 deletions module/src/jni/remapper.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
#include "remapper.h"

#include <link.h>
#include <sys/mman.h>

#include <cinttypes>
#include <cstdint>
#include <string>
#include <vector>

#include "log.h"

// Struct to hold a single entry in /proc/maps/
// Format: 7ac49c2000(start)-7ac4a26000(end) r--p (permissions) 00000000(offset) 00:00 0 (dev) 1245 (inode) /apex/com.android.runtime/bin/linker64 (path) // NOLINT
struct PROCMAPSINFO {
uintptr_t start, end, offset;
uint8_t perms;
ino_t inode;
char* dev;
char* path;
};


std::vector<PROCMAPSINFO> get_modules_by_name(std::string mName) {
std::string process_maps_locations = "/proc/self/maps";

std::vector<PROCMAPSINFO> maps;

char buffer[512];
FILE *fp = fopen(process_maps_locations.c_str(), "re");

if (fp == nullptr) {
return maps;
}

while (fgets(buffer, sizeof(buffer), fp)) {
if (strstr(buffer, mName.c_str())) {
PROCMAPSINFO info{};
char perms[10];
char path[255];
char dev[25];

sscanf(
buffer,
"%" SCNxPTR "-%" SCNxPTR " %s %" SCNxPTR " %s %ld %s",
&info.start, &info.end, perms, &info.offset, dev, &info.inode, path);

/* Store process permissions in the struct directly via bitwise operations */
if (strchr(perms, 'r')) info.perms |= PROT_READ;
if (strchr(perms, 'w')) info.perms |= PROT_WRITE;
if (strchr(perms, 'x')) info.perms |= PROT_EXEC;
if (strchr(perms, 'r')) info.perms |= PROT_READ;

info.dev = dev;
info.path = path;

maps.push_back(info);
}
}

fclose(fp);

return maps;
}

void remap_lib(std::string lib_path) {
std::string lib_name = lib_path.substr(lib_path.find_last_of("/\\") + 1);

std::vector<PROCMAPSINFO> maps = get_modules_by_name(lib_name);
if (maps.size() == 0) {
return;
}

LOGI("Remapping %s", lib_name.c_str());

for (PROCMAPSINFO info : maps) {
void *address = reinterpret_cast<void *>(info.start);
size_t size = info.end - info.start;

void *map = mmap(0, size, PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);

if ((info.perms & PROT_READ) == 0) {
LOGI("Removing memory protection: %s", info.path);
mprotect(address, size, PROT_READ);
}

if (map == nullptr) {
LOGE("Failed to Allocate Memory: %s", strerror(errno));
return;
}

/* Copy the in-memory data to new virtual location via the memove, allocate and commit it via mremap */
std::memmove(map, address, size);
mremap(map, size, size, MREMAP_MAYMOVE | MREMAP_FIXED, info.start);

/* Re-apply memory protections */
mprotect(reinterpret_cast<void *>(info.start), size, info.perms);

LOGI("Allocated at address %p with size of %zu", map, size);
}

LOGI("Remapped");
}
97 changes: 1 addition & 96 deletions module/src/jni/remapper.h
Original file line number Diff line number Diff line change
@@ -1,98 +1,3 @@
#include <cstdint>
#include <link.h>
#include <sys/mman.h>
#include <vector>
#include <string>

#include "log.h"

/* Struct to hold a single entry in /proc/maps/ */
/* Format: 7ac49c2000(start)-7ac4a26000(end) r--p (permissions) 00000000(offset) 00:00 0 (dev) 1245 (inode) /apex/com.android.runtime/bin/linker64 (path) */
struct PROCMAPSINFO {
uintptr_t start, end, offset;
uint8_t perms;
ino_t inode;
char* dev;
char* path;
};

std::vector<PROCMAPSINFO> get_modules_by_name(std::string mName, std::string pid)
{
std::string process_maps_locations_via_proc_id = "/proc/" + pid + "/maps";
std::string process_maps_locations = "/proc/self/maps";

std::vector<PROCMAPSINFO> returnVal;

char buffer[512];
FILE *fp = fopen(process_maps_locations.c_str(), "re");

if (fp != nullptr)
{
while (fgets(buffer, sizeof(buffer), fp))
{
if (strstr(buffer, mName.c_str()))
{
PROCMAPSINFO info{};
char perms[10];
char path[255];
char dev[25];

sscanf(buffer, "%lx-%lx %s %ld %s %ld %s", &info.start, &info.end, perms, &info.offset, dev, &info.inode, path);

/* Store process permissions in the struct directly via bitwise operations */
if (strchr(perms, 'r')) info.perms |= PROT_READ;
if (strchr(perms, 'w')) info.perms |= PROT_WRITE;
if (strchr(perms, 'x')) info.perms |= PROT_EXEC;
if (strchr(perms, 'r')) info.perms |= PROT_READ;

info.dev = dev;
info.path = path;

/* LOGI("Line at: %s", buffer); */
returnVal.push_back(info);
}
}
}
return returnVal;
}

void remap_lib(std::string name, std::string pid)
{
std::vector<PROCMAPSINFO> maps = get_modules_by_name(name, pid);

for (PROCMAPSINFO info : maps)
{
void *address = (void *)info.start;
size_t size = info.end - info.start;

void *map = mmap(0, size, PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);

if ((info.perms & PROT_READ) == 0) {
LOGI("Removing memory protection: %s", info.path);
mprotect(address, size, PROT_READ);
}

if (map == nullptr) {
LOGE("Failed to Allocate Memory: %s", strerror(errno));
return;
}

/* Copy the in-memory data to new virtual location via the memove, allocate and commit it via mremap */
std::memmove(map, address, size);
mremap(map, size, size, MREMAP_MAYMOVE | MREMAP_FIXED, info.start);

/* Re-apply memory protections */
mprotect((void *)info.start, size, info.perms);

LOGI("Allocated at address %p with size of %zu", map, size);
}

LOGI("Remapping completed!!");
}

bool remap_all(std::vector<std::string> libs, std::string pid)
{
for (int i = 0; i < libs.size(); i++)
remap_lib(libs[i], pid);
}

void remap_lib(std::string lib_path);

0 comments on commit 6235122

Please sign in to comment.