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