如何在C++中以编程方式检索 64 位进程的详细信息
How can I programmatically retrieve the details of a 64 bit process in C++?
我的目标是以编程方式获取 64 位进程的完整命令行。我已经理解并编写了这段代码,其中我对所有当前正在运行的进程进行了流程演练,并获取了它们的每个详细信息。但问题是此代码无法对 64 位进程(不在 WOW64 下运行的进程)执行相同的操作。
#include <windows.h>
#include <tlhelp32.h>
#include <tchar.h>
#include <iostream>
#include <cstdio>
#include <fstream>
using namespace std;
BOOL GetProcessList( FILE *f);
BOOL ListProcessModules( DWORD dwPID, FILE *f);
BOOL ListProcessThreads( DWORD dwOwnerPID, FILE *f );
void printError( TCHAR* msg, FILE *f );
typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
LPFN_ISWOW64PROCESS fnIsWow64Process;
BOOL IsWow64(HANDLE processHandle)
{
BOOL bIsWow64 = FALSE;
//IsWow64Process is not available on all supported versions of Windows.
//Use GetModuleHandle to get a handle to the DLL that contains the function
//and GetProcAddress to get a pointer to the function if available.
fnIsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress(
GetModuleHandle(TEXT("kernel32")),"IsWow64Process");
if(fnIsWow64Process != NULL)
{
if (!fnIsWow64Process(processHandle, &bIsWow64))
{
//handle error
}
}
return bIsWow64;
}
int main( void )
{
FILE *f = fopen("file_.txt", "w");
if (f == NULL)
{
printf("Error opening file!n");
exit(1);
}
GetProcessList(f);
return 0;
}
BOOL GetProcessList( FILE *f)
{
HANDLE hProcessSnap;
HANDLE hProcess;
PROCESSENTRY32 pe32;
DWORD dwPriorityClass;
fprintf(f, "start writing:n");
/*
myfile.open ("example.txt");
myfile << "writing starts here..." << endl;
*/
// Take a snapshot of all processes in the system.
hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
if( hProcessSnap == INVALID_HANDLE_VALUE )
{
printError( TEXT("CreateToolhelp32Snapshot (of processes)"), f);
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"), f ); // 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
{
_tprintf( TEXT("nn=====================================================" ));
_tprintf( TEXT("nPROCESS NAME: %s"), pe32.szExeFile );
_tprintf( TEXT("n-------------------------------------------------------" ));
fprintf(f, "nn=====================================================");
fprintf(f, "nPROCESS NAME: %s", pe32.szExeFile );
fprintf(f, "n------------------------------------------------------------");
/*
myfile << "nn=====================================================";
myfile << "nPROCESS NAME " << pe32.szExeFile;
myfile << "n-----------------------------------------------------------";
*/
// Retrieve the priority class.
dwPriorityClass = 0;
hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID );
//is hProcess the handle to the process?
if( hProcess == NULL )
printError( TEXT("OpenProcess"), f );
else
{
if(IsWow64(hProcess)){
_tprintf(TEXT("nThe process is running under WOW64.n"));
fprintf(f, "nThe process is running under WOW64.n");
//myfile << "nThe process is running under WOW64.n";
}
else{
_tprintf(TEXT("nThe process is not running under WOW64.n"));
fprintf(f, "nThe process is not running under WOW64.n");
//myfile << "nThe process is not running under WOW64.n";
}
dwPriorityClass = GetPriorityClass( hProcess );
if( !dwPriorityClass )
printError( TEXT("GetPriorityClass"), f );
CloseHandle( hProcess );
}
_tprintf( TEXT("n Process ID = 0x%08X"), pe32.th32ProcessID );
_tprintf( TEXT("n Thread count = %d"), pe32.cntThreads );
_tprintf( TEXT("n Parent process ID = 0x%08X"), pe32.th32ParentProcessID );
_tprintf( TEXT("n Priority base = %d"), pe32.pcPriClassBase );
fprintf(f, "n Process ID = 0x%08X", pe32.th32ProcessID);
fprintf(f, "n Thread count = %d", pe32.cntThreads );
fprintf(f, "n Parent process ID = 0x%08X", pe32.th32ParentProcessID );
fprintf(f, "n Priority base = %d", pe32.pcPriClassBase );
if( dwPriorityClass )
_tprintf( TEXT("n Priority class = %d"), dwPriorityClass );
// List the modules and threads associated with this process
ListProcessModules( pe32.th32ProcessID,f );
ListProcessThreads( pe32.th32ProcessID,f );
char *cmd_line = NULL;
//get_cmdline_from_pid(pe32.th32ProcessID, cmd_line);
} while( Process32Next( hProcessSnap, &pe32 ) );
CloseHandle( hProcessSnap );
return( TRUE );
}
BOOL ListProcessModules( DWORD dwPID,FILE *f )
{
HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
MODULEENTRY32 me32;
// Take a snapshot of all modules in the specified process.
hModuleSnap = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, dwPID );
if( hModuleSnap == INVALID_HANDLE_VALUE )
{
printError( TEXT("CreateToolhelp32Snapshot (of modules)"), f );
return( FALSE );
}
// Set the size of the structure before using it.
me32.dwSize = sizeof( MODULEENTRY32 );
// Retrieve information about the first module,
// and exit if unsuccessful
if( !Module32First( hModuleSnap, &me32 ) )
{
printError( TEXT("Module32First"), f ); // show cause of failure
CloseHandle( hModuleSnap ); // clean the snapshot object
return( FALSE );
}
// Now walk the module list of the process,
// and display information about each module
do
{
_tprintf( TEXT("nn MODULE NAME: %s"), me32.szModule );
_tprintf( TEXT("n Executable = %s"), me32.szExePath );
_tprintf( TEXT("n Process ID = 0x%08X"), me32.th32ProcessID );
_tprintf( TEXT("n Ref count (g) = 0x%04X"), me32.GlblcntUsage );
_tprintf( TEXT("n Ref count (p) = 0x%04X"), me32.ProccntUsage );
_tprintf( TEXT("n Base address = 0x%08X"), (DWORD) me32.modBaseAddr );
_tprintf( TEXT("n Base size = %d"), me32.modBaseSize );
fprintf(f, "nn MODULE NAME: %s", me32.szModule );
fprintf(f, "n Executable = %s", me32.szExePath );
fprintf(f, "n Process ID = 0x%08X", me32.th32ProcessID );
fprintf(f, "n Ref count (g) = 0x%04X", me32.GlblcntUsage );
fprintf(f, "n Ref count (p) = 0x%04X", me32.ProccntUsage );
fprintf(f, "n Base address = 0x%08X", (DWORD) me32.modBaseAddr );
fprintf(f, "n Base size = %d", me32.modBaseSize );
} while( Module32Next( hModuleSnap, &me32 ) );
CloseHandle( hModuleSnap );
return( TRUE );
}
BOOL ListProcessThreads( DWORD dwOwnerPID,FILE *f )
{
HANDLE hThreadSnap = INVALID_HANDLE_VALUE;
THREADENTRY32 te32;
// Take a snapshot of all running threads
hThreadSnap = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 );
if( hThreadSnap == INVALID_HANDLE_VALUE )
return( FALSE );
// Fill in the size of the structure before using it.
te32.dwSize = sizeof(THREADENTRY32);
// Retrieve information about the first thread,
// and exit if unsuccessful
if( !Thread32First( hThreadSnap, &te32 ) )
{
printError( TEXT("Thread32First"), f ); // show cause of failure
CloseHandle( hThreadSnap ); // clean the snapshot object
return( FALSE );
}
// Now walk the thread list of the system,
// and display information about each thread
// associated with the specified process
do
{
if( te32.th32OwnerProcessID == dwOwnerPID )
{
_tprintf( TEXT("nn THREAD ID = 0x%08X"), te32.th32ThreadID );
_tprintf( TEXT("n Base priority = %d"), te32.tpBasePri );
_tprintf( TEXT("n Delta priority = %d"), te32.tpDeltaPri );
_tprintf( TEXT("n"));
fprintf(f, "nn THREAD ID = 0x%08X", te32.th32ThreadID);
fprintf(f, "n Base priority = %d", te32.tpBasePri );
fprintf(f, "n Delta priority = %d", te32.tpDeltaPri );
fprintf(f, "n");
}
} while( Thread32Next(hThreadSnap, &te32 ) );
CloseHandle( hThreadSnap );
return( TRUE );
}
void printError( TCHAR* msg, FILE *f )
{
DWORD eNum;
TCHAR sysMsg[256];
TCHAR* p;
eNum = GetLastError( );
FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, eNum,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
sysMsg, 256, NULL );
// Trim the end of the line and terminate it with a null
p = sysMsg;
while( ( *p > 31 ) || ( *p == 9 ) )
++p;
do { *p-- = 0; } while( ( p >= sysMsg ) &&
( ( *p == '.' ) || ( *p < 33 ) ) );
// Display the message
_tprintf( TEXT("n WARNING: %s failed with error %d (%s)"), msg, eNum, sysMsg );
fprintf(f, "n WARNING: %s failed with error %d (%s)", msg, eNum, sysMsg);
}
它给了我ERROR CODE 299
,这表明它无法从进程中读取或写入内存,因此不会为我提供任何 64 位进程的可执行命令。
=====================================================
PROCESS NAME: taskhostex.exe
------------------------------------------------------------
The process is not running under WOW64.
Process ID = 0x00001954
Thread count = 10
Parent process ID = 0x000003BC
Priority base = 8
WARNING: CreateToolhelp32Snapshot (of modules) failed with error 299 (Only part of a ReadProcessMemory or WriteProcessMemory request was completed)
谁能帮我解决这个问题?
谢谢。
这
是不可能的。从文档中:
如果指定的进程是 64 位进程,并且调用方是 32位进程,此函数失败,最后一个错误代码是 ERROR_PARTIAL_COPY(299)。
您需要将代码编译为 64 位。
这里有关于这个问题的更多信息:如何从 32 位 WOW 进程枚举 64 位进程中的模块。
相关文章:
- boost::进程间消息队列引发错误
- 在进程中对同一管道进行读取和写入时C++管道出现问题
- 是否可以通过C++扩展强制多个python进程共享同一内存
- IPC使用多个管道和分支进程来运行Python程序
- 使用VerQueryValue检索应用程序的文件描述
- 异常属于C++中的线程还是进程
- WMI检测进程创建事件-c++
- 是否可以从格式字符串中检索"width"
- 使用 pqxx 将 std::vector 存储在 postgresql 中,并从数据库中检索它
- c++多进程编写一个唯一的文件
- 如何在C++中将函数发送到另一个进程
- 在Qt Creator中,如何在连接到正在运行的进程后查看控制台输出
- 终止 QProcess 不会终止子进程
- 将返回值从 exe 传递到 bat,并将其传递给 C# 中的进程
- COM :是否可以查看是否存在对我的某个 COM 对象的进程外引用?我可以释放它吗?
- 如何在C++中以编程方式检索 64 位进程的详细信息
- 检索FreeBSD系统中进程的内存使用情况
- 如何从wow64进程中检索特定内核对象的64位地址
- 可以从用户检索输入并运行另一个进程
- 正在从另一个进程检索GUI对象