补全文件

This commit is contained in:
jiqiu2021
2024-11-15 15:33:18 +08:00
parent a50ca00c54
commit b50d500319
3 changed files with 396 additions and 0 deletions

View File

@@ -0,0 +1,131 @@
//
// Created by Mac on 2024/11/15.
//
// 给riru修复了内存泄漏的问题
#include "newriruhide.h"
/**
* Magic to hide from /proc/###/maps, the idea is from Haruue Icymoon (https://github.com/haruue)
*/
extern "C" {
int riru_hide(const std::set<std::string_view> &) ;
}
#ifdef __LP64__
#define LIB_PATH "/system/lib64/"
#else
#define LIB_PATH "/system/lib/"
#endif
struct hide_struct {
procmaps_struct *original;
uintptr_t backup_address;
};
static int get_prot(const procmaps_struct *procstruct) {
int prot = 0;
if (procstruct->is_r) {
prot |= PROT_READ;
}
if (procstruct->is_w) {
prot |= PROT_WRITE;
}
if (procstruct->is_x) {
prot |= PROT_EXEC;
}
return prot;
}
#define FAILURE_RETURN(exp, failure_value) ({ \
__typeof__(exp) _rc; \
_rc = (exp); \
if (_rc == failure_value) { \
PLOGE(#exp); \
return 1; \
} \
_rc; })
static int do_hide(hide_struct *data) {
auto procstruct = data->original;
auto start = (uintptr_t) procstruct->addr_start;
auto end = (uintptr_t) procstruct->addr_end;
auto length = end - start;
int prot = get_prot(procstruct);
// backup
data->backup_address = (uintptr_t) FAILURE_RETURN(
mmap(nullptr, length, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0),
MAP_FAILED);
LOGD("%" PRIxPTR"-%" PRIxPTR" %s %ld %s is backup to %" PRIxPTR, start, end, procstruct->perm,
procstruct->offset,
procstruct->pathname, data->backup_address);
if (procstruct->is_r || procstruct->is_x) { // If readable or executable
LOGD("memcpy -> backup");
memcpy((void *) data->backup_address, (void *) start, length);
// Unmap original memory region
LOGD("munmap original");
FAILURE_RETURN(munmap((void *) start, length), -1);
// Remap backup memory to original location
LOGD("mmap original with backup");
FAILURE_RETURN(mmap((void *) start, length, prot, MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0),
MAP_FAILED);
}
return 0;
}
int riru_hide(const std::set<std::string_view> &names) {
procmaps_iterator *maps = pmparser_parse(-1);
if (maps == nullptr) {
LOGE("cannot parse the memory map");
return false;
}
char buf[PATH_MAX];
hide_struct *data = nullptr;
size_t data_count = 0;
procmaps_struct *maps_tmp;
while ((maps_tmp = pmparser_next(maps)) != nullptr) {
bool matched = false;
#ifdef DEBUG_APP
matched = strstr(maps_tmp->pathname, "libriru.so");
#endif
matched = names.count(maps_tmp->pathname);
// Match the memory regions we want to hide
if (!matched) continue;
auto start = (uintptr_t) maps_tmp->addr_start;
auto end = (uintptr_t) maps_tmp->addr_end;
if (maps_tmp->is_r || maps_tmp->is_x) { // If memory is readable or executable
if (data) {
data = (hide_struct *) realloc(data, sizeof(hide_struct) * (data_count + 1));
} else {
data = (hide_struct *) malloc(sizeof(hide_struct));
}
data[data_count].original = maps_tmp;
data_count += 1;
}
LOGD("%" PRIxPTR"-%" PRIxPTR" %s %ld %s", start, end, maps_tmp->perm, maps_tmp->offset,
maps_tmp->pathname);
}
for (int i = 0; i < data_count; ++i) {
do_hide(&data[i]);
}
// Free backup memory to avoid leaks
for (int i = 0; i < data_count; ++i) {
FAILURE_RETURN(munmap((void *) data[i].backup_address, (uintptr_t) maps_tmp->addr_end - (uintptr_t) maps_tmp->addr_start), -1);
}
if (data) free(data);
pmparser_free(maps);
return 0;
}

