青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆 - 74, 文章 - 0, 評論 - 26, 引用 - 0
數(shù)據(jù)加載中……

(轉(zhuǎn))Windows應(yīng)用程序捆綁核心編程

1.3  虛擬內(nèi)存訪問

每個進程都擁有自己的虛擬地址空間,那么怎樣才能訪問這個空間呢?這就需要用到Windows API函數(shù)。這些函數(shù)直接與編寫程序相關(guān),因而更受軟件工程師的關(guān)注。有關(guān)這方面的函數(shù)較多,這里介紹幾個重要的函數(shù)。

1.3.1  獲取系統(tǒng)信息

在一個程序中不能直接應(yīng)用某個系統(tǒng)的設(shè)備參數(shù),否則將不利于程序的移植。因此,如果確實需要用到這樣的設(shè)備參數(shù),則需要一個系統(tǒng)信息函數(shù)來獲得。VC++ 編譯器所提供這樣的函數(shù)為GetSystemInfo()。該函數(shù)需要一個指向SYSTEM_INFO結(jié)構(gòu)的指針作為參數(shù)。其原型表示為:

l           

void GetSystemInfo(LPSYSTEM_INFO lpSystemInfo);

l           

其中l(wèi)pSystemInfo返回LPSYSTEM_INFO結(jié)構(gòu)的地址,用于裝載適當?shù)南到y(tǒng)信息,這個結(jié)構(gòu)體定義為:

l           

typedef struct _SYSTEM_INFO { 

    union {   

        DWORD dwOemId;   

        struct {     

            WORD wProcessorArchitecture;      

            WORD wReserved;   

        };

    }; 

   

    DWORD  dwPageSize; 

    LPVOID  lpMinimumApplicationAddress; 

    LPVOID  lpMaximumApplicationAddress; 

    DWORD_PTR  dwActiveProcessorMask; 

    DWORD  dwNumberOfProcessors; 

    DWORD  dwProcessorType; 

    DWORD  dwAllocationGranularity; 

    WORD   wProcessorLevel; 

    WORD   wProcessorRevision;

} SYSTEM_INFO;

l           

其中參數(shù)含義如下所述。

dwOemId:是一個過時選項,用于與Windows NT 3.5以及以前的版本兼容。

wProcessorArchitecture:指明處理的結(jié)構(gòu),如Intel、Alpha、Intel 64位或Alpha       64位。

dwPageSize:用于顯示CPU的頁面大小。在x86 CPU上,這個值是4096字節(jié)。在Alpha CPU上,這個值是8192字節(jié)。在IA-64上,這個值是8192字節(jié)。

lpMinimumApplicationAddress:用于給出每個進程可用地址空間的最小內(nèi)存地址。在Windows 98上,這個值是0x400000,因為每個進程的地址空間中下面的4MB是不能使用的。在Windows 2K/XP上,這個值是0x10000,因為每個進程的地址空間中開頭的64KB總是空閑的。

lpMaximumApplicationAddress:用于給出每個進程可用地址空間的最大內(nèi)存地址。在Windows 98上,這個地址是0x7FFFFFFF,因為共享內(nèi)存映射文件區(qū)域和共享操作系統(tǒng)代碼包含在上面的2GB分區(qū)中。在Windows XP上,這個地址是0x7FFEFFFF。

dwActiveProcessorMask:位屏蔽,指明哪個CPU是活動的。

dwNumberOfProcessors:計算機中CPU的數(shù)目。

dwProcessorType:處理器類型。

dwAllocationGranularity:保留的地址空間區(qū)域的分配粒度。

wProcessorLevel:進一步細分處理器的結(jié)構(gòu)。

wProcessorRevision:用于進一步細分處理器的級別。

wReserved:保留供將來使用。

在以上參數(shù)中只有l(wèi)pMinimumApplicationAddress、lpMaximumApplicationAddress、dwPageSize和dwAllocationGranularity與內(nèi)存有關(guān)。

1.3.2  在應(yīng)用程序中使用虛擬內(nèi)存

