+ 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))
+ {