1. 程式人生 > >Android7.0對dlopen的改變

Android7.0對dlopen的改變

tail 地址 npr and eof size strtok log brush

兩個內存段

在同一個進程空間中dlopen一個.so文件,理論上在內存中是同一片區域,但實際調試中發現Android7.0(read "/proc/self/maps")中,先後讀同一個.so內存中居然出現兩個段!

這在低版本Android(比如4.x)中不曾出現。

如下一些blog中分析,與Android7.0對dlopen的改寫有關,可能是不同命名空間下讀取結果不一樣,可能是對安全性的提升。

Android 7.0 行為變更

NDK 應用鏈接至平臺庫

技術分享

Android 7.0 dlopen的不同

7.0對已加載.so的引用/Hook

由於以上分析,自己的代碼中dlopen的.so文件與目標程序中加載的.so在不同內存段中,故不能直接Hook,要想方法拿到目標程序加載的.so的內存地址。

可以用base_addr + offset得到目標方法的地址,base_addr通過查找 “/proc/self/maps” 得到

//這個方法來自 android inject 用於獲取地址
    void* get_module_base(int pid, const char* module_name)
{
    FILE *fp;
    long addr = 0;
    char *pch;
    char filename[32];
    char line[1024];
    if (pid < 0) {
        /* self process */
        snprintf(filename, sizeof(filename), "/proc/self/maps", pid);
    }
    else {
        snprintf(filename, sizeof(filename), "/proc/%d/maps", pid);
    }
    fp = fopen(filename, "r");
    if (fp != NULL) {
        while (fgets(line, sizeof(line), fp)) {
            if (strstr(line, module_name)) {
                pch = strtok(line, "-");
                addr = strtoul(pch, NULL, 16);

                if (addr == 0x8000)
                    addr = 0;

                break;
            }
        }
        fclose(fp);
    }
    return (void *)addr;
}

參考blog:

如何hook dlopen和dlsym底層函數  

Android7.0對dlopen的改變