Boost Library to find parent's process ID - c++

I am really messed up with the code base I have and I am working on portability of C++ code.
As of now the code seems to be windows specific and it tries to take the parent's process ID that is executing itself. Eg: I write a code in C++ that uses the Parent's process ID of the cmd that is executing the corresponding EXE created by its (code's)compilation.
DWORD getParentPID()
{
HANDLE hSnapshot;
PROCESSENTRY32 pe32;
DWORD parentPID = 0, PID = GetCurrentProcessId();
hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
__try{
if( hSnapshot == INVALID_HANDLE_VALUE ) __leave;
ZeroMemory( &pe32, sizeof( pe32 ) );
pe32.dwSize = sizeof( pe32 );
if( !Process32First( hSnapshot, &pe32 ) ) __leave;
do{
if( pe32.th32ProcessID == PID ){
parentPID = pe32.th32ParentProcessID;
break;
}
}while( Process32Next( hSnapshot, &pe32 ) );
}
__finally{
if( hSnapshot != INVALID_HANDLE_VALUE ) CloseHandle( hSnapshot );
}
return parentPID;
}
Obviously, this code is not intended to work on Linux and I don't want any precompilation, Looking forward to some platform independent code using Boost C++.
PS: Precompilation up to som extent is accepted. Mainly Targeted platforms are Windows and Linux.I might be missing on some small points due to the workload.
Any Lead is appreciated, thanks in advance.

Related

GetProcessMemoryInfo failed with error 6 Handle is invalid

I'm trying to get the list of processes running in the system using C++. I use the functions available in the Windows API (like OpenProcess & CreateToolhelp32Snapshot ) to get it done.
The problem is that the code works fine for most of the processes, but couldn't get the memory info for crucial system processes alone, I have given the seDebugPrivilege also and have run the program as administrator only.
I get the output like
File Name PID Memory Used
winlogon.exe 1248 2432 KB
fontdrvhost.exe 1308
WARNING: GetProcessMemoryInfo failed with error 6 (The handle is invalid)
dwm.exe 1384
WARNING: GetProcessMemoryInfo failed with error 6 (The handle is invalid)
svchost.exe 1448 4744 KB
My code is :
BOOL GetProcessList( )
{
HANDLE hProcessSnap;
HANDLE hProcess;
HANDLE hToken;
PROCESSENTRY32 pe32;
DWORD dwPriorityClass;
PROCESS_MEMORY_COUNTERS pmc;
hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
if( hProcessSnap == INVALID_HANDLE_VALUE )
{
char err[]="CreateToolhelp32Snapshot (of processes)";
printError( err );
return( FALSE );
}
pe32.dwSize = sizeof( PROCESSENTRY32 );
if( !Process32First( hProcessSnap, &pe32 ) )
{
char err[]="Process32First";
printError( err ); // show cause of failure
CloseHandle( hProcessSnap ); // clean the snapshot object
return( FALSE );
}
if(!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &hToken))
{
if (GetLastError() == ERROR_NO_TOKEN)
{
if (!ImpersonateSelf(SecurityImpersonation))
return FALSE;
if(!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &hToken)){
char err[]="OpenThreadToken";
printError( err );
return FALSE;
}
}
else
return FALSE;
}
SetPrivilege(hToken, SE_DEBUG_NAME, FALSE);
do
{
printf( "%-25s", pe32.szExeFile );
dwPriorityClass = 0;
SIZE_T dwMin, dwMax;
hProcess = OpenProcess( PROCESS_QUERY_LIMITED_INFORMATION , FALSE, pe32.th32ProcessID );
printf("%-10d", pe32.th32ProcessID );
if(GetProcessMemoryInfo( hProcess, (PROCESS_MEMORY_COUNTERS *)&pmc, sizeof(pmc)))
{
printf( "%-10d KB", pmc.PagefileUsage/1024);
} else{
char err[]="GetProcessMemoryInfo";
printError( err );
}
printf("\n");
CloseHandle(hProcess);
}while( Process32Next( hProcessSnap, &pe32 ) );
CloseHandle( hProcessSnap );
return( TRUE );
}
To get this code to work, you have to change:
SetPrivilege(hToken, SE_DEBUG_NAME, FALSE)
to:
SetPrivilege(hToken, SE_DEBUG_NAME, TRUE)
As others have commented, to get this code to work properly, you have to:
check for and report all possible error conditions
release all resources when you are done, in this case release hToken (via CloseHandle()) and call revertToSelf() if needs be.
Other than that, it's a decent effort so thumbs up for that.
Link to SetPrivilege(), in case any future visitor needs it:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa446619.aspx
Happy hacking.

WINAPI VirtualQueryEx - invalid handle

I am trying to read some pages of memory of a 32 bit process using VirtualQueryEx using Visual Studio 2012.
However when I run the program I get VirtualQueryEx Error 6: Invalid Handle. However there is no error with the handle itself [hProcess] and I am passing in the appropriate parameters. What could be it?
#include <windows.h>
#include <tlhelp32.h>
#include <tchar.h>
#include <stdio.h>
// Forward declarations:
BOOL GetProcessList( );
BOOL ListProcessModules( DWORD dwPID );
BOOL ListProcessThreads( DWORD dwOwnerPID );
void printError( TCHAR* msg );
int main( void )
{
GetProcessList( );
system("pause");
return 0;
}
BOOL GetProcessList( )
{
HANDLE hProcessSnap;
HANDLE hProcess;
PROCESSENTRY32 pe32;
DWORD dwPriorityClass;
// Take a snapshot of all processes in the system.
hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
if( hProcessSnap == INVALID_HANDLE_VALUE )
{
printError( TEXT("CreateToolhelp32Snapshot (of processes)") );
return( FALSE );
}
// Set the size of the structure before using it.
pe32.dwSize = sizeof( PROCESSENTRY32 );
// Retrieve information about the first process,
// and exit if unsuccessful
if( !Process32First( hProcessSnap, &pe32 ) )
{
printError( TEXT("Process32First") ); // show cause of failure
CloseHandle( hProcessSnap ); // clean the snapshot object
return( FALSE );
}
// Now walk the snapshot of processes, and
// display information about each process in turn
do
{
//If the process name equals foo_process.exe
if (!_tcscmp(pe32.szExeFile, _T("foo_process.exe")))
{
hProcess = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, false, pe32.th32ProcessID );
if( hProcess == NULL )
printError( TEXT("OpenProcess") );
unsigned char *addr = NULL;
MEMORY_BASIC_INFORMATION meminfo;
if (VirtualQueryEx(hProcess, addr, &meminfo, sizeof(meminfo)) == 0){
printError( TEXT("VirtualQueryEx") );
//return FALSE;
}
}
} while( Process32Next( hProcessSnap, &pe32 ) );
CloseHandle( hProcessSnap );
return( TRUE );
}
void printError( TCHAR* msg )
{
...
}
EDIT: Handle has value:
EDIT 2: More Info:
Windows 7 64bit platform.
Visual Studio 2012 (32 bit debugger) ran
as Administrator
Process is *32 (32bit)
unsigned char *addr = NULL;
You're asking VirtualQueryEx to Query address 0 which is not valid, causing the failure.

Using Module32First/Next to Enumerate 32bit Process Modules from 64bit Process

Here's the code:
hModuleSnap = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE32, dwPID );
if( hModuleSnap == INVALID_HANDLE_VALUE )
{
return( r_mi );
}
me32.dwSize = sizeof( MODULEENTRY32 );
if( !Module32First( hModuleSnap, &me32 ) )
{
CloseHandle( hModuleSnap );
return( r_mi );
}
do
{
MessageBoxA(0,me32.szModule,0,0);
} while( Module32Next( hModuleSnap, &me32 ) );
Problem is that when trying to enumerate the modules of a 32bit process from a 64bit process, only the x64 modules are being listed.
From MSDN for TH32CS_SNAPMODULE32:
Includes all 32-bit modules of the process specified in th32ProcessID in the snapshot when called from a 64-bit process.
But still, it's only listing the x64 modules
Anyone know a work around for this?
You have to use TH32CS_SNAPMODULE32 | TH32CS_SNAPMODULE
thanks for Hans Passant for figuring this out.

Does this program leak memory?

