jimmy肖明 发表于 2024-3-3 09:18:58

64位环境下32位进程获取64位进程的命令行参数和当前目录


BOOL GetProcessCurDir(HANDLE hProcess,mystring&strCurDir)
{
    BOOL bSuccess = FALSE;
    PROCESS_BASIC_INFORMATION pbi;
    TNtQueryInformationProcess pfnNtQueryInformationProcess = NULL;
    TNtReadVirtualMemory pfnNtReadVirtualMemory = NULL;

    pfnNtQueryInformationProcess = (TNtQueryInformationProcess)GetProcAddress(GetModuleHandle(_T("ntdll.dll")),"NtQueryInformationProcess");
    pfnNtReadVirtualMemory = (TNtReadVirtualMemory)GetProcAddress(GetModuleHandle(_T("ntdll.dll")),"NtReadVirtualMemory");

    if ( pfnNtQueryInformationProcess!=NULL ){
      DWORD dwSize;
      SIZE_T size;
      int iReturn;
      PVOID pAddrPEB = NULL;

      iReturn = pfnNtQueryInformationProcess( hProcess,ProcessBasicInformation,&pbi,sizeof(pbi),&dwSize);
      pAddrPEB = pbi.PebBaseAddress;   

      // NtQueryInformationProcess returns a negative value if it fails
      if (iReturn >= 0) {
            // 1. Find the Process Environment Block
            __PEB PEB;
            size = dwSize;
            if ( ERROR_SUCCESS != pfnNtReadVirtualMemory(hProcess, pAddrPEB, &PEB, sizeof(PEB), &size) ) {
                // Call GetLastError() if you need to know why
                return bSuccess;
            }

            // 2. From this PEB, get the address of the block containing
            // a pointer to the CmdLine
            _RTL_USER_PROCESS_PARAMETERS stBlock;
            if ( ERROR_SUCCESS != pfnNtReadVirtualMemory(hProcess, (LPVOID)PEB.ProcessParameters, &stBlock, sizeof(stBlock), &size)) {
                // Call GetLastError() if you need to know why
                return bSuccess;
            }

            // 3. Get the CurDir
            wchar_t wszCurDir;
            if ( ERROR_SUCCESS != pfnNtReadVirtualMemory(hProcess, (LPVOID)stBlock.DosPath.Buffer,
                wszCurDir, stBlock.DosPath.Length*sizeof(wchar_t), &size)) {
                  // Call GetLastError() if you need to know why
                  return bSuccess;
            }

#ifdef UNICODE
            // Both strings are in UNICODE.
            strCurDir.assign(wszCurDir);
#else
            CHAR szCurDir;
            WideCharToMultiByte(CP_ACP,0,wszCurDir,size/sizeof(wchar_t),szCurDir,MAX_PATH,NULL,NULL);
            strCurDir.assign(szCurDir);
#endif
            bSuccess = TRUE;
      }
    }
    return bSuccess;
}


