0

My C++ application running under SYSTEM is unable to create new values or keys in the HKEY_CURRENT_USER registry the code seems to work fine when run as the current user but it doesn't work when running under SYSTEM. I'm not sure why this is happening but if I had to guess it's because it's not running as the current user. Is there any way to make it write to the HKEY_CURRENT_USER registry without having the application run as the current user?

Here's the code that works when run as the current user but not as SYSTEM

void WriteToCurUsrReg()
{
     TCHAR ExplorePath[256], RunPath[256];
     TCHAR notepadexe[50] = {L"notepad.exe"};
     StringCchPrintf(ExplorePath, sizeof(ExplorePath), L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer");
     StringCchPrintf(RunPath, sizeof(RunPath), L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer\\Run");
     DWORD runvalue = 1;
    
     HKEY  hKey = NULL;
     LONG  lErrorCode = 0;

     lErrorCode = RegOpenKeyEx(HKEY_CURRENT_USER, ExplorePath, 0, KEY_ALL_ACCESS, &hKey);
     if (lErrorCode == ERROR_SUCCESS)
     {
          RegSetValueEx(hKey,L"Run",0,REG_DWORD,(LPBYTE)&runvalue,sizeof(runvalue));
          lErrorCode = RegCloseKey(hKey);
          if (lErrorCode != ERROR_SUCCESS)
          {
              printf("RegCloseKey Failed :%d %s %d",GetLastError() ,__FILE__ , __LINE__);
          }
     }


     lErrorCode = RegOpenKeyEx(HKEY_CURRENT_USER, RunPath, 0, KEY_ALL_ACCESS, &hKey);
     if (lErrorCode == ERROR_SUCCESS)
     {
          RegSetValueEx(hKey,L"1",0,REG_SZ,(LPBYTE)notepadexe,128);
          lErrorCode = RegCloseKey(hKey);
          if (lErrorCode != ERROR_SUCCESS)
          {
              printf("RegCloseKey Failed :%d %s %d",GetLastError() ,__FILE__ , __LINE__);
          }
     }
     else
     {
         hKey = NULL;
         LONG lError = RegCreateKey(HKEY_CURRENT_USER, RunPath, &hKey); 
         DWORD dwLength = 0;
         if(lError == ERROR_SUCCESS)
         {                  
              RegSetValueEx(hKey,L"1", 0, REG_SZ,(LPBYTE)notepadexe, 128);
              lErrorCode = RegCloseKey(hKey);
              if (lErrorCode != ERROR_SUCCESS)
              {
                  printf("RegCloseKey Failed :%d %s %d",GetLastError() ,__FILE__ , __LINE__);   
              }
         }
     }
}

There are no errors that occur when I run the program under SYSTEM, the program successfully runs and exits without issue but the function the program is supposed to perform is not complete ie: the program doesn't create any keys or values in the HKEY_CURRENT_USER registry.

Skittari
  • 13
  • 5
  • What output do you get when it doesn't work? Please [edit] the question. – Jabberwocky Feb 22 '22 at 09:11
  • 2
    Which user do you want to write to? There is the `HKEY_USERS` key which contains the `HKEY_CURRENT_USER` entries for all users – Alan Birtles Feb 22 '22 at 09:12
  • @Alan Birtles I want to write to whoever the current user is and not one user in specific. – Skittari Feb 22 '22 at 10:20
  • @Skittari please define _"running under SYSTEM"_. How do you proceed to _"run your code under SYSTEM"_? – Jabberwocky Feb 22 '22 at 10:25
  • @Skittari: If your "current user" is `SYSTEM`, then how do you expect that to work? SYSTEM` doesn't have a hive under `HKEY_USERS` IIRC; `SYSTEM` uses HKLM. `HKEY_CURRENT_USER` makes perfect sense for normal programs that are started by the logged-in user . However, see `RegOpenCurrentUser` for impersonation. – MSalters Feb 22 '22 at 14:45
  • 1
    On a side note: the 2nd parameter of `StringCchPrintf()` is expressed in characters, not bytes, so using `sizeof()` is wrong when `TCHAR` maps to `WCHAR`, which can lead to buffer overflows. Use `_countof()` or equivalent instead. – Remy Lebeau Feb 24 '22 at 04:18

2 Answers2

1

As you surmised, when running as the SYSTEM user, that is the user that HKEY_CURRENT_USER represents, not a logged in user.

You need to use LoadUserProfile() or RegOpenCurrentUser() to access the HKEY_CURRENT_USER hive of another user.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
0

I think that you are running your process as a Windows service otherwise you can run it as administrator and everything should work.

In case that your process is a windows service it's not sure that a user is logged on, maybe no user is using the computer at that time.

Anyway you can test is a user is logged on with the code you can find here.

Of course you have to run your process/service with elevated privilegies and you can do it with a manifest file with the key:

<requestedExecutionLevel level="requireAdministrator" uiAccess="false"></requestedExecutionLevel>
Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
Marco Beninca
  • 605
  • 4
  • 15