欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

[分享]调戏:自建ASLR机制

[分享]调戏:自建ASLR机制

理论上这玩意没有想象中那么高深莫测
无非就是NtMapViewOfSection的时候,让文件映射的基址发生变化。

对于32位的系统可以直接上驱动级hook去处理。
但是因为最近我不太喜欢使用驱动,所以呢,写个ring3的处理吧(其实老外早做过这事儿了)。
好了不管那些事儿了,直接代码走起。
这里有个事情就是如何实现在Kernel32后快速加载么?
我实现的方法其实就是LPK劫持。这劫持效率你懂得。


typedef LONG (__stdcall *T_NtMapViewOfSection)(

	__in HANDLE SectionHandle,

	__in HANDLE ProcessHandle,

	__inout PVOID *BaseAddress,

	__in ULONG_PTR ZeroBits,

	__in SIZE_T CommitSize,

	__inout_opt PLARGE_INTEGER SectionOffset,

	__inout PSIZE_T ViewSize,

	__in int InheritDisposition,

	__in ULONG AllocationType,

	__in int Win32Protect

	);

typedef LONG (__stdcall *T_NtUnmapViewOfSection)(

	__in HANDLE ProcessHandle,

	__in PVOID BaseAddress

	);

T_NtUnmapViewOfSection funcNtUnmapViewOfSection =NULL;

T_NtMapViewOfSection OldNtMapViewOfSection = NULL;

LONG __stdcall

	OnNtMapViewOfSection(

	__in HANDLE SectionHandle,

	__in HANDLE ProcessHandle,

	__inout PVOID *BaseAddress,

	__in ULONG_PTR ZeroBits,

	__in SIZE_T CommitSize,

	__inout_opt PLARGE_INTEGER SectionOffset,

	__inout PSIZE_T ViewSize,

	__in int InheritDisposition,

	__in ULONG AllocationType,

	__in int Win32Protect

	)

{

	MEMORY_BASIC_INFORMATION mbi;

	LONG ns;

	ns = OldNtMapViewOfSection(SectionHandle,

		ProcessHandle,

		BaseAddress,

		ZeroBits,

		CommitSize,

		SectionOffset,

		ViewSize,

		InheritDisposition,

		Win32Protect);

	if (ns==0 || ns == 0x40000003)

	{

		VirtualQuery(*BaseAddress,&mbi,sizeof(mbi));

		if (mbi.Type == MEM_IMAGE)

		{

			PIMAGE_DOS_HEADER DosHeader;

			PIMAGE_NT_HEADERS NtHeader;

			DosHeader = (PIMAGE_DOS_HEADER)*BaseAddress;

			NtHeader = (PIMAGE_NT_HEADERS)((char *)DosHeader+DosHeader->e_lfanew);

			if (NtHeader->OptionalHeader.ImageBase == (ULONG)*BaseAddress)

			{

				if(!(NtHeader->OptionalHeader.DllCharacteristics & 0x40))

				{

					if (NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress)

					{

						funcNtUnmapViewOfSection(ProcessHandle,*BaseAddress);//释放原始

						VirtualAlloc(*BaseAddress,*ViewSize,MEM_RESERVE,PAGE_NOACCESS);//占坑

						ns = OldNtMapViewOfSection(SectionHandle,

							ProcessHandle,

							BaseAddress,

							ZeroBits,

							CommitSize,

							SectionOffset,

							ViewSize,

							InheritDisposition,

							Win32Protect);

					}

				}

			}

		}

	}

	return ns;

}

VOID InitASLR()

{

	//除了ntdll.dll之外的dll理论上都可以的,但是为了方便我还是从kernel32之后的dll做这个处理,其实fs:[x]的存在,即使怎么随机化,都是没用的

	funcNtUnmapViewOfSection = (T_NtUnmapViewOfSection)GetProcAddress(GetModuleHandleA("ntdll.dll"),"NtUnmapViewOfSection");

	InlineHook((void *)GetProcAddress(GetModuleHandleA("ntdll.dll"),"NtMapViewOfSection"),(void *)OnNtMapViewOfSection,(void **)&OldNtMapViewOfSection);

}



至于驱动级的实现,可以把kernel32也处理了,但是ntdll因为KiXXX系列函数被系统绑定了加载地址,所以ntdll理论上只能在系统启动时,随机一次地址(正统的ASLR也是这样的)。具体驱动怎么实现释放和占坑,这就看写驱动的人了,反正我没搞驱动的。

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途。
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功