| // Copyright 2017 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "base/win/patch_util.h" |
| |
| #include "base/logging.h" |
| |
| namespace base { |
| namespace win { |
| namespace internal { |
| |
| DWORD ModifyCode(void* destination, const void* source, int length) { |
| if ((NULL == destination) || (NULL == source) || (0 == length)) { |
| NOTREACHED(); |
| return ERROR_INVALID_PARAMETER; |
| } |
| |
| // Change the page protection so that we can write. |
| MEMORY_BASIC_INFORMATION memory_info; |
| DWORD error = NO_ERROR; |
| DWORD old_page_protection = 0; |
| |
| if (!VirtualQuery(destination, &memory_info, sizeof(memory_info))) { |
| error = GetLastError(); |
| return error; |
| } |
| |
| DWORD is_executable = (PAGE_EXECUTE | PAGE_EXECUTE_READ | |
| PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY) & |
| memory_info.Protect; |
| |
| if (VirtualProtect(destination, length, |
| is_executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE, |
| &old_page_protection)) { |
| // Write the data. |
| CopyMemory(destination, source, length); |
| |
| // Restore the old page protection. |
| error = ERROR_SUCCESS; |
| VirtualProtect(destination, length, old_page_protection, |
| &old_page_protection); |
| } else { |
| error = GetLastError(); |
| } |
| |
| return error; |
| } |
| |
| } // namespace internal |
| } // namespace win |
| } // namespace base |