對內(nèi)存分配可以采用不同的方法,常用的方法有:用C/C++語言的內(nèi)存分配函數(shù),例如,用malloc() 和 free()、new 和 delete 函數(shù)分配和釋放堆內(nèi)存;用Windows傳統(tǒng)的全局或者局部內(nèi)存分配函數(shù),如GlobalAlloc()和GlobalFree();用Win32的堆分配函數(shù),如HeapAlloc()和HeapFree();用Win32的虛擬內(nèi)存分配函數(shù),如VirtualAlloc()和VirtualFree()。注意,用不同的方法分配內(nèi)存后,要用相對應(yīng)的函數(shù)來釋放所占用的內(nèi)存。這里只介紹Win32的虛擬內(nèi)存分配函數(shù)。

在進程創(chuàng)建之初并被賦予地址空間時,其虛擬地址空間尚未分配,處于空閑狀態(tài)。這時地址空間內(nèi)的內(nèi)存是不能使用的,必須通過VirtualAlloc()函數(shù)來分配其中的各個區(qū)域,對其進行保留。VirtualAlloc()函數(shù)原型為:

l           

LPVOID VirtualAlloc(

    LPVOID lpAddress,

    DWORD dwSize,

    DWORD flAllocationType,

    DWORD flProtect

    );

l           

該函數(shù)用來分配一定范圍的虛擬頁。參數(shù)1指定起始地址;參數(shù)2指定分配內(nèi)存的長度;參數(shù)3指定分配方式,取值MEM_COMMINT或者MEM_RESERVE;參數(shù)4指定控制訪問本次分配的內(nèi)存的標識,取值為PAGE_READONLY、PAGE_READWRITE或者PAGE_NOACCESS。

分配完成后,即在進程的虛擬地址空間中保留了一個區(qū)域,可以對此區(qū)域中的內(nèi)存進行保護權(quán)限許可范圍內(nèi)的訪問。當不再需要訪問此地址空間區(qū)域時,應(yīng)釋放此區(qū)域,由VirtualFree()負責完成。其函數(shù)原型為:

l           

BOOL VirtualFree(

    LPVOID lpAddress,

    DWORD dwSize,

    DWORD dwFreeType

    );

l           

其中參數(shù)含義如下所述。

lpAddress:指向待釋放頁面區(qū)域的指針。如果參數(shù)dwFreeType指定了MEM_RELEASE,則lpAddress必須為頁面區(qū)域保留由VirtualAlloc()所返回的基地址。

dwSize:指定了要釋放的地址空間區(qū)域的大小,如果參數(shù)dwFreeType指定了MEM_RELEASE標志,則將dwSize設(shè)置為0,由系統(tǒng)計算在特定內(nèi)存地址上的待釋放區(qū)域的大小。

dwFreeType:為所執(zhí)行的釋放操作的類型,其可能的取值為MEM_RELEASE和MEM_DECOMMIT,其中MEM_RELEASE標志指明要釋放指定的保留頁面區(qū)域,MEM_DECOMMIT標志則對指定的占用頁面區(qū)域進行占用的解除。

如果VirtualFree()執(zhí)行完成,將回收全部范圍的已分配頁面,此后如再對這些已釋  放頁面區(qū)域內(nèi)存進行訪問將引發(fā)內(nèi)存訪問異常。釋放后的頁面區(qū)域可供系統(tǒng)繼續(xù)分配   使用。

1.3.3  獲取虛存狀態(tài)

Windows API函數(shù)GlobalMemoryStatus()可用于檢索關(guān)于當前內(nèi)存狀態(tài)的動態(tài)信息。在軟件的About對話框中,通常用這個函數(shù)來獲取系統(tǒng)內(nèi)存的使用情況。其函數(shù)原型為:

l           

void GlobalMemoryStatus(LPMEMORYSTATUS lpmstMemStat);

l           

其中l(wèi)pmstMemStat返回MEMORYSTATUS結(jié)構(gòu)的地址,這個結(jié)構(gòu)體的定義為:

