Here's some proof of concept code that anyone can play with to determine how RegQueryValueEx reacts to any type of data written to the key. The code first lists all the strings from the key and then it appends a new string to the key. So, you can modify the RegSetValueEx call to write any type of crazy data to the key whether or not that data is null terminated. Take the really incompetent programmer approach and get really creative (crazy) with what you write to the key.
You'll have to create the registry key prior to running the code.
Code:
// The following registry key must exist prior to running app
// HKEY_LOCAL_MACHINE\Software\TestKey\TestSubKey
// TestSubKey is a REG_MULTI_SZ key
#pragma comment ( lib, "advapi32.lib" )
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <time.h>
int main(void)
{
HKEY hKey = NULL;
DWORD dwReturn = ERROR_SUCCESS;
char szNewString[MAX_PATH] = {0};
srand(time(NULL));
_snprintf(szNewString,sizeof(szNewString), _T("NewString%d"),rand() % 100);
dwReturn = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
TEXT("Software\\TestKey"),
0,
KEY_ALL_ACCESS,
&hKey
);
if( dwReturn == ERROR_SUCCESS )
{
DWORD dwSize;
dwReturn = RegQueryValueEx(
hKey,
TEXT("TestSubKey"),
0,
0,
0,
&dwSize
);
if( dwReturn == ERROR_SUCCESS )
{
DWORD dwType;
DWORD dwNewSize = dwSize + _tcslen(szNewString) ;
LPBYTE lpBuffer = LPBYTE(GlobalAlloc(GPTR, dwNewSize + 1));
if( lpBuffer == NULL )
{
_tprintf("GlobalAlloc failed (%d)\n", GetLastError());
RegCloseKey(hKey);
return -1;
}
dwReturn = RegQueryValueEx(
hKey,
TEXT("TestSubKey"),
0,
&dwType,
lpBuffer,
&dwSize
);
if( dwReturn == ERROR_SUCCESS )
{
LPTSTR p = LPTSTR(lpBuffer);
for(; *p; p += _tcslen(p) + 1)
_tprintf("%s\n",p);
if(!*p)
{
_tcscpy(p,szNewString );
dwReturn = RegSetValueEx(
hKey,
TEXT("TestSubKey"),
0,
dwType,
lpBuffer,
dwNewSize
);
if( dwReturn == ERROR_SUCCESS )
_tprintf("Registry update successful\n");
else _tprintf("Registry update FAILED\n");
}
else _tprintf("pointer is not at end of buffer\n");
}
else _tprintf("Second RegQueryValueEx failed\n");
GlobalFree(HGLOBAL(lpBuffer));
}
else _tprintf("First RegQueryValueEx failed\n");
RegCloseKey(hKey);
}
else _tprintf("RegOpenKeyEx failed\n");
return 0;
}