2

I tried to create a key in windows registry, but I got this error:

5 Access is denied.

The code snippet is like this:

HKEY hKey;
LPCTSTR sk = TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\notepad.exe"); //notepad.exe is the key I want to create
    //note: if I change the first parameter to KEY_CURRENT_USER, the key will be created 
LONG createResKey = RegCreateKeyEx(HKEY_LOCAL_MACHINE, sk, 0, NULL, REG_OPTION_BACKUP_RESTORE, KEY_ALL_ACCESS, NULL, &hKey, NULL);

if (createResKey == ERROR_SUCCESS) {
    qDebug() << "Success creating key.";
}
else {
    qDebug() << "Error creating key.";

    showErrorText(createResKey);
}

Maybe it is because my program doesn't have the admin privilege, I tried my best to do research online and tried to get the admin privilege, but failed. I am quite confused about how to solve this problem right now.

Edit: What do I want to achieve?
I am trying to block some specific apps from starting by modifying the registry. For example, if I want to block notepad, first I have to create a "notepad.exe" key, and then set a string value "debugger" to it and set its value to "debugfile.exe". So the notepad will be block from starting.

Theodore Tang
  • 831
  • 2
  • 21
  • 42
  • 1
    Did you consider just right-clicking on the EXE from Explorer and selecting "run as administrator" ? – selbie Jun 22 '18 at 05:28
  • @selbie yes, I did try that, but somehow it still says "access is denied". Besides I wanna it gets the admin privileges programmatically – Theodore Tang Jun 22 '18 at 05:33
  • Are you so sure to need admin privileges? Can't you avoid them? Then life would be easier (because you'll just build on what the OS easily provides) – Basile Starynkevitch Jun 22 '18 at 05:35
  • @BasileStarynkevitch Not so sure actually. I just need to figure out why it says "access is denied". But from what I found online, people were saying that it is probably because I don't have the admin privileges. – Theodore Tang Jun 22 '18 at 05:38
  • Can you afford spending months to learn Windows and its WinAPI? I am biased (I know Linux & POSIX, and hate Windows), but if you are ready to invest efforts on learning OS I would recommend POSIX, not WinAPI. – Basile Starynkevitch Jun 22 '18 at 05:39
  • I see the problem... answer coming shortly. – selbie Jun 22 '18 at 05:39
  • @BasileStarynkevitch okay, I appreciate your advice. And I will see what I can do. Honestly I dislike dealing with windows api too. – Theodore Tang Jun 22 '18 at 05:42
  • @selbie Alight. Thanks. I will wait for your solution. – Theodore Tang Jun 22 '18 at 05:42
  • For your consideration.... – selbie Jun 22 '18 at 05:48
  • 1
    Both answers seem technically correct, but what exactly are you trying to do here? What's the end goal? – MrEricSir Jun 22 '18 at 06:52
  • @MrEricSir Well, I am trying to block some specific apps from starting by modifying the registry. For example, if I want to block notepad, first I have to create a "notepad.exe" key – Theodore Tang Jun 22 '18 at 06:59
  • @TheodoreTang: don't comment your own question, but **edit your question** to improve it. In general, explaining briefly the motivation of your question is wise – Basile Starynkevitch Jun 22 '18 at 07:39

3 Answers3

8

GUI toolkits are so complex that it is usually advised to avoid taking administrative privileges to run them, and many GUI toolkits have (for good reasons) code to detect and disable (or warn against) that. On Linux, that means that you should not run GTK or Qt code as root (and if you do, some warning is emitted, or maybe the toolkit aborts; for Qt, see this; for GTK, see that).

In practice, you should try to have some small program (probably on the command line, or as a daemon) with administrative privilege and have your Qt program start it (e.g. with QProcess) and/or communicate with it (using some kind of inter-process communication), taking advantage of the process isolation and multi-user ability provided by your operating system.

I guess that some general understanding of OSes should help. Then I recommend reading Operating Systems: Three Easy Pieces to get more insight about OSes in general.

Details -i.e. how to start some program with more privileges than your Qt program- are operating system specific (on Linux, read about setuid). Inter-process communication facilities are also OS specific (on Linux, see pipe(7), fifo(7), shm_overview(7), unix(7), sem_overview(7) etc... and read some Linux programming book, perhaps the old ALP or something newer). How to get more privileges or do inter-process communication on Windows is a very different question (unrelated to Qt).

So you need to dive into the WinAPI documentation (perhaps here) to find out how to start a daemon or a small program with administrative privilege and how to perform inter-process communication with it. I guess that Windows has such facilities, but they are not wrapped in Qt (and neither is the access to the registery) and you need to write Windows specific code and learn more about WinAPI. I cannot help you, since I don't know and never used Windows.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • Thanks for you advice, although what you said are currently beyond my understanding, I will try to look into them. – Theodore Tang Jun 22 '18 at 05:23
  • 1
    You probably need to spend months in learning Windows programming. – Basile Starynkevitch Jun 22 '18 at 05:24
  • @BasileStarynkevitch, *"GUI toolkits are so complex that it is usually advised to avoid taking administrative privileges to run them"*. I know a lot of GUI programs (at least on windows) that ask for administrative privileges upon performing some functions. Would you please elaborate on why is that considered bad practice? Is the aim here to avoid exploits that might exist in these GUI toolkits from taking over the whole system (and limit them to user privileges)? I think that docker is an example of software that uses the architecture you are suggesting.. thanks... – Mike Jun 22 '18 at 06:52
  • AFAIK, Both GTK and Qt code have some provision on Linux (e.g. emit at least some warning) to avoid being run as root – Basile Starynkevitch Jun 22 '18 at 07:35
2

KEY_ALL_ACCESS is a rather heavyweight permission. And even an escalated process may not have that kind of access to a system registry key in HKLM. In any case don't use the REG_OPTION_BACKUP_RESTORE and KEY_ALL_ACCESS flags. Instead just ask for KEY_WRITE.

LONG createResKey = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
                                    sk,
                                    0,
                                    NULL,
                                    0,
                                    KEY_WRITE,  
                                    NULL, 
                                    &hKey,
                                    NULL);

Then right-click on your EXE and select "Run as administrator".

selbie
  • 100,020
  • 15
  • 103
  • 173
  • Just tried your solution, and it worked. Thanks. But is there a way that doesn't need to click run as administrator manually, and the program just gets the admin privileges at the run time? – Theodore Tang Jun 22 '18 at 05:54
  • 1
    That wouldn't be very secure... if any program could just modify the system registry. – selbie Jun 22 '18 at 05:56
  • @ Alright! Again thanks for your solution. It saved me tons of time to do the research on my own. – Theodore Tang Jun 22 '18 at 05:59
2

To gets the admin privileges at the run time you need to add to you .pro file:

win32 {
    RC_FILE = rcfile.rc
}

Then create rcfile.rc with following:

#include <windows.h>
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "YourProgrammName.exe.manifest"

Then create YourProgrammName.exe.manifest file with following text:

name="YourProgrammName.myapp" type="win32" />
<description> Really Cool App</description>
<dependency />
<!-- Identify the application security requirements. -->
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
  <security>
   <requestedPrivileges>
    <requestedExecutionLevel
      level="requireAdministrator"
      uiAccess="false"/>
    </requestedPrivileges>
   </security>
</trustInfo>
<!-- padding to four-byte multiple file size including the byte order mark --   
<!-- padding 123 -->
 </assembly>
Alexey Tsybin
  • 220
  • 1
  • 6