diff --git a/README.md b/README.md index 716b262..eeb4509 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,10 @@ if (FAILED(hr)) } return SlimDetoursTransactionCommit(); ``` +If you feel the above Detours-style API calls complicated, [SlimDetours](https://github.com/KNSoft/KNSoft.SlimDetours) provides some APIs in [Wrapper.c](https://github.com/KNSoft/KNSoft.SlimDetours/blob/main/Source/SlimDetours/Wrapper.c), which can do the job with just one line, such as: +```C +SlimDetoursSetHook((PVOID*)&g_pfnXxx, Hooked_Xxx); +``` ### Delay Hook diff --git a/README.zh-CN.md b/README.zh-CN.md index 73fab07..1dc1ac5 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -69,6 +69,10 @@ if (FAILED(hr)) } return SlimDetoursTransactionCommit(); ``` +如果觉得如上Detours风格的API调用复杂,[SlimDetours](https://github.com/KNSoft/KNSoft.SlimDetours)在[Wrapper.c](https://github.com/KNSoft/KNSoft.SlimDetours/blob/main/Source/SlimDetours/Wrapper.c)中提供了一些API,仅需一行即可完成工作,如: +```C +SlimDetoursSetHook((PVOID*)&g_pfnXxx, Hooked_Xxx); +``` ### 延迟挂钩 diff --git a/Source/KNSoft.SlimDetours.vcxproj b/Source/KNSoft.SlimDetours.vcxproj index e9ece06..9f50b89 100644 --- a/Source/KNSoft.SlimDetours.vcxproj +++ b/Source/KNSoft.SlimDetours.vcxproj @@ -206,6 +206,7 @@ + diff --git a/Source/KNSoft.SlimDetours.vcxproj.filters b/Source/KNSoft.SlimDetours.vcxproj.filters index 2614da1..c1d4ffe 100644 --- a/Source/KNSoft.SlimDetours.vcxproj.filters +++ b/Source/KNSoft.SlimDetours.vcxproj.filters @@ -27,6 +27,9 @@ SlimDetours + + SlimDetours + Detours diff --git a/Source/SlimDetours/SlimDetours.h b/Source/SlimDetours/SlimDetours.h index 602798d..328df43 100644 --- a/Source/SlimDetours/SlimDetours.h +++ b/Source/SlimDetours/SlimDetours.h @@ -27,7 +27,7 @@ extern "C" { #define DETOUR_INSTRUCTION_TARGET_NONE ((PVOID)0) #define DETOUR_INSTRUCTION_TARGET_DYNAMIC ((PVOID)(LONG_PTR)-1) -/* APIs */ +/* API from Detours */ HRESULT NTAPI @@ -53,6 +53,66 @@ SlimDetoursDetach( _Inout_ PVOID* ppPointer, _In_ PVOID pDetour); +PVOID +NTAPI +SlimDetoursCodeFromPointer( + _In_ PVOID pPointer); + +PVOID +NTAPI +SlimDetoursCopyInstruction( + _In_opt_ PVOID pDst, + _In_ PVOID pSrc, + _Out_opt_ PVOID* ppTarget, + _Out_opt_ LONG* plExtra); + +/* Wrapper API by SlimDetours */ + +HRESULT +NTAPI +SlimDetoursEnableHook( + _In_ BOOL Enable, + _Inout_ PVOID* ppPointer, + _In_ PVOID pDetour); + +HRESULT +NTAPI +SlimDetoursSetHook( + _Inout_ PVOID* ppPointer, + _In_ PVOID pDetour); + +HRESULT +NTAPI +SlimDetoursUnsetHook( + _Inout_ PVOID* ppPointer, + _In_ PVOID pDetour); + +HRESULT +NTAPI +SlimDetoursEnableHooksV( + _In_ BOOL Enable, + _In_ ULONG Count, + _In_ va_list ArgPtr); + +HRESULT +WINAPIV +SlimDetoursEnableHooks( + _In_ BOOL Enable, + _In_ ULONG Count, + ...); + +HRESULT +WINAPIV +SlimDetoursSetHooks( + _In_ ULONG Count, + ...); + +HRESULT +WINAPIV +SlimDetoursUnsetHooks( + _In_ ULONG Count, + ...); + #if (NTDDI_VERSION >= NTDDI_WIN6) typedef @@ -90,76 +150,6 @@ SlimDetoursDelayAttach( #endif /* (NTDDI_VERSION >= NTDDI_WIN6) */ -PVOID -NTAPI -SlimDetoursCodeFromPointer( - _In_ PVOID pPointer); - -PVOID -NTAPI -SlimDetoursCopyInstruction( - _In_opt_ PVOID pDst, - _In_ PVOID pSrc, - _Out_opt_ PVOID* ppTarget, - _Out_opt_ LONG* plExtra); - #ifdef __cplusplus } #endif - -/* Type - safe overloads for C++ */ - -#if __cplusplus >= 201103L || _MSVC_LANG >= 201103L -#include - -template -struct SlimDetoursIsFunctionPointer : std::false_type -{ -}; - -template -struct SlimDetoursIsFunctionPointer : std::is_function::type> -{ -}; - -template::value, int>::type = 0> -HRESULT -SlimDetoursAttach( - _Inout_ T* ppPointer, - _In_ T pDetour) noexcept -{ - return SlimDetoursAttach(reinterpret_cast(ppPointer), reinterpret_cast(pDetour)); -} - -template::value, int>::type = 0> -HRESULT -SlimDetoursDetach( - _Inout_ T* ppPointer, - _In_ T pDetour) noexcept -{ - return SlimDetoursDetach(reinterpret_cast(ppPointer), reinterpret_cast(pDetour)); -} - -#if (NTDDI_VERSION >= NTDDI_WIN6) - -template::value, int>::type = 0> -HRESULT -SlimDetoursDelayAttach( - _In_ T* ppPointer, - _In_ T pDetour, - _In_ PCWSTR DllName, - _In_ PCSTR Function, - _In_opt_ __callback DETOUR_DELAY_ATTACH_CALLBACK Callback, - _In_opt_ PVOID Context) -{ - return SlimDetoursDelayAttach(reinterpret_cast(ppPointer), - reinterpret_cast(pDetour), - DllName, - Function, - Callback, - Context); -} - -#endif /* (NTDDI_VERSION >= NTDDI_WIN6) */ - -#endif // __cplusplus >= 201103L || _MSVC_LANG >= 201103L diff --git a/Source/SlimDetours/Wrapper.c b/Source/SlimDetours/Wrapper.c new file mode 100644 index 0000000..32fb601 --- /dev/null +++ b/Source/SlimDetours/Wrapper.c @@ -0,0 +1,125 @@ +/* + * KNSoft SlimDetours (https://github.com/KNSoft/SlimDetours) Wrapper API + * Copyright (c) KNSoft.org (https://github.com/KNSoft). All rights reserved. + * Licensed under the MIT license. + */ + +#include "SlimDetours.inl" + +HRESULT +NTAPI +SlimDetoursEnableHook( + _In_ BOOL Enable, + _Inout_ PVOID* ppPointer, + _In_ PVOID pDetour) +{ + HRESULT hr; + + hr = SlimDetoursTransactionBegin(); + if (FAILED(hr)) + { + return hr; + } + hr = Enable ? SlimDetoursAttach(ppPointer, pDetour) : SlimDetoursDetach(ppPointer, pDetour); + if (FAILED(hr)) + { + SlimDetoursTransactionAbort(); + return hr; + } + return SlimDetoursTransactionCommit(); +} + +HRESULT +NTAPI +SlimDetoursSetHook( + _Inout_ PVOID* ppPointer, + _In_ PVOID pDetour) +{ + return SlimDetoursEnableHook(TRUE, ppPointer, pDetour); +} + +HRESULT +NTAPI +SlimDetoursUnsetHook( + _Inout_ PVOID* ppPointer, + _In_ PVOID pDetour) +{ + return SlimDetoursEnableHook(FALSE, ppPointer, pDetour); +} + +HRESULT +NTAPI +SlimDetoursEnableHooksV( + _In_ BOOL Enable, + _In_ ULONG Count, + _In_ va_list ArgPtr) +{ + HRESULT hr; + ULONG i; + PVOID* ppPointer; + PVOID pDetour; + + hr = SlimDetoursTransactionBegin(); + if (FAILED(hr)) + { + return hr; + } + for (i = 0; i < Count; i++) + { + ppPointer = va_arg(ArgPtr, PVOID*); + pDetour = va_arg(ArgPtr, PVOID); + hr = Enable ? SlimDetoursAttach(ppPointer, pDetour) : SlimDetoursDetach(ppPointer, pDetour); + if (FAILED(hr)) + { + SlimDetoursTransactionAbort(); + return hr; + } + } + return SlimDetoursTransactionCommit(); +} + +HRESULT +WINAPIV +SlimDetoursEnableHooks( + _In_ BOOL Enable, + _In_ ULONG Count, + ...) +{ + HRESULT hr; + va_list ap; + + va_start(ap, Count); + hr = SlimDetoursEnableHooksV(Enable, Count, ap); + va_end(ap); + return hr; +} + +HRESULT +WINAPIV +SlimDetoursSetHooks( + _In_ ULONG Count, + ...) +{ + HRESULT hr; + va_list ap; + + va_start(ap, Count); + hr = SlimDetoursEnableHooksV(TRUE, Count, ap); + va_end(ap); + return hr; +} + +HRESULT +WINAPIV +SlimDetoursUnsetHooks( + _In_ ULONG Count, + ...) +{ + HRESULT hr; + va_list ap; + + va_start(ap, Count); + hr = SlimDetoursEnableHooksV(FALSE, Count, ap); + va_end(ap); + return hr; +}