-5

I'm looking for way to open registry editor and show some specific key or value. For example, if I pass "HKLM\\SOFTWARE\\Skype\\Installer" I want to get such a result:enter image description here

All suggestions except system() calls are welcome.

ST3
  • 8,826
  • 3
  • 68
  • 92
  • 2
    Why no `system()` calls? You're essentially asking to launch an external program here, don't see why you'd not use `system()` or a related fork/exec type thing to do so. – Joe Jul 25 '13 at 16:49
  • What is wrong with `system()`? That is simple shortcut for a bunch of setup to calling CreateProcess, etc. – wallyk Jul 25 '13 at 16:50
  • 4
    I find that link full of mostly bogus information and irrelevant to what you are trying to do. You want to actually run REGEDIT.EXE. Whether you do it via `system` or by creating a separate process and launching it, you will have the same result and restrictions etc. It's one thing to avoid using `system` to run a utility that you can query an API for to get information, it's another thing entirely when your *expressed goal* is to run the program in question. – Joe Jul 25 '13 at 17:01
  • 2
    system() calls are potentially harmful because they *create processes*. Opening regedit requires creating a process. If you want to create a process, then creating a process is, well, part of the task. – Sneftel Jul 25 '13 at 17:05
  • BTW. What is wrong with my question? I'm asking this all downvoters – ST3 Jul 25 '13 at 17:05
  • @Ben I agree what in `system()` way and in another way another process will be launched, but while calling `system()` you make hole in OS. Because it is probably the easiest part of reverse engineering, is to change strings values. I have seen such a malware which rewrite some purely designed software. – ST3 Jul 25 '13 at 17:09
  • 2
    well, you're gonna have to put "regedit.exe" somewhere, so that the computer knows you want to run regedit. And then someone can change it to "deleteeverythingandsendmybankaccountdetailstocriminals.exe", I guess. It is literally impossible to write a program which does not perform differently if its data is maliciously changed. – Sneftel Jul 25 '13 at 17:11
  • @Ben Well you are half right. Yes it is possible to change string values in both ways. But during lets say `ShellExecute()` is much more difficult to make run another stuff because during `system()` call you set all parameters in one place it means what during non `system()` call hacker needs to amass request and it is **much much more difficult**. I know it is impossible to make 100% safe software but we need to try. – ST3 Jul 25 '13 at 17:21
  • CreateProcess then one of these; [How to launch windows regedit with certain path?](http://stackoverflow.com/questions/137182/how-to-launch-windows-regedit-with-certain-path) – Alex K. Jul 25 '13 at 18:44
  • 1
    Why don't you use the Windows API to find and change registry values? – Thomas Matthews Jul 25 '13 at 21:29
  • @ThomasMatthews I do not need to change values. I need to open regedit. – ST3 Jul 26 '13 at 05:31
  • @RemyLebeau That is alomost dublicate. I have looked through that and answers was about listing values, not about opening regedit. What is more that question is about cmd. I posted my function, if you do not believe, investigate that. – ST3 Jul 26 '13 at 05:44
  • @user2623967: The answer I linked to does open RegEdit to the desired path, via a Registry hack that tells RegEdit what path to open to. `system()` just calls `CreateProcess()` to execute a copy of `cmd.exe` with the specified input command as a parameter. – Remy Lebeau Jul 26 '13 at 19:50

2 Answers2

1

Just call system. To use Raymond Chen's words: It rather involved being on the other side of this airtight hatchway. Any relevant attack requires compromising the machine to the point that your system call is utterly irrelevant. In fact, any attacker that can change RegEdit can change your program as well, so he could just add that system call. (Which he won't, since it is pointless anyway)

MSalters
  • 173,980
  • 10
  • 155
  • 350
0

Here is, what I needed.

String GetFullHKEY (HKEY hKeyRoot)
{
    if (HKEY_LOCAL_MACHINE == hKeyRoot) return _T("HKEY_LOCAL_MACHINE\\");
    if (HKEY_CLASSES_ROOT == hKeyRoot) return _T("HKEY_CLASSES_ROOT\\");
    if (HKEY_CURRENT_CONFIG == hKeyRoot) return _T("HKEY_CURRENT_CONFIG\\");
    if (HKEY_CURRENT_USER == hKeyRoot) return _T("HKEY_CURRENT_USER\\");
    if (HKEY_USERS == hKeyRoot) return _T("HKEY_USERS\\");
}

bool RegistryGoTo (HKEY hKeyRoot, const String &lpctPath, String lpctValue)
{
    if (lpctPath.empty() || 0 == hKeyRoot) 
        return false;
    if( lpctValue.empty() && lpctValue.empty() == 0)
    {
        lpctValue.clear();
    }

    SHELLEXECUTEINFO shi = { 0 };
    DEVMODE dm = { 0 };

    HWND hWndRegedit = ::FindWindow (_T("RegEdit_RegEdit"), NULL);
    if (NULL == hWndRegedit)
    {
        shi.cbSize = sizeof(SHELLEXECUTEINFO);
        shi.fMask  = SEE_MASK_NOCLOSEPROCESS; 
        shi.lpVerb = _T("open"); 
        shi.lpFile = _T("regedit.exe"); 
        shi.nShow  = SW_SHOWNORMAL; 

        ShellExecuteEx (&shi);
        if( GetLastError() != 0 )
        {
            Sleep(200);
            ShellExecuteEx (&shi);
        }
        WaitForInputIdle (shi.hProcess, INFINITE);

        hWndRegedit = ::FindWindow (_T("RegEdit_RegEdit"), NULL);
    }

    if (NULL == hWndRegedit) return FALSE;

    SetForegroundWindow (hWndRegedit);
    ShowWindow (hWndRegedit, SW_SHOWNORMAL);

    HWND hWndTreeView = FindWindowEx (hWndRegedit, NULL, _T ("SysTreeView32"), NULL);
    SetForegroundWindow (hWndTreeView);
    SetFocus (hWndTreeView);

    for (int i = 0; i < 30; i++)
    {
        SendMessage (hWndTreeView, WM_KEYDOWN, VK_LEFT, 0);
    } 

    dm.dmSize = sizeof (DEVMODE);
    EnumDisplaySettings (NULL, ENUM_CURRENT_SETTINGS, &dm);

    if (8 < dm.dmBitsPerPel) Sleep (100);

    // the path must start with a backslash
    String stRegPath = String (_T("\\")) + GetFullHKEY(hKeyRoot) + lpctPath;

    // open path
    for (int iIndex = 0; iIndex < (int) stRegPath.length (); iIndex++)
    {
        if (_T('\\') == stRegPath [iIndex])  
        {
            SendMessage (hWndTreeView, WM_KEYDOWN, VK_RIGHT, 0);

            if (8 < dm.dmBitsPerPel) 
                Sleep (100);
        } 
        else SendMessage (hWndTreeView, WM_CHAR, toupper (stRegPath [iIndex]), 0);
    } 

    SetForegroundWindow (hWndRegedit);
    SetFocus (hWndRegedit);

    if (lpctValue.length())
    {
        HWND hWndListView = FindWindowEx (hWndRegedit, NULL, _T("SysListView32"), NULL);
        SetForegroundWindow (hWndListView);
        SetFocus (hWndListView);

        Sleep (100); 

        SendMessage (hWndListView, WM_KEYDOWN, VK_HOME, 0);

        String stValue = lpctValue;

        for (String::iterator it = stValue.begin (); it != stValue.end (); ++it)
        {
            SendMessage (hWndListView, WM_CHAR, toupper (*it), 0);
        } 
    } 

    return true;
}
ST3
  • 8,826
  • 3
  • 68
  • 92
  • 1
    That is some really elaborate code that is not actually needed. You are doing inadequate error handling, and you are leaking the process handle that `ShellExecuteEx()` returns. You could just put the desired path in the Registry (`HKCU\Software\Microsoft\Windows\CurrentVersion\Applets\Regedit\Lastkey`) and then run RegEdit and be done with it. No need to manally send keystrokes to the RegEdit window. – Remy Lebeau Jul 26 '13 at 19:56