1 : // Copyright 2015 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 : //
15 : // Declares a helper class for use in performing hot-patching operations.
16 : // The class takes care of modifying page protections as the patcher works.
17 :
18 : #ifndef SYZYGY_AGENT_ASAN_SCOPED_PAGE_PROTECTIONS_H_
19 : #define SYZYGY_AGENT_ASAN_SCOPED_PAGE_PROTECTIONS_H_
20 :
21 : #include <windows.h>
22 : #include <map>
23 : #include "base/macros.h"
24 :
25 : namespace agent {
26 : namespace asan {
27 :
28 : // Helper class for managing page protections during hot-patching.
29 : // Notice that modifying page protections is inherently racy. This class
30 : // performs no locking. It's wise to call this function from under a lock
31 : // that prevents concurrent patching on the same module, and the caller must
32 : // guarantee that the underlying pages are not unloaded during patching.
33 : class ScopedPageProtections {
34 : public:
35 E : ScopedPageProtections() {}
36 : ~ScopedPageProtections();
37 :
38 : // Makes the page(s) containing @p size bytes starting at @p addr writable.
39 : // @param addr The address to be written.
40 : // @param size The number of bytes to be written.
41 : // @returns true on success, false otherwise.
42 : bool EnsureContainingPagesWritable(void* addr, size_t size);
43 :
44 : // Restores all page protections that have been modified. This is
45 : // automatically invoked on destruction. Specifically remembers pages for
46 : // which restoring protections failed. Repeated calls to this function
47 : // will try again for those pages.
48 : // @returns true on success, false otherwise.
49 : bool RestorePageProtections();
50 :
51 : private:
52 : // Helper function for EnsureContainingPagesWritable.
53 : // @pre page Points to the beginning of a page.
54 : // @param page The address of the page to make writable.
55 : bool EnsurePageWritable(void* page);
56 :
57 : using UnprotectedPages = std::map<void*, DWORD>;
58 :
59 : // Stores the pages unprotected with their original settings.
60 : UnprotectedPages unprotected_pages_;
61 :
62 : DISALLOW_COPY_AND_ASSIGN(ScopedPageProtections);
63 : };
64 :
65 : } // namespace asan
66 : } // namespace agent
67 :
68 : #endif // SYZYGY_AGENT_ASAN_SCOPED_PAGE_PROTECTIONS_H_
|