BOOL GetProcessCurDir64(HANDLE hProcess,mystring&strCurDir)
{
    BOOL bSuccess = FALSE;
    PROCESS_BASIC_INFORMATION64 pbi64;
    TNtQueryInformationProcess pfnNtQueryInformationProcess = NULL;
    TNtReadVirtualMemory64 pfnNtReadVirtualMemory = NULL;

    pfnNtQueryInformationProcess = (TNtQueryInformationProcess)GetProcAddress(GetModuleHandle(_T("ntdll.dll")),"NtWow64QueryInformationProcess64");
    pfnNtReadVirtualMemory = (TNtReadVirtualMemory64)GetProcAddress(GetModuleHandle(_T("ntdll.dll")),"NtWow64ReadVirtualMemory64");

    if ( pfnNtQueryInformationProcess!=NULL ){
      DWORD dwSize;
      UINT64 size;
      int iReturn;
      PVOID64 pAddrPEB = NULL;
      
      iReturn = pfnNtQueryInformationProcess( hProcess,ProcessBasicInformation,&pbi64,sizeof(pbi64),&dwSize);
      pAddrPEB = pbi64.PebBaseAddress;

      // NtQueryInformationProcess returns a negative value if it fails
      if (iReturn >= 0) {
            // 1. Find the Process Environment Block
            __PEB64 PEB;
            size = dwSize;
            if ( ERROR_SUCCESS != pfnNtReadVirtualMemory(hProcess, pAddrPEB, &PEB, sizeof(PEB), &size) ) {
                // Call GetLastError() if you need to know why
                return bSuccess;
            }

            // 2. From this PEB, get the address of the block containing
            // a pointer to the CmdLine
            _RTL_USER_PROCESS_PARAMETERS64 stBlock;
            if ( ERROR_SUCCESS != pfnNtReadVirtualMemory(hProcess, PEB.ProcessParameters, &stBlock, sizeof(stBlock),&size)) {
                // Call GetLastError() if you need to know why
                return bSuccess;
            }

            // 3. Get the CurDir
            wchar_t wszCurDir;
            if ( ERROR_SUCCESS != pfnNtReadVirtualMemory(hProcess, stBlock.DosPath.Buffer,
                wszCurDir, stBlock.DosPath.Length*sizeof(wchar_t), &size)) {
                  // Call GetLastError() if you need to know why
                  return bSuccess;
            }

#ifdef UNICODE
            // Both strings are in UNICODE.
            strCurDir.assign(wszCurDir);
#else
            CHAR szCurDir;
            WideCharToMultiByte(CP_ACP,0,wszCurDir,size/sizeof(wchar_t),szCurDir,MAX_PATH,NULL,NULL);
            strCurDir.assign(szCurDir);
#endif
            bSuccess = TRUE;
      }
    }
    return bSuccess;
}


BOOL GetProcessCmdLine(HANDLE hProcess,mystring&strCmdLine)
{
    BOOL bSuccess = FALSE;
    PROCESS_BASIC_INFORMATION pbi;
    TNtQueryInformationProcess pfnNtQueryInformationProcess = NULL;
    TNtReadVirtualMemory pfnNtReadVirtualMemory = NULL;

    pfnNtQueryInformationProcess = (TNtQueryInformationProcess)GetProcAddress(GetModuleHandle(_T("ntdll.dll")),"NtQueryInformationProcess");
    pfnNtReadVirtualMemory = (TNtReadVirtualMemory)GetProcAddress(GetModuleHandle(_T("ntdll.dll")),"NtReadVirtualMemory");

    if ( pfnNtQueryInformationProcess!=NULL ){
      DWORD dwSize;
      SIZE_T size;
      int iReturn;
      PVOID pAddrPEB = NULL;

      iReturn = pfnNtQueryInformationProcess( hProcess,ProcessBasicInformation,&pbi,sizeof(pbi),&dwSize);
      pAddrPEB = pbi.PebBaseAddress;

      // NtQueryInformationProcess returns a negative value if it fails
      if (iReturn >= 0) {
            // 1. Find the Process Environment Block
            __PEB PEB;
            size = dwSize;
            if ( ERROR_SUCCESS != pfnNtReadVirtualMemory(hProcess, pAddrPEB, &PEB, sizeof(PEB), &size) ) {
                // Call GetLastError() if you need to know why
                return bSuccess;
            }

            // 2. From this PEB, get the address of the block containing
            // a pointer to the CmdLine
            _RTL_USER_PROCESS_PARAMETERS Block;
            if ( ERROR_SUCCESS != pfnNtReadVirtualMemory(hProcess, (LPVOID)PEB.ProcessParameters, &Block, sizeof(Block), &size)) {
                  // Call GetLastError() if you need to know why
                  return(FALSE);
            }

            // 3. Get the CmdLine
            wchar_t wszCmdLine = {0};
            if ( ERROR_SUCCESS != pfnNtReadVirtualMemory(hProcess, (LPVOID)Block.CmdLine.Buffer,
                wszCmdLine, MAX_PATH*sizeof(wchar_t), &size)) {
                  // Call GetLastError() if you need to know why
                  return(FALSE);
            }

            // 4. Skip the application pathname
            //    it can be empty, "c:\...\app.exe" or c:\...\app.exe
            wchar_t* pPos = wszCmdLine;
            if (*pPos != L'\0') {
                if (*pPos == L'"') {
                  // Find the next " character
                  pPos = wcschr(&pPos, L'"');
                } else {
                  // Find the next SPACE character
                  pPos = wcschr(&pPos, L'');
                }

                // Skip it
                if (pPos != NULL)
                  pPos++;
            }

            // Copy it back
            if (pPos != NULL) {

                if (*pPos != L'\0') {
#ifdef UNICODE
                  // Both strings are in UNICODE.
                  strCmdLine.assign(wszCmdLine);
#else
                  CHAR szCmdLine = {0};
                  WideCharToMultiByte(CP_ACP,0,wszCmdLine,size/sizeof(wchar_t),szCmdLine,MAX_PATH,NULL,NULL);
                  strCmdLine = szCmdLine;
#endif
                  bSuccess = TRUE;
                }
            }
      }
    }
    return bSuccess;
}


