| 1397 | } |
| 1398 | |
| 1399 | static PDETOUR_TRAMPOLINE detour_alloc_trampoline(PBYTE pbTarget) |
| 1400 | { |
| 1401 | // We have to place trampolines within +/- 2GB of target. |
| 1402 | |
| 1403 | PDETOUR_TRAMPOLINE pLo; |
| 1404 | PDETOUR_TRAMPOLINE pHi; |
| 1405 | |
| 1406 | detour_find_jmp_bounds(pbTarget, &pLo, &pHi); |
| 1407 | |
| 1408 | PDETOUR_TRAMPOLINE pTrampoline = NULL; |
| 1409 | |
| 1410 | // Insure that there is a default region. |
| 1411 | if (s_pRegion == NULL && s_pRegions != NULL) { |
| 1412 | s_pRegion = s_pRegions; |
| 1413 | } |
| 1414 | |
| 1415 | // First check the default region for an valid free block. |
| 1416 | if (s_pRegion != NULL && s_pRegion->pFree != NULL && |
| 1417 | s_pRegion->pFree >= pLo && s_pRegion->pFree <= pHi) { |
| 1418 | |
| 1419 | found_region: |
| 1420 | pTrampoline = s_pRegion->pFree; |
| 1421 | // do a last sanity check on region. |
| 1422 | if (pTrampoline < pLo || pTrampoline > pHi) { |
| 1423 | return NULL; |
| 1424 | } |
| 1425 | s_pRegion->pFree = (PDETOUR_TRAMPOLINE)pTrampoline->pbRemain; |
| 1426 | memset(pTrampoline, 0xcc, sizeof(*pTrampoline)); |
| 1427 | return pTrampoline; |
| 1428 | } |
| 1429 | |
| 1430 | // Then check the existing regions for a valid free block. |
| 1431 | for (s_pRegion = s_pRegions; s_pRegion != NULL; s_pRegion = s_pRegion->pNext) { |
| 1432 | if (s_pRegion != NULL && s_pRegion->pFree != NULL && |
| 1433 | s_pRegion->pFree >= pLo && s_pRegion->pFree <= pHi) { |
| 1434 | goto found_region; |
| 1435 | } |
| 1436 | } |
| 1437 | |
| 1438 | // We need to allocate a new region. |
| 1439 | |
| 1440 | // Round pbTarget down to 64KB block. |
| 1441 | pbTarget = pbTarget - (PtrToUlong(pbTarget) & 0xffff); |
| 1442 | |
| 1443 | PVOID pbNewlyAllocated = |
| 1444 | detour_alloc_trampoline_allocate_new(pbTarget, pLo, pHi); |
| 1445 | if (pbNewlyAllocated != NULL) { |
| 1446 | s_pRegion = (DETOUR_REGION*)pbNewlyAllocated; |
| 1447 | s_pRegion->dwSignature = DETOUR_REGION_SIGNATURE; |
| 1448 | s_pRegion->pFree = NULL; |
| 1449 | s_pRegion->pNext = s_pRegions; |
| 1450 | s_pRegions = s_pRegion; |
| 1451 | DETOUR_TRACE((" Allocated region %p..%p\n\n", |
| 1452 | s_pRegion, ((PBYTE)s_pRegion) + DETOUR_REGION_SIZE - 1)); |
| 1453 | |
| 1454 | // Put everything but the first trampoline on the free list. |
| 1455 | PBYTE pFree = NULL; |
| 1456 | pTrampoline = ((PDETOUR_TRAMPOLINE)s_pRegion) + 1; |
no test coverage detected
searching dependent graphs…