日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

Windows2000下用戶模式的內存掃描

瀏覽:212日期:2023-08-27 11:11:07

簡述:

本文簡要介紹了在Windows2000下實現內存掃描的基本理論和實現的辦

法。內存掃描是一項重要的技術,有相當廣泛的應用范圍:如病毒掃描、

游戲修改等。Windows2000是一個完全保護的系統,且具有兩種工作模式,

即用戶態和核心態(User Model and Kernel Model)。內存掃描也可分為

用戶態的內存掃描與核心態的內存掃描。本文主要講述的是工作于用戶態

的內存掃描。

一.相關理論

早期在Dos壞境下進行內存掃描是一件相對簡單的事情。因為DOS工作在

CPU的實模式下,沒有采用虛存技術也沒有提供內存的保護機制,只要實實

在在的掃描完所有的物理內存,一切工作也就完成了,早期有一些防毒軟

件就是用了這樣的辦法。當然為了提高效率,我們并不用掃描所有的內存

區域,因為有些空間是沒有被用到的,掃描這些地方也是只浪費時間。這

可以通過遍歷DOS系統的MCB(Memory Control Block)鏈,來得到實際內

存的使用區域,從而使掃描的效率大大提高。相似的思路在Windows2000下

的內存掃描也是適用的。

Windows2000則是一個完全保護的系統,工作于CPU的保護模式下,引入

了虛存技術。每個進程擁有獨立的4GB的地址空間,其中低的2GB為進程的私有空間,高的2GB為系統空間的映射(如果在Boot.ini文件中使用

“/3GB”的開關可以使進程的私有空間增大到3GB,系統空間1GB)。對于

每個進程來講其虛擬的地址空間是連續的,實際上它們是以頁面為單位

離 散的存在于物理內存中,一些可能被交換到硬盤上的頁面文件中,而

且還有大部分的空間是未提交(Uncommitted)的。因此在Windows2000

中對進程的用戶空間進行掃描必須依次對每個進程的空間進行掃描。一

個進程的低2GB有空間的分布如下表:

范圍

大小

作用

0x0~~ 0xFFFF

64 KB

不可訪問區域,只是用來防止非法的指針訪問,訪問該范圍的地址會導致訪問違例。

0x10000~~

0x7FFEFFFF

2 GB 減去至少 192 KB

進程的私有地址空間

0x7FFDE000~~

0x7FFDEFFF

4 KB

進程中第一個線程的線程環境塊,即 TEB ( Thread environment block )

0x7FFDF000~~ 0x7FFDFFFF

4 KB

進程的進程環境塊,即 PEB ( Process environment block )

0x7FFE0000~~

0x7FFE0FFF

4 KB

一個共享的只讀用戶數據塊,該塊映射到到系

統空間的一個數據塊,其中存放的是一些系統

信息如系統時間、時鐘的滴答數、系統版本號

等。這樣訪問這些信息的時候系統就不用切換

到核心模式。

0x7FFE1000~~

0x7FFEFFFF

60 KB

不可訪問

0x7FFF0000~~ 0x7FFFFFFF

64 KB

不可訪問,用于防止線程的緩沖跨越兩種模式

空間的邊界

表 1