l           

typedef struct MEMORYSTATUS{

    DWORD dwLength;

    DWORD dwMemoryLoad;        

    DWORD dwTotalPhys;

    DWORD dwAvailPhys;

    DWORD dwTotalPageFile;

    DWORD dwAvailPageFile;

    DWORD dwTotalVirtual;

    DWORD dwAvailVirtual; 

} MEMORYSTATUS ,* LPMEMORYSTATUS;

l           

其中參數(shù)含義如下所述。

dwLength:MEMORYSTATUS結(jié)構(gòu)大小。

dwMemoryLoad:已使用內(nèi)存所占的百分比。

dwTotalPhys:物理存儲器的總字節(jié)數(shù)。

dwAvailPhys:空閑物理存儲器的字節(jié)數(shù)。

dwTotalPageFile:頁文件包含的最大字節(jié)數(shù)。

dwAvailPageFile:用戶模式分區(qū)中空閑內(nèi)存大小。

dwTotalVirtual:用戶模式分區(qū)大小。

dwAvailVirtual:表示當前進程中還剩下的自由區(qū)域的總和。

在調(diào)用GlobalMemoryStatus()之前,必須將dwLength成員初始化為用字節(jié)表示的結(jié)構(gòu)的大小,即一個MEMORYSTATUS結(jié)構(gòu)的大小。這個初始化操作使得Microsoft能夠在新版本W(wǎng)indows系統(tǒng)中將新成員添加到這個結(jié)構(gòu)中,而不會破壞現(xiàn)有的應(yīng)用程序。當調(diào)用GlobalMemoryStatus()時,它將對該結(jié)構(gòu)的其余成員進行初始化并返回。

如果某個應(yīng)用程序在內(nèi)存大于4GB的計算機上運行,或者合計交換文件的大小大于4GB,那么可以使用新的GlobalMemoryStatusEx()函數(shù)。其函數(shù)的原型為:

l           

BOOL GlobalMemoryStatusEx(MEMORYSTATUSEX  &mst);

l           

其中mst返回MEMORYSTATUSEX結(jié)構(gòu)的填充信息,該結(jié)構(gòu)體與原先的MEMORYSTATUS結(jié)構(gòu)基本相同,差別在于新結(jié)構(gòu)的所有成員的大小都是64位寬,因此它的值可以大于4 GB。

1.3.4  確定虛擬地址空間的狀態(tài)

對內(nèi)存的管理除了對當前內(nèi)存的使用狀態(tài)信息進行獲取外,還經(jīng)常需要獲取有關(guān)進程的虛擬地址空間的狀態(tài)信息。例如,如何得到一個進程已提交的頁面范圍?這就要用到兩個 API函數(shù)VirtualQuery()或VirtualQueryEx()來進行查詢。這兩個函數(shù)的功能相似,不同就是VirtualQuery()只是查詢本進程內(nèi)存空間信息,而VirtualQueryEx()可以查詢指定進程的內(nèi)存空間信息。VirtualQuery()函數(shù)原型如下:

l           

DWORD VirtualQuery(

    LPVOID lpAddress,     

    PMEMORY_BASIC_INFORMATION lpBuffer,

    DWORD dwLength

    );

l           

VirtualQueryEx()函數(shù)原型如下:

l           

DWORD VirtualQueryEx(

    HANDLE hProcess ,

    LPCVOID lpAddress ,

    PMEMORY_BASIC_INFORMATION lpBuffer ,

    DWORD dwLength

    );

l           

其中參數(shù)含義如下所述。

hProcess:進程的句柄。

lpAddress:想要了解其信息的虛存地址。

lpBuffer:返回MEMORY_ BASIC_INFORMATION結(jié)構(gòu)的地址。

dwLength:返回的字節(jié)數(shù)。

PWEMORY_BASIC_INFORMATION的定義如下:

l           

