Search code examples
cwindowscreateprocesssystem32

Createprocess() of "C:\\Windows\\System32\\OpenSSH\\ssh.exe" fails with error=2


On a Windows-10 machine, I am trying to run ssh.exe as a child process using createprocess, something like the below snippet:

// Create the child process.
bSuccess = CreateProcess(NULL,
    child_cmd,     // command line 
    NULL,          // process security attributes 
    NULL,          // primary thread security attributes 
    TRUE,          // handles are inherited 
    0,             // creation flags 
    NULL,          // use parent's environment 
    NULL,          // use parent's current directory 
    &siStartInfo,  // STARTUPINFO pointer 
    &piProcInfo);  // receives PROCESS_INFORMATION 

                   // If an error occurs, exit the application. 
if (!bSuccess)
{
    ErrorExit(TEXT("CreateProcess"));
    return NULL;
}

The CreateProcess API fails with error 2 (file not found) when child_cmd parameter contains “C:\\Windows\\System32\\OpenSSH\\ssh.exe”. What is puzzling is that, this file - ‘C:\Windows\System32\OpenSSH\ssh.exe’ - exists on the machine; yet, CreateProcess() reports error 2. If I copied ‘C:\Windows\System32\OpenSSH\ssh.exe’ [from command prompt] to some other location, say ‘C:\tmp\System32_OpenSSH\ssh.exe’ and then call CreateProcess() with child_cmd parameter containing “C:\\tmp\\System32_OpenSSH\\ssh.exe”, the exact same program works like a charm. Any clue what is going on here? Are there any OS imposed restrictions regarding C:\Windows\system32 folder?

I faced similar problem with file copy as well - system("copy C:\\Windows\\system32\\OpenSSH\\ssh.exe OpenSSH_ssh.exe").


Solution

  • My psychic powers suggest that while you do indeed have a binary named ssh.exe in your C:\Windows\System32\OpenSSH folder, your compiled code is running as 32-bit, but your OS is 64-bit.

    32-bit code running on a 64-bit OS gets a redirection of the file system for certain folders. Such that any attempt to access C:\Windows\System32 is getting mapped to C:\Windows\SysWOW64. I'm guessing don't have a copy of ssh.exe in your C:\Windows\SysWOW64\OpenSSH folder. (Appears to be the case for me too.)

    If you compile your code as 64-bit, it would likely work. Off the top of my head, I don't remember the rules if a 32-bit process is allowed to "create" a 64-bit process. (I would think so - right?) But a quick Google references this post on StackOverflow. Looks like there are some APIs that can be invoked to disable file system redirection.