欢迎来到 嗅灵易学

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

[不敢声称原创,怕被喷]R3下猥琐NTDLL钩子

[不敢声称原创,怕被喷]R3下猥琐NTDLL钩子

在R3下对NTDLL里面的Zw函数的HOOK 大部分都是在函数前几个字节做HOOK,或者IAT之类的.这样的HOOK 虽然比较方便,不过也存在一个很大的弊端,就是函数HOOK 很容易被检测,所以我们需要一种更猥琐的HOOK方式.当然这只是相对.而不是真的很猥琐......
NTDLL里面的ZW函数大部分都是这样的

MOV EAX,1
MOV EDX,7FFE0300
CALL DWORD PTR DS:[EDX]
RETN 20

NTDLL里面的ZW函数都是通过系统全局共享内存7FFE0300调用KiFastSystemCall进入内核,所以我们要做的就是HOOK这个函数.
77866190 >  8BD4             MOV EDX,ESP
77866192    0F34             SYSENTER
77866194 >  C3               RETN

大家看到了,大小5个字节 而且还有个返回函数,所以我们只能短跳再长跳.....
void HookSystemCall_HOOK()
{
	DWORD dwOldProtect;
	HMODULE hModule = GetModuleHandleA("NTDLL.dll");
	DWORD dwKiFastSystemCall = PtrToUlong(GetProcAddress(hModule, "KiFastSystemCall"));
	VirtualProtect(ULongToPtr(dwKiFastSystemCall - 0xA), 100, PAGE_EXECUTE_READWRITE, &dwOldProtect);
	*(PWORD)ULongToPtr(dwKiFastSystemCall) = 0xF4EB;
	*(PBYTE)ULongToPtr(dwKiFastSystemCall - 0xA) = 0xE9;
	*(PDWORD)ULongToPtr(dwKiFastSystemCall - 0x9) = PtrToUlong(KiFastSystemCall) - (dwKiFastSystemCall - 0xA) - 5;
}

接下来就是JMP到我们的函数里面了.接下来要处理的就是把我们要的ZW函数给分拣出来.大家肯定注意到ZW的汇编代码MOV EAX,1,没错这个1就是ZW函数的序号.既然如此分拣出我们要的函数也不是什么问题
__declspec(naked) void KiFastSystemCall()
{
	__asm{
			cmp         eax,1 ;EAX保存着我们需要的函数的序号.我们跳.....
			jz          Label
			jmp         KiFastSystemCallEx
			;其他的返回原始KiFastSystemCall的地方,当然,原来的函数已经被我们JMP出来啦.需要特别处理
Label:
			add         esp,4
			;不再返回到原始的ZwAccessCheck函数里面.而是直接返回调用ZwAccessCheck的函数.
			jmp         MyZwAccessCheck ;
	}
}

上面的函数就是我们的KiFastSystemCall啦.接下来就是我们的MyZwAccessCheck函数.还有一个我们需要自己进入内核的KiFastSystemCallEx函数,我们自己构造一个.当然我们还需要构造一个新的ZwAccessCheck函数,原始的那个函数调用的KiFastSystemCall已经被我们HOOK了.
//自己构造一个KiFastSystemCall  这样原始的RETN问题就解决了.
__declspec(naked) void KiFastSystemCallEx()
{
	__asm  {
		mov edx,esp
		__emit 0x0F
		__emit 0x34
		retn
	}
}
//跳板函数  
__declspec(naked) NTSTATUS NTAPI ZwAccessCheck(
    IN PSECURITY_DESCRIPTOR SecurityDescriptor,
    IN HANDLE ClientToken,
    IN ACCESS_MASK DesiredAccess,
    IN PGENERIC_MAPPING GenericMapping,
    OUT PPRIVILEGE_SET PrivilegeSet,
    OUT PULONG ReturnLength,
    OUT PACCESS_MASK GrantedAccess,
    OUT PNTSTATUS AccessStatus)
{
    __asm
	{
		MOV EAX,1
		CALL KiFastSystemCallEx
		RETN 20
	}
}
NTSTATUS NTAPI MyZwAccessCheck(
    IN PSECURITY_DESCRIPTOR SecurityDescriptor,
    IN HANDLE ClientToken,
    IN ACCESS_MASK DesiredAccess,
    IN PGENERIC_MAPPING GenericMapping,
    OUT PPRIVILEGE_SET PrivilegeSet,
    OUT PULONG ReturnLength,
    OUT PACCESS_MASK GrantedAccess,
    OUT PNTSTATUS AccessStatus)
{
    return ZwAccessCheck(
    ISecurityDescriptor,
    ClientToken,
    DesiredAccess,
    GenericMapping,
    PrivilegeSet,
    ReturnLength,
    GrantedAccess,
    AccessStatus);
}

差不多一个意思....剩下的就是依葫芦画瓢....自由发挥了.

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

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

0 0 0 举报
复制成功