View File

@@ -0,0 +1,38 @@
//
// Created by Mac on 2024/11/15.
//
#ifndef ZYGISK_MYINJECTOR_NEWRIRUHIDE_H
#define ZYGISK_MYINJECTOR_NEWRIRUHIDE_H
#define EXPORT __attribute__((visibility("default"))) __attribute__((used))
#include <cinttypes>
#include <sys/mman.h>
#include <set>
#include <string_view>
#include "pmparser.h"
#include "android/log.h"
#ifndef LOG_TAG
#ifdef __LP64__
#define LOG_TAG "Riru64"
#else
#define LOG_TAG "Riru"
#endif
#endif
#ifndef NDEBUG
#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#else
#define LOGV(...)
#define LOGD(...)
#endif
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
#define PLOGE(fmt, args...) LOGE(fmt " failed with %d: %s", ##args, errno, strerror(errno))
extern "C" {
int riru_hide(const std::set<std::string_view> &) EXPORT;
}
#endif //ZYGISK_MYINJECTOR_NEWRIRUHIDE_H

View File

@@ -0,0 +1,227 @@
/*
@Author : ouadimjamal@gmail.com
@date : December 2015
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation. No representations are made about the suitability of this
software for any purpose. It is provided "as is" without express or
implied warranty.
*/
#include "pmparser.h"
/**
* gobal variables
*/
//procmaps_struct* g_last_head=NULL;
//procmaps_struct* g_current=NULL;
procmaps_iterator* pmparser_parse(int pid){
procmaps_iterator* maps_it = static_cast<procmaps_iterator *>(malloc(
sizeof(procmaps_iterator)));
char maps_path[500];
if(pid>=0 ){
sprintf(maps_path,"/proc/%d/maps",pid);
}else{
sprintf(maps_path,"/proc/self/maps");
}
FILE* file=fopen(maps_path,"r");
if(!file){
fprintf(stderr,"pmparser : cannot open the memory maps, %s\n",strerror(errno));
return NULL;
}
int ind=0;char buf[PROCMAPS_LINE_MAX_LENGTH];
int c;
procmaps_struct* list_maps=NULL;
procmaps_struct* tmp;
procmaps_struct* current_node=list_maps;
char addr1[20],addr2[20], perm[8], offset[20], dev[10],inode[30],pathname[PATH_MAX];
while( !feof(file) ){
if (fgets(buf,PROCMAPS_LINE_MAX_LENGTH,file) == NULL && errno){
fprintf(stderr,"pmparser : fgets failed, %s\n",strerror(errno));
return NULL;
}
//allocate a node
tmp=(procmaps_struct*)malloc(sizeof(procmaps_struct));
//fill the node
_pmparser_split_line(buf,addr1,addr2,perm,offset, dev,inode,pathname);
//printf("#%s",buf);
//printf("%s-%s %s %s %s %s\t%s\n",addr1,addr2,perm,offset,dev,inode,pathname);
//addr_start & addr_end
unsigned long l_addr_start;
sscanf(addr1,"%lx",(long unsigned *)&tmp->addr_start );
sscanf(addr2,"%lx",(long unsigned *)&tmp->addr_end );
//size
tmp->length = (unsigned long)((char*)tmp->addr_end - (char*)tmp->addr_start); //perm
strcpy(tmp->perm,perm);
tmp->is_r=(perm[0]=='r');
tmp->is_w=(perm[1]=='w');
tmp->is_x=(perm[2]=='x');
tmp->is_p=(perm[3]=='p');
//offset
sscanf(offset,"%lx",&tmp->offset );
//device
strcpy(tmp->dev,dev);
//inode
tmp->inode=atoi(inode);
//pathname
strcpy(tmp->pathname,pathname);
tmp->next=NULL;
//attach the node
if(ind==0){
list_maps=tmp;
list_maps->next=NULL;
current_node=list_maps;
}
current_node->next=tmp;
current_node=tmp;
ind++;
//printf("%s",buf);
}
//close file
fclose(file);
//g_last_head=list_maps;
maps_it->head = list_maps;
maps_it->current = list_maps;
return maps_it;
}
procmaps_struct* pmparser_next(procmaps_iterator* p_procmaps_it){
if(p_procmaps_it->current == NULL)
return NULL;
procmaps_struct* p_current = p_procmaps_it->current;
p_procmaps_it->current = p_procmaps_it->current->next;
return p_current;
/*
if(g_current==NULL){
g_current=g_last_head;
}else
g_current=g_current->next;
return g_current;
*/
}
void pmparser_free(procmaps_iterator* p_procmaps_it){
procmaps_struct* maps_list = p_procmaps_it->head;
if(maps_list==NULL) return ;
procmaps_struct* act=maps_list;
procmaps_struct* nxt=act->next;
while(act!=NULL){
free(act);
act=nxt;
if(nxt!=NULL)
nxt=nxt->next;
}
free(p_procmaps_it);
}
void _pmparser_split_line(
char*buf,char*addr1,char*addr2,
char*perm,char* offset,char* device,char*inode,
char* pathname){
//
int orig=0;
int i=0;
//addr1
while(buf[i]!='-'){
addr1[i-orig]=buf[i];
i++;
}
addr1[i]='\0';
i++;
//addr2
orig=i;
while(buf[i]!='\t' && buf[i]!=' '){
addr2[i-orig]=buf[i];
i++;
}
addr2[i-orig]='\0';
//perm
while(buf[i]=='\t' || buf[i]==' ')
i++;
orig=i;
while(buf[i]!='\t' && buf[i]!=' '){
perm[i-orig]=buf[i];
i++;
}
perm[i-orig]='\0';
//offset
while(buf[i]=='\t' || buf[i]==' ')
i++;
orig=i;
while(buf[i]!='\t' && buf[i]!=' '){
offset[i-orig]=buf[i];
i++;
}
offset[i-orig]='\0';
//dev
while(buf[i]=='\t' || buf[i]==' ')
i++;
orig=i;
while(buf[i]!='\t' && buf[i]!=' '){
device[i-orig]=buf[i];
i++;
}
device[i-orig]='\0';
//inode
while(buf[i]=='\t' || buf[i]==' ')
i++;
orig=i;
while(buf[i]!='\t' && buf[i]!=' '){
inode[i-orig]=buf[i];
i++;
}
inode[i-orig]='\0';
//pathname
pathname[0]='\0';
while(buf[i]=='\t' || buf[i]==' ')
i++;
orig=i;
while(buf[i]!='\t' && buf[i]!=' ' && buf[i]!='\n'){
pathname[i-orig]=buf[i];
i++;
}
pathname[i-orig]='\0';
}
void pmparser_print(procmaps_struct* map, int order){
procmaps_struct* tmp=map;
int id=0;
if(order<0) order=-1;
while(tmp!=NULL){
//(unsigned long) tmp->addr_start;
if(order==id || order==-1){
printf("Backed by:\t%s\n",strlen(tmp->pathname)==0?"[anonym*]":tmp->pathname);
printf("Range:\t\t%p-%p\n",tmp->addr_start,tmp->addr_end);
printf("Length:\t\t%ld\n",tmp->length);
printf("Offset:\t\t%ld\n",tmp->offset);
printf("Permissions:\t%s\n",tmp->perm);
printf("Inode:\t\t%d\n",tmp->inode);
printf("Device:\t\t%s\n",tmp->dev);
}
if(order!=-1 && id>order)
tmp=NULL;
else if(order==-1){
printf("#################################\n");
tmp=tmp->next;
}else tmp=tmp->next;
id++;
}
}