-
函數原型
int mprotect(void *addr, size_t len, int prot);
-
頭文件
#include <sys/mman.h> #include <unistd.h>
-
描述
control the protection of pages.
The mprotect() system call changes the specified pages to have protection prot. When a program violates the protections of a page, it gets a SIGBUS or SIGSEGV signal.
主要是用來修改一段指定內存區域的保護屬性。
使用mprotect這裏最重要的一點是被保護的內存是按頁對齊的,範圍也是按頁來的。這是因爲Linux管理進程地址空間是一VMA(Virtual Memory Area)爲單位來管理進程虛擬地址空間的,而VMA必須是page size大小的整數倍。
-
參數
PROT_NONE No permissions at all. PROT_READ The pages can be read. PROT_WRITE The pages can be written. PROT_EXEC The pages can be executed.
-
返回值
Upon successful completion, a value of 0 is returned. Otherwise, a value of -1 is returned and errno is set to indicate the error.
常見的錯誤有:
-
EACCES
該內存不能設置爲相應權限。這是可能發生的,比如,如果你 mmap(2) 映射一個文件爲只讀的,接着使用 mprotect() 標誌爲 PROT_WRITE。
-
EINVAL
start 不是一個有效的指針,指向的不是某個內存頁的開頭。
-
ENOMEM
內核內部的結構體無法分配。
-
-
舉個例子,修改虛函數表
#include <stdio.h> #include <unistd.h> #include <sys/mman.h> void print() { printf("print\n"); } class Base { public: virtual void print(){ printf("Base::print\n"); } }; void changeVtable() { Base base; void** vtable= *(void***)&base; // 獲取頁大小 unsigned long pagesize = sysconf(_SC_PAGE_SIZE); // 內存按頁對齊 void* align_page_addr = reinterpret_cast<void*>(reinterpret_cast<unsigned long>(&vtable[0]) & (~(pagesize-1))); // 修改權限 int ret = mprotect(align_page_addr, pagesize, PROT_READ | PROT_WRITE | PROT_EXEC); if(ret != 0) { printf("mprotect error\n"); return; } // 修改虛函數表內容 vtable[0] = reinterpret_cast<void*>(print); } int main() { Base* pbase = new Base(); Base base; printf("%p\n",print); printf("%p\n",reinterpret_cast<void*>(**(void***)(&base))); printf("%p\n",reinterpret_cast<void*>(**(void***)(pbase))); print(); base.print(); pbase->print(); changeVtable(); printf("%p\n",print); printf("%p\n",reinterpret_cast<void*>(**(void***)(&base))); printf("%p\n",reinterpret_cast<void*>(**(void***)(pbase))); print(); base.print(); pbase->print(); delete pbase; return 0; }
輸出結果爲:
0x10f7f1cd0 0x10f7f1ee0 0x10f7f1ee0 print Base::print Base::print 0x10f7f1cd0 0x10f7f1cd0 0x10f7f1cd0 print Base::print print
注意虛函數的調用時刻。
Linux mprotect函數 -- control the protection of pages
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.