BOOL InitializeUin() { ULONG_PTR Length; WCHAR ch; PWSTR CommandLine, QQUIN; CommandLine = CurrentPeb()->ProcessParameters->CommandLine.Buffer; QQUIN = wcsstr(CommandLine, L"QQUIN:"); if (QQUIN == nullptr) return FALSE; QQUIN += CONST_STRLEN(L"QQUIN:"); CommandLine = QQUIN; while (*CommandLine != ' ' && *CommandLine != '\t' && *CommandLine != 0) ++CommandLine; Length = PtrOffset(CommandLine, QQUIN); if (Length >= sizeof(GlobalRegistryDb) - sizeof(L".db")) return FALSE; Length /= sizeof(WCHAR); swprintf(GlobalRegistryDb, L"Registry_%.*s.db", Length, QQUIN); swprintf(GlobalHistoryDb, L"History_%.*s.db", Length, QQUIN); return TRUE; }
NTSTATUS GenerateXlAccCommandLine(PWSTR* XlAccCmdLine, PWSTR Entry, PCWSTR ApplicationName, PCWSTR CommandLine) { PWSTR Buffer; ULONG_PTR Length; PLDR_MODULE Module; UNICODE_STRING AccPath; ApplicationName = ApplicationName == NULL ? L"" : ApplicationName; CommandLine = CommandLine == NULL ? L"" : CommandLine; Module = FindLdrModuleByHandle(&__ImageBase); Length = (lstrlenW(ApplicationName) + lstrlenW(CommandLine) + MAX_NTPATH) * sizeof(WCHAR) + Module->FullDllName.Length; Buffer = (PWSTR)malloc(Length); if (Buffer == NULL) return STATUS_NO_MEMORY; *XlAccCmdLine = Buffer; AccPath = Module->FullDllName; AccPath.Length = (USHORT)PtrOffset(PathFindFileNameW(Module->FullDllName.Buffer), Module->FullDllName.Buffer); swprintf( Buffer, L"\"%wZXLacc.exe\" -hookstart game:\"%s\" path:\"%s\" param:%s", &AccPath, Entry, ApplicationName, CommandLine ); return STATUS_SUCCESS; }
ULONG NitroPlus:: HashBuffer( PVOID Buffer, ULONG Length ) { PBYTE Buf; ULONG Hash; Hash = 0x20101118; Buf = (PBYTE)Buffer; for (; Length; --Length) { Hash -= *Buf++; } return Hash * PtrOffset(Buf, Buffer); }
ULONG FASTCALL GetStringOffset(PSCRIPT_OBJECT Script, ULONG OpIndex, PCSTR StringBuffer) { ULONG Offset, Hash; PTEXT_NODE* TextNode; TextNodeList* NodeList; PML_HANDLE_TABLE_ENTRY NodeListHandle; Offset = Script->OpBuffer[OpIndex]; if (Script->ScriptName == NULL) return Offset; Hash = HashAPILower(Script->ScriptName); //AllocConsole();PrintConsoleW(L"%08X, %S\n", Hash, Script->ScriptName); LOOP_ONCE { NodeListHandle = g_TextTable->Lookup(Hash); if (NodeListHandle == NULL) break; NodeList = (TextNodeList *)NodeListHandle->Handle; if (NodeList == NULL) break; TextNode = BinarySearch(NodeList->GetData(), NodeList->GetData() + NodeList->GetSize(), Offset, [] (PTEXT_NODE* ValuePtr, ULONG Value, ULONG Context) { return (*ValuePtr)->Offset == Value ? 0 : (*ValuePtr)->Offset < Value ? -1 : 1; }, 0 ); if (TextNode == NULL) break; Offset = PtrOffset((*TextNode)->Text, StringBuffer); } return Offset; }
NTSTATUS LeGlobalData::Initialize() { BOOL IsLoader; PLEPEB LePeb; PLDR_MODULE Ntdll; PPEB_BASE Peb; NTSTATUS Status; NLSTABLEINFO NlsTableInfo; UNICODE_STRING SystemDirectory, NlsFileName, OemNlsFileName, LangFileName; PKEY_VALUE_PARTIAL_INFORMATION IndexValue; IsLoader = IsLeLoader(); Wow64 = Ps::IsWow64Process(); Ntdll = GetNtdllLdrModule(); LOOP_ONCE { LePeb = OpenOrCreateLePeb(); if (LePeb == nullptr) { ULONG_PTR DefaultACPLength, DefaultLCIDLength, DefaultOEMCPLength; WCHAR DefaultACP[0x20], DefaultOEMCP[0x20], DefaultLCID[0x20]; PVOID ReloadedNtdll; PUNICODE_STRING FullDllName; LePeb = GetLePeb(); InitDefaultLeb(&LePeb->Leb); FullDllName = &FindLdrModuleByHandle(&__ImageBase)->FullDllName; CopyMemory(LePeb->LeDllFullPath, FullDllName->Buffer, FullDllName->Length + sizeof(WCHAR)); Status = LoadPeImage(Ntdll->FullDllName.Buffer, &ReloadedNtdll, nullptr, LOAD_PE_IGNORE_RELOC); if (NT_SUCCESS(Status)) { PVOID LdrLoadDllAddress; LdrLoadDllAddress = LookupExportTable(ReloadedNtdll, NTDLL_LdrLoadDll); LePeb->LdrLoadDllAddress = PtrAdd(LdrLoadDllAddress, PtrOffset(Ntdll->DllBase, ReloadedNtdll)); CopyMemory(LePeb->LdrLoadDllBackup, LdrLoadDllAddress, LDR_LOAD_DLL_BACKUP_SIZE); LePeb->LdrLoadDllBackupSize = LDR_LOAD_DLL_BACKUP_SIZE; UnloadPeImage(ReloadedNtdll); } DefaultACPLength = (swprintf(DefaultACP, L"%d", LePeb->Leb.AnsiCodePage) + 1) * sizeof(WCHAR); DefaultOEMCPLength = (swprintf(DefaultOEMCP, L"%d", LePeb->Leb.OemCodePage) + 1) * sizeof(WCHAR); DefaultLCIDLength = (swprintf(DefaultLCID, L"%d", LePeb->Leb.LocaleID) + 1) * sizeof(WCHAR); REGISTRY_REDIRECTION_ENTRY64 *Entry, Entries[] = { { { (ULONG64)HKEY_LOCAL_MACHINE, USTR64(REGPATH_CODEPAGE), USTR64(REGKEY_ACP), REG_SZ, }, { (ULONG64)HKEY_LOCAL_MACHINE, USTR64(REGPATH_CODEPAGE), USTR64(REGKEY_ACP), REG_SZ, DefaultACP, DefaultACPLength }, }, { { (ULONG64)HKEY_LOCAL_MACHINE, USTR64(REGPATH_CODEPAGE), USTR64(REGKEY_OEMCP), REG_SZ, }, { (ULONG64)HKEY_LOCAL_MACHINE, USTR64(REGPATH_CODEPAGE), USTR64(REGKEY_OEMCP), REG_SZ, DefaultOEMCP, DefaultOEMCPLength }, }, { { (ULONG64)HKEY_LOCAL_MACHINE, USTR64(REGPATH_LANGUAGE), USTR64(REGKEY_DEFAULT_LANGUAGE), REG_SZ, }, { (ULONG64)HKEY_LOCAL_MACHINE, USTR64(REGPATH_LANGUAGE), USTR64(REGKEY_DEFAULT_LANGUAGE), REG_SZ, DefaultLCID, DefaultLCIDLength }, }, }; Status = this->InitRegistryRedirection(Entries, countof(Entries), nullptr); } else { *GetLePeb() = *LePeb; Status = this->InitRegistryRedirection(LePeb->Leb.RegistryReplacement, LePeb->Leb.NumberOfRegistryRedirectionEntries, &LePeb->Leb); NtClose(LePeb->Section); CloseLePeb(LePeb); } if (IsLoader) break; Status = this->TextMetricCache.Initialize(); FAIL_RETURN(Status); PVOID NlsBaseAddress; LCID DefaultLocaleID; LARGE_INTEGER DefaultCasingTableSize; Status = NtInitializeNlsFiles(&NlsBaseAddress, &DefaultLocaleID, &DefaultCasingTableSize); FAIL_RETURN(Status); this->GetLePeb()->OriginalLocaleID = DefaultLocaleID; NtUnmapViewOfSection(CurrentProcess, NlsBaseAddress); WriteLog(L"init leb %s", GetLePeb()->LeDllFullPath); SystemDirectory = Ntdll->FullDllName; SystemDirectory.Length -= Ntdll->BaseDllName.Length; Status = RtlDuplicateUnicodeString(RTL_DUPSTR_ADD_NULL, &SystemDirectory, &this->SystemDirectory); FAIL_RETURN(Status); RtlInitEmptyString(&NlsFileName, nullptr, 0); RtlInitEmptyString(&OemNlsFileName, nullptr, 0); RtlInitEmptyString(&LangFileName, nullptr, 0); SCOPE_EXIT { RtlFreeUnicodeString(&NlsFileName); RtlFreeUnicodeString(&OemNlsFileName); RtlFreeUnicodeString(&LangFileName); } SCOPE_EXIT_END; Status = GetNlsFile(&NlsFileName, GetLeb()->AnsiCodePage, REGPATH_CODEPAGE); FAIL_RETURN(Status); Status = GetNlsFile(&OemNlsFileName, GetLeb()->OemCodePage, REGPATH_CODEPAGE); FAIL_RETURN(Status); Status = GetLangFile(&LangFileName, GetLeb()->LocaleID, REGPATH_LANGUAGE); FAIL_RETURN(Status); NtFileMemory AnsiFile, OemFile, LangFile; Status = ReadFileInSystemDirectory(AnsiFile, &NlsFileName); FAIL_RETURN(Status); Status = ReadFileInSystemDirectory(OemFile, &OemNlsFileName); FAIL_RETURN(Status); Status = ReadFileInSystemDirectory(LangFile, &LangFileName); FAIL_RETURN(Status); AnsiCodePageOffset = 0; OemCodePageOffset = ROUND_UP(AnsiFile.GetSize32(), 16); UnicodeCaseTableOffset = OemCodePageOffset + ROUND_UP(OemFile.GetSize32(), 16); Status = AllocVirtualMemory(&CodePageMapView, UnicodeCaseTableOffset + LangFile.GetSize32(), PAGE_READWRITE, MEM_COMMIT | MEM_TOP_DOWN); FAIL_RETURN(Status); CopyMemory(PtrAdd(CodePageMapView, AnsiCodePageOffset), AnsiFile.GetBuffer(), AnsiFile.GetSize32()); CopyMemory(PtrAdd(CodePageMapView, OemCodePageOffset), OemFile.GetBuffer(), OemFile.GetSize32()); CopyMemory(PtrAdd(CodePageMapView, UnicodeCaseTableOffset), LangFile.GetBuffer(), LangFile.GetSize32()); ProtectVirtualMemory(CodePageMapView, UnicodeCaseTableOffset + LangFile.GetSize32(), PAGE_READONLY); RtlInitNlsTables( (PUSHORT)PtrAdd(CodePageMapView, AnsiCodePageOffset), (PUSHORT)PtrAdd(CodePageMapView, OemCodePageOffset), (PUSHORT)PtrAdd(CodePageMapView, UnicodeCaseTableOffset), &NlsTableInfo ); RtlResetRtlTranslations(&NlsTableInfo); WriteLog(L"reset nls"); Peb = CurrentPeb(); Peb->AnsiCodePageData = (PUSHORT)PtrAdd(CodePageMapView, AnsiCodePageOffset); Peb->OemCodePageData = (PUSHORT)PtrAdd(CodePageMapView, OemCodePageOffset); Peb->UnicodeCaseTableData = (PUSHORT)PtrAdd(CodePageMapView, UnicodeCaseTableOffset); // LdrInitShimEngineDynamic(&__ImageBase); LdrRegisterDllNotification(0, [] (ULONG NotificationReason, PCLDR_DLL_NOTIFICATION_DATA NotificationData, PVOID Context) { return ((PLeGlobalData)Context)->DllNotification(NotificationReason, NotificationData); }, this, &DllNotificationCookie ); } Status = InstallHookPort(); WriteLog(L"inst hp: %08X", Status); FAIL_RETURN(Status); HookNtdllRoutines(Ntdll->DllBase); WriteLog(L"hook ntdll"); if (IsLoader) return Status; PLDR_MODULE Kernel32Ldr; Kernel32Ldr = GetKernel32Ldr(); if (Kernel32Ldr != nullptr) { Kernel32Ldr->EntryPoint = DelayInitDllEntry; // HookKernel32Routines(Kernel32Ldr->DllBase); } WriteLog(L"init %p", Status); return Status; }
NTSTATUS CheckIsExplorer() { NTSTATUS Status; PLDR_MODULE Module; PWSTR FullPath, BackSlash; ULONG ReturnLength; ULONG_PTR Length; MEMORY_BASIC_INFORMATION MemoryBasic; PPROCESS_IMAGE_FILE_NAME ExeFileName; PMEMORY_MAPPED_FILENAME_INFORMATION NtdllFileName; MEMORY_MAPPED_FILENAME_INFORMATION LocalMapped; static WCHAR ExplorerName[] = L"explorer.exe"; Status = NtQueryVirtualMemory(CurrentProcess, NtClose, MemoryMappedFilenameInformation, &LocalMapped, sizeof(LocalMapped), &Length); if (Status != STATUS_INFO_LENGTH_MISMATCH && Status != STATUS_BUFFER_OVERFLOW) return Status; NtdllFileName = (PMEMORY_MAPPED_FILENAME_INFORMATION)AllocStack(Length); Status = NtQueryVirtualMemory(CurrentProcess, NtClose, MemoryMappedFilenameInformation, NtdllFileName, Length, &Length); FAIL_RETURN(Status); Status = NtQueryInformationProcess(CurrentProcess, ProcessImageFileName, nullptr, 0, &ReturnLength); if (Status != STATUS_INFO_LENGTH_MISMATCH) return Status; ExeFileName = (PPROCESS_IMAGE_FILE_NAME)AllocStack(ReturnLength); Status = NtQueryInformationProcess(CurrentProcess, ProcessImageFileName, ExeFileName, ReturnLength, &ReturnLength); FAIL_RETURN(Status); BackSlash = nullptr; Length = NtdllFileName->Name.Length / sizeof(WCHAR) - 1; for (; Length != 0; --Length) { if (NtdllFileName->Name.Buffer[Length] != '\\') continue; if (BackSlash != nullptr) { BackSlash = &NtdllFileName->Name.Buffer[Length]; break; } BackSlash = &NtdllFileName->Name.Buffer[Length]; } if (BackSlash == nullptr) return STATUS_NO_MATCH; ++BackSlash; if (PtrOffset(BackSlash, NtdllFileName->Name.Buffer) + sizeof(ExplorerName) > NtdllFileName->Name.MaximumLength) return STATUS_NO_MATCH; CopyStruct(BackSlash, ExplorerName, sizeof(ExplorerName)); NtdllFileName->Name.Length = PtrOffset(BackSlash + CONST_STRLEN(ExplorerName), NtdllFileName->Name.Buffer); Status = RtlEqualUnicodeString(&NtdllFileName->Name, &ExeFileName->ImageFileName, TRUE) ? STATUS_SUCCESS : STATUS_NO_MATCH; return Status; }
UPK_STATUS NitroPlus:: Pack( PCWSTR InputPath, PCWSTR OutputFile /* = NULL */, PLARGE_INTEGER PackedFiles /* = NULL */, ULONG Flags /* = 0 */ ) { UNREFERENCED_PARAMETER(OutputFile); UNREFERENCED_PARAMETER(Flags); ULONG PathLength, Length, Hash, Offset; ULONG Size, CompressedSize, FileBufferSize, CompresseBufferSize; WCHAR FilePath[MAX_NTPATH]; PVOID NpaEntryBase, FileBuffer, CompresseBuffer; PBYTE NpaEntryBuffer; PWSTR FileName; NTSTATUS Status; LARGE_INTEGER FileCount, PackedFileCount; NITRO_PLUS_ENTRY *BaseEntry, *Entry; NITRO_PLUS_NPA_HEADER Header; NITRO_PLUS_NPA_ETNRY *Info; NtFileDisk File; if (PackedFiles == NULL) PackedFiles = &PackedFileCount; PackedFiles->QuadPart = 0; if (!EnumDirectoryFiles( (PVOID *)&BaseEntry, L"*.*", sizeof(*BaseEntry), InputPath, &FileCount, (EnumDirectoryFilesCallBackRoutine)QueryFileList, 0, EDF_SUBDIR) ) { return STATUS_UNSUCCESSFUL; } FileBufferSize = 0; CompresseBufferSize = 0; FileBuffer = NULL; CompresseBuffer = NULL; *(PULONG)&Header.Signature = NPA_HEADER_MAGIC; Header.Version = NPA_GCLX_VERSION; Header.EntryCount = FileCount.LowPart; Header.FileCount = FileCount.LowPart; Header.DirectoryCount = 0; Header.IsCompressed = TRUE; Header.IsEncrypted = TRUE; RtlRandom(&Header.Hash[0]); RtlRandom(&Header.Hash[1]); PathLength = StrLengthW(InputPath); if (OutputFile != NULL) { Status = m_File.Create(OutputFile); } else { FileName = FilePath + PathLength; CopyMemory(FilePath, InputPath, PathLength * sizeof(*FilePath)); if (FileName[-1] == '\\') --FileName; *(PULONG64)FileName = TAG4W('.npa'); FileName[4] = 0; Status = m_File.Create(FilePath); } if (!NT_SUCCESS(Status)) goto RETURN_POINT; PathLength += InputPath[PathLength - 1] != '\\'; NpaEntryBase = AllocateMemory(sizeof(*BaseEntry) * FileCount.LowPart); if (NpaEntryBase == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; goto RETURN_POINT; } NpaEntryBuffer = (PBYTE)NpaEntryBase; Entry = BaseEntry; for (ULONG Index = 0, Count = FileCount.LowPart; Count; ++Index, --Count) { Length = StrLengthW(Entry->FileName) - PathLength; Length = WideCharToMultiByte( CP_SHIFTJIS, 0, Entry->FileName + PathLength, Length, (PSTR)NpaEntryBuffer + 4, INT_MAX, NULL, NULL ); // Nt_UnicodeToAnsi((PSTR)NpaEntryBuffer + 4, INT_MAX, Entry->FileName + PathLength, Length, &Length); *(PULONG)NpaEntryBuffer = Length; NpaEntryBuffer += 4; Entry->DecryptLength = Length; Entry->Seed = HashBuffer(NpaEntryBuffer, Length); EncryptName(NpaEntryBuffer, Length, Index, &Header); NpaEntryBuffer += Length; NpaEntryBuffer += sizeof(*Info); ++Entry; } Header.EntrySize = PtrOffset(NpaEntryBuffer, NpaEntryBase); Hash = Header.Hash[0] * Header.Hash[1]; NpaEntryBuffer = (PBYTE)NpaEntryBase; Entry = BaseEntry; Offset = 0; m_File.Seek(Header.EntrySize + sizeof(Header), FILE_BEGIN); for (ULONG Index = 0, Count = FileCount.LowPart; Count; ++Index, --Count) { Status = File.Open(Entry->FileName); if (!NT_SUCCESS(Status)) break; Size = File.GetSize32(); if (FileBufferSize < Size) { FileBufferSize = Size; FileBuffer = ReAllocateMemory(FileBuffer, FileBufferSize); if (FileBuffer == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; break; } } Status = File.Read(FileBuffer, Size); if (!NT_SUCCESS(Status)) break; CompressedSize = Size * 4; if (CompresseBufferSize < CompressedSize) { CompresseBufferSize = CompressedSize; CompresseBuffer = ReAllocateMemory(CompresseBuffer, CompresseBufferSize); if (CompresseBuffer == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; break; } } CompressedSize = CompresseBufferSize; Status = compress2(CompresseBuffer, &CompressedSize, FileBuffer, Size, Z_BEST_COMPRESSION); if (Status != Z_OK) { Status = STATUS_UNSUCCESSFUL; break; } EncryptData( CompresseBuffer, MY_MIN(CompressedSize, Entry->DecryptLength + 0x1000), (Hash + Entry->Seed) * Size ); NpaEntryBuffer += *(PULONG)NpaEntryBuffer + 4; Info = (NITRO_PLUS_NPA_ETNRY *)NpaEntryBuffer; NpaEntryBuffer += sizeof(*Info); Info->FileType = NP_FILE_TYPE_FILE; Info->CompressedSize = CompressedSize; Info->Offset = Offset; Info->OriginalSize = Size; Info->DirectoryIndex = 0; Status = m_File.Write(CompresseBuffer, CompressedSize); if (!NT_SUCCESS(Status)) break; Offset += CompressedSize; ++Entry; } if (!NT_SUCCESS(Status)) goto RETURN_POINT; m_File.Seek(0, FILE_BEGIN); Status = m_File.Write(&Header, sizeof(Header)); if (!NT_SUCCESS(Status)) goto RETURN_POINT; Status = m_File.Write(NpaEntryBase, Header.EntrySize); if (!NT_SUCCESS(Status)) goto RETURN_POINT; PackedFiles->QuadPart = FileCount.QuadPart; RETURN_POINT: FreeMemory(FileBuffer); EnumDirectoryFilesFree(BaseEntry); return Status; }
NTSTATUS LeGlobalData::Initialize() { PLEPEB LePeb; PLDR_MODULE Ntdll; PPEB_BASE Peb; NTSTATUS Status; NLSTABLEINFO NlsTableInfo; UNICODE_STRING SystemDirectory, NlsFileName, OemNlsFileName, LangFileName; PKEY_VALUE_PARTIAL_INFORMATION IndexValue; Wow64 = Ps::IsWow64Process(); Ntdll = GetNtdllLdrModule(); LePeb = OpenOrCreateLePeb(); if (LePeb == nullptr) { PVOID ReloadedNtdll; PUNICODE_STRING FullDllName; LePeb = GetLePeb(); InitDefaultLeb(&LePeb->Leb); FullDllName = &FindLdrModuleByHandle(&__ImageBase)->FullDllName; CopyMemory(LePeb->LeDllFullPath, FullDllName->Buffer, FullDllName->Length + sizeof(WCHAR)); Status = LoadPeImage(Ntdll->FullDllName.Buffer, &ReloadedNtdll, nullptr, LOAD_PE_IGNORE_RELOC); if (NT_SUCCESS(Status)) { PVOID LdrLoadDllAddress; LdrLoadDllAddress = EATLookupRoutineByHashPNoFix(ReloadedNtdll, NTDLL_LdrLoadDll); LePeb->LdrLoadDllAddress = PtrAdd(LdrLoadDllAddress, PtrOffset(Ntdll->DllBase, ReloadedNtdll)); CopyMemory(LePeb->LdrLoadDllBackup, LdrLoadDllAddress, LDR_LOAD_DLL_BACKUP_SIZE); LePeb->LdrLoadDllBackupSize = LDR_LOAD_DLL_BACKUP_SIZE; UnloadPeImage(ReloadedNtdll); } } else { *GetLePeb() = *LePeb; ZwClose(LePeb->Section); CloseLePeb(LePeb); } WriteLog(L"init leb %s", GetLePeb()->LeDllFullPath); SystemDirectory = Ntdll->FullDllName; SystemDirectory.Length -= Ntdll->BaseDllName.Length; Status = RtlDuplicateUnicodeString(RTL_DUPSTR_ADD_NULL, &SystemDirectory, &this->SystemDirectory); FAIL_RETURN(Status); RtlInitEmptyUnicodeString(&NlsFileName, nullptr, 0); RtlInitEmptyUnicodeString(&OemNlsFileName, nullptr, 0); RtlInitEmptyUnicodeString(&LangFileName, nullptr, 0); SCOPE_EXIT { RtlFreeUnicodeString(&NlsFileName); RtlFreeUnicodeString(&OemNlsFileName); RtlFreeUnicodeString(&LangFileName); } SCOPE_EXIT_END; Status = GetNlsFile(&NlsFileName, GetLeb()->AnsiCodePage, REGPATH_CODEPAGE); FAIL_RETURN(Status); Status = GetNlsFile(&OemNlsFileName, GetLeb()->OemCodePage, REGPATH_CODEPAGE); FAIL_RETURN(Status); Status = GetLangFile(&LangFileName, GetLeb()->LocaleID, REGPATH_LANGUAGE); FAIL_RETURN(Status); NtFileMemory AnsiFile, OemFile, LangFile; Status = ReadFileInSystemDirectory(AnsiFile, &NlsFileName); FAIL_RETURN(Status); Status = ReadFileInSystemDirectory(OemFile, &OemNlsFileName); FAIL_RETURN(Status); Status = ReadFileInSystemDirectory(LangFile, &LangFileName); FAIL_RETURN(Status); AnsiCodePageOffset = 0; OemCodePageOffset = ROUND_UP(AnsiFile.GetSize32(), 16); UnicodeCaseTableOffset = OemCodePageOffset + ROUND_UP(OemFile.GetSize32(), 16); Status = AllocVirtualMemory(&CodePageMapView, UnicodeCaseTableOffset + LangFile.GetSize32(), PAGE_READWRITE, MEM_COMMIT | MEM_TOP_DOWN); FAIL_RETURN(Status); CopyMemory(PtrAdd(CodePageMapView, AnsiCodePageOffset), AnsiFile.GetBuffer(), AnsiFile.GetSize32()); CopyMemory(PtrAdd(CodePageMapView, OemCodePageOffset), OemFile.GetBuffer(), OemFile.GetSize32()); CopyMemory(PtrAdd(CodePageMapView, UnicodeCaseTableOffset), LangFile.GetBuffer(), LangFile.GetSize32()); ProtectVirtualMemory(CodePageMapView, UnicodeCaseTableOffset + LangFile.GetSize32(), PAGE_READONLY); RtlInitNlsTables( (PUSHORT)PtrAdd(CodePageMapView, AnsiCodePageOffset), (PUSHORT)PtrAdd(CodePageMapView, OemCodePageOffset), (PUSHORT)PtrAdd(CodePageMapView, UnicodeCaseTableOffset), &NlsTableInfo ); RtlResetRtlTranslations(&NlsTableInfo); WriteLog(L"reset nls"); Peb = CurrentPeb(); Peb->AnsiCodePageData = (PUSHORT)PtrAdd(CodePageMapView, AnsiCodePageOffset); Peb->OemCodePageData = (PUSHORT)PtrAdd(CodePageMapView, OemCodePageOffset); Peb->UnicodeCaseTableData = (PUSHORT)PtrAdd(CodePageMapView, UnicodeCaseTableOffset); // LdrInitShimEngineDynamic(&__ImageBase); LdrRegisterDllNotification(0, [] (ULONG NotificationReason, PCLDR_DLL_NOTIFICATION_DATA NotificationData, PVOID Context) { return ((PLeGlobalData)Context)->DllNotification(NotificationReason, NotificationData); }, this, &DllNotificationCookie ); Status = InstallHookPort(); FAIL_RETURN(Status); WriteLog(L"inst hp"); HookNtdllRoutines(Ntdll->DllBase); WriteLog(L"hook ntdll"); PLDR_MODULE Kernel32Ldr; Kernel32Ldr = GetKernel32Ldr(); if (Kernel32Ldr != nullptr) { Kernel32Ldr->EntryPoint = DelayInitDllEntry; // HookKernel32Routines(Kernel32Ldr->DllBase); } WriteLog(L"init %p", Status); return Status; }