Skip to content

Commit

Permalink
[WRAPPER] Add wrapper APIs, remove C++ type-safe overloads
Browse files Browse the repository at this point in the history
  • Loading branch information
RatinCN committed Jul 29, 2024
1 parent db5a9d3 commit 0939099
Show file tree
Hide file tree
Showing 6 changed files with 198 additions and 71 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -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);
```
### 延迟挂钩
Expand Down
1 change: 1 addition & 0 deletions Source/KNSoft.SlimDetours.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@
<ClCompile Include="SlimDetours\Thread.c" />
<ClCompile Include="SlimDetours\Trampoline.c" />
<ClCompile Include="SlimDetours\Transaction.c" />
<ClCompile Include="SlimDetours\Wrapper.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="Detours\src\detours.h" />
Expand Down
3 changes: 3 additions & 0 deletions Source/KNSoft.SlimDetours.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
<ClCompile Include="SlimDetours\Transaction.c">
<Filter>SlimDetours</Filter>
</ClCompile>
<ClCompile Include="SlimDetours\Wrapper.c">
<Filter>SlimDetours</Filter>
</ClCompile>
<ClCompile Include="Detours\src\creatwth.cpp">
<Filter>Detours</Filter>
</ClCompile>
Expand Down
132 changes: 61 additions & 71 deletions Source/SlimDetours/SlimDetours.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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 <type_traits>

template<typename T>
struct SlimDetoursIsFunctionPointer : std::false_type
{
};

template<typename T>
struct SlimDetoursIsFunctionPointer<T*> : std::is_function<typename std::remove_pointer<T>::type>
{
};

template<typename T, typename std::enable_if<SlimDetoursIsFunctionPointer<T>::value, int>::type = 0>
HRESULT
SlimDetoursAttach(
_Inout_ T* ppPointer,
_In_ T pDetour) noexcept
{
return SlimDetoursAttach(reinterpret_cast<void**>(ppPointer), reinterpret_cast<void*>(pDetour));
}

template<typename T, typename std::enable_if<SlimDetoursIsFunctionPointer<T>::value, int>::type = 0>
HRESULT
SlimDetoursDetach(
_Inout_ T* ppPointer,
_In_ T pDetour) noexcept
{
return SlimDetoursDetach(reinterpret_cast<void**>(ppPointer), reinterpret_cast<void*>(pDetour));
}

#if (NTDDI_VERSION >= NTDDI_WIN6)

template<typename T, typename std::enable_if<SlimDetoursIsFunctionPointer<T>::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<void**>(ppPointer),
reinterpret_cast<void*>(pDetour),
DllName,
Function,
Callback,
Context);
}

#endif /* (NTDDI_VERSION >= NTDDI_WIN6) */

#endif // __cplusplus >= 201103L || _MSVC_LANG >= 201103L
125 changes: 125 additions & 0 deletions Source/SlimDetours/Wrapper.c
Original file line number Diff line number Diff line change
@@ -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;
}

0 comments on commit 0939099

Please sign in to comment.