mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 09:25:10 +00:00
- Change the protection in WriteProcessMemory if it is necessary.
svn path=/trunk/; revision=18744
This commit is contained in:
parent
ee7bf669c9
commit
3df6f62217
1 changed files with 89 additions and 7 deletions
|
@ -58,17 +58,99 @@ WriteProcessMemory (
|
|||
SIZE_T *lpNumberOfBytesWritten
|
||||
)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
NTSTATUS Status, ProtectStatus;
|
||||
MEMORY_BASIC_INFORMATION MemInfo;
|
||||
ULONG Length;
|
||||
BOOLEAN UnProtect;
|
||||
|
||||
Status = NtWriteVirtualMemory( hProcess, lpBaseAddress, (LPVOID)lpBuffer, nSize,
|
||||
(PULONG)lpNumberOfBytesWritten
|
||||
);
|
||||
if (lpNumberOfBytesWritten)
|
||||
{
|
||||
*lpNumberOfBytesWritten = 0;
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
while (nSize)
|
||||
{
|
||||
Status = NtQueryVirtualMemory(hProcess,
|
||||
lpBaseAddress,
|
||||
MemoryBasicInformation,
|
||||
&MemInfo,
|
||||
sizeof(MEMORY_BASIC_INFORMATION),
|
||||
NULL);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
SetLastErrorByStatus(Status);
|
||||
return FALSE;
|
||||
}
|
||||
Length = MemInfo.RegionSize - ((ULONG_PTR)lpBaseAddress - (ULONG_PTR)MemInfo.BaseAddress);
|
||||
if (Length > nSize)
|
||||
{
|
||||
Length = nSize;
|
||||
}
|
||||
UnProtect = MemInfo.Protect & (PAGE_READWRITE|PAGE_WRITECOPY|PAGE_EXECUTE_READWRITE|PAGE_EXECUTE_WRITECOPY) ? FALSE : TRUE;
|
||||
if (UnProtect)
|
||||
{
|
||||
MemInfo.BaseAddress = lpBaseAddress;
|
||||
MemInfo.RegionSize = Length;
|
||||
if (MemInfo.Protect & (PAGE_EXECUTE|PAGE_EXECUTE_READ))
|
||||
{
|
||||
MemInfo.Protect &= ~(PAGE_EXECUTE|PAGE_EXECUTE_READ);
|
||||
MemInfo.Protect |= PAGE_EXECUTE_READWRITE;
|
||||
}
|
||||
else
|
||||
{
|
||||
MemInfo.Protect &= ~(PAGE_READONLY|PAGE_NOACCESS);
|
||||
MemInfo.Protect |= PAGE_READWRITE;
|
||||
}
|
||||
|
||||
ProtectStatus = NtProtectVirtualMemory(hProcess,
|
||||
&MemInfo.BaseAddress,
|
||||
&MemInfo.RegionSize,
|
||||
MemInfo.Protect,
|
||||
&MemInfo.Protect);
|
||||
if (!NT_SUCCESS(ProtectStatus))
|
||||
{
|
||||
SetLastErrorByStatus(ProtectStatus);
|
||||
return FALSE;
|
||||
}
|
||||
Length = MemInfo.RegionSize - ((ULONG_PTR)lpBaseAddress - (ULONG_PTR)MemInfo.BaseAddress);
|
||||
if (Length > nSize)
|
||||
{
|
||||
Length = nSize;
|
||||
}
|
||||
}
|
||||
|
||||
Status = NtWriteVirtualMemory(hProcess,
|
||||
lpBaseAddress,
|
||||
(LPVOID)lpBuffer,
|
||||
Length,
|
||||
&Length);
|
||||
if (UnProtect)
|
||||
{
|
||||
ProtectStatus = NtProtectVirtualMemory(hProcess,
|
||||
&MemInfo.BaseAddress,
|
||||
&MemInfo.RegionSize,
|
||||
MemInfo.Protect,
|
||||
&MemInfo.Protect);
|
||||
}
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
SetLastErrorByStatus (Status);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if (UnProtect && !NT_SUCCESS(ProtectStatus))
|
||||
{
|
||||
SetLastErrorByStatus (ProtectStatus);
|
||||
return FALSE;
|
||||
}
|
||||
lpBaseAddress = (LPVOID)((ULONG_PTR)lpBaseAddress + Length);
|
||||
lpBuffer = (LPCVOID)((ULONG_PTR)lpBuffer + Length);
|
||||
nSize -= Length;
|
||||
if (lpNumberOfBytesWritten)
|
||||
{
|
||||
*lpNumberOfBytesWritten += Length;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue