C++ write an array to a binary entry in the registry - c++

I need to write an array into a BINARY registry key.
The array contains a series of characters...
char ArrayUserName[100]
it is loaded with the value of ZK8ORQ1
I need to write that value to a binary value (REG_BINARY) in the registry.
void WriteRegistryValues()
{
DWORD dwDisposition;
FILE *fileb;
fileb = fopen("C:\\logs\\cplog2.txt", "a+");
fprintf(fileb,"Field ID %d: [%s]\n", 2, ArrayUserName);
fprintf(fileb,"Field ID %d: [%s]\n", 3, ArrayPassword);
HKEY hKey;
LPCTSTR sk = TEXT("SOFTWARE\\XXXX\\YYYY\\GINA");
LONG openRes = RegOpenKeyEx(HKEY_LOCAL_MACHINE, sk, 0, KEY_ALL_ACCESS , &hKey);
if (openRes==ERROR_SUCCESS) {
fprintf(fileb, "Success opening key.\n");
} else {
fprintf(fileb, "Error opening key.\n");
}
LPCTSTR value = TEXT("Domain");
LONG setRes = RegSetValueEx(hKey, value, 0, REG_BINARY, (CONST BYTE*)ArrayUserName, 100);
if (setRes == ERROR_SUCCESS) {
fprintf(fileb, "Success writing to Registry.\n");
} else {
fprintf(fileb, "Error writing to Registry.\n");
}
LONG closeOut = RegCloseKey(hKey);
if (closeOut == ERROR_SUCCESS) {
fprintf(fileb, "Success closing key.\n");
} else {
fprintf(fileb, "Error closing key.\n");
}
fclose(fileb);
In the text file, i see the values of the username and the password
as
Field ID 2: [zk8orq1]
Field ID 3: [P#ssword2]
Success opening key.
Error writing to Registry.
Success closing key.
What am i missing?
thank you

One thing I can see is that you want to use UCHAR byteRegArray, instead of char,
UCHAR byteRegArray[] = {0x01, 0x00....... };
RegSetValueEx(hKey, "sflaksdfl;asjdf", 0, REG_BINARY, (BYTE *)byteRegArray, sizeof(byteRegArray));
you also need to check what the error message is, not just compare to ERROR_SUCCESS, I believe there are more specific ERROR code.

Related

I am getting error 2 in my winreg function

My code:
HKEY hKey;
char *path = "SYSTEM\\CurrentControlSet\\Control\\IDConfigDB\\Hardware Profiles\\0001\\HwProfileGuid";
LONG result = RegOpenKeyExA(HKEY_LOCAL_MACHINE, path, 0, KEY_ALL_ACCESS, &hKey);
QString q = QString::number(result);
if (result == ERROR_SUCCESS) {
QMessageBox messageBox1;
messageBox1.critical(0,"Error", "Success");
messageBox1.setFixedSize(500,200);
} else {
QMessageBox messageBox2;
messageBox2.critical(0,"Error", q);
messageBox2.setFixedSize(500,200);
}
The error I am getting:
Where the key is in my Registry:
I think the problem is related to the way I put the info in the path variable, but I am not sure.
You have HwProfileGuid in the wrong place.
HwProfileGuid is a value inside of the 0001 key, but you are trying to open HwProfileGuid as a sub-key of 0001 instead, which is why you are getting error 2 (ERROR_FILE_NOT_FOUND), because there is no sub-key named HwProfileGuid.
Also, KEY_ALL_ACCESS is too many rights to request just to read a value from a key. Use KEY_QUERY_VALUE instead. Don't request more rights than you actually need.
Try this:
const char *path = "SYSTEM\\CurrentControlSet\\Control\\IDConfigDB\\Hardware Profiles\\0001";
const char *valueName = "HwProfileGuid";
char guid[40] = {0};
HKEY hKey;
LONG result = RegOpenKeyExA(HKEY_LOCAL_MACHINE, path, 0, KEY_QUERY_VALUE, &hKey);
if (result == ERROR_SUCCESS) {
DWORD size = sizeof(guid);
result = RegQueryValueExA(hKey, valueName, NULL, NULL, reinterpret_cast<LPBYTE>(guid), &size);
RegCloseKey(hKey);
}
QMessageBox messageBox;
if (result == ERROR_SUCCESS) {
messageBox.critical(0, "Success", guid);
} else {
messageBox.critical(0, "Error", QString::number(result));
}
messageBox.setFixedSize(500, 200);
Alternatively, you can use RegGetValueA() instead of using
RegOpenKeyExA()+RegQueryValueExA():
const char *path = "SYSTEM\\CurrentControlSet\\Control\\IDConfigDB\\Hardware Profiles\\0001";
const char *valueName = "HwProfileGuid";
char guid[40] = {0};
DWORD size = sizeof(guid);
QMessageBox messageBox;
LSTATUS result = RegGetValueA(HKEY_LOCAL_MACHINE, path, valueName, RRF_RT_REG_SZ, NULL, guid, &size);
if (result == ERROR_SUCCESS) {
messageBox.critical(0, "Success", guid);
} else {
messageBox.critical(0, "Error", QString::number(result));
}
messageBox.setFixedSize(500, 200);
Dont pass Computer\\HKEY_LOCAL_MACHINE to the string. just SYSTEM\\CurrentControlSet\\Control\\IDConfigDB\\Hardware Profiles\\0001 Because HKEY_LOCAL_MACHINE are exist in RegOpenKey First Parameter. And dont try to open the value of key just the key RegSetKeyValue() For writing value of key
here the working code:
HKEY hKey;
LONG result = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\IDConfigDB\\Hardware Profiles\\0001", 0, KEY_ALL_ACCESS, &hKey);
cout << result << "\n";

RegCreateKeyEx succeeding, but no key added

I am trying to get into C++ programming on Windows for reverse engineering purpose, and I am stuck trying to had a Windows registry key. The functions RegCreateKey and RegSetValueEx are returning ERROR_SUCCESS, but the key is missing when checking the registry.
Here is the code:
void AddRunKey() {
wchar_t subkey[512];
wchar_t cmd[512];
wcscpy_s(subkey, L"Test");
wcscpy_s(cmd, L"%windir%\system32\cmd.exe");
HKEY runKey;
long res;
res = RegCreateKeyEx(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurentVersion\\Run", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &runKey, NULL);
if (res != ERROR_SUCCESS) {
std::cout << "fail\n";
}
res = RegSetValueEx(runKey, subkey, 0, REG_EXPAND_SZ, (BYTE*)cmd, wcslen(cmd) + 1);
if (res != ERROR_SUCCESS) {
std::cout << "fail\n";
}
RegCloseKey(runKey);
}
int _tmain() {
AddRunKey();
}
I compiled it on Visual Studio, release mode, 64 bits on a Windows 10 - 64 bits virtual machine. No errors are returned when running the code.
When opening the Windows registry editor, under HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run, the key cannot be found
What is causing this behavior ? How can I fix it ?
EDIT (updated the key path): RegCloseKey returns 0
I see several mistakes in your code.
You need to escape the \ characters in your file path.
You misspelled CurentVersion in the key path. It needs to be CurrentVersion instead.
You are calling RegSetValueEx() and RegCloseKey() unconditionally whether RegCreateKeyEx() succeeds or fails.
You need to specify the value size in the last parameter of RegSetValueEx() in bytes and not in characters.
Try this instead:
void AddRunKey() {
wchar_t subkey[512];
wchar_t cmd[512];
wcscpy_s(subkey, L"Test");
wcscpy_s(cmd, L"%windir%\\system32\\cmd.exe");
HKEY runKey;
long res = RegCreateKeyEx(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", 0, NULL, 0, KEY_SET_VALUE, NULL, &runKey, NULL);
if (res != ERROR_SUCCESS) {
std::cout << "fail\n";
}
else
{
res = RegSetValueEx(runKey, subkey, 0, REG_EXPAND_SZ, (BYTE*)cmd, (wcslen(cmd) + 1) * sizeof(cmd[0]));
if (res != ERROR_SUCCESS) {
std::cout << "fail\n";
}
RegCloseKey(runKey);
}
}
int _tmain() {
AddRunKey();
}

Enumerating registry subkeys in HKEY_LOCAL_MACHINE\SOFTWARE in c++

I have trouble enumerating subkeys of HKEY_LOCAL_MACHINE\SOFTWARE, all I can get is subkeys on HKEY_LOCAL_MACHINE.
WCHAR Temp[255];
DWORD TMP = 255;
HKEY hKey;
int count = 0;
long regError;
...
regError = RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\", NULL, KEY_ENUMERATE_SUB_KEYS, &hKey);
if (regError == ERROR_SUCCESS){
file<<"Key opened!\nSubkeys of HKEY_LOCAL_MACHINE\\SOFTWARE:\n\n";
while ((regError = RegEnumKeyEx(HKEY_LOCAL_MACHINE, count, Temp, &TMP, NULL, NULL, NULL, NULL)) == ERROR_SUCCESS){
TMP = sizeof (Temp);
count++;
file<<count<<". "<<Temp<<std::endl;
}
if (regError == ERROR_NO_MORE_ITEMS) file<<"Done.";
else file << std::endl <<"RegEnumKeyEx error!";
}
else file << std::endl <<"RegOpenKeyEx error!";
RegCloseKey(hKey);
Here is my file:
Key opened!
Subkeys of HKEY_LOCAL_MACHINE\SOFTWARE:
1. BCD00000000
2. DRIVERS
3. HARDWARE
4. SAM
5. SECURITY
6. SOFTWARE
7. SYSTEM
Done.
How can I output keys inside of HKEY_LOCAL_MACHINE\SOFTWARE and not just HKLM? Thanks.
You are passing the wrong HKEY to RegEnumKeyEx(). You are passing the HKLM root, but you need to pass the HKEY that RegOpenKeyEx() returns. In other words, change this:
RegEnumKeyEx(HKEY_LOCAL_MACHINE, ...)
To this:
RegEnumKeyEx(hKey, ...)

Getting a proper value from RegQueryValueEx

I am trying to extract a value from the windows registry of type REG_SZ, using RegQueryValueEx, I got the value except it was riddled with strange "\000" before each letter.To show you what I mean here are some images:
Value I want(It is a device name of a wireless adapter)
Value I got:
here is the code:
HKEY hlistkey = NULL;
HKEY hkey = NULL;
int dwIndex=0;
string devName = returndevName(); //return current selected device name using iphlpapi.h
WCHAR KeyNameBuf[512];
DWORD keyNameSizBuf = 512;
char buffer[512];
RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}") ,0,KEY_READ, &hlistkey );
if(!hlistkey)
{
cout << "failed" << endl;
}
while(RegEnumKeyEx(hlistkey,dwIndex++,KeyNameBuf,&keyNameSizBuf,0,NULL,NULL,NULL) == ERROR_SUCCESS )
{
RegOpenKeyEx(hlistkey, KeyNameBuf, 0, KEY_READ | KEY_SET_VALUE, &hkey);
if(hkey)
{
keyNameSizBuf = 512;
if(RegQueryValueEx(hkey,TEXT("NetCfgInstanceId"), 0,NULL,(LPBYTE)buffer,&keyNameSizBuf ) == ERROR_SUCCESS )
{
if(strcmp(buffer,devName.c_str() ) ==0)
{
//set value here
}
}
RegCloseKey(hkey);
}
}
}
comparing buffer and devName would not be the same because of the extra null characters .If I cast buffer to a string I simply got a "{" which is the first value.I need to get the value of the devename in the registry before I can change the "NetworkAddress" in the registry.
Since you are using WCHAR, I assume you are compiling with Unicode support. If this is true, then also the buffer needs to be WCHAR.

c++ RegSetValueEx sets only one char value in registry

I'm casting (char * ) on data and i'm getting only one char value in the registry. if
i don't use the casting msvc 2010 tells me that the argument type LPCTSTR is incompatible with const char *.
can someone help me?
HKEY hKey;
LPCTSTR sk = TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run");
LONG openRes = RegOpenKeyEx(HKEY_CURRENT_USER, sk, 0, KEY_ALL_ACCESS , &hKey);
if (openRes==ERROR_SUCCESS) {
printf("Success opening key.");
} else {
printf("Error opening key.");
}
LPCTSTR value = TEXT("SomeKey");
LPCTSTR data = L"TestData\0";
LONG setRes = RegSetValueEx (hKey, value, 0, REG_SZ, (LPBYTE)data, strlen(data)+1);
if (setRes == ERROR_SUCCESS) {
printf("Success writing to Registry.");
} else {
printf("Error writing to Registry.");
}
cout << setRes << endl;
LONG closeOut = RegCloseKey(hKey);
if (closeOut == ERROR_SUCCESS) {
printf("Success closing key.");
} else {
printf("Error closing key.");
}
strlen(data) is probably returning a value of 1, as strlen expects a char* and L"TestData\0" is wide. Use TEXT("TestData\0") and call _tcslen(data).
Note that RegSetValueEx expects the sizeof the data, so use _tcslen(data) * sizeof(TCHAR)
Where are you casting data?
Either way, it looks like you may be working with wide characters, but you seem to be using "plain old" strlen - instead of wcslen or some other function intended to work with wide-character strings.
replace the L"TestData" by _T("TestData"); and strlen(data)+1 by tcslen(data) * sizeof(TCHAR));
so your code looks like this :
LPCTSTR value = TEXT("SomeKey");
LPCTSTR data = TEXT("TestData");
LONG setRes = RegSetValueEx(hKey, value, 0, REG_SZ, (LPBYTE)data, _tcslen(data) * sizeof(TCHAR));