mmap mprotect详解
mmap&mprotect
最近做了一道題, 竟然不讓用system和execve, 讓用mmap 和 mprotect來解決。可是身為小白萌新的我,對此一臉懵逼, 查閱相關(guān)內(nèi)容和文檔, 寫下這篇博客, 用來回顧和分享。
mmap函數(shù)
-
頭文件: <sys/mman.h>
-
函數(shù)原型:
void* mmap(void* start,size_t length,int prot,int flags,int fd,off_t offset); -
作用:
mmap將一個文件或者其它對象映射進內(nèi)存,同時設(shè)置那段內(nèi)存的屬性可讀可寫或者是可執(zhí)行。文件被映射到多個頁上,如果文件的大小不是所有頁的大小之和,最后一個頁不被使用的空間將會清零。mmap在用戶空間映射調(diào)用系統(tǒng)中作用很大。 -
條件:
mmap()必須以PAGE_SIZE為單位進行映射,而內(nèi)存也只能以頁為單位進行映射,若要映射非PAGE_SIZE整數(shù)倍的地址范圍,要先進行內(nèi)存對齊,強行以PAGE_SIZE的倍數(shù)大小進行映射。 -
參數(shù)說明:
- start:映射區(qū)的開始地址,設(shè)置為0時表示由系統(tǒng)決定映射區(qū)的起始地址。
- length:映射區(qū)的長度。//長度單位是 以字節(jié)為單位,不足一內(nèi)存頁按一內(nèi)存頁處理
- prot:期望的內(nèi)存保護標志,不能與文件的打開模式?jīng)_突。是以下的某個值,可以通過or運算合理地組合在一起
- PROT_EXEC //頁內(nèi)容可以被執(zhí)行
- PROT_READ //頁內(nèi)容可以被讀取
- PROT_WRITE //頁可以被寫入
- PROT_NONE //頁不可訪問
- flags:指定映射對象的類型,映射選項和映射頁是否可以共享。它的值可以是一個或者多個以下位的組合體
- MAP_FIXED //使用指定的映射起始地址,如果由start和len參數(shù)指定的內(nèi)存區(qū)重疊于現(xiàn)存的映射空間,重疊部分將會被丟棄。如果指定的起始地址不可用,操作將會失敗。并且起始地址必須落在頁的邊界上。
- MAP_SHARED //與其它所有映射這個對象的進程共享映射空間。對共享區(qū)的寫入,相當于輸出到文件。直到msync()或者munmap()被調(diào)用,文件實際上不會被更新。
- MAP_PRIVATE //建立一個寫入時拷貝的私有映射。內(nèi)存區(qū)域的寫入不會影響到原文件。這個標志和以上標志是互斥的,只能使用其中一個。
- MAP_DENYWRITE //這個標志被忽略。
- MAP_EXECUTABLE //同上
- MAP_NORESERVE //不要為這個映射保留交換空間。當交換空間被保留,對映射區(qū)修改的可能會得到保證。當交換空間不被保留,同時內(nèi)存不足,對映射區(qū)的修改會引起段違例信號。
- MAP_LOCKED //鎖定映射區(qū)的頁面,從而防止頁面被交換出內(nèi)存。
- MAP_GROWSDOWN //用于堆棧,告訴內(nèi)核VM系統(tǒng),映射區(qū)可以向下擴展。
- MAP_ANONYMOUS //匿名映射,映射區(qū)不與任何文件關(guān)聯(lián)。
- MAP_ANON //MAP_ANONYMOUS的別稱,不再被使用。
- MAP_FILE //兼容標志,被忽略。
- MAP_32BIT //將映射區(qū)放在進程地址空間的低2GB,MAP_FIXED指定時會被忽略。當前這個標志只在x86-64平臺上得到支持。
- MAP_POPULATE //為文件映射通過預(yù)讀的方式準備好頁表。隨后對映射區(qū)的訪問不會被頁違例阻塞。
- MAP_NONBLOCK //僅和MAP_POPULATE一起使用時才有意義。不執(zhí)行預(yù)讀,只為已存在于內(nèi)存中的頁面建立頁表入口。
- fd:有效的文件描述詞。一般是由open()函數(shù)返回,其值也可以設(shè)置為-1,此時需要指定flags參數(shù)中的MAP_ANON,表明進行的是匿名映射。
- offset:被映射對象內(nèi)容的起點。
想要更詳細的理解,請點擊
mprotect函數(shù)
- 頭文件: <unistd.h>, <sys/mmap.h>
- 函數(shù)原型:
int mprotect(const void *start, size_t len, int prot); - 作用:
可以用來修改一段指定內(nèi)存區(qū)域的保護屬性。把自start開始的、長度為len的內(nèi)存區(qū)的保護屬性修改為prot指定的值 - 參數(shù)說明:
- start:指向需要修改的地址
- len: 需要修改的長度
- prot:可以取以下幾個值,并且可以用“|”將幾個屬性合起來使用:
- PROT_READ:表示內(nèi)存段內(nèi)的內(nèi)容可寫;
- PROT_WRITE:表示內(nèi)存段內(nèi)的內(nèi)容可讀;
- PROT_EXEC:表示內(nèi)存段中的內(nèi)容可執(zhí)行;
- PROT_NONE:表示內(nèi)存段中的內(nèi)容根本沒法訪問。
總結(jié)
簡單來說mmap函數(shù)創(chuàng)建一塊內(nèi)存區(qū)域,將一個文件映射到該區(qū)域,進程可以像操作內(nèi)存一樣操作文件。mprotect函數(shù)可以改變一塊內(nèi)存區(qū)域的權(quán)限(以頁為單位),在做pwn題的時候, 通常把bss的權(quán)限改為可讀可寫可執(zhí)行,將shellcode寫入并執(zhí)行。一般來說64位下mprotect(0x600000,0x1000,7)(起始地址,長度,權(quán)限)32位下mprotect(0x804A000,0x400,7),長度都是對齊的,記住有三個參數(shù)在這里。
總結(jié)
以上是生活随笔為你收集整理的mmap mprotect详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [Jarvis OJ - PWN]——B
- 下一篇: [Jarvis OJ - PWN]——T