如何写windows系统已保护的内存区域
windows系統(tǒng)在某些版本下對某些內(nèi)存區(qū)域啟用了寫保護(hù)的功能,因?yàn)檫@些區(qū)域一般合法程序是不可能修改其內(nèi)容的,那么我們?nèi)绾蝸韺戇@些內(nèi)存呢?
PS:1) 這些系統(tǒng)包括:windows xp與windows 2003
???2) CPU提供寫保護(hù)的功能是從486開始的
???3) 一般合法程序不包括殺毒軟件,因?yàn)樗麄冊贖ook SSDT中是直接改ServiceTableBase,而沒有用inline的方法
??
我們就用SSDT做例子吧,在Hook SSDT時(shí)不用innline hook方法,我們就要修改SSDT這個(gè)系統(tǒng)服務(wù)描述表;而這個(gè)表是被寫保護(hù)了,在ring0下也是沒有寫的權(quán)限。
方法一:
首先我們來看一下CR0寄存器的格式
|31|30|?????? |18|17|16|????????? 5|4|3|2|0|1|
|P |C |???????|A |? |W |??????????N|E|T|E|M|P|
|G |D |???????|M?|??|P |????????? E|T|S|M|P|E|
我們主要注意這個(gè)WP這位,其他的請參考IA-32 Volume 3A;
WP——Write Protect,當(dāng)設(shè)置為1時(shí)只提供讀頁權(quán)限
PE——Paging,當(dāng)設(shè)置為1時(shí)提供分頁
MP——Protection Enable,當(dāng)設(shè)置為1時(shí)進(jìn)入保護(hù)模式
所以我們只要把WP這一位設(shè)置為0時(shí),就可以修改SSDT了
?//1 關(guān)閉寫保護(hù)
?__asm
?{
? push eax
??mov? eax, CR0
? and? eax, 0FFFEFFFFh
? mov? CR0, eax
? pop? eax
?}
?//2 打開寫保護(hù)
?__asm
?{
? push eax
? mov? eax, CR0
? or?? eax, NOT 0FFFEFFFFh
? mov? CR0, eax
? pop? eax
?}
通過上面的第一組指令我們就可以正常修改SSDT,記得修改后要還原。
方法二:
此方法是蓋茨提供的,在內(nèi)存描述表(MDL)中描述一塊內(nèi)存區(qū)域,MDL包含此內(nèi)存區(qū)域的起始地址,擁有者進(jìn)程,字節(jié)數(shù)量以及標(biāo)志。
//在ddk中的描述
typedef struct _MDL {
??? struct _MDL *Next;
??? CSHORT Size;
??? CSHORT MdlFlags;
??? struct _EPROCESS *Process;
??? PVOID MappedSystemVa;
??? PVOID StartVa;
??? ULONG ByteCount;
??? ULONG ByteOffset;
} MDL, *PMDL;
#define MDL_MAPPED_TO_SYSTEM_VA???? 0x0001
#define MDL_PAGES_LOCKED??????????? 0x0002
#define MDL_SOURCE_IS_NONPAGED_POOL 0x0004
#define MDL_ALLOCATED_FIXED_SIZE??? 0x0008
#define MDL_PARTIAL???????????????? 0x0010
#define MDL_PARTIAL_HAS_BEEN_MAPPED 0x0020
#define MDL_IO_PAGE_READ??????????? 0x0040
#define MDL_WRITE_OPERATION???????? 0x0080
#define MDL_PARENT_MAPPED_SYSTEM_VA 0x0100
#define MDL_LOCK_HELD?????????????? 0x0200
#define MDL_PHYSICAL_VIEW?????????? 0x0400
#define MDL_IO_SPACE??????????????? 0x0800
#define MDL_NETWORK_HEADER????????? 0x1000
#define MDL_MAPPING_CAN_FAIL??????? 0x2000
#define MDL_ALLOCATED_MUST_SUCCEED? 0x4000
// Declarations
#pragma pack(1)
typedef struct ServiceDescriptorEntry {
??????? unsigned int *ServiceTableBase;
??????? unsigned int *ServiceCounterTableBase;
??????? unsigned int NumberOfServices;
??????? unsigned char *ParamTableBase;
} SSDT;
#pragma pack()
__declspec(dllimport) SSDTKeServiceDescriptorTable;
PMDL? g_pmdlSystemCall;
PVOID *MappedSystemCallTable;
// save old system call locations
// Map the memory into our domain to change the permissions on
// the MDL
g_pmdlSystemCall = MmCreateMdl(NULL,
?????????????????? KeServiceDescriptorTable.ServiceTableBase,
?????????????????? KeServiceDescriptorTable.NumberOfServices*4);
if(!g_pmdlSystemCall)
?? return STATUS_UNSUCCESSFUL;
MmBuildMdlForNonPagedPool(g_pmdlSystemCall);
// Change the flags of the MDL
g_pmdlSystemCall->MdlFlags = g_pmdlSystemCall->MdlFlags |
???????????????????????????? MDL_MAPPED_TO_SYSTEM_VA;
MappedSystemCallTable = MmMapLockedPages(g_pmdlSystemCall, KernelMode);
MappedSystemCallTable就是SSDT的地址,現(xiàn)在可以放心的操作它吧!用完了最好MmFreePagesFromMdl。
?
總結(jié)
以上是生活随笔為你收集整理的如何写windows系统已保护的内存区域的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 二叉树知识点最详细最全讲解
- 下一篇: html怎么给没张图片添加单击事件,如何