专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅

首页 »DotNet » 函数注释:MiCreatePebOrTeb函数注释 »正文

函数注释:MiCreatePebOrTeb函数注释

来源: 发布时间:星期四, 2009年2月12日 浏览:48次 评论:0


今天看以前有关FS寄存器文章,看到说进程PEB地址总是0x7FFDF000.于是写了来验证

下.但是运行的后发现却不是这样:PEB地址总是不停变化,是随机.如何回事呢?找到WRK代码,

PEB地址分配在MiCreatePebOrTeb,于是仔细阅读了这个,才知道了如何回事.



晚上在baidu上搜了下,发现早就有人发表文章介绍说明这个情况了:Windows xp从SP2开始(包括SP2),就开始

随机返回PEB地址了.



下面是我代码注释:



NTSTATUS
MiCreatePebOrTeb (
IN PEPROCESS TargetProcess,
IN ULONG Size,
OUT PVOID *Base
)

/*

Routine Description:

This routine creates a TEB or PEB page within the target process.

Arguments:

TargetProcess - Supplies a poer to the process in which to create
the structure.

Size - Supplies the size of the structure to create a VAD for.

Base - Supplies a poer to place the PEB/TEB virtual address _disibledevent=>
//
// Allocate and initialize the Vad before acquiring the address space
// and working mutexes so as to minimize mutex hold duration.
//

Vad = (PMMVAD_LONG) ExAllocatePoolWithTag (NonPagedPool,
(MMVAD_LONG),
'ldaV');

(Vad NULL) {
STATUS_NO_MEMORY;
}

Vad->u.LongFlags = 0;

Vad->u.VadFlags.CommitCharge = BYTES_TO_PAGES (Size);
Vad->u.VadFlags.MemCommit = 1;
Vad->u.VadFlags.PrivateMemory = 1;
Vad->u.VadFlags.Protection = MM_READWRITE;

//
// Mark VAD as not deletable, no protection change.
//

Vad->u.VadFlags.NoChange = 1;
Vad->u2.LongFlags2 = 0;
Vad->u2.VadFlags2.OneSecured = 1;
Vad->u2.VadFlags2.LongVad = 1;
Vad->u2.VadFlags2.ReadOnly = 0;

//
// Get the address creation mutex to block multiple threads from
// creating or deleting address space at the same time and
// get the working mutex so virtual address descriptors can
// be inserted and walked.
//

LOCK_ADDRESS_SPACE (TargetProcess);


//
// Find a VA for the PEB _disibledevent=># d(_WIN64)
|| (Size (PEB32))
#end
) {
PVOID HighestVadAddress;

LARGE_INTEGER CurrentTime;

HighestVadAddress = (PVOID) ((PCHAR)MM_HIGHEST_VAD_ADDRESS + 1);
//MM_HIGHEST_VAD_ADDRESS=MM_HIGH_USER_ADDRESS – (64 * 1024)
//HighestVadAddress = 0x7FFF0000

KeQueryTickCount (&CurrentTime);

CurrentTime.LowPart &= ((X64K >> PAGE_SHIFT) - 1);

// (X64K >> PAGE_SHIFT) – 1 = 0xF
(CurrentTime.LowPart <= 1) {
CurrentTime.LowPart = 2;
}
//
// Select a varying PEB address without fragmenting the address space.
//
HighestVadAddress = (PVOID) ((PCHAR)HighestVadAddress - (CurrentTime.LowPart << PAGE_SHIFT));
//PAGE_SHIFT = 12.
//上面可以看出.PEB地址要求从14个地址中取出个: 0x7FFF0000 – 2<<12 /

//0x7FFF0000 – 3<<12/ 0x7FFF0000 – 4<<12 …0x7FFF0000 – 15<<12

(MiCheckForConflictingVadExistence (TargetProcess, HighestVadAddress, (PVOID) ((PCHAR) HighestVadAddress + ROUND_TO_PAGES (Size) - 1)) FALSE) {

//MiCheckForConflictingVadExistence用来检查指定进程地址中从HighestVadAddress到
// (PCHAR) HighestVadAddress + ROUND_TO_PAGES (Size) – 1是否已经分配了.如果没有
//分配,返回FALSE.则表示分配成功了.
// Got an address ...
//
*Base = HighestVadAddress;
goto AllocatedAddress;
}
}



//分配TEB,或者上面分配PEB不成功,就到下面分配流程了.
//下面这个从(PCHAR)MM_HIGHEST_VAD_ADDRESS + 1,(值为7FFF0000)向下分配
//空闲页(大小为0x1000).
Status = MiFindEmptyAddressRangeDown (&TargetProcess->VadRoot,
ROUND_TO_PAGES (Size),
((PCHAR)MM_HIGHEST_VAD_ADDRESS + 1),
PAGE_SIZE,
Base);

(!NT_SUCCESS(Status)) {

//
// No range was available, deallocate the Vad and the status.
//

UNLOCK_ADDRESS_SPACE (TargetProcess);
ExFreePool (Vad);
Status;
}
//好了,到此为止,PEB和TEB内存空间已经分配好了.下面进行些后续操作.
AllocatedAddress:

//
// An unoccupied address range has been found, finish initializing the


// virtual address descriptor to describe this range.
//

Vad->StartingVpn = MI_VA_TO_VPN (*Base);
Vad->EndingVpn = MI_VA_TO_VPN ((PCHAR)*Base + Size - 1);

Vad->u3.Secured.StartVpn = (ULONG_PTR)*Base;
Vad->u3.Secured.EndVpn = (ULONG_PTR)MI_VPN_TO_VA_ENDING (Vad->EndingVpn);

Status = MiInsertVadCharges ((PMMVAD) Vad, TargetProcess);

(!NT_SUCCESS (Status)) {

//
// A failure has occurred. Deallocate the Vad and the status.
//

UNLOCK_ADDRESS_SPACE (TargetProcess);
ExFreePool (Vad);

Status;
}

LOCK_WS_UNSAFE (Thread, TargetProcess);

MiInsertVad ((PMMVAD) Vad, TargetProcess);

UNLOCK_WS_UNSAFE (Thread, TargetProcess);

UNLOCK_ADDRESS_SPACE (TargetProcess);

Status;
}



网上有篇文章<系统维护窍门技巧:windows xp sp2溢出保护>上说到了PEB地址随机出现,该文把0x210看成是
个flag了.从上面源码我们可出0x210是PEB结构大小.MiCreatePebOrTeb就是根据此大小来判读
是PEB还是TEB分配.不管是PEB还是TEB,系统最终都是分配个1个PAGE.

0

相关文章

读者评论

发表评论

  • 昵称:
  • 内容: