Win10 WorkingSet 相关分析

发布于 2019-04-21  175 次阅读


主要是看看win10怎么实现遍历进程工作集的 未完成 ,先大致看看,时间匆忙 欢迎朋友们指出错误~~一起学习~


#define PS_PROCESS_FLAGS_CREATE_REPORTED        0x00000001UL // Create process debug call has occurred
#define PS_PROCESS_FLAGS_NO_DEBUG_INHERIT       0x00000002UL // Don't inherit debug port
#define PS_PROCESS_FLAGS_PROCESS_EXITING        0x00000004UL // PspExitProcess entered
#define PS_PROCESS_FLAGS_PROCESS_DELETE         0x00000008UL // Delete process has been issued
#define PS_PROCESS_FLAGS_WOW64_SPLIT_PAGES      0x00000010UL // Wow64 split pages
#define PS_PROCESS_FLAGS_VM_DELETED             0x00000020UL // VM is deleted
#define PS_PROCESS_FLAGS_OUTSWAP_ENABLED        0x00000040UL // Outswap enabled
#define PS_PROCESS_FLAGS_OUTSWAPPED             0x00000080UL // Outswapped
#define PS_PROCESS_FLAGS_FORK_FAILED            0x00000100UL // Fork status
#define PS_PROCESS_FLAGS_WOW64_4GB_VA_SPACE     0x00000200UL // Wow64 process with 4gb virtual address space
#define PS_PROCESS_FLAGS_ADDRESS_SPACE1         0x00000400UL // Addr space state1
#define PS_PROCESS_FLAGS_ADDRESS_SPACE2         0x00000800UL // Addr space state2
#define PS_PROCESS_FLAGS_SET_TIMER_RESOLUTION   0x00001000UL // SetTimerResolution has been called
#define PS_PROCESS_FLAGS_BREAK_ON_TERMINATION   0x00002000UL // Break on process termination
#define PS_PROCESS_FLAGS_CREATING_SESSION       0x00004000UL // Process is creating a session
#define PS_PROCESS_FLAGS_USING_WRITE_WATCH      0x00008000UL // Process is using the write watch APIs
#define PS_PROCESS_FLAGS_IN_SESSION             0x00010000UL // Process is in a session
#define PS_PROCESS_FLAGS_OVERRIDE_ADDRESS_SPACE 0x00020000UL // Process must use native address space (Win64 only)
#define PS_PROCESS_FLAGS_HAS_ADDRESS_SPACE      0x00040000UL // This process has an address space
#define PS_PROCESS_FLAGS_LAUNCH_PREFETCHED      0x00080000UL // Process launch was prefetched
#define PS_PROCESS_INJECT_INPAGE_ERRORS         0x00100000UL // Process should be given inpage errors - hardcoded in trap.asm too
#define PS_PROCESS_FLAGS_VM_TOP_DOWN            0x00200000UL // Process memory allocations default to top-down
#define PS_PROCESS_FLAGS_IMAGE_NOTIFY_DONE      0x00400000UL // We have sent a message for this image
#define PS_PROCESS_FLAGS_PDE_UPDATE_NEEDED      0x00800000UL // The system PDEs need updating for this process (NT32 only)
#define PS_PROCESS_FLAGS_VDM_ALLOWED            0x01000000UL // Process allowed to invoke NTVDM support
#define PS_PROCESS_FLAGS_SMAP_ALLOWED           0x02000000UL // Process allowed to invoke SMAP support
#define PS_PROCESS_FLAGS_CREATE_FAILED          0x04000000UL // Process create failed

#define PS_PROCESS_FLAGS_DEFAULT_IO_PRIORITY    0x38000000UL // The default I/O priority for created threads. (3 bits)

#define PS_PROCESS_FLAGS_PRIORITY_SHIFT         27

#define PS_PROCESS_FLAGS_EXECUTE_SPARE1         0x40000000UL //
#define PS_PROCESS_FLAGS_EXECUTE_SPARE2         0x80000000UL //

typedef struct _MEMORY_WORKING_SET_BLOCK
{
	ULONG_PTR Protection : 5;
	ULONG_PTR ShareCount : 3;
	ULONG_PTR Shared : 1;
	ULONG_PTR Node : 3;
#ifdef _WIN64
	ULONG_PTR VirtualPage : 52;
#else
	ULONG VirtualPage : 20;
#endif
} MEMORY_WORKING_SET_BLOCK, *PMEMORY_WORKING_SET_BLOCK;

typedef struct _MEMORY_WORKING_SET_INFORMATION
{
	ULONG_PTR NumberOfEntries;
	MEMORY_WORKING_SET_BLOCK WorkingSetInfo[1];
} MEMORY_WORKING_SET_INFORMATION, *PMEMORY_WORKING_SET_INFORMATION;

typedef struct  _WalkExec_Context {

	uintptr_t unk_index;//0x0
	struct _MMSUPPORT_FULL*Vm;//0x8
	uintptr_t unk_ptr;//0x10
	uintptr_t unk_ptr2;//0x18
	uintptr_t selfmap;//0x20
	uintptr_t Partition;//0x28
	uintptr_t bounds_1_start;//0x30
	uintptr_t bounds_1_end;//0x38
	uintptr_t bounds_2_start;//0x40
	uintptr_t bounds_2_end;//0x48
	uintptr_t bounds_3_start;//0x50
	uintptr_t bounds_3_end;//0x58
	uintptr_t bounds_4_start;//0x60
	uintptr_t bounds_4_end;//0x68
	uintptr_t unk_flags;//0x70
	WalkCallback func1;//0x78 
	WalkCallback func2;//0x80
	uintptr_t unk_struct_ptr;//0x88
}WalkExec_Context, *pWalkExec_Context;// sizeof(0x90) win10 16299

typedef struct _WalkBounds {
	uintptr_t unk_kernelspace_bounds1_start;//0x0
	uintptr_t unk_kernelspace_bounds1_end;//0x8
	uintptr_t unk_kernelspace_bounds2_start;//0x10
	uintptr_t unk_kernelspace_bounds2_end;//0x18
	//pad____
}WalkBounds,*pWalkBounds;
#define FIND(A,e) (size_t)&(((A *)0)->e)
typedef void (__fastcall *WalkCallback)(struct  _WalkExec_Context*context);


uintptr_t get_u64(uintptr_t pt) {
	return *(uintptr_t*)pt;
}


NTKERNELAPI
KPROCESSOR_MODE
PsGetCurrentThreadPreviousMode(
	VOID
);

void KeStackAttachProcess(
	PRKPROCESS   PROCESS,
	PRKAPC_STATE ApcState
);
_MMSUPPORT_SHARED *__fastcall MiGetSharedVm(_MMSUPPORT_FULL *a1)
{
	_MMSUPPORT_SHARED *result; // rax@2

	if ((a1->Instance.Flags & 7) == 2)
		result = (_MMSUPPORT_SHARED *)&unk_381540;
	else
		result = &a1->Shared;
	return result;
}

KIRQL __fastcall MiLockWorkingSetShared(struct _MMSUPPORT_FULL *a1)
{
	char *v1; // rbx@1
	KIRQL result; // eax@3
	struct _MMSUPPORT_SHARED * shared;
	shared =MiGetSharedVm(a1)
	result = ExAcquireSpinLockShared(shared);
	if (shared->GoodCitizenWaiting)
		_InterlockedExchange(&shared->GoodCitizenWaiting, 0);
	return result;
}
void __fastcall MiUnlockWorkingSetShared(_MMSUPPORT_FULL *a1, KIRQL irql)
{
	_MMSUPPORT_SHARED *shared; // rax@1
	int result; // eax@1
	shared = MiGetSharedVm(a1);
	 ExReleaseSpinLockSharedFromDpcLevel(shared);
	__writecr8(irql);
	return ;
}

