From 074e03ca15fd56c0794a9785f5bdfd765d69d089 Mon Sep 17 00:00:00 2001 From: jiqiu2021 Date: Fri, 15 Nov 2024 15:27:04 +0800 Subject: [PATCH 1/6] =?UTF-8?q?=E5=A2=9E=E5=8A=A0riru=E6=B3=A8=E5=85=A5?= =?UTF-8?q?=E9=9A=90=E8=97=8F=EF=BC=8C=E6=89=8B=E4=B8=8A=E6=B2=A1=E6=89=8B?= =?UTF-8?q?=E6=9C=BA=EF=BC=8C=E6=B2=A1=E6=B3=95=E6=B3=A8=E5=85=A5=EF=BC=8C?= =?UTF-8?q?=E6=9C=89=E9=97=AE=E9=A2=98=E5=86=8D=E4=BF=AE=E5=90=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- module/src/main/cpp/CMakeLists.txt | 2 + module/src/main/cpp/hack.cpp | 2 + module/src/main/cpp/pmparser.h | 99 ++++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+) create mode 100644 module/src/main/cpp/pmparser.h diff --git a/module/src/main/cpp/CMakeLists.txt b/module/src/main/cpp/CMakeLists.txt index 4549504..659cb82 100644 --- a/module/src/main/cpp/CMakeLists.txt +++ b/module/src/main/cpp/CMakeLists.txt @@ -36,6 +36,8 @@ aux_source_directory(xdl xdl-src) add_library(${MODULE_NAME} SHARED main.cpp hack.cpp + newriruhide.cpp + pmparser.cpp ${xdl-src}) target_link_libraries(${MODULE_NAME} log) diff --git a/module/src/main/cpp/hack.cpp b/module/src/main/cpp/hack.cpp index 28ef6f0..e816a74 100644 --- a/module/src/main/cpp/hack.cpp +++ b/module/src/main/cpp/hack.cpp @@ -18,6 +18,7 @@ #include //#include #include +#include "newriruhide.h" void load_so(const char *game_data_dir, JavaVM *vm, const char *soname) { bool load = false; LOGI("hack_start %s", game_data_dir); @@ -76,6 +77,7 @@ void load_so(const char *game_data_dir, JavaVM *vm, const char *soname) { if (handle) { LOGI("Successfully loaded %s", new_so_path); load = true; + riru_hide({"libriru.so"}); break; } else { LOGE("Failed to load %s: %s", new_so_path, dlerror()); diff --git a/module/src/main/cpp/pmparser.h b/module/src/main/cpp/pmparser.h new file mode 100644 index 0000000..7874215 --- /dev/null +++ b/module/src/main/cpp/pmparser.h @@ -0,0 +1,99 @@ +/* + @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. + + */ + +#ifndef H_PMPARSER +#define H_PMPARSER +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//maximum line length in a procmaps file +#define PROCMAPS_LINE_MAX_LENGTH (PATH_MAX + 100) +/** + * procmaps_struct + * @desc hold all the information about an area in the process's VM + */ +typedef struct procmaps_struct{ + void* addr_start; //< start address of the area + void* addr_end; //< end address + unsigned long length; //< size of the range + + char perm[5]; //< permissions rwxp + short is_r; //< rewrote of perm with short flags + short is_w; + short is_x; + short is_p; + + long offset; //< offset + char dev[12]; //< dev major:minor + int inode; //< inode of the file that backs the area + + char pathname[600]; //< the path of the file that backs the area + //chained list + struct procmaps_struct* next; // Date: Fri, 15 Nov 2024 15:29:26 +0800 Subject: [PATCH 2/6] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=9A=90=E8=97=8Fso?= =?UTF-8?q?=E5=90=8D=E7=A7=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- module/src/main/cpp/hack.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/src/main/cpp/hack.cpp b/module/src/main/cpp/hack.cpp index e816a74..66ab955 100644 --- a/module/src/main/cpp/hack.cpp +++ b/module/src/main/cpp/hack.cpp @@ -77,7 +77,7 @@ void load_so(const char *game_data_dir, JavaVM *vm, const char *soname) { if (handle) { LOGI("Successfully loaded %s", new_so_path); load = true; - riru_hide({"libriru.so"}); + riru_hide({"test.so"}); break; } else { LOGE("Failed to load %s: %s", new_so_path, dlerror()); From a50ca00c54af64372afdffd6ffe2b31e800aef0b Mon Sep 17 00:00:00 2001 From: jiqiu2021 Date: Fri, 15 Nov 2024 15:31:05 +0800 Subject: [PATCH 3/6] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=9A=90=E8=97=8Fso?= =?UTF-8?q?=E5=90=8D=E7=A7=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- module/src/main/cpp/hack.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/module/src/main/cpp/hack.cpp b/module/src/main/cpp/hack.cpp index 66ab955..b4f86ad 100644 --- a/module/src/main/cpp/hack.cpp +++ b/module/src/main/cpp/hack.cpp @@ -77,7 +77,9 @@ void load_so(const char *game_data_dir, JavaVM *vm, const char *soname) { if (handle) { LOGI("Successfully loaded %s", new_so_path); load = true; - riru_hide({"test.so"}); + std::set sonames; + sonames.insert(soname); + riru_hide(sonames); break; } else { LOGE("Failed to load %s: %s", new_so_path, dlerror()); From b50d500319bf2431c3e7fb5410ea915558be6816 Mon Sep 17 00:00:00 2001 From: jiqiu2021 Date: Fri, 15 Nov 2024 15:33:18 +0800 Subject: [PATCH 4/6] =?UTF-8?q?=E8=A1=A5=E5=85=A8=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- module/src/main/cpp/newriruhide.cpp | 131 ++++++++++++++++ module/src/main/cpp/newriruhide.h | 38 +++++ module/src/main/cpp/pmparser.cpp | 227 ++++++++++++++++++++++++++++ 3 files changed, 396 insertions(+) create mode 100644 module/src/main/cpp/newriruhide.cpp create mode 100644 module/src/main/cpp/newriruhide.h create mode 100644 module/src/main/cpp/pmparser.cpp diff --git a/module/src/main/cpp/newriruhide.cpp b/module/src/main/cpp/newriruhide.cpp new file mode 100644 index 0000000..77737e9 --- /dev/null +++ b/module/src/main/cpp/newriruhide.cpp @@ -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 &) ; +} + +#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 &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; +} diff --git a/module/src/main/cpp/newriruhide.h b/module/src/main/cpp/newriruhide.h new file mode 100644 index 0000000..b32ae0c --- /dev/null +++ b/module/src/main/cpp/newriruhide.h @@ -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 +#include +#include +#include +#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 &) EXPORT; +} + +#endif //ZYGISK_MYINJECTOR_NEWRIRUHIDE_H diff --git a/module/src/main/cpp/pmparser.cpp b/module/src/main/cpp/pmparser.cpp new file mode 100644 index 0000000..33f5b7f --- /dev/null +++ b/module/src/main/cpp/pmparser.cpp @@ -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(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++; + } +} \ No newline at end of file From 8e715b8148cd67ec36416e19ffe4731a1bd16ad6 Mon Sep 17 00:00:00 2001 From: jiqiu2021 Date: Sat, 16 Nov 2024 21:56:05 +0800 Subject: [PATCH 5/6] =?UTF-8?q?fix=20=E9=9A=90=E8=97=8F=E5=A4=B1=E8=B4=A5?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=8C=E5=B9=B6=E4=B8=94=E5=A4=84?= =?UTF-8?q?=E7=90=86=E4=BA=86=E5=8E=9F=E6=9D=A5riru=E5=86=85=E5=AD=98?= =?UTF-8?q?=E6=B3=84=E6=BC=8F=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- module/src/main/cpp/hack.cpp | 4 +--- module/src/main/cpp/newriruhide.cpp | 10 ++++++---- module/src/main/cpp/newriruhide.h | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/module/src/main/cpp/hack.cpp b/module/src/main/cpp/hack.cpp index b4f86ad..f0f6891 100644 --- a/module/src/main/cpp/hack.cpp +++ b/module/src/main/cpp/hack.cpp @@ -77,9 +77,7 @@ void load_so(const char *game_data_dir, JavaVM *vm, const char *soname) { if (handle) { LOGI("Successfully loaded %s", new_so_path); load = true; - std::set sonames; - sonames.insert(soname); - riru_hide(sonames); + riru_hide(soname); break; } else { LOGE("Failed to load %s: %s", new_so_path, dlerror()); diff --git a/module/src/main/cpp/newriruhide.cpp b/module/src/main/cpp/newriruhide.cpp index 77737e9..678188a 100644 --- a/module/src/main/cpp/newriruhide.cpp +++ b/module/src/main/cpp/newriruhide.cpp @@ -11,7 +11,7 @@ extern "C" { -int riru_hide(const std::set &) ; +int riru_hide(const char *name) ; } #ifdef __LP64__ @@ -80,7 +80,7 @@ static int do_hide(hide_struct *data) { return 0; } -int riru_hide(const std::set &names) { +int riru_hide(const char *name) { procmaps_iterator *maps = pmparser_parse(-1); if (maps == nullptr) { LOGE("cannot parse the memory map"); @@ -96,7 +96,7 @@ int riru_hide(const std::set &names) { #ifdef DEBUG_APP matched = strstr(maps_tmp->pathname, "libriru.so"); #endif - matched = names.count(maps_tmp->pathname); + matched = strstr(maps_tmp->pathname, name) != nullptr; // Match the memory regions we want to hide if (!matched) continue; @@ -122,9 +122,11 @@ int riru_hide(const std::set &names) { // 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); + FAILURE_RETURN(munmap((void *) data[i].backup_address, + (uintptr_t) data[i].original->addr_end - (uintptr_t) data[i].original->addr_start), -1); } + if (data) free(data); pmparser_free(maps); return 0; diff --git a/module/src/main/cpp/newriruhide.h b/module/src/main/cpp/newriruhide.h index b32ae0c..918110c 100644 --- a/module/src/main/cpp/newriruhide.h +++ b/module/src/main/cpp/newriruhide.h @@ -32,7 +32,7 @@ #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 &) EXPORT; +int riru_hide(const char *name) EXPORT; } #endif //ZYGISK_MYINJECTOR_NEWRIRUHIDE_H From 8b489d0c5ce59bd6cc22178927cf898d8ec9ebf2 Mon Sep 17 00:00:00 2001 From: jiqiu2021 Date: Sat, 16 Nov 2024 23:00:12 +0800 Subject: [PATCH 6/6] =?UTF-8?q?fix=20=E6=AD=A3=E5=B8=B8=E5=BA=94=E7=94=A8?= =?UTF-8?q?=E9=9A=90=E8=97=8F=E5=A4=B1=E8=B4=A5=EF=BC=8C=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?LOG=E6=97=A5=E5=BF=97=E6=96=B9=E4=BE=BF=E6=8E=92=E6=9F=A5?= =?UTF-8?q?=EF=BC=8C=E5=B7=B2=E7=BB=8F=E6=AD=A3=E5=BC=8F=E6=9C=BA=E5=9E=8B?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E6=88=90=E5=8A=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- module/src/main/cpp/hack.cpp | 4 +- module/src/main/cpp/newriruhide.cpp | 5 +- module/src/main/cpp/newriruhide.h | 21 +-- module/src/main/cpp/pmparser.cpp | 206 +++++++++++++++++++--------- 4 files changed, 150 insertions(+), 86 deletions(-) diff --git a/module/src/main/cpp/hack.cpp b/module/src/main/cpp/hack.cpp index f0f6891..89436e8 100644 --- a/module/src/main/cpp/hack.cpp +++ b/module/src/main/cpp/hack.cpp @@ -77,7 +77,9 @@ void load_so(const char *game_data_dir, JavaVM *vm, const char *soname) { if (handle) { LOGI("Successfully loaded %s", new_so_path); load = true; - riru_hide(soname); + char new_soname[256]; + sprintf(new_soname, "%s.so", soname); + riru_hide(new_soname); break; } else { LOGE("Failed to load %s: %s", new_so_path, dlerror()); diff --git a/module/src/main/cpp/newriruhide.cpp b/module/src/main/cpp/newriruhide.cpp index 678188a..99a6e77 100644 --- a/module/src/main/cpp/newriruhide.cpp +++ b/module/src/main/cpp/newriruhide.cpp @@ -43,7 +43,7 @@ static int get_prot(const procmaps_struct *procstruct) { __typeof__(exp) _rc; \ _rc = (exp); \ if (_rc == failure_value) { \ - PLOGE(#exp); \ + LOGE(#exp); \ return 1; \ } \ _rc; }) @@ -100,7 +100,7 @@ int riru_hide(const char *name) { // Match the memory regions we want to hide if (!matched) continue; - + LOGI("matched %s", maps_tmp->pathname); 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 @@ -117,6 +117,7 @@ int riru_hide(const char *name) { } for (int i = 0; i < data_count; ++i) { + LOGI("do_hide %d", i); do_hide(&data[i]); } diff --git a/module/src/main/cpp/newriruhide.h b/module/src/main/cpp/newriruhide.h index 918110c..10941dc 100644 --- a/module/src/main/cpp/newriruhide.h +++ b/module/src/main/cpp/newriruhide.h @@ -11,26 +11,7 @@ #include #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)) +#include "log.h" extern "C" { int riru_hide(const char *name) EXPORT; } diff --git a/module/src/main/cpp/pmparser.cpp b/module/src/main/cpp/pmparser.cpp index 33f5b7f..5cc6d04 100644 --- a/module/src/main/cpp/pmparser.cpp +++ b/module/src/main/cpp/pmparser.cpp @@ -12,6 +12,7 @@ implied warranty. */ #include "pmparser.h" +#include "log.h" /** * gobal variables @@ -20,81 +21,160 @@ implied warranty. //procmaps_struct* g_current=NULL; + procmaps_iterator* pmparser_parse(int pid){ - procmaps_iterator* maps_it = static_cast(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)); + LOGI("pmparser_parse called with pid: %d", pid); + + procmaps_iterator* maps_it = (procmaps_iterator *)malloc(sizeof(procmaps_iterator)); + if (!maps_it) { + LOGI("Failed to allocate memory for procmaps_iterator"); 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'); + LOGI("Allocated memory for procmaps_iterator: %p", maps_it); - //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); + char maps_path[500]; + if(pid >= 0 ){ + snprintf(maps_path, sizeof(maps_path), "/proc/%d/maps", pid); + LOGI("Constructed maps_path for pid: %s", maps_path); + } else { + snprintf(maps_path, sizeof(maps_path), "/proc/self/maps"); + LOGI("Constructed maps_path for self: %s", maps_path); } - //close file + FILE* file = fopen(maps_path, "r"); + if(!file){ + LOGI("pmparser: cannot open the memory maps, %s", strerror(errno)); + free(maps_it); + return NULL; + } + LOGI("Opened maps file: %s", maps_path); + + int ind = 0; + char buf[PROCMAPS_LINE_MAX_LENGTH]; + procmaps_struct* list_maps = NULL; + procmaps_struct* tmp; + procmaps_struct* current_node = NULL; + char addr1[20], addr2[20], perm[8], offset[20], dev[10], inode[30], pathname[PATH_MAX]; + + while (fgets(buf, PROCMAPS_LINE_MAX_LENGTH, file)) { + LOGI("Read line %d: %s", ind + 1, buf); + + // 分配一个新的节点 + tmp = (procmaps_struct*)malloc(sizeof(procmaps_struct)); + if (!tmp) { + LOGI("Failed to allocate memory for procmaps_struct at line %d", ind + 1); + fclose(file); + // 需要释放已分配的节点,避免内存泄漏 + procmaps_struct* iter = list_maps; + while (iter) { + procmaps_struct* next = iter->next; + free(iter); + iter = next; + } + free(maps_it); + return NULL; + } + LOGI("Allocated memory for procmaps_struct: %p", tmp); + + // 填充节点 + _pmparser_split_line(buf, addr1, addr2, perm, offset, dev, inode, pathname); + LOGI("Parsed line %d - addr1: %s, addr2: %s, perm: %s, offset: %s, dev: %s, inode: %s, pathname: %s", + ind + 1, addr1, addr2, perm, offset, dev, inode, pathname); + + // 使用临时变量解析地址 + unsigned long tmp_addr_start_ul, tmp_addr_end_ul; + if (sscanf(addr1, "%lx", &tmp_addr_start_ul) != 1) { + LOGI("Failed to parse addr_start at line %d", ind + 1); + free(tmp); + continue; + } + if (sscanf(addr2, "%lx", &tmp_addr_end_ul) != 1) { + LOGI("Failed to parse addr_end at line %d", ind + 1); + free(tmp); + continue; + } + LOGI("Parsed addresses - addr_start: 0x%lx, addr_end: 0x%lx", tmp_addr_start_ul, tmp_addr_end_ul); + + tmp->addr_start = (void*)tmp_addr_start_ul; + tmp->addr_end = (void*)tmp_addr_end_ul; + + // size + tmp->length = (unsigned long)((char*)tmp->addr_end - (char*)tmp->addr_start); + LOGI("Calculated length: %lu", tmp->length); + + // perm + strncpy(tmp->perm, perm, sizeof(tmp->perm) - 1); + tmp->perm[sizeof(tmp->perm) - 1] = '\0'; + tmp->is_r = (perm[0] == 'r'); + tmp->is_w = (perm[1] == 'w'); + tmp->is_x = (perm[2] == 'x'); + tmp->is_p = (perm[3] == 'p'); + LOGI("Permissions - is_r: %d, is_w: %d, is_x: %d, is_p: %d", tmp->is_r, tmp->is_w, tmp->is_x, tmp->is_p); + + // offset + if (sscanf(offset, "%lx", &tmp->offset) != 1) { + LOGI("Failed to parse offset at line %d", ind + 1); + free(tmp); + continue; + } + LOGI("Parsed offset: 0x%lx", tmp->offset); + + // device + strncpy(tmp->dev, dev, sizeof(tmp->dev) - 1); + tmp->dev[sizeof(tmp->dev) - 1] = '\0'; + LOGI("Device: %s", tmp->dev); + + // inode + tmp->inode = atoi(inode); + LOGI("Inode: %d", tmp->inode); + + // pathname + strncpy(tmp->pathname, pathname, sizeof(tmp->pathname) - 1); + tmp->pathname[sizeof(tmp->pathname) - 1] = '\0'; + LOGI("Pathname: %s", tmp->pathname); + + tmp->next = NULL; + + // 连接节点到链表 + if(ind == 0){ + list_maps = tmp; + current_node = list_maps; + LOGI("Initialized list_maps with first node: %p", list_maps); + } + else{ + current_node->next = tmp; + current_node = tmp; + LOGI("Appended node to list_maps: %p", tmp); + } + ind++; + } + + if (ferror(file)) { + LOGI("Error occurred while reading the maps file"); + // 释放已分配的节点和 maps_it + procmaps_struct* iter = list_maps; + while (iter) { + procmaps_struct* next = iter->next; + free(iter); + iter = next; + } + fclose(file); + free(maps_it); + return NULL; + } + + // 关闭文件 fclose(file); + LOGI("Closed maps file: %s", maps_path); - - //g_last_head=list_maps; + // 设置迭代器 maps_it->head = list_maps; - maps_it->current = list_maps; + maps_it->current = list_maps; + LOGI("Initialized procmaps_iterator - head: %p, current: %p", maps_it->head, maps_it->current); + return maps_it; } - procmaps_struct* pmparser_next(procmaps_iterator* p_procmaps_it){ if(p_procmaps_it->current == NULL) return NULL;