mirror of
https://github.com/Microsoft/Detours
synced 2026-06-08 11:44:51 +00:00
89fc407283
* Add context callback support for x86 and x64 * Wrap feature support in #ifdef DETOURS_SUPPORT_DETOUR_CONTEXT_CALLBACK * Working sample * Use CALL rather than JMP, saving 11 bytes of code gen, and 8 bytes of memory (after alignment) * Move to matrix for callback CI build * Use strings rather than bools for matrix * Rerun checks --------- Co-authored-by: Jay Krell <jay.krell@cornell.edu>
130 lines
4.0 KiB
C++
130 lines
4.0 KiB
C++
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Detours Test Program (dumpi.cpp of dumpi.exe)
|
|
//
|
|
// Microsoft Research Detours Package
|
|
//
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
//
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <windows.h>
|
|
#include <shellapi.h>
|
|
#pragma warning(push)
|
|
#if _MSC_VER > 1400
|
|
#pragma warning(disable:6102 6103) // /analyze warnings
|
|
#endif
|
|
#include <strsafe.h>
|
|
#pragma warning(pop)
|
|
#include <detours.h>
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
DWORD GetTlsIndex()
|
|
{
|
|
static DWORD index = TlsAlloc();
|
|
return index;
|
|
}
|
|
|
|
struct CallbackContext
|
|
{
|
|
const char* Name = nullptr;
|
|
bool DetourSawCorrectCallback = false;
|
|
|
|
CallbackContext(const char* name) : Name(name) {}
|
|
};
|
|
|
|
void __stdcall StoreContextInTLSCallback(PVOID pContext)
|
|
{
|
|
DWORD index = GetTlsIndex();
|
|
if (index != TLS_OUT_OF_INDEXES)
|
|
{
|
|
TlsSetValue(index, pContext);
|
|
}
|
|
}
|
|
|
|
CallbackContext* GetContextInDetour()
|
|
{
|
|
DWORD index = GetTlsIndex();
|
|
return (index == TLS_OUT_OF_INDEXES ? nullptr : reinterpret_cast<CallbackContext*>(TlsGetValue(index)));
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
static void (WINAPI* TrueSetLastError)(DWORD) = SetLastError;
|
|
static DWORD(WINAPI* TrueGetLastError)() = GetLastError;
|
|
|
|
const char* SetLastErrorName = "SetLastError";
|
|
const char* GetLastErrorName = "GetLastError";
|
|
|
|
void __stdcall SetLastErrorDetour(DWORD error)
|
|
{
|
|
CallbackContext* context = GetContextInDetour();
|
|
if (context)
|
|
{
|
|
context->DetourSawCorrectCallback = (strncmp(context->Name, SetLastErrorName, 12) == 0);
|
|
}
|
|
TrueSetLastError(error);
|
|
}
|
|
|
|
DWORD __stdcall GetLastErrorDetour()
|
|
{
|
|
CallbackContext* context = GetContextInDetour();
|
|
if (context)
|
|
{
|
|
context->DetourSawCorrectCallback = (strncmp(context->Name, GetLastErrorName, 12) == 0);
|
|
}
|
|
return TrueGetLastError();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////// main.
|
|
//
|
|
int CDECL main(int, char **)
|
|
{
|
|
DWORD error = NO_ERROR;
|
|
CallbackContext setLastErrorContext{ SetLastErrorName };
|
|
CallbackContext getLastErrorContext{ GetLastErrorName };
|
|
|
|
DetourTransactionBegin();
|
|
DetourUpdateThread(GetCurrentThread());
|
|
error = DetourAttachWithContextCallback(&(PVOID&)TrueSetLastError, SetLastErrorDetour, nullptr, nullptr, nullptr, StoreContextInTLSCallback, &setLastErrorContext);
|
|
if (error == ERROR_NOT_SUPPORTED)
|
|
{
|
|
printf("callback.exe: Callback is not supported; did you compile with DETOURS_SUPPORT_CONTEXT_CALLBACK?\n");
|
|
return HRESULT_FROM_WIN32(error);
|
|
}
|
|
if (error != NO_ERROR) {
|
|
printf("callback.exe: Error detouring function: %ld\n", error);
|
|
return HRESULT_FROM_WIN32(error);
|
|
}
|
|
DetourAttachWithContextCallback(&(PVOID&)TrueGetLastError, GetLastErrorDetour, nullptr, nullptr, nullptr, StoreContextInTLSCallback, &getLastErrorContext);
|
|
error = DetourTransactionCommit();
|
|
if (error != NO_ERROR) {
|
|
printf("callback.exe: Error committing attach transaction: %ld\n", error);
|
|
return HRESULT_FROM_WIN32(error);
|
|
}
|
|
|
|
SetLastError(0);
|
|
GetLastError();
|
|
|
|
DetourTransactionBegin();
|
|
DetourUpdateThread(GetCurrentThread());
|
|
DetourDetach(&(PVOID&)TrueSetLastError, SetLastErrorDetour);
|
|
DetourDetach(&(PVOID&)TrueGetLastError, GetLastErrorDetour);
|
|
error = DetourTransactionCommit();
|
|
if (error != NO_ERROR) {
|
|
printf("callback.exe: Error committing detach transaction: %ld\n", error);
|
|
return HRESULT_FROM_WIN32(error);
|
|
}
|
|
|
|
printf("callback.exe: SetLastError did %ssee the correct callback context!\n", (setLastErrorContext.DetourSawCorrectCallback ? "" : "NOT "));
|
|
printf("callback.exe: GetLastError did %ssee the correct callback context!\n", (getLastErrorContext.DetourSawCorrectCallback ? "" : "NOT "));
|
|
|
|
return 0;
|
|
}
|
|
|
|
// End of File
|