我想尝试构建一个小的程序,该程序可以读取其他程序的内存并将其转储到文本文件(如果显然可以访问)。但是对我来说,访问似乎是一个问题。我首先尝试了一下,想打印当前正在运行的所有进程的列表,但是显然我什至无权打开某些进程。但是,如果我在Cheat Engine之类的程序中打开列表,它将显示所有进程名称(如果我正确查看,则系统进程例如主要是PID 4)。现在,我刚刚在打开进程时弄乱了所需的访问级别,还是作弊引擎只是使用了一些技巧或从其他位置读取了名称?我同时尝试了QueryFullProcessImageName
和GetBaseModuleName
,其中后者需要PROCESS_VM_READ
访问,这就是我使用QueryFullProcessImageName
的原因,因为我试图将访问级别降到最低。
#include <cstring>
#include <iostream>
#include <iomanip>
#ifdef _WIN32_WINNT
#undef _WIN32_WINNT
#endif
#define _WIN32_WINNT 0x0600 /* Define so QueryFullProcessImageName can be used */
#include <windows.h>
#include <psapi.h>
using namespace std;
WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR cmdLine, int cmdShow) {
DWORD processIds[256]; /* Buffer for the process IDs */
DWORD cbNeeded; /* Space needed from EnumProcesses() to store all IDs */
/*
* I will not check if the space was sufficient or not because this is just a local experiment
* and i can insure it is enough space
*/
if (EnumProcesses(processIds, sizeof(processIds), &cbNeeded) == 0) {
cout << "Error while enumerating processes(" << GetLastError() << ")" << endl;
return 0;
}
for (unsigned int i = 0; i < cbNeeded / sizeof(DWORD); i++) {
DWORD nameBufferSize = 128;
LPSTR processBaseName = new CHAR[128];
/* Open the process; here is where i get access denied */
HANDLE openProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, processIds[i]);
if (openProcess == NULL) {
if(GetLastError() == 5) strcpy(processBaseName, "<denied>");
else strcpy(processBaseName, "<unknown>");
} else if (QueryFullProcessImageName(openProcess, NULL, processBaseName, nameBufferSize) == 0) {
if(GetLastError() == 5) strcpy(processBaseName, "<denied>");
else strcpy(processBaseName, "<unknown>");
}
cout << "PID: " << setw(6) << left << processIds[i] << "\t" << processBaseName << endl;
delete processBaseName;
CloseHandle(openProcess);
}
return 0;
}
答案 0 :(得分:1)
在这里有许多有用的信息进行了评论,以便我自己回答问题。如上所述,问题是我将永远没有足够的权限来打开受保护的系统进程。解决方案是以另一种方式收集信息。如前所述,使用CreateToolhelp32Snapshot
可以更容易地获得当前所有正在运行的进程的快照。然后,我可以通过Process32First
遍历它们,然后再跟着Process32Next
遍历它们,然后只需读取结构的PROCESSENTRY32::szExeFile
即可获得进程的名称。
我现在使用的代码:
HANDLE processSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (processSnapshot == INVALID_HANDLE_VALUE) {
std::cout << "Error while taking process snapshot(" << GetLastError() << ")" << std::endl;
return 0
}
PROCESSENTRY32 process;
process.dwSize = sizeof(PROCESSENTRY32); /* This is neccessary as the Process32First/Next function expects the size of the class in this member before the first call */
if ( ! Process32First(processSnapshot, &process) ) {
std::cout << "Error while accessing first entry of snapshot(" << GetLastError() << ")" << std::endl;
return 0;
}
do {
std::cout << "PID: " << process.th32ProcessID << "\t" << process.szExeFile << std::endl;
} while( Process32Next(processSnapshot, &process) );
if (GetLastError() != ERROR_NO_MORE_FILES) { /* The Process32Next function throws the ERROR_NO_MORE_FILES error code when there is no more entry to read. If this is not the last error message something went wrong. */
std::cout << "Error while enumerating processes(" << GetLastError() << ")" << std::endl;
}
请注意,快照是当前状态的快照,如果打开或关闭了任何进程,则需要再次获取快照以获取新状态和新进程的信息。
答案 1 :(得分:0)
受保护的过程是您的主要原因。例如,您无法打开csrss.exe,smss.exe或系统的句柄。其次,尝试启用调试特权public void startTask()
{
// Create a Runnable
Runnable task = new Runnable()
{
public void run()
{
runTask();
}
};
// Run the task in a background thread
Thread backgroundThread = new Thread(task);
// Terminate the running thread if the application exits
backgroundThread.setDaemon(true);
// Start the thread
backgroundThread.start();
}
public void runTask()
{
final int[] i = new int[1];
int numRow;
Label lblRow1;
Connection con;
PreparedStatement s5 = null;
final PreparedStatement[] s6 = {null};
con = KoneksiDB.getKoneksi();
FileInputStream input = null;
try {
input = new FileInputStream(new File(String.valueOf(selectedFile)));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
POIFSFileSystem fis = null;
try {
fis = new POIFSFileSystem(input);
} catch (IOException e) {
e.printStackTrace();
}
HSSFWorkbook workbook = null;
try {
workbook = new HSSFWorkbook(fis);
} catch (IOException e) {
e.printStackTrace();
}
HSSFSheet sheet = workbook.getSheetAt(0);
numRow = sheet.getPhysicalNumberOfRows();
final Row[] row = new Row[1];
{
try
{
// Get the Status
// Update the Label on the JavaFx Application Thread
Platform.runLater(new Runnable()
{
@Override
public void run()
{
for (i[0] = 1; i[0] <= sheet.getLastRowNum(); i[0]++)
{
row[0] = sheet.getRow(i[0]);
String col9 =
row[0].getCell(1).getStringCellValue();
double col10 =
row[0].getCell(9).getNumericCellValue();
String sqlcommand9 = "UPDATE hg_saham SET
harga_harian= '" + col10 + "' WHERE kode_saham='" + col9 + "'";
try {
s6[0] = (PreparedStatement)
con.prepareStatement(sqlcommand9);
} catch (SQLException e) {
e.printStackTrace();
}
try {
s6[0].addBatch();
} catch (SQLException e) {
e.printStackTrace();
}
try {
s6[0].executeBatch();
} catch (SQLException e) {
e.printStackTrace();
}
System.out.println("Processing " + i[0] + " of " +
sheet.getLastRowNum());
}
String status = "Processing " + i[0] + " of " +
sheet.getLastRowNum();
actionStatus.setText(status);
lbltext.setText(status);
}
});
Thread.sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
@FXML
private void handleKembali(ActionEvent event) {
dialogStage.close();
}
public void setDialog(Stage dialogStage) {
this.dialogStage = dialogStage;
}
}
。然后还以管理员身份运行,以查看是否有更多进程。但是,即使具有调试特权,您也无法访问受保护的进程。为此,您需要使用SeDebugPriviledge
或SeLocateProcessImageFileName
的内核模式驱动程序。