- Change the protection in WriteProcessMemory if it is necessary.

svn path=/trunk/; revision=18744
This commit is contained in:
Hartmut Birr 2005-10-24 17:23:42 +00:00
parent ee7bf669c9
commit 3df6f62217

View file

@ -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;
}