Hey, I am trying to use the ReadProcessMemory function but every time I call it I get the error code 299 from the function GetLastError() that means: "Only part of a ReadProcessMemory or WriteProcessMemory request was completed.".
It may be due to your not elevating the token privilege level since you're reading memory on the system level. But even if your are elevating the privilege level, you may not be doing it correctly. The reason being is that I noticed you were not elevating the privilege level correctly in one of your other posts. You were calling it after opening the process. It must be called prior to opening the process. Also, the 0x001cf834 address is incorrect. I put some info in the sample to explain the address.
But anyway, the following example displays the command line parms (if any) of the process in question.
Code:
#define UNICODE
#define _UNICODE
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#pragma comment(lib, "advapi32.lib")
// Process data block is found in an NT machine.
// on an Intel system at 0x00020000 which is the 32
// memory page. At offset 0x0498 is what I believe to be
// the process' startup directory which is followed by
// the system's PATH. Next is process full command
// followed by the exe name.
#define PROCESS_DATA_BLOCK_ADDRESS (LPVOID)0x00020498
// align pointer
#define ALIGNMENT(x) ( (x & 0xFFFFFFFC) ? (x & 0xFFFFFFFC) + sizeof(DWORD) : x )
BOOL GetCommandLine (HANDLE hProcess, LPWSTR lpszCmdLine)
{
LPBYTE lpBuffer = NULL;
LPBYTE lpPosition = NULL;
DWORD dwBytesRead;
MEMORY_BASIC_INFORMATION mbi;
SYSTEM_INFO sysinfo;
GetSystemInfo (&sysinfo);
lpBuffer = (LPBYTE)malloc (sysinfo.dwPageSize);
if ( lpBuffer == NULL )
return FALSE;
if ( VirtualQueryEx (hProcess, PROCESS_DATA_BLOCK_ADDRESS, &mbi, sizeof(mbi) ) == 0)
return FALSE;
if (!ReadProcessMemory ( hProcess, mbi.BaseAddress, (LPVOID)lpBuffer,
sysinfo.dwPageSize, &dwBytesRead))
return FALSE;
lpPosition = lpBuffer + ((DWORD)PROCESS_DATA_BLOCK_ADDRESS - (DWORD)mbi.BaseAddress);
lpPosition = lpPosition + (wcslen ((LPWSTR)lpPosition) + 1) * sizeof(WCHAR);
lpPosition = (LPBYTE)ALIGNMENT((DWORD)lpPosition);
lpPosition = lpPosition + (wcslen ((LPWSTR)lpPosition) + 1) * sizeof(WCHAR);
if ( *lpPosition == '\0' ) lpPosition += sizeof(WCHAR);
wcsncpy ( lpszCmdLine, (LPWSTR)lpPosition, MAX_PATH );
lpszCmdLine[MAX_PATH-1] = L'\0';
if (lpBuffer != NULL) free(lpBuffer);
return TRUE;
}
BOOL EnableTokenPrivilege (LPTSTR privilege)
{
HANDLE hToken;
TOKEN_PRIVILEGES token_privileges;
DWORD dwSize;
ZeroMemory (&token_privileges, sizeof (token_privileges));
token_privileges.PrivilegeCount = 1;
if ( !OpenProcessToken (GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken))
return FALSE;
if (!LookupPrivilegeValue ( NULL, privilege, &token_privileges.Privileges[0].Luid))
{
CloseHandle (hToken);
return FALSE;
}
token_privileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!AdjustTokenPrivileges ( hToken, FALSE, &token_privileges, 0, NULL, &dwSize))
{
CloseHandle (hToken);
return FALSE;
}
CloseHandle (hToken);
return TRUE;
}
int wmain (int argc, wchar_t *argv[])
{
WCHAR CommandLine[MAX_PATH] = {0};
WCHAR *endptr;
DWORD pID;
HANDLE hProcess = NULL;
if ( argc != 2 )
return 0;
pID = wcstoul ( argv[1], &endptr, 10 );
if ( !EnableTokenPrivilege (SE_DEBUG_NAME) )
{
printf ( "Cannot get required privilege %lu\n", GetLastError () );
return 0;
}
hProcess = OpenProcess (PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_QUERY_INFORMATION,
FALSE, pID);
if ( hProcess == NULL )
{
printf ("Cannot open process. pID: %lu, error %lu\n", pID, GetLastError ());
return 0;
}
if ( !GetCommandLine ( hProcess, CommandLine ) )
{
printf ("Cannot get process command line, error: %lu\n", GetLastError ());
return 0;
}
else
printf ("The command line is %S\n", CommandLine);
CloseHandle ( hProcess );
return 0;
}