Author Topic: Accessing the environment of a child process  (Read 3694 times)

nidud

  • Member
  • *****
  • Posts: 1614
    • https://github.com/nidud/asmc
Accessing the environment of a child process
« on: February 18, 2016, 08:01:36 AM »
Is there a simple way to access the environment of a child process?

Code: [Select]
CreateProcess( ... )
WaitForSingleObject( PI.hProcess, INFINITE )
;
; test the environment of the child process..
;
CloseHandle( PI.hProcess )
CloseHandle( PI.hThread )

jj2007

  • Member
  • *****
  • Posts: 8772
  • Assembler is fun ;-)
    • MasmBasic
Re: Accessing the environment of a child process
« Reply #1 on: February 18, 2016, 03:25:37 PM »
If you have its source code, WM_COPYDATA is a good option. Otherwise code injection (but watch the forum rules...)

Zen

  • Member
  • ****
  • Posts: 962
  • slightly red-shifted
Re: Accessing the environment of a child process
« Reply #2 on: February 20, 2016, 06:00:38 AM »
NIDUD,
Child Processes, MSDN
...But, this is probably what you're most interested in: Process Security and Access Rights, MSDN
You will notice that this is the MSDN documentation for the current version of the Windows Operating System. As I recall, access of child process memory from the parent process works differently on older versions of the Windows Operating System.

...If you visit Raymond Chen's Windows Blog site, search for the term: child process,...Child Process Search
A process inherits its environment from its parent, and the consequences of this simple statement, Raymond Chen
Zen

nidud

  • Member
  • *****
  • Posts: 1614
    • https://github.com/nidud/asmc
Re: Accessing the environment of a child process
« Reply #3 on: February 20, 2016, 11:18:44 PM »
Thanks.

I'm trying to see if it's possible to get (and update) the current directory from running batch files. I'll look into the CreateEnvironmentBlock() function and see how that works.

dedndave

  • Member
  • *****
  • Posts: 8808
  • Still using Abacus 2.0
    • DednDave
Re: Accessing the environment of a child process
« Reply #4 on: February 21, 2016, 01:26:57 AM »
there are numerous batch tricks

tell us exactly what you are trying to do
it sounds like you could just pass the current directory on the command line
(you can get that from API too - lol)

dedndave

  • Member
  • *****
  • Posts: 8808
  • Still using Abacus 2.0
    • DednDave
Re: Accessing the environment of a child process
« Reply #5 on: February 21, 2016, 01:55:22 AM »
in other words...

make me understand why GetCurrentDirectory won't work for you

nidud

  • Member
  • *****
  • Posts: 1614
    • https://github.com/nidud/asmc
Re: Accessing the environment of a child process
« Reply #6 on: February 21, 2016, 03:36:06 AM »
in other words...

make me understand why GetCurrentDirectory won't work for you

In the shell (the file manager) the CD command is parsed inline from the command line, but the same command inside a batch file will be ignored. The same also apply to other changes to the environment so I try to find a way of duplicating the behaviour of CMD.

This problem also occur in a make process when multiple targets are parsed into separate batch files. COMMAND behaves differently but I like to use CMD to avoid loading NTVDM in XP. (%COMSPEC% usually points to COMMAND.COM in <= XP).

The SetCurrentDirectory() command do not update the current directory, but the chdir() command do:
Code: [Select]
.if SetCurrentDirectory()
.if GetCurrentDirectory()
mov eax,003A003Dh
mov ah,path
sub ah,'a' - 'A'
push eax
mov ecx,esp
lea eax,path
SetEnvironmentVariable( ecx, eax )

dedndave

  • Member
  • *****
  • Posts: 8808
  • Still using Abacus 2.0
    • DednDave
Re: Accessing the environment of a child process
« Reply #7 on: February 21, 2016, 05:06:58 AM »
ok - i am still not clear on what you are trying to accomplish

are you writing a program or a batch file or both ?

maybe you want to...

1) GetEnvironmentStrings - create an environment block of the current process
2) modify the environment strings, as desired
3) CreateProcess and pass the address of the new environment block
4) FreeEnvironmentStrings - release the environment memory block

the environment functions may be ANSI or UNICODE - use the same type for both

dedndave

  • Member
  • *****
  • Posts: 8808
  • Still using Abacus 2.0
    • DednDave
Re: Accessing the environment of a child process
« Reply #8 on: February 21, 2016, 05:12:39 AM »
for batch files, there are many little tricks to use

the SET command has a lot of info in the help

Code: [Select]
C:\> SET /?>temp.txt
there are a few others, too
i don't remember what they are, but i can probably find them if you're interested

nidud

  • Member
  • *****
  • Posts: 1614
    • https://github.com/nidud/asmc
Re: Accessing the environment of a child process
« Reply #9 on: February 21, 2016, 07:28:26 AM »
Well, a batch file is basically an extension of the current running shell. Normally a .BAT file is an extension to COMMAND.COM, and a .CMD file an extension to CMD.EXE: they behave differently.

The .COM extension indicates a 16-bit real or emulated environment with a global scope with regards to current drive/directory and environment variables. In the NT environment the scope is limited to the current process normally inherited from the parent. The file manager has to emulate the behaviour of both.

If using an NT-prompt, as Start->Run>CMD, and you type "readme.txt" and hit enter, same as CreateProcess( "cmd /C readme.txt" ), will normally open Notepad with the readme file. Using COMMAND gives you a "Wrong command or file name" error. I assume this dual behaviour ended with Win7-32, however they both keep the same environment during execution of batch files and commands.

Parsing commands and batch files is basically to complicated so you either call them directly or create a batch file from the command and pass this to CreateProcess(). The problem with that is the non-update of the environment for the parent, in this case the shell.

nidud

  • Member
  • *****
  • Posts: 1614
    • https://github.com/nidud/asmc
Re: Accessing the environment of a child process
« Reply #10 on: February 22, 2016, 04:38:20 AM »
I tested the Raymond Chen's method by creating a new environment block from the child process using CreateEnvironmentBlock(). The parent execute a batch file that print a string, change an existing (or add a new) string, and change directory.

Code: [Select]
ECHO %A0name%
SET ALLUSERSPROFILE=VOID
CD ..

The test code adds a pointer to a new environment block so the new block created from the child process should include this.

Code: [Select]
.data
command db "C:\windows\system32\cmd.exe /C child.cmd",0
environ db "A0name=value",0,0,0,0
...
CreateProcess( 0, ; pointer to name of executable module
addr command, ; pointer to command line string
0, ; process security attributes
0, ; thread security attributes
1, ; handle inheritance flag
0, ; creation flags
addr environ, ; pointer to new environment block
0, ; pointer to current directory name
edi, ; pointer to STARTUPINFO
esi ) ; pointer to PROCESS_INFORMATION

WaitForSingleObject( esi, INFINITE )


.if OpenProcess( PROCESS_VM_READ or PROCESS_QUERY_INFORMATION, 1, PI.dwProcessId )
mov ProcessHandle,eax
printf( "OpenProcess(): %d\n", eax )

.if OpenProcessToken( ProcessHandle, TOKEN_READ, addr TokenHandle )
printf( "OpenProcessToken(): %d\n", TokenHandle )
.else
perror( "OpenProcessToken()" )
.endif

.if CreateEnvironmentBlock( addr EnvironmentBlock, TokenHandle, 1 )
PrintEnvironmentBlock( EnvironmentBlock, 4 )
.else
perror( "CreateEnvironmentBlock()" )
.endif
CloseHandle( ProcessHandle )
.else
perror( "OpenProcess()" )
.endif

CloseHandle( esi )
CloseHandle( PI.hThread )

The output from the batch file confirm the new environment is used:
Code: [Select]
K:\asmc\source\test\childcwd>ECHO value
value
K:\asmc\source\test\childcwd>SET ALLUSERSPROFILE=VOID
K:\asmc\source\test\childcwd>CD ..

However, the environment created from the token handle of the child is still from the parent:
Code: [Select]
OpenProcess(): 1984
OpenProcessToken(): 1988
CreateEnvironmentBlock():
 EnvironmentBlock 0: =C:=C:\WINDOWS\system32
 EnvironmentBlock 1: =ExitCode=00000000
 EnvironmentBlock 2: =K:=K:\asmc\SOURCE\test\childcwd
 EnvironmentBlock 3: ALLUSERSPROFILE=C:\Documents and Settings\All Users.WINDOWS

nidud

  • Member
  • *****
  • Posts: 1614
    • https://github.com/nidud/asmc
Re: Accessing the environment of a child process
« Reply #11 on: February 22, 2016, 07:25:04 AM »
Otherwise code injection (but watch the forum rules...)

 :biggrin:

That was (and still is) the plan but I was hoping for a simpler solution. The code injection in this case is a call inside the process.
Code: [Select]
@call child
@parent /CmdToEnv

So basically the call writes a file with the environment from the child process and the parent updates from this file.