OLD | NEW |
1 // Copyright 2015 Google Inc. All Rights Reserved. | 1 // Copyright 2015 Google Inc. All Rights Reserved. |
2 // | 2 // |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
4 // you may not use this file except in compliance with 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 | 5 // You may obtain a copy of the License at |
6 // | 6 // |
7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
8 // | 8 // |
9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
71 reinterpret_cast<uint8_t*>(new_entry_point) - hot_patch_start - 5; | 71 reinterpret_cast<uint8_t*>(new_entry_point) - hot_patch_start - 5; |
72 | 72 |
73 // This is the location where the short jump overwriting the first two bytes | 73 // This is the location where the short jump overwriting the first two bytes |
74 // of the function should be placed. | 74 // of the function should be placed. |
75 volatile uint16_t* jump_hook_place = | 75 volatile uint16_t* jump_hook_place = |
76 reinterpret_cast<uint16_t*>(hot_patch_start + 5); | 76 reinterpret_cast<uint16_t*>(hot_patch_start + 5); |
77 | 77 |
78 // Writes on x86 architecture are atomic within a cross 4-byte boundary. | 78 // Writes on x86 architecture are atomic within a cross 4-byte boundary. |
79 // NOTE: This can be loosened. Any two bytes starting at an address that meets | 79 // NOTE: This can be loosened. Any two bytes starting at an address that meets |
80 // the (address % 4 != 3) condition does not cross 4-byte boundary. | 80 // the (address % 4 != 3) condition does not cross 4-byte boundary. |
81 CHECK_EQ(0, reinterpret_cast<int>(jump_hook_place) % 2); | 81 CHECK_EQ(0u, reinterpret_cast<uintptr_t>(jump_hook_place) % 2); |
82 | 82 |
83 // We write the instruction JMP -5 which is represented as: 0xEB 0xF9 | 83 // We write the instruction JMP -5 which is represented as: 0xEB 0xF9 |
84 // We reverse the order of the bytes because of the little endian encoding | 84 // We reverse the order of the bytes because of the little endian encoding |
85 // to get the final value 0xF9EB. | 85 // to get the final value 0xF9EB. |
86 *jump_hook_place = 0xF9EB; | 86 *jump_hook_place = 0xF9EB; |
87 | 87 |
88 // Restore the old page protection. | 88 // Restore the old page protection. |
89 if (!::VirtualProtect(reinterpret_cast<LPVOID>(hot_patch_start), | 89 if (!::VirtualProtect(reinterpret_cast<LPVOID>(hot_patch_start), |
90 hot_patch_length, | 90 hot_patch_length, |
91 old_page_protection, | 91 old_page_protection, |
92 &old_page_protection)) { | 92 &old_page_protection)) { |
93 // We do not return false if this fails as the hot patching already | 93 // We do not return false if this fails as the hot patching already |
94 // happened. | 94 // happened. |
95 LOG(ERROR) << "Could not reset old privileges to page. Error code: " | 95 LOG(ERROR) << "Could not reset old privileges to page. Error code: " |
96 << ::common::LogWe(); | 96 << ::common::LogWe(); |
97 } | 97 } |
98 | 98 |
99 return true; | 99 return true; |
100 } | 100 } |
101 | 101 |
102 } // namespace common | 102 } // namespace common |
103 } // namespace agent | 103 } // namespace agent |
OLD | NEW |