从android进程内存中读取.so文件

时间:2017-04-27 15:11:14

标签: android android-ndk java-native-interface native android-memory

我正在尝试从android进程内存中读取所有.so文件并将其存储在地图中供以后使用。虽然,下面的代码片段适用于所有非root用户设备,但它不适用于root的android 7设备,Nexus 6。 " m_modules"地图总是空的。但是,当我运行" cat / proc / self / maps"在adb shell中,它显示了.so文件的内存映射。 有人可以帮助我。

Android中使用的原生代码段:

bool elf_hooker::phrase_proc_maps()
{

    m_modules.clear();
    FILE* fd = fopen("/proc/self/maps", "r");
    if (fd != NULL) {
    char buff[2048+1];
    while(fgets(buff, 2048, fd) != NULL) {
        const char *sep = "\t \r\n";
        char *line = NULL;
        char* addr = strtok_r(buff, sep, &line);
        if (!addr) {
            continue;
        }

        char *flags = strtok_r(NULL, sep, &line);
        if (!flags || flags[0] != 'r' || flags[3] == 's') {

            //log_info("######## FIRST CRASHING IF ********************");
            //
            /*
                1. mem section cound NOT be read, without 'r' flag.
                2. read from base addr of /dev/mail module would crash.
                   i dont know how to handle it, just skip it.

                   1f5573000-1f58f7000 rw-s 1f5573000 00:0c 6287 /dev/mali0

            */
            continue;
        }
        strtok_r(NULL, sep, &line);  // offsets
        char *dev = strtok_r(NULL, sep, &line);  // dev number.
        int major = 0, minor = 0;
        if (!phrase_dev_num(dev, &major, &minor) || major == 0) {

            //log_info("######## SECOND CRASHING IF ********************");
            /*
                if dev major number equal to 0, mean the module must NOT be
                a shared or executable object loaded from disk.
                e.g:
                lookup symbol from [vdso] would crash.
                7f7b48a000-7f7b48c000 r-xp 00000000 00:00 0  [vdso]
            */
            continue;
        }

        strtok_r(NULL, sep, &line);  // node

        char* filename = strtok_r(NULL, sep, &line); //module name
        if (!filename) {
            continue;
        }
        std::string module_name = filename;
        std::map<std::string, elf_module>::iterator itor = m_modules.find(module_name);
        if (itor == m_modules.end() &&
                !(in_exception_list(module_name.substr(module_name.find_last_of("/\\") + 1)))) {
            void* base_addr = NULL;
            void* end_addr = NULL;
            if (phrase_proc_base_addr(addr, &base_addr, &end_addr) && elf_module::is_elf_module(base_addr)) {
                elf_module module(reinterpret_cast<ElfW(Addr)>
                (base_addr), module_name.c_str());
                m_modules.insert(std::pair<std::string, elf_module>(module_name, module));
            }
        }
    }
    fclose(fd);
    return 0;

}

return -1;

}

助手功能:

bool elf_hooker::phrase_proc_base_addr(char* addr, void** pbase_addr, void** 
pend_addr)
{
char* split = strchr(addr, '-');
if (split != NULL) {
    if (pbase_addr != NULL) {
        *pbase_addr = (void *) strtoul(addr, NULL, 16);
    }
    if (pend_addr != NULL) {
        *pend_addr = (void *) strtoul(split + 1, NULL, 16);
    }
    return true;
}
return false;
}

bool elf_hooker::phrase_dev_num(char* devno, int *pmajor, int *pminor)
{
*pmajor = 0;
*pminor = 0;
if (devno != NULL && strlen(devno) == 5 && devno[2] == ':') {
    *pmajor = strtoul(devno + 0, NULL, 16);
    *pminor = strtoul(devno + 3, NULL, 16);
    return true;
}
return false;
}

adb shell显示&#34; cat / proc / self / maps /&#34; :

enter image description here

0 个答案:

没有答案