When I call GetStdHandle() (or some other function that does something with my process), for example:
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE); GetStdHandle() will return the STDOUT handle of my process, but how does this function knows what my process is, I mean I did not gave it the process id as a parameter.
2 Answers
Well, let's pretend that you needed to pass the process ID. How would you go about doing that?
DWORD my_id = GetCurrentProcessId(); HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE, my_id); Obviously, if we're going to call this more than once, we could save ourselves some duplication of effort, by putting it into a helper function:
HANDLE MyGetStdHandle(DWORD nStdHandle) { DWORD my_id = GetCurrentProcessId(); return GetStdHandle(STD_OUTPUT_HANDLE, my_id); } But heck, lots of people are going to need this function. Maybe we should put it into a library ... or an API ... in fact, let's just add it to the Windows API and call it GetStdHandle().
Which they did.
(OK, it doesn't really work that way, but I think it illustrates the point. The Windows API has to know what process you are calling it from, or it wouldn't be able to do anything.)
3Well, in Windows there's Thread Environment Block per thread that stored into CPU segment like fs on x86 and gs on x64.
Inside Thread Environment Block there's Process Environment Block, that stored RTL_USER_PROCESS_PARAMETER.
This is where they stored the Standard Handles, .
So GetStdHandle(STD_OUTPUT_HANDLE) return NtCurrentPeb()->ProcessParameter->StandardOutput and so on.
Assembly on x64
%define NtCurrentPeb gs:[0x60] %define ProcessParameter 32 %define StandardOutput 40 mov rax, NtCurrentPeb() mov rax, ProcessParameter[rax] mov rax, StandardOutput[rax]