Linux編程--地址計(jì)算

背景

在學(xué)習(xí)Matrix的ELF Hook的過程中,發(fā)現(xiàn)在查找Library基址指針的時(shí)候,對(duì)于指針的運(yùn)算有一些疑惑,特此記錄。

問題描述

在獲取Library的基址時(shí),有如下代碼:

    // 添加b模式因?yàn)樗荁inary文件,如果不添加則無法打開
    FILE *maps_file = fopen(maps_path, "rbe");
    char maps_line[512];
    // fgets函數(shù)可以讀取maps_line的大小或者是遇到\n停止,即讀一行數(shù)據(jù)
    while (fgets(maps_line, sizeof(maps_line) - 1, maps_file) != nullptr) {
        // 獲取第一個(gè)出現(xiàn)`-`位置的字符串
        char *first_bar_pos = strchr(maps_line, '-');
        // 計(jì)算maps中的地址大小
        auto addr_size = (unsigned int) (first_bar_pos - (char *) maps_line);
        // 計(jì)算該P(yáng)age的權(quán)限位
        char * privbits = first_bar_pos + addr_size 
                +1/* barchar itself*/
                +1/* space before privbit*/;
        // 如果當(dāng)前內(nèi)存頁不可讀,也不可執(zhí)行的話,也就意味著不是我們要找的ELF文件的內(nèi)存地址
        if (privbits[0] != 'r' || privbits[2] != 'x') {
            continue;
        }
    }

在計(jì)算addr_size的時(shí)候,使用的兩個(gè)(char *)的減進(jìn)行運(yùn)算,為何能得到地址的大小?而且獲取到privbits有什么用?

日志與截圖

首先看一下maps里面的內(nèi)容:

$cat /proc/self/maps
5da215f000-5da21a3000 r-xp 00000000 fd:01 128                            /vendor/bin/sh
5da21a3000-5da21a5000 r--p 00043000 fd:01 128                            /vendor/bin/sh
5da21a5000-5da21a6000 rw-p 00045000 fd:01 128                            /vendor/bin/sh
5da21a6000-5da21a7000 rw-p 00000000 00:00 0 
7ac0a00000-7ac0e00000 rw-p 00000000 00:00 0                              [anon:libc_malloc]
7ac0f06000-7ac0f26000 r--s 00000000 00:10 3324                           /dev/__properties__/u:object_r:default_prop:s0
7ac0f26000-7ac0f27000 rw-p 00000000 00:00 0                              [anon:linker_alloc_vector]
7ac0f28000-7ac1000000 r-xp 00000000 fd:01 4761                           /vendor/lib64/libc++.so
7ac1000000-7ac1008000 r--p 000d7000 fd:01 4761                           /vendor/lib64/libc++.so
7ac1008000-7ac1009000 rw-p 000df000 fd:01 4761                           /vendor/lib64/libc++.so
7ac1009000-7ac100c000 rw-p 00000000 00:00 0                              [anon:.bss]
7ac100c000-7ac10c8000 r-xp 00000000 fd:00 3463                           /system/lib64/libc.so
7ac10c8000-7ac10c9000 ---p 00000000 00:00 0 
7ac10c9000-7ac10cf000 r--p 000bc000 fd:00 3463                           /system/lib64/libc.so
7ac10cf000-7ac10d1000 rw-p 000c2000 fd:00 3463                           /system/lib64/libc.so

在本地運(yùn)行后,打印的日志如下,:

first_bar_pos:549218901232
maps_line:549218901222
maps_line:5da215f000-5da21a3000 r-xp 00000000 fd:01 128                            /vendor/bin/sh
first_bar_pos:      -5da21a3000 r-xp 00000000 fd:01 128                            /vendor/bin/sh
addr_size = 10

正好addr_size = maps_line - first_bar_pos。

first_bar_posmaps_line則這是上面兩個(gè)字符串的地址,那么這兩個(gè)地址相減,就是5da215f000字符串的大小,正好是10個(gè)字節(jié)。

所以就認(rèn)為計(jì)算出來的地址長度為10。而對(duì)于字符char而言,一個(gè)字符占一個(gè)字節(jié),所以也就是10個(gè)字節(jié)。

privbits

相應(yīng)的,在獲取到addr_size的大小之后,通過first_bar_pos+addr_size+1+1,獲取到的字符數(shù)組首地址指向的就是r-xp這一段文本了。所以,根據(jù)該權(quán)限標(biāo)志位來判斷該內(nèi)存頁是否可讀,可執(zhí)行

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容