NTSTATUS __fastcall MiGetWorkingSetInfoEx(struct _MMSUPPORT_FULL *pMmSupport_Full, PMEMORY_WORKING_SET_INFORMATION Cache_Buff, unsigned __int64 MmInfoLen, int Tag) {
	struct WalkExec_Context context = { 0 };
	BOOLEAN bAttach; 
	PEPROCESS TargetProcess;
	KAPC_STATE ApcState;
	KIRQL irql;
	NTSTATUS Status;
	if (pMmSupport_Full->Instance.Flags & 7)
		goto LABEL_5;

	TargetProcess = (pMmSupport_Full - (FIND(_EPROCESS, Vm)));
	if (TargetProcess != PsIdleProcess)
	{
		if (TargetProcess!=GetCurrentProcess())
		{
			KeStackAttachProcess(TargetProcess, &ApcState);
			bAttach = TRUE;
		}
	LABEL_5:
		irql = MiLockWorkingSetShared(pMmSupport_Full);
		if (Process && Process->Flags & PS_PROCESS_FLAGS_VM_DELETED)     // 检查
		{
			Status = STATUS_PROCESS_IS_TERMINATING;
			goto LABEL_14;
		}


	}


	return Status;
}
NTSTATUS __fastcall MiGetWorkingSetInfo(__int64 pMemInfoBuff, PMEMORY_WORKING_SET_INFORMATION OutCache, unsigned __int64 MmInfoLen, _EPROCESS pEProcess)
{
	NTSTATUS result;
	PMDL Mdl;
	if (MmInfoLen > 0xFFFFFFFF)
	{
		result = STATUS_INVALID_BUFFER_SIZE;
	}
	else
	{
		Mdl = ExAllocatePoolWithTag(POOL_NX_ALLOCATION, 8 * ((MmInfoLen >> 12) + ((MmInfoLen & 0xFFF) != 0) + 7i64), 0x20206D4Du);
		if (Mdl == NULL) {
			return STATUS_INSUFFICIENT_RESOURCES;
		}
		MmInitializeMdl(Mdl, pMemInfoBuff, MmInfoLen);
		try {
			MmProbeAndLockPages(Mdl,PsGetCurrentThreadPreviousMode(),IoWriteAccess);

		} except(EXCEPTION_EXECUTE_HANDLER) {

			ExFreePool(Mdl);
			return GetExceptionCode();
		}
		Info = MmGetSystemAddressForMdlSafe(Mdl, NormalPagePriority);


		if (Info)
		{
			result = MiGetWorkingSetInfoEx(&pEProcess->Vm, (__int64)Info, MmInfoLen, 1);// Process+0x500=MMSupport_Full
			if (NT_SUCCESS(result))
				*OutCache = *Info;
			else
				result = STATUS_INSUFFICIENT_RESOURCES;
		}

		MmUnlockPages(Mdl);
		ExFreePool(Mdl);

	}

	return result;
}



