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

隨筆 - 74, 文章 - 0, 評論 - 26, 引用 - 0
數據加載中……

(轉)Windows應用程序捆綁核心編程

1.3  虛擬內存訪問

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

1.3.1  獲取系統信息

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

l           

void GetSystemInfo(LPSYSTEM_INFO lpSystemInfo);

l           

其中lpSystemInfo返回LPSYSTEM_INFO結構的地址,用于裝載適當的系統信息,這個結構體定義為:

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           

其中參數含義如下所述。

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

wProcessorArchitecture:指明處理的結構,如Intel、Alpha、Intel 64位或Alpha       64位。

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

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

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

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

dwNumberOfProcessors:計算機中CPU的數目。

dwProcessorType:處理器類型。

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

wProcessorLevel:進一步細分處理器的結構。

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

wReserved:保留供將來使用。

在以上參數中只有lpMinimumApplicationAddress、lpMaximumApplicationAddress、dwPageSize和dwAllocationGranularity與內存有關。

1.3.2  在應用程序中使用虛擬內存

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

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

l           

LPVOID VirtualAlloc(

    LPVOID lpAddress,

    DWORD dwSize,

    DWORD flAllocationType,

    DWORD flProtect

    );

l           

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

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

l           

BOOL VirtualFree(

    LPVOID lpAddress,

    DWORD dwSize,

    DWORD dwFreeType

    );

l           

其中參數含義如下所述。

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

dwSize:指定了要釋放的地址空間區域的大小,如果參數dwFreeType指定了MEM_RELEASE標志,則將dwSize設置為0,由系統計算在特定內存地址上的待釋放區域的大小。

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

如果VirtualFree()執行完成,將回收全部范圍的已分配頁面,此后如再對這些已釋  放頁面區域內存進行訪問將引發內存訪問異常。釋放后的頁面區域可供系統繼續分配   使用。

1.3.3  獲取虛存狀態

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

l           

void GlobalMemoryStatus(LPMEMORYSTATUS lpmstMemStat);

l           

其中lpmstMemStat返回MEMORYSTATUS結構的地址,這個結構體的定義為:

l           

typedef struct MEMORYSTATUS{

    DWORD dwLength;

    DWORD dwMemoryLoad;        

    DWORD dwTotalPhys;

    DWORD dwAvailPhys;

    DWORD dwTotalPageFile;

    DWORD dwAvailPageFile;

    DWORD dwTotalVirtual;

    DWORD dwAvailVirtual; 

} MEMORYSTATUS ,* LPMEMORYSTATUS;

l           

其中參數含義如下所述。

dwLength:MEMORYSTATUS結構大小。

dwMemoryLoad:已使用內存所占的百分比。

dwTotalPhys:物理存儲器的總字節數。

dwAvailPhys:空閑物理存儲器的字節數。

dwTotalPageFile:頁文件包含的最大字節數。

dwAvailPageFile:用戶模式分區中空閑內存大小。

dwTotalVirtual:用戶模式分區大小。

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

在調用GlobalMemoryStatus()之前,必須將dwLength成員初始化為用字節表示的結構的大小,即一個MEMORYSTATUS結構的大小。這個初始化操作使得Microsoft能夠在新版本Windows系統中將新成員添加到這個結構中,而不會破壞現有的應用程序。當調用GlobalMemoryStatus()時,它將對該結構的其余成員進行初始化并返回。

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

l           

BOOL GlobalMemoryStatusEx(MEMORYSTATUSEX  &mst);

l           

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

1.3.4  確定虛擬地址空間的狀態

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

l           

DWORD VirtualQuery(

    LPVOID lpAddress,     

    PMEMORY_BASIC_INFORMATION lpBuffer,

    DWORD dwLength

    );

l           

VirtualQueryEx()函數原型如下:

l           

DWORD VirtualQueryEx(

    HANDLE hProcess ,

    LPCVOID lpAddress ,

    PMEMORY_BASIC_INFORMATION lpBuffer ,

    DWORD dwLength

    );

l           

其中參數含義如下所述。

hProcess:進程的句柄。

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

lpBuffer:返回MEMORY_ BASIC_INFORMATION結構的地址。

dwLength:返回的字節數。

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           

其中參數含義如下所述。

BaseAddress:被查詢內存塊的基地址。

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

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

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

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

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

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

1.3.5  改變內存頁面保護屬性

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

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

BOOL VirtualProtect(

    PVOID pvAddress,

    DWORD dwSize,

    DWORD flNewProtect,

    PDWORD pflOldProtect

    );

l           

VirtualProtectEx()函數原型如下:

l           

BOOL VirtualProtectEx(

    HANDLE hProcess,

    PVOID pvAddress,

    DWORD dwSize,

    DWORD flNewProtect,

    PDWORD pflOldProtect

    );

l           

其中參數的含義如下所述。

hProcess:要修改內存的進程句柄。

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

dwSize:用于指明想要改變保護屬性的字節數。

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

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

1.3.6  進行一個進程的內存讀寫

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

l           

BOOL ReadProcessMemory(

    HANDLE hProcess,

    LPCVOID lpBaseAddress,

    LPVOID lpBuffer,

    DWORD nSize, 

    LPDWORD lpNumberOfBytesRead

    );

l           

其中hProcess為要讀入的進程句柄,lpBaseAddress為讀內存的起始地址,lpBuffer為讀入數據的地址,nSize為要讀入的字節數,lpNumberOfBytesRead為實際讀入的字   節數。

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

l           

BOOL WriteProcessMemory(

    HANDLE hProcess,

    LPVOID lpBaseAddress,

    LPVOID lpBuffer,

    DWORD nSize,

    LPDWORD lpNumberOfBytesWritten

    );

l           

其中參數hProcess為要寫入的進程句柄,lpBaseAddress為寫內存的起始地址,lpBuffer為寫入數據的地址,nSize為要寫入的字節數,lpNumberOfBytesWritten為實際寫入的字節數。

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>
            亚洲一区在线观看免费观看电影高清| 久久精品二区亚洲w码| 亚洲欧美日韩国产一区| 亚洲精品四区| 一区二区久久| 午夜在线a亚洲v天堂网2018| 亚洲欧美日韩成人高清在线一区| 欧美自拍偷拍| 欧美69视频| 国产精品久久久久aaaa樱花| 国产麻豆91精品| 在线 亚洲欧美在线综合一区| 1024国产精品| 香蕉久久夜色精品| 欧美顶级少妇做爰| 午夜精品免费| 欧美激情偷拍| 在线日韩av| 欧美伊人久久久久久久久影院| 乱码第一页成人| 亚洲欧美在线视频观看| 欧美精品一区三区| 91久久精品美女高潮| 久久av老司机精品网站导航| 亚洲激情成人| 欧美在线观看天堂一区二区三区| 亚洲影院在线观看| 99re6这里只有精品视频在线观看| 久久精品在线观看| 国产精品一区二区久久| 中文国产成人精品| 亚洲精品日韩综合观看成人91| 久久在线视频在线| 国产中文一区二区| 老司机67194精品线观看| 久久gogo国模裸体人体| 国产一区二区丝袜高跟鞋图片| 香蕉乱码成人久久天堂爱免费| 一本一本a久久| 国产精品伦一区| 久久精品视频免费观看| 久久久久免费视频| 久久综合999| 亚洲国产日韩欧美在线动漫| 亚洲国产精品ⅴa在线观看| 欧美人成在线视频| 久久动漫亚洲| 欧美激情欧美激情在线五月| 亚洲一二三级电影| 久久久久9999亚洲精品| 亚洲免费不卡| 欧美一级大片在线观看| 亚洲精品一区在线观看香蕉| 亚洲自拍偷拍网址| 在线视频中文亚洲| 欧美风情在线观看| 久久综合色播五月| 国产精品亚洲第一区在线暖暖韩国| 玖玖在线精品| 狠狠色综合网站久久久久久久| 99在线热播精品免费| 亚洲人线精品午夜| 免费在线国产精品| 亚洲国产高清在线观看视频| 国产一区二区三区四区五区美女| 亚洲桃色在线一区| 香蕉成人伊视频在线观看| 欧美视频在线观看一区| 91久久精品国产91久久性色| 亚洲另类自拍| 欧美另类综合| 亚洲视频一区二区| 久久av二区| 黑人一区二区| 欧美日本在线视频| 亚洲午夜免费福利视频| 午夜在线一区二区| 激情久久久久久久久久久久久久久久| 久久精品国产一区二区三区| 国产日本精品| 久久久久久噜噜噜久久久精品| 欧美大片第1页| 亚洲香蕉在线观看| 国产欧美日韩在线观看| 久久九九久久九九| 亚洲毛片在线| 久久精品男女| 日韩亚洲视频| 国内精品模特av私拍在线观看| 久久香蕉国产线看观看av| 一本一本久久a久久精品综合妖精| 欧美一区二区久久久| 亚洲国产精品成人精品| 国产精品久久久久久久久| 久久人人97超碰国产公开结果 | 欧美第十八页| 亚洲午夜一区二区| 在线观看日韩av电影| 国产精品扒开腿爽爽爽视频| 久久不射2019中文字幕| 中文在线不卡视频| 亚洲日本欧美天堂| 欧美电影在线| 亚洲福利视频免费观看| 久久午夜精品| 久久久国产精品亚洲一区 | 亚洲欧美久久| 在线亚洲+欧美+日本专区| 亚洲国产日韩一区二区| 一区二区在线观看视频| 国产主播一区二区| 亚洲国产精品激情在线观看| 一本高清dvd不卡在线观看| 欧美大胆成人| 亚洲精品婷婷| 亚洲午夜视频在线| 性欧美在线看片a免费观看| 亚洲图片你懂的| 久久精品免费看| 久久一本综合频道| 欧美精品成人91久久久久久久| 久久人人97超碰国产公开结果 | 亚洲欧美日产图| 久久久久国产一区二区三区| 裸体一区二区| 一区二区三区视频观看| 亚洲——在线| 欧美精品成人一区二区在线观看 | 亚洲男人的天堂在线aⅴ视频| 欧美一区二区免费视频| 你懂的国产精品| 国产精品久久久久久模特| 尤物yw午夜国产精品视频| 99精品99| 欧美电影免费观看高清完整版| 亚洲午夜av电影| 欧美片在线观看| 最新日韩在线| 蜜臀99久久精品久久久久久软件| 亚洲欧洲一区二区三区久久| 欧美一区二区三区在线观看视频| 欧美福利视频在线| 在线播放国产一区中文字幕剧情欧美| 亚洲一二三区视频在线观看| 91久久夜色精品国产九色| 狼人天天伊人久久| 极品少妇一区二区三区精品视频| 亚洲自拍偷拍色片视频| 91久久精品美女高潮| 久久综合中文色婷婷| 久久福利精品| 亚洲国产成人一区| 欧美黄色免费网站| 欧美日韩国产综合视频在线| 中国亚洲黄色| 久久国产精品高清| 在线日本高清免费不卡| 欧美福利一区二区| 欧美日韩一区二区三区在线| 亚洲天堂成人在线视频| 亚洲欧美亚洲| 亚洲欧洲精品一区二区| 亚洲免费激情| 一区久久精品| 99精品热视频| 国产一区二区剧情av在线| 欧美激情按摩在线| 国产精品大全| 亚洲国产精品热久久| 国产精品成人va在线观看| 欧美成人综合一区| 国产精品一区二区久久久| 欧美激情一区二区三区| 国产精品久久久久一区二区| 嫩草国产精品入口| 国产日产亚洲精品| 夜夜躁日日躁狠狠久久88av| 亚洲人体偷拍| 欧美成人精品一区二区三区| 久久久久久999| 国产日韩精品在线观看| 99综合电影在线视频| 99热精品在线| 欧美精品色一区二区三区| 美女任你摸久久| 国产一区二区三区在线观看精品| 亚洲一二三区精品| 亚洲欧美日韩精品在线| 国产精品毛片a∨一区二区三区| 亚洲欧洲精品一区二区三区不卡 | 国产九九精品| 国产精品99久久99久久久二8 | 免费成人在线观看视频| 国产日韩精品一区二区浪潮av | 99综合在线| 欧美性猛交xxxx免费看久久久 | 99re热精品| 亚洲一区精彩视频| 国产精品自拍在线| 久久免费黄色|