typedef struct _MEMORY_BASIC_INFORMATION{

    PVOID BaseAddress;  

    PVOID AllocationBase;

    DWORD AllocationProtect;

    DWORD RegionSize;

    DWORD State;

    DWORD Protect;

    DWORD Type;

} MEMORY_BASIC_INFORMATION, * PMEMORY_BASIC_INFORMATION;

l           

其中參數(shù)含義如下所述。

BaseAddress:被查詢內(nèi)存塊的基地址。

AllocationBase:用VirtualAlloc()分配該內(nèi)存時實際分配的基地址。

AllocationProtect:分配該頁面時,頁面的一些屬性,如PAGE_READWRITE、PAGE_EXECUTE等(其他屬性可參考 Platform SDK)。

RegionSize:從BaseAddress開始,具有相同屬性的頁面的大小。

State:頁面的狀態(tài),有3種可能值:MEM_COMMIT、MEM_FREE和MEM_ RESERVE,這個參數(shù)是最重要的,從中可知指定內(nèi)存頁面的狀態(tài)。

Protect:頁面的屬性,它可能的取值與 AllocationProtect 相同。

Type:指明了該內(nèi)存塊的類型,有3種可能值:MEM_IMAGE、MEM_MAPPED和MEM_PRIVATE。

1.3.5  改變內(nèi)存頁面保護屬性

在進行進程掛鉤時,經(jīng)常要向內(nèi)存頁中寫入部分代碼,這就需要改變內(nèi)存頁的保護屬性。有幸的是Win32提供了兩個API函數(shù)VirtualProtect()和VirtualProtectEx(),它們可以對改變內(nèi)存頁保護。例如,在使用這兩個函數(shù)時,可以先按PAGE_READWRITE屬性來提交一個頁的地址,并且立即將數(shù)據(jù)填寫到該頁中,然后再把該頁的屬性改變?yōu)镻AGE_READONLY,這樣可以有效地保護數(shù)據(jù)不被該進程中的任何其他線程重寫。在調(diào)用這兩個函數(shù)之前最好先了解有關(guān)頁面的信息,可以通過VirtualQuery()來實現(xiàn)。

VirtualProtect()與VirtualProtectEx()函數(shù)的區(qū)別在于VirtualProtect()只適用于本進程,而VirtualProtectEx()可以適用于其他進程。VirtualProtect()函數(shù)原型如下:

BOOL VirtualProtect(

    PVOID pvAddress,

    DWORD dwSize,

    DWORD flNewProtect,

    PDWORD pflOldProtect

    );

l           

VirtualProtectEx()函數(shù)原型如下:

l           

BOOL VirtualProtectEx(

    HANDLE hProcess,

    PVOID pvAddress,

    DWORD dwSize,

    DWORD flNewProtect,

    PDWORD pflOldProtect

    );

l           

其中參數(shù)的含義如下所述。

hProcess:要修改內(nèi)存的進程句柄。

pvAddress:指向內(nèi)存的基地址(它必須位于進程的用戶方式分區(qū)中)。

dwSize:用于指明想要改變保護屬性的字節(jié)數(shù)。

flNewProtect:代表PAGE_*保護屬性標志中的任何一個標志,但PAGE_ WRITECOPY和PAGE_EXECUTE_WRITECOPY這兩個標志除外。

pflOldProtect:是DWORD大小的地址,VirtualProtect()和VirtualProtectEx()將用原先與pvAddress位置上的字節(jié)相關(guān)的保護屬性填入該地址。盡管許多應(yīng)用程序并不需要該信息,但是必須為該參數(shù)傳遞一個有效地址,否則該函數(shù)的運行將會失敗。

1.3.6  進行一個進程的內(nèi)存讀寫

前面已經(jīng)說明了如何獲得一個進程的內(nèi)存屬性、如何分配內(nèi)存和如何改變內(nèi)存頁的保護屬性,其最終的目的是要對一個進程中內(nèi)存內(nèi)容進行讀寫。要完成此工作,需要用到兩個函數(shù):ReadProcessMemory() 和WriteProcessMemory(),這兩個函數(shù)非常有用。如果知道了一個進程的句柄和內(nèi)存地址,就可以用ReadProcessMemory()函數(shù)來得到該進程和該地址中的內(nèi)容,此函數(shù)的原型為:

