VC宣告
LPVOID VirtualAlloc(
LPVOID lpAddress, // region to reserve or commit
SIZE_T dwSize, // size of region
DWORD flAllocationType, // type of allocation
DWORD flProtect // type of access protection
);
[編輯本段]
說明
該函式的功能是在呼叫程序的虛地址空間,預定或者提交一部分頁
如果用於記憶體分配的話,並且分配型別未指定MEM_RESET,則系統將自動設定為0;
引數表說明
LPVOID lpAddress, 分配記憶體區域的地址。當你使用VirtualAlloc來提交一塊以前保留的記憶體塊的時候,lpAddress引數可以用來識別以前保留的記憶體塊。如果這個引數是NULL,系統將會決定分配記憶體區域的位置,並且按64-KB向上取整(roundup)。
SIZE_T dwSize, 要分配或者保留的區域的大小。這個引數以位元組為單位,而不是頁,系統會根據這個大小一直分配到下頁的邊界DWORD
flAllocationType, 分配型別 ,你可以指定或者合併以下標誌:MEM_COMMIT,MEM_AUTO_COMMIT,MEM_RESERVE和MEM_TOP_DOWN。
DWORD flProtect 指定了被分配區域的訪問保護方式
分配型別 功能
MEM_COMMIT 在記憶體或者指定的磁碟頁檔案(虛擬記憶體檔案)中分配一物理儲存區域 函式初始化這個區域為0
MEM_PHYSICAL 該型別必須和MEM_RESERVE一起使用 分配一塊具有讀寫功能的物理記憶體區
MEM_RESERVE 保留虛擬地址空間以便以後提交。
MEM_RESET
MEM_TOP_DOWN 告訴系統從最高可允許的虛擬地址開始對映應用程式。
MEM_WRITE_WATCH
訪問型別
PAGE_READONLY 該區域為只讀。如果應用程式試圖訪問區域中的頁的時候,將會被拒絕訪問PAGE_READWRITE 區域可被應用程式讀寫
PAGE_EXECUTE 區域包含可被系統執行的程式碼。試圖讀寫該區域的操作將被拒絕。
PAGE_EXECUTE_READ 區域包含可執行程式碼,應用程式可以讀該區域。
PAGE_EXECUTE_READWRITE 區域包含可執行程式碼,應用程式可以讀寫該區域。
PAGE_GUARD 區域第一次被訪問時進入一個STATUS_GUARD_PAGE異常,這個標誌要和其他保護標誌合併使用,表明區域被第一次訪問的許可權
PAGE_NOACCESS 任何訪問該區域的操作將被拒絕
PAGE_NOCACHE RAM中的頁對映到該區域時將不會被微處理器快取(cached)
注:PAGE_GUARD和PAGE_NOCHACHE標誌可以和其他標誌合併使用以進一步指定頁的特徵。PAGE_GUARD標誌指定了一個防護頁(guard page),即當一個頁被提交時會因第一次被訪問而產生一個one-shot異常,接著取得指定的訪問許可權。PAGE_NOCACHE防止當它對映到虛擬頁的時候被微處理器快取。這個標誌方便裝置驅動使用直接記憶體訪問方式(DMA)來共享記憶體塊。
返回值
如果呼叫成功,返回分配的首地址,
呼叫失敗,返回NULL 你可以透過GetLastError函式來獲取錯誤資訊
筆記
VirtualAlloc可以透過並行多次呼叫提交一個區域的部分或全部來保留一個大的記憶體區域。多重呼叫提交同一塊區域不會引起失敗。這使得一個應用程式保留記憶體後可以隨意提交將被寫的頁。當這種方式不在有效的時候,它會釋放應用程式透過檢測被保留頁的狀態看它是否在提交呼叫之前已經被提交
例子:
#include
void main()
{
SYSTEM_INFO sf;
GetSystemInfo(&sf);
//分配記憶體,標記為提交、可讀可寫
LPVOID lpvBase = VirtualAlloc(
NULL, // system selects address
4096, // size of allocation
MEM_COMMIT, // allocate reserved pages
PAGE_READWRITE); // protection = no access
if (lpvBase == NULL )
return;
//向該記憶體裡面寫些東西
unsigned char *ustr=(unsigned char *)lpvBase;
ustr[0]=0x89;
//修改為“只讀”屬性,驗證是否能寫入
DWORD dw;
VirtualProtect(lpvBase,4096,PAGE_READONLY,&dw);
// ustr[0]=0x44; //失敗
//修改為“不可訪問”,驗證是否能讀出
VirtualProtect(lpvBase,4096,PAGE_NOACCESS,&dw);
// dw = ustr[0]; //失敗
}
VC宣告
LPVOID VirtualAlloc(
LPVOID lpAddress, // region to reserve or commit
SIZE_T dwSize, // size of region
DWORD flAllocationType, // type of allocation
DWORD flProtect // type of access protection
);
[編輯本段]
說明
該函式的功能是在呼叫程序的虛地址空間,預定或者提交一部分頁
如果用於記憶體分配的話,並且分配型別未指定MEM_RESET,則系統將自動設定為0;
[編輯本段]
引數表說明
LPVOID lpAddress, 分配記憶體區域的地址。當你使用VirtualAlloc來提交一塊以前保留的記憶體塊的時候,lpAddress引數可以用來識別以前保留的記憶體塊。如果這個引數是NULL,系統將會決定分配記憶體區域的位置,並且按64-KB向上取整(roundup)。
SIZE_T dwSize, 要分配或者保留的區域的大小。這個引數以位元組為單位,而不是頁,系統會根據這個大小一直分配到下頁的邊界DWORD
flAllocationType, 分配型別 ,你可以指定或者合併以下標誌:MEM_COMMIT,MEM_AUTO_COMMIT,MEM_RESERVE和MEM_TOP_DOWN。
DWORD flProtect 指定了被分配區域的訪問保護方式
分配型別 功能
MEM_COMMIT 在記憶體或者指定的磁碟頁檔案(虛擬記憶體檔案)中分配一物理儲存區域 函式初始化這個區域為0
MEM_PHYSICAL 該型別必須和MEM_RESERVE一起使用 分配一塊具有讀寫功能的物理記憶體區
MEM_RESERVE 保留虛擬地址空間以便以後提交。
MEM_RESET
MEM_TOP_DOWN 告訴系統從最高可允許的虛擬地址開始對映應用程式。
MEM_WRITE_WATCH
訪問型別
PAGE_READONLY 該區域為只讀。如果應用程式試圖訪問區域中的頁的時候,將會被拒絕訪問PAGE_READWRITE 區域可被應用程式讀寫
PAGE_EXECUTE 區域包含可被系統執行的程式碼。試圖讀寫該區域的操作將被拒絕。
PAGE_EXECUTE_READ 區域包含可執行程式碼,應用程式可以讀該區域。
PAGE_EXECUTE_READWRITE 區域包含可執行程式碼,應用程式可以讀寫該區域。
PAGE_GUARD 區域第一次被訪問時進入一個STATUS_GUARD_PAGE異常,這個標誌要和其他保護標誌合併使用,表明區域被第一次訪問的許可權
PAGE_NOACCESS 任何訪問該區域的操作將被拒絕
PAGE_NOCACHE RAM中的頁對映到該區域時將不會被微處理器快取(cached)
注:PAGE_GUARD和PAGE_NOCHACHE標誌可以和其他標誌合併使用以進一步指定頁的特徵。PAGE_GUARD標誌指定了一個防護頁(guard page),即當一個頁被提交時會因第一次被訪問而產生一個one-shot異常,接著取得指定的訪問許可權。PAGE_NOCACHE防止當它對映到虛擬頁的時候被微處理器快取。這個標誌方便裝置驅動使用直接記憶體訪問方式(DMA)來共享記憶體塊。
[編輯本段]
返回值
如果呼叫成功,返回分配的首地址,
呼叫失敗,返回NULL 你可以透過GetLastError函式來獲取錯誤資訊
[編輯本段]
筆記
VirtualAlloc可以透過並行多次呼叫提交一個區域的部分或全部來保留一個大的記憶體區域。多重呼叫提交同一塊區域不會引起失敗。這使得一個應用程式保留記憶體後可以隨意提交將被寫的頁。當這種方式不在有效的時候,它會釋放應用程式透過檢測被保留頁的狀態看它是否在提交呼叫之前已經被提交
例子:
#include
void main()
{
SYSTEM_INFO sf;
GetSystemInfo(&sf);
//分配記憶體,標記為提交、可讀可寫
LPVOID lpvBase = VirtualAlloc(
NULL, // system selects address
4096, // size of allocation
MEM_COMMIT, // allocate reserved pages
PAGE_READWRITE); // protection = no access
if (lpvBase == NULL )
return;
//向該記憶體裡面寫些東西
unsigned char *ustr=(unsigned char *)lpvBase;
ustr[0]=0x89;
//修改為“只讀”屬性,驗證是否能寫入
DWORD dw;
VirtualProtect(lpvBase,4096,PAGE_READONLY,&dw);
// ustr[0]=0x44; //失敗
//修改為“不可訪問”,驗證是否能讀出
VirtualProtect(lpvBase,4096,PAGE_NOACCESS,&dw);
// dw = ustr[0]; //失敗
return;
}