From 3df6f622174d420928c1fa48523f370f54a43a85 Mon Sep 17 00:00:00 2001 From: Hartmut Birr Date: Mon, 24 Oct 2005 17:23:42 +0000 Subject: [PATCH] - Change the protection in WriteProcessMemory if it is necessary. svn path=/trunk/; revision=18744 --- reactos/lib/kernel32/mem/procmem.c | 96 +++++++++++++++++++++++++++--- 1 file changed, 89 insertions(+), 7 deletions(-) diff --git a/reactos/lib/kernel32/mem/procmem.c b/reactos/lib/kernel32/mem/procmem.c index 925370c7555..40fc3b51da1 100644 --- a/reactos/lib/kernel32/mem/procmem.c +++ b/reactos/lib/kernel32/mem/procmem.c @@ -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; } -- 2.17.1