Skip to content

Commit

Permalink
Format & Type Enhancements To /RegOverride
Browse files Browse the repository at this point in the history
- Allow registry numerical values to be specified in octal or hex format.
- Allow override of REG_QWORD types.
- Updated version to 1.0.3.0 and compiled/signed binaries.
- Changed registry query behavior to more accurately mimic the native routine when an insufficent buffer is supplied.
- Addressed issue where successive /RegOverride commmands would not work.
  • Loading branch information
NoMoreFood committed Jun 14, 2018
1 parent 5a3ac57 commit b052895
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 56 deletions.
30 changes: 15 additions & 15 deletions Build/WinPriv-hash.txt
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@

Algorithm Hash Path
--------- ---- ----
SHA256 1F3D88165DE705F833C080F7BAD3EC8013854EE5BA1DD5CA86152104F0014F82 x64\WinPriv.exe
SHA256 E22303994A24F0B7C74426E3223CB114E6F885FCCCE451188E65F71132AC60AA x64\WinPrivCmd.exe
SHA256 F07FD74C808DF528149B978F6C2EDEF16F2D993F9DFD70AD8EEF6C9B97398291 x86\WinPriv.exe
SHA256 2F382647FF587B7C70BE9C73FDA25AF7CA5DE149C55877D2FBE1CB8BD1A4C6B8 x86\WinPrivCmd.exe
SHA256 34AE925B652BFA03A36BFD728C0EC9C429C60A5C0E5C21F4351798C3DB0EC865 WinPriv.zip
SHA256 447B8774DA7E9B83EDED50C2EA5C64C0973669D543FC51DAC03B07F3BF5644BD x64\WinPriv.exe
SHA256 1EE798FFBD84142B46B209D569EA30210930B994C1F9173328A08187E9C3C36C x64\WinPrivCmd.exe
SHA256 6EAB565F15B8D140A7BB690D26E4EE4AA8B792E7D288B1CC10CA0E41BE81D63D x86\WinPriv.exe
SHA256 F4BF456304DD40488B4DF4FAA395F942BC809ECCD9BB73B51461EE02F740EACC x86\WinPrivCmd.exe
SHA256 8D05DD4B4A2F5CAD17DDC3862CA757AF53CF8728CA0996EE3B57D6E9C4E67833 WinPriv.zip



Algorithm Hash Path
--------- ---- ----
SHA1 A8EB525CEDF7AE340E178DA07ABADA9A735197A3 x64\WinPriv.exe
SHA1 B85A571643186788662F6C6FE04F4A458F5C42B7 x64\WinPrivCmd.exe
SHA1 6691DCA6E3691AC777A4224DF7E11BB60114AFC1 x86\WinPriv.exe
SHA1 8A4DBB4700D7B712EB319C350E06A423FAB320FE x86\WinPrivCmd.exe
SHA1 BA0B0BD31DBCEA8D00016305B95C233EB11358E2 WinPriv.zip
SHA1 81F9ECB11140D275C6C75D3AB16179524145FE27 x64\WinPriv.exe
SHA1 4514E1FF080F8A727080750217A465A29C34C720 x64\WinPrivCmd.exe
SHA1 2CDDC34CC839D2D7408243F8AD9C04D5D90E8F5F x86\WinPriv.exe
SHA1 9AFFC6F7BC311B4B3E7A3934C72CE64845DD19D0 x86\WinPrivCmd.exe
SHA1 361FCB0645B22A260C2C36931AF1BF6EF661DF8A WinPriv.zip



Algorithm Hash Path
--------- ---- ----
MD5 438A11FEF70928ECC17BFCF8E2155CE2 x64\WinPriv.exe
MD5 04B3CD0192FA339AA3D8E8FDE1F3C3D6 x64\WinPrivCmd.exe
MD5 91E669F6CD5236D7565447F755E78A48 x86\WinPriv.exe
MD5 1758F6A17B569F76B4E6F4AE3F1D113F x86\WinPrivCmd.exe
MD5 225D18F69E1252A4E9F07B2B557E0785 WinPriv.zip
MD5 BDEE609386160B8B402801785B775863 x64\WinPriv.exe
MD5 150C87455D0037BAC4955C1C54F40335 x64\WinPrivCmd.exe
MD5 C6862E5B65950D9326AD59D16A4CA0FB x86\WinPriv.exe
MD5 2BD2E18E8EC664484BC4265006D5736C x86\WinPrivCmd.exe
MD5 6B3BF0A247FE34BC5EE58707CEB0340D WinPriv.zip


Binary file modified Build/WinPriv.zip
Binary file not shown.
Binary file modified Build/x64/WinPriv.exe
Binary file not shown.
Binary file modified Build/x64/WinPrivCmd.exe
Binary file not shown.
Binary file modified Build/x86/WinPriv.exe
Binary file not shown.
Binary file modified Build/x86/WinPrivCmd.exe
Binary file not shown.
Binary file modified WinPriv/WinPrivResource.rc
Binary file not shown.
119 changes: 78 additions & 41 deletions WinPrivLibrary/WinPrivLibraryDetours.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
#include "WinPrivShared.h"
#include "WinPrivLibrary.h"

#define sizereq(x,y) (offsetof(x,y) + sizeof(((x*) NULL)->y))
#define align(x,y) ((((uintptr_t) (x)) + (((y)/CHAR_BIT)-1)) & ~(((y)/CHAR_BIT)-1))
// ___ ___ __ __ ___
// |__ | | |__ / \ |__) |__ |\ |
// | | |___ |___ \__/ | |___ | \|
Expand Down Expand Up @@ -125,25 +127,32 @@ EXTERN_C NTSTATUS WINAPI DetourNtQueryValueKey(_In_ HANDLE KeyHandle,
if (tInterceptInfo->RegKeyName.Length == NULL) break;

// fetch value name
LPWSTR sValueName = sParams[1];
LPWSTR sValueName = sParams[iParam + 1];
tInterceptInfo->RegValueName = { (USHORT)wcslen(sValueName) * sizeof(WCHAR),
(USHORT)wcslen(sValueName) * sizeof(WCHAR), _wcsdup(sValueName) };

// match the aesthetic types to the typed enumerations
LPWSTR sType = sParams[2];
LPWSTR sType = sParams[iParam + 2];
if (_wcsicmp(sType, L"REG_DWORD") == 0) tInterceptInfo->RegValueType = REG_DWORD;
else if (_wcsicmp(sType, L"REG_QWORD") == 0) tInterceptInfo->RegValueType = REG_QWORD;
else if (_wcsicmp(sType, L"REG_SZ") == 0) tInterceptInfo->RegValueType = REG_SZ;
else if (_wcsicmp(sType, L"REG_BLOCK") == 0) tInterceptInfo->RegValueType = -1;
else break;

// decode the value string to a data blob
LPWSTR sData = sParams[3];
LPWSTR sData = sParams[iParam + 3];
if (tInterceptInfo->RegValueType == REG_DWORD)
{
tInterceptInfo->RegValueData = (DWORD *)malloc(sizeof(DWORD));
swscanf(sData, L"%lu", (DWORD *)tInterceptInfo->RegValueData);
swscanf(sData, L"%li", (DWORD *)tInterceptInfo->RegValueData);
tInterceptInfo->RegValueDataSize = sizeof(DWORD);
}
else if (tInterceptInfo->RegValueType == REG_QWORD)
{
tInterceptInfo->RegValueData = (unsigned __int64 *)malloc(sizeof(unsigned __int64));
swscanf(sData, L"%lli", (unsigned __int64 *)tInterceptInfo->RegValueData);
tInterceptInfo->RegValueDataSize = sizeof(unsigned __int64);
}
else if (tInterceptInfo->RegValueType == REG_SZ)
{
tInterceptInfo->RegValueData = sData;
Expand Down Expand Up @@ -179,7 +188,7 @@ EXTERN_C NTSTATUS WINAPI DetourNtQueryValueKey(_In_ HANDLE KeyHandle,
// allocate space for name and lookup
NTSTATUS iStatus = -1;
PKEY_NAME_INFORMATION pNameInfo = (PKEY_NAME_INFORMATION)malloc(iKeyNameSize);
if (pNameInfo != NULL && NtQueryKey(KeyHandle, KeyNameInformation, pNameInfo,
if (pNameInfo != NULL && NtQueryKey(KeyHandle, KeyNameInformation, pNameInfo,
iKeyNameSize, &iKeyNameSize) == STATUS_SUCCESS)
{
// convert to unicode string structure for quick comparisons
Expand All @@ -204,50 +213,78 @@ EXTERN_C NTSTATUS WINAPI DetourNtQueryValueKey(_In_ HANDLE KeyHandle,
if (KeyValueInformationClass == KeyValueFullInformation ||
KeyValueInformationClass == KeyValueFullInformationAlign64)
{
// calculated required size and return if not large enough
*ResultLength = offsetof(KEY_VALUE_FULL_INFORMATION, Name) +
tRegOverrideInfo->RegKeyName.Length + tRegOverrideInfo->RegValueDataSize;
if (*ResultLength > Length)
const UINT_PTR alignment = (KeyValueInformationClass == KeyValueFullInformation) ? 32 : 64;
iStatus = Length >= sizeof(ULONG) ? STATUS_BUFFER_OVERFLOW : STATUS_BUFFER_TOO_SMALL;
*ResultLength = (ULONG)align(offsetof(KEY_VALUE_FULL_INFORMATION, Name) +
tRegOverrideInfo->RegValueName.Length + tRegOverrideInfo->RegValueDataSize, alignment);

PKEY_VALUE_FULL_INFORMATION tKeyInfo = (PKEY_VALUE_FULL_INFORMATION)KeyValueInformation;

if (sizereq(KEY_VALUE_FULL_INFORMATION, TitleIndex) <= Length)
{
tKeyInfo->TitleIndex = 0;
}
if (sizereq(KEY_VALUE_FULL_INFORMATION, Type) <= Length)
{
iStatus = STATUS_BUFFER_TOO_SMALL;
break;
tKeyInfo->Type = tRegOverrideInfo->RegValueType;
}
if (sizereq(KEY_VALUE_FULL_INFORMATION, NameLength) <= Length)
{
tKeyInfo->NameLength = tRegOverrideInfo->RegValueName.Length;
}
if (sizereq(KEY_VALUE_FULL_INFORMATION, DataLength) <= Length)
{
tKeyInfo->DataLength = tRegOverrideInfo->RegValueDataSize;
}

// populate type and name information
PKEY_VALUE_FULL_INFORMATION tKeyInfo = (PKEY_VALUE_FULL_INFORMATION)KeyValueInformation;
tKeyInfo->TitleIndex = 0;
tKeyInfo->Type = tRegOverrideInfo->RegValueType;
tKeyInfo->NameLength = tRegOverrideInfo->RegKeyName.Length;
memcpy(tKeyInfo->Name, tRegOverrideInfo->RegValueName.Buffer, tRegOverrideInfo->RegKeyName.Length);

// populate data
tKeyInfo->DataLength = tRegOverrideInfo->RegValueDataSize;
tKeyInfo->DataOffset = (ULONG)((LPBYTE)&tKeyInfo->Name - (LPBYTE)tKeyInfo) + tKeyInfo->NameLength;
LPVOID pData = (DWORD *)((LPBYTE)KeyValueInformation + tKeyInfo->DataOffset);
memcpy(pData, tRegOverrideInfo->RegValueData, tKeyInfo->DataLength);
iStatus = STATUS_SUCCESS;
// copy name payload
const ULONG iNameRequiredSize = (ULONG)offsetof(KEY_VALUE_FULL_INFORMATION, Name) + tKeyInfo->NameLength;
if (iNameRequiredSize <= Length)
{
memcpy(tKeyInfo->Name, tRegOverrideInfo->RegValueName.Buffer, tKeyInfo->NameLength);
}

// copy data payload
const ULONG iDataRequiredSize = (ULONG)align(iNameRequiredSize + tKeyInfo->DataLength, alignment);
if (iDataRequiredSize <= Length)
{
tKeyInfo->DataOffset = (ULONG)align(iNameRequiredSize, alignment);
LPVOID pData = (LPVOID)align(((LPBYTE)KeyValueInformation + tKeyInfo->DataOffset), alignment);
memcpy(pData, tRegOverrideInfo->RegValueData, tKeyInfo->DataLength);
iStatus = STATUS_SUCCESS;
}
}
else if (KeyValueInformationClass == KeyValuePartialInformation ||
KeyValueInformationClass == KeyValuePartialInformationAlign64)
{
// calculated required size and return if not large enough
*ResultLength = offsetof(KEY_VALUE_PARTIAL_INFORMATION, Data) +
tRegOverrideInfo->RegValueDataSize;
if (*ResultLength > Length)
{
iStatus = STATUS_BUFFER_TOO_SMALL;
break;
}
// calculate required size and set default status
const UINT_PTR alignment = (KeyValueInformationClass == KeyValuePartialInformation) ? 32 : 64;
iStatus = Length >= sizeof(ULONG) ? STATUS_BUFFER_OVERFLOW : STATUS_BUFFER_TOO_SMALL;
*ResultLength = (ULONG)align(offsetof(KEY_VALUE_PARTIAL_INFORMATION, Data) +
tRegOverrideInfo->RegValueDataSize, alignment);

// populate type information
PKEY_VALUE_PARTIAL_INFORMATION tKeyInfo = (PKEY_VALUE_PARTIAL_INFORMATION)KeyValueInformation;
tKeyInfo->TitleIndex = 0;
tKeyInfo->Type = tRegOverrideInfo->RegValueType;

// populate data
tKeyInfo->DataLength = tRegOverrideInfo->RegValueDataSize;
memcpy(tKeyInfo->Data, tRegOverrideInfo->RegValueData, tKeyInfo->DataLength);
iStatus = STATUS_SUCCESS;
if (sizereq(KEY_VALUE_PARTIAL_INFORMATION, TitleIndex) <= Length)
{
tKeyInfo->TitleIndex = 0;
}
if (sizereq(KEY_VALUE_PARTIAL_INFORMATION, Type) <= Length)
{
tKeyInfo->Type = tRegOverrideInfo->RegValueType;
}
if (sizereq(KEY_VALUE_PARTIAL_INFORMATION, DataLength) <= Length)
{
tKeyInfo->DataLength = tRegOverrideInfo->RegValueDataSize;
}

// copy data payload
if (*ResultLength <= Length)
{
memcpy((PVOID)align(tKeyInfo->Data, alignment),
tRegOverrideInfo->RegValueData, tKeyInfo->DataLength);
iStatus = STATUS_SUCCESS;
}
}
}
}
Expand Down Expand Up @@ -278,7 +315,7 @@ EXTERN_C NTSTATUS WINAPI DetourNtEnumerateValueKey(_In_ HANDLE KeyHandle, _In_ U
NTSTATUS iStatus = TrueNtEnumerateValueKey(KeyHandle, Index,
KeyValueInformationClass, KeyValueInformation, Length, ResultLength);

if (iStatus == STATUS_SUCCESS && KeyValueInformation != NULL &&
if (iStatus == STATUS_SUCCESS && KeyValueInformation != NULL &&
(KeyValueInformationClass == KeyValueFullInformation ||
KeyValueInformationClass == KeyValueFullInformationAlign64))
{
Expand Down Expand Up @@ -397,7 +434,7 @@ void UpdateIpAddress(_In_ LPCWSTR sName, _Inout_ LPSOCKADDR tSockToUpdate)
{
static INT iHostOverrideParams = 0;
static LPWSTR * sHostOverride = CommandLineToArgvW(_wgetenv(WINPRIV_EV_HOST_OVERRIDE), &iHostOverrideParams);
wprintf(L"\n\nLookup: %s\n\n", sName);

// parse the parameters to create the intercept list
for (int iParam = 0; iParam < iHostOverrideParams; iParam += 2)
{
Expand Down

0 comments on commit b052895

Please sign in to comment.