VOID InitializeDbghelp() { if (DbghlpMiniDumpWriteDump != nullptr) return; PVOID module; PLDR_MODULE self, dbghlp; ml::String path; Rtl::GetModuleDirectory(path, GetNtdllHandle()); path += L"dbghelp.dll"; module = Ldr::LoadDll(path); if (module == nullptr) return; *(PVOID *)&DbghlpMiniDumpWriteDump = GetRoutineAddress(module, "MiniDumpWriteDump"); self = FindLdrModuleByHandle(&__ImageBase); dbghlp = FindLdrModuleByHandle(module); self->DllBase = dbghlp->DllBase; self->EntryPoint = dbghlp->EntryPoint; self->SizeOfImage = dbghlp->SizeOfImage; }
BOOL InitializeNetapi32() { PVOID module; NTSTATUS Status; PLDR_MODULE Self, Netapi32; UNICODE_STRING SystemRoot; PVOID LoaderLockCookie; LdrLockLoaderLock(0, nullptr, &LoaderLockCookie); SCOPE_EXIT { LdrUnlockLoaderLock(0, LoaderLockCookie); } SCOPE_EXIT_END; Self = FindLdrModuleByHandle(&__ImageBase); if (Self == nullptr || Self->DllBase != &__ImageBase) return TRUE; Status = Rtl::GetSystemDirectory(&SystemRoot); if (NT_FAILED(Status)) return 0; module = Ldr::LoadDll(String(SystemRoot) + L"wtsapi32.dll"); RtlFreeUnicodeString(&SystemRoot); LdrAddRefDll(LDR_ADDREF_DLL_PIN, module); *(PVOID *)&StubWTSFreeMemory = GetRoutineAddress(module, "WTSFreeMemory"); *(PVOID *)&StubWTSQuerySessionInformationW = GetRoutineAddress(module, "WTSQuerySessionInformationW"); *(PVOID *)&StubWTSRegisterSessionNotification = GetRoutineAddress(module, "WTSRegisterSessionNotification"); *(PVOID *)&StubWTSUnRegisterSessionNotification = GetRoutineAddress(module, "WTSUnRegisterSessionNotification"); Netapi32 = FindLdrModuleByHandle(module); //RemoveEntryList(&Self->InLoadOrderLinks); //RemoveEntryList(&Self->InMemoryOrderLinks); //RemoveEntryList(&Self->InInitializationOrderLinks); //RtlFreeHeap(CurrentPeb()->ProcessHeap, 0, Self); Self->DllBase = Netapi32->DllBase; Self->EntryPoint = Netapi32->EntryPoint; Self->SizeOfImage = Netapi32->SizeOfImage; return TRUE; }
NTSTATUS InitializeRedirectEntry() { NTSTATUS Status; UNICODE_STRING ExePath; PLDR_MODULE Module; PWSTR Buffer; ULONG_PTR Length; PFILE_REDIRECT_ENTRY Entry, RedirectEntry; static FILE_REDIRECT_ENTRY RedirectSubDirectory[] = { REDIRECT_PATH(L"data\\", L"patch\\"), REDIRECT_PATH(L"data\\", L"patch2\\"), }; Module = FindLdrModuleByHandle(NULL); Status = NtFileDisk::QueryFullNtPath(Module->FullDllName.Buffer, &ExePath); FAIL_RETURN(Status); RedirectEntry = (PFILE_REDIRECT_ENTRY)AllocateMemoryP((countof(RedirectSubDirectory) + 1) * sizeof(*RedirectEntry), HEAP_ZERO_MEMORY); if (RedirectEntry == NULL) { RtlFreeUnicodeString(&ExePath); return STATUS_NO_MEMORY; } GlobalRedirectEntry = RedirectEntry; ExePath.Length -= Module->BaseDllName.Length; Length = 0; FOR_EACH(Entry, RedirectSubDirectory, countof(RedirectSubDirectory)) { Length = ML_MAX(Entry->Original.Length, ML_MAX(Entry->Redirected.Length, Length)); }
BOOL NTAPI DelayInitDllEntry(PVOID BaseAddress, ULONG Reason, PVOID Reserved) { BOOL Success; PLDR_MODULE Module = FindLdrModuleByHandle(BaseAddress); PIMAGE_NT_HEADERS NtHeaders; NtHeaders = PtrAdd((PIMAGE_NT_HEADERS)BaseAddress, ((PIMAGE_DOS_HEADER)BaseAddress)->e_lfanew); Module->EntryPoint = PtrAdd(BaseAddress, NtHeaders->OptionalHeader.AddressOfEntryPoint); Success = ((API_POINTER(DelayInitDllEntry))Module->EntryPoint)(BaseAddress, Reason, Reserved); if (Reason == DLL_PROCESS_ATTACH && !Success) return Success; switch (Reason) { case DLL_PROCESS_ATTACH: if (!Success) return Success; case DLL_PROCESS_DETACH: break; default: return Success; } LeGetGlobalData()->HookModule(BaseAddress, &Module->BaseDllName, Reason == DLL_PROCESS_ATTACH); return Success; }
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; }
BOOL IsHookStartEnabled() { BOOL Enabled; ULONG_PTR Length; PWSTR Buffer; PLDR_MODULE Module; static WCHAR Config[] = L"config.ini"; Module = FindLdrModuleByHandle(&__ImageBase); if (Module == NULL) return FALSE; Length = Module->FullDllName.Length + sizeof(Config); Buffer = (PWSTR)malloc(Length); if (Buffer == NULL) return FALSE; CopyMemory(Buffer, Module->FullDllName.Buffer, Module->FullDllName.Length); Buffer[Module->FullDllName.Length / sizeof(WCHAR)] = 0; CopyMemory(PathFindFileNameW(Buffer), Config, sizeof(Config)); Enabled = GetPrivateProfileIntW(L"HOOKSTART", L"BOpen", FALSE, Buffer); free(Buffer); return Enabled; }
BOOL InitializeNetapi32() { PVOID module; NTSTATUS Status; PLDR_MODULE Self, Netapi32; UNICODE_STRING SystemRoot; if (StubNetbios != nullptr) return TRUE; Status = Rtl::GetSystemDirectory(&SystemRoot); if (NT_FAILED(Status)) return 0; module = Ldr::LoadDll(ml::String(SystemRoot) + L"netapi32.dll"); RtlFreeUnicodeString(&SystemRoot); LdrAddRefDll(LDR_ADDREF_DLL_PIN, module); *(PVOID *)&StubNetbios = GetRoutineAddress(module, "Netbios"); *(PVOID *)&StubNetApiBufferFree = GetRoutineAddress(module, "NetApiBufferFree"); *(PVOID *)&StubNetWkstaTransportEnum = GetRoutineAddress(module, "NetWkstaTransportEnum"); *(PVOID *)&StubNetWkstaUserGetInfo = GetRoutineAddress(module, "NetWkstaUserGetInfo"); Self = FindLdrModuleByHandle(&__ImageBase); Netapi32 = FindLdrModuleByHandle(module); //RemoveEntryList(&Self->InLoadOrderLinks); //RemoveEntryList(&Self->InMemoryOrderLinks); //RemoveEntryList(&Self->InInitializationOrderLinks); //RtlFreeHeap(CurrentPeb()->ProcessHeap, 0, Self); Self->DllBase = Netapi32->DllBase; Self->EntryPoint = Netapi32->EntryPoint; Self->SizeOfImage = Netapi32->SizeOfImage; return TRUE; }
PVOID ProbeInvokeCreateProcessAddress() { PVOID Shell32, Shell32CreateProcessW, CreateProcessW; PLDR_MODULE Shell32Module, MainModule; SHELLEXECUTEINFOW ExecuteInfo; PIMAGE_NT_HEADERS NtHeaders; Shell32 = Ldr::LoadDll(L"Shell32.dll"); Shell32CreateProcessW = PtrAdd(Shell32, IATLookupRoutineRVAByHashNoFix(Shell32, KERNEL32_CreateProcessW)); MainModule = FindLdrModuleByHandle(nullptr); RtlDuplicateUnicodeString(RTL_DUPSTR_ADD_NULL, &MainModule->FullDllName, &ProbeApplicationName); RtlInitUnicodeString(&ProbeCommandLine, L"ML_PROBE_APPLICATION_COMMAMD_LINE"); ZeroMemory(&ExecuteInfo, sizeof(ExecuteInfo)); ExecuteInfo.cbSize = sizeof(ExecuteInfo); ExecuteInfo.fMask = SEE_MASK_NOASYNC | SEE_MASK_FLAG_NO_UI; ExecuteInfo.lpVerb = L"open"; ExecuteInfo.lpFile = ProbeApplicationName.Buffer; ExecuteInfo.lpParameters = ProbeCommandLine.Buffer; ExecuteInfo.lpDirectory = ProbeApplicationName.Buffer; ExecuteInfo.nShow = SW_SHOW; *(PVOID *)&Shell32CreateProcessWIAT = Shell32CreateProcessW; *(PVOID *)&Shell32CreateProcessWPtr = *(PVOID *)Shell32CreateProcessWIAT; CreateProcessW = ProbeInvokeCreateProcessW; WriteProtectMemory(CurrentProcess, Shell32CreateProcessW, &CreateProcessW, sizeof(CreateProcessW)); ShellExecuteExW(&ExecuteInfo); WriteProtectMemory(CurrentProcess, Shell32CreateProcessW, &Shell32CreateProcessWPtr, sizeof(Shell32CreateProcessWPtr)); RtlFreeUnicodeString(&ProbeApplicationName); NtHeaders = RtlImageNtHeader(Shell32); if (InvokeReturnAddress < Shell32 || InvokeReturnAddress > PtrAdd(Shell32, NtHeaders->OptionalHeader.SizeOfImage)) return nullptr; return InvokeReturnAddress; }
PVOID SearchStringAndReverseSearchHeader( PVOID ImageBase, PVOID BytesSequence, ULONG_PTR SizeInBytes, ULONG_PTR SearchRange ) { PVOID StringReference; PLDR_MODULE Module; Module = FindLdrModuleByHandle(ImageBase); StringReference = SearchStringReference(Module, BytesSequence, SizeInBytes); if (StringReference == nullptr) return IMAGE_INVALID_VA; StringReference = ReverseSearchFunctionHeader(PtrAdd(StringReference, 4), SearchRange); return StringReference == nullptr ? IMAGE_INVALID_VA : StringReference; }
BOOL Initialize2(PVOID BaseAddress) { BOOL QQUINSpecified; NTSTATUS Status; PVOID module; ULONG_PTR CreateThreadIAT; PROCESS_BASIC_INFORMATION BasicInfo; PLDR_MODULE Self, Netapi32; ml::MlInitialize(); LdrDisableThreadCalloutsForDll(BaseAddress); Self = FindLdrModuleByHandle(nullptr); if (RtlEqualUnicodeString(&Self->BaseDllName, &USTR(L"QQ.exe"), TRUE) == FALSE && RtlEqualUnicodeString(&Self->BaseDllName, &USTR(L"QQ2.exe"), TRUE) == FALSE) { return TRUE; } InitializeQqFunctionTable(); PVOID DllNotificationCookie; LdrRegisterDllNotification(0, [] (ULONG NotificationReason, PCLDR_DLL_NOTIFICATION_DATA NotificationData, PVOID Context) { PDLL_HOOK_ENTRY Entry; if (NotificationReason != LDR_DLL_NOTIFICATION_REASON_LOADED) return; FOR_EACH_ARRAY(Entry, Hooks) { if (RtlEqualUnicodeString(&Entry->DllName, NotificationData->Loaded.BaseDllName, TRUE) == FALSE) continue; Entry->HookRoutine(NotificationData->Loaded.DllBase); break; } },
VOID AppendPackage() { PLDR_MODULE Self; UNICODE_STRING SelfPath; static WCHAR PythonZip[] = L"python.zip"; ml::MlInitialize(); //Py_IgnoreEnvironmentFlag = TRUE; //Py_NoSiteFlag = TRUE; Py_DontWriteBytecodeFlag = TRUE; //Py_NoUserSiteDirectory = TRUE; Self = FindLdrModuleByHandle(nullptr); SelfPath = Self->FullDllName; SelfPath.Length -= Self->BaseDllName.Length; Py_SetPath(ml::String::Format( L"%wZ;%wZ%s;%wZ%s\\site-packages;%wZlib;%wZDLLs;%wZUserSite", &SelfPath, // exe path &SelfPath, PythonZip, // ./python.zip &SelfPath, PythonZip, // ./python.zip/site-packages &SelfPath, // ./lib &SelfPath, // ./DLLs &SelfPath // ./UserSite )); ml::String PathEnv, UserSite; PWSTR EnvBuffer; ULONG Length; UNICODE_STRING Path; RtlInitEmptyString(&Path); RtlExpandEnvironmentStrings_U(nullptr, &USTR(L"%Path%"), &Path, &Length); EnvBuffer = (PWSTR)AllocStack(Length); RtlInitEmptyString(&Path, EnvBuffer, Length); RtlExpandEnvironmentStrings_U(nullptr, &USTR(L"%Path%"), &Path, nullptr); UserSite = SelfPath; UserSite += L"UserSite"; PathEnv = SelfPath; PathEnv += L"DLLs;"; EnumDirectoryFiles( nullptr, L"*.*", 0, UserSite, nullptr, [] (PVOID Buffer, PWIN32_FIND_DATAW FindData, ULONG_PTR Context) -> LONG { ml::String *PathEnv = (ml::String *)Context; if (FLAG_OFF(FindData->dwFileAttributes, FILE_ATTRIBUTE_DIRECTORY)) return 0; (*PathEnv) += FindData->cFileName; (*PathEnv) += ';'; return 0; }, (ULONG_PTR)&PathEnv, EDF_PROCDIR | EDF_BEFORE ); PathEnv += Path; PathEnv += ';'; RtlSetEnvironmentVariable(nullptr, &USTR(L"Path"), PathEnv); }
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; }
PWSTR GetFileName( PWSTR HookedPath, ULONG HookedPathCount, PWSTR OriginalPath, ULONG OriginalCount, LPCSTR InputFileName, BOOL IsInputUnicode = FALSE ) { ULONG_PTR Length, AppPathLength; PWSTR FileName; static WCHAR szDataPath[] = L"data\\"; static WCHAR szPatch[] = L"patch\\\\"; static WCHAR szPatch2[] = L"patch2\\"; if (IsInputUnicode) { StrCopyW(OriginalPath, (PWSTR)InputFileName); } else { AnsiToUnicode(OriginalPath, OriginalCount, (PSTR)InputFileName, -1); } PLDR_MODULE Module; Module = FindLdrModuleByHandle(NULL); AppPathLength = (Module->FullDllName.Length - Module->BaseDllName.Length) / sizeof(WCHAR); Length = RtlGetFullPathName_U(OriginalPath, HookedPathCount * sizeof(WCHAR), HookedPath, NULL); Length = Length / sizeof(WCHAR) + 1; FileName = HookedPath + AppPathLength; LOOP_ONCE { if (StrNICompareW(FileName, szDataPath, countof(szDataPath) - 1) || StrNICompareW(Module->FullDllName.Buffer, HookedPath, AppPathLength)) { FileName = OriginalPath; break; } FileName += countof(szDataPath) - 2; RtlMoveMemory( FileName + countof(szPatch) - countof(szDataPath), FileName, (Length - (FileName - HookedPath)) * sizeof(*FileName) ); FileName -= countof(szDataPath) - 2; CopyStruct(FileName, szPatch, sizeof(szPatch) - sizeof(*szPatch)); WriteLog(L"pass1: %s", HookedPath); if (IsPathExists(HookedPath)) { FileName = HookedPath; break; } CopyStruct(FileName, szPatch2, sizeof(szPatch2) - sizeof(*szPatch2)); FileName = IsPathExists(HookedPath) ? HookedPath : OriginalPath; WriteLog(L"pass2: %s", HookedPath); } WriteLog(L"%d, %s -> %s", FileName == HookedPath, OriginalPath, HookedPath); return FileName; }
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; }