659 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			659 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			C++
		
	
	
	
| //////////////////////////////////////////////////////////////////////////////
 | |
| //
 | |
| //  Detours Test Program (dtest.cpp of dtest.exe)
 | |
| //
 | |
| //  Microsoft Research Detours Package
 | |
| //
 | |
| //  Copyright (c) Microsoft Corporation.  All rights reserved.
 | |
| //
 | |
| #include <stdio.h>
 | |
| #include <stdarg.h>
 | |
| #include <windows.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>
 | |
| #include "dtarge.h"
 | |
| 
 | |
| DWORD_PTR WINAPI LocalTarget1(DWORD_PTR v1);
 | |
| 
 | |
| ////////////////////////////////////////////////////// Multi-Argument Detours.
 | |
| //
 | |
| DWORD_PTR (WINAPI * Trampoline_LocalTarget1)(DWORD_PTR v1) = LocalTarget1;
 | |
| 
 | |
| DWORD_PTR (WINAPI * Trampoline_Target0)() = Target0;
 | |
| DWORD_PTR (WINAPI * Trampoline_Target1)(DWORD_PTR v1) = Target1;
 | |
| DWORD_PTR (WINAPI * Trampoline_Target2)(DWORD_PTR v1, DWORD_PTR v2) = Target2;
 | |
| DWORD_PTR (WINAPI * Trampoline_Target3)
 | |
|     (DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3) = Target3;
 | |
| DWORD_PTR (WINAPI * Trampoline_Target4)
 | |
|     (DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4) = Target4;
 | |
| DWORD_PTR (WINAPI * Trampoline_Target5)
 | |
|     (DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
 | |
|      DWORD_PTR v5) = Target5;
 | |
| DWORD_PTR (WINAPI * Trampoline_Target6)
 | |
|     (DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
 | |
|      DWORD_PTR v5, DWORD_PTR v6) = Target6;
 | |
| DWORD_PTR (WINAPI * Trampoline_Target7)
 | |
|     (DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
 | |
|      DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7) = Target7;
 | |
| DWORD_PTR (WINAPI * Trampoline_Target8)
 | |
|     (DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
 | |
|      DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8) = Target8;
 | |
| DWORD_PTR (WINAPI * Trampoline_Target9)
 | |
|     (DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
 | |
|      DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
 | |
|      DWORD_PTR v9) = Target9;
 | |
| DWORD_PTR (WINAPI * Trampoline_Target10)
 | |
|     (DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
 | |
|      DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
 | |
|      DWORD_PTR v9, DWORD_PTR v10) = Target10;
 | |
| DWORD_PTR (WINAPI * Trampoline_Target11)
 | |
|     (DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
 | |
|      DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
 | |
|      DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11) = Target11;
 | |
| DWORD_PTR (WINAPI * Trampoline_Target12)
 | |
|     (DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
 | |
|      DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
 | |
|      DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12) = Target12;
 | |
| DWORD_PTR (WINAPI * Trampoline_Target13)
 | |
|     (DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
 | |
|      DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
 | |
|      DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12,
 | |
|      DWORD_PTR v13) = Target13;
 | |
| DWORD_PTR (WINAPI * Trampoline_Target14)
 | |
|     (DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
 | |
|      DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
 | |
|      DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12,
 | |
|      DWORD_PTR v13, DWORD_PTR v14) = Target14;
 | |
| DWORD_PTR (WINAPI * Trampoline_Target15)
 | |
|     (DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
 | |
|      DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
 | |
|      DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12,
 | |
|      DWORD_PTR v13, DWORD_PTR v14, DWORD_PTR v15) = Target15;
 | |
| DWORD_PTR (WINAPI * Trampoline_Target16)
 | |
|     (DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
 | |
|      DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
 | |
|      DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12,
 | |
|      DWORD_PTR v13, DWORD_PTR v14, DWORD_PTR v15, DWORD_PTR v16) = Target16;
 | |
| DWORD_PTR (WINAPI * Trampoline_TargetV)(DWORD_PTR v1, ...) = TargetV;
 | |
| DWORD_PTR (WINAPI * Trampoline_TargetR)(DWORD_PTR v1, ...) = TargetR;
 | |
| 
 | |
| //////////////////////////////////////////////////////////////////////////////
 | |
| //
 | |
| VOID dprintf(const char * fmt, ...)
 | |
| {
 | |
|     CHAR szBuf[1024];
 | |
| 
 | |
|     va_list args;
 | |
|     va_start(args, fmt);
 | |
|     StringCchPrintfA(szBuf, sizeof(szBuf), fmt, args);
 | |
|     va_end(args);
 | |
| 
 | |
|     OutputDebugStringA(szBuf);
 | |
| }
 | |
| 
 | |
| //////////////////////////////////////////////////////////////////////////////
 | |
| //
 | |
| DWORD_PTR WINAPI LocalTarget1(DWORD_PTR v1)
 | |
| {
 | |
|     printf("  LocalTarget1 (%ld)\n", (DWORD)v1);
 | |
|     // dprintf("LocalTarget1\n");
 | |
|     // __debugbreak();
 | |
|     return 9000;
 | |
| }
 | |
| 
 | |
| //////////////////////////////////////////////////////////////////////////////
 | |
| //
 | |
| DWORD_PTR WINAPI MyLocalTarget1(DWORD_PTR v1)
 | |
| {
 | |
|     printf("  MyLocalTarget1 (%ld)\n",
 | |
|            (DWORD)v1);
 | |
|     // dprintf("LocalTarget1, Trampoline_LocalTarget1=%p\n", Trampoline_LocalTarget1);
 | |
|     return Trampoline_LocalTarget1(v1);
 | |
| }
 | |
| 
 | |
| DWORD_PTR WINAPI MyTarget0()
 | |
| {
 | |
|     printf("  MyTarget0 ()\n");
 | |
|     return Trampoline_Target0();
 | |
| }
 | |
| 
 | |
| DWORD_PTR WINAPI MyTarget1(DWORD_PTR v1)
 | |
| {
 | |
|     printf("  MyTarget1 (%ld)\n",
 | |
|            (DWORD)v1);
 | |
|     return Trampoline_Target1(v1);
 | |
| }
 | |
| 
 | |
| DWORD_PTR WINAPI MyTarget2(DWORD_PTR v1, DWORD_PTR v2)
 | |
| {
 | |
|     printf("  MyTarget2 (%ld,%ld)\n",
 | |
|            (DWORD)v1, (DWORD)v2);
 | |
|     return Trampoline_Target2(v1,v2);
 | |
| }
 | |
| 
 | |
| DWORD_PTR WINAPI MyTarget3(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3)
 | |
| {
 | |
|     printf("  MyTarget3 (%ld,%ld,%ld)\n",
 | |
|            (DWORD)v1, (DWORD)v2, (DWORD)v3);
 | |
|     return Trampoline_Target3(v1,v2,v3);
 | |
| }
 | |
| 
 | |
| DWORD_PTR WINAPI MyTarget4(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4)
 | |
