Skip to content

Commit

Permalink
Feature: Make section count configurable, fix RTC error, and expose D…
Browse files Browse the repository at this point in the history
…etourIsFunctionImported (#225)

A few minor changes:

- Expose detour_is_imported via a new public function DetourIsFunctionImported
- Make certain runtime checks happy by masking pbTarget before casting to smaller type
- Enable user to compile with a different number of supported section headers (leaves default at 32)
  • Loading branch information
JohnMcPMS authored Jul 6, 2022
1 parent a1dd93f commit 24357c6
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 5 deletions.
9 changes: 8 additions & 1 deletion src/detours.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1395,6 +1395,12 @@ PVOID WINAPI DetourAllocateRegionWithinJumpBounds(_In_ LPCVOID pbTarget,
return pbNewlyAllocated;
}

BOOL WINAPI DetourIsFunctionImported(_In_ PBYTE pbCode,
_In_ PBYTE pbAddress)
{
return detour_is_imported(pbCode, pbAddress);
}

static PDETOUR_TRAMPOLINE detour_alloc_trampoline(PBYTE pbTarget)
{
// We have to place trampolines within +/- 2GB of target.
Expand Down Expand Up @@ -1437,7 +1443,8 @@ static PDETOUR_TRAMPOLINE detour_alloc_trampoline(PBYTE pbTarget)
// We need to allocate a new region.

// Round pbTarget down to 64KB block.
pbTarget = pbTarget - (PtrToUlong(pbTarget) & 0xffff);
// /RTCc RuntimeChecks breaks PtrToUlong.
pbTarget = pbTarget - (ULONG)((ULONG_PTR)pbTarget & 0xffff);

PVOID pbNewlyAllocated =
detour_alloc_trampoline_allocate_new(pbTarget, pLo, pHi);
Expand Down
14 changes: 10 additions & 4 deletions src/detours.h
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,11 @@ extern const GUID DETOUR_EXE_RESTORE_GUID;
extern const GUID DETOUR_EXE_HELPER_GUID;

#define DETOUR_TRAMPOLINE_SIGNATURE 0x21727444 // Dtr!
typedef struct _DETOUR_TRAMPOLINE DETOUR_TRAMPOLINE, *PDETOUR_TRAMPOLINE;
typedef struct _DETOUR_TRAMPOLINE DETOUR_TRAMPOLINE, *PDETOUR_TRAMPOLINE;

#ifndef DETOUR_MAX_SUPPORTED_IMAGE_SECTION_HEADERS
#define DETOUR_MAX_SUPPORTED_IMAGE_SECTION_HEADERS 32
#endif // !DETOUR_MAX_SUPPORTED_IMAGE_SECTION_HEADERS

/////////////////////////////////////////////////////////// Binary Structures.
//
Expand Down Expand Up @@ -454,9 +458,9 @@ typedef struct _DETOUR_EXE_RESTORE
#endif
#ifdef IMAGE_NT_OPTIONAL_HDR64_MAGIC // some environments do not have this
BYTE raw[sizeof(IMAGE_NT_HEADERS64) +
sizeof(IMAGE_SECTION_HEADER) * 32];
sizeof(IMAGE_SECTION_HEADER) * DETOUR_MAX_SUPPORTED_IMAGE_SECTION_HEADERS];
#else
BYTE raw[0x108 + sizeof(IMAGE_SECTION_HEADER) * 32];
BYTE raw[0x108 + sizeof(IMAGE_SECTION_HEADER) * DETOUR_MAX_SUPPORTED_IMAGE_SECTION_HEADERS];
#endif
};
DETOUR_CLR_HEADER clr;
Expand Down Expand Up @@ -590,7 +594,9 @@ PVOID WINAPI DetourCopyInstruction(_In_opt_ PVOID pDst,
BOOL WINAPI DetourSetCodeModule(_In_ HMODULE hModule,
_In_ BOOL fLimitReferencesToModule);
PVOID WINAPI DetourAllocateRegionWithinJumpBounds(_In_ LPCVOID pbTarget,
_Out_ PDWORD pcbAllocatedSize);
_Out_ PDWORD pcbAllocatedSize);
BOOL WINAPI DetourIsFunctionImported(_In_ PBYTE pbCode,
_In_ PBYTE pbAddress);

///////////////////////////////////////////////////// Loaded Binary Functions.
//
Expand Down
25 changes: 25 additions & 0 deletions tests/test_module_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -728,4 +728,29 @@ TEST_CASE("DetourRestoreAfterWithEx", "[module]")
// TODO: Needs to be written.
}

// Define the import symbol so that we can get the address of the IAT entry for a static import
#ifdef _X86_
#pragma warning(disable:4483) // disable warning/error about __identifier(<string>)
#define __imp_SetLastError __identifier("_imp__SetLastError@4")
#endif

extern "C" extern void *__imp_SetLastError;

TEST_CASE("DetourIsFunctionImported", "[module]")
{
SECTION("Passing NULL code pointer, results in false")
{
REQUIRE(!DetourIsFunctionImported(NULL, reinterpret_cast<PBYTE>(&__imp_SetLastError)));
}

SECTION("Passing NULL target, results in false")
{
REQUIRE(!DetourIsFunctionImported(reinterpret_cast<PBYTE>(&__ImageBase), NULL));
}

SECTION("Passing imported function, results in true")
{
REQUIRE(DetourIsFunctionImported(reinterpret_cast<PBYTE>(&__ImageBase), reinterpret_cast<PBYTE>(&__imp_SetLastError)));
}
}

0 comments on commit 24357c6

Please sign in to comment.