二.實現 從上表可以看出,我們要掃描范圍的起點和終點不是從 0~~2GB,而只是其中的一 部分。要得到這個起點和終點可以使用API函數GetSystemInfo,函數的原型如下: VOID GetSystemInfo( LPSYSTEM_INFO lpSystemInfo // system information ); 而在結構SYSTEM_INFO中有兩個域: lpMinimumApplicationAddress 和 lpMaximumApplicationAddress (類型都是 LPVOID) 中 ,我們就可以得到一個應用程序可用的最小和最大的地址空間。這樣我們就得到了要掃描的地址的起點和終點。那么是不是這起點和終點間所有的地址都要掃描呢?并不是這樣的,因為一般情況下一個進程是用不著這么大(接近2GB)的地址空間的。因此一個進程的大部分地址空間都是未用(Free)或是保留(Reserved)的,真正用到的只是那些已提交(Committed)的內存而已。

內存頁面可以有三種狀態: 未用( Free)、保留(Reserved)和提交

(Committed)。一個未用的頁面是指該頁面未被保留或是提交,對一個進

程來講一個未用的頁面是不可訪問的,訪問這樣的頁面將導致訪問違例。

進程可以要求系統保留一些頁面以備后用,系統返回一段保留的地址給進

程,但是這些地址同樣是不可訪問的,進程若想使用這段地址空間,使用

必須先提交。只有一個提交的頁面才是一個真正可以訪問的頁面。不過你

提交了一個頁面,系統并不會馬上分配物理頁面,只有在該頁面第一次被

訪問到時,系統才會分配頁面并初始化。另外,這三個狀態的兩兩之間都

是可以相互轉化的。相關的API函數有 VirtualAlloc 、 VirtualAllocEx 、

VirtualFree 、 VirtualFreeEx 等 .

這樣我們的工作已大大減少了,只需要掃描那些提交的頁面就好了。接下來要做的就

是得到一個進程的已提交的頁面范圍。這就要用到另外兩個 API函數VirtualQuery和

VirtualQueryEx。兩個函數的功能相似,不同就是VirtualQuery只是查詢本進程而

VirtualQueryEx可以查詢指定進程的內存空間信息,后者正是我們所需要的,函數原

型如下:

DWord VirtualQueryEx(

HANDLE hProcess , // handle to process LPCVOID lpAddress , // address of region PMEMORY_BASIC_INFORMATION lpBuffer , // information buffer SIZE_T dwLength // size of buffer ); 第一個參數是進程的句柄;第二個參數是內存地址指針;第三個參數是指向 MEMORY_BASIC_INFORMATION 結構的指針,用于返回內存空間的信息;第四個參數是 lpBuffer 的長度。再來看一下結構 MEMORY_BASIC_INFORMATION 的聲明: typedef struct _MEMORY_BASIC_INFORMATION { PVOID BaseAddress ; PVOID AllocationBase ; DWORD AllocationProtect ; SIZE_T RegionSize ; DWORD State ; DWORD Protect ; DWORD Type ; } MEMORY_BASIC_INFORMATION, *PMEMORY_BASIC_INFORMATION; 第一個參數是查詢內存塊的基地址;第二個參數指的是用VirtualAlloc分配該內存時實際分配的基地址, 可以小于 BaseAddress ,也就是說 BaseAddress 一定包含在 AllocationBase 分配的范圍內;第三個參數指的是分 配該頁面時,頁面的一些屬性,如 PAGE_READWRITE、PAGE_EXECUTE 等(其它屬性 可參考 Platform SDK );第四 個參數指的是從 BaseAddress 開始,具有相同屬性的頁面的大小。第五參數指的是頁面的狀態,有三種可能值: MEM_COMMIT、MEM_FREE 和 MEM_RESERVE ,這個參數對我們來說是最重要的了,從中我們便可知指定內存頁面的狀態了; 第六個參數指的是頁面的屬性,其可能的取值與 AllocationProtect 相同;最后一個參數指明了該內存塊的類型,有三種可能值: MEM_IMAGE 、 MEM_MAPPED 和 MEM_PRIVATE 。 這樣我們就可得到進程中需要掃描的地址范圍了。到這里剩下的問題就是要讀取指定的進程的指定的地地址空間的內容了。這里要用到的是用于調試程序和錯誤處理( Debugging and Error Handling )的 API函數。在“ Platform SDK: Debugging and Error Handling” 章節中,介紹了一部分與程序調試和錯誤處理相關的 API函數,有許多是很有用,例如我們下面用到的 ReadProcessMemory 和 WriteProcessMemory, 它們原型如下: BOOL ReadProcessMemory( HANDLE hProcess , // handle to the process LPCVOID lpBaseAddress , // base of memory area LPVOID lpBuffer , // data buffer SIZE_T nSize , // number of bytes to read SIZE_T * lpNumberOfBytesRead // number of bytes read ); BOOL WriteProcessMemory( HANDLE hProcess , // handle to process LPVOID lpBaseAddress , // base of memory area LPCVOID lpBuffer , // data buffer SIZE_T nSize , // count of bytes to write SIZE_T * lpNumberOfBytesWritten // count of bytes written ); 參數很簡單從它們的名字都可以猜出其意義了,這里就不多做說明了。要說明的是 要對一個進程進行 ReadProcessMemory操作,當前進程對要讀的進程必須有PROCESS_VM_READ訪問權。要對一個進程進行WriteProcessMemory操作,當前進程對要寫的進程必須有PROCESS_VM_WRITE 和PROCESS_VM_OPERATION訪問權。要獲得一個進程的句柄和對這個進程的一些控制權可以使用API函數OpenProcess得到,其使用不做詳細說明了,只給出其原型: HANDLE OpenProcess( DWORD dwDesiredAccess , // access flag BOOL bInheritHandle , // handle inheritance option DWORD dwProcessId // process identifIEr );

這樣對一個進程的用戶地址空間內存掃描的流程基本就闡述清楚了。

三 相關的問題:

在實際操作中會遇到一些問題。如果我們指定了寫相關的訪問權(如

PROCESS_VM_WRITE 、 PROCESS_SET_INFORMATION 、 PROCESS_ALL_ACCESS 等 ),用

OpenProcess打開一些普通進程是沒什么問題,但要是打開的是系統安全進程

(如Sy stem、Winlogon、smss、csRSS、services、lsass等)或是一些注冊為

服務的進程時,就會遇到“訪問拒絕”的錯誤,這是為了系統的安全而采取的保

護手段。說明了當前的進程沒有足夠的權限來進行此操作。在進程控制結構中

有一個“訪問令牌”(Access tokens),里面包含有本進程的權限信息。一些常

用的權限如表1所示(摘自Inside Windows2000,Third Edition)。

權限名

權限含義

SeBackup

在備份的時候繞過安全檢查

SeDebug

可對一個進程進行調試

SeShutdown

可關閉本地系統

SeTakeOwnerShip

在沒有得到自由訪問權的情況下得到一個對象的所有權

表 2

要對一個任意進程(包括系統安全進程和服務進程)進行 指定了寫相 關的訪問權的 OpenProcess操作,只要當前進程具有SeDeDebug權限就 可 以了。要是一個用戶是Administrator或是被給予了相應的權限, 就可以具 有該權限。可是,就算我們用Administrator帳號對一個系統安全進程執行 OpenProcess(PROCESS_ALL_ACCESS,FALSE, dwProcessID)還是會遇到 “訪 問拒絕”的錯誤。什么原因呢?原來在默認的情況下進程的一些訪問權限 是沒有被使能( Enabled)的,所以我們要做的首先是使能這些權限。與此 相關的一些API函數有OpenProcessToken、 LookupPrivilegeValue 、 AdjustTokenPrivileges 。我們要修改一個進程的訪問令牌,首先要獲得進 程訪問令牌的句柄,這可以通過 OpenProcessToken得到,函數的原型如:

BOOL OpenProcessToken( HANDLE ProcessHandle , DWORD DesiredAccess , PHANDLE TokenHandle ); 第一參數是要修改訪問權限的進程句柄;第三個參數就是返回的訪問令牌指針;第二個參數指定你要進行的操作類型,如要修改令牌我們要指定第二個參數為 TOKEN_ADJUST_PRIVILEGES( 其它一些參數可參考 Platform SDK )。通過這個函數我們就可以得到當前進程的訪問令牌的句柄(指定函數的第一個參數為 GetCurrentProcess()就可以了)。接著我們可以調用AdjustTokenPrivileges對這個訪問令牌進行修改。AdjustTokenPrivileges的原型如下: BOOL AdjustTokenPrivileges( HANDLE TokenHandle , // handle to token BOOL DisableAllPrivileges , // disabling option PTOKEN_PRIVILEGES NewState , // privilege information DWORD BufferLength , // size of buffer PTOKEN_PRIVILEGES PreviousState , // original state buffer PDWORD ReturnLength // required buffer size );

第一個參數是訪問令牌的句柄;第二個參數決定是進行權限修改還是除能( Disable)所有權限;第三個參數指明要修改的權限,是一個指向 TOKEN_PRIVILEGES 結構的指針,該結構包含一個數組,數據組的每個項指明了權限的類型和要進行的操作 ; 第四個參數是結構 PreviousState 的長度,如果 PreviousState 為空,該參數應為 NULL ;第五個參數也是一個 指向 TOKEN_PRIVILEGES 結構的指針,存放修改前的訪問權限的信息,可空;最后一個參數為實際 PreviousState 結構返回的大小。在使用這個函數前再看一下 TOKEN_PRIVILEGES 這個結構,其聲明如下:

typedef struct _TOKEN_PRIVILEGES { DWORD PrivilegeCount ; LUID_AND_ATTRIBUTES Privileges []; } TOKEN_PRIVILEGES, *PTOKEN_PRIVILEGES;

PrivilegeCount 指的數組原素的個數,接著是一個 LUID_AND_ATTRIBUTES 類型的數組,再來看一下 LUID_AND_ATTRIBUTES 這個結構的內容,聲明如下:

typedef struct _LUID_AND_ATTRIBUTES { LUID Luid ; DWORD Attributes ;

} LUID_AND_ATTRIBUTES, *PLUID_AND_ATTRIBUTES

第二個參數就指明了我們要進行的操作類型,有三個可選項:

SE_PRIVILEGE_ENABLED 、 SE_PRIVILEGE_ENABLED_BY_DEFAULT 、

SE_PRIVILEGE_USED_FOR_ACCESS 。要使能一個權限就指定 Attributes 為

SE_PRIVILEGE_ENABLED 。第一個參數就是指權限的類型,是一個 LUID 的

值, LUID 就是指 locally unique identifier ,我想 GUID 大家是比較熟

悉的,和 GUID 的要求保證全局唯一不同, LUID 只要保證局部唯一,就是

指在系統的每一次運行期間保證是唯一的就可以了。另外和 GUID 相同的

一點, LUID 也是一個 64 位的值,相信大家都看過 GUID 那一大串的值,我

們要怎么樣才能知道一個權限對應的 LUID 值是多少呢?這就要用到另外

一個 API 函數 LookupPrivilegeValue ,其原形如下:

BOOL LookupPrivilegeValue( LPCTSTR lpSystemName , // system name LPCTSTR lpName , // privilege name PLUID lpLuid // locally unique identifier );

第一個參數是系統的名稱,如果是本地系統只要指明為 NULL 就可以了,

第三個參數就是返回 LUID 的指針,第二個參數就是指明了權限的名稱,

如“ SeDebugPrivilege ”。在 Winnt.h 中還定義了一些權限名稱的宏,

如:

#define SE_BACKUP_NAME TEXT('SeBackupPrivilege')

#define SE_RESTORE_NAME TEXT('SeRestorePrivilege')

#define SE_SHUTDOWN_NAME TEXT('SeShutdownPrivilege')

#define SE_DEBUG_NAME TEXT('SeDebugPrivilege')

這樣通過這三個函數的調用,我們就可以用 OpenProcess(PROCESS_ALL_ACCESS,FALSE, dwProcessID)來打獲得任意進程的句柄,并

且指定了所有的訪問權。

四 總結

用戶模式的內存掃描還是具有想當的局限性,它不能完全掃描

Windows2000的全部內存空間。要對系統空間進行掃描,在Windows2000下,用戶模式的應用程序是不能實現的。要實現對系統空間的掃描,必須

通過工作于核心模式的程序—驅動程序來實現。

標簽: Windows系統
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
久久美女精品| 精品一区二区三区视频在线播放| 成人国产精品一区二区免费麻豆| 国产精品日本一区二区三区在线| 国产亚洲一区| 国产精品亚洲四区在线观看| 国产免费播放一区二区| 国产精品777777在线播放| 美女性感视频久久| 免费在线成人| sm捆绑调教国产免费网站在线观看 | 中文字幕在线免费观看视频| 在线一区av| 日韩电影二区| 国内精品福利| 亚洲人亚洲人色久| 久久99久久久精品欧美| 高清久久精品| 亚洲国产日韩欧美在线| 亚洲精品系列| 久久精品欧洲| 久久天堂精品| 蜜桃av一区二区三区电影| 91成人福利| 欧美日韩免费观看视频| 在线亚洲国产精品网站| 91综合久久爱com| 国产一区二区三区不卡视频网站| 国产不卡人人| 美日韩精品视频| 国产精品欧美大片| 久久精品国语| 日韩欧美中文字幕电影| 久久精品人人| 99日韩精品| 国产精品2区| 亚洲激情另类| 鲁大师精品99久久久| 亚洲高清久久| 欧美久久久网站| 亚洲电影有码| 日韩福利视频导航| 午夜影院一区| 视频一区免费在线观看| 嫩草伊人久久精品少妇av杨幂| 日韩精品免费一区二区在线观看| 久久av一区二区三区| 麻豆国产精品一区二区三区| 亚洲欧美不卡| 精品视频一区二区三区在线观看 | 99视频一区| 国产精品地址| av不卡免费看| 精品美女久久| 在线观看亚洲精品福利片| 国产aa精品| 日韩一区中文| 亚洲成人国产| 麻豆精品在线视频| 久久先锋影音| 欧美日韩国产观看视频| 91av一区| 国产亚洲福利| 国产成人调教视频在线观看| 视频一区欧美日韩| 色天使综合视频| 国产精品免费大片| 亚洲激情五月| 岛国av在线播放| 欧美在线看片| 欧美中文日韩| 欧美va天堂在线| 国产aⅴ精品一区二区四区| 日本中文字幕一区二区视频 | 久久婷婷久久| 美女视频免费精品| 日韩精品一区二区三区中文在线| 久久九九电影| 高清av一区| 国产欧美亚洲一区| 中文国产一区| 成人羞羞视频在线看网址| 久久精品 人人爱| 视频精品一区二区| 不卡中文字幕| 播放一区二区| 91欧美在线| 欧美激情 亚洲a∨综合| 日韩欧美高清一区二区三区| 在线亚洲自拍| 国产在线成人| 久久国产免费| 欧美日韩免费看片| 国产一区精品福利| 国产精品三级| 日韩av一二三| 男女男精品网站| 99在线精品免费视频九九视| 久久高清免费| 99久精品视频在线观看视频| 精品国产免费人成网站| 你懂的亚洲视频| 国产精品色在线网站| 日韩av不卡在线观看| 亚洲精品极品| 日韩视频1区| 日韩精品免费视频人成| 亚洲资源网站| 亚洲一区二区av| 中文精品电影| 日韩中文字幕91| 一区在线免费| 亚洲欧美日韩一区在线观看| 国产农村妇女精品一区二区| 日韩一区二区久久| 日韩午夜电影| 久热精品在线| 日本亚洲视频在线| 91亚洲精品视频在线观看| 69堂免费精品视频在线播放| 欧美综合社区国产| 美女久久精品| 国产一区二区三区成人欧美日韩在线观看| 久久永久免费| 都市激情国产精品| 日韩伦理一区| 日本韩国欧美超级黄在线观看| 三上悠亚国产精品一区二区三区| 日本在线精品| 亚洲激情婷婷| 亚洲日韩视频| 久久激情五月激情| 精品中文在线| 中文字幕成在线观看| 亚洲电影在线| 免费视频最近日韩| 91欧美精品| 蜜桃久久久久| 日韩视频网站在线观看| 免费精品国产的网站免费观看| 亚洲精品小说| 亚洲综合不卡| 日本色综合中文字幕| 免费在线亚洲欧美| 日本在线精品| 免费在线欧美视频| 国产欧美视频在线| 日产精品一区二区| 国产91精品对白在线播放| 国产精品呻吟| 国产精品资源| 99精品小视频| 婷婷精品久久久久久久久久不卡| 国产精品一页| 欧洲在线一区| 亚洲日本久久| 精品伊人久久| 激情五月色综合国产精品| 伊人久久一区| 久久精品一区二区三区中文字幕| 成人羞羞在线观看网站| 中文字幕日韩高清在线| 精品亚洲a∨| 欧美日韩国产探花| 国产69精品久久| 日本а中文在线天堂| 中文字幕系列一区| 99日韩精品| 日韩黄色在线观看| 欧美极品中文字幕| 不卡av一区二区| 久久国产66| 美女av在线免费看| 亚洲制服欧美另类| 麻豆中文一区二区| 国产精品88久久久久久| 日韩激情啪啪| 欧美日韩精品免费观看视完整| 综合一区二区三区| 欧美国产偷国产精品三区| 免费不卡在线观看| 91青青国产在线观看精品| 中文字幕一区二区三区日韩精品 | 国产精品亚洲欧美一级在线| 蜜桃精品在线| 青青草91视频| 激情综合网站| 欧美成a人片免费观看久久五月天| 欧美成人综合| 欧美黄色一区| 蜜桃一区二区三区在线| 亚洲啊v在线| 欧美精品国产| 亚洲男女av一区二区| 国产精品天堂蜜av在线播放| 国产精品日本| 国产精品成人一区二区不卡| 亚洲精品麻豆| 激情婷婷久久| 麻豆精品新av中文字幕|