2006-06-22 23:06:14 +00:00
|
|
|
/*
|
|
|
|
* PROJECT: ReactOS Win32 Base API
|
|
|
|
* LICENSE: GPL - See COPYING in the top level directory
|
|
|
|
* FILE: dll/win32/kernel32/mem/procmem.c
|
|
|
|
* PURPOSE: Handles virtual memory APIs
|
|
|
|
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
1999-10-17 18:18:44 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/* INCLUDES ******************************************************************/
|
|
|
|
|
2003-01-15 21:24:36 +00:00
|
|
|
#include <k32.h>
|
1999-10-17 18:18:44 +00:00
|
|
|
|
2004-10-30 22:18:17 +00:00
|
|
|
#define NDEBUG
|
2007-09-02 19:42:22 +00:00
|
|
|
#include <debug.h>
|
2004-10-30 22:18:17 +00:00
|
|
|
|
1999-10-17 18:18:44 +00:00
|
|
|
/* FUNCTIONS *****************************************************************/
|
2003-07-10 18:50:51 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2004-01-23 17:18:16 +00:00
|
|
|
BOOL
|
2006-06-22 23:06:14 +00:00
|
|
|
NTAPI
|
|
|
|
ReadProcessMemory(IN HANDLE hProcess,
|
|
|
|
IN LPCVOID lpBaseAddress,
|
|
|
|
IN LPVOID lpBuffer,
|
2010-07-17 05:18:31 +00:00
|
|
|
IN SIZE_T nSize,
|
|
|
|
OUT SIZE_T* lpNumberOfBytesRead)
|
1999-10-17 18:18:44 +00:00
|
|
|
{
|
2006-06-22 23:06:14 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
/* Do the read */
|
|
|
|
Status = NtReadVirtualMemory(hProcess,
|
|
|
|
(PVOID)lpBaseAddress,
|
|
|
|
lpBuffer,
|
|
|
|
nSize,
|
|
|
|
lpNumberOfBytesRead);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* We failed */
|
|
|
|
SetLastErrorByStatus (Status);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Return success */
|
|
|
|
return TRUE;
|
1999-10-17 18:18:44 +00:00
|
|
|
}
|
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2004-01-23 17:18:16 +00:00
|
|
|
BOOL
|
2006-06-22 23:06:14 +00:00
|
|
|
NTAPI
|
|
|
|
WriteProcessMemory(IN HANDLE hProcess,
|
|
|
|
IN LPVOID lpBaseAddress,
|
|
|
|
IN LPCVOID lpBuffer,
|
|
|
|
IN SIZE_T nSize,
|
|
|
|
OUT SIZE_T *lpNumberOfBytesWritten)
|
1999-10-17 18:18:44 +00:00
|
|
|
{
|
2006-06-22 23:06:14 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
ULONG OldValue;
|
|
|
|
SIZE_T RegionSize;
|
|
|
|
PVOID Base;
|
|
|
|
BOOLEAN UnProtect;
|
|
|
|
|
|
|
|
/* Set parameters for protect call */
|
|
|
|
RegionSize = nSize;
|
|
|
|
Base = lpBaseAddress;
|
|
|
|
|
|
|
|
/* Check the current status */
|
|
|
|
Status = NtProtectVirtualMemory(hProcess,
|
|
|
|
&Base,
|
|
|
|
&RegionSize,
|
|
|
|
PAGE_EXECUTE_READWRITE,
|
|
|
|
&OldValue);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Check if we are unprotecting */
|
|
|
|
UnProtect = OldValue & (PAGE_READWRITE |
|
|
|
|
PAGE_WRITECOPY |
|
|
|
|
PAGE_EXECUTE_READWRITE |
|
|
|
|
PAGE_EXECUTE_WRITECOPY) ? FALSE : TRUE;
|
2008-06-29 08:03:25 +00:00
|
|
|
if (!UnProtect)
|
2005-10-24 17:54:55 +00:00
|
|
|
{
|
2006-06-22 23:06:14 +00:00
|
|
|
/* Set the new protection */
|
|
|
|
Status = NtProtectVirtualMemory(hProcess,
|
|
|
|
&Base,
|
|
|
|
&RegionSize,
|
|
|
|
OldValue,
|
|
|
|
&OldValue);
|
|
|
|
|
|
|
|
/* Write the memory */
|
|
|
|
Status = NtWriteVirtualMemory(hProcess,
|
2005-10-24 17:54:55 +00:00
|
|
|
lpBaseAddress,
|
2006-06-22 23:06:14 +00:00
|
|
|
(LPVOID)lpBuffer,
|
|
|
|
nSize,
|
|
|
|
lpNumberOfBytesWritten);
|
2005-10-24 17:54:55 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2006-06-22 23:06:14 +00:00
|
|
|
/* We failed */
|
2005-10-24 17:54:55 +00:00
|
|
|
SetLastErrorByStatus(Status);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2006-06-22 23:06:14 +00:00
|
|
|
|
|
|
|
/* Flush the ITLB */
|
|
|
|
NtFlushInstructionCache(hProcess, lpBaseAddress, nSize);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Check if we were read only */
|
|
|
|
if ((OldValue & PAGE_NOACCESS) || (OldValue & PAGE_READONLY))
|
2005-10-24 17:54:55 +00:00
|
|
|
{
|
2006-06-22 23:06:14 +00:00
|
|
|
/* Restore protection and fail */
|
|
|
|
NtProtectVirtualMemory(hProcess,
|
|
|
|
&Base,
|
|
|
|
&RegionSize,
|
|
|
|
OldValue,
|
|
|
|
&OldValue);
|
|
|
|
SetLastErrorByStatus(STATUS_ACCESS_VIOLATION);
|
|
|
|
return FALSE;
|
2005-10-24 17:54:55 +00:00
|
|
|
}
|
|
|
|
|
2006-06-22 23:06:14 +00:00
|
|
|
/* Otherwise, do the write */
|
2005-10-24 17:54:55 +00:00
|
|
|
Status = NtWriteVirtualMemory(hProcess,
|
|
|
|
lpBaseAddress,
|
|
|
|
(LPVOID)lpBuffer,
|
2006-06-22 23:06:14 +00:00
|
|
|
nSize,
|
|
|
|
lpNumberOfBytesWritten);
|
|
|
|
|
|
|
|
/* And restore the protection */
|
|
|
|
NtProtectVirtualMemory(hProcess,
|
|
|
|
&Base,
|
|
|
|
&RegionSize,
|
|
|
|
OldValue,
|
|
|
|
&OldValue);
|
2005-10-24 17:54:55 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2006-06-22 23:06:14 +00:00
|
|
|
/* We failed */
|
|
|
|
SetLastErrorByStatus(STATUS_ACCESS_VIOLATION);
|
2005-10-24 17:54:55 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
2006-06-22 23:06:14 +00:00
|
|
|
|
|
|
|
/* Flush the ITLB */
|
|
|
|
NtFlushInstructionCache(hProcess, lpBaseAddress, nSize);
|
|
|
|
return TRUE;
|
2005-10-24 17:54:55 +00:00
|
|
|
}
|
2006-06-22 23:06:14 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* We failed */
|
|
|
|
SetLastErrorByStatus(Status);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2000-07-01 17:07:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* EOF */
|