| {
 | |
|     printf("  MyTarget4 (%ld,%ld,%ld,%ld)\n",
 | |
|            (DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4);
 | |
|     return Trampoline_Target4(v1,v2,v3,v4);
 | |
| }
 | |
| 
 | |
| DWORD_PTR WINAPI MyTarget5(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
 | |
|                            DWORD_PTR v5)
 | |
| {
 | |
|     printf("  MyTarget5 (%ld,%ld,%ld,%ld,%ld)\n",
 | |
|            (DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
 | |
|            (DWORD)v5);
 | |
|     return Trampoline_Target5(v1,v2,v3,v4,v5);
 | |
| }
 | |
| 
 | |
| DWORD_PTR WINAPI MyTarget6(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
 | |
|                            DWORD_PTR v5, DWORD_PTR v6)
 | |
| {
 | |
|     printf("  MyTarget6 (%ld,%ld,%ld,%ld,%ld,%ld)\n",
 | |
|            (DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
 | |
|            (DWORD)v5, (DWORD)v6);
 | |
|     return Trampoline_Target6(v1,v2,v3,v4,v5,v6);
 | |
| }
 | |
| 
 | |
| DWORD_PTR WINAPI MyTarget7(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
 | |
|                            DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7)
 | |
| {
 | |
|     printf("  MyTarget7 (%ld,%ld,%ld,%ld,%ld,%ld,%ld)\n",
 | |
|            (DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
 | |
|            (DWORD)v5, (DWORD)v6, (DWORD)v7);
 | |
|     return Trampoline_Target7(v1,v2,v3,v4,v5,v6,v7);
 | |
| }
 | |
| 
 | |
| DWORD_PTR WINAPI MyTarget8(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
 | |
|                            DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8)
 | |
| {
 | |
|     printf("  MyTarget8 (%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)\n",
 | |
|            (DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
 | |
|            (DWORD)v5, (DWORD)v6, (DWORD)v7, (DWORD)v8);
 | |
|     return Trampoline_Target8(v1,v2,v3,v4,v5,v6,v7,v8);
 | |
| }
 | |
| 
 | |
| DWORD_PTR WINAPI MyTarget9(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
 | |
|                          DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
 | |
|                          DWORD_PTR v9)
 | |
| {
 | |
|     printf("  MyTarget9 (%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)\n",
 | |
|            (DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
 | |
|            (DWORD)v5, (DWORD)v6, (DWORD)v7, (DWORD)v8,
 | |
|            (DWORD)v9);
 | |
|     return Trampoline_Target9(v1,v2,v3,v4,v5,v6,v7,v8,v9);
 | |
| }
 | |
| 
 | |
| DWORD_PTR WINAPI MyTarget10(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
 | |
|                             DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
 | |
|                             DWORD_PTR v9, DWORD_PTR v10)
 | |
| {
 | |
|     printf("  MyTarget10(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)\n",
 | |
|            (DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
 | |
|            (DWORD)v5, (DWORD)v6, (DWORD)v7, (DWORD)v8,
 | |
|            (DWORD)v9, (DWORD)v10);
 | |
|     return Trampoline_Target10(v1,v2,v3,v4,v5,v6,v7,v8,v9,v10);
 | |
| }
 | |
| 
 | |
| DWORD_PTR WINAPI MyTarget11(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
 | |
|                             DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
 | |
|                             DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11)
 | |
| {
 | |
|     printf("  MyTarget11(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)\n",
 | |
|            (DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
 | |
|            (DWORD)v5, (DWORD)v6, (DWORD)v7, (DWORD)v8,
 | |
|            (DWORD)v9, (DWORD)v10, (DWORD)v11);
 | |
|     return Trampoline_Target11(v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,v11);
 | |
| }
 | |
| 
 | |
| DWORD_PTR WINAPI MyTarget12(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
 | |
|                             DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
 | |
|                             DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12)
 | |
| {
 | |
|     printf("  MyTarget12(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)\n",
 | |
|            (DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
 | |
|            (DWORD)v5, (DWORD)v6, (DWORD)v7, (DWORD)v8,
 | |
|            (DWORD)v9, (DWORD)v10, (DWORD)v11, (DWORD)v12);
 | |
|     return Trampoline_Target12(v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,v11,v12);
 | |
| }
 | |
| 
 | |
| DWORD_PTR WINAPI MyTarget13(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
 | |
|                             DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
 | |
|                             DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12,
 | |
|                             DWORD_PTR v13)
 | |
| {
 | |
|     printf("  MyTarget13(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)\n",
 | |
|            (DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
 | |
|            (DWORD)v5, (DWORD)v6, (DWORD)v7, (DWORD)v8,
 | |
|            (DWORD)v9, (DWORD)v10, (DWORD)v11, (DWORD)v12,
 | |
|            (DWORD)v13);
 | |
|     return Trampoline_Target13(v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,v11,v12,v13);
 | |
| }
 | |
| 
 | |
| DWORD_PTR WINAPI MyTarget14(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
 | |
|                             DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
 | |
|                             DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12,
 | |
|                             DWORD_PTR v13, DWORD_PTR v14)
 | |
| {
 | |
|     printf("  MyTarget14(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)\n",
 | |
|            (DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
 | |
|            (DWORD)v5, (DWORD)v6, (DWORD)v7, (DWORD)v8,
 | |
|            (DWORD)v9, (DWORD)v10, (DWORD)v11, (DWORD)v12,
 | |
|            (DWORD)v13, (DWORD)v14);
 | |
|     return Trampoline_Target14(v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,v11,v12,v13,v14);
 | |
| }
 | |
| 
 | |
| DWORD_PTR WINAPI MyTarget15(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
 | |
|                             DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
 | |
|                             DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12,
 | |
|                             DWORD_PTR v13, DWORD_PTR v14, DWORD_PTR v15)
 | |
| {
 | |
|     printf("  MyTarget15(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)\n",
 | |
|            (DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
 | |
|            (DWORD)v5, (DWORD)v6, (DWORD)v7, (DWORD)v8,
 | |
|            (DWORD)v9, (DWORD)v10, (DWORD)v11, (DWORD)v12,
 | |
|            (DWORD)v13, (DWORD)v14, (DWORD)v15);
 | |
|     return Trampoline_Target15(v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,v11,v12,v13,v14,v15);
 | |
| }
 | |
| 
 | |
| DWORD_PTR WINAPI MyTarget16(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
 | |
|                             DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
 | |
|                             DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12,
 | |
|                             DWORD_PTR v13, DWORD_PTR v14, DWORD_PTR v15, DWORD_PTR v16)
 | |
| {
 | |
|     printf("  MyTarget16(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)\n",
 | |
|            (DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
 | |
|            (DWORD)v5, (DWORD)v6, (DWORD)v7, (DWORD)v8,
 | |
|            (DWORD)v9, (DWORD)v10, (DWORD)v11, (DWORD)v12,
 | |
|            (DWORD)v13, (DWORD)v14, (DWORD)v15, (DWORD)v16);
 | |
|     return Trampoline_Target16(v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,v11,v12,v13,v14,v15,v16);
 | |
| }
 | |
| 
 | |
| DWORD_PTR WINAPI MyTargetV(DWORD_PTR v1, ...)
 | |
| {
 | |
|     DWORD_PTR args[32];
 | |
| 
 | |
|     va_list va;
 | |
|     va_start(va, v1);
 | |
| 
 | |
|     int argc = 0;
 | |
|     for (args[argc++] = v1; args[argc-1] != 0;) {
 | |
|         args[argc++] = va_arg(va, DWORD_PTR);
 | |
|     }
 | |
|     va_end(va);
 | |
| 
 | |
|     printf("  MyTargetV (");
 | |
|     int i = argc - 1;
 | |
|     for (; i > 0; i--) {
 | |
|         printf("%ld,", (DWORD)args[i]);
 | |
|     }
 | |
|     printf("%ld)\n", (DWORD)args[0]);
 | |
| 
 | |
|     switch (argc) {
 | |
|       default:
 | |
|         return Trampoline_TargetV(0);
 | |
|       case 1:
 | |
|         return Trampoline_TargetV(args[0]);
 | |
|       case 2:
 | |
|         return Trampoline_TargetV(args[0], args[1]);
 | |
|       case 3:
 | |
|         return Trampoline_TargetV(args[0], args[1], args[2]);
 | |
|       case 4:
 | |
|         return Trampoline_TargetV(args[0], args[1], args[2], args[3]);
 | |
|       case 5:
 | |
|         return Trampoline_TargetV(args[0], args[1], args[2], args[3],
 | |
|                                   args[4]);
 | |
|       case 6:
 | |
|         return Trampoline_TargetV(args[0], args[1], args[2], args[3],
 | |
|                                   args[4], args[5]);
 | |
|       case 7:
 | |
|         return Trampoline_TargetV(args[0], args[1], args[2], args[3],
 | |
|                                   args[4], args[5], args[6]);
 | |
|       case 8:
 | |
|         return Trampoline_TargetV(args[0], args[1], args[2], args[3],
 | |
|                                   args[4], args[5], args[6], args[7]);
 | |
|       case 9:
 | |
|         return Trampoline_TargetV(args[0], args[1], args[2], args[3],
 | |
|                                   args[4], args[5], args[6], args[7],
 | |
|                                   args[8]);
 | |
|       case 10:
 | |
|         return Trampoline_TargetV(args[0], args[1], args[2], args[3],
 | |
|                                   args[4], args[5], args[6], args[7],
 | |
|                                   args[8], args[9]);
 | |
|       case 11:
 | |
|         return Trampoline_TargetV(args[0], args[1], args[2], args[3],
 | |
|                                   args[4], args[5], args[6], args[7],
 | |
|                                   args[8], args[9], args[10]);
 | |
|       case 12:
 | |
|         return Trampoline_TargetV(args[0], args[1], args[2], args[3],
 | |
|                                   args[4], args[5], args[6], args[7],
 | |
|                                   args[8], args[9], args[10], args[11]);
 | |
|       case 13:
 | |
|         return Trampoline_TargetV(args[0], args[1], args[2], args[3],
 | |
|                                   args[4], args[5], args[6], args[7],
 | |
|                                   args[8], args[9], args[10], args[11],
 | |
|                                   args[12]);
 | |
|       case 14:
 | |
|         return Trampoline_TargetV(args[0], args[1], args[2], args[3],
 | |
|                                   args[4], args[5], args[6], args[7],
 | |
|                                   args[8], args[9], args[10], args[11],
 | |
|                                   args[12], args[13]);
 | |
|       case 15:
 | |
|         return Trampoline_TargetV(args[0], args[1], args[2], args[3],
 | |
|                                   args[4], args[5], args[6], args[7],
 | |
|                                   args[8], args[9], args[10], args[11],
 | |
|                                   args[12], args[13], args[14]);
 | |
|       case 16:
 | |
|         return Trampoline_TargetV(args[0], args[1], args[2], args[3],
 | |
|                                   args[4], args[5], args[6], args[7],
 | |
|                                   args[8], args[9], args[10], args[11],
 | |
|                                   args[12], args[13], args[14], args[15]);
 | |
|       case 17:
 | |
|         return Trampoline_TargetV(args[0], args[1], args[2], args[3],
 | |
|                                   args[4], args[5], args[6], args[7],
 | |
|                                   args[8], args[9], args[10], args[11],
 | |
|                                   args[12], args[13], args[14], args[15],
 | |
|                                   args[16]);
 | |
|     }
 | |
| }
 | |
| 
 | |
| DWORD_PTR WINAPI MyTargetR(DWORD_PTR v1, ...)
 | |
| {
 | |
|     DWORD_PTR args[32];
 | |
| 
 | |
|     va_list va;
 | |
|     va_start(va, v1);
 | |
| 
 | |
|     int argc = 0;
 | |
|     for (args[argc++] = v1; args[argc-1] != 0;) {
 | |
|         args[argc++] = va_arg(va, DWORD_PTR);
 | |
|     }
 | |
|     va_end(va);
 | |
| 
 | |
|     if (v1 < 5) {
 | |
|         printf("  MyTargetR (");
 | |
|         int i = argc - 1;
 | |
|         for (; i > 0; i--) {
 | |
|             printf("%ld,", (DWORD)args[i]);
 | |
|         }
 | |
|         printf("%ld)\n", (DWORD)args[0]);
 | |
|     }
 | |
|     else {
 | |
|         printf(".");
 | |
|     }
 | |
| 
 | |
|     switch (argc) {
 | |
|       default:
 | |
|         return Trampoline_TargetR(0);
 | |
|       case 1:
 | |
|         return Trampoline_TargetR(args[0]);
 | |
|       case 2:
 | |
|         return Trampoline_TargetR(args[0], args[1]);
 | |
|       case 3:
 | |
|         return Trampoline_TargetR(args[0], args[1], args[2]);
 | |
|       case 4:
 | |
|         return Trampoline_TargetR(args[0], args[1], args[2], args[3]);
 | |
|       case 5:
 | |
|         return Trampoline_TargetR(args[0], args[1], args[2], args[3],
 | |
|                                   args[4]);
 | |
|       case 6:
 | |
|         return Trampoline_TargetR(args[0], args[1], args[2], args[3],
 | |
|                                   args[4], args[5]);
 | |
|       case 7:
 | |
|         return Trampoline_TargetR(args[0], args[1], args[2], args[3],
 | |
|                                   args[4], args[5], args[6]);
 | |
|       case 8:
 | |
|         return Trampoline_TargetR(args[0], args[1], args[2], args[3],
 | |
|                                   args[4], args[5], args[6], args[7]);
 | |
|       case 9:
 | |
|         return Trampoline_TargetR(args[0], args[1], args[2], args[3],
 | |
|                                   args[4], args[5], args[6], args[7],
 | |
|                                   args[8]);
 | |
|       case 10:
 | |
|         return Trampoline_TargetR(args[0], args[1], args[2], args[3],
 | |
|                                   args[4], args[5], args[6], args[7],
 | |
|                                   args[8], args[9]);
 | |
|       case 11:
 | |
|         return Trampoline_TargetR(args[0], args[1], args[2], args[3],
 | |
|                                   args[4], args[5], args[6], args[7],
 | |
|                                   args[8], args[9], args[10]);
 | |
|       case 12:
 | |
|         return Trampoline_TargetR(args[0], args[1], args[2], args[3],
 | |
|                                   args[4], args[5], args[6], args[7],
 | |
|                                   args[8], args[9], args[10], args[11]);
 | |
|       case 13:
 | |
|         return Trampoline_TargetR(args[0], args[1], args[2], args[3],
 | |
|                                   args[4], args[5], args[6], args[7],
 | |
|                                   args[8], args[9], args[10], args[11],
 | |
|                                   args[12]);
 | |
|       case 14:
 | |
|         return Trampoline_TargetR(args[0], args[1], args[2], args[3],
 | |
|                                   args[4], args[5], args[6], args[7],
 | |
|                                   args[8], args[9], args[10], args[11],
 | |
|                                   args[12], args[13]);
 | |
|       case 15:
 | |
|         return Trampoline_TargetR(args[0], args[1], args[2], args[3],
 | |
|                                   args[4], args[5], args[6], args[7],
 | |
|                                   args[8], args[9], args[10], args[11],
 | |
|                                   args[12], args[13], args[14]);
 | |
|       case 16:
 | |
|         return Trampoline_TargetR(args[0], args[1], args[2], args[3],
 | |
|                                   args[4], args[5], args[6], args[7],
 | |
|                                   args[8], args[9], args[10], args[11],
 | |
|                                   args[12], args[13], args[14], args[15]);
 | |
|       case 17:
 | |
|         return Trampoline_TargetR(args[0], args[1], args[2], args[3],
 | |
|                                   args[4], args[5], args[6], args[7],
 | |
|                                   args[8], args[9], args[10], args[11],
 | |
|                                   args[12], args[13], args[14], args[15],
 | |
|                                   args[16]);
 | |
|     }
 | |
| }
 | |
| 
 | |
| /////////////////////////////////////////////////////////// Recursive Detours.
 | |
| //
 | |
| DWORD_PTR (WINAPI * Trampoline_Target0_1)() = NULL;
 | |
| DWORD_PTR (WINAPI * Trampoline_Target0_2)() = NULL;
 | |
| DWORD_PTR (WINAPI * Trampoline_Target0_3)() = NULL;
 | |
| 
 | |
| static DWORD_PTR WINAPI MyTarget0_1()
 | |
| {
 | |
|     printf("  Starting Target0_1.\n");
 | |
|     DWORD_PTR rv = Trampoline_Target0_1();
 | |
|     printf("  End Target0_1.\n");
 | |
|     return rv;
 | |
| }
 | |
| 
 | |
| static DWORD_PTR WINAPI MyTarget0_2()
 | |
| {
 | |
|     printf("  Starting Target0_2.\n");
 | |
|     DWORD_PTR rv = Trampoline_Target0_2();
 | |
|     printf("  End Target0_2.\n");
 | |
|     return rv;
 | |
| }
 | |
| 
 | |
| static DWORD_PTR WINAPI MyTarget0_3()
 | |
| {
 | |
|     printf("  Starting Target0_3.\n");
 | |
|     DWORD_PTR rv = Trampoline_Target0_3();
 | |
|     printf("  End Target0_3.\n");
 | |
|     return rv;
 | |
| }
 | |
| 
 | |
| //////////////////////////////////////////////////////////////////////////////
 | |
| //
 | |
| int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hprev, LPSTR lpszCmdLine, int nCmdShow)
 | |
| {
 | |
|     (void)hinst;
 | |
|     (void)hprev;
 | |
|     (void)lpszCmdLine;
 | |
|     (void)nCmdShow;
 | |
| 
 | |
|     printf("Calling LocalTarget1 w/o detour\n");
 | |
|     LocalTarget1(1);
 | |
| 
 | |
|     DetourTransactionBegin();
 | |
|     DetourUpdateThread(GetCurrentThread());
 | |
|     DetourAttach(&(PVOID&)Trampoline_LocalTarget1, MyLocalTarget1);
 | |
|     DetourTransactionCommit();
 | |
| 
 | |
|     printf("Calling LocalTarget1 w/ detour\n");
 | |
|     LocalTarget1(2);
 | |
| 
 | |
|     DetourTransactionBegin();
 | |
|     DetourUpdateThread(GetCurrentThread());
 | |
|     DetourAttach(&(PVOID&)Trampoline_Target0, MyTarget0);
 | |
|     DetourTransactionCommit();
 | |
| 
 | |
|     printf("Calling Target0 function.\n");
 | |
|     //dprintf("- Trampoline_Target0:: %p\n", Trampoline_Target0);
 | |
|     //dprintf("- Target0           :: %p\n", Target0);
 | |
|     Target0();
 | |
| 
 | |
|     DetourTransactionBegin();
 | |
|     DetourUpdateThread(GetCurrentThread());
 | |
|     DetourAttach(&(PVOID&)Trampoline_Target1, MyTarget1);
 | |
|     DetourAttach(&(PVOID&)Trampoline_Target2, MyTarget2);
 | |
|     DetourAttach(&(PVOID&)Trampoline_Target3, MyTarget3);
 | |
|     DetourAttach(&(PVOID&)Trampoline_Target4, MyTarget4);
 | |
|     DetourAttach(&(PVOID&)Trampoline_Target5, MyTarget5);
 | |
|     DetourAttach(&(PVOID&)Trampoline_Target6, MyTarget6);
 | |
|     DetourAttach(&(PVOID&)Trampoline_Target7, MyTarget7);
 | |
|     DetourAttach(&(PVOID&)Trampoline_Target8, MyTarget8);
 | |
|     DetourAttach(&(PVOID&)Trampoline_Target9, MyTarget9);
 | |
|     DetourAttach(&(PVOID&)Trampoline_Target10, MyTarget10);
 | |
|     DetourAttach(&(PVOID&)Trampoline_Target11, MyTarget11);
 | |
|     DetourAttach(&(PVOID&)Trampoline_Target12, MyTarget12);
 | |
|     DetourAttach(&(PVOID&)Trampoline_Target13, MyTarget13);
 | |
|     DetourAttach(&(PVOID&)Trampoline_Target14, MyTarget14);
 | |
|     DetourAttach(&(PVOID&)Trampoline_Target15, MyTarget15);
 | |
|     DetourAttach(&(PVOID&)Trampoline_Target16, MyTarget16);
 | |
|     DetourAttach(&(PVOID&)Trampoline_TargetV, MyTargetV);
 | |
|     DetourAttach(&(PVOID&)Trampoline_TargetR, MyTargetR);
 | |
|     DetourTransactionCommit();
 | |
| 
 | |
|     printf("Calling TargetN functions.\n");
 | |
|     LocalTarget1(1);
 | |
|     Target0();
 | |
|     Target1(1);
 | |
|     Target2(1,2);
 | |
|     Target3(1,2,3);
 | |
|     Target4(1,2,3,4);
 | |
|     Target5(1,2,3,4,5);
 | |
|     Target6(1,2,3,4,5,6);
 | |
|     Target7(1,2,3,4,5,6,7);
 | |
|     Target8(1,2,3,4,5,6,7,8);
 | |
|     Target9(1,2,3,4,5,6,7,8,9);
 | |
|     Target10(1,2,3,4,5,6,7,8,9,10);
 | |
|     Target11(1,2,3,4,5,6,7,8,9,10,11);
 | |
|     Target12(1,2,3,4,5,6,7,8,9,10,11,12);
 | |
|     Target13(1,2,3,4,5,6,7,8,9,10,11,12,13);
 | |
|     Target14(1,2,3,4,5,6,7,8,9,10,11,12,13,14);
 | |
|     Target15(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15);
 | |
|     Target16(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16);
 | |
|     TargetV(0);
 | |
|     TargetV(1,0);
 | |
|     TargetV(2,1,0);
 | |
|     TargetV(3,2,1,0);
 | |
|     TargetV(4,3,2,1,0);
 | |
|     TargetV(5,4,3,2,1,0);
 | |
|     TargetV(6,5,4,3,2,1,0);
 | |
|     TargetV(7,6,5,4,3,2,1,0);
 | |
|     TargetV(8,7,6,5,4,3,2,1,0);
 | |
|     TargetV(9,8,7,6,5,4,3,2,1,0);
 | |
|     TargetV(10,9,8,7,6,5,4,3,2,1,0);
 | |
|     TargetV(11,10,9,8,7,6,5,4,3,2,1,0);
 | |
|     TargetV(12,11,10,9,8,7,6,5,4,3,2,1,0);
 | |
|     TargetV(13,12,11,10,9,8,7,6,5,4,3,2,1,0);
 | |
|     TargetV(14,13,12,11,10,9,8,7,6,5,4,3,2,1,0);
 | |
|     TargetV(15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0);
 | |
|     TargetV(16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0);
 | |
|     TargetR(4,3,2,1,0);
 | |
|     DWORD_PTR rv = TargetR(100,10,9,8,7,6,5,4,3,2,1,0);
 | |
|     printf(" => %ld\n", (DWORD)rv);
 | |
| 
 | |
|     Trampoline_Target0_1 = Target0;
 | |
|     Trampoline_Target0_2 = Target0;
 | |
|     Trampoline_Target0_3 = Target0;
 | |
| 
 | |
|     //dprintf("Trampoline_Target0_1 = %p\n", DetourCodeFromPointer(Trampoline_Target0_1, NULL));
 | |
|     //__debugbreak();
 | |
| 
 | |
|     printf("Calling Target0 again with 1 detour.\n");
 | |
|     Target0();
 | |
| 
 | |
|     DetourTransactionBegin();
 | |
|     DetourUpdateThread(GetCurrentThread());
 | |
|     DetourAttach(&(PVOID&)Trampoline_Target0_1, MyTarget0_1);
 | |
|     DetourTransactionCommit();
 | |
| 
 | |
|     //dprintf("Trampoline_Target0_2 = %p\n", DetourCodeFromPointer(Trampoline_Target0_2, NULL));
 | |
|     //__debugbreak();
 | |
|     printf("Calling Target0 again with 2 detours.\n");
 | |
|     Target0();
 | |
| 
 | |
|     DetourTransactionBegin();
 | |
|     DetourUpdateThread(GetCurrentThread());
 | |
|     DetourAttach(&(PVOID&)Trampoline_Target0_2, MyTarget0_2);
 | |
|     DetourTransactionCommit();
 | |
| 
 | |
|     //dprintf("Trampoline_Target0_3 = %p\n", DetourCodeFromPointer(Trampoline_Target0_3, NULL));
 | |
|     //__debugbreak();
 | |
|     printf("Calling Target0 again with 3 detours.\n");
 | |
|     Target0();
 | |
| 
 | |
| 
 | |
|     DetourTransactionBegin();
 | |
|     DetourUpdateThread(GetCurrentThread());
 | |
|     DetourAttach(&(PVOID&)Trampoline_Target0_3, MyTarget0_3);
 | |
|     DetourTransactionCommit();
 | |
| 
 | |
|     //dprintf("Trampoline_Target0_3 = %p\n", DetourCodeFromPointer(Trampoline_Target0_3, NULL));
 | |
|     //__debugbreak();
 | |
|     printf("Calling Target0 again with 4 detours.\n");
 | |
|     Target0();
 | |
| 
 | |
|     DetourTransactionBegin();
 | |
|     DetourUpdateThread(GetCurrentThread());
 | |
|     DetourDetach(&(PVOID&)Trampoline_Target0, MyTarget0);
 | |
|     DetourDetach(&(PVOID&)Trampoline_Target1, MyTarget1);
 | |
|     DetourDetach(&(PVOID&)Trampoline_Target2, MyTarget2);
 | |
|     DetourDetach(&(PVOID&)Trampoline_Target3, MyTarget3);
 | |
|     DetourDetach(&(PVOID&)Trampoline_Target4, MyTarget4);
 | |
|     DetourDetach(&(PVOID&)Trampoline_Target5, MyTarget5);
 | |
|     DetourDetach(&(PVOID&)Trampoline_Target6, MyTarget6);
 | |
|     DetourDetach(&(PVOID&)Trampoline_Target7, MyTarget7);
 | |
|     DetourDetach(&(PVOID&)Trampoline_Target8, MyTarget8);
 | |
|     DetourDetach(&(PVOID&)Trampoline_Target9, MyTarget9);
 | |
|     DetourDetach(&(PVOID&)Trampoline_Target10, MyTarget10);
 | |
|     DetourDetach(&(PVOID&)Trampoline_Target11, MyTarget11);
 | |
|     DetourDetach(&(PVOID&)Trampoline_Target12, MyTarget12);
 | |
|     DetourDetach(&(PVOID&)Trampoline_Target13, MyTarget13);
 | |
|     DetourDetach(&(PVOID&)Trampoline_Target14, MyTarget14);
 | |
|     DetourDetach(&(PVOID&)Trampoline_Target15, MyTarget15);
 | |
|     DetourDetach(&(PVOID&)Trampoline_Target16, MyTarget16);
 | |
|     DetourDetach(&(PVOID&)Trampoline_TargetV, MyTargetV);
 | |
|     DetourDetach(&(PVOID&)Trampoline_TargetR, MyTargetR);
 | |
|     DetourTransactionCommit();
 | |
| 
 | |
|     printf("Done.\n");
 | |
| 
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| //
 | |
| ///////////////////////////////////////////////////////////////// End of File.
 |