欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

[原创]适配古河大佬的注入工具到 AndroidN+

[原创]适配古河大佬的注入工具到 AndroidN+

原注入工具 https://bbs.pediy.com/thread-141355.htm

做了两个改动:

1. 获取目标进程中dlopen等函数地址时,先获取下导出该函数的模块名称,原代码是默认dlxxxx函数通过linker导出,有极少设备是libdl.so或libc.so

原代码:

int inject_remote_process(...) {

    ...

    dlopen_addr = get_remote_addr( target_pid, linker_path, (void *)dlopen );

    dlsym_addr = get_remote_addr( target_pid, linker_path, (void *)dlsym );

    dlclose_addr = get_remote_addr( target_pid, linker_path, (void *)dlclose );

    ...

}

修改后代码:

int inject_remote_process(...) {

    ...

    dlopen_addr = get_remote_addr(target_pid, (void *)dlopen);

    dlsym_addr = get_remote_addr(target_pid, (void *)dlsym );

    dlclose_addr = get_remote_addr(target_pid, (void *)dlclose);

    dlerror_addr = get_remote_addr(target_pid, (void *)dlerror);

    ...

}

void* get_remote_addr(pid_t target_pid, void* local_addr) {

    ...

    get_module_path((unsigned long)local_addr, module_path);

    local_handle = get_module_base(-1, module_path);

    remote_handle = get_module_base(target_pid, module_path);

    ...

}


2. androidN以上设备对dlopen的使用有权限检查,可以使用另外一个函数加载so,代码如下:

static void init_dlopen_ext_offset() {

    FILE *fp = NULL;

    if (!(fp = fopen(linker_path, "rb")))  {

        DEBUG_PRINT("[init_dlopen_ext_offset]Unable to open %s\n", linker_path);

        return;

    }

    fseek(fp, 0, SEEK_END);

    int size = ftell(fp);

    fseek(fp, 0, SEEK_SET);

    char *buffer = (char*)malloc(size);

    if (fread(buffer, 1, size, fp) != size) {

        DEBUG_PRINT("fread error\n");

        return;

    }

    fclose(fp);

    unsigned long symstr_off = 0, symtab_off = 0, symtab_size = 0;

    unsigned long symtab_entsize = 0, symtab_count = 0;

    const elf_header_t* eh  = (elf_header_t*)buffer;

    const elf_sheader_t* esh = (elf_sheader_t*)(buffer + eh->shoff);

    char* section_str = esh[eh->shstrndx].sh_offset + buffer;

    for (int i = 0; i < eh->shnum; i++) {

        char* sname = esh[i].sh_name + section_str;

        if (strcmp(sname, ".symtab") == 0) {

            symtab_off = esh[i].sh_offset; 

            symtab_size = esh[i].sh_size;

            symtab_entsize = esh[i].sh_entsize;

            symtab_count = symtab_size / symtab_entsize;

            DEBUG_PRINT("[init_dlopen_ext_offset]: symtab offset = %lx, count=%lx, index= %d\n", 

                symtab_off, symtab_count, i);

        }

        if (strcmp(sname, ".strtab") == 0) {

            symstr_off = esh[i].sh_offset;

            DEBUG_PRINT("[init_dlopen_ext_offset] symstr offset = %lx, index = %d\n", symstr_off, i);

        }

    }

    if(!symtab_off) {

        DEBUG_PRINT("[init_dlopen_ext_offset] can't find symtab from sections\n");

    }

    elf_sym_t* edt = (elf_sym_t*)(buffer + symtab_off);

    const char* name_dlopen_ext_N = "__dl__ZL10dlopen_extPKciPK17android_dlextinfoPv";

    const char* name_dlopen_ext_O = "__dl__ZL10dlopen_extPKciPK17android_dlextinfoPKv";

    const char* name_dlopen_ext_P = "__dl___loader_android_dlopen_ext";

    for(int i = 0 ; i < symtab_count; i++) {

        uint8_t st_type = ELF32_ST_TYPE(edt[i].info);

        char* st_name = buffer + symstr_off + edt[i].name;

        // DEBUG_PRINT("[init_dlopen_ext_offset] walk sym name:%s, value:%x\n", st_name, edt[i].value);

        if (st_type == STT_FUNC && edt[i].size) {

            if(strcmp(st_name, name_dlopen_ext_N) == 0) {

                dlopen_ext_offset = edt[i].value;

                DEBUG_PRINT("[init_dlopen_ext_offset] find dlopen_ext_N: %x\n", dlopen_ext_offset);

                break;

            }

            else if (strcmp(st_name, name_dlopen_ext_O) == 0) {

                dlopen_ext_offset = edt[i].value;

                DEBUG_PRINT("[init_dlopen_ext_offset] find dlopen_ext_O: %x\n", dlopen_ext_offset);

                break;

            }

            else if (strcmp(st_name, name_dlopen_ext_P) == 0) {

                dlopen_ext_offset = edt[i].value;

                DEBUG_PRINT("[init_dlopen_ext_offset] find dlopen_ext_P: %x\n", dlopen_ext_offset);

                break;

            }

        }

    }

    free(buffer);

}


完整代码:https://github.com/longpoxin/inject_dex

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功