@wzwjustdoit/dsh-plugin-git-bash 0.0.0-stage → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +154 -2
  3. package/client.js +736 -0
  4. package/cordis.patch.yml +27 -0
  5. package/lib/agents.d.ts +5 -0
  6. package/lib/agents.d.ts.map +1 -0
  7. package/lib/agents.js +56 -0
  8. package/lib/agents.js.map +1 -0
  9. package/lib/discovery.d.ts +21 -0
  10. package/lib/discovery.d.ts.map +1 -0
  11. package/lib/discovery.js +122 -0
  12. package/lib/discovery.js.map +1 -0
  13. package/lib/index.d.ts +55 -0
  14. package/lib/index.d.ts.map +1 -0
  15. package/lib/index.js +369 -0
  16. package/lib/index.js.map +1 -0
  17. package/native/CMakeLists.txt +58 -0
  18. package/native/bin/win32-x64/msys-token-guard-hook.dll +0 -0
  19. package/native/bin/win32-x64/msys-token-guard.exe +0 -0
  20. package/native/msys-token-guard-hook.cpp +470 -0
  21. package/native/msys-token-guard.cpp +671 -0
  22. package/native/vendor/detours/LICENSE.md +23 -0
  23. package/native/vendor/detours/README.dsh.md +13 -0
  24. package/native/vendor/detours/creatwth.cpp +1577 -0
  25. package/native/vendor/detours/detours.cpp +2364 -0
  26. package/native/vendor/detours/detours.h +1059 -0
  27. package/native/vendor/detours/detver.h +27 -0
  28. package/native/vendor/detours/disasm.cpp +4236 -0
  29. package/native/vendor/detours/image.cpp +2251 -0
  30. package/native/vendor/detours/modules.cpp +929 -0
  31. package/native/vendor/detours/uimports.cpp +269 -0
  32. package/package.json +120 -4
  33. package/scripts/build-native.mjs +35 -0
  34. package/scripts/dsh.desktop.startup/README.md +27 -0
  35. package/scripts/dsh.desktop.startup/dsh.desktop.startup.gitbash.bat +28 -0
  36. package/scripts/dsh.desktop.startup/dsh.desktop.startup.gitbash.sh +46 -0
  37. package/scripts/dsh.desktop.startup/dsh.desktop.startup.gitbash.vbs +0 -0
  38. package/scripts/dsh.web.startup/README.md +33 -0
  39. package/scripts/dsh.web.startup/dsh.web.startup.gitbash.bat +28 -0
  40. package/scripts/dsh.web.startup/dsh.web.startup.gitbash.sh +48 -0
  41. package/scripts/dsh.web.startup/dsh.web.startup.gitbash.vbs +0 -0
@@ -0,0 +1,1577 @@
1
+ //////////////////////////////////////////////////////////////////////////////
2
+ //
3
+ // Create a process with a DLL (creatwth.cpp of detours.lib)
4
+ //
5
+ // Microsoft Research Detours Package, Version 4.0.1
6
+ //
7
+ // Copyright (c) Microsoft Corporation. All rights reserved.
8
+ //
9
+
10
+ #if _MSC_VER >= 1900
11
+ #pragma warning(push)
12
+ #pragma warning(disable:4091) // empty typedef
13
+ #endif
14
+ #define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS 1
15
+ #define _ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE 1
16
+ #include <windows.h>
17
+ #include <stddef.h>
18
+ #pragma warning(push)
19
+ #if _MSC_VER > 1400
20
+ #pragma warning(disable:6102 6103) // /analyze warnings
21
+ #endif
22
+ #include <strsafe.h>
23
+ #pragma warning(pop)
24
+
25
+ // #define DETOUR_DEBUG 1
26
+ #define DETOURS_INTERNAL
27
+
28
+ #include "detours.h"
29
+
30
+ #if DETOURS_VERSION != 0x4c0c1 // 0xMAJORcMINORcPATCH
31
+ #error detours.h version mismatch
32
+ #endif
33
+
34
+ #if _MSC_VER >= 1900
35
+ #pragma warning(pop)
36
+ #endif
37
+
38
+ #define IMPORT_DIRECTORY OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]
39
+ #define BOUND_DIRECTORY OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT]
40
+ #define CLR_DIRECTORY OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR]
41
+ #define IAT_DIRECTORY OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT]
42
+
43
+ //////////////////////////////////////////////////////////////////////////////
44
+ //
45
+ const GUID DETOUR_EXE_HELPER_GUID = { /* ea0251b9-5cde-41b5-98d0-2af4a26b0fee */
46
+ 0xea0251b9, 0x5cde, 0x41b5,
47
+ { 0x98, 0xd0, 0x2a, 0xf4, 0xa2, 0x6b, 0x0f, 0xee }};
48
+
49
+ //////////////////////////////////////////////////////////////////////////////
50
+ //
51
+ // Enumate through modules in the target process.
52
+ //
53
+ static BOOL WINAPI LoadNtHeaderFromProcess(HANDLE hProcess,
54
+ HMODULE hModule,
55
+ PIMAGE_NT_HEADERS32 pNtHeader)
56
+ {
57
+ PBYTE pbModule = (PBYTE)hModule;
58
+
59
+ if (pbModule == NULL) {
60
+ SetLastError(ERROR_INVALID_PARAMETER);
61
+ return FALSE;
62
+ }
63
+
64
+ MEMORY_BASIC_INFORMATION mbi;
65
+ ZeroMemory(&mbi, sizeof(mbi));
66
+
67
+ if (VirtualQueryEx(hProcess, hModule, &mbi, sizeof(mbi)) == 0) {
68
+ return FALSE;
69
+ }
70
+
71
+ IMAGE_DOS_HEADER idh;
72
+
73
+ if (!ReadProcessMemory(hProcess, pbModule, &idh, sizeof(idh), NULL)) {
74
+ DETOUR_TRACE(("ReadProcessMemory(idh@%p..%p) failed: %d\n",
75
+ pbModule, pbModule + sizeof(idh), GetLastError()));
76
+ return FALSE;
77
+ }
78
+
79
+ if (idh.e_magic != IMAGE_DOS_SIGNATURE ||
80
+ (DWORD)idh.e_lfanew > mbi.RegionSize ||
81
+ (DWORD)idh.e_lfanew < sizeof(idh)) {
82
+
83
+ SetLastError(ERROR_BAD_EXE_FORMAT);
84
+ return FALSE;
85
+ }
86
+
87
+ if (!ReadProcessMemory(hProcess, pbModule + idh.e_lfanew,
88
+ pNtHeader, sizeof(*pNtHeader), NULL)) {
89
+ DETOUR_TRACE(("ReadProcessMemory(inh@%p..%p:%p) failed: %d\n",
90
+ pbModule + idh.e_lfanew,
91
+ pbModule + idh.e_lfanew + sizeof(*pNtHeader),
92
+ pbModule,
93
+ GetLastError()));
94
+ return FALSE;
95
+ }
96
+
97
+ if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) {
98
+ SetLastError(ERROR_BAD_EXE_FORMAT);
99
+ return FALSE;
100
+ }
101
+
102
+ return TRUE;
103
+ }
104
+
105
+ static HMODULE WINAPI EnumerateModulesInProcess(HANDLE hProcess,
106
+ HMODULE hModuleLast,
107
+ PIMAGE_NT_HEADERS32 pNtHeader)
108
+ {
109
+ PBYTE pbLast = (PBYTE)hModuleLast + MM_ALLOCATION_GRANULARITY;
110
+
111
+ MEMORY_BASIC_INFORMATION mbi;
112
+ ZeroMemory(&mbi, sizeof(mbi));
113
+
114
+ // Find the next memory region that contains a mapped PE image.
115
+ //
116
+
117
+ for (;; pbLast = (PBYTE)mbi.BaseAddress + mbi.RegionSize) {
118
+ if (VirtualQueryEx(hProcess, (PVOID)pbLast, &mbi, sizeof(mbi)) == 0) {
119
+ break;
120
+ }
121
+
122
+ // Usermode address space has such an unaligned region size always at the
123
+ // end and only at the end.
124
+ //
125
+ if ((mbi.RegionSize & 0xfff) == 0xfff) {
126
+ break;
127
+ }
128
+ if (((PBYTE)mbi.BaseAddress + mbi.RegionSize) < pbLast) {
129
+ break;
130
+ }
131
+
132
+ // Skip uncommitted regions and guard pages.
133
+ //
134
+ if ((mbi.State != MEM_COMMIT) ||
135
+ ((mbi.Protect & 0xff) == PAGE_NOACCESS) ||
136
+ (mbi.Protect & PAGE_GUARD)) {
137
+ continue;
138
+ }
139
+
140
+ if (LoadNtHeaderFromProcess(hProcess, (HMODULE)pbLast, pNtHeader)) {
141
+ return (HMODULE)pbLast;
142
+ }
143
+ }
144
+ return NULL;
145
+ }
146
+
147
+ //////////////////////////////////////////////////////////////////////////////
148
+ //
149
+ // Find a region of memory in which we can create a replacement import table.
150
+ //
151
+ static PBYTE FindAndAllocateNearBase(HANDLE hProcess, PBYTE pbBase, DWORD cbAlloc)
152
+ {
153
+ MEMORY_BASIC_INFORMATION mbi;
154
+ ZeroMemory(&mbi, sizeof(mbi));
155
+
156
+ PBYTE pbLast = pbBase;
157
+ for (;; pbLast = (PBYTE)mbi.BaseAddress + mbi.RegionSize) {
158
+
159
+ ZeroMemory(&mbi, sizeof(mbi));
160
+ if (VirtualQueryEx(hProcess, (PVOID)pbLast, &mbi, sizeof(mbi)) == 0) {
161
+ if (GetLastError() == ERROR_INVALID_PARAMETER) {
162
+ break;
163
+ }
164
+ DETOUR_TRACE(("VirtualQueryEx(%p) failed: %d\n",
165
+ pbLast, GetLastError()));
166
+ break;
167
+ }
168
+ // Usermode address space has such an unaligned region size always at the
169
+ // end and only at the end.
170
+ //
171
+ if ((mbi.RegionSize & 0xfff) == 0xfff) {
172
+ break;
173
+ }
174
+
175
+ // Skip anything other than a pure free region.
176
+ //
177
+ if (mbi.State != MEM_FREE) {
178
+ continue;
179
+ }
180
+
181
+ PBYTE pbAddress = (PBYTE)(((DWORD_PTR)mbi.BaseAddress + 0xffff) & ~(DWORD_PTR)0xffff);
182
+
183
+ #ifdef _WIN64
184
+ // The distance from pbBase to pbAddress must fit in 32 bits.
185
+ //
186
+ const size_t GB4 = ((((size_t)1) << 32) - 1);
187
+ if ((size_t)(pbAddress - pbBase) > GB4) {
188
+ DETOUR_TRACE(("FindAndAllocateNearBase(1) failing due to distance >4GB %p\n", pbAddress));
189
+ return NULL;
190
+ }
191
+ #endif
192
+
193
+ DETOUR_TRACE(("Free region %p..%p\n",
194
+ mbi.BaseAddress,
195
+ (PBYTE)mbi.BaseAddress + mbi.RegionSize));
196
+
197
+ for (; pbAddress < (PBYTE)mbi.BaseAddress + mbi.RegionSize; pbAddress += MM_ALLOCATION_GRANULARITY) {
198
+ PBYTE pbAlloc = (PBYTE)VirtualAllocEx(hProcess, pbAddress, cbAlloc,
199
+ MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
200
+ if (pbAlloc == NULL) {
201
+ DETOUR_TRACE(("VirtualAllocEx(%p) failed: %d\n", pbAddress, GetLastError()));
202
+ continue;
203
+ }
204
+ #ifdef _WIN64
205
+ // The distance from pbBase to pbAddress must fit in 32 bits.
206
+ //
207
+ if ((size_t)(pbAddress - pbBase) > GB4) {
208
+ DETOUR_TRACE(("FindAndAllocateNearBase(2) failing due to distance >4GB %p\n", pbAddress));
209
+ return NULL;
210
+ }
211
+ #endif
212
+ DETOUR_TRACE(("[%p..%p] Allocated for import table.\n",
213
+ pbAlloc, pbAlloc + cbAlloc));
214
+ return pbAlloc;
215
+ }
216
+ }
217
+ return NULL;
218
+ }
219
+
220
+ static inline DWORD PadToDword(DWORD dw)
221
+ {
222
+ return (dw + 3) & ~3u;
223
+ }
224
+
225
+ static inline DWORD PadToDwordPtr(DWORD dw)
226
+ {
227
+ return (dw + 7) & ~7u;
228
+ }
229
+
230
+ static inline HRESULT ReplaceOptionalSizeA(_Inout_z_count_(cchDest) LPSTR pszDest,
231
+ _In_ size_t cchDest,
232
+ _In_z_ LPCSTR pszSize)
233
+ {
234
+ if (cchDest == 0 || pszDest == NULL || pszSize == NULL ||
235
+ pszSize[0] == '\0' || pszSize[1] == '\0' || pszSize[2] != '\0') {
236
+
237
+ // can not write into empty buffer or with string other than two chars.
238
+ return ERROR_INVALID_PARAMETER;
239
+ }
240
+
241
+ for (; cchDest >= 2; cchDest--, pszDest++) {
242
+ if (pszDest[0] == '?' && pszDest[1] == '?') {
243
+ pszDest[0] = pszSize[0];
244
+ pszDest[1] = pszSize[1];
245
+ break;
246
+ }
247
+ }
248
+
249
+ return S_OK;
250
+ }
251
+
252
+ static BOOL RecordExeRestore(HANDLE hProcess, HMODULE hModule, DETOUR_EXE_RESTORE& der)
253
+ {
254
+ // Save the various headers for DetourRestoreAfterWith.
255
+ ZeroMemory(&der, sizeof(der));
256
+ der.cb = sizeof(der);
257
+
258
+ der.pidh = (PBYTE)hModule;
259
+ der.cbidh = sizeof(der.idh);
260
+ if (!ReadProcessMemory(hProcess, der.pidh, &der.idh, sizeof(der.idh), NULL)) {
261
+ DETOUR_TRACE(("ReadProcessMemory(idh@%p..%p) failed: %d\n",
262
+ der.pidh, der.pidh + der.cbidh, GetLastError()));
263
+ return FALSE;
264
+ }
265
+ DETOUR_TRACE(("IDH: %p..%p\n", der.pidh, der.pidh + der.cbidh));
266
+
267
+ // We read the NT header in two passes to get the full size.
268
+ // First we read just the Signature and FileHeader.
269
+ der.pinh = der.pidh + der.idh.e_lfanew;
270
+ der.cbinh = FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader);
271
+ if (!ReadProcessMemory(hProcess, der.pinh, &der.inh, der.cbinh, NULL)) {
272
+ DETOUR_TRACE(("ReadProcessMemory(inh@%p..%p) failed: %d\n",
273
+ der.pinh, der.pinh + der.cbinh, GetLastError()));
274
+ return FALSE;
275
+ }
276
+
277
+ // Second we read the OptionalHeader and Section headers.
278
+ der.cbinh = (FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader) +
279
+ der.inh.FileHeader.SizeOfOptionalHeader +
280
+ der.inh.FileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER));
281
+
282
+ if (der.cbinh > sizeof(der.raw)) {
283
+ return FALSE;
284
+ }
285
+
286
+ if (!ReadProcessMemory(hProcess, der.pinh, &der.inh, der.cbinh, NULL)) {
287
+ DETOUR_TRACE(("ReadProcessMemory(inh@%p..%p) failed: %d\n",
288
+ der.pinh, der.pinh + der.cbinh, GetLastError()));
289
+ return FALSE;
290
+ }
291
+ DETOUR_TRACE(("INH: %p..%p\n", der.pinh, der.pinh + der.cbinh));
292
+
293
+ // Third, we read the CLR header
294
+
295
+ if (der.inh.OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
296
+ if (der.inh32.CLR_DIRECTORY.VirtualAddress != 0 &&
297
+ der.inh32.CLR_DIRECTORY.Size != 0) {
298
+
299
+ DETOUR_TRACE(("CLR32.VirtAddr=%x, CLR.Size=%x\n",
300
+ der.inh32.CLR_DIRECTORY.VirtualAddress,
301
+ der.inh32.CLR_DIRECTORY.Size));
302
+
303
+ der.pclr = ((PBYTE)hModule) + der.inh32.CLR_DIRECTORY.VirtualAddress;
304
+ }
305
+ }
306
+ else if (der.inh.OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
307
+ if (der.inh64.CLR_DIRECTORY.VirtualAddress != 0 &&
308
+ der.inh64.CLR_DIRECTORY.Size != 0) {
309
+
310
+ DETOUR_TRACE(("CLR64.VirtAddr=%x, CLR.Size=%x\n",
311
+ der.inh64.CLR_DIRECTORY.VirtualAddress,
312
+ der.inh64.CLR_DIRECTORY.Size));
313
+
314
+ der.pclr = ((PBYTE)hModule) + der.inh64.CLR_DIRECTORY.VirtualAddress;
315
+ }
316
+ }
317
+
318
+ if (der.pclr != 0) {
319
+ der.cbclr = sizeof(der.clr);
320
+ if (!ReadProcessMemory(hProcess, der.pclr, &der.clr, der.cbclr, NULL)) {
321
+ DETOUR_TRACE(("ReadProcessMemory(clr@%p..%p) failed: %d\n",
322
+ der.pclr, der.pclr + der.cbclr, GetLastError()));
323
+ return FALSE;
324
+ }
325
+ DETOUR_TRACE(("CLR: %p..%p\n", der.pclr, der.pclr + der.cbclr));
326
+ }
327
+
328
+ return TRUE;
329
+ }
330
+
331
+ //////////////////////////////////////////////////////////////////////////////
332
+ //
333
+ #if DETOURS_32BIT
334
+ #define DWORD_XX DWORD32
335
+ #define IMAGE_NT_HEADERS_XX IMAGE_NT_HEADERS32
336
+ #define IMAGE_NT_OPTIONAL_HDR_MAGIC_XX IMAGE_NT_OPTIONAL_HDR32_MAGIC
337
+ #define IMAGE_ORDINAL_FLAG_XX IMAGE_ORDINAL_FLAG32
338
+ #define UPDATE_IMPORTS_XX UpdateImports32
339
+ #define DETOURS_BITS_XX 32
340
+ #include "uimports.cpp"
341
+ #undef DETOUR_EXE_RESTORE_FIELD_XX
342
+ #undef DWORD_XX
343
+ #undef IMAGE_NT_HEADERS_XX
344
+ #undef IMAGE_NT_OPTIONAL_HDR_MAGIC_XX
345
+ #undef IMAGE_ORDINAL_FLAG_XX
346
+ #undef UPDATE_IMPORTS_XX
347
+ #endif // DETOURS_32BIT
348
+
349
+ #if DETOURS_64BIT
350
+ #define DWORD_XX DWORD64
351
+ #define IMAGE_NT_HEADERS_XX IMAGE_NT_HEADERS64
352
+ #define IMAGE_NT_OPTIONAL_HDR_MAGIC_XX IMAGE_NT_OPTIONAL_HDR64_MAGIC
353
+ #define IMAGE_ORDINAL_FLAG_XX IMAGE_ORDINAL_FLAG64
354
+ #define UPDATE_IMPORTS_XX UpdateImports64
355
+ #define DETOURS_BITS_XX 64
356
+ #include "uimports.cpp"
357
+ #undef DETOUR_EXE_RESTORE_FIELD_XX
358
+ #undef DWORD_XX
359
+ #undef IMAGE_NT_HEADERS_XX
360
+ #undef IMAGE_NT_OPTIONAL_HDR_MAGIC_XX
361
+ #undef IMAGE_ORDINAL_FLAG_XX
362
+ #undef UPDATE_IMPORTS_XX
363
+ #endif // DETOURS_64BIT
364
+
365
+ //////////////////////////////////////////////////////////////////////////////
366
+ //
367
+ #if DETOURS_64BIT
368
+
369
+ C_ASSERT(sizeof(IMAGE_NT_HEADERS64) == sizeof(IMAGE_NT_HEADERS32) + 16);
370
+
371
+ static BOOL UpdateFrom32To64(HANDLE hProcess, HMODULE hModule, WORD machine,
372
+ DETOUR_EXE_RESTORE& der)
373
+ {
374
+ IMAGE_DOS_HEADER idh;
375
+ IMAGE_NT_HEADERS32 inh32;
376
+ IMAGE_NT_HEADERS64 inh64;
377
+ IMAGE_SECTION_HEADER sects[32];
378
+ PBYTE pbModule = (PBYTE)hModule;
379
+ DWORD n;
380
+
381
+ ZeroMemory(&inh32, sizeof(inh32));
382
+ ZeroMemory(&inh64, sizeof(inh64));
383
+ ZeroMemory(sects, sizeof(sects));
384
+
385
+ DETOUR_TRACE(("UpdateFrom32To64(%04x)\n", machine));
386
+ //////////////////////////////////////////////////////// Read old headers.
387
+ //
388
+ if (!ReadProcessMemory(hProcess, pbModule, &idh, sizeof(idh), NULL)) {
389
+ DETOUR_TRACE(("ReadProcessMemory(idh@%p..%p) failed: %d\n",
390
+ pbModule, pbModule + sizeof(idh), GetLastError()));
391
+ return FALSE;
392
+ }
393
+ DETOUR_TRACE(("ReadProcessMemory(idh@%p..%p)\n",
394
+ pbModule, pbModule + sizeof(idh)));
395
+
396
+ PBYTE pnh = pbModule + idh.e_lfanew;
397
+ if (!ReadProcessMemory(hProcess, pnh, &inh32, sizeof(inh32), NULL)) {
398
+ DETOUR_TRACE(("ReadProcessMemory(inh@%p..%p) failed: %d\n",
399
+ pnh, pnh + sizeof(inh32), GetLastError()));
400
+ return FALSE;
401
+ }
402
+ DETOUR_TRACE(("ReadProcessMemory(inh@%p..%p)\n", pnh, pnh + sizeof(inh32)));
403
+
404
+ if (inh32.FileHeader.NumberOfSections > (sizeof(sects)/sizeof(sects[0]))) {
405
+ return FALSE;
406
+ }
407
+
408
+ PBYTE psects = pnh +
409
+ FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader) +
410
+ inh32.FileHeader.SizeOfOptionalHeader;
411
+ ULONG cb = inh32.FileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER);
412
+ if (!ReadProcessMemory(hProcess, psects, &sects, cb, NULL)) {
413
+ DETOUR_TRACE(("ReadProcessMemory(ish@%p..%p) failed: %d\n",
414
+ psects, psects + cb, GetLastError()));
415
+ return FALSE;
416
+ }
417
+ DETOUR_TRACE(("ReadProcessMemory(ish@%p..%p)\n", psects, psects + cb));
418
+
419
+ ////////////////////////////////////////////////////////// Convert header.
420
+ //
421
+ inh64.Signature = inh32.Signature;
422
+ inh64.FileHeader = inh32.FileHeader;
423
+ inh64.FileHeader.Machine = machine;
424
+ inh64.FileHeader.SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER64);
425
+
426
+ inh64.OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR64_MAGIC;
427
+ inh64.OptionalHeader.MajorLinkerVersion = inh32.OptionalHeader.MajorLinkerVersion;
428
+ inh64.OptionalHeader.MinorLinkerVersion = inh32.OptionalHeader.MinorLinkerVersion;
429
+ inh64.OptionalHeader.SizeOfCode = inh32.OptionalHeader.SizeOfCode;
430
+ inh64.OptionalHeader.SizeOfInitializedData = inh32.OptionalHeader.SizeOfInitializedData;
431
+ inh64.OptionalHeader.SizeOfUninitializedData = inh32.OptionalHeader.SizeOfUninitializedData;
432
+ inh64.OptionalHeader.AddressOfEntryPoint = inh32.OptionalHeader.AddressOfEntryPoint;
433
+ inh64.OptionalHeader.BaseOfCode = inh32.OptionalHeader.BaseOfCode;
434
+ inh64.OptionalHeader.ImageBase = inh32.OptionalHeader.ImageBase;
435
+ inh64.OptionalHeader.SectionAlignment = inh32.OptionalHeader.SectionAlignment;
436
+ inh64.OptionalHeader.FileAlignment = inh32.OptionalHeader.FileAlignment;
437
+ inh64.OptionalHeader.MajorOperatingSystemVersion
438
+ = inh32.OptionalHeader.MajorOperatingSystemVersion;
439
+ inh64.OptionalHeader.MinorOperatingSystemVersion
440
+ = inh32.OptionalHeader.MinorOperatingSystemVersion;
441
+ inh64.OptionalHeader.MajorImageVersion = inh32.OptionalHeader.MajorImageVersion;
442
+ inh64.OptionalHeader.MinorImageVersion = inh32.OptionalHeader.MinorImageVersion;
443
+ inh64.OptionalHeader.MajorSubsystemVersion = inh32.OptionalHeader.MajorSubsystemVersion;
444
+ inh64.OptionalHeader.MinorSubsystemVersion = inh32.OptionalHeader.MinorSubsystemVersion;
445
+ inh64.OptionalHeader.Win32VersionValue = inh32.OptionalHeader.Win32VersionValue;
446
+ inh64.OptionalHeader.SizeOfImage = inh32.OptionalHeader.SizeOfImage;
447
+ inh64.OptionalHeader.SizeOfHeaders = inh32.OptionalHeader.SizeOfHeaders;
448
+ inh64.OptionalHeader.CheckSum = inh32.OptionalHeader.CheckSum;
449
+ inh64.OptionalHeader.Subsystem = inh32.OptionalHeader.Subsystem;
450
+ inh64.OptionalHeader.DllCharacteristics = inh32.OptionalHeader.DllCharacteristics;
451
+ inh64.OptionalHeader.SizeOfStackReserve = inh32.OptionalHeader.SizeOfStackReserve;
452
+ inh64.OptionalHeader.SizeOfStackCommit = inh32.OptionalHeader.SizeOfStackCommit;
453
+ inh64.OptionalHeader.SizeOfHeapReserve = inh32.OptionalHeader.SizeOfHeapReserve;
454
+ inh64.OptionalHeader.SizeOfHeapCommit = inh32.OptionalHeader.SizeOfHeapCommit;
455
+ inh64.OptionalHeader.LoaderFlags = inh32.OptionalHeader.LoaderFlags;
456
+ inh64.OptionalHeader.NumberOfRvaAndSizes = inh32.OptionalHeader.NumberOfRvaAndSizes;
457
+ for (n = 0; n < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; n++) {
458
+ inh64.OptionalHeader.DataDirectory[n] = inh32.OptionalHeader.DataDirectory[n];
459
+ }
460
+
461
+ /////////////////////////////////////////////////////// Write new headers.
462
+ //
463
+ DWORD dwProtect = 0;
464
+ if (!DetourVirtualProtectSameExecuteEx(hProcess, pbModule, inh64.OptionalHeader.SizeOfHeaders,
465
+ PAGE_EXECUTE_READWRITE, &dwProtect)) {
466
+ return FALSE;
467
+ }
468
+
469
+ if (!WriteProcessMemory(hProcess, pnh, &inh64, sizeof(inh64), NULL)) {
470
+ DETOUR_TRACE(("WriteProcessMemory(inh@%p..%p) failed: %d\n",
471
+ pnh, pnh + sizeof(inh64), GetLastError()));
472
+ return FALSE;
473
+ }
474
+ DETOUR_TRACE(("WriteProcessMemory(inh@%p..%p)\n", pnh, pnh + sizeof(inh64)));
475
+
476
+ psects = pnh +
477
+ FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader) +
478
+ inh64.FileHeader.SizeOfOptionalHeader;
479
+ cb = inh64.FileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER);
480
+ if (!WriteProcessMemory(hProcess, psects, &sects, cb, NULL)) {
481
+ DETOUR_TRACE(("WriteProcessMemory(ish@%p..%p) failed: %d\n",
482
+ psects, psects + cb, GetLastError()));
483
+ return FALSE;
484
+ }
485
+ DETOUR_TRACE(("WriteProcessMemory(ish@%p..%p)\n", psects, psects + cb));
486
+
487
+ // Record the updated headers.
488
+ if (!RecordExeRestore(hProcess, hModule, der)) {
489
+ return FALSE;
490
+ }
491
+
492
+ // Remove the import table.
493
+ if (der.pclr != NULL && (der.clr.Flags & 1)) {
494
+ inh64.IMPORT_DIRECTORY.VirtualAddress = 0;
495
+ inh64.IMPORT_DIRECTORY.Size = 0;
496
+
497
+ if (!WriteProcessMemory(hProcess, pnh, &inh64, sizeof(inh64), NULL)) {
498
+ DETOUR_TRACE(("WriteProcessMemory(inh@%p..%p) failed: %d\n",
499
+ pnh, pnh + sizeof(inh64), GetLastError()));
500
+ return FALSE;
501
+ }
502
+ }
503
+
504
+ DWORD dwOld = 0;
505
+ if (!VirtualProtectEx(hProcess, pbModule, inh64.OptionalHeader.SizeOfHeaders,
506
+ dwProtect, &dwOld)) {
507
+ return FALSE;
508
+ }
509
+
510
+ return TRUE;
511
+ }
512
+ #endif // DETOURS_64BIT
513
+
514
+ //////////////////////////////////////////////////////////////////////////////
515
+ //
516
+ BOOL WINAPI DetourUpdateProcessWithDll(_In_ HANDLE hProcess,
517
+ _In_reads_(nDlls) LPCSTR *rlpDlls,
518
+ _In_ DWORD nDlls)
519
+ {
520
+ // Find the next memory region that contains a mapped PE image.
521
+ //
522
+ BOOL bHas64BitDll = FALSE;
523
+ BOOL bHas32BitExe = FALSE;
524
+ BOOL bIs32BitProcess;
525
+ HMODULE hModule = NULL;
526
+ HMODULE hLast = NULL;
527
+
528
+ DETOUR_TRACE(("DetourUpdateProcessWithDll(%p,dlls=%d)\n", hProcess, nDlls));
529
+
530
+ for (;;) {
531
+ IMAGE_NT_HEADERS32 inh;
532
+
533
+ if ((hLast = EnumerateModulesInProcess(hProcess, hLast, &inh)) == NULL) {
534
+ break;
535
+ }
536
+
537
+ DETOUR_TRACE(("%p machine=%04x magic=%04x\n",
538
+ hLast, inh.FileHeader.Machine, inh.OptionalHeader.Magic));
539
+
540
+ if ((inh.FileHeader.Characteristics & IMAGE_FILE_DLL) == 0) {
541
+ hModule = hLast;
542
+ if (inh.OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC
543
+ && inh.FileHeader.Machine != 0) {
544
+
545
+ bHas32BitExe = TRUE;
546
+ }
547
+ DETOUR_TRACE(("%p Found EXE\n", hLast));
548
+ }
549
+ else {
550
+ if (inh.OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC
551
+ && inh.FileHeader.Machine != 0) {
552
+
553
+ bHas64BitDll = TRUE;
554
+ }
555
+ }
556
+ }
557
+
558
+ if (hModule == NULL) {
559
+ SetLastError(ERROR_INVALID_OPERATION);
560
+ return FALSE;
561
+ }
562
+
563
+ if (!bHas32BitExe) {
564
+ bIs32BitProcess = FALSE;
565
+ }
566
+ else if (!bHas64BitDll) {
567
+ bIs32BitProcess = TRUE;
568
+ }
569
+ else {
570
+ if (!IsWow64Process(hProcess, &bIs32BitProcess)) {
571
+ return FALSE;
572
+ }
573
+ }
574
+
575
+ DETOUR_TRACE((" 32BitExe=%d 32BitProcess\n", bHas32BitExe, bIs32BitProcess));
576
+
577
+ return DetourUpdateProcessWithDllEx(hProcess,
578
+ hModule,
579
+ bIs32BitProcess,
580
+ rlpDlls,
581
+ nDlls);
582
+ }
583
+
584
+ BOOL WINAPI DetourUpdateProcessWithDllEx(_In_ HANDLE hProcess,
585
+ _In_ HMODULE hModule,
586
+ _In_ BOOL bIs32BitProcess,
587
+ _In_reads_(nDlls) LPCSTR *rlpDlls,
588
+ _In_ DWORD nDlls)
589
+ {
590
+ // Find the next memory region that contains a mapped PE image.
591
+ //
592
+ BOOL bIs32BitExe = FALSE;
593
+
594
+ DETOUR_TRACE(("DetourUpdateProcessWithDllEx(%p,%p,dlls=%d)\n", hProcess, hModule, nDlls));
595
+
596
+ IMAGE_NT_HEADERS32 inh;
597
+
598
+ if (hModule == NULL || LoadNtHeaderFromProcess(hProcess, hModule, &inh) == NULL) {
599
+ SetLastError(ERROR_INVALID_OPERATION);
600
+ return FALSE;
601
+ }
602
+
603
+ if (inh.OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC
604
+ && inh.FileHeader.Machine != 0) {
605
+
606
+ bIs32BitExe = TRUE;
607
+ }
608
+
609
+ DETOUR_TRACE((" 32BitExe=%d 32BitProcess\n", bIs32BitExe, bIs32BitProcess));
610
+
611
+ if (hModule == NULL) {
612
+ SetLastError(ERROR_INVALID_OPERATION);
613
+ return FALSE;
614
+ }
615
+
616
+ // Save the various headers for DetourRestoreAfterWith.
617
+ //
618
+ DETOUR_EXE_RESTORE der;
619
+
620
+ if (!RecordExeRestore(hProcess, hModule, der)) {
621
+ return FALSE;
622
+ }
623
+
624
+ #if defined(DETOURS_64BIT)
625
+ // Try to convert a neutral 32-bit managed binary to a 64-bit managed binary.
626
+ if (bIs32BitExe && !bIs32BitProcess) {
627
+ if (!der.pclr // Native binary
628
+ || (der.clr.Flags & 1) == 0 // Or mixed-mode MSIL
629
+ || (der.clr.Flags & 2) != 0) { // Or 32BIT Required MSIL
630
+
631
+ SetLastError(ERROR_INVALID_HANDLE);
632
+ return FALSE;
633
+ }
634
+
635
+ if (!UpdateFrom32To64(hProcess, hModule,
636
+ #if defined(DETOURS_X64)
637
+ IMAGE_FILE_MACHINE_AMD64,
638
+ #elif defined(DETOURS_IA64)
639
+ IMAGE_FILE_MACHINE_IA64,
640
+ #elif defined(DETOURS_ARM64)
641
+ IMAGE_FILE_MACHINE_ARM64,
642
+ #else
643
+ #error Must define one of DETOURS_X64 or DETOURS_IA64 or DETOURS_ARM64 on 64-bit.
644
+ #endif
645
+ der)) {
646
+ return FALSE;
647
+ }
648
+ bIs32BitExe = FALSE;
649
+ }
650
+ #endif // DETOURS_64BIT
651
+
652
+ // Now decide if we can insert the detour.
653
+
654
+ #if defined(DETOURS_32BIT)
655
+ if (bIs32BitProcess) {
656
+ // 32-bit native or 32-bit managed process on any platform.
657
+ if (!UpdateImports32(hProcess, hModule, rlpDlls, nDlls)) {
658
+ return FALSE;
659
+ }
660
+ }
661
+ else {
662
+ // 64-bit native or 64-bit managed process.
663
+ //
664
+ // Can't detour a 64-bit process with 32-bit code.
665
+ // Note: This happens for 32-bit PE binaries containing only
666
+ // manage code that have been marked as 64-bit ready.
667
+ //
668
+ SetLastError(ERROR_INVALID_HANDLE);
669
+ return FALSE;
670
+ }
671
+ #elif defined(DETOURS_64BIT)
672
+ if (bIs32BitProcess || bIs32BitExe) {
673
+ // Can't detour a 32-bit process with 64-bit code.
674
+ SetLastError(ERROR_INVALID_HANDLE);
675
+ return FALSE;
676
+ }
677
+ else {
678
+ // 64-bit native or 64-bit managed process on any platform.
679
+ if (!UpdateImports64(hProcess, hModule, rlpDlls, nDlls)) {
680
+ return FALSE;
681
+ }
682
+ }
683
+ #else
684
+ #pragma Must define one of DETOURS_32BIT or DETOURS_64BIT.
685
+ #endif // DETOURS_64BIT
686
+
687
+ /////////////////////////////////////////////////// Update the CLR header.
688
+ //
689
+ if (der.pclr != NULL) {
690
+ DETOUR_CLR_HEADER clr;
691
+ CopyMemory(&clr, &der.clr, sizeof(clr));
692
+ clr.Flags &= 0xfffffffe; // Clear the IL_ONLY flag.
693
+
694
+ DWORD dwProtect;
695
+ if (!DetourVirtualProtectSameExecuteEx(hProcess, der.pclr, sizeof(clr), PAGE_READWRITE, &dwProtect)) {
696
+ DETOUR_TRACE(("VirtualProtectEx(clr) write failed: %d\n", GetLastError()));
697
+ return FALSE;
698
+ }
699
+
700
+ if (!WriteProcessMemory(hProcess, der.pclr, &clr, sizeof(clr), NULL)) {
701
+ DETOUR_TRACE(("WriteProcessMemory(clr) failed: %d\n", GetLastError()));
702
+ return FALSE;
703
+ }
704
+
705
+ if (!VirtualProtectEx(hProcess, der.pclr, sizeof(clr), dwProtect, &dwProtect)) {
706
+ DETOUR_TRACE(("VirtualProtectEx(clr) restore failed: %d\n", GetLastError()));
707
+ return FALSE;
708
+ }
709
+ DETOUR_TRACE(("CLR: %p..%p\n", der.pclr, der.pclr + der.cbclr));
710
+
711
+ #if DETOURS_64BIT
712
+ if (der.clr.Flags & 0x2) { // Is the 32BIT Required Flag set?
713
+ // X64 never gets here because the process appears as a WOW64 process.
714
+ // However, on IA64, it doesn't appear to be a WOW process.
715
+ DETOUR_TRACE(("CLR Requires 32-bit\n", der.pclr, der.pclr + der.cbclr));
716
+ SetLastError(ERROR_INVALID_HANDLE);
717
+ return FALSE;
718
+ }
719
+ #endif // DETOURS_64BIT
720
+ }
721
+
722
+ //////////////////////////////// Save the undo data to the target process.
723
+ //
724
+ if (!DetourCopyPayloadToProcess(hProcess, DETOUR_EXE_RESTORE_GUID, &der, sizeof(der))) {
725
+ DETOUR_TRACE(("DetourCopyPayloadToProcess failed: %d\n", GetLastError()));
726
+ return FALSE;
727
+ }
728
+ return TRUE;
729
+ }
730
+
731
+ //////////////////////////////////////////////////////////////////////////////
732
+ //
733
+ BOOL WINAPI DetourCreateProcessWithDllA(_In_opt_ LPCSTR lpApplicationName,
734
+ _Inout_opt_ LPSTR lpCommandLine,
735
+ _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
736
+ _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
737
+ _In_ BOOL bInheritHandles,
738
+ _In_ DWORD dwCreationFlags,
739
+ _In_opt_ LPVOID lpEnvironment,
740
+ _In_opt_ LPCSTR lpCurrentDirectory,
741
+ _In_ LPSTARTUPINFOA lpStartupInfo,
742
+ _Out_ LPPROCESS_INFORMATION lpProcessInformation,
743
+ _In_ LPCSTR lpDllName,
744
+ _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA)
745
+ {
746
+ DWORD dwMyCreationFlags = (dwCreationFlags | CREATE_SUSPENDED);
747
+ PROCESS_INFORMATION pi;
748
+ BOOL fResult = FALSE;
749
+
750
+ if (pfCreateProcessA == NULL) {
751
+ pfCreateProcessA = CreateProcessA;
752
+ }
753
+
754
+ fResult = pfCreateProcessA(lpApplicationName,
755
+ lpCommandLine,
756
+ lpProcessAttributes,
757
+ lpThreadAttributes,
758
+ bInheritHandles,
759
+ dwMyCreationFlags,
760
+ lpEnvironment,
761
+ lpCurrentDirectory,
762
+ lpStartupInfo,
763
+ &pi);
764
+
765
+ if (lpProcessInformation != NULL) {
766
+ CopyMemory(lpProcessInformation, &pi, sizeof(pi));
767
+ }
768
+
769
+ if (!fResult) {
770
+ return FALSE;
771
+ }
772
+
773
+ LPCSTR rlpDlls[2];
774
+ DWORD nDlls = 0;
775
+ if (lpDllName != NULL) {
776
+ rlpDlls[nDlls++] = lpDllName;
777
+ }
778
+
779
+ if (!DetourUpdateProcessWithDll(pi.hProcess, rlpDlls, nDlls)) {
780
+ TerminateProcess(pi.hProcess, ~0u);
781
+ return FALSE;
782
+ }
783
+
784
+ if (!(dwCreationFlags & CREATE_SUSPENDED)) {
785
+ ResumeThread(pi.hThread);
786
+ }
787
+ return TRUE;
788
+ }
789
+
790
+
791
+ BOOL WINAPI DetourCreateProcessWithDllW(_In_opt_ LPCWSTR lpApplicationName,
792
+ _Inout_opt_ LPWSTR lpCommandLine,
793
+ _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
794
+ _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
795
+ _In_ BOOL bInheritHandles,
796
+ _In_ DWORD dwCreationFlags,
797
+ _In_opt_ LPVOID lpEnvironment,
798
+ _In_opt_ LPCWSTR lpCurrentDirectory,
799
+ _In_ LPSTARTUPINFOW lpStartupInfo,
800
+ _Out_ LPPROCESS_INFORMATION lpProcessInformation,
801
+ _In_ LPCSTR lpDllName,
802
+ _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW)
803
+ {
804
+ DWORD dwMyCreationFlags = (dwCreationFlags | CREATE_SUSPENDED);
805
+ PROCESS_INFORMATION pi;
806
+
807
+ if (pfCreateProcessW == NULL) {
808
+ pfCreateProcessW = CreateProcessW;
809
+ }
810
+
811
+ BOOL fResult = pfCreateProcessW(lpApplicationName,
812
+ lpCommandLine,
813
+ lpProcessAttributes,
814
+ lpThreadAttributes,
815
+ bInheritHandles,
816
+ dwMyCreationFlags,
817
+ lpEnvironment,
818
+ lpCurrentDirectory,
819
+ lpStartupInfo,
820
+ &pi);
821
+
822
+ if (lpProcessInformation) {
823
+ CopyMemory(lpProcessInformation, &pi, sizeof(pi));
824
+ }
825
+
826
+ if (!fResult) {
827
+ return FALSE;
828
+ }
829
+
830
+ LPCSTR rlpDlls[2];
831
+ DWORD nDlls = 0;
832
+ if (lpDllName != NULL) {
833
+ rlpDlls[nDlls++] = lpDllName;
834
+ }
835
+
836
+ if (!DetourUpdateProcessWithDll(pi.hProcess, rlpDlls, nDlls)) {
837
+ TerminateProcess(pi.hProcess, ~0u);
838
+ return FALSE;
839
+ }
840
+
841
+ if (!(dwCreationFlags & CREATE_SUSPENDED)) {
842
+ ResumeThread(pi.hThread);
843
+ }
844
+ return TRUE;
845
+ }
846
+
847
+ BOOL WINAPI DetourCopyPayloadToProcess(_In_ HANDLE hProcess,
848
+ _In_ REFGUID rguid,
849
+ _In_reads_bytes_(cbData) PVOID pvData,
850
+ _In_ DWORD cbData)
851
+ {
852
+ DWORD cbTotal = (sizeof(IMAGE_DOS_HEADER) +
853
+ sizeof(IMAGE_NT_HEADERS) +
854
+ sizeof(IMAGE_SECTION_HEADER) +
855
+ sizeof(DETOUR_SECTION_HEADER) +
856
+ sizeof(DETOUR_SECTION_RECORD) +
857
+ cbData);
858
+
859
+ PBYTE pbBase = (PBYTE)VirtualAllocEx(hProcess, NULL, cbTotal,
860
+ MEM_COMMIT, PAGE_READWRITE);
861
+ if (pbBase == NULL) {
862
+ DETOUR_TRACE(("VirtualAllocEx(%d) failed: %d\n", cbTotal, GetLastError()));
863
+ return FALSE;
864
+ }
865
+
866
+ PBYTE pbTarget = pbBase;
867
+ IMAGE_DOS_HEADER idh;
868
+ IMAGE_NT_HEADERS inh;
869
+ IMAGE_SECTION_HEADER ish;
870
+ DETOUR_SECTION_HEADER dsh;
871
+ DETOUR_SECTION_RECORD dsr;
872
+ SIZE_T cbWrote = 0;
873
+
874
+ ZeroMemory(&idh, sizeof(idh));
875
+ idh.e_magic = IMAGE_DOS_SIGNATURE;
876
+ idh.e_lfanew = sizeof(idh);
877
+ if (!WriteProcessMemory(hProcess, pbTarget, &idh, sizeof(idh), &cbWrote) ||
878
+ cbWrote != sizeof(idh)) {
879
+ DETOUR_TRACE(("WriteProcessMemory(idh) failed: %d\n", GetLastError()));
880
+ return FALSE;
881
+ }
882
+ pbTarget += sizeof(idh);
883
+
884
+ ZeroMemory(&inh, sizeof(inh));
885
+ inh.Signature = IMAGE_NT_SIGNATURE;
886
+ inh.FileHeader.SizeOfOptionalHeader = sizeof(inh.OptionalHeader);
887
+ inh.FileHeader.Characteristics = IMAGE_FILE_DLL;
888
+ inh.FileHeader.NumberOfSections = 1;
889
+ inh.OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR_MAGIC;
890
+ if (!WriteProcessMemory(hProcess, pbTarget, &inh, sizeof(inh), &cbWrote) ||
891
+ cbWrote != sizeof(inh)) {
892
+ return FALSE;
893
+ }
894
+ pbTarget += sizeof(inh);
895
+
896
+ ZeroMemory(&ish, sizeof(ish));
897
+ memcpy(ish.Name, ".detour", sizeof(ish.Name));
898
+ ish.VirtualAddress = (DWORD)((pbTarget + sizeof(ish)) - pbBase);
899
+ ish.SizeOfRawData = (sizeof(DETOUR_SECTION_HEADER) +
900
+ sizeof(DETOUR_SECTION_RECORD) +
901
+ cbData);
902
+ if (!WriteProcessMemory(hProcess, pbTarget, &ish, sizeof(ish), &cbWrote) ||
903
+ cbWrote != sizeof(ish)) {
904
+ return FALSE;
905
+ }
906
+ pbTarget += sizeof(ish);
907
+
908
+ ZeroMemory(&dsh, sizeof(dsh));
909
+ dsh.cbHeaderSize = sizeof(dsh);
910
+ dsh.nSignature = DETOUR_SECTION_HEADER_SIGNATURE;
911
+ dsh.nDataOffset = sizeof(DETOUR_SECTION_HEADER);
912
+ dsh.cbDataSize = (sizeof(DETOUR_SECTION_HEADER) +
913
+ sizeof(DETOUR_SECTION_RECORD) +
914
+ cbData);
915
+ if (!WriteProcessMemory(hProcess, pbTarget, &dsh, sizeof(dsh), &cbWrote) ||
916
+ cbWrote != sizeof(dsh)) {
917
+ return FALSE;
918
+ }
919
+ pbTarget += sizeof(dsh);
920
+
921
+ ZeroMemory(&dsr, sizeof(dsr));
922
+ dsr.cbBytes = cbData + sizeof(DETOUR_SECTION_RECORD);
923
+ dsr.nReserved = 0;
924
+ dsr.guid = rguid;
925
+ if (!WriteProcessMemory(hProcess, pbTarget, &dsr, sizeof(dsr), &cbWrote) ||
926
+ cbWrote != sizeof(dsr)) {
927
+ return FALSE;
928
+ }
929
+ pbTarget += sizeof(dsr);
930
+
931
+ if (!WriteProcessMemory(hProcess, pbTarget, pvData, cbData, &cbWrote) ||
932
+ cbWrote != cbData) {
933
+ return FALSE;
934
+ }
935
+ pbTarget += cbData;
936
+
937
+ DETOUR_TRACE(("Copied %d byte payload into target process at %p\n",
938
+ cbTotal, pbTarget - cbTotal));
939
+ return TRUE;
940
+ }
941
+
942
+ static BOOL s_fSearchedForHelper = FALSE;
943
+ static PDETOUR_EXE_HELPER s_pHelper = NULL;
944
+
945
+ VOID CALLBACK DetourFinishHelperProcess(_In_ HWND,
946
+ _In_ HINSTANCE,
947
+ _In_ LPSTR,
948
+ _In_ INT)
949
+ {
950
+ LPCSTR * rlpDlls = NULL;
951
+ DWORD Result = 9900;
952
+
953
+ if (s_pHelper == NULL) {
954
+ DETOUR_TRACE(("DetourFinishHelperProcess called with s_pHelper = NULL.\n"));
955
+ Result = 9905;
956
+ goto Cleanup;
957
+ }
958
+
959
+ HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, s_pHelper->pid);
960
+ if (hProcess == NULL) {
961
+ DETOUR_TRACE(("OpenProcess(pid=%d) failed: %d\n",
962
+ s_pHelper->pid, GetLastError()));
963
+ Result = 9901;
964
+ goto Cleanup;
965
+ }
966
+
967
+ rlpDlls = new NOTHROW LPCSTR [s_pHelper->nDlls];
968
+ DWORD cSize = s_pHelper->cb - sizeof(DETOUR_EXE_HELPER);
969
+ DWORD cOffset = 0;
970
+ for (DWORD n = 0; n < s_pHelper->nDlls; n++) {
971
+ size_t cchDest = 0;
972
+ HRESULT hr = StringCchLengthA(&s_pHelper->rDlls[cOffset], cSize - cOffset, &cchDest);
973
+ if (!SUCCEEDED(hr)) {
974
+ Result = 9902;
975
+ goto Cleanup;
976
+ }
977
+
978
+ rlpDlls[n] = &s_pHelper->rDlls[cOffset];
979
+ cOffset += (DWORD)cchDest + 1;
980
+ }
981
+
982
+ if (!DetourUpdateProcessWithDll(hProcess, rlpDlls, s_pHelper->nDlls)) {
983
+ DETOUR_TRACE(("DetourUpdateProcessWithDll(pid=%d) failed: %d\n",
984
+ s_pHelper->pid, GetLastError()));
985
+ Result = 9903;
986
+ goto Cleanup;
987
+ }
988
+ Result = 0;
989
+
990
+ Cleanup:
991
+ if (rlpDlls != NULL) {
992
+ delete[] rlpDlls;
993
+ rlpDlls = NULL;
994
+ }
995
+
996
+ ExitProcess(Result);
997
+ }
998
+
999
+ BOOL WINAPI DetourIsHelperProcess(VOID)
1000
+ {
1001
+ PVOID pvData;
1002
+ DWORD cbData;
1003
+
1004
+ if (s_fSearchedForHelper) {
1005
+ return (s_pHelper != NULL);
1006
+ }
1007
+
1008
+ s_fSearchedForHelper = TRUE;
1009
+ pvData = DetourFindPayloadEx(DETOUR_EXE_HELPER_GUID, &cbData);
1010
+
1011
+ if (pvData == NULL || cbData < sizeof(DETOUR_EXE_HELPER)) {
1012
+ return FALSE;
1013
+ }
1014
+
1015
+ s_pHelper = (PDETOUR_EXE_HELPER)pvData;
1016
+ if (s_pHelper->cb < sizeof(*s_pHelper)) {
1017
+ s_pHelper = NULL;
1018
+ return FALSE;
1019
+ }
1020
+
1021
+ return TRUE;
1022
+ }
1023
+
1024
+ static
1025
+ BOOL WINAPI AllocExeHelper(_Out_ PDETOUR_EXE_HELPER *pHelper,
1026
+ _In_ DWORD dwTargetPid,
1027
+ _In_ DWORD nDlls,
1028
+ _In_reads_(nDlls) LPCSTR *rlpDlls)
1029
+ {
1030
+ PDETOUR_EXE_HELPER Helper = NULL;
1031
+ BOOL Result = FALSE;
1032
+
1033
+ if (pHelper == NULL) {
1034
+ goto Cleanup;
1035
+ }
1036
+ *pHelper = NULL;
1037
+
1038
+ if (nDlls < 1 || nDlls > 4096) {
1039
+ SetLastError(ERROR_INVALID_PARAMETER);
1040
+ goto Cleanup;
1041
+ }
1042
+
1043
+ DWORD cSize = 4;
1044
+ for (DWORD n = 0; n < nDlls; n++) {
1045
+ HRESULT hr;
1046
+ size_t cchDest = 0;
1047
+
1048
+ hr = StringCchLengthA(rlpDlls[n], 4096, &cchDest);
1049
+ if (!SUCCEEDED(hr)) {
1050
+ goto Cleanup;
1051
+ }
1052
+
1053
+ cSize += (DWORD)cchDest + 1;
1054
+ }
1055
+
1056
+ Helper = (PDETOUR_EXE_HELPER) new NOTHROW BYTE[sizeof(DETOUR_EXE_HELPER) + cSize];
1057
+ if (Helper == NULL) {
1058
+ goto Cleanup;
1059
+ }
1060
+
1061
+ Helper->cb = sizeof(DETOUR_EXE_HELPER) + cSize;
1062
+ Helper->pid = dwTargetPid;
1063
+ Helper->nDlls = nDlls;
1064
+
1065
+ _Field_range_(0, cSize - 4) DWORD cOffset = 0;
1066
+ for (DWORD n = 0; n < nDlls; n++) {
1067
+ HRESULT hr;
1068
+ size_t cchDest = 0;
1069
+
1070
+ if (cOffset > 0x10000 || cSize > 0x10000 || cOffset + 2 >= cSize) {
1071
+ goto Cleanup;
1072
+ }
1073
+
1074
+ if (cOffset + 2 >= cSize || cOffset + 65536 < cSize) {
1075
+ goto Cleanup;
1076
+ }
1077
+
1078
+ _Analysis_assume_(cOffset + 1 < cSize);
1079
+ _Analysis_assume_(cOffset < 0x10000);
1080
+ _Analysis_assume_(cSize < 0x10000);
1081
+
1082
+ PCHAR psz = &Helper->rDlls[cOffset];
1083
+
1084
+ hr = StringCchCopyA(psz, cSize - cOffset, rlpDlls[n]);
1085
+ if (!SUCCEEDED(hr)) {
1086
+ goto Cleanup;
1087
+ }
1088
+
1089
+ // REVIEW 28020 The expression '1<=_Param_(2)& &_Param_(2)<=2147483647' is not true at this call.
1090
+ // REVIEW 28313 Analysis will not proceed past this point because of annotation evaluation. The annotation expression *_Param_(3)<_Param_(2)&&*_Param_(3)<=stringLength$(_Param_(1)) cannot be true under any assumptions at this point in the program.
1091
+ #pragma warning(suppress:28020 28313)
1092
+ hr = StringCchLengthA(psz, cSize - cOffset, &cchDest);
1093
+ if (!SUCCEEDED(hr)) {
1094
+ goto Cleanup;
1095
+ }
1096
+
1097
+ // Replace "32." with "64." or "64." with "32."
1098
+
1099
+ for (DWORD c = (DWORD)cchDest + 1; c > 3; c--) {
1100
+ #if DETOURS_32BIT
1101
+ if (psz[c - 3] == '3' && psz[c - 2] == '2' && psz[c - 1] == '.') {
1102
+ psz[c - 3] = '6'; psz[c - 2] = '4';
1103
+ break;
1104
+ }
1105
+ #else
1106
+ if (psz[c - 3] == '6' && psz[c - 2] == '4' && psz[c - 1] == '.') {
1107
+ psz[c - 3] = '3'; psz[c - 2] = '2';
1108
+ break;
1109
+ }
1110
+ #endif
1111
+ }
1112
+
1113
+ cOffset += (DWORD)cchDest + 1;
1114
+ }
1115
+
1116
+ *pHelper = Helper;
1117
+ Helper = NULL;
1118
+ Result = TRUE;
1119
+
1120
+ Cleanup:
1121
+ if (Helper != NULL) {
1122
+ delete[] (PBYTE)Helper;
1123
+ Helper = NULL;
1124
+ }
1125
+ return Result;
1126
+ }
1127
+
1128
+ static
1129
+ VOID WINAPI FreeExeHelper(PDETOUR_EXE_HELPER *pHelper)
1130
+ {
1131
+ if (*pHelper != NULL) {
1132
+ delete[] (PBYTE)*pHelper;
1133
+ *pHelper = NULL;
1134
+ }
1135
+ }
1136
+
1137
+ BOOL WINAPI DetourProcessViaHelperA(_In_ DWORD dwTargetPid,
1138
+ _In_ LPCSTR lpDllName,
1139
+ _In_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA)
1140
+ {
1141
+ return DetourProcessViaHelperDllsA(dwTargetPid, 1, &lpDllName, pfCreateProcessA);
1142
+ }
1143
+
1144
+
1145
+ BOOL WINAPI DetourProcessViaHelperDllsA(_In_ DWORD dwTargetPid,
1146
+ _In_ DWORD nDlls,
1147
+ _In_reads_(nDlls) LPCSTR *rlpDlls,
1148
+ _In_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA)
1149
+ {
1150
+ BOOL Result = FALSE;
1151
+ PROCESS_INFORMATION pi;
1152
+ STARTUPINFOA si;
1153
+ CHAR szExe[MAX_PATH];
1154
+ CHAR szCommand[MAX_PATH];
1155
+ PDETOUR_EXE_HELPER helper = NULL;
1156
+ HRESULT hr;
1157
+
1158
+ DETOUR_TRACE(("DetourProcessViaHelperDlls(pid=%d,dlls=%d)\n", dwTargetPid, nDlls));
1159
+ if (nDlls < 1 || nDlls > 4096) {
1160
+ SetLastError(ERROR_INVALID_PARAMETER);
1161
+ goto Cleanup;
1162
+ }
1163
+ if (!AllocExeHelper(&helper, dwTargetPid, nDlls, rlpDlls)) {
1164
+ goto Cleanup;
1165
+ }
1166
+
1167
+ DWORD nLen = GetEnvironmentVariableA("WINDIR", szExe, ARRAYSIZE(szExe));
1168
+ if (nLen == 0 || nLen >= ARRAYSIZE(szExe)) {
1169
+ goto Cleanup;
1170
+ }
1171
+
1172
+ #if DETOURS_OPTION_BITS
1173
+ #if DETOURS_32BIT
1174
+ hr = StringCchCatA(szExe, ARRAYSIZE(szExe), "\\sysnative\\rundll32.exe");
1175
+ #else // !DETOURS_32BIT
1176
+ hr = StringCchCatA(szExe, ARRAYSIZE(szExe), "\\syswow64\\rundll32.exe");
1177
+ #endif // !DETOURS_32BIT
1178
+ #else // DETOURS_OPTIONS_BITS
1179
+ hr = StringCchCatA(szExe, ARRAYSIZE(szExe), "\\system32\\rundll32.exe");
1180
+ #endif // DETOURS_OPTIONS_BITS
1181
+ if (!SUCCEEDED(hr)) {
1182
+ goto Cleanup;
1183
+ }
1184
+
1185
+ hr = StringCchPrintfA(szCommand, ARRAYSIZE(szCommand),
1186
+ "rundll32.exe \"%hs\",#1", &helper->rDlls[0]);
1187
+ if (!SUCCEEDED(hr)) {
1188
+ goto Cleanup;
1189
+ }
1190
+
1191
+ ZeroMemory(&pi, sizeof(pi));
1192
+ ZeroMemory(&si, sizeof(si));
1193
+ si.cb = sizeof(si);
1194
+
1195
+ DETOUR_TRACE(("DetourProcessViaHelperDlls(\"%hs\", \"%hs\")\n", szExe, szCommand));
1196
+ if (pfCreateProcessA(szExe, szCommand, NULL, NULL, FALSE, CREATE_SUSPENDED,
1197
+ NULL, NULL, &si, &pi)) {
1198
+
1199
+ if (!DetourCopyPayloadToProcess(pi.hProcess,
1200
+ DETOUR_EXE_HELPER_GUID,
1201
+ helper, helper->cb)) {
1202
+ DETOUR_TRACE(("DetourCopyPayloadToProcess failed: %d\n", GetLastError()));
1203
+ TerminateProcess(pi.hProcess, ~0u);
1204
+ CloseHandle(pi.hProcess);
1205
+ CloseHandle(pi.hThread);
1206
+ goto Cleanup;
1207
+ }
1208
+
1209
+ ResumeThread(pi.hThread);
1210
+ WaitForSingleObject(pi.hProcess, INFINITE);
1211
+
1212
+ DWORD dwResult = 500;
1213
+ GetExitCodeProcess(pi.hProcess, &dwResult);
1214
+
1215
+ CloseHandle(pi.hProcess);
1216
+ CloseHandle(pi.hThread);
1217
+
1218
+ if (dwResult != 0) {
1219
+ DETOUR_TRACE(("Rundll32.exe failed: result=%d\n", dwResult));
1220
+ goto Cleanup;
1221
+ }
1222
+ Result = TRUE;
1223
+ }
1224
+ else {
1225
+ DETOUR_TRACE(("CreateProcess failed: %d\n", GetLastError()));
1226
+ goto Cleanup;
1227
+ }
1228
+
1229
+ Cleanup:
1230
+ FreeExeHelper(&helper);
1231
+ return Result;
1232
+ }
1233
+
1234
+ BOOL WINAPI DetourProcessViaHelperW(_In_ DWORD dwTargetPid,
1235
+ _In_ LPCSTR lpDllName,
1236
+ _In_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW)
1237
+ {
1238
+ return DetourProcessViaHelperDllsW(dwTargetPid, 1, &lpDllName, pfCreateProcessW);
1239
+ }
1240
+
1241
+ BOOL WINAPI DetourProcessViaHelperDllsW(_In_ DWORD dwTargetPid,
1242
+ _In_ DWORD nDlls,
1243
+ _In_reads_(nDlls) LPCSTR *rlpDlls,
1244
+ _In_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW)
1245
+ {
1246
+ BOOL Result = FALSE;
1247
+ PROCESS_INFORMATION pi;
1248
+ STARTUPINFOW si;
1249
+ WCHAR szExe[MAX_PATH];
1250
+ WCHAR szCommand[MAX_PATH];
1251
+ PDETOUR_EXE_HELPER helper = NULL;
1252
+ HRESULT hr;
1253
+
1254
+ DETOUR_TRACE(("DetourProcessViaHelperDlls(pid=%d,dlls=%d)\n", dwTargetPid, nDlls));
1255
+ if (nDlls < 1 || nDlls > 4096) {
1256
+ SetLastError(ERROR_INVALID_PARAMETER);
1257
+ goto Cleanup;
1258
+ }
1259
+ if (!AllocExeHelper(&helper, dwTargetPid, nDlls, rlpDlls)) {
1260
+ goto Cleanup;
1261
+ }
1262
+
1263
+ DWORD nLen = GetEnvironmentVariableW(L"WINDIR", szExe, ARRAYSIZE(szExe));
1264
+ if (nLen == 0 || nLen >= ARRAYSIZE(szExe)) {
1265
+ goto Cleanup;
1266
+ }
1267
+
1268
+ #if DETOURS_OPTION_BITS
1269
+ #if DETOURS_32BIT
1270
+ hr = StringCchCatW(szExe, ARRAYSIZE(szExe), L"\\sysnative\\rundll32.exe");
1271
+ #else // !DETOURS_32BIT
1272
+ hr = StringCchCatW(szExe, ARRAYSIZE(szExe), L"\\syswow64\\rundll32.exe");
1273
+ #endif // !DETOURS_32BIT
1274
+ #else // DETOURS_OPTIONS_BITS
1275
+ hr = StringCchCatW(szExe, ARRAYSIZE(szExe), L"\\system32\\rundll32.exe");
1276
+ #endif // DETOURS_OPTIONS_BITS
1277
+ if (!SUCCEEDED(hr)) {
1278
+ goto Cleanup;
1279
+ }
1280
+
1281
+ hr = StringCchPrintfW(szCommand, ARRAYSIZE(szCommand),
1282
+ L"rundll32.exe \"%hs\",#1", &helper->rDlls[0]);
1283
+ if (!SUCCEEDED(hr)) {
1284
+ goto Cleanup;
1285
+ }
1286
+
1287
+ ZeroMemory(&pi, sizeof(pi));
1288
+ ZeroMemory(&si, sizeof(si));
1289
+ si.cb = sizeof(si);
1290
+
1291
+ DETOUR_TRACE(("DetourProcessViaHelperDlls(\"%ls\", \"%ls\")\n", szExe, szCommand));
1292
+ if (pfCreateProcessW(szExe, szCommand, NULL, NULL, FALSE, CREATE_SUSPENDED,
1293
+ NULL, NULL, &si, &pi)) {
1294
+
1295
+ if (!DetourCopyPayloadToProcess(pi.hProcess,
1296
+ DETOUR_EXE_HELPER_GUID,
1297
+ helper, helper->cb)) {
1298
+ DETOUR_TRACE(("DetourCopyPayloadToProcess failed: %d\n", GetLastError()));
1299
+ TerminateProcess(pi.hProcess, ~0u);
1300
+ CloseHandle(pi.hProcess);
1301
+ CloseHandle(pi.hThread);
1302
+ goto Cleanup;
1303
+ }
1304
+
1305
+ ResumeThread(pi.hThread);
1306
+
1307
+ ResumeThread(pi.hThread);
1308
+ WaitForSingleObject(pi.hProcess, INFINITE);
1309
+
1310
+ DWORD dwResult = 500;
1311
+ GetExitCodeProcess(pi.hProcess, &dwResult);
1312
+
1313
+ CloseHandle(pi.hProcess);
1314
+ CloseHandle(pi.hThread);
1315
+
1316
+ if (dwResult != 0) {
1317
+ DETOUR_TRACE(("Rundll32.exe failed: result=%d\n", dwResult));
1318
+ goto Cleanup;
1319
+ }
1320
+ Result = TRUE;
1321
+ }
1322
+ else {
1323
+ DETOUR_TRACE(("CreateProcess failed: %d\n", GetLastError()));
1324
+ goto Cleanup;
1325
+ }
1326
+
1327
+ Cleanup:
1328
+ FreeExeHelper(&helper);
1329
+ return Result;
1330
+ }
1331
+
1332
+ BOOL WINAPI DetourCreateProcessWithDllExA(_In_opt_ LPCSTR lpApplicationName,
1333
+ _Inout_opt_ LPSTR lpCommandLine,
1334
+ _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
1335
+ _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
1336
+ _In_ BOOL bInheritHandles,
1337
+ _In_ DWORD dwCreationFlags,
1338
+ _In_opt_ LPVOID lpEnvironment,
1339
+ _In_opt_ LPCSTR lpCurrentDirectory,
1340
+ _In_ LPSTARTUPINFOA lpStartupInfo,
1341
+ _Out_ LPPROCESS_INFORMATION lpProcessInformation,
1342
+ _In_ LPCSTR lpDllName,
1343
+ _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA)
1344
+ {
1345
+ if (pfCreateProcessA == NULL) {
1346
+ pfCreateProcessA = CreateProcessA;
1347
+ }
1348
+
1349
+ PROCESS_INFORMATION backup;
1350
+ if (lpProcessInformation == NULL) {
1351
+ lpProcessInformation = &backup;
1352
+ ZeroMemory(&backup, sizeof(backup));
1353
+ }
1354
+
1355
+ if (!pfCreateProcessA(lpApplicationName,
1356
+ lpCommandLine,
1357
+ lpProcessAttributes,
1358
+ lpThreadAttributes,
1359
+ bInheritHandles,
1360
+ dwCreationFlags | CREATE_SUSPENDED,
1361
+ lpEnvironment,
1362
+ lpCurrentDirectory,
1363
+ lpStartupInfo,
1364
+ lpProcessInformation)) {
1365
+ return FALSE;
1366
+ }
1367
+
1368
+ LPCSTR szDll = lpDllName;
1369
+
1370
+ if (!DetourUpdateProcessWithDll(lpProcessInformation->hProcess, &szDll, 1) &&
1371
+ !DetourProcessViaHelperA(lpProcessInformation->dwProcessId,
1372
+ lpDllName,
1373
+ pfCreateProcessA)) {
1374
+
1375
+ TerminateProcess(lpProcessInformation->hProcess, ~0u);
1376
+ CloseHandle(lpProcessInformation->hProcess);
1377
+ CloseHandle(lpProcessInformation->hThread);
1378
+ return FALSE;
1379
+ }
1380
+
1381
+ if (!(dwCreationFlags & CREATE_SUSPENDED)) {
1382
+ ResumeThread(lpProcessInformation->hThread);
1383
+ }
1384
+
1385
+ if (lpProcessInformation == &backup) {
1386
+ CloseHandle(lpProcessInformation->hProcess);
1387
+ CloseHandle(lpProcessInformation->hThread);
1388
+ }
1389
+
1390
+ return TRUE;
1391
+ }
1392
+
1393
+ BOOL WINAPI DetourCreateProcessWithDllExW(_In_opt_ LPCWSTR lpApplicationName,
1394
+ _Inout_opt_ LPWSTR lpCommandLine,
1395
+ _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
1396
+ _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
1397
+ _In_ BOOL bInheritHandles,
1398
+ _In_ DWORD dwCreationFlags,
1399
+ _In_opt_ LPVOID lpEnvironment,
1400
+ _In_opt_ LPCWSTR lpCurrentDirectory,
1401
+ _In_ LPSTARTUPINFOW lpStartupInfo,
1402
+ _Out_ LPPROCESS_INFORMATION lpProcessInformation,
1403
+ _In_ LPCSTR lpDllName,
1404
+ _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW)
1405
+ {
1406
+ if (pfCreateProcessW == NULL) {
1407
+ pfCreateProcessW = CreateProcessW;
1408
+ }
1409
+
1410
+ PROCESS_INFORMATION backup;
1411
+ if (lpProcessInformation == NULL) {
1412
+ lpProcessInformation = &backup;
1413
+ ZeroMemory(&backup, sizeof(backup));
1414
+ }
1415
+
1416
+ if (!pfCreateProcessW(lpApplicationName,
1417
+ lpCommandLine,
1418
+ lpProcessAttributes,
1419
+ lpThreadAttributes,
1420
+ bInheritHandles,
1421
+ dwCreationFlags | CREATE_SUSPENDED,
1422
+ lpEnvironment,
1423
+ lpCurrentDirectory,
1424
+ lpStartupInfo,
1425
+ lpProcessInformation)) {
1426
+ return FALSE;
1427
+ }
1428
+
1429
+
1430
+ LPCSTR sz = lpDllName;
1431
+
1432
+ if (!DetourUpdateProcessWithDll(lpProcessInformation->hProcess, &sz, 1) &&
1433
+ !DetourProcessViaHelperW(lpProcessInformation->dwProcessId,
1434
+ lpDllName,
1435
+ pfCreateProcessW)) {
1436
+
1437
+ TerminateProcess(lpProcessInformation->hProcess, ~0u);
1438
+ CloseHandle(lpProcessInformation->hProcess);
1439
+ CloseHandle(lpProcessInformation->hThread);
1440
+ return FALSE;
1441
+ }
1442
+
1443
+ if (!(dwCreationFlags & CREATE_SUSPENDED)) {
1444
+ ResumeThread(lpProcessInformation->hThread);
1445
+ }
1446
+
1447
+ if (lpProcessInformation == &backup) {
1448
+ CloseHandle(lpProcessInformation->hProcess);
1449
+ CloseHandle(lpProcessInformation->hThread);
1450
+ }
1451
+ return TRUE;
1452
+ }
1453
+
1454
+ BOOL WINAPI DetourCreateProcessWithDllsA(_In_opt_ LPCSTR lpApplicationName,
1455
+ _Inout_opt_ LPSTR lpCommandLine,
1456
+ _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
1457
+ _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
1458
+ _In_ BOOL bInheritHandles,
1459
+ _In_ DWORD dwCreationFlags,
1460
+ _In_opt_ LPVOID lpEnvironment,
1461
+ _In_opt_ LPCSTR lpCurrentDirectory,
1462
+ _In_ LPSTARTUPINFOA lpStartupInfo,
1463
+ _Out_ LPPROCESS_INFORMATION lpProcessInformation,
1464
+ _In_ DWORD nDlls,
1465
+ _In_reads_(nDlls) LPCSTR *rlpDlls,
1466
+ _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA)
1467
+ {
1468
+ if (pfCreateProcessA == NULL) {
1469
+ pfCreateProcessA = CreateProcessA;
1470
+ }
1471
+
1472
+ PROCESS_INFORMATION backup;
1473
+ if (lpProcessInformation == NULL) {
1474
+ lpProcessInformation = &backup;
1475
+ ZeroMemory(&backup, sizeof(backup));
1476
+ }
1477
+
1478
+ if (!pfCreateProcessA(lpApplicationName,
1479
+ lpCommandLine,
1480
+ lpProcessAttributes,
1481
+ lpThreadAttributes,
1482
+ bInheritHandles,
1483
+ dwCreationFlags | CREATE_SUSPENDED,
1484
+ lpEnvironment,
1485
+ lpCurrentDirectory,
1486
+ lpStartupInfo,
1487
+ lpProcessInformation)) {
1488
+ return FALSE;
1489
+ }
1490
+
1491
+ if (!DetourUpdateProcessWithDll(lpProcessInformation->hProcess, rlpDlls, nDlls) &&
1492
+ !DetourProcessViaHelperDllsA(lpProcessInformation->dwProcessId,
1493
+ nDlls,
1494
+ rlpDlls,
1495
+ pfCreateProcessA)) {
1496
+
1497
+ TerminateProcess(lpProcessInformation->hProcess, ~0u);
1498
+ CloseHandle(lpProcessInformation->hProcess);
1499
+ CloseHandle(lpProcessInformation->hThread);
1500
+ return FALSE;
1501
+ }
1502
+
1503
+ if (!(dwCreationFlags & CREATE_SUSPENDED)) {
1504
+ ResumeThread(lpProcessInformation->hThread);
1505
+ }
1506
+
1507
+ if (lpProcessInformation == &backup) {
1508
+ CloseHandle(lpProcessInformation->hProcess);
1509
+ CloseHandle(lpProcessInformation->hThread);
1510
+ }
1511
+
1512
+ return TRUE;
1513
+ }
1514
+
1515
+ BOOL WINAPI DetourCreateProcessWithDllsW(_In_opt_ LPCWSTR lpApplicationName,
1516
+ _Inout_opt_ LPWSTR lpCommandLine,
1517
+ _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
1518
+ _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
1519
+ _In_ BOOL bInheritHandles,
1520
+ _In_ DWORD dwCreationFlags,
1521
+ _In_opt_ LPVOID lpEnvironment,
1522
+ _In_opt_ LPCWSTR lpCurrentDirectory,
1523
+ _In_ LPSTARTUPINFOW lpStartupInfo,
1524
+ _Out_ LPPROCESS_INFORMATION lpProcessInformation,
1525
+ _In_ DWORD nDlls,
1526
+ _In_reads_(nDlls) LPCSTR *rlpDlls,
1527
+ _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW)
1528
+ {
1529
+ if (pfCreateProcessW == NULL) {
1530
+ pfCreateProcessW = CreateProcessW;
1531
+ }
1532
+
1533
+ PROCESS_INFORMATION backup;
1534
+ if (lpProcessInformation == NULL) {
1535
+ lpProcessInformation = &backup;
1536
+ ZeroMemory(&backup, sizeof(backup));
1537
+ }
1538
+
1539
+ if (!pfCreateProcessW(lpApplicationName,
1540
+ lpCommandLine,
1541
+ lpProcessAttributes,
1542
+ lpThreadAttributes,
1543
+ bInheritHandles,
1544
+ dwCreationFlags | CREATE_SUSPENDED,
1545
+ lpEnvironment,
1546
+ lpCurrentDirectory,
1547
+ lpStartupInfo,
1548
+ lpProcessInformation)) {
1549
+ return FALSE;
1550
+ }
1551
+
1552
+
1553
+ if (!DetourUpdateProcessWithDll(lpProcessInformation->hProcess, rlpDlls, nDlls) &&
1554
+ !DetourProcessViaHelperDllsW(lpProcessInformation->dwProcessId,
1555
+ nDlls,
1556
+ rlpDlls,
1557
+ pfCreateProcessW)) {
1558
+
1559
+ TerminateProcess(lpProcessInformation->hProcess, ~0u);
1560
+ CloseHandle(lpProcessInformation->hProcess);
1561
+ CloseHandle(lpProcessInformation->hThread);
1562
+ return FALSE;
1563
+ }
1564
+
1565
+ if (!(dwCreationFlags & CREATE_SUSPENDED)) {
1566
+ ResumeThread(lpProcessInformation->hThread);
1567
+ }
1568
+
1569
+ if (lpProcessInformation == &backup) {
1570
+ CloseHandle(lpProcessInformation->hProcess);
1571
+ CloseHandle(lpProcessInformation->hThread);
1572
+ }
1573
+ return TRUE;
1574
+ }
1575
+
1576
+ //
1577
+ ///////////////////////////////////////////////////////////////// End of File.