1 // Copyright 2017 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/win/patch_util.h"
6
7 #include "base/notreached.h"
8
9 namespace base {
10 namespace win {
11 namespace internal {
12
ModifyCode(void * destination,const void * source,size_t length)13 DWORD ModifyCode(void* destination, const void* source, size_t length) {
14 if ((nullptr == destination) || (nullptr == source) || (0 == length)) {
15 NOTREACHED();
16 }
17
18 // Change the page protection so that we can write.
19 MEMORY_BASIC_INFORMATION memory_info;
20 DWORD error = NO_ERROR;
21 DWORD old_page_protection = 0;
22
23 if (!VirtualQuery(destination, &memory_info, sizeof(memory_info))) {
24 error = GetLastError();
25 return error;
26 }
27
28 DWORD is_executable = (PAGE_EXECUTE | PAGE_EXECUTE_READ |
29 PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY) &
30 memory_info.Protect;
31
32 if (VirtualProtect(destination, length,
33 is_executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE,
34 &old_page_protection)) {
35 // Write the data.
36 CopyMemory(destination, source, length);
37
38 // Restore the old page protection.
39 error = ERROR_SUCCESS;
40 VirtualProtect(destination, length, old_page_protection,
41 &old_page_protection);
42 } else {
43 error = GetLastError();
44 }
45
46 return error;
47 }
48
49 } // namespace internal
50 } // namespace win
51 } // namespace base
52