Skip to content
This repository has been archived by the owner on Apr 15, 2022. It is now read-only.

Commit

Permalink
Merge pull request #3 from fotile96/10.21390.2025
Browse files Browse the repository at this point in the history
Fix for Windows 11
  • Loading branch information
xupefei committed Aug 23, 2021
2 parents 400b08f + c1c43a7 commit ae7160d
Show file tree
Hide file tree
Showing 5 changed files with 165 additions and 19 deletions.
27 changes: 18 additions & 9 deletions LocaleEmulator/Hooks/Gdi32Hook.cpp
@@ -1,4 +1,5 @@
#include "stdafx.h"
#include <algorithm>

ULONG (NTAPI *GdiGetCodePage)(HDC NewDC);

Expand Down Expand Up @@ -129,12 +130,9 @@ VOID LeGlobalData::AddTextMetricToCache(LPENUMLOGFONTEXW LogFont, PTEXT_METRIC_I

HGDIOBJ NTAPI LeGetStockObject(LONG Object)
{
HGDIOBJ StockObject;
PULONG_PTR Index;
PLeGlobalData GlobalData = LeGetGlobalData();

StockObject = nullptr;

static ULONG_PTR StockObjectIndex[] =
{
ANSI_FIXED_FONT,
Expand All @@ -146,7 +144,7 @@ HGDIOBJ NTAPI LeGetStockObject(LONG Object)
SYSTEM_FIXED_FONT,
};

if (!GlobalData->HookRoutineData.Gdi32.StockObjectInitialized)
/*if (!GlobalData->HookRoutineData.Gdi32.StockObjectInitialized)
{
PROTECT_SECTION(&GlobalData->HookRoutineData.Gdi32.GdiLock)
{
Expand All @@ -160,17 +158,27 @@ HGDIOBJ NTAPI LeGetStockObject(LONG Object)
GlobalData->HookRoutineData.Gdi32.StockObjectInitialized = TRUE;
}
}
}*/

LOOP_ONCE
{
if (Object > countof(GlobalData->HookRoutineData.Gdi32.StockObject))
if (Object >= countof(GlobalData->HookRoutineData.Gdi32.StockObject))
break;

StockObject = GlobalData->HookRoutineData.Gdi32.StockObject[Object];
auto& StockObject = GlobalData->HookRoutineData.Gdi32.StockObject[Object];

if (StockObject != nullptr)
return StockObject;

auto StockObjectIndexLast = StockObjectIndex + countof(StockObjectIndex);

if (std::find(StockObjectIndex, StockObjectIndexLast, Object) != StockObjectIndexLast) {
PROTECT_SECTION(&GlobalData->HookRoutineData.Gdi32.GdiLock) {
if (StockObject == nullptr)
return StockObject = GetFontFromFont(GlobalData, (HFONT)GlobalData->GetStockObject(Object));
return StockObject;
}
}
}

return GlobalData->GetStockObject(Object);
Expand All @@ -181,7 +189,8 @@ BOOL NTAPI LeDeleteObject(HGDIOBJ GdiObject)
HGDIOBJ* StockObject;
PLeGlobalData GlobalData = LeGetGlobalData();

if (GdiObject == nullptr || GlobalData->HookRoutineData.Gdi32.StockObjectInitialized == FALSE)
//if (GdiObject == nullptr || GlobalData->HookRoutineData.Gdi32.StockObjectInitialized == FALSE)
if (GdiObject == nullptr)
return TRUE;

FOR_EACH_ARRAY(StockObject, GlobalData->HookRoutineData.Gdi32.StockObject)
Expand Down Expand Up @@ -727,7 +736,7 @@ LeNtGdiHfontCreate(
enumlfex->elfEnumLogfontEx.elfLogFont.lfCharSet = GlobalData->GetLeb()->DefaultCharset;

//if (GdiGetCodePage == NULL)
//CopyStruct(enumlfex.elfEnumLogfontEx.elfLogFont.lfFaceName, GlobalData->GetLeb()->DefaultFaceName, LF_FACESIZE);
//CopyStruct(enumlfex->elfEnumLogfontEx.elfLogFont.lfFaceName, GlobalData->GetLeb()->DefaultFaceName, LF_FACESIZE);
//AllocConsole();
//PrintConsoleW(L"%s\n", enumlfex.elfEnumLogfontEx.elfLogFont.lfFaceName);

Expand Down
108 changes: 108 additions & 0 deletions LocaleEmulator/Hooks/Kernel32Hook.cpp
Expand Up @@ -123,13 +123,121 @@ NTSTATUS LeGlobalData::HackUserDefaultLCID2(PVOID Kernel32)
return STATUS_SUCCESS;
}

void* GetFirstCallTarget(void* start_offset, DWORD parse_range, void **next) {
void* res = nullptr;
WalkOpCodeT(start_offset, parse_range,
WalkOpCodeM(Buffer, OpLength, Ret)
{
if (Buffer[0] != CALL) {
return STATUS_NOT_FOUND;
}

res = GetCallDestination(Buffer);
*next = &Buffer[OpLength];
return STATUS_SUCCESS;
}
);
return res;
}

void* GetKthCallTarget(void* start_offset, DWORD parse_range_each, int K) {
// returns nullptr if K == 0
if (start_offset == nullptr)
return nullptr;
void *next, *res = nullptr;
while (K >= 1) {
res = GetFirstCallTarget(start_offset, parse_range_each, &next);
if (res == nullptr)
return nullptr;
start_offset = next;
--K;
}
return res;
}

typedef DWORD(__stdcall* pSetupAnsiOemCodeHashNodes)();

NTSTATUS LeSetupAnsiOemCodeHashNodes() {

RTL_OSVERSIONINFOW osvi;

ZeroMemory(&osvi, sizeof(RTL_OSVERSIONINFOW));
osvi.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOW);

RtlGetVersion(&osvi);
if (osvi.dwMajorVersion < 10 || osvi.dwBuildNumber < 19042)
return STATUS_SUCCESS; // does not need this trick for older versions.


PLDR_MODULE Kernel = FindLdrModuleByName(&USTR(L"KERNELBASE.dll"));
if (Kernel == nullptr)
return STATUS_PROCEDURE_NOT_FOUND;

void* pKernelBaseDllInitialize = GetKthCallTarget(Kernel->EntryPoint, 0x30, 1);
if (pKernelBaseDllInitialize == nullptr)
return STATUS_PROCEDURE_NOT_FOUND;

WriteLog(L"KernelBaseDllInitialize: %p\n", pKernelBaseDllInitialize);

void* pKernelBaseBaseDllInitialize = GetKthCallTarget(pKernelBaseDllInitialize, 0x20, 2);
if (pKernelBaseBaseDllInitialize == nullptr)
return STATUS_PROCEDURE_NOT_FOUND;

WriteLog(L"KernelBaseBaseDllInitialize: %p\n", pKernelBaseBaseDllInitialize);

void* pBaseNlsDllInitialize = nullptr;
void* _;
WalkOpCodeT(pKernelBaseBaseDllInitialize, 0x400,
WalkOpCodeM(Buffer, OpLength, Ret)
{
if (Buffer[0] != 0xB8 || *((DWORD*)&Buffer[1]) != 0x190) {
// locate first `mov eax, 0x190`
return STATUS_NOT_FOUND;
}
_ = Buffer;
pBaseNlsDllInitialize = GetKthCallTarget(_, 0x20, 1);
return STATUS_SUCCESS;
}
);
if (pBaseNlsDllInitialize == nullptr)
return STATUS_PROCEDURE_NOT_FOUND;

WriteLog(L"BaseNlsDllInitialize: %p\n", pBaseNlsDllInitialize);

void* pNlsProcessInitialize = GetKthCallTarget(pBaseNlsDllInitialize, 0x30, 1);
if (pNlsProcessInitialize == nullptr)
return STATUS_PROCEDURE_NOT_FOUND;

WriteLog(L"NlsProcessInitialize: %p\n", pNlsProcessInitialize);

auto the_func = (pSetupAnsiOemCodeHashNodes)GetKthCallTarget(pNlsProcessInitialize, 0x30, 3);
if (the_func == nullptr)
return STATUS_PROCEDURE_NOT_FOUND;

WriteLog(L"SetupAnsiOemCodeHashNodes: %p\n", the_func);

the_func();
}

NTSTATUS LeGlobalData::HackAnsiOemCodeHashNodes() {
PLeGlobalData GlobalData = LeGetGlobalData();

unsigned char* pTeb = (unsigned char*)(__readfsdword(48));
*(short*)(pTeb + 0x228) = GlobalData->GetLeb()->AnsiCodePage;
*(short*)(pTeb + 0x22a) = GlobalData->GetLeb()->OemCodePage;

return LeSetupAnsiOemCodeHashNodes();
}

NTSTATUS LeGlobalData::HookKernel32Routines(PVOID Kernel32)
{
PVOID GetCurrentNlsCache;
NTSTATUS Status;

Status = this->HackUserDefaultLCID2(Kernel32);

Status = this->HackAnsiOemCodeHashNodes();

WriteLog(L"hook k32: %p", Status);

return Status;
Expand Down
24 changes: 24 additions & 0 deletions LocaleEmulator/Hooks/NtdllHook.cpp
Expand Up @@ -872,6 +872,27 @@ LONG NTAPI LeKnownExceptionFilter(PEXCEPTION_POINTERS ExceptionPointers)
return Result;
}

NTSTATUS NTAPI LeCustomCPToUnicodeN(IN PCPTABLEINFO CustomCP,
OUT PWCHAR UnicodeString,
IN ULONG UnicodeSize,
OUT PULONG ResultSize OPTIONAL,
IN PCHAR CustomString,
IN ULONG CustomSize) {
PLeGlobalData GlobalData = LeGetGlobalData();

if (CustomCP->CodePage != 65001 && CustomCP->CodePage != GlobalData->GetLeb()->AnsiCodePage) {
PROTECT_SECTION(&GlobalData->HookRoutineData.Ntdll.NtLock) {
if (CustomCP->CodePage != 65001 && CustomCP->CodePage != GlobalData->GetLeb()->AnsiCodePage) {
RtlInitCodePageTable((PUSHORT)PtrAdd(GlobalData->CodePageMapView,
GlobalData->AnsiCodePageOffset), CustomCP);
}
}
}

return GlobalData->HookStub.StubRtlCustomCPToUnicodeN(CustomCP, UnicodeString,
UnicodeSize, ResultSize, CustomString, CustomSize);
}

NTSTATUS LeGlobalData::HookNtdllRoutines(PVOID Ntdll)
{
NTSTATUS Status;
Expand Down Expand Up @@ -912,10 +933,13 @@ NTSTATUS LeGlobalData::HookNtdllRoutines(PVOID Ntdll)
{
Mp::FunctionCallVa(LdrInitNtContinue, LeLdrInitNtContinue, &HookStub.StubLdrInitNtContinue),
Mp::FunctionJumpVa(::RtlKnownExceptionFilter, LeKnownExceptionFilter, &HookStub.StubRtlKnownExceptionFilter),
Mp::FunctionJumpVa(::RtlCustomCPToUnicodeN, LeCustomCPToUnicodeN, &HookStub.StubRtlCustomCPToUnicodeN),
};

Mp::PatchMemory(p, countof(p));

RtlInitializeCriticalSectionAndSpinCount(&HookRoutineData.Ntdll.NtLock, 4000);

return STATUS_SUCCESS;
}

Expand Down
10 changes: 9 additions & 1 deletion LocaleEmulator/LocaleEmulator.h
Expand Up @@ -523,9 +523,11 @@ class LeGlobalData
ml::GrowableArray<REGISTRY_REDIRECTION_ENTRY> RegistryRedirectionEntry;
ml::HashTableT<TEXT_METRIC_INTERNAL> TextMetricCache;

public:
PVOID CodePageMapView;
ULONG_PTR AnsiCodePageOffset, OemCodePageOffset, UnicodeCaseTableOffset;

protected:
PVOID DllNotificationCookie;

UNICODE_STRING SystemDirectory;
Expand All @@ -544,6 +546,7 @@ class LeGlobalData
API_POINTER(RtlKnownExceptionFilter) StubRtlKnownExceptionFilter;
API_POINTER(NtContinue) StubLdrInitNtContinue;
API_POINTER(LdrResSearchResource) StubLdrResSearchResource;
API_POINTER(RtlCustomCPToUnicodeN) StubRtlCustomCPToUnicodeN;

API_POINTER(NtUserMessageCall) StubNtUserMessageCall;
API_POINTER(NtUserDefSetText) StubNtUserDefSetText;
Expand Down Expand Up @@ -587,13 +590,16 @@ class LeGlobalData
RtlFreeUnicodeString(&Ntdll.CodePageKey);
RtlFreeUnicodeString(&Ntdll.LanguageKey);
RtlDeleteCriticalSection(&Gdi32.GdiLock);
RtlDeleteCriticalSection(&Ntdll.NtLock);
}

struct
{
UNICODE_STRING CodePageKey;
UNICODE_STRING LanguageKey;

RTL_CRITICAL_SECTION NtLock;

} Ntdll;

struct
Expand All @@ -602,7 +608,8 @@ class LeGlobalData

struct
{
BOOLEAN StockObjectInitialized : 1;
// maybe set up a flag for each kind of object?
//BOOLEAN StockObjectInitialized : 1;

RTL_CRITICAL_SECTION GdiLock;

Expand Down Expand Up @@ -702,6 +709,7 @@ class LeGlobalData

NTSTATUS HackUserDefaultLCID(PVOID Kernel32);
NTSTATUS HackUserDefaultLCID2(PVOID Kernel32);
NTSTATUS HackAnsiOemCodeHashNodes();
NTSTATUS InjectSelfToChildProcess(HANDLE Process, PCLIENT_ID Cid);

/************************************************************************
Expand Down
15 changes: 6 additions & 9 deletions LocaleEmulator/ml.cpp
Expand Up @@ -6964,17 +6964,14 @@ CreateFileInternalWithFullPath(
*/
InitializeObjectAttributes(&ObjectAttributes, FileName, OBJ_CASE_INSENSITIVE, nullptr, nullptr);

API_POINTER(ZwCreateFile) XCreateFile;
static API_POINTER(ZwCreateFile) XCreateFile;

#if ML_KERNEL_MODE

XCreateFile = ZwCreateFile;

#else
if (XCreateFile == nullptr) {

XCreateFile = NtCreateFile;
PLDR_MODULE Nt = FindLdrModuleByName(&USTR(L"ntdll.dll"));

#endif
XCreateFile = (API_POINTER(ZwCreateFile))LookupExportTable(Nt->DllBase, NTDLL_NtCreateFile);
}

Status = XCreateFile(
FileHandle,
Expand Down Expand Up @@ -14544,4 +14541,4 @@ Nt_FreeMemory(

MY_NAMESPACE_END

#endif
#endif

0 comments on commit ae7160d

Please sign in to comment.