| 293 | |
| 294 | template<class T> |
| 295 | static void LoadActiveCode( |
| 296 | const T &code, |
| 297 | uptr *entry_point, |
| 298 | FunctionPrefixKind prefix_kind = FunctionPrefixNone) { |
| 299 | if (ActiveCode == nullptr) { |
| 300 | ActiveCode = AllocateCode2GBAway((u8*)&InterceptorFunction); |
| 301 | ASSERT_NE(ActiveCode, nullptr) << "failed to allocate RWX memory 2GB away"; |
| 302 | } |
| 303 | |
| 304 | size_t position = 0; |
| 305 | |
| 306 | // Add padding to avoid memory violation when scanning the prefix. |
| 307 | for (int i = 0; i < 16; ++i) |
| 308 | ActiveCode[position++] = 0xC3; // Instruction 'ret'. |
| 309 | |
| 310 | // Add function padding. |
| 311 | size_t padding = 0; |
| 312 | if (prefix_kind == FunctionPrefixPadding) |
| 313 | padding = 16; |
| 314 | else if (prefix_kind == FunctionPrefixDetour || |
| 315 | prefix_kind == FunctionPrefixHotPatch) |
| 316 | padding = FIRST_32_SECOND_64(5, 6); |
| 317 | // Insert |padding| instructions 'nop'. |
| 318 | for (size_t i = 0; i < padding; ++i) |
| 319 | ActiveCode[position++] = 0x90; |
| 320 | |
| 321 | // Keep track of the entry point. |
| 322 | *entry_point = (uptr)&ActiveCode[position]; |
| 323 | |
| 324 | // Add the detour instruction (i.e. mov edi, edi) |
| 325 | if (prefix_kind == FunctionPrefixDetour) { |
| 326 | #if SANITIZER_WINDOWS64 |
| 327 | // Note that "mov edi,edi" is NOP in 32-bit only, in 64-bit it clears |
| 328 | // higher bits of RDI. |
| 329 | // Use 66,90H as NOP for Windows64. |
| 330 | ActiveCode[position++] = 0x66; |
| 331 | ActiveCode[position++] = 0x90; |
| 332 | #else |
| 333 | // mov edi,edi. |
| 334 | ActiveCode[position++] = 0x8B; |
| 335 | ActiveCode[position++] = 0xFF; |
| 336 | #endif |
| 337 | |
| 338 | } |
| 339 | |
| 340 | // Copy the function body. |
| 341 | for (size_t i = 0; i < sizeof(T); ++i) |
| 342 | ActiveCode[position++] = code[i]; |
| 343 | } |
| 344 | |
| 345 | int InterceptorFunctionCalled; |
| 346 | IdentityFunction InterceptedRealFunction; |
no test coverage detected