l           

BOOL ReadProcessMemory(

    HANDLE hProcess,

    LPCVOID lpBaseAddress,

    LPVOID lpBuffer,

    DWORD nSize, 

    LPDWORD lpNumberOfBytesRead

    );

l           

其中hProcess為要讀入的進程句柄,lpBaseAddress為讀內(nèi)存的起始地址,lpBuffer為讀入數(shù)據(jù)的地址,nSize為要讀入的字節(jié)數(shù),lpNumberOfBytesRead為實際讀入的字   節(jié)數(shù)。

同樣,如果知道了一個進程的句柄和內(nèi)存地址,可以用WriteProcessMemory()函數(shù)向該進程和該地址中寫入新的內(nèi)容,這個函數(shù)的原型為:

l           

BOOL WriteProcessMemory(

    HANDLE hProcess,

    LPVOID lpBaseAddress,

    LPVOID lpBuffer,

    DWORD nSize,

    LPDWORD lpNumberOfBytesWritten

    );

l           

其中參數(shù)hProcess為要寫入的進程句柄,lpBaseAddress為寫內(nèi)存的起始地址,lpBuffer為寫入數(shù)據(jù)的地址,nSize為要寫入的字節(jié)數(shù),lpNumberOfBytesWritten為實際寫入的字節(jié)數(shù)。

