xref: /aosp_15_r20/external/cronet/base/win/patch_util.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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