signed __int64 __fastcall MiGetSystemCacheReverseMap(unsigned __int64 Pa) {

	PULONG64 _PDE_BASE = 0x0FFFFF6FB40000000;
	PULONG64 _PFN_DATABASE = 0xFFFFFA8000000010;
    uintptr_t  r8= ((_PDE_BASE[((Pa >> 0x12) & 0x3FFFFFF8)]) >> 0xC) & 0xFFFFFFFFF;
    r8 = r8 + r8 * 2;
    r8 += r8;
	uintptr_t  rcx = (Pa >> 0x12) & 7;
	rcx = rcx + rcx * 2;
	rcx = rcx << 4;
	rcx += _PFN_DATABASE[r8 * 8];
	return rcx;
}
__int64 __fastcall MiWalkPageTables(struct  _WalkExec_Context*context) {


}
int __fastcall MiWalkPageTablesRecursively(__int64 _WalkExec_Context, unsigned __int64 Bounds4_start, unsigned int WalkCount) {

}
signed __int64 __fastcall MiInitializeWalkBounds(struct WalkExec_Context *context, struct WalkBounds *pWalk) {
	struct _MMSUPPORT_FULL*Vm = context->Vm;
	int flags;
	signed __int64 result;
	if (! (Vm->Instance.Flags& 7) )
	{
		pWalk->unk_kernelspace_bounds1_start = nullptr;
		pWalk->unk_kernelspace_bounds1_end = 0xFFFF7FFFFFFFFFFF;
		pWalk->unk_kernelspace_bounds2_start = get_u64(nt + qword_380730);
		pWalk->unk_kernelspace_bounds2_end = pWalk->unk_kernelspace_bounds_start+ 0x10803FFF;
		goto LABEL_3;
	}

	if ((Vm->Instance.Flags & 7) == 1) {
	
		pWalk->unk_kernelspace_bounds1_start = get_u64(nt + qword_380330);
		pWalk->unk_kernelspace_bounds1_end = pWalk->unk_kernelspace_bounds1_start + 0x7FFFFFFFFF;
		return 1;
	}
	if ((Vm->Instance.Flags & 7) == 2) {

		pWalk->unk_kernelspace_bounds1_start = get_u64(nt + qword_3806A8);
		pWalk->unk_kernelspace_bounds1_end = pWalk->unk_kernelspace_bounds1_start - 1 + (get_u64(nt + qword_380688) << 21);
		return 1;
	}
	flags = (Vm->Instance.Flags & 7) - 3;

	if ((Vm->Instance.Flags & 7) == 3)
	{
		pWalk->unk_kernelspace_bounds1_start = get_u64(nt + qword_3805D0);
		pWalk->unk_kernelspace_bounds1_end = get_u64(nt + qword_3805D0 )- 1 + (get_u64(nt + qword_3805B0) << 21);
		if (get_u64(nt + qword_380640))// zero
		{
			pWalk->unk_kernelspace_bounds2_start = get_u64(nt + qword_380660);
			pWalk->unk_kernelspace_bounds2_end = get_u64(nt + qword_380660) - 1 + (get_u64(nt + qword_380640) << 21);
		LABEL_3:
			v3 = pWalk->unk_kernelspace_bounds2_start;
			v4 = pWalk->unk_kernelspace_bounds1_start < v3;
			v5 = pWalk->unk_kernelspace_bounds1_start == v3;
			result = 2;
			if (!v4 && !v5)
			{
				v9 = pWalk->unk_kernelspace_bounds2_start;
				pWalk->unk_kernelspace_bounds2_start = pWalk->unk_kernelspace_bounds1_start
				pWalk->unk_kernelspace_bounds1_start = v9;
			}
			return result;
		}
		return 1;
	}
	result = 1i64;
	if (flags == 1)
	{
		pWalk->unk_kernelspace_bounds1_start = get_u64(nt + qword_380540);
		pWalk->unk_kernelspace_bounds1_end = get_u64(nt + qword_380540) - 1 + (get_u64(nt + qword_380520) << 21);
	}
	return result;

}
__int8 __fastcall MiGetWsleContents(__int64 Va_AndMask, unsigned __int64 Va_Align) {
	PULONG64 Pte_base_Dynamic = 0xFFFFF68000000000;


	__int64 pte_entry = Pte_base_Dynamic[(Va_Align >> 9) & 0x7FFFFFFFF8]

		if (pte_entry & 1)
		{
		
			return  (((__int8)(pte_entry >> 0x38)) & 0xF) | ((((__int8)(pte_entry >> 0x3C)) & 7) << 4);
		}

	return 0x10;
}
int __fastcall MiGetWsleProtection(unsigned __int64 Va_Align, __int8 Ws_Mask) {

	PULONG64 Pte_base_Dynamic = 0xFFFFF68000000000;
	int result = (Ws_Mask >> 4) & 7;
	if (result)
	{
		__int64 pte_entry = Pte_base_Dynamic[(Va_Align >> 9) & 0x7FFFFFFFF8]
			if ((pte_entry & 0x18) == 8)
			{
				result |= 0x18;

			}
			else if (pte_entry & 0x10) {
				result |= 0x8;
			}
	}
	return result;
}

__int64 __fastcall MiGetPfnProtection(__int64 Va_AndMask, __int64 AlignVa,__int64 r8_unk) {


	__int64 pProcess = nullptr; 
	 __int8 Ws_Mask = MiGetWsleContents(Va_AndMask, AlignVa);
	result = MiGetWsleProtection(v3, unk);
	if (!(_DWORD)result)
	{
		v6 = *(_QWORD *)(r8_unk + 8);
		v7 = (*(_DWORD *)(r8_unk + 16) >> 5) & 0x1F;
		if (v6 >= 0)
		{
			result = (unsigned int)MmMakeProtectNotWriteCopy[(unsigned __int64)(unsigned int)v7];
		}
		else
		{
			pProcess =  PsGetCurrentProcess();
			if (pProcess->CloneRoot)
			{
				if (MiLocateCloneAddress(v8, v6 | 0x8000000000000000ui64))
					v7 = MmMakeProtectNotWriteCopy[(unsigned __int64)(unsigned int)v7];
			}
			result = (unsigned int)v7;
		}
	}
	return result;
 }


本站文章基于国际协议BY-NA-SA 4.0协议共享;
如未特殊说明,本站文章皆为原创文章,请规范转载。

0

博客管理员