64-bitenvironment-variablesprocess-explorer

SetEnvironmentVariable within 32bit Process on 64 bit Windows OS


I recently found an interesting issue. When using SetEnvironmentVariable, I can use Process Explorer to get the newly created environment variable. However when the process itself is 32 bit and the OS as 64 bit, Process Explorer (at least v10 ~ the latest v11.33) cannot find the new variables. If the program is native 64 bit then everything works fine, just as well as 32 bit process running on 32 bit OS.

The SetEnvironmentVariable API call should be successful, because the return value is TRUE and calling GetEnvironmentVariable returns correct value. Also if you create a child process, you can find the variable was correctly set in the new process by using Process Explorer.

I'm not if this is the limitation of SysWOW64 or a bug in Process Explorer. Anyone knows?

And, is there any way to get the 32 bit environment variables correctly? (for example, force Process Explorer to run in 32 bit mode, or some other tools)

Sample source to reproduce:

#include <stdio.h>
#include <windows.h>

int main(int argc, char *argv[])
{
    printf("setting variable... %s\n", 
        SetEnvironmentVariable("a_new_var", "1.0") ? "OK" : "FAILED");
    printf("press anykey to continue...\n");
    getchar();
    // system(argv[0]); // uncomment to inspect the child process
    return 0;
}

Solution

  • I'm not sure how WOW64 works, but I'm pretty (99%) sure there are two PEBs (Process Environment Blocks) created - a 32-bit one and a 64-bit one. The process parameter structures (RTL_USER_PROCESS_PARAMETERS) are probably duplicated as well. So when you call SetEnvironmentVariable it is only modifying the 32-bit environment block. PE would be running as a native 64-bit program, which would mean it only knows about the 64-bit PEB and the 64-bit environment block (which hasn't changed).

    Update (2010-07-10):

    Just some new info on this old topic: You can find the 32-bit PEB by calling NtQueryInformationProcess with ProcessWow64Information. It gives you a PVOID with the address of the PEB.