• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

               C++ 技術中心

               :: 首頁 :: 聯系 ::  :: 管理
              160 Posts :: 0 Stories :: 87 Comments :: 0 Trackbacks

            公告

            鄭重聲明:本BLOG所發表的原創文章,作者保留一切權利。必須經過作者本人同意后方可轉載,并注名作者(天空)和出處(CppBlog.com)。作者Email:coder@luckcoder.com

            留言簿(27)

            搜索

            •  

            最新隨筆

            最新評論

            評論排行榜

            mprotect: 設置內存訪問權限

            mmap 的第三個參數指定對內存區域的保護,由標記讀、寫、執行權限的 PROT_READ、PROT_WRITE 和 PROT_EXEC 按位與操作獲得,或者是限制沒有訪問權限的 PROT_NONE。如果程序嘗試在不允許這些權限的本地內存上操作,它將被 SIGSEGV 信號(Segmentation fault,段錯誤)終止。

            在內存映射完成后,這些權限仍可以被 mprotect 系統調用所修改。mprotect 的參數分別為內存區間的地址,區間的大小,新的保護標志設置。所指定的內存區間必須包含整個頁:區間地址必須和整個系統頁大小對齊,而區間長度必須是頁大小的整數倍。這些頁的保護標記被這里指定的新保護模式替換。

            獲得頁面對齊的內存
            應注意的是, malloc 返回的內存區域通常并不與內存頁面對齊,甚至在內存的大小是頁大小整數倍的情況下也一樣。如果您想保護從 malloc 獲得的內存,您不得不分配一個更大的內存區域并在其中找到一個與頁對齊的區間。
            您可以選擇使用 mmap 系統調用來繞過 malloc 并直接從 Linux 內核中分配頁面對齊內存。

            mmap通過映射 /dev/zero 來分配內存頁。內存將被初始化為可讀和可寫模式。

            int fd = open (“/dev/zero”, O_RDONLY);
            char* memory = mmap (NULL, page_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
            close (fd);
            

            然后,您的程序可以使用 mprotect 把它變成只讀:

            mprotect (memory, page_size, PROT_READ);
            

            有一種監控內存訪問的高級技巧,可以通過利用 mmap 和 mprotect 保護目標內存區間,然后當程序訪問時候接收并處理 Linux 系統發送的 SIGSEGV 信號。代碼 展示了這個技巧。

            代碼使用mprotect檢測內存訪問

            #include <fcntl.h>
            #include <signal.h>
            #include <stdio.h>
            #include <string.h>
            #include <sys/mman.h>
            #include <sys/stat.h>
            #include <sys/types.h>
            #include <unistd.h>
            
            static int alloc_size;
            static char* memory;
            
            void segv_handler (int signal_number)
            {
              printf (“memory accessed!\n”);
              mprotect (memory, alloc_size, PROT_READ | PROT_WRITE);
            }
            
            int main ()
            {
              int fd;
              struct sigaction sa;
            
              /* 初始化segv_handler為SIGSEGV的句柄。*/
              memset (&sa, 0, sizeof (sa));
              sa.sa_handler = &segv_handler;
              sigaction (SIGSEGV, &sa, NULL);
            
              /* 使用映射/dev/zero分配內存頁。最初映射的內存為只寫。*/
              alloc_size = getpagesize ();
              fd = open (“/dev/zero”, O_RDONLY);
              memory = mmap (NULL, alloc_size, PROT_WRITE, MAP_PRIVATE, fd, 0);
              close (fd);
              /* 寫頁來獲得一個私有復制。 */
              memory[0] = 0;
              /* 使內存為不可寫。 */
              mprotect (memory, alloc_size, PROT_NONE);
            
              /* 寫分配內存區域。 */
              memory[0] = 1;
              /* 所有工作都結束;unmap內存映射。 */
              printf (“all done\n”);
              munmap (memory, alloc_size);
            
              return 0;
            }
            

            上述程序按照如下步驟執行:

            1. 程序為 SIGSEGV 建立一個信號處理句柄。
            2. 程序通過映射 /dev/zero 分配一個內存分頁,然后通過寫入數據的方式獲得一個私有復本。
            3. 程序通過調用帶 PROT_NONE 權限的 mprotect 保護了內存。
            4. 當程序在后續執行中寫入內存時,Linux 向進程發送 SIGSEGV,這個信號被 segv_handler 句柄接收處理。這個句柄將解除內存保護,因而程序內存訪問得以繼續。
            5. 當信號句柄執行完成時,程序控制權返回 main 函數,程序將使用 munmap 來釋放內存。
            posted on 2013-06-27 10:05 C++技術中心 閱讀(3355) 評論(0)  編輯 收藏 引用 所屬分類: Linux 編程
            久久天天躁狠狠躁夜夜2020一| 天天躁日日躁狠狠久久 | 久久精品国产WWW456C0M| 精品无码久久久久久久久久| 日本国产精品久久| 久久精品国产亚洲77777| 狠狠精品久久久无码中文字幕| 亚洲伊人久久综合影院| 精品亚洲综合久久中文字幕| 久久亚洲中文字幕精品一区四| 亚洲午夜无码久久久久| 国产精品丝袜久久久久久不卡| 亚洲AV无码久久精品狠狠爱浪潮| 久久精品国产福利国产琪琪| 午夜天堂av天堂久久久| 久久国产精品免费一区二区三区| 久久亚洲精精品中文字幕| 国产毛片久久久久久国产毛片 | 久久综合久久久| 狠狠色婷婷久久一区二区| 久久久久黑人强伦姧人妻| 国产成人久久精品区一区二区| 精品久久久无码21p发布| 久久久久99精品成人片三人毛片 | 99久久精品国产一区二区三区| 亚洲va国产va天堂va久久| 亚洲国产婷婷香蕉久久久久久| 久久精品一区二区影院| 日韩一区二区久久久久久| 久久九九精品99国产精品| 久久久久亚洲av成人网人人软件| 久久久久亚洲AV成人网人人软件| 欧美一区二区精品久久| 18岁日韩内射颜射午夜久久成人| 狠狠色婷婷久久一区二区三区| 蜜臀av性久久久久蜜臀aⅴ| 伊人久久综合无码成人网| 五月丁香综合激情六月久久 | 国产精品99久久久久久董美香| 精品蜜臀久久久久99网站| 久久精品国内一区二区三区|