Due to the new usage for returning the process id? And how can i check when memory is begin leaked, throughtout debugging my application? (This length check on the explanation section really sucks =P)
#include "stdafx.h"
#include "Process.h"
#include <TlHelp32.h>
#include <iostream>
DWORD GetProcessId( const wchar_t* szProcess )
{
if( szProcess )
{
HANDLE hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
PROCESSENTRY32 *pe32 = new PROCESSENTRY32();
memset( pe32, 0, sizeof( PROCESSENTRY32 ) );
pe32->dwSize = sizeof( PROCESSENTRY32 );
//Process32First( hSnapshot, pe32 );
while( Process32Next( hSnapshot, pe32 ) )
{
if( pe32->szExeFile && !wcscmp( szProcess, pe32->szExeFile ) )
{
CloseHandle( hSnapshot );
return( pe32->th32ProcessID ); // std::wcout << pe32->szExeFile << std::endl;
}
}
CloseHandle( hSnapshot );
}
return 0;
}
HANDLE GetProcessHandle( DWORD dwProcessId )
{
if( dwProcessId )
return( OpenProcess( PROCESS_VM_READ | PROCESS_VM_WRITE, 0, dwProcessId ) );
return 0;
}
bool WriteExternProcessMemory( HANDLE hProcess, void* pAddr, size_t uSize, const char* szWrite, LPCVOID outBuffer )
{
if( pAddr && szWrite && hProcess )
{
DWORD dwOldProtect;
if( !VirtualProtectEx( hProcess, pAddr, uSize, PAGE_EXECUTE_READWRITE, &dwOldProtect ) )
return( !WriteProcessMemory( hProcess, pAddr, outBuffer, uSize, NULL ) );
}
return false;
}
-Edit,
the usage is:
void *pRecv;
WriteExternProcessMemory( GetProcessHandle( GetProcessId( _T( "notepad.exe" ) ) ), (void*)0x401000, 2, "\x40\x40", &pRecv );
This is leaking:
PROCESSENTRY32 *pe32 = new PROCESSENTRY32();
Better use:
PROCESSENTRY32 pe32 = {0};
pe32.dwSize = sizeof( PROCESSENTRY32 );
//Process32First( hSnapshot, pe32 );
while( Process32Next( hSnapshot, &pe32 ) )
...
Also, you're not closing the handle created at GetProcessHandle, which is also a leak.
Yes, you are right. Allocating memory without freeing it later, as your program does, constitutes a memory leak.
You can find leaks in your program by using a memory leak detector.
Valgrind is a wonderful tool to tell you about memory leaks. If you are compiling with debugging symbols (-g for GCC), it will even tell you what line the leak happened on!
http://valgrind.org/

Incorrect values from GetProcessHandleCount

I faced with strange behavior of function GetProcessHandleCount().
At first I take a snapshot of all processes in the system as it is described in msdn:
HANDLE hProcessSnap;
HANDLE hProcess;
PROCESSENTRY32 pe32;
hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
pe32.dwSize = sizeof( PROCESSENTRY32 );
if( !Process32First( hProcessSnap, &pe32 ) )
{
CloseHandle( hProcessSnap );
return 0;
}
Then I walk the snapshot of processes, and count up open handles by using function
GetProcessHandleCount:
int count_of_handles=0;
DWORD dwHandleCount=0;
do {
hProcess = OpenProcess( PROCESS_QUERY_INFORMATION,FALSE,pe32.th32ProcessID);
GetProcessHandleCount(hProcess,&dwHandleCount);
count_of_handles+=dwHandleCount;
if( hProcess != NULL )
CloseHandle( hProcess );
} while( Process32Next( hProcessSnap, &pe32 ) );
I checked this program in Windows 7 x64. Program displayed count_of_handles ~16000, but really this value was ~100 000 (if believe in Windows Task Manager).
Then I executed this program in Windows XP x32 (by VMWare), and count_of_handles was ~9000 (but in real it was ~8000).
What is wrong with my code? Thank you.
For one thing, GetProcessHandleCount might return zero (which signifies an error). This could explain coming to a result lower than what you expect. This might be caused in turn by OpenProcess failing (you don't check for that either).
As well as Jon's reason, the value from Task Manager1 includes handles open in the kernel – these will not be included in your total across processes.
1 For this kind of thing Process Explorer is far more effective. Including being able to list open handles per process and in the kernel, the system pseudo-process in Process Explorer's listing.