BOOL GetProcessCmdLine64(HANDLE hProcess,mystring&strCmdLine)
{
    BOOL bSuccess = FALSE;
    PROCESS_BASIC_INFORMATION64 pbi64;
    TNtQueryInformationProcess pfnNtQueryInformationProcess = NULL;
    TNtReadVirtualMemory64 pfnNtReadVirtualMemory = NULL;

    pfnNtQueryInformationProcess = (TNtQueryInformationProcess)GetProcAddress(GetModuleHandle(_T("ntdll.dll")),"NtWow64QueryInformationProcess64");
    pfnNtReadVirtualMemory = (TNtReadVirtualMemory64)GetProcAddress(GetModuleHandle(_T("ntdll.dll")),"NtWow64ReadVirtualMemory64");

    if ( pfnNtQueryInformationProcess!=NULL ){
      DWORD dwSize;
      UINT64 size;
      int iReturn;
      PVOID64 pAddrPEB = NULL;

      iReturn = pfnNtQueryInformationProcess( hProcess,ProcessBasicInformation,&pbi64,sizeof(pbi64),&dwSize);
      pAddrPEB = pbi64.PebBaseAddress;

      // NtQueryInformationProcess returns a negative value if it fails
      if (iReturn >= 0) {
            // 1. Find the Process Environment Block
            __PEB64 PEB;
            size = dwSize;
            if ( ERROR_SUCCESS != pfnNtReadVirtualMemory(hProcess, pAddrPEB, &PEB, sizeof(PEB), &size) ) {
                // Call GetLastError() if you need to know why
                return bSuccess;
            }

            // 2. From this PEB, get the address of the block containing
            // a pointer to the CmdLine
            _RTL_USER_PROCESS_PARAMETERS64 stBlock;
            if ( ERROR_SUCCESS != pfnNtReadVirtualMemory(hProcess, (LPVOID)PEB.ProcessParameters, &stBlock, sizeof(stBlock), &size)) {
                // Call GetLastError() if you need to know why
                return(FALSE);
            }

            // 3. Get the CmdLine
            wchar_t wszCmdLine = {0};
            if ( ERROR_SUCCESS != pfnNtReadVirtualMemory(hProcess, (LPVOID)stBlock.CmdLine.Buffer,
                wszCmdLine, MAX_PATH*sizeof(wchar_t), &size)) {
                  // Call GetLastError() if you need to know why
                  return(FALSE);
            }

            // 4. Skip the application pathname
            //    it can be empty, "c:\...\app.exe" or c:\...\app.exe
            wchar_t* pPos = wszCmdLine;
            if (*pPos != L'\0') {
                if (*pPos == L'"') {
                  // Find the next " character
                  pPos = wcschr(&pPos, L'"');
                } else {
                  // Find the next SPACE character
                  pPos = wcschr(&pPos, L'');
                }

                // Skip it
                if (pPos != NULL)
                  pPos++;
            }

            // Copy it back
            if (pPos != NULL) {

                if (*pPos != L'\0') {
#ifdef UNICODE
                  // Both strings are in UNICODE.
                  strCmdLine.assign(wszCmdLine);
#else
                  CHAR szCmdLine = {0};
                  WideCharToMultiByte(CP_ACP,0,wszCmdLine,size/sizeof(wchar_t),szCmdLine,MAX_PATH,NULL,NULL);
                  strCmdLine.assign(szCmdLine);

#endif
                  bSuccess = TRUE;
                }
            }
      }
    }
    return bSuccess;
}


