Skip to content
KitploitKITPLOIT
أدواتالمدونة
إرسال
أدواتالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

··الخلاصات·اتصال·الخصوصية·© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
NtDetours — تطبيق Detours (x64/x86) الذي يستخدم استيراد ntdll فقط | Kitploit
أدوات/GitHubGitHub/rbmm/ntdetours
تحليل الكودتحليل الشفرة الديناميكي (DAST)الهندسة العكسيةمصممي الأخطاءتحليل البرمجيات الخبيثةتحليل الملفات الثنائية
GitHubrbmm/ntdetours

NtDetours

تطبيق Detours (x64/x86) الذي يستخدم استيراد ntdll فقط

عرض المستودع
9316منذ 26 أيامتمت المراجعة من قبل Kitploit

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
مشاركة
NTSTATUS NTAPI TrInit(PVOID ImageBase = &__ImageBase);

اجعل IAT قابلاً للكتابة.

ابحث عن simple.cpp

يستدعي TimedSleepEx واجهة برمجة التطبيقات الحقيقية SleepEx عبر مؤشر الدالة TrueSleepEx.``` static DWORD (WINAPI * TrueSleepEx)(DWORD dwMilliseconds, BOOL bAlertable) = SleepEx;

DWORD WINAPI TimedSleepEx(DWORD dwMilliseconds, BOOL bAlertable) { ... DWORD ret = TrueSleepEx(dwMilliseconds, bAlertable); ... }

root@kitploit:~
**_لا تفعل هذا !_** الرابط معرّف بالفعل```
EXTERN_C PVOID __imp_SleepEx = SleepEx;

