[英]What data type should the buffer be for ReadProcessMemory?
在所有示例中,我都看到了第三個參數或buffer
是一個整數,但是我不確定該值應該代表wtf還是無論如何它都有用,所以我嘗試了一個char
數組並得到了隨機垃圾,所以我我很好奇這個值可以用於什么,最好的容器,以及數據類型是否取決於我們所查詢的值。
看完我的代碼后,我意識到我在聲明它時沒有初始化進程句柄,從而犯了一個非常愚蠢的錯誤。 雖然這是我的代碼,但是現在我得到ERROR_PARTIAL_COPY
。 且dwRead
為dwRead
#include <iostream>
#include <windows.h>
using namespace std;
int main()
{
system("tasklist");
SYSTEM_INFO SysInfo;
GetSystemInfo(&SysInfo);
DWORD proc_Id = 0;
cin >> proc_Id;
HANDLE hProc = INVALID_HANDLE_VALUE;
char value[500];
SIZE_T dwRead;
hProc = OpenProcess(PROCESS_ALL_ACCESS, TRUE, proc_Id);
if(hProc == NULL)
{
cout << "Error when trying to retrieve process handle" << endl;
}
void *baseAddr = (void*)hProc;
if(VirtualAllocEx(hProc, NULL, SysInfo.dwPageSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READ) == NULL)
{
cout << "VirtualAllocEx error" << endl;
}
if(ReadProcessMemory(hProc, baseAddr, &value, sizeof(value), &dwRead) == 0)
{
cout << "ReadProcessMemory failed: " << GetLastError() << endl;
}
cout << "Value is: " << value << endl;
cout << "Amount read successfully: " << dwRead << endl;
}
BOOL WINAPI ReadProcessMemory( HANDLE hProcess, LPCVOID lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesRead );
該參數聲明為LPVOID
( void*
的typedef
)。 任何指針都可以隱式轉換為空指針-這意味着您提供的緩沖區實際上可以是您喜歡的任何類型。 唯一的限制是它必須足夠大以容納nSize
字節的數據。
SIZE_T dwRead;
int iValue;
if (ReadProcessMemory(hProcess, lpAddress, &iValue, sizeof(iValue), &dwRead)) // read an int
{
if (dwRead == sizeof(iValue))
{
// got int successfully
}
}
char buf[256];
if (ReadProcessMemory(hProcess, lpAddress, buf, sizeof(buf), &dwRead)) // read 256 chars
{
// got dwRead bytes successfully
}
如果返回的緩沖區中有垃圾,則可能是因為讀取失敗,或者未讀取所需的數據,並且未正確檢查返回值。 如果函數成功執行,則lpNumberOfBytesRead
參數可讓您確定成功讀取了多少字節。
如果函數返回0
則表示它完全失敗-在這種情況下,您提供的緩沖區的內容是未定義的,不應使用。
您應該使用函數要使用的數據類型。
https://msdn.microsoft.com/zh-cn/library/windows/desktop/ms680553(v=vs.85).aspx
至於第三個參數,只要相應地調整第四個參數,就可以使用指向任何類型數據的指針。
例如,將指向int的指針作為第三參數並將sizeof(int)
作為第四參數傳遞可能很好。
我建議使用零初始化您正在傳遞的數據(至少出於調試原因),並檢查該函數返回的所有數據是什么(尤其是作為第5個變量傳遞的指針的變量的值)。
哪種數據類型最適合您的用例取決於您。
如果您使用char
-array,這將是一種方法:
#include <iostream>
#include <Windows.h>
int main()
{
HANDLE hProcess = NULL; //to be initialized
LPCVOID lpBaseAddress = NULL; //to be initialized
char buffer[256];
SIZE_T bufferSize = sizeof(buffer);
SIZE_T bytesRead = 0;
if (::ReadProcessMemory(hProcess, lpBaseAddress, buffer, bufferSize, &bytesRead)) // read 256 chars
{
std::cout << "ReadProcessMemory succeeded by reading " << bytesRead << " bytes";
//Do something with the buffer....
}
else
{
char messageBuffer[256];
DWORD messageBufferSize = sizeof(messageBuffer);
DWORD lastError = ::GetLastError();
DWORD realMessageSize = ::FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
lastError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
messageBuffer,
messageBufferSize,
NULL);
//If FormatMessageA fails it returns 0. So we make sure that the string is empty
messageBuffer[realMessageSize] = 0;
std::cerr << "ReadProcessMemory failed with " << lastError << ": " << messageBuffer;
}
}
因為“ David Heffernan”指出了不清楚用零初始化緩沖區的含義,所以我將嘗試解釋一下:
這被認為是調試的“提示”,因為我認為比將數據單位化時更容易看到調試器中已更改的數據。 絕對不需要。
假設您的ReadProcessMemory
調用成功返回,並且您要檢查緩沖區中的數據。 你需要檢查多少字節寫入緩沖器,然后看第一bytesWritten
您的數組的字節。
如果您未將通過緩沖區傳遞的數據初始化為0
則可能更難在“真實數據”和已統一化的數據之間找到破折號,因此可能會導致誤解。 特別是對於大錯誤。
這僅是為了在開發過程中使用某種工具,以便更輕松地檢查數據, 一旦一切按預期進行 , 應將其刪除。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.