1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
|
//////////////////////////////////////////////////////////////////////////////
//
// Detour Test Program (extend.cpp of extend.dll)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// An example dynamically detouring a function.
//
#include <stdio.h>
#include <windows.h>
#include "detours.h"
static LONG nExtends = 0;
static LONG nInterns = 0;
static DWORD (WINAPI * TrueTarget)(DWORD dwCount) = NULL;
static DWORD (WINAPI * TrueHidden)(DWORD dwCount) = NULL;
static int (WINAPI * TrueEntryPoint)(VOID) = NULL;
// Extend is a detour for Target.
static DWORD WINAPI Extend(DWORD dwCount)
{
InterlockedIncrement(&nExtends);
printf("extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: Extend (%ld) -> %ld.\n", dwCount, dwCount + 1000);
dwCount = TrueTarget(dwCount + 1000);
printf("extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: Extend (.....) -> %ld.\n", dwCount);
return dwCount;
}
// Intern is a detour for Hidden.
static DWORD WINAPI Intern(DWORD dwCount)
{
InterlockedIncrement(&nInterns);
printf("extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: Intern (%ld) -> %ld.\n", dwCount, dwCount + 10);
dwCount = TrueHidden(dwCount + 10);
printf("extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: Intern (.....) -> %ld.\n", dwCount);
return dwCount;
}
static int WINAPI ExtendEntryPoint()
{
// We couldn't call LoadLibrary in DllMain, so our functions here.
LONG error;
// We separate out the functions in the export table (Target)
// from the ones that require debug symbols (Hidden).
TrueTarget =
(DWORD (WINAPI *)(DWORD))
DetourFindFunction("target" DETOURS_STRINGIFY(DETOURS_BITS) ".dll", "Target");
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)TrueTarget, Extend);
error = DetourTransactionCommit();
if (error == NO_ERROR) {
printf("extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: Detoured Target().\n");
}
else {
printf("extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: Error detouring Target(): %ld\n", error);
}
// Now try to detour the functions requiring debug symbols.
TrueHidden =
(DWORD (WINAPI *)(DWORD))
DetourFindFunction("target" DETOURS_STRINGIFY(DETOURS_BITS) ".dll", "Hidden");
if (TrueHidden == NULL) {
error = GetLastError();
printf("extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: TrueHidden = %p (error = %ld)\n", TrueHidden, error);
}
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)TrueHidden, Intern);
error = DetourTransactionCommit();
if (error == NO_ERROR) {
printf("extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: Detoured Hidden().\n");
}
else {
printf("extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: Error detouring Hidden(): %ld\n", error);
}
// Now let the application start executing.
printf("extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: Calling EntryPoint\n");
fflush(stdout);
return TrueEntryPoint();
}
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
{
LONG error;
(void)hinst;
(void)reserved;
if (DetourIsHelperProcess()) {
return TRUE;
}
if (dwReason == DLL_PROCESS_ATTACH) {
DetourRestoreAfterWith();
printf("extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: Starting.\n");
fflush(stdout);
// NB: DllMain can't call LoadLibrary, so we hook the app entry point.
TrueEntryPoint = (int (WINAPI *)())DetourGetEntryPoint(NULL);
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)TrueEntryPoint, ExtendEntryPoint);
error = DetourTransactionCommit();
if (error == NO_ERROR) {
printf("extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: Detoured EntryPoint().\n");
}
else {
printf("extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: Error detouring EntryPoint(): %ld\n", error);
}
}
else if (dwReason == DLL_PROCESS_DETACH) {
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
// Detach functions found from the export table.
if (TrueTarget != NULL) {
DetourDetach(&(PVOID&)TrueTarget, (PVOID)Extend);
}
// Detach functions found from debug symbols.
if (TrueHidden != NULL) {
DetourDetach(&(PVOID&)TrueHidden, (PVOID)Intern);
}
// Detach the entry point.
DetourDetach(&(PVOID&)TrueEntryPoint, ExtendEntryPoint);
error = DetourTransactionCommit();
printf("extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: Removed Target() detours (%ld), %ld/%ld calls.\n",
error, nExtends, nInterns);
fflush(stdout);
}
return TRUE;
}
//
///////////////////////////////////////////////////////////////// End of File.
|