متغير ( لـ x86 سيكون هذا __imp__SleepEx@8 وتحتاج إلى استخدام``` __pragma(comment(linker, "/alternatename:___imp_SleepEx=__imp__SleepEx@8"))

root@kitploit:~
لذا استخدم ***__imp_SleepEx*** بدلاً من ***TrueSleepEx*** واستدعِ واجهة البرمجة بالطريقة المعتادة والمريحة.

أي واجهة برمجة مستوردة SomeApi يتم استدعاؤها عبر مؤشر ***__imp_SomeApi*** (التحميل المؤجل عبر ***__imp_load_SomeApi***). استخدمها!

مثال```
//EXTERN_C extern PVOID __imp_SleepEx;
DECLARE_T_HOOK(SleepEx, 8)

DWORD WINAPI hook_SleepEx( _In_ DWORD dwMilliseconds, _In_ BOOL bAlertable )
{
	ULONG ret = SleepEx(dwMilliseconds, bAlertable);

	DbgPrint("%s(%x, %x) = %x\n", __FUNCTION__, dwMilliseconds, bAlertable, ret);

	return ret;
}

void DetoursDemo()
{
	DBG_PRINT_ON();

	if (0 <= TrInit())
	{
		ThreadInfo* pti;
		SuspendAll(&pti);

		DbgPrint("before: SleepEx = 0x%p\n", SleepEx);

		TrHook(&__imp_SleepEx, hook_SleepEx, pti);

		DbgPrint("after: SleepEx = 0x%p\n", SleepEx);

		ResumeAndFree(pti);

		union {
			PVOID pv;
			DWORD (WINAPI * fn_SleepEx)( _In_ DWORD dwMilliseconds, _In_ BOOL bAlertable );
		};

		if (pv = GetProcAddress(GetModuleHandleW(L"kernel32"), "SleepEx"))
		{
			if (QueueUserAPC((PAPCFUNC)OutputDebugStringA, GetCurrentThread(), (ULONG_PTR)"asynchronous procedure call...\n"))
			{
				fn_SleepEx(INFINITE, TRUE);
			}
		}
	}
}

مخرجات التصحيح النموذجية:``` NT::ThreadInfo::ThreadInfo<000002196427D6A0>(0000000000000814) NT::ThreadInfo::ThreadInfo<000002196427DBC0>(0000000000000128) NT::ThreadInfo::ThreadInfo<000002196427E0E0>(00000000000023D0) before: SleepEx = 0x00007FFED3DB06B0 0x00007FFED3DB06B0 -> 0x00007FF78BEB06C0 -> 0x00007FFE5394FFB8 [0x00007FFE5394FF98] after: SleepEx = 0x00007FFE5394FFB8 NT::ThreadInfo::~ThreadInfo<000002196427E0E0>(00000000000023D0) NT::ThreadInfo::~ThreadInfo<000002196427DBC0>(0000000000000128) NT::ThreadInfo::~ThreadInfo<000002196427D6A0>(0000000000000814) asynchronous procedure call... NT::hook_SleepEx(ffffffff, 1) = c0

root@kitploit:~
مثال آخر، مع unhook:```
DWORD WINAPI hook_SleepEx( _In_ DWORD dwMilliseconds, _In_ BOOL bAlertable )
{
	// don't use any [TrueSleepEx](https://github.com/microsoft/Detours/blob/main/samples/simple/simple.cpp#L23) !! 
	ULONG ret = SleepEx(dwMilliseconds, bAlertable);

	DbgPrint("%s(%x, %x) = %x\n", __FUNCTION__, dwMilliseconds, bAlertable, ret);

	return ret;
}

int
WINAPI
hook_MessageBoxW(
				 _In_opt_ HWND hWnd,
				 _In_opt_ PCWSTR lpText,
				 _In_opt_ PCWSTR lpCaption,
				 _In_ UINT uType)
{
	// don't use any [Real_MessageBoxW](https://raw.githubusercontent.com/microsoft/Detours/main/samples/traceapi/_win32.cpp) !! 
	
	int ret = MessageBoxW(hWnd, lpText, __FUNCTIONW__, uType);

	DbgPrint("%s(\"%S\", \"%S\") = %x\n", __FUNCTION__, lpText, lpCaption, ret);

	return ret;
}

DECLARE_T_HOOK(SleepEx, 8)
DECLARE_T_HOOK(MessageBoxW, 16)

T_HOOKS_BEGIN(gHooks)
	T_HOOK(SleepEx),
	T_HOOK(MessageBoxW),
T_HOOKS_END()

void DemoApiCalls()
{
	union {
		PVOID pv;
		DWORD (WINAPI * fn_SleepEx)( _In_ DWORD dwMilliseconds, _In_ BOOL bAlertable );
		int (WINAPI * fn_MessageBoxW)( _In_opt_ HWND hWnd, _In_opt_ LPCWSTR lpText, _In_opt_ LPCWSTR lpCaption, _In_ UINT uType);
	};

	if (pv = GetProcAddress(GetModuleHandleW(L"kernel32"), "SleepEx"))
	{
		if (QueueUserAPC((PAPCFUNC)OutputDebugStringA, GetCurrentThread(), (ULONG_PTR)"asynchronous procedure call...\n"))
		{
			fn_SleepEx(INFINITE, TRUE);
		}
	}

	if (pv = GetProcAddress(GetModuleHandleW(L"user32"), "MessageBoxW"))
	{
		fn_MessageBoxW(0, L"[some text]", 0, MB_ICONINFORMATION);
	}
}

void DetoursDemo()
{
	DBG_PRINT_ON();

	if (0 <= TrInit())
	{
		ThreadInfo* pti;
		SuspendAll(&pti);
		TrHook(gHooks, _countof(gHooks), pti);
		ResumeAndFree(pti);

		DemoApiCalls();

		SuspendAll(&pti);
		TrUnHook(gHooks, _countof(gHooks), pti);
		ResumeAndFree(pti);

		DemoApiCalls();
	}
}

NT::ThreadInfo::ThreadInfo<0000026DEA5AD6D0>(00000000000017E8)
NT::ThreadInfo::ThreadInfo<0000026DEA5ADBF0>(00000000000013E0)
NT::ThreadInfo::ThreadInfo<0000026DEA5AE110>(00000000000002D4)
0x00007FFED3DB06B0 -> 0x00007FF693E10790 -> 0x00007FFE5394FFB8 [0x00007FFE5394FF98]
0x00007FFED41CA160 -> 0x00007FF693E10720 -> 0x00007FFE5430FFB8 [0x00007FFE5430FF98]
NT::ThreadInfo::~ThreadInfo<0000026DEA5AE110>(00000000000002D4)
NT::ThreadInfo::~ThreadInfo<0000026DEA5ADBF0>(00000000000013E0)
NT::ThreadInfo::~ThreadInfo<0000026DEA5AD6D0>(00000000000017E8)
asynchronous procedure call...
NT::hook_SleepEx(ffffffff, 1) = c0


---------------------------
NT::hook_MessageBoxW
---------------------------
[some text]
---------------------------
OK   
---------------------------

NT::hook_MessageBoxW("[some text]", "(null)") = 1

NT::ThreadInfo::ThreadInfo<0000026DEA5C7370>(0000000000001A84)
NT::ThreadInfo::ThreadInfo<0000026DEA5C7890>(0000000000000D1C)
NT::ThreadInfo::ThreadInfo<0000026DEA5E2950>(00000000000020C8)
NT::ThreadInfo::ThreadInfo<0000026DEA5E2E70>(0000000000000D18)
NT::ThreadInfo::ThreadInfo<0000026DEA5E3390>(0000000000001974)
NT::ThreadInfo::ThreadInfo<0000026DEA5DD3D0>(00000000000023E0)
NT::ThreadInfo::ThreadInfo<0000026DEA5DD8F0>(0000000000001C58)
NT::ThreadInfo::~ThreadInfo<0000026DEA5DD8F0>(0000000000001C58)
NT::ThreadInfo::~ThreadInfo<0000026DEA5DD3D0>(00000000000023E0)
NT::ThreadInfo::~ThreadInfo<0000026DEA5E3390>(0000000000001974)
NT::ThreadInfo::~ThreadInfo<0000026DEA5E2E70>(0000000000000D18)
NT::ThreadInfo::~ThreadInfo<0000026DEA5E2950>(00000000000020C8)
NT::ThreadInfo::~ThreadInfo<0000026DEA5C7890>(0000000000000D1C)
NT::ThreadInfo::~ThreadInfo<0000026DEA5C7370>(0000000000001A84)

asynchronous procedure call...

---------------------------
Error
---------------------------
[some text]
---------------------------
OK   
---------------------------

DBG_PRINT_ON() / DBG_PRINT_OFF()

تمكين / تعطيل مخرجات التصحيح ( افتراضيًا معطّل)


NTSTATUS NTAPI SuspendAll(Out ThreadInfo** ppti);

تعداد سلاسل العمليات في العملية عبر NtGetNextThread تحقق مما إذا كانت سلسلة العمليات الحالية ( ZwQueryInformationThread(ThreadBasicInformation) ) تعليق سلسلة العمليات ZwSuspendThread حفظ سياقها ZwGetContextThread ربط معلومات سلسلة العمليات (المقبض/السياق) بالقائمة


void NTAPI ResumeAndFree(In ThreadInfo* pti);

اجتياز قائمة سلاسل العمليات ( pti ) استئناف سلسلة العمليات إغلاق مقبضها تحرير الذاكرة


NTSTATUS NTAPI TrHook(Inout void** p__imp, In PVOID hook, In_opt ThreadInfo* pti)```

{ T_HOOK_ENTRY entry = { p__imp, hook }; return TrHook(&entry, 1, pti); }

root@kitploit:~
نسخة مبسطة، لربط واجهة برمجية واحدة (API) وعند عدم الحاجة لإلغاء الربط
شبه مطابقة تقريبًا لـ [DetourAttach](https://github.com/microsoft/Detours/wiki/DetourAttach)
الفرق الوحيد - TrHook يقوم بالتطبيق الفعلي فورًا، بينما DetourAttach - بعد DetourTransactionCommit

*****************************************************************************************************
###### void NTAPI TrHook(_In_ T_HOOK_ENTRY* entry, _In_ ULONG n, _In_opt_ ThreadInfo* pti = 0);
*****************************************************************************************************

محاولة تخصيص ترامبولين (trampoline) في نطاق -/+ 2GB (في وضع 32 بت أي عنوان مقبول) من المنطقة المُرقّعة
ربط الواجهة البرمجية عن طريق تعيين خطاف JMP في بدايتها وحفظ التعليمات الأصلية داخل الترامبولين
التنقل عبر قائمة الخيوط (اختياري) وإذا لزم الأمر (Pc في JMP) - ضبط سياق الخيوط

توجد عدة حالات:```
////////////////////////////////////////////////////////////////////////////////////////////////////////
// typical case:

-------------------------------------------------------------------------
before:
-------------------------------------------------------------------------
EXTERN_C PVOID __imp_RtlDispatchAPC = RtlDispatchAPC;

RtlDispatchAPC:
00007FFAB20AF6D0  mov         r11,rsp 
00007FFAB20AF6D3  mov         qword ptr [r11+8],rbx 
00007FFAB20AF6D7  mov         qword ptr [r11+10h],rsi

--------------------------------------------------------------------------
after: TrHook(&__imp_RtlDispatchAPC, hook_RtlDispatchAPC);
--------------------------------------------------------------------------

RtlDispatchAPC:
00007FFB876AF6D0  jmp         hook_RtlDispatchAPC
00007FFB876AF6D7  mov         qword ptr [r11+10h],rsi 

trampoline:
00007FFA3225FFB8  mov         r11,rsp 
00007FFA3225FFBB  mov         qword ptr [r11+8],rbx 
00007FFA3225FFBF  jmp         RtlDispatchAPC + 7 (7FFB876AF6D7h) 

__imp_RtlDispatchAPC = trampoline;

////////////////////////////////////////////////////////////////////////////////////////////////////////
// x86 mov edi,edi:

#pragma comment(linker, "/alternatename:___imp_RtlActivateActivationContextUnsafeFast=__imp_@RtlActivateActivationContextUnsafeFast@8")

EXTERN_C PVOID __imp_RtlActivateActivationContextUnsafeFast = RtlActivateActivationContextUnsafeFast;

771F6FBB  int         3    
771F6FBC  int         3    
771F6FBD  int         3    
771F6FBE  int         3    
771F6FBF  int         3    
RtlActivateActivationContextUnsafeFast:
771F6FC0  mov         edi,edi 
771F6FC2  push        ebp  

--------------------------------------------------------------------------
after: TrHook(&__imp_RtlActivateActivationContextUnsafeFast, hook_RtlActivateActivationContextUnsafeFast);
--------------------------------------------------------------------------

__imp_RtlActivateActivationContextUnsafeFast = 771F6FC2 ( RtlActivateActivationContextUnsafeFast + 2 )

771F6FBB  jmp         hook_RtlActivateActivationContextUnsafeFast
RtlActivateActivationContextUnsafeFast:
771F6FC0  jmp         771F6FBB 
771F6FC2  push        ebp  

////////////////////////////////////////////////////////////////////////////////////////////////////////
// case 1: data access relocated

-------------------------------------------------------------------------
before:
-------------------------------------------------------------------------
EXTERN_C PVOID __imp_CsrFreeCaptureBuffer = CsrFreeCaptureBuffer;

CsrFreeCaptureBuffer:
00007FFAB20A4980  sub         rsp,28h 
00007FFAB20A4984  cmp         byte ptr [7FFAB21B43ECh],0 
00007FFAB20A498B  jne         CsrFreeCaptureBuffer+1Eh (7FFAB20A499Eh) 

--------------------------------------------------------------------------
after: TrHook(&__imp_CsrFreeCaptureBuffer, hook_CsrFreeCaptureBuffer);
--------------------------------------------------------------------------

CsrFreeCaptureBuffer:
00007FFAB20A4980  jmp         hook_CsrFreeCaptureBuffer 
00007FFAB20A498B  jne         CsrFreeCaptureBuffer+1Eh (7FFAB20A499Eh) 

trampoline:
00007FFA3225F878  sub         rsp,28h 
00007FFA3225F87C  cmp         byte ptr [7FFAB21B43ECh],0 
00007FFA3225F883  jmp         CsrFreeCaptureBuffer+0Bh (7FFAB20A498Bh) 

__imp_CsrFreeCaptureBuffer = trampoline;

////////////////////////////////////////////////////////////////////////////////////////////////////////
// case 7: - Jcc rel8 (2 bytes) extended  to Jcc rel32 (6 bytes) inside trampoline

-------------------------------------------------------------------------
before:
-------------------------------------------------------------------------
EXTERN_C PVOID __imp_CsrFreeCaptureBuffer = CsrAllocateMessagePointer;

CsrAllocateMessagePointer:
00007FFAB20A46A0  test        edx,edx 
00007FFAB20A46A2  je          CsrAllocateMessagePointer+2Eh (7FFAB20A46CEh) 
00007FFAB20A46A4  mov         rax,qword ptr [rcx+18h] 
00007FFAB20A46A8  mov         qword ptr [r8],rax 

--------------------------------------------------------------------------
after: TrHook(&__imp_CsrAllocateMessagePointer, hook_CsrAllocateMessagePointer);
--------------------------------------------------------------------------
CsrAllocateMessagePointer:
00007FFAB20A46A0  jmp         hook_CsrAllocateMessagePointer 
00007FFAB20A46A8  mov         qword ptr [r8],rax 

trampoline:
00007FFA3225FA38  test        edx,edx 
00007FFA3225FA3A  je          CsrAllocateMessagePointer+2Eh (7FFAB20A46CEh) 
00007FFA3225FA40  mov         rax,qword ptr [rcx+18h] 
00007FFA3225FA44  jmp         CsrAllocateMessagePointer+8 (7FFAB20A46A8h) 

__imp_CsrAllocateMessagePointer = trampoline;

////////////////////////////////////////////////////////////////////////////////////////////////////////
// case 8: function too small ( < 5 bytes )

-------------------------------------------------------------------------
before:
-------------------------------------------------------------------------
EXTERN_C PVOID __imp_CsrIdentifyAlertableThread = CsrIdentifyAlertableThread;

CsrIdentifyAlertableThread:
00007FFAB20BE480  xor         eax,eax 
00007FFAB20BE482  ret              
00007FFAB20BE483  int         3    
00007FFAB20BE484  int         3    
00007FFAB20BE485  int         3    

--------------------------------------------------------------------------
after: TrHook(&__imp_CsrIdentifyAlertableThread, hook_CsrIdentifyAlertableThread);
--------------------------------------------------------------------------
CsrIdentifyAlertableThread:
00007FFAB20BE480  jmp hook_CsrIdentifyAlertableThread

trampoline:
00007FFA3225F7F8  xor         eax,eax 
00007FFA3225F7FA  ret              

__imp_CsrIdentifyAlertableThread = trampoline;

note - no JMP at the end of trampoline !

////////////////////////////////////////////////////////////////////////////////////////////////////////
// case JMP_rel32: function begin with 5 bytes relative JMP

-------------------------------------------------------------------------
before:
-------------------------------------------------------------------------
EXTERN_C PVOID __imp_DbgQueryDebugFilterState = DbgQueryDebugFilterState;

DbgQueryDebugFilterState:
00007FFAB211B160  jmp         NtQueryDebugFilterState (7FFAB20D1720h) 

--------------------------------------------------------------------------
after: TrHook(&__imp_DbgQueryDebugFilterState, hook_DbgQueryDebugFilterState);
--------------------------------------------------------------------------

DbgQueryDebugFilterState:
00007FFAB211B160  jmp         hook_DbgQueryDebugFilterState(7FFAB20D1720h) 

__imp_DbgQueryDebugFilterState = NtQueryDebugFilterState;

no trampoline used here ! __imp_DbgQueryDebugFilterState redirected from DbgQueryDebugFilterState to NtQueryDebugFilterState

////////////////////////////////////////////////////////////////////////////////////////////////////////
// case 2: CALL/JMP/Jcc rel32 relocated
-------------------------------------------------------------------------
before:
-------------------------------------------------------------------------
EXTERN_C PVOID __imp_DbgQueryDebugFilterState = DbgUiConvertStateChangeStructure;

DbgUiConvertStateChangeStructure:
00007FFAB21080E0  xor         r8d,r8d 
00007FFAB21080E3  jmp         DbgUiConvertStateChangeStructureEx+10h (7FFAB2108100h) 

--------------------------------------------------------------------------
after: TrHook(&__imp_DbgUiConvertStateChangeStructure, hook_DbgUiConvertStateChangeStructure);
--------------------------------------------------------------------------

DbgUiConvertStateChangeStructure:
00007FFAB20A46A0  jmp         hook_DbgUiConvertStateChangeStructure 


trampoline:
00007FFA3225F4F8  xor         r8d,r8d 
00007FFA3225F4FB  jmp         DbgUiConvertStateChangeStructureEx+10h (7FFAB2108100h) 

__imp_DbgUiConvertStateChangeStructure = trampoline;

////////////////////////////////////////////////////////////////////////////////////////////////////////
for x86:

-------------------------------------------------------------------------
before:
-------------------------------------------------------------------------
EXTERN_C PVOID __imp_RtlGetActiveConsoleId = RtlGetActiveConsoleId;

RtlGetActiveConsoleId:
7721FDA0  call        RtlGetCurrentServiceSessionId (771FF310h) 
7721FDA5  test        eax,eax 

--------------------------------------------------------------------------
after: TrHook(&__imp_RtlGetActiveConsoleId, hook_RtlGetActiveConsoleId);
--------------------------------------------------------------------------

RtlGetActiveConsoleId:
7721FDA0  jmp         hook_RtlGetActiveConsoleId
7721FDA5  test        eax,eax 

trampoline:
02902A94  call        RtlGetCurrentServiceSessionId (771FF310h) 
02902A99  jmp         RtlGetActiveConsoleId+5 (7721FDA5h) 

__imp_RtlGetActiveConsoleId = trampoline;

////////////////////////////////////////////////////////////////////////////////////////////////////////
// case 9: Too few instructions !

RtlIsZeroMemory:
7FFB85F5C130   xor         eax,eax
7FFB85F5C132   jmp         00007FFB85F5C143 ↓
7FFB85F5C134   test        rdx,rdx
7FFB85F5C137   je          00007FFB85F5C157 ↓
7FFB85F5C139   cmp         byte ptr [rcx],al
7FFB85F5C13B   jne         00007FFB85F5C171 ↓
7FFB85F5C13D   inc         rcx
7FFB85F5C140   dec         rdx
7FFB85F5C143   test        cl,7
7FFB85F5C146   jne         00007FFB85F5C134 ↑
7FFB85F5C148   jmp         00007FFB85F5C157 ↓
7FFB85F5C14A   cmp         qword ptr [rcx],rax
7FFB85F5C14D   jne         00007FFB85F5C171 ↓
7FFB85F5C14F   add         rcx,8
7FFB85F5C153   sub         rdx,8
7FFB85F5C157   cmp         rdx,8
7FFB85F5C15B   jae         00007FFB85F5C14A ↑
7FFB85F5C15D   test        rdx,rdx
7FFB85F5C160   je          00007FFB85F5C16F ↓
7FFB85F5C162   cmp         byte ptr [rcx],al
7FFB85F5C164   jne         00007FFB85F5C171 ↓
7FFB85F5C166   inc         rcx
7FFB85F5C169   sub         rdx,1
7FFB85F5C16D   jne         00007FFB85F5C162 ↑
7FFB85F5C16F   mov         al,1
7FFB85F5C171   ret

we can not hook such api - only 4 bytes exist
note 
7FFB85F5C146   jne         00007FFB85F5C134 ↑
if we set JMP in [7FFB85F5C130, 7FFB85F5C135) - this will be jmp to instruction body

////////////////////////////////////////////////////////////////////////////////////////////////////////
// skip import jump

-------------------------------------------------------------------------
before:
-------------------------------------------------------------------------
EXTERN_C PVOID __imp_NtdllDefWindowProc_W = NtdllDefWindowProc_W;

NtdllDefWindowProc_W:
7FFAB20CEAD0   jmp         qword ptr [DefWindowProcW(7FFF55F9A760)]
 
DefWindowProcW
7FFF55F9A760  mov         rax,rsp 
7FFF55F9A763  mov         qword ptr [rax+8],rbx 
7FFF55F9A767  mov         qword ptr [rax+10h],rsi 

--------------------------------------------------------------------------
after: TrHook(&__imp_NtdllDefWindowProc_W, hook_NtdllDefWindowProc_W);
--------------------------------------------------------------------------

NtdllDefWindowProc_W:
7FFAB20CEAD0   jmp         qword ptr [DefWindowProcW(7FFF55F9A760)]

DefWindowProcW
7FFF55F9A760  jmp         hook_NtdllDefWindowProc_W
7FFF55F9A767  mov         qword ptr [rax+10h],rsi

trampoline:
7FFED78555F8  mov         rax,rsp 
7FFED78555FB  mov         qword ptr [rax+8],rbx 
7FFED78555FF  jmp         DefWindowProcW + 7 (7FFF55F9A767h) 

__imp_NtdllDefWindowProc_W = trampoline;

so we set hook on DefWindowProcW instead on NtdllDefWindowProc_W

////////////////////////////////////////////////////////////////////////////////////////////////////////
// case JMP_rel8: function begin with short JMP

-------------------------------------------------------------------------
before:
-------------------------------------------------------------------------
EXTERN_C PVOID __imp_uaw_wcschr = uaw_wcschr;

uaw_wcschr:
7FFF562C6A10  jmp         uaw_wcschr+0Bh (7FFF562C6A1B) 
7FFF562C6A12  test        ax,ax 
7FFF562C6A15  je          uaw_wcschr+18h (7FFF562C6A28) 
7FFF562C6A17  add         rcx,2 
7FFF562C6A1B  movzx       eax,word ptr [rcx] 
7FFF562C6A1E  cmp         ax,dx 
7FFF562C6A21  jne         uaw_wcschr+2 (7FFF562C6A12) 
7FFF562C6A23  mov         rax,rcx 
7FFF562C6A26  ret              
7FFF562C6A27  int         3    
7FFF562C6A28  xor         eax,eax 
7FFF562C6A2A  ret              

--------------------------------------------------------------------------
after: TrHook(&__imp_uaw_wcschr, hook_uaw_wcschr);
--------------------------------------------------------------------------

uaw_wcschr:
7FFF562C6A10  jmp         uaw_wcschr+0Bh (7FFF562C6A1B) 
7FFF562C6A12  test        ax,ax 
7FFF562C6A15  je          uaw_wcschr+18h (7FFF562C6A28) 
7FFF562C6A17  add         rcx,2 
7FFF562C6A1B  jmp         hook_uaw_wcschr
7FFF562C6A21  jne         uaw_wcschr+2 (7FFF562C6A12) 
7FFF562C6A23  mov         rax,rcx 
7FFF562C6A26  ret              
7FFF562C6A27  int         3    
7FFF562C6A28  xor         eax,eax 
7FFF562C6A2A  ret              

trampoline:
FFED786A338  movzx       eax,word ptr [rcx] 
FFED786A33B  cmp         ax,dx 
FFED786A33E  jmp         uaw_wcschr+11h (7FFF562C6A21) 

__imp_uaw_wcschr = trampoline;

usual all such functions ( with short JMP at begin) consist from do-while optimized loop
( uaw_wcschr, SHSearchMapInt, FixSlashesAndColonW)

problem here - that hook function can be recursive called in loop

example of uaw_wcschr hook:


PUWSTR
__cdecl
hook_uaw_wcschr(
		   _In_ PCUWSTR String,
		   _In_ WCHAR   Character
		   )
{
	DbgPrint("%p: %p> uaw_wcschr(\"%S\", '%c')...\n", _AddressOfReturnAddress(), _ReturnAddress(), String, Character);
	PUWSTR pw = uaw_wcschr(String, Character);
	DbgPrint("%p: %p> uaw_wcschr(\"%S\", '%c') = \"%S\"\n", _AddressOfReturnAddress(), _ReturnAddress(), String, Character, pw);
	return pw;
}

	TrInit();
	TrHook(&__imp_uaw_wcschr, hook_uaw_wcschr);
	uaw_wcschr(L"123*567", '*'); 

and debug output:

000000459910F978: 00007FF6E5FEFCAB> uaw_wcschr("23*567", '*')...
000000459910F928: 00007FF6E5FF086E> uaw_wcschr("3*567", '*')...
000000459910F8D8: 00007FF6E5FF086E> uaw_wcschr("*567", '*')...
000000459910F8D8: 00007FF6E5FF086E> uaw_wcschr("*567", '*') = "*567"
000000459910F928: 00007FF6E5FF086E> uaw_wcschr("3*567", '*') = "*567"
000000459910F978: 00007FF6E5FEFCAB> uaw_wcschr("23*567", '*') = "*567"

////////////////////////////////////////////////////////////////////////////////////////////////////////
// "micro" jmp

case when JMP/Jcc/LOOP/JRCX point to first 5 bytes offunction ( where JMP must be placed )
probably only hypothetical case, but for correct handle, require many extra code.

before:

someapi:
7FF64B5096CF  jrcxz       someapi+4 (7FF64B5096D3) 
7FF64B5096D1  jnp         someapi+6 (7FF64B5096D5) 
7FF64B5096D3  loop        someapi (7FF64B5096CF) 
7FF64B5096D5  ...  

after:

someapi:
7FF64B5096CF  jmp         NT::hook_someapi (7FF64B510F14h) 
7FF64B5096D5  ...              

trampoline:
7FF5CB53FFB8  jrcxz       7FF5CB53FFC0 
7FF5CB53FFBA  jnp         someapi+6 (7FF64B5096D5) 
7FF5CB53FFC0  loop        7FF5CB53FFB8 
7FF5CB53FFC2  jmp         someapi+6 (7FF64B5096D5) 

في بداية الـ API المُثبَّت عليه الخطاف (hooked api)، نضع إما قفزة مباشرة JMP إلى الخطاف إذا كان ذلك ممكنًا، أو قفزة JMP إلى قفزة غير مباشرة JMP [hook_someapi] داخل الترامبولين (إذا كانت المسافة أكثر من 2 جيجابايت بين someapi و hook_someapi)

لذا، بعد الخطاف سيكون إما``` someapi: jmp hook_someapi ; JMP rel32

root@kitploit:~
أو```
someapi:
	jmp tramp ; JMP rel32

tramp:
	jmp [hook_someapi] ; JMP [m64]

في نهاية الـtrampoline عادةً ستكون هناك قفزة JMP نسبية إلى الكود بعد JMP في جسم الدالة باستثناء الحالة 8 - عندما تكون الدالة المُعترضة صغيرة جدًا (تعليمة ret أو JMP موجودة بالفعل في الـtramoline)

تنزيل الأداة