posted on 2007-11-15 12:40 井泉 閱讀(942) 評論(0)  編輯 收藏 引用 所屬分類: c code

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            激情久久综合| 亚洲午夜电影在线观看| 亚洲三级毛片| 国产欧美一区二区精品仙草咪| 欧美aaa级| 蜜臀av性久久久久蜜臀aⅴ四虎 | 久久精品国产一区二区三| 亚洲视频中文字幕| 中文精品视频| 欧美激情精品久久久久久大尺度| 另类欧美日韩国产在线| 欧美大片免费| 亚洲国产欧洲综合997久久| 欧美刺激午夜性久久久久久久| 免费观看日韩av| 欧美成人午夜激情| 亚洲精品免费一二三区| 一区二区三区四区国产| 一本久久精品一区二区| 亚洲在线网站| 久久久久综合网| 欧美成人午夜激情视频| 亚洲精品中文字| 亚洲综合国产| 欧美在线资源| 欧美福利电影网| 免费在线视频一区| 欧美丝袜第一区| 欧美激情中文不卡| 国产欧美日韩视频一区二区三区| 国产一区二区按摩在线观看| 亚洲国产美国国产综合一区二区| 一区二区高清视频| 久久久精品久久久久| 亚洲欧洲精品一区二区三区不卡 | 国产精品天天看| 伊人成人在线| 亚洲欧美精品一区| 欧美成人第一页| 99国产精品视频免费观看一公开| 亚洲精品国产系列| 久久国产精品网站| 欧美日韩国产美| 伊人久久亚洲影院| 亚洲精品在线免费| 99国产麻豆精品| 蜜桃av久久久亚洲精品| 亚洲人www| 久久久久久久精| 国产精品一区免费观看| 亚洲精品在线一区二区| 久久精品一区四区| 99国产精品自拍| 另类亚洲自拍| 国产亚洲精品福利| 午夜在线观看免费一区| 亚洲国产一区二区三区在线播| 99亚洲一区二区| 免费黄网站欧美| 国产亚洲欧洲997久久综合| 一区二区高清| 亚洲七七久久综合桃花剧情介绍| 久久久久国产精品一区| 免费亚洲网站| 在线观看日韩av| 久久亚洲影音av资源网| 亚洲欧美日韩在线观看a三区| 欧美日韩三级视频| 一区二区不卡在线视频 午夜欧美不卡在| 美女精品国产| 久色成人在线| 亚洲精品字幕| 亚洲电影欧美电影有声小说| 久久久久久久波多野高潮日日| 国产网站欧美日韩免费精品在线观看| 亚洲精品社区| 亚洲高清在线观看| 欧美精品日韩三级| 一个人看的www久久| 91久久精品一区二区三区| 欧美激情四色| 亚洲午夜一级| 亚洲在线网站| 国产在线高清精品| 久久久人成影片一区二区三区观看 | 亚洲免费在线播放| 国产麻豆精品theporn| 午夜精品一区二区三区在线播放| 亚洲伊人色欲综合网| 国产女人水真多18毛片18精品视频| 国产一区999| 久久在线免费视频| 美女91精品| 一本色道**综合亚洲精品蜜桃冫| 亚洲精选久久| 欧美日本国产一区| 亚洲欧美视频一区| 羞羞漫画18久久大片| 狠狠爱综合网| 欧美电影免费网站| 亚洲综合99| 亚洲午夜久久久久久久久电影网| 理论片一区二区在线| 久久伊人亚洲| 99精品99| 性做久久久久久久久| 国产麻豆综合| 欧美大尺度在线| 国产精品第2页| 鲁鲁狠狠狠7777一区二区| 欧美精品亚洲精品| 久久福利毛片| 国产精品久久一区二区三区| 亚洲电影av在线| 国内成+人亚洲| 亚洲欧美日韩国产一区二区| 亚洲天堂第二页| 欧美国产精品日韩| 欧美成人亚洲成人| 黑人巨大精品欧美黑白配亚洲| 一区二区精品| 夜夜精品视频一区二区| 欧美成人亚洲成人| 亚洲二区在线视频| 亚洲国产专区| 久久综合狠狠综合久久综合88| 久久人体大胆视频| 国产一区二区三区av电影 | 99riav国产精品| 亚洲黄一区二区| 理论片一区二区在线| 欧美国产欧美综合| 亚洲国产色一区| 免费高清在线一区| 欧美大片91| 亚洲欧洲日本专区| 欧美二区在线播放| 亚洲第一伊人| 一区二区三区黄色| 国产精品久久久久久久久借妻| 一本久久综合亚洲鲁鲁| 欧美一级视频| 狠狠色综合网站久久久久久久| 久久久青草婷婷精品综合日韩| 久久亚洲国产成人| 91久久在线视频| 欧美日韩精品免费观看| 9l视频自拍蝌蚪9l视频成人| 久久久久久成人| 国产欧美日韩在线视频| 欧美在线视频观看免费网站| 噜噜噜91成人网| 亚洲免费黄色| 欧美性片在线观看| 午夜在线不卡| 欧美高清视频一区二区三区在线观看| 亚洲精品日产精品乱码不卡| 欧美理论电影在线播放| 亚洲欧美国产精品va在线观看| 久久久蜜桃一区二区人| 亚洲精品在线三区| 国产区日韩欧美| 免费永久网站黄欧美| 国产精品99久久99久久久二8| 久久精品av麻豆的观看方式| 亚洲成人在线视频播放| 欧美日韩一级黄| 久久久成人精品| 亚洲激情偷拍| 亚洲精品一区二区三区婷婷月| 欧美日韩另类综合| 欧美一级网站| 日韩视频免费观看| 蜜臀久久久99精品久久久久久| 亚洲深夜福利网站| 黄网站免费久久| 国产精品久久久久久久久久妞妞| 久久精品男女| 一区二区高清在线观看| 欧美成人一区二区三区片免费| 午夜精品三级视频福利| 亚洲精品黄色| 激情亚洲一区二区三区四区| 欧美视频一区二区三区四区 | 国产精品久久婷婷六月丁香| 另类激情亚洲| 久久国产精品第一页| 一区二区av| 亚洲日韩欧美视频一区| 久久精品亚洲| 午夜免费电影一区在线观看| 亚洲免费av片| 在线成人免费观看| 国产日本欧美一区二区三区在线| 欧美日韩成人激情| 欧美片在线观看| 欧美黄色大片网站| 裸体丰满少妇做受久久99精品| 午夜精品一区二区三区电影天堂 | 久久国产直播|