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 return ERROR_INVALID_PARAMETER;
17 }
18
19 // Change the page protection so that we can write.
20 MEMORY_BASIC_INFORMATION memory_info;
21 DWORD error = NO_ERROR;
22 DWORD old_page_protection = 0;
23
24 if (!VirtualQuery(destination, &memory_info, sizeof(memory_info))) {
25 error = GetLastError();
26 return error;
27 }
28
29 DWORD is_executable = (PAGE_EXECUTE | PAGE_EXECUTE_READ |
30 PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY) &
31 memory_info.Protect;
32
33 if (VirtualProtect(destination, length,
34 is_executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE,
35 &old_page_protection)) {
36 // Write the data.
37 CopyMemory(destination, source, length);
38
39 // Restore the old page protection.
40 error = ERROR_SUCCESS;
41 VirtualProtect(destination, length, old_page_protection,
42 &old_page_protection);
43 } else {
44 error = GetLastError();
45 }
46
47 return error;
48 }
49
50 } // namespace internal
51 } // namespace win
52 } // namespace base
53