- Change the protection in WriteProcessMemory if it is necessary. Modified: trunk/reactos/lib/kernel32/mem/procmem.c _____
Modified: trunk/reactos/lib/kernel32/mem/procmem.c --- trunk/reactos/lib/kernel32/mem/procmem.c 2005-10-24 17:21:23 UTC (rev 18743) +++ trunk/reactos/lib/kernel32/mem/procmem.c 2005-10-24 17:23:42 UTC (rev 18744) @@ -58,17 +58,99 @@
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_WRITE COPY) ? 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; }