fix ps so an x64 process's path is returned correctly when ps is run from a wow64 meterpeter.

git-svn-id: file:///home/svn/framework3/trunk@8322 4d416f70-5f16-0410-b530-b9f4589650da
unstable
Stephen Fewer 2010-01-29 12:00:45 +00:00
parent 47b08fa6ef
commit 7a32f9f2e2
2 changed files with 58 additions and 10 deletions

View File

@ -104,17 +104,24 @@ DWORD ps_getnativearch( VOID )
}
/*
* Attempt to get the processes path and name. First try to use psapi!GetModuleFileNameExA.
* If that fails then try to read the path via the process's PEB.
* Attempt to get the processes path and name.
* First, try psapi!GetModuleFileNameExA (Windows 2000/XP/2003/Vista/2008/7 but cant get x64 process paths from a wow64 process)
* Secondly, try kernel32!QueryFullProcessImageNameA (Windows Vista/2008/7)
* Thirdly, try psapi!GetProcessImageFileNameA (Windows XP/2003/Vista/2008/7 - returns native path)
* If that fails then try to read the path via the process's PEB. (Windows NT4 and above).
* Note: cpExeName is optional and only retrieved by parsing the PEB as the toolhelp/psapi techniques can get the name easier.
*/
BOOL ps_getpath( DWORD pid, char * cpExePath, DWORD dwExePathSize, char * cpExeName, DWORD dwExeNameSize )
{
BOOL success = FALSE;
HANDLE hProcess = NULL;
GETMODULEFILENAMEEXA pGetModuleFileNameExA = NULL;
HMODULE hPsapi = NULL;
HMODULE hNtdll = NULL;
// make these static to avoid some overhead when resolving due to the repeated calls to ps_getpath fo a ps command...
static GETMODULEFILENAMEEXA pGetModuleFileNameExA = NULL;
static GETPROCESSIMAGEFILENAMEA pGetProcessImageFileNameA = NULL;
static QUERYFULLPROCESSIMAGENAMEA pQueryFullProcessImageNameA = NULL;
do
{
if( !cpExePath || !dwExePathSize )
@ -126,10 +133,13 @@ BOOL ps_getpath( DWORD pid, char * cpExePath, DWORD dwExePathSize, char * cpExeN
if( !hProcess )
break;
// first, try psapi!GetModuleFileNameExA (Windows 2000/XP/2003/Vista/2008/7 but cant get x64 process paths from a wow64 process)
hPsapi = LoadLibrary( "psapi" );
if( hPsapi )
{
if( !pGetModuleFileNameExA )
pGetModuleFileNameExA = (GETMODULEFILENAMEEXA)GetProcAddress( hPsapi, "GetModuleFileNameExA" );
if( pGetModuleFileNameExA )
{
if( pGetModuleFileNameExA( hProcess, NULL, cpExePath, dwExePathSize ) )
@ -137,6 +147,39 @@ BOOL ps_getpath( DWORD pid, char * cpExePath, DWORD dwExePathSize, char * cpExeN
}
}
// secondly, try kernel32!QueryFullProcessImageNameA (Windows Vista/2008/7)
if( !success )
{
DWORD dwSize = dwExePathSize;
HANDLE hKernel = LoadLibraryA( "kernel32" );
if( !pQueryFullProcessImageNameA )
pQueryFullProcessImageNameA = (QUERYFULLPROCESSIMAGENAMEA)GetProcAddress( hKernel, "QueryFullProcessImageNameA" );
if( pQueryFullProcessImageNameA )
{
if( pQueryFullProcessImageNameA( hProcess, 0, cpExePath, &dwSize ) )
success = TRUE;
}
if( hKernel )
FreeLibrary( hKernel );
}
// thirdly, try psapi!GetProcessImageFileNameA (Windows XP/2003/Vista/2008/7 - returns a native path not a win32 path)
if( !success && hPsapi )
{
if( !pGetProcessImageFileNameA )
pGetProcessImageFileNameA = (GETPROCESSIMAGEFILENAMEA)GetProcAddress( hPsapi, "GetProcessImageFileNameA" );
if( pGetProcessImageFileNameA )
{
if( pGetProcessImageFileNameA( hProcess, cpExePath, dwExePathSize ) )
success = TRUE;
}
}
// finally if all else has failed, manually pull the exe path/name out of th PEB...
if( !success )
{
WCHAR * wcImagePathName = NULL;
@ -201,6 +244,9 @@ BOOL ps_getpath( DWORD pid, char * cpExePath, DWORD dwExePathSize, char * cpExeN
if( hProcess )
CloseHandle( hProcess );
if( !success && cpExePath )
memset( cpExePath, 0, dwExePathSize );
return success;
}

View File

@ -3,7 +3,9 @@
#define _METERPRETER_SOURCE_EXTENSION_STDAPI_STDAPI_SERVER_PROCESS_PS_H
//===============================================================================================//
typedef DWORD (WINAPI * GETMODULEFILENAMEEXA)( HANDLE, HMODULE, LPTSTR, DWORD );
typedef DWORD (WINAPI * GETMODULEFILENAMEEXA)( HANDLE hProcess, HMODULE hModule, LPTSTR lpExeName, DWORD dwSize );
typedef DWORD (WINAPI * GETPROCESSIMAGEFILENAMEA)( HANDLE hProcess, LPTSTR lpExeName, DWORD dwSize );
typedef BOOL (WINAPI * QUERYFULLPROCESSIMAGENAMEA)( HANDLE hProcess, DWORD dwFlags, LPTSTR lpExeName, PDWORD lpdwSize );
typedef HANDLE (WINAPI * CREATETOOLHELP32SNAPSHOT)( DWORD dwFlags, DWORD th32ProcessID );
typedef BOOL (WINAPI * PROCESS32FIRST)( HANDLE hSnapshot, LPPROCESSENTRY32 lppe );
typedef BOOL (WINAPI * PROCESS32NEXT)( HANDLE hSnapshot, LPPROCESSENTRY32 lppe );