improve: port common code to C

This commit ports even more C++ code to C99, now, the codes available in the "common" folder.
This commit is contained in:
ThePedroo
2025-04-14 00:54:24 -03:00
parent 5b3d9c75fd
commit 1a3f497e1a
20 changed files with 633 additions and 857 deletions
+49 -77
View File
@@ -1,113 +1,85 @@
#pragma once
#ifndef DAEMON_H
#define DAEMON_H
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#include <string_view>
#include <string>
#include <unistd.h>
#include <vector>
#if defined(__LP64__)
# define LP_SELECT(lp32, lp64) lp64
#ifdef __LP64__
#define LP_SELECT(lp32, lp64) lp64
#else
# define LP_SELECT(lp32, lp64) lp32
#define LP_SELECT(lp32, lp64) lp32
#endif
constexpr auto kCPSocketName = "/" LP_SELECT("cp32", "cp64") ".sock";
#define SOCKET_FILE_NAME LP_SELECT("cp32", "cp64") ".sock"
class UniqueFd {
using Fd = int;
public:
UniqueFd() = default;
UniqueFd(Fd fd) : fd_(fd) {}
~UniqueFd() { if (fd_ >= 0) close(fd_); }
// Disallow copy
UniqueFd(const UniqueFd&) = delete;
UniqueFd& operator=(const UniqueFd&) = delete;
// Allow move
UniqueFd(UniqueFd&& other) { std::swap(fd_, other.fd_); }
UniqueFd& operator=(UniqueFd&& other) {
std::swap(fd_, other.fd_);
return *this;
}
// Implict cast to Fd
operator const Fd&() const { return fd_; }
private:
Fd fd_ = -1;
enum rezygiskd_actions {
PingHeartbeat,
GetProcessFlags,
GetInfo,
ReadModules,
RequestCompanionSocket,
GetModuleDir,
ZygoteRestart,
SystemServerStarted,
UpdateMountNamespace
};
struct zygote_modules {
struct zygisk_modules {
char **modules;
size_t modules_count;
};
enum zygote_root_impl {
ZYGOTE_ROOT_IMPL_NONE,
ZYGOTE_ROOT_IMPL_APATCH,
ZYGOTE_ROOT_IMPL_KERNELSU,
ZYGOTE_ROOT_IMPL_MAGISK
enum root_impl {
ROOT_IMPL_NONE,
ROOT_IMPL_APATCH,
ROOT_IMPL_KERNELSU,
ROOT_IMPL_MAGISK
};
struct zygote_info {
struct zygote_modules *modules;
enum zygote_root_impl root_impl;
struct rezygisk_info {
struct zygisk_modules *modules;
enum root_impl root_impl;
pid_t pid;
bool running;
};
enum mount_namespace_state {
Clean,
Rooted,
Module
Clean,
Rooted,
Module
};
namespace zygiskd {
void rezygiskd_init(const char *path);
struct ModuleInfo {
std::string path;
/* TODO: Perhaps we can also remove this and just send paths? */
std::string name;
void rezygiskd_get_path(char *buf, size_t buf_size);
inline explicit ModuleInfo(std::string path, std::string name) : path(path), name(name) {}
};
int rezygiskd_connect(uint8_t retry);
enum class SocketAction {
PingHeartBeat,
GetProcessFlags,
GetInfo,
ReadModules,
RequestCompanionSocket,
GetModuleDir,
ZygoteRestart,
SystemServerStarted,
UpdateMountNamespace
};
bool rezygiskd_ping();
void Init(const char *path);
uint32_t rezygiskd_get_process_flags(uid_t uid);
std::string GetTmpPath();
void rezygiskd_get_info(struct rezygisk_info *info);
bool PingHeartbeat();
void free_rezygisk_info(struct rezygisk_info *info);
std::vector<ModuleInfo> ReadModules();
bool rezygiskd_read_modules(struct zygisk_modules *modules);
void free_modules(struct zygisk_modules *modules);
uint32_t GetProcessFlags(uid_t uid);
int rezygiskd_connect_companion(size_t index);
int ConnectCompanion(size_t index);
int rezygiskd_get_module_dir(size_t index);
int GetModuleDir(size_t index);
void rezygiskd_zygote_restart();
void ZygoteRestart();
void rezygiskd_system_server_started();
void SystemServerStarted();
bool rezygiskd_update_mns(enum mount_namespace_state nms_state, char *buf, size_t buf_size);
void GetInfo(struct zygote_info *info);
std::string UpdateMountNamespace(enum mount_namespace_state mns_state);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* DAEMON_H */
-2
View File
@@ -6,8 +6,6 @@
#include <linux/elf.h>
#include <sys/types.h>
#define restrict /* INFO: Temporary measure */
#define SHT_GNU_HASH 0x6ffffff6
struct symtabs {
-24
View File
@@ -1,24 +0,0 @@
#include <dirent.h>
#include <functional>
#include <string>
#include <vector>
#include <unistd.h>
struct mount_info {
unsigned int id;
unsigned int parent;
dev_t device;
std::string root;
std::string target;
std::string vfs_option;
struct {
unsigned int shared;
unsigned int master;
unsigned int propagate_from;
} optional;
std::string type;
std::string source;
std::string fs_option;
};
std::vector<mount_info> parse_mount_info(const char *pid);
+17
View File
@@ -0,0 +1,17 @@
#ifndef MISC_H
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/*
* Bionic's atoi runs through strtol().
* Use our own implementation for faster conversion.
*/
int parse_int(const char *str);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* MISC_H */
-98
View File
@@ -1,98 +0,0 @@
#pragma once
#include <list>
#include <memory>
#include <pthread.h>
#include <string>
#include <string_view>
#include "logging.h"
#define DISALLOW_COPY_AND_MOVE(clazz) \
clazz(const clazz &) = delete; \
clazz(clazz &&) = delete;
class mutex_guard {
DISALLOW_COPY_AND_MOVE(mutex_guard)
public:
explicit mutex_guard(pthread_mutex_t &m): mutex(&m) {
pthread_mutex_lock(mutex);
}
void unlock() {
pthread_mutex_unlock(mutex);
mutex = nullptr;
}
~mutex_guard() {
if (mutex) pthread_mutex_unlock(mutex);
}
private:
pthread_mutex_t *mutex;
};
using thread_entry = void *(*)(void *);
int new_daemon_thread(thread_entry entry, void *arg);
static inline bool str_contains(std::string_view s, std::string_view ss) {
return s.find(ss) != std::string_view::npos;
}
template<typename T, typename Impl>
class stateless_allocator {
public:
using value_type = T;
T *allocate(size_t num) { return static_cast<T*>(Impl::allocate(sizeof(T) * num)); }
void deallocate(T *ptr, size_t num) { Impl::deallocate(ptr, sizeof(T) * num); }
stateless_allocator() = default;
stateless_allocator(const stateless_allocator&) = default;
stateless_allocator(stateless_allocator&&) = default;
template <typename U>
stateless_allocator(const stateless_allocator<U, Impl>&) {}
bool operator==(const stateless_allocator&) { return true; }
bool operator!=(const stateless_allocator&) { return false; }
};
template <typename T>
class reversed_container {
public:
reversed_container(T &base) : base(base) {}
decltype(std::declval<T>().rbegin()) begin() { return base.rbegin(); }
decltype(std::declval<T>().crbegin()) begin() const { return base.crbegin(); }
decltype(std::declval<T>().crbegin()) cbegin() const { return base.crbegin(); }
decltype(std::declval<T>().rend()) end() { return base.rend(); }
decltype(std::declval<T>().crend()) end() const { return base.crend(); }
decltype(std::declval<T>().crend()) cend() const { return base.crend(); }
private:
T &base;
};
template <typename T>
reversed_container<T> reversed(T &base) {
return reversed_container<T>(base);
}
template<class T>
static inline void default_new(T *&p) { p = new T(); }
template<class T>
static inline void default_new(std::unique_ptr<T> &p) { p.reset(new T()); }
struct StringCmp {
using is_transparent = void;
bool operator()(std::string_view a, std::string_view b) const { return a < b; }
};
/*
* Bionic's atoi runs through strtol().
* Use our own implementation for faster conversion.
*/
int parse_int(std::string_view s);
std::list<std::string> split_str(std::string_view s, std::string_view delimiter);
std::string join_str(const std::list<std::string>& list, std::string_view delimiter);
template <typename T>
static inline T align_to(T v, int a) {
static_assert(std::is_integral<T>::value);
return (v + a - 1) / a * a;
}
+17 -23
View File
@@ -1,31 +1,25 @@
#pragma once
#ifndef SOCKET_UTILS_H
#define SOCKET_UTILS_H
#include <string>
#include <string_view>
#include <stdint.h>
#include "logging.h"
int read_fd(int fd);
char *read_string(int fd);
namespace socket_utils {
#define write_func_def(type) \
ssize_t write_## type(int fd, type val)
ssize_t xread(int fd, void *buf, size_t count);
#define read_func_def(type) \
ssize_t read_## type(int fd, type *val)
size_t xwrite(int fd, const void *buf, size_t count);
write_func_def(uint8_t);
read_func_def(uint8_t);
uint8_t read_u8(int fd);
write_func_def(uint32_t);
read_func_def(uint32_t);
uint32_t read_u32(int fd);
write_func_def(size_t);
read_func_def(size_t);
size_t read_usize(int fd);
std::string read_string(int fd);
bool write_u8(int fd, uint8_t val);
bool write_u32(int fd, uint32_t val);
int recv_fd(int fd);
bool write_usize(int fd, size_t val);
bool write_string(int fd, std::string_view str);
}
#endif /* SOCKET_UTILS_H */
-66
View File
@@ -1,66 +0,0 @@
#ifndef SOLIST_H
#define SOLIST_H
/* INFO: Temporary */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
typedef struct SoInfo SoInfo;
struct SoInfo {
char data[0];
};
#define FuncType(name) void (*name)
struct pdg {
void *(*ctor)();
void *(*dtor)();
};
/*
INFO: When dlopen'ing a library, the system will save information of the
opened library so a structure called soinfo, which contains another
called solist, a list with the information of opened objects.
Due to special handling in ptracer, however, it won't heave gaps in the
memory of the list since we will close there, not loading a library creating
this gap. However, the previously loaded library would remain in the solist,
requiring ReZygisk to clean those up.
To do that, we use 2 functions: soinfo_free, and set_size, which will
zero the region size, and then remove all traces of that library (libzygisk.so)
which was previously loaded.
SOURCES:
- https://android.googlesource.com/platform/bionic/+/refs/heads/android15-release/linker/linker.cpp#1712
*/
bool solist_drop_so_path(const char *target_path);
/*
INFO: When dlopen'ing a library, the system will increment 1 to a global
counter that tracks the amount of libraries ever loaded in that process,
the same happening in dlclose.
This cannot directly be used to detect if ReZygisk is present, however, with
enough data about specific environments, this can be used to detect if any
other library (be it malicious or not) was loaded. To avoid future detections,
we patch that value to the original value.
To do that, we retrieve the address of both "g_module_load_counter" and "g_module
_unload_counter" variables and force set them to the original value, based on
the modules dlopen'ed.
SOURCES:
- https://android.googlesource.com/platform/bionic/+/refs/heads/android15-release/linker/linker.cpp#1874
- https://android.googlesource.com/platform/bionic/+/refs/heads/android15-release/linker/linker.cpp#1944
- https://android.googlesource.com/platform/bionic/+/refs/heads/android15-release/linker/linker.cpp#3413
*/
void solist_reset_counters(size_t load, size_t unload);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* SOLIST_H */