-
-
[求助] 想在lsp内实现soinfo断链 处理失败
-
发表于:
2025-4-24 14:19
2326
-
[求助] 想在lsp内实现soinfo断链 处理失败
评论区指点了
在Riru里面有demo 大家可以学习一下
能读取到so_name 但无法断链 不知道哪出问题 求大佬指点
void *read_pointer(void *addr) {
return *(void **) addr;
}
uint64_t read_ulong(void *addr) {
return *(uint64_t *) addr;
}
char *read_utf8_string(void *addr) {
char *str = *(char **) addr;
return str ? strdup(str) : nullptr;
}
void *getSoInfoHead() {
void *handle = xdl_open(GetLinkerPath(), XDL_DEFAULT);
void *address = xdl_dsym(handle, "__dl__ZL6solist", nullptr);
return read_pointer(address);
}
// 定义 soinfo 结构体
typedef struct soinfo soinfo_t;
struct soinfo {
void *soinfo_addr; // 结构地址
void *phdr; // 程序头
void *base; // 基地址
uint64_t size; // 大小
void *dynamic; // 动态段
void *_next; // 下一个 soinfo 地址
char *strtab; // 字符串表
void *symtab; // 符号表
void *plt_rela; // PLT 重定位表
uint64_t plt_rela_count; // PLT 重定位计数
void *rela; // 重定位表
uint64_t rela_count; // 重定位计数
void *init_array; // 初始化数组
uint64_t init_array_count; // 初始化数组计数
void *fini_array; // 终止数组
uint64_t fini_array_count; // 终止数组计数
void *init_func; // 初始化函数
void *fini_func; // 终止函数
struct {
void *l_addr; // 链接映射地址
char *l_name; // 链接映射名称
} link_map_head; // 链接映射头
void *load_bias; // 加载偏移
void *handle_; // 句柄
};
soinfo_t *parse_soinfo(void *soinfo_addr) {
auto *info = (soinfo_t *) malloc(sizeof(soinfo_t));
if (!info) return nullptr;
info->soinfo_addr = soinfo_addr;
info->phdr = read_pointer(soinfo_addr);
info->base = read_pointer((char *) soinfo_addr + 16);
info->size = read_ulong((char *) soinfo_addr + 24);
info->dynamic = read_pointer((char *) soinfo_addr + 32);
info->_next = (char *) soinfo_addr + 40;
info->strtab = read_utf8_string((char *) soinfo_addr + 56);
info->symtab = read_pointer((char *) soinfo_addr + 64);
info->plt_rela = read_pointer((char *) soinfo_addr + 104);
info->plt_rela_count = read_ulong((char *) soinfo_addr + 112);
info->rela = read_pointer((char *) soinfo_addr + 120);
info->rela_count = read_ulong((char *) soinfo_addr + 128);
info->init_array = read_pointer((char *) soinfo_addr + 152);
info->init_array_count = read_ulong((char *) soinfo_addr + 160);
info->fini_array = read_pointer((char *) soinfo_addr + 168);
info->fini_array_count = read_ulong((char *) soinfo_addr + 176);
info->init_func = read_pointer((char *) soinfo_addr + 184);
info->fini_func = read_pointer((char *) soinfo_addr + 192);
info->link_map_head.l_addr = (char *) soinfo_addr + 208;
info->link_map_head.l_name = read_utf8_string((char *) soinfo_addr + 216);
info->load_bias = read_pointer((char *) soinfo_addr + 248);
info->handle_ = read_pointer((char *) soinfo_addr + 420);
return info;
}
soinfo_t *next(soinfo_t *self) {
return parse_soinfo(read_pointer(self->_next));
}
int memory_protect(void *addr, size_t len, const char *perms) {
if (!addr || len == 0) {
LOGE("Invalid address or length\n");
return -1;
}
// 解析权限字符串
int prot = 0;
if (strchr(perms, 'r')) prot |= PROT_READ;
if (strchr(perms, 'w')) prot |= PROT_WRITE;
if (strchr(perms, 'x')) prot |= PROT_EXEC;
// 调用 mprotect
if (mprotect(addr, len, prot) == -1) {
LOGE("mprotect error\n");
return -1;
}
return 0;
}
// 这里获取是因为下面的跳转逻辑出错 想着调用系统方法进行删除 实则还是不行
typedef bool (*SolistRemoveSoinfoFunc)(soinfo *);
void *handle = xdl_open(GetLinkerPath(), XDL_DEFAULT);
void *func_address = xdl_dsym(handle, "__dl__Z20solist_remove_soinfoP6soinfo", nullptr);
soinfo_t *soInfo = parse_soinfo(getSoInfoHead());
while (true) {
char *realPath;
soinfo_t *_soInfo;
try {
_soInfo = next(soInfo);
} catch (...) {
break;
}
realPath = _soInfo->link_map_head.l_name;
if (strstr(realPath, "zygisk_lsposed")) {
// 抹掉前64位
memory_protect(_soInfo->base, 64, "rw-");
memset(_soInfo->base, 0xFF, 64);
memory_protect(_soInfo->base, 64, "r--");
soinfo_t *_soInfo_;
try {
_soInfo_ = next(_soInfo);
} catch (...) {
// 这里要创建一个空的指针 因为可能扫到soinfo末尾
}
LOGD("prev %s", soInfo->link_map_head.l_name);
LOGD("find %s", _soInfo->link_map_head.l_name);
LOGD("next find %s", _soInfo_->link_map_head.l_name);
// 下面这种方式 不管用
// uintptr_t current_value = *(uintptr_t *) soInfo->_next;
// LOGE("%p - %p - %p", soInfo->_next, current_value, _soInfo_->soinfo_addr);
// memory_protect(soInfo->_next, 8, "rw-");
// *(uintptr_t *) soInfo->_next = (uintptr_t ) _soInfo_->soinfo_addr;
// current_value = *(uintptr_t *) soInfo->_next;
// LOGE("%p - %p - %p", soInfo->_next, current_value, _soInfo_->soinfo_addr);
// memory_protect(soInfo->_next, 8, "r--");
// 然后想通过直接调用系统方法的方式进行处理 也失败
auto so_list_remove_soinfo = reinterpret_cast<SolistRemoveSoinfoFunc>(func_address);
so_list_remove_soinfo(soInfo);
break;
}
soInfo = _soInfo;
}
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
最后于 2025-4-29 09:28
被肉蚌葱鸡编辑
,原因: