I'm pretty sure my RegSetSetValueExA works fine, My data I'm writing is (CONST BYTE*)&setValue. My setvalue is a DWORD and I've already wrote to the registry with this with RegOpenKeyExA and it works fine.
I think the problem is coming from RegCreateKeyExA because I'm creating my new key from that.
Also, my REG_DWORD requires me to write in Binary for some reason
https://gyazo.com/e418587d579a3e540656f06a2524901f
I've tried looking at other threads but everyone's problem seems different to mine because they're using RegOpenKeyExA.
#include "stdafx.h"
#include <stdio.h>
#include <iostream>
#include <Windows.h>
#include <cstdio>
#include "Strsafe.h"
// Stolen microsoft error code credits:msdn
void ErrorExit(LPTSTR lpszFunction)
{
// Retrieve the system error message for the last-error code
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dw = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&lpMsgBuf,
0, NULL);
// Display the error message and exit the process
lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
(lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR));
StringCchPrintf((LPTSTR)lpDisplayBuf,
LocalSize(lpDisplayBuf) / sizeof(TCHAR),
TEXT("%s failed with error %d: %s"),
lpszFunction, dw, lpMsgBuf);
MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);
LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);
ExitProcess(dw);
}
// end of stolen code
int main()
{
DWORD Disposition = REG_CREATED_NEW_KEY;
BYTE lpData[32];
DWORD setValue = 2;
PHKEY throwAwayKey = 0;
DWORD lpType = { REG_DWORD };
DWORD lpcbData = { sizeof(lpData) };
HKEY hKey = 0;
char regPath[64] = "Software\\Policies\\Microsoft\\Windows\\System";
char lpValueName[32] = "DisableCMD";
long RegCKExA = RegCreateKeyExA(HKEY_CURRENT_USER, regPath, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &Disposition);
if (RegCKExA == ERROR_SUCCESS)
{
std::cout << "Successfully executed RegCreatKeyExA\n";
}
else
{
std::cout << "An error has occurred while executing RRegCreateKeyExA. Error code: ";
ErrorExit((LPTSTR)TEXT("RegCreateKeyExA"));
getchar();
return EXIT_FAILURE;
}
long regQVExA = RegQueryValueExA(hKey, lpValueName, NULL, &lpType, (LPBYTE)lpData, &lpcbData);
if (regQVExA == ERROR_SUCCESS)
{
std::cout << "Successfully executed RegQueryValueExA and DisableCMD is already on this computer. Press ENTER to continute\n";
getchar();
return ERROR_SUCCESS; // Difference is it returns here if DisableCMD exists
}
else
std::cout << "DisableCMD not found. Starting creation of DisableCMD registry value. Press ENTER to continue";
getchar();
auto regSVExA = RegSetValueExA(hKey, lpValueName, 0, REG_DWORD, (CONST BYTE*)&setValue, lpcbData);
if (regSVExA == ERROR_SUCCESS)
{
std::cout << "Successfully executed RegSetValueExA\n";
getchar();
}
else
{
std::cout << "An error has occurred while executing RegSetValueExA. Error code: ";
getchar();
return EXIT_FAILURE;
}
RegCloseKey(hKey);
return 0;
}
I refactored your functions as WriteDWORD and ReadDWORD.
Note that the code is actually VERY SIMILAR to your code. So why did I bother? Well, there is one subtle difference in that I made DWORD the input/output type instead of the BYTE array you had.
LSTATUS WriteDWORD(LPCSTR lpPath, LPCSTR lpValueName, DWORD dwData)
{
LSTATUS status = ERROR_SUCCESS;
HKEY hKey = NULL;
DWORD dwDisposition = 0;
status = RegCreateKeyExA(HKEY_CURRENT_USER, lpPath, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dwDisposition);
if (status != ERROR_SUCCESS)
{
return status;
}
status = RegSetValueExA(hKey, lpValueName, 0, REG_DWORD, (CONST BYTE*) &dwData, sizeof(DWORD));
RegCloseKey(hKey);
return status;
}
LSTATUS ReadDWORD(LPCSTR lpPath, LPCSTR lpValueName, DWORD* pdwData)
{
LSTATUS status = ERROR_SUCCESS;
HKEY hKey = NULL;
DWORD dwDisposition = 0;
status = RegCreateKeyExA(HKEY_CURRENT_USER, lpPath, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dwDisposition);
if (status != ERROR_SUCCESS)
{
return status;
}
DWORD dwType = 0;
DWORD cbData = sizeof(DWORD);
status = RegQueryValueExA(hKey, lpValueName, NULL, &dwType, (LPBYTE)pdwData, &cbData);
RegCloseKey(hKey);
return status;
}
Here is a sample usage:
int main()
{
char szPath[64] = "Software\\Policies\\Microsoft\\Windows\\System";
char szValueName[32] = "DisableCMD";
WriteDWORD(szPath, szValueName, 1234);
DWORD dwValue = 0;
ReadDWORD(szPath, szValueName, &dwValue); // dwValue now contains 1234
return 0;
}
Note that I did a few things:
I used DWORD dwData for the writer but DWORD* pdwData for the reader.
I preinitialized DWORD cbData = sizeof(DWORD); (i.e. 4)
I hope this gives you insight to the "Binary" part of your question. A DWORD is 4 bytes. When you wrote it to the registry, you are telling it to store a DWORD which is a 32 bit number or 4 bytes. When you read it back from registry, to reconstitute in your app you should supply a pointer to a DWORD. Since you gave it a byte array, the 32 bit number populated the first 4 bytes of the array you supplied. You may not have understood it but it is the correct behavior.
If you used std::cout you will find that it reacts differently to the same 4 bytes because of the overloaded C++ type. If you had used a DWORD you would have seen your number. However, since you have it in your byte array, it will be binary gibberish.
Related
This program enumerate all handles and get their names.
For pID 4 OpenProcess gets error 5 with SeDebugPrivilege.
UAC off. Running from Admin.
Enable SeDebugPrivilege
BOOL EnableDebugPrivilege(BOOL bEnable)
{
HANDLE hToken = nullptr;
LUID luid;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) return FALSE;
if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) return FALSE;
TOKEN_PRIVILEGES tokenPriv;
tokenPriv.PrivilegeCount = 1;
tokenPriv.Privileges[0].Luid = luid;
tokenPriv.Privileges[0].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : 0;
if (!AdjustTokenPrivileges(hToken, FALSE, &tokenPriv, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) return FALSE;
_tprintf(_T("Privileges error: %d\n", GetLastError()));
return TRUE;
}
Enumerate handles
DWORD EnumerateFileHandles(ULONG pid)
{
HINSTANCE hNtDll = LoadLibrary(_T("ntdll.dll"));
assert(hNtDll != NULL);
PFN_NTQUERYSYSTEMINFORMATION NtQuerySystemInformation =
(PFN_NTQUERYSYSTEMINFORMATION)GetProcAddress(hNtDll,
"NtQuerySystemInformation");
assert(NtQuerySystemInformation != NULL);
PFN_NTQUERYINFORMATIONFILE NtQueryInformationFile =
(PFN_NTQUERYINFORMATIONFILE)GetProcAddress(hNtDll,
"NtQueryInformationFile");
DWORD nSize = 4096, nReturn;
PSYSTEM_HANDLE_INFORMATION pSysHandleInfo = (PSYSTEM_HANDLE_INFORMATION)
HeapAlloc(GetProcessHeap(), 0, nSize);
while (NtQuerySystemInformation(SystemExtendedHandleInformation, pSysHandleInfo,
nSize, &nReturn) == STATUS_INFO_LENGTH_MISMATCH)
{
HeapFree(GetProcessHeap(), 0, pSysHandleInfo);
nSize += 4096;
pSysHandleInfo = (SYSTEM_HANDLE_INFORMATION*)HeapAlloc(
GetProcessHeap(), 0, nSize);
}
DWORD dwFiles = 0;
_tprintf(_T("Handles Number: %d\n"), pSysHandleInfo->NumberOfHandles);
for (ULONG i = 0; i < pSysHandleInfo->NumberOfHandles; i++)
{
PSYSTEM_HANDLE pHandle = &(pSysHandleInfo->Handles[i]);
if (pHandle->ProcessId == 4)
{
HANDLE hProcess = OpenProcess(
PROCESS_DUP_HANDLE, FALSE, pHandle->ProcessId);
if (hProcess == NULL)
{
_tprintf(_T("OpenProcess failed w/err 0x%08lx\n"), GetLastError());
continue;
}
HANDLE hCopy;
if (!DuplicateHandle(hProcess, (HANDLE)pHandle->Handle,
GetCurrentProcess(), &hCopy, MAXIMUM_ALLOWED, FALSE, 0))
continue;
TCHAR buf[MAX_PATH];
if (GetFinalPathNameByHandle(hCopy, buf, sizeof(buf), VOLUME_NAME_DOS))
wprintf(L"p%d:h%d:t%d:\t%s\n", pHandle->ProcessId, pHandle->Handle, pHandle->ObjectTypeNumber, buf);
CloseHandle(hProcess);
CloseHandle(hCopy);
}
}
HeapFree(GetProcessHeap(), 0, pSysHandleInfo);
return dwFiles;
}
On windows 7 x64 it's work fine.
But on Windows 10 x64 OpenProcess returns error 5 with SeDebugPrivilege.
How open system process(pID 4) on windows 10.
You can't open a handle for it as the documentation for OpenProcess specifically says it'll fail:
If the specified process is the Idle process or one of the CSRSS
processes, this function fails and the last error code is
ERROR_ACCESS_DENIED because their access restrictions prevent
user-level code from opening them.
If you want to get system process names, you could try to use CreateToolhelp32Snapshot() to get the snapshot of the process, then use Process32First() and Process32Next() to enumerate the all process.
Here is an example:
#include <iostream>
#include <stdio.h>
#include <windows.h>
#include <string>
#include <TlHelp32.h>
using namespace std;
int main()
{
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(pe32);
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);//get the snapshot
if (hProcessSnap == INVALID_HANDLE_VALUE)
{
cout << "CreateToolhelp32Snapshot Error!" << endl;
return false;
}
BOOL bResult = Process32First(hProcessSnap, &pe32);
int num(0);
while(bResult)
{
cout << "[" << ++num << "] : " << "Process Name:"<< pe32.szExeFile << " " << "ProcessID:" << pe32.th32ProcessID << endl;
bResult = Process32Next(hProcessSnap, &pe32);
}
CloseHandle(hProcessSnap);
}
Hope it could help you!
Im trying to read a registry using the winapi and c++.
The code runs, but the result is not the contents of the registry
After a hexdump is just 0xCD repeated over and over. (So, as if the data hasnt been modified by RegQueryValueEx, and is just the result of the malloc)
I tried running as admin too, with no luck.
This is the code im using:
HKEY hKey;
if (RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\Shell\\Bags\\1\\Desktop", 0, KEY_ALL_ACCESS, &hKey) != ERROR_SUCCESS)
return;
//Read & save
DWORD BufferSize = TOTALBYTES;
DWORD cbData;
DWORD dwRet;
LPBYTE data = (LPBYTE)malloc(BufferSize);
cbData = BufferSize;
DWORD type = REG_BINARY;
dwRet = RegQueryValueEx(hKey, "IconLayouts", NULL, &type, data, &cbData);
while (dwRet == ERROR_MORE_DATA) {
BufferSize += BYTEINCREMENT;
data = (LPBYTE)realloc(data, BufferSize);
cbData = BufferSize;
dwRet = RegQueryValueEx(hKey, "IconLayouts", NULL, &type, data, &cbData);
}
if (dwRet == ERROR_SUCCESS)
{
//Write current registry to a file
std::ofstream currentRegistryFile(DIRECTORY + currentDesktop + ".bin");
if (!currentRegistryFile) {
log(currentDesktop + " file couldn't be opened.");
return;
}
for (int i = 0; i < cbData; i++)
currentRegistryFile << (data)[cbData];
}
else
log("Couldnt read registry");
//Close registry
RegCloseKey(hKey);
Your saving code is the problem. It’s actually accessing the array out of bounds:
for (int i = 0; i < cbData; i++)
currentRegistryFile << (data)[cbData];
Note you’re indexing data with constant value of cbData and not loop variable i. Change that.
I'm new to C++ and to WinCe developing.
I want to read a string from the registry and display with the MessageBox(). I have tried the following.
HKEY key;
if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("System\\CurrentControlSet\\GPS Intermediate Driver\\Drivers\\SiRFStar3HW"), 0, KEY_READ, &key) != ERROR_SUCCESS)
{
MessageBox(NULL,L"Can't open the registry!",L"Error",MB_OK);
}
char value[5];
DWORD value_length=5;
DWORD type=REG_SZ;
RegQueryValueEx(key,(LPCTSTR)"Baud", NULL, &type, (LPBYTE)&value, &value_length);
wchar_t buffer[5];
_stprintf(buffer, _T("%i"), value);
::MessageBox(NULL,buffer,L"Value:",MB_OK);
::RegCloseKey(key);
So I know somethings wrong in here, but how can I solve?
Navigating the Win32 API can be a tricky business. The registry APIs are some of the more complicated. Here's a short program to demonstrate how to read a registry string.
#include <Windows.h>
#include <iostream>
#include <string>
using namespace std;
wstring ReadRegValue(HKEY root, wstring key, wstring name)
{
HKEY hKey;
if (RegOpenKeyEx(root, key.c_str(), 0, KEY_READ, &hKey) != ERROR_SUCCESS)
throw "Could not open registry key";
DWORD type;
DWORD cbData;
if (RegQueryValueEx(hKey, name.c_str(), NULL, &type, NULL, &cbData) != ERROR_SUCCESS)
{
RegCloseKey(hKey);
throw "Could not read registry value";
}
if (type != REG_SZ)
{
RegCloseKey(hKey);
throw "Incorrect registry value type";
}
wstring value(cbData/sizeof(wchar_t), L'\0');
if (RegQueryValueEx(hKey, name.c_str(), NULL, NULL, reinterpret_cast<LPBYTE>(&value[0]), &cbData) != ERROR_SUCCESS)
{
RegCloseKey(hKey);
throw "Could not read registry value";
}
RegCloseKey(hKey);
size_t firstNull = value.find_first_of(L'\0');
if (firstNull != string::npos)
value.resize(firstNull);
return value;
}
int wmain(int argc, wchar_t* argv[])
{
wcout << ReadRegValue(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion", L"CommonFilesDir");
return 0;
}
Notes:
I don't have CE so this is a plain Win32 app, compiled for Unicode. I took that route because CE doesn't do ANSI characters.
I've taken advantage of a number of C++ features. Most significantly std::wstring. This makes string handling a cinch.
I've used exceptions for error handling. You could replace that with some other mechanism, but it served my purpose of keeping the error handling issues in the background.
Using exceptions makes closing the registry key slightly messy. A better solution would be to use an RAII class to wrap up the lifetime of the registry key. I've omitted that for simplicity, but in production code you would want to take that extra step.
Usually, RegQueryValueEx returns REG_SZ data that is null-terminated. This code deals with that by truncating beyond the first null character. In case the value returned is not null-terminated, that truncation won't happen, but the value will still be fine.
I've just printed to my console, but it would be trivial for you to call MessageBox. Like this: MessageBox(0, value.c_str(), L"Caption", MB_OK)
Here is a complete source code to read a key value of Registry and print it to the screen:
//Create C++ Win32 Project in Visual Studio
//Project -> "project" Properties->Configuration Properties->C/C++->Advanced->Show Includes : YES(/ showIncludes)
//Project -> "project" Properties->Configuration Properties->General->Project Defaults->Use of MFC : Use MFC in a shared DLL
#include <iostream>
#include <afx.h>
using namespace std;
int ReadRegistryKeyAttributes(CString ConstantKeyPath)
{
//Here ConstantKeyPath is considered as Registry Key Path to Read
HKEY MyRegistryKey;
if (RegOpenKeyEx(HKEY_CURRENT_USER, ConstantKeyPath, 0, KEY_READ, &MyRegistryKey) != ERROR_SUCCESS)
{
cout << "KeyOpen Failed" << endl;
return -1;
}
DWORD type = REG_DWORD;
DWORD cbData;
unsigned long size = 1024;
CString csVersionID;
csVersionID = _T("VersionID"); //Here VersionID is considered as Name of the Key
if (RegQueryValueEx(MyRegistryKey, csVersionID, NULL, &type, (LPBYTE)&cbData, &size) != ERROR_SUCCESS)
{
RegCloseKey(MyRegistryKey);
cout << "VersionID Key Attribute Reading Failed" << endl;
return -1; //Error
}
else
{
cout << "VersionID = " << cbData << endl; //Key value will be printed here.
}
return 1; //Success
}
int main()
{
int iResult;
CString KeyPath = _T("Software\\RCD_Technologies\\Rajib_Test");
iResult = ReadRegistryKeyAttributes(KeyPath);
if (iResult < 0)
{
cout << "ReadRegistryKeyAttributes operation Failed" << endl;
return -1;
}
cout << "<--- ReadRegistryKeyAttribute Operation Successfull -->" << endl;
getchar();
return 0;
}
Hope this example will be helpful who are seeking this problem.
This is untested (my device doesn't have your key/value), but compiles for CE and gives you the gist of how you do what you're after:
#include
int _tmain(int argc, _TCHAR* argv[])
{
HKEY key;
if(!RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
_T("System\\CurrentControlSet\\GPS Intermediate Driver\\Drivers\\SiRFStar3HW"),
0,
NULL,
&key))
{
MessageBox(NULL, _T("Failed to open key"), _T("Error"), 0);
return -1;
}
DWORD length;
// get the size - it's going to be 4 for a DWORD, but this shows how to deal with REG_SZ, etc
if(!RegQueryValueEx(
key,
_T("Baud"),
NULL,
NULL,
NULL,
&length))
{
MessageBox(NULL, _T("Failed to get buffer size"), _T("Error"), 0);
goto exit;
}
// allocate - again, if we know it's a DWORD, this could be simplified
BYTE *buffer = (BYTE*)LocalAlloc(LPTR, length);
// query
if(!RegQueryValueEx(
key,
_T("Baud"),
NULL, NULL,
buffer,
&length))
{
MessageBox(NULL, _T("Failed to get value data"), _T("Error"), 0);
goto exit;
}
// assuming "baud" is a DWORD, not a string
DWORD baud = *(DWORD*)buffer;
// build an output
TCHAR message[MAX_PATH];
_stprintf(message, _T("The baud value is %i"), baud);
MessageBox(NULL, message, _T("Success"), 0);
exit:
RegCloseKey(key);
return 0;
}
When using a char array you will need to set not the buffer but the pointer to the buffer, like this:
MessageBox(0,&buffer,"Value:",MB_OK);
just use RegQueryValueEx and put it in buf
I am trying to list all modules on a specific process, but I am getting "Access denied", even when I set token privileges.
Here is the code:
#include <cstdlib>
#include <iostream>
#include <windows.h>
#include <psapi.h>
#include <Tlhelp32.h>
using namespace std;
#pragma comment(lib, "cmcfg32.lib")
BOOL SetPrivilege(HANDLE hToken, LPCTSTR lpszPrivilege, BOOL bEnablePrivilege)
{
TOKEN_PRIVILEGES tp;
LUID luid;
if (!LookupPrivilegeValue(NULL, lpszPrivilege, &luid))
{
char buf[256];
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, 255, NULL);
cout << "LookupPrivilegeValue error: " << buf;
return FALSE;
}
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
if (bEnablePrivilege) { tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; }
else { tp.Privileges[0].Attributes = 0; }
if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES) NULL, (PDWORD)NULL))
{
char buf[256];
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, 255, NULL);
cout << "AdjustTokenPrivileges error: " << buf;
return FALSE;
}
if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
{
printf("The token does not have the specified privilege. \n");
return FALSE;
}
return TRUE;
}
int GetPID(char pname[])
{
PROCESSENTRY32 pEntry;
HANDLE hSnapshot = NULL;
pEntry.dwSize = sizeof(PROCESSENTRY32);
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
Process32First(hSnapshot,&pEntry);
do { if(strcmp(pEntry.szExeFile, pname) == 0) { return pEntry.th32ProcessID; } } while(Process32Next(hSnapshot,&pEntry));
return 0;
}
int main()
{
HANDLE currentToken;
OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, ¤tToken);
if (!SetPrivilege(currentToken, SE_DEBUG_NAME, TRUE))
{
MessageBox(0, "Unable to adjust privileges", "Error", MB_ICONERROR);
}
DWORD ID = GetPID("test.exe");
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, ID);
if(!hProcess)
{
MessageBox(0, "Process not found", "Error", MB_ICONERROR);
}
else
{
HMODULE hMods[2048];
DWORD cbNeeded;
if(EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded))
{
for (unsigned int i = 0; i < (cbNeeded/sizeof(HMODULE)); i++)
{
TCHAR szModName[MAX_PATH];
if (GetModuleFileNameEx(hProcess, hMods[i], szModName, sizeof(szModName)/sizeof(TCHAR)))
{
cout << "DLL: " << szModName << " Handle: " << hMods[i] << endl;
}
}
}
else
{
char buf[256];
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, 255, NULL);
cout << "Error: " << buf;
}
system("pause");
}
CloseHandle(hProcess);
return 0;
}
Note that I can list process modules of any other process, but I can't with a specific one.
Both process are running with the same user credentials.
Can you tell me if I am doing something wrong?
Use Process Explorer to see the Security of kernel objects you are interested in. May be the target process has set its owner/DACL information such that it disallows READ for other processes. AntiVirus programs, services, file-system/kernel-driver are such kind of processes denying such actions.
And more importantly: it depends on the elevation/admin/ring-level of your own process.
ADDED:
Privileges doesn't directly apply to objects, but to the system as a whole. Try opening with TOKEN_ALL_ACCESS and see if it succeeds.
I've got most of the code for writing a value to the windows registry, however when I change the path to a dummy key and value that I've set up for testing it fails. My code is below:
HKEY hKey;
LPCTSTR sk = TEXT("SOFTWARE\TestSoftware");
LONG openRes = RegOpenKeyEx(HKEY_LOCAL_MACHINE, sk, 0, KEY_ALL_ACCESS , &hKey);
if (openRes==ERROR_SUCCESS) {
printf("Success opening key.");
} else {
printf("Error opening key.");
}
LPCTSTR value = TEXT("TestSoftwareKey");
LPCTSTR data = "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.");
}
LONG closeOut = RegCloseKey(hKey);
if (closeOut == ERROR_SUCCESS) {
printf("Success closing key.");
} else {
printf("Error closing key.");
}
All three tests yield error statuses.
The part that confuses me is that I was able to run this code when pointing it at other portions of the registry. Any ideas?
thanks,
brian
I feel silly. The solution is that need to properly escape the slash in the string as follows:
LPCTSTR sk = TEXT("SOFTWARE\\TestSoftware");
Hopefully someone finds this useful...
HKEY OpenKey(HKEY hRootKey, char* strKey)
{
HKEY hKey;
LONG nError = RegOpenKeyEx(hRootKey, strKey, NULL, KEY_ALL_ACCESS, &hKey);
if (nError==ERROR_FILE_NOT_FOUND)
{
cout << "Creating registry key: " << strKey << endl;
nError = RegCreateKeyEx(hRootKey, strKey, NULL, NULL, REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,NULL, &hKey, NULL);
}
if (nError)
cout << "Error: " << nError << " Could not find or create " << strKey << endl;
return hKey;
}
void SetintVal(HKEY hKey, LPCTSTR lpValue, DWORD data)
{
LONG nError = RegSetValueEx(hKey, lpValue, NULL, REG_DWORD, (LPBYTE)&data, sizeof(DWORD));
if (nError)
cout << "Error: " << nError << " Could not set registry value: " << (char*)lpValue << endl;
}
DWORD GetintVal(HKEY hKey, LPCTSTR lpValue)
{
DWORD data;
DWORD size = sizeof(data);
DWORD type = REG_DWORD;
LONG nError = RegQueryValueEx(hKey, lpValue, NULL, &type, (LPBYTE)&data, &size);
if (nError==ERROR_FILE_NOT_FOUND)
data = 0;
SetVal() is called.
else if (nError)
cout << "Error: " << nError << " Could not get registry value " << (char*)lpValue << endl;
return data;
}
BOOL SetcharVal(HKEY Key,char* subkey,char* StringName,char* Stringdata)
{
HKEY hKey = OpenKey(Key,subkey);
LONG openRes = RegOpenKeyEx(Key, subkey, 0, KEY_ALL_ACCESS , &hKey);
if (openRes==ERROR_SUCCESS) {
} else {
printf("Error opening key.");
}
LONG setRes = RegSetValueEx (hKey, StringName, 0, REG_SZ, (LPBYTE)Stringdata, strlen(Stringdata)+1);
if (setRes == ERROR_SUCCESS) {
} else {
printf("Error writing to Registry.");
}
LONG closeOut = RegCloseKey(hKey);
if (closeOut == ERROR_SUCCESS) {
} else {
printf("Error closing key.");
}
}
char* GetCharVal(HKEY Key,char* subkey,char* StringName)
{
DWORD dwType = REG_SZ;
HKEY hKey = 0;
char value[1024];
DWORD value_length = 1024;
RegOpenKey(HKEY_LOCAL_MACHINE,subkey,&hKey);
RegQueryValueEx(hKey, StringName, NULL, &dwType, (LPBYTE)&value, &value_length);
RegCloseKey(hKey);
return value;
}
I am using this code.
For UNICODE environment:
//Writing to registry
HKEY hKey;
LPCTSTR sk = TEXT("SOFTWARE\\Microsoft\\Windows");
LONG openRes = RegOpenKeyEx(HKEY_LOCAL_MACHINE, sk, 0, KEY_ALL_ACCESS, &hKey);
if (openRes == ERROR_SUCCESS) {
printf("Success opening key.");
}
else {
printf("Error opening key.");
}
LPCTSTR value = TEXT("Sample");
WCHAR path[80] = TEXT("C:\\samples\\app.exe");
LONG setRes = RegSetValueEx(hKey, value, 0, REG_SZ, (LPBYTE)path, sizeof(path));
if (setRes == ERROR_SUCCESS) {
printf("Success writing to Registry.");
}
else {
printf("Error writing to Registry.");
}
LONG closeOut = RegCloseKey(hKey);
if (closeOut == ERROR_SUCCESS) {
printf("Success closing key.");
}
else {
printf("Error closing key.");
}