#include <TlHelp32.h>
#include <winternl.h>   // for Windows internal declarations.
#include "Toolhelp/Toolhelp.h"

//////////////////////////////////////////////////////////////////////////
#define WOW64

#ifdef _UNICODE
#define mystring wstring
#else
#define mystring string
#endif

typedef struct
{
    DWORD Filler;
    DWORD ProcessParameters;
} __PEB;

typedef struct
{
    PVOID64 Filler;
    PVOID64 ProcessParameters;
} __PEB64;

//
// Current Directory Structures
//
typedef struct
{
    UNICODE_STRING DosPath;
    HANDLE Handle;
}_CURDIR;

typedef struct _UNICODE_STRING64 {
    SHORT Length;
    SHORT MaximumLength;
    DWORD Fill;
    PVOID64Buffer;
} UNICODE_STRING64;

typedef struct
{
    DWORD MaximumLength;
    DWORD Length;
    DWORD Flags;
    DWORD DebugFlags;
    PVOID ConsoleHandle;
    DWORD ConsoleFlags;
    PVOID StandardInput;
    PVOID StandardOutput;
    PVOID StandardError;
    //////////////////////////
    UNICODE_STRING DosPath;    //CurrentDirectory
    HANDLE Handle;
    //////////////////////////
    UNICODE_STRING DllPath;
    UNICODE_STRING ImagePathName;
    UNICODE_STRING CmdLine;
    //……
}_RTL_USER_PROCESS_PARAMETERS;

typedef struct
{
    DWORD MaximumLength;
    DWORD Length;
    DWORD Flags;
    DWORD DebugFlags;
    PVOID64 ConsoleHandle;
    DWORD ConsoleFlags;
    PVOID64 StandardInput;
    PVOID64 StandardOutput;
    PVOID64 StandardError;
    //////////////////////////
    UNICODE_STRING64 DosPath;//CurrentDirectory
    HANDLE Handle;
    //////////////////////////
    UNICODE_STRING64 DllPath;
    UNICODE_STRING64 ImagePathName;
    UNICODE_STRING64 CmdLine;
    //……
}_RTL_USER_PROCESS_PARAMETERS64;



// end_ntddk end_ntifs
typedef struct _PROCESS_BASIC_INFORMATION64 {
    PVOID64 Reserved1;
    PVOID64 PebBaseAddress;
    PVOID64 Reserved2;
    PVOID64 UniqueProcessId;
    PVOID64 Reserved3;
} PROCESS_BASIC_INFORMATION64,*PPROCESS_BASIC_INFORMATION64;

typedef LONG (WINAPI *TNtQueryInformationProcess)(HANDLE,UINT,PVOID,ULONG,PULONG);
typedef LONG (WINAPI *TNtReadVirtualMemory)(HANDLE ProcessHandle, PVOID BaseAddress, PVOID Buffer, ULONG NumberOfBytesToRead, PULONG NumberOfBytesReaded);
typedef LONG (WINAPI *TNtReadVirtualMemory64)(HANDLE ProcessHandle, PVOID64 BaseAddress, PVOID Buffer, UINT64 NumberOfBytesToRead, PUINT64 NumberOfBytesReaded);
//////////////////////////////////////////////////////////////////////////


typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);

BOOL IsWow64()
{
    BOOL bIsWow64 = FALSE;

    LPFN_ISWOW64PROCESS
      fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(
      GetModuleHandle("kernel32"),"IsWow64Process");

    if (NULL != fnIsWow64Process)
    {
      if (!fnIsWow64Process(GetCurrentProcess(),&bIsWow64))
      {
            // handle error
      }
    }
    return bIsWow64;
}


页: [1]
查看完整版本: 64位环境下32位进程获取64位进程的命令行参数和当前目录