1. 通過軟件 hexedit
sudo hexedit /dev/mem
必須用管理員權限,這樣可以訪問到物理內存了,是不是很帥?
2. 程序編碼訪問物理地址
一、先補充一下基礎知識
1.打開設備文件: mem是一個字符設備文件,是計算機主存的一個映像。通常只有root用戶對其有讀寫權限。因此只有root用戶能進行這些操作。 如果要打開設備文件/dev/mem,需要系統調用open()函數,作用是打開一個文件或設備,其函數原型爲: int open(const char *path, int flags); 返回值:如果操作成功則返回一個文件描述符,否則返回-1 形 參: path 被打開文件的路徑即文件名描述。 flags 文件的訪問模式描述,可常用的選項見下: O_RDONLY 只讀方式 O_WRONLY 只寫方式 O_RDWR 可讀寫方式 說 明:此函數用於打開文件或者設備 頭文件:#include <fcntl.h> #include <stat.h> 定義在/usr/include/fcntl.h中 2.讀取內存映像: 內存映像其實在內存中創建一個與外存中文件完全相同的映像。用戶可以將整個文件映射到內存中,也可以將文件的一部分映射到內存中。 使用操作內存的方法對文件進行操作。系統會將內存映像文件所做的改動反映到真實文件中去。 在內存映像I/O的實現過程中需要用到一些系統調用: 首先是創建內存映像文件的系統調用mmap()函數,其函數原型爲: void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset); 返回值:成功時,返回值爲指向內存映像起始地址的指針,當調用失敗時,返回值爲-1 形 參: start 一個void指針,表示希望將文件映射到此指針指向的位置,通常爲NULL。 length 定義內存映像文件所佔用的內存空間大小,以字節計。 prot 內存映像文件的安全屬性,注意和open函數中的flags屬性保持一致。它的可使用的選項如下: Flags 含義 PROT_EXEC 被映像內存可能含義機器碼,可被執行 PROT_NONE 映像內存不允許訪問 PROT_READ 映像內存可讀 PROT_WRITE 映像內存可寫 flags 內存映像的標誌,選項如下: Flags 含義 MAP_FIXED 指定映射起始地址,如果由start和len指定的內存區重疊於現存的映射空間,重疊部分將會被丟棄。 如果指定的起始地址不可用,操作將會失敗。並且起始地址必須落在頁的邊界上。 MAP_SHARED 與其它所有映射這個對象的進程共享映射空間。對共享區的寫入,相當於輸出到文件。 直到msync()或者munmap()被調用,文件實際上不會被更新。 MAP_PRIVATE 建立一個寫入時拷貝的私有映射。內存區域的寫入不會影響到原文件。 這個標誌和以上標誌是互斥的,只能使用其中一個。 MAP_NORESERVE 不要爲這個映射保留交換空間。當交換空間被保留,對映射區修改的可能會得到保證。 當交換空間不被保留,同時內存不足,對映射區的修改會引起段違例信號。 MAP_LOCKED 鎖定映射區的頁面,從而防止頁面被交換出內存。 MAP_GROWSDOWN 用於堆棧,告訴內核VM系統,映射區可以向下擴展。 MAP_ANONYMOUS 匿名映射,映射區不與任何文件關聯。 MAP_ANON MAP_ANONYMOUS的別稱,不再被使用。 MAP_FILE 兼容標誌,被忽略。 MAP_32BIT 將映射區放在進程地址空間的低2GB,MAP_FIXED指定時會被忽略。 當前這個標誌只在x86-64平臺上得到支持。 MAP_POPULATE 爲文件映射通過預讀的方式準備好頁表。隨後對映射區的訪問不會被頁違例阻塞。 MAP_NONBLOCK 僅和MAP_POPULATE一起使用時纔有意義。不執行預讀,只爲已存在於內存中的頁面建立頁表入口。 fd 要映射的文件的描述符。 offset 所映射的數據內容 距離文件頭的偏移量。 說 明:此函數用於將一個文件或它的一部分映射到內存中。 頭文件:#include <sys/mman.h> #include <sys/types.h> 函數定義在/usr/include/sys/mman.h 3.撤銷內存映像的修改 另外我們使用完內存映像文件後,要用系統調用函數munmap()函數來撤銷,其函數原型爲: int munmap(void *start, size_t length); 返回值:成功時,返回值爲0;調用失敗時返回值爲 -1,並將errno設置爲相應值。 形 參: start 要撤銷的內存映像文件的起始地址。 length 要撤銷的內存映像文件的大小。 說 明:當進程結束或利用exec相關函數來執行其他程序時,映射內存會自動解除,但關閉對應的文件描述詞時不會解除映射。 頭文件:#include <sys/mman.h> 4.將內存映像的改動保存到外存中 最後,如果我們要將內存映像的改動保存到外存中,還需要系統調用msync()函數,其函數原型爲: int msync(const void *start,size_t length,int flags); 返回值:成功時,返回值爲0;調用失敗時返回值爲 -1,並將errno設置爲相應值。 形 參: start 要保存到外存的那些源文件的起始地址。 length 表示內存映像文件的大小。 flags 設置了函數的相應操作,其具體選項如下: Flags 含義 MS_ASYNC 調用一個寫操作並返回 MS_INVALIDATE 映像到相同文件的內存映像數據更新 MS_SYNC 完成寫操作後函數返回 說 明:進程在映射空間的對共享內容的改變並不直接寫回到磁盤文件中,往往在調用munmap()後才執行該操作。 可以通過調用msync()函數來實現磁盤文件內容與共享內存區中的內容一致,即同步操作。 頭文件:#include <sys/mman.h> 5.通過/dev/mem設備文件和mmap系統調用,可以將線性地址描述的物理內存映射到進程的地址空間,然後就可以直接訪問這段內存了。
接下來看一個小程序: