Groups > Microsoft > WinDbg > Re: WIN32 API, help to capture env variables of another running pr




WIN32 API, help to capture env variables of another running
proces

WIN32 API, help to capture env variables of another running proces
Thu, 20 Mar 2008 19:30:00 -070
I need some help with capturing the environemnt variables from a current 
running process.  My process has no relationship to the process id to be 
query.  The code below gets me to the process memory, and I can get the 
command line that the original process was launched with but I am completely 
lost on how to go after the environment variables.  Nothing special here, no 
.net, platform is Windows XP SP2, the original application is a traditional 
win32 api application that is started with a batch file and has a command 
(console) window. Using VS2003 IDE, not 2005 yet.  At GM we are usually 3 to 
5 years behind the current OS/Software releases.  Any help is alway 
appreciated!

Regards.


typedef long NTSTATUS;

#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)

typedef enum _PROCESSINFOCLASS  PROCESSINFOCLASS;

typedef struct _INFOBLOCK
{
	unsigned long dwFiller[16];
	unsigned short wLength;
	unsigned short wMaxLength;
	const unsigned short *dwCmdLineAddress;
	const unsigned short *env;
} INFOBLOCK, *PINFOBLOCK;

typedef struct _PEB
{
	unsigned long dwFiller[4];
	PINFOBLOCK dwInfoBlockAddress;
} PEB, *PPEB;

typedef struct _PROCESS_BASIC_INFORMATION
{
	NTSTATUS ExitStatus;
	PPEB PebBaseAddress;
	unsigned long AffinityMask;
	long BasePriority;
	unsigned long UniqueProcessId;
	unsigned long InheritedFromUniqueProcessId;
} PBI;

typedef NTSTATUS (NTAPI *ZWQueryInformationProcessW)(HANDLE, 
PROCESSINFOCLASS, PVOID, ULONG, PULONG); 


void Get(HANDLE hProcess)
{
	ZWQueryInformationProcessW ZwQueryInformationProcessA;

	HMODULE hModule = GetModuleHandle(_T("ntdll"));

	ZwQueryInformationProcessA = 
(ZWQueryInformationProcessW)GetProcAddress(hModule, 
"ZwQueryInformationProcess");

	if (ZwQueryInformationProcessA == NULL) exit(1);

	PBI ProcInfo;
	PEB ProcPEB;
	INFOBLOCK ProcBlock;
	unsigned long ReturnLength;
	//HANDLE hProcess;
	unsigned short *pszCmdLine = NULL;
	int bSuccess;

	//hProcess = GetCurrentProcess();
	//hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, 
FALSE, 2780);

	if (! NT_SUCCESS(ZwQueryInformationProcessA(hProcess, 
ProcessBasicInformation, &ProcInfo, sizeof(ProcInfo), &ReturnLength))) 
exit(1);

	bSuccess = ReadProcessMemory(hProcess, (const void 
*)ProcInfo.PebBaseAddress, &ProcPEB, sizeof(ProcPEB), &ReturnLength);

	if (bSuccess != false)
	{
		bSuccess = ReadProcessMemory(hProcess, (const void 
*)ProcPEB.dwInfoBlockAddress, &ProcBlock, sizeof(ProcBlock),
&ReturnLength);

		pszCmdLine = (unsigned short *) new BYTE[ProcBlock.wMaxLength];
	}

	if (bSuccess != false)
	{
		bSuccess = ReadProcessMemory(hProcess, ProcBlock.dwCmdLineAddress, 
pszCmdLine, ProcBlock.wMaxLength, &ReturnLength);
	}

	_tprintf(TEXT("%S\n"),pszCmdLine); 

	if (NULL != pszCmdLine) delete [] pszCmdLine;

	// CloseHandle(hProcess);

	return;
}


int main()
{
	// Get the list of process identifiers.
	unsigned long processID[1024];
	unsigned long size;
	unsigned long n_processID;
	char szProcessName[MAX_PATH] = TEXT("<unknown>");
	HANDLE hProcess;
	HMODULE hModule;
	std::vector<std::pair<unsigned long, std::string> > processes;

	if (! EnumProcesses(processID, sizeof(processID), &size)) return -1;

	// Calculate how many process identifiers were returned.
	n_processID = size / sizeof(unsigned long);

	// Print the name and process identifier for each process.
	for (unsigned ii = 0; ii < n_processID; ++ii)
	{
		if (processID[ii] == 0) continue;
		
		// Get a handle to the process.
		hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, 
processID[ii]);

		// Get the process name.
		if (hProcess == NULL) continue;

		if (EnumProcessModules(hProcess, &hModule, sizeof(hModule), &size))
		{
			GetModuleBaseName(hProcess, hModule, szProcessName, 
sizeof(szProcessName)/sizeof(char));

			processes.push_back(std::make_pair(processID[ii], szProcessName));
		}

		if (! stricmp(szProcessName, "cmd.exe"))
		{
			Get(hProcess);

			std::cout << "Found PID: " << processID[ii] <<
std::endl;
		}

		//_tprintf(TEXT("%s  (PID: %u)\n"), szProcessName, processID[ii]);

		CloseHandle(hProcess);
	}

	std::sort(processes.begin(), processes.end());

	return 0;
Post Reply
Re: WIN32 API, help to capture env variables of another running proces
Sat, 22 Mar 2008 14:20:01 -070
There is no documented way to access that piece of information
across processes.

The undocumented way begins with
RTL_USER_PROCESS_PARAMETERS::Environment


-- 

-- 
This posting is provided "AS IS" with no warranties, and confers no
rights.
Use of any included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm


"Shawn" <Shawn@discussions.microsoft.com> wrote in message 
news:93372DF0-9734-4DB3-A23A-E0CE63A87519@microsoft.com...
>I need some help with capturing the environemnt variables from a current
> running process.  My process has no relationship to the process id to be
> query.  The code below gets me to the process memory, and I can get the
> command line that the original process was launched with but I am 
> completely
> lost on how to go after the environment variables.  Nothing special here, 
> no
> .net, platform is Windows XP SP2, the original application is a 
> traditional
> win32 api application that is started with a batch file and has a command
> (console) window. Using VS2003 IDE, not 2005 yet.  At GM we are usually 3 
> to
> 5 years behind the current OS/Software releases.  Any help is alway
> appreciated!
>
> Regards.
>
>
> typedef long NTSTATUS;
>
> #define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
>
> typedef enum _PROCESSINFOCLASS  
> PROCESSINFOCLASS;
>
> typedef struct _INFOBLOCK
> {
> unsigned long dwFiller[16];
> unsigned short wLength;
> unsigned short wMaxLength;
> const unsigned short *dwCmdLineAddress;
> const unsigned short *env;
> } INFOBLOCK, *PINFOBLOCK;
>
> typedef struct _PEB
> {
> unsigned long dwFiller[4];
> PINFOBLOCK dwInfoBlockAddress;
> } PEB, *PPEB;
>
> typedef struct _PROCESS_BASIC_INFORMATION
> {
> NTSTATUS ExitStatus;
> PPEB PebBaseAddress;
> unsigned long AffinityMask;
> long BasePriority;
> unsigned long UniqueProcessId;
> unsigned long InheritedFromUniqueProcessId;
> } PBI;
>
> typedef NTSTATUS (NTAPI *ZWQueryInformationProcessW)(HANDLE,
> PROCESSINFOCLASS, PVOID, ULONG, PULONG);
>
>
> void Get(HANDLE hProcess)
> {
> ZWQueryInformationProcessW ZwQueryInformationProcessA;
>
> HMODULE hModule = GetModuleHandle(_T("ntdll"));
>
> ZwQueryInformationProcessA =
> (ZWQueryInformationProcessW)GetProcAddress(hModule,
> "ZwQueryInformationProcess");
>
> if (ZwQueryInformationProcessA == NULL) exit(1);
>
> PBI ProcInfo;
> PEB ProcPEB;
> INFOBLOCK ProcBlock;
> unsigned long ReturnLength;
> //HANDLE hProcess;
> unsigned short *pszCmdLine = NULL;
> int bSuccess;
>
> //hProcess = GetCurrentProcess();
> //hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
> FALSE, 2780);
>
> if (! NT_SUCCESS(ZwQueryInformationProcessA(hProcess,
> ProcessBasicInformation, &ProcInfo, sizeof(ProcInfo),
&ReturnLength)))
> exit(1);
>
> bSuccess = ReadProcessMemory(hProcess, (const void
> *)ProcInfo.PebBaseAddress, &ProcPEB, sizeof(ProcPEB),
&ReturnLength);
>
> if (bSuccess != false)
> {
> bSuccess = ReadProcessMemory(hProcess, (const void
> *)ProcPEB.dwInfoBlockAddress, &ProcBlock, sizeof(ProcBlock), 
> &ReturnLength);
>
> pszCmdLine = (unsigned short *) new BYTE[ProcBlock.wMaxLength];
> }
>
> if (bSuccess != false)
> {
> bSuccess = ReadProcessMemory(hProcess, ProcBlock.dwCmdLineAddress,
> pszCmdLine, ProcBlock.wMaxLength, &ReturnLength);
> }
>
> _tprintf(TEXT("%S\n"),pszCmdLine);
>
> if (NULL != pszCmdLine) delete [] pszCmdLine;
>
> // CloseHandle(hProcess);
>
> return;
> }
>
>
> int main()
> {
> // Get the list of process identifiers.
> unsigned long processID[1024];
> unsigned long size;
> unsigned long n_processID;
> char szProcessName[MAX_PATH] = TEXT("<unknown>");
> HANDLE hProcess;
> HMODULE hModule;
> std::vector<std::pair<unsigned long, std::string> > processes;
>
> if (! EnumProcesses(processID, sizeof(processID), &size)) return -1;
>
> // Calculate how many process identifiers were returned.
> n_processID = size / sizeof(unsigned long);
>
> // Print the name and process identifier for each process.
> for (unsigned ii = 0; ii < n_processID; ++ii)
> {
> if (processID[ii] == 0) continue;
>
> // Get a handle to the process.
> hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false,
> processID[ii]);
>
> // Get the process name.
> if (hProcess == NULL) continue;
>
> if (EnumProcessModules(hProcess, &hModule, sizeof(hModule),
&size))
> {
> GetModuleBaseName(hProcess, hModule, szProcessName,
> sizeof(szProcessName)/sizeof(char));
>
> processes.push_back(std::make_pair(processID[ii], szProcessName));
> }
>
> if (! stricmp(szProcessName, "cmd.exe"))
> {
> Get(hProcess);
>
> std::cout << "Found PID: " << processID[ii] <<
std::endl;
> }
>
> //_tprintf(TEXT("%s  (PID: %u)\n"), szProcessName,
processID[ii]);
>
> CloseHandle(hProcess);
> }
>
> std::sort(processes.begin(), processes.end());
>
> return 0;
> } 

Post Reply
Re: WIN32 API, help to capture env variables of another running pr
Sat, 22 Mar 2008 15:52:00 -070
Thank you for you reply.
I did receive a solution from another forum, similar to what my included 
code does, but it does exactly what I was looking for.  It captures ALL the 
environment variables of a running process ID.  It is a perfect solution for 
my issue.  And it is documented, using GetProcAddress and ReadProcessMemory, 
and mining the Process Environment Block of memory.

"Ivan Brugiolo [MSFT]" wrote:

> There is no documented way to access that piece of information
> across processes.
> 
> The undocumented way begins with
> RTL_USER_PROCESS_PARAMETERS::Environment
> 
> 
> -- 
> 
> -- 
> This posting is provided "AS IS" with no warranties, and confers
no rights.
> Use of any included script samples are subject to the terms specified at
> http://www.microsoft.com/info/cpyright.htm
> 
> 
> "Shawn" <Shawn@discussions.microsoft.com> wrote in message

> news:93372DF0-9734-4DB3-A23A-E0CE63A87519@microsoft.com...
> >I need some help with capturing the environemnt variables from a
current
> > running process.  My process has no relationship to the process id to
be
> > query.  The code below gets me to the process memory, and I can get
the
> > command line that the original process was launched with but I am 
> > completely
> > lost on how to go after the environment variables.  Nothing special
here, 
> > no
> > .net, platform is Windows XP SP2, the original application is a 
> > traditional
> > win32 api application that is started with a batch file and has a
command
> > (console) window. Using VS2003 IDE, not 2005 yet.  At GM we are
usually 3 
> > to
> > 5 years behind the current OS/Software releases.  Any help is alway
> > appreciated!
> >
> > Regards.
> >
> >
> > typedef long NTSTATUS;
> >
> > #define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
> >
> > typedef enum _PROCESSINFOCLASS  
> > PROCESSINFOCLASS;
> >
> > typedef struct _INFOBLOCK
> > {
> > unsigned long dwFiller[16];
> > unsigned short wLength;
> > unsigned short wMaxLength;
> > const unsigned short *dwCmdLineAddress;
> > const unsigned short *env;
> > } INFOBLOCK, *PINFOBLOCK;
> >
> > typedef struct _PEB
> > {
> > unsigned long dwFiller[4];
> > PINFOBLOCK dwInfoBlockAddress;
> > } PEB, *PPEB;
> >
> > typedef struct _PROCESS_BASIC_INFORMATION
> > {
> > NTSTATUS ExitStatus;
> > PPEB PebBaseAddress;
> > unsigned long AffinityMask;
> > long BasePriority;
> > unsigned long UniqueProcessId;
> > unsigned long InheritedFromUniqueProcessId;
> > } PBI;
> >
> > typedef NTSTATUS (NTAPI *ZWQueryInformationProcessW)(HANDLE,
> > PROCESSINFOCLASS, PVOID, ULONG, PULONG);
> >
> >
> > void Get(HANDLE hProcess)
> > {
> > ZWQueryInformationProcessW ZwQueryInformationProcessA;
> >
> > HMODULE hModule = GetModuleHandle(_T("ntdll"));
> >
> > ZwQueryInformationProcessA =
> > (ZWQueryInformationProcessW)GetProcAddress(hModule,
> > "ZwQueryInformationProcess");
> >
> > if (ZwQueryInformationProcessA == NULL) exit(1);
> >
> > PBI ProcInfo;
> > PEB ProcPEB;
> > INFOBLOCK ProcBlock;
> > unsigned long ReturnLength;
> > //HANDLE hProcess;
> > unsigned short *pszCmdLine = NULL;
> > int bSuccess;
> >
> > //hProcess = GetCurrentProcess();
> > //hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
> > FALSE, 2780);
> >
> > if (! NT_SUCCESS(ZwQueryInformationProcessA(hProcess,
> > ProcessBasicInformation, &ProcInfo, sizeof(ProcInfo),
&ReturnLength)))
> > exit(1);
> >
> > bSuccess = ReadProcessMemory(hProcess, (const void
> > *)ProcInfo.PebBaseAddress, &ProcPEB, sizeof(ProcPEB),
&ReturnLength);
> >
> > if (bSuccess != false)
> > {
> > bSuccess = ReadProcessMemory(hProcess, (const void
> > *)ProcPEB.dwInfoBlockAddress, &ProcBlock, sizeof(ProcBlock), 
> > &ReturnLength);
> >
> > pszCmdLine = (unsigned short *) new BYTE[ProcBlock.wMaxLength];
> > }
> >
> > if (bSuccess != false)
> > {
> > bSuccess = ReadProcessMemory(hProcess, ProcBlock.dwCmdLineAddress,
> > pszCmdLine, ProcBlock.wMaxLength, &ReturnLength);
> > }
> >
> > _tprintf(TEXT("%S\n"),pszCmdLine);
> >
> > if (NULL != pszCmdLine) delete [] pszCmdLine;
> >
> > // CloseHandle(hProcess);
> >
> > return;
> > }
> >
> >
> > int main()
> > {
> > // Get the list of process identifiers.
> > unsigned long processID[1024];
> > unsigned long size;
> > unsigned long n_processID;
> > char szProcessName[MAX_PATH] = TEXT("<unknown>");
> > HANDLE hProcess;
> > HMODULE hModule;
> > std::vector<std::pair<unsigned long, std::string> >
processes;
> >
> > if (! EnumProcesses(processID, sizeof(processID), &size)) return
-1;
> >
> > // Calculate how many process identifiers were returned.
> > n_processID = size / sizeof(unsigned long);
> >
> > // Print the name and process identifier for each process.
> > for (unsigned ii = 0; ii < n_processID; ++ii)
> > {
> > if (processID[ii] == 0) continue;
> >
> > // Get a handle to the process.
> > hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
false,
> > processID[ii]);
> >
> > // Get the process name.
> > if (hProcess == NULL) continue;
> >
> > if (EnumProcessModules(hProcess, &hModule, sizeof(hModule),
&size))
> > {
> > GetModuleBaseName(hProcess, hModule, szProcessName,
> > sizeof(szProcessName)/sizeof(char));
> >
> > processes.push_back(std::make_pair(processID[ii], szProcessName));
> > }
> >
> > if (! stricmp(szProcessName, "cmd.exe"))
> > {
> > Get(hProcess);
> >
> > std::cout << "Found PID: " << processID[ii]
<< std::endl;
> > }
> >
> > //_tprintf(TEXT("%s  (PID: %u)\n"), szProcessName,
processID[ii]);
> >
> > CloseHandle(hProcess);
> > }
> >
> > std::sort(processes.begin(), processes.end());
> >
> > return 0;
> > } 
> 
> 
Post Reply
about | contact