March 28th, 2024
3 reactions

I called CreateEnvironmentBlock with a process's token, but I didn't get that process's environment

A customer found that when they obtained the token to a process with OpenProcessToken and passed that token to CreateEnvironmentBlock, the returned environment variables didn't match the actual environment variables of the other process. Is CreateEnvironmentBlock broken?

No, CreateEnvironmentBlock is not broken. The thing that's broken is your expectations.

Nowhere does it say that CreateEnvironmentBlock copies the environment of another process. After all, it's not called CopyProcessEnvironmentBlock. Indeed, the handle that you pass to CreateEnvironmentBlock isn't even a process handle!

What CreateEnvironmentBlock does is create a new environment block for the user specified by the token. This is the mechanism that the system uses to create the initial environment for a user when they log in.

Environment variables are local to a process, and there is no documented way of extracting them. We asked the customer why they needed to extract the environment variables of another process. We never heard back.

Topics
Share

Author

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.

8 comments

Discussion is closed. Login to edit/delete existing comments.

Sort by :
Newest Popular Oldest
  • Dan Weiss

    If you really really needed to know what the environment in another process was, you could use code injection and ask from within that process.

  • Uwe Baemayr

    I had to do something like this in a COM surrogate when I ported an in-process COM server component from 32-bit to 64-bit. The large MFC-based hosting application needed to stay 32-bit (for now) so I had it invoke the new 64-bit COM component out-of-process using the surrogate. Then I discovered that the surrogate does not inherit the creator's environment (it needed the PATH and a few other variables), and always starts up in C:\WINDOWS\SYSTEM32. Since it was my component, adding an interface to set the environment and current working directory solved the problem, but it would have been...

    Read more

    I had to do something like this in a COM surrogate when I ported an in-process COM server component from 32-bit to 64-bit. The large MFC-based hosting application needed to stay 32-bit (for now) so I had it invoke the new 64-bit COM component out-of-process using the surrogate. Then I discovered that the surrogate does not inherit the creator's environment (it needed the PATH and a few other variables), and always starts up in C:\WINDOWS\SYSTEM32. Since it was my component, adding an interface to set the environment and current working directory solved the problem, but it would have been easier if that information could have been gleaned by the surrogate-hosted component.

    Read less
    • Joshua Hudson

      Hmmm; I had the reverse problem and found the simplest solution was to launch the executable that would contain the COM component myself. Oh well.

  • Joshua Hudson

    Sounds like a diagnostic tool. On modern Unix variants you can get this stuff out of PS if you are the user of the process you want to look at.

    I wouldn't be surprised if there's a decent way to get this out of a process on Windows but I only came up with a terrible way. Hint: GetEnviornmentVariable has to be implemented somehow.

    • Wilhelm Payne

      I'm certain that there is a way because Process Explorer is able to display the environment for processes on the system.

      • Me Gusta

        The most obvious way would be to inject a DLL.

    • Neil Rashbrook

      There's an edge case whereby if you're the debugger of the process then you can just ask the process to call GetEnvironmentVariable for you.

    • Henke37

      My gut says that the PEB has it. So use NtQueryInformationProcess to get the PEB base address and ReadProcessMemory to extract the data. I would consider the relevant struct part to be "stable enough" for widespread use. But it's still not officially documented.

Stay informed

Get notified when new posts are published.
Follow this blog