diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..532843b
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,65 @@
+###############################################################################
+# Set default behavior to automatically normalize line endings.
+###############################################################################
+* text=auto
+
+*.cpp diff
+
+###############################################################################
+# Set default behavior for command prompt diff.
+#
+# This is need for earlier builds of msysgit that does not have it on by
+# default for csharp files.
+# Note: This is only used by command line
+###############################################################################
+#*.cs diff=csharp
+
+###############################################################################
+# Set the merge driver for project and solution files
+#
+# Merging from the command prompt will add diff markers to the files if there
+# are conflicts (Merging from VS is not affected by the settings below, in VS
+# the diff markers are never inserted). Diff markers may cause the following
+# file extensions to fail to load in VS. An alternative would be to treat
+# these files as binary and thus will always conflict and require user
+# intervention with every merge. To do so, just uncomment the entries below
+###############################################################################
+#*.sln merge=binary
+#*.csproj merge=binary
+#*.vbproj merge=binary
+#*.vcxproj merge=binary
+#*.vcproj merge=binary
+#*.dbproj merge=binary
+#*.fsproj merge=binary
+#*.lsproj merge=binary
+#*.wixproj merge=binary
+#*.modelproj merge=binary
+#*.sqlproj merge=binary
+#*.wwaproj merge=binary
+
+###############################################################################
+# behavior for image files
+#
+# image files are treated as binary by default.
+###############################################################################
+#*.jpg binary
+#*.png binary
+#*.gif binary
+
+###############################################################################
+# diff behavior for common document formats
+#
+# Convert binary document formats to text before diffing them. This feature
+# is only available from the command line. Turn it on by uncommenting the
+# entries below.
+###############################################################################
+#*.doc diff=astextplain
+#*.DOC diff=astextplain
+#*.docx diff=astextplain
+#*.DOCX diff=astextplain
+#*.dot diff=astextplain
+#*.DOT diff=astextplain
+#*.pdf diff=astextplain
+#*.PDF diff=astextplain
+#*.rtf diff=astextplain
+#*.RTF diff=astextplain
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..d9981d6
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,160 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# User-specific files
+.vs
+*.suo
+*.user
+*.sln.docstates
+
+# Build results
+
+[Dd]ebug/
+[Rr]elease/
+x64/
+build/
+[Bb]in/
+[Oo]bj/
+
+bin.*/
+
+# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
+# Not needed anymore: !packages/*/build/
+packages/
+*.nupkg
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+*_i.c
+*_p.c
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+!lib.*/*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.log
+*.scc
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opensdf
+*.sdf
+*.cachefile
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# NCrunch
+*.ncrunch*
+.*crunch*.local.xml
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.Publish.xml
+
+# NuGet Packages Directory
+## TODO: If you have NuGet Package Restore enabled, uncomment the next line
+#packages/
+
+# Windows Azure Build Output
+csx
+*.build.csdef
+
+# Windows Store app package directory
+AppPackages/
+
+# Others
+sql/
+*.Cache
+ClientBin/
+[Ss]tyle[Cc]op.*
+~$*
+*~
+*.dbmdl
+*.[Pp]ublish.xml
+*.pfx
+*.publishsettings
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file to a newer
+# Visual Studio version. Backup files are not needed, because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+
+# SQL Server files
+App_Data/
+
+#LightSwitch generated files
+GeneratedArtifacts/
+_Pvt_Extensions/
+ModelManifest.xml
+
+# =========================
+# Windows detritus
+# =========================
+
+# Windows image file caches
+Thumbs.db
+ehthumbs.db
+
+# Folder config file
+Desktop.ini
+
+# Recycle Bin used on file shares
+$RECYCLE.BIN/
+
+# Mac desktop service store files
+.DS_Store
diff --git a/InjectDll/InjectDll.vcxproj b/InjectDll/InjectDll.vcxproj
new file mode 100644
index 0000000..74f933f
--- /dev/null
+++ b/InjectDll/InjectDll.vcxproj
@@ -0,0 +1,181 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 15.0
+ {9BB3F6F3-87B1-4541-A709-2C80967C97EE}
+ Win32Proj
+ InjectDll
+ 10.0.17134.0
+
+
+
+ DynamicLibrary
+ true
+ v141
+ Unicode
+
+
+ DynamicLibrary
+ false
+ v141
+ true
+ Unicode
+
+
+ DynamicLibrary
+ true
+ v141
+ Unicode
+
+
+ DynamicLibrary
+ false
+ v141
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(SolutionDir)bin\
+ $(ProjectName)32
+
+
+ true
+ $(SolutionDir)bin.$(PlatformTarget)\
+
+
+ false
+ $(SolutionDir)bin.$(PlatformTarget)\
+ $(ProjectName)32
+
+
+ false
+ $(SolutionDir)bin.$(PlatformTarget)\
+
+
+
+ NotUsing
+ Level3
+ Disabled
+ true
+ WIN32;_DEBUG;INJECTDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
+ true
+
+ MultiThreadedDebug
+
+
+ Windows
+ true
+ Source.def
+ $(SolutionDir)lib.$(PlatformTarget)\detours.lib;%(AdditionalDependencies)
+
+
+
+
+ NotUsing
+ Level3
+ Disabled
+ true
+ _DEBUG;INJECTDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
+ true
+
+
+
+ Windows
+ true
+ Source.def
+ $(SolutionDir)lib.$(PlatformTarget)\detours.lib;%(AdditionalDependencies)
+
+
+
+
+ NotUsing
+ Level3
+ MaxSpeed
+ true
+ true
+ true
+ WIN32;NDEBUG;INJECTDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
+ true
+
+ MultiThreaded
+
+
+ Windows
+ true
+ true
+ true
+ Source.def
+ $(SolutionDir)lib.$(PlatformTarget)\detours.lib;%(AdditionalDependencies)
+
+
+
+
+ NotUsing
+ Level3
+ MaxSpeed
+ true
+ true
+ true
+ NDEBUG;INJECTDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
+ true
+
+
+
+ Windows
+ true
+ true
+ true
+ Source.def
+ $(SolutionDir)lib.$(PlatformTarget)\detours.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/InjectDll/InjectDll.vcxproj.filters b/InjectDll/InjectDll.vcxproj.filters
new file mode 100644
index 0000000..ee2d994
--- /dev/null
+++ b/InjectDll/InjectDll.vcxproj.filters
@@ -0,0 +1,32 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;hm;inl;inc;ipp;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Header Files
+
+
+
+
+ Source Files
+
+
+
+
+ Source Files
+
+
+
\ No newline at end of file
diff --git a/InjectDll/Source.def b/InjectDll/Source.def
new file mode 100644
index 0000000..b3b601c
--- /dev/null
+++ b/InjectDll/Source.def
@@ -0,0 +1,3 @@
+LIBRARY InjectDll32
+EXPORTS
+ DetourFinishHelperProcess @1
\ No newline at end of file
diff --git a/InjectDll/dllmain.cpp b/InjectDll/dllmain.cpp
new file mode 100644
index 0000000..a7d999f
Binary files /dev/null and b/InjectDll/dllmain.cpp differ
diff --git a/InjectDll/targetver.h b/InjectDll/targetver.h
new file mode 100644
index 0000000..567cd34
Binary files /dev/null and b/InjectDll/targetver.h differ
diff --git a/InjectDll64/InjectDll64.vcxproj b/InjectDll64/InjectDll64.vcxproj
new file mode 100644
index 0000000..ae89d09
--- /dev/null
+++ b/InjectDll64/InjectDll64.vcxproj
@@ -0,0 +1,179 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 15.0
+ {82864E7A-BBCC-47E5-9A85-A6999B1B1560}
+ Win32Proj
+ InjectDll
+ 10.0.17134.0
+
+
+
+ DynamicLibrary
+ true
+ v141
+ Unicode
+
+
+ DynamicLibrary
+ false
+ v141
+ true
+ Unicode
+
+
+ DynamicLibrary
+ true
+ v141
+ Unicode
+
+
+ DynamicLibrary
+ false
+ v141
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(SolutionDir)bin.$(PlatformTarget)\
+
+
+ true
+ $(SolutionDir)bin\
+
+
+ false
+ $(SolutionDir)bin.$(PlatformTarget)\
+
+
+ false
+ $(SolutionDir)bin.$(PlatformTarget)\
+
+
+
+ NotUsing
+ Level3
+ Disabled
+ true
+ WIN32;_DEBUG;INJECTDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
+ true
+
+
+
+ Windows
+ true
+ Source.def
+ $(SolutionDir)lib.$(PlatformTarget)\detours.lib;%(AdditionalDependencies)
+
+
+
+
+ NotUsing
+ Level3
+ Disabled
+ true
+ _DEBUG;INJECTDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
+ true
+
+ MultiThreadedDebug
+
+
+ Windows
+ true
+ Source.def
+ $(SolutionDir)lib.x64\detours.lib;%(AdditionalDependencies)
+
+
+
+
+ NotUsing
+ Level3
+ MaxSpeed
+ true
+ true
+ true
+ WIN32;NDEBUG;INJECTDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
+ true
+
+
+
+ Windows
+ true
+ true
+ true
+ Source.def
+ $(SolutionDir)lib.$(PlatformTarget)\detours.lib;%(AdditionalDependencies)
+
+
+
+
+ NotUsing
+ Level3
+ MaxSpeed
+ true
+ true
+ true
+ NDEBUG;INJECTDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
+ true
+
+ MultiThreaded
+
+
+ Windows
+ true
+ true
+ true
+ Source.def
+ $(SolutionDir)lib.$(PlatformTarget)\detours.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/InjectDll64/InjectDll64.vcxproj.filters b/InjectDll64/InjectDll64.vcxproj.filters
new file mode 100644
index 0000000..f1df2dd
--- /dev/null
+++ b/InjectDll64/InjectDll64.vcxproj.filters
@@ -0,0 +1,32 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;hm;inl;inc;ipp;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Header Files
+
+
+
+
+ Source Files
+
+
+
+
+ Source Files
+
+
+
\ No newline at end of file
diff --git a/InjectDll64/Source.def b/InjectDll64/Source.def
new file mode 100644
index 0000000..3753171
--- /dev/null
+++ b/InjectDll64/Source.def
@@ -0,0 +1,3 @@
+LIBRARY InjectDll64
+EXPORTS
+ DetourFinishHelperProcess @1
\ No newline at end of file
diff --git a/InjectDll64/targetver.h b/InjectDll64/targetver.h
new file mode 100644
index 0000000..567cd34
Binary files /dev/null and b/InjectDll64/targetver.h differ
diff --git a/README.md b/README.md
index d956918..68fa6f3 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,98 @@
-# takedetour
-A template (and a sample) for writing tracers on Windows. Based on the Detours library.
+
+# TakeDetour
+
+This project is a template for building tracers on Windows. It wraps the excellent [Microsoft Detours library](https://github.com/Microsoft/Detours) to create a self-contained, single binary with all the hooking functions you define. As an example, I hooked the `CreateDirectory` function so running the [TakeDetour.exe](https://github.com/lowleveldesign/takedetour/releases) with any application prints all the calls to this function on the Windows Debug Output (you may use [DebugView](https://docs.microsoft.com/en-us/sysinternals/downloads/debugview) to see it). For example:
+
+```
+PS> .\TakeDetour.exe -w c:\windows\system32\notepad.exe
+INFO: Starting the 'c:\windows\system32\notepad.exe' process.
+
+Press Ctrl + C to stop the target process.
+```
+
+Start the DebugView and make sure **Capture -> Capture Global Win32** is checked. Then, open the **New File** dialog in notepad, and you should see trace messages appearing in the DebugView window:
+
+![DebugView output](dbgview_output.png)
+
+**The released executable works on all Windows system starting from 7 and can hook both 32-bit and 64-bit applications.**
+
+## What this project contains
+
+I implemented two ways of interacting with a target process. You may either **start a new process** or **attach to an existing process**. The first way uses the [`DetourCreateProcessWithDllEx`](https://github.com/Microsoft/Detours/wiki/DetourCreateProcessWithDllEx) function from the Detours library. The latter injects the DLL using the remote thread.
+
+Whether you start a new process or attach to an existing one, you may add the **-w** argument to control the injection process. This option makes the application to wait for a **Ctrl + C** event or a target process termination. When a user presses Ctrl + C after attaching to a process, the injected DLL is detached, and the target process continues running. Pressing Ctrl + C after starting a new process forces the target process to terminate.
+
+All the dependencies are embedded as binary resources, and TakeDetour unpacks them to a temporary folder (`%TEMP%\takedetour`) on start. The default executable is 32-bit. Thus, to hook a 64-bit process it needs to spawn a helper process. When running TakeDetour on a 64-bit system, remember that the Wow64 engine maps some folder paths. For example: `TakeDetour c:\Windows\System32\notepad.exe` will start a 32-bit notepad.exe. To start the 64-bit version, use `TakeDetour c:\Windows\sysnative\notepad.exe`.
+
+The injected dll name is InjectDll32.dll for 32-bit process and InjectDll64.dll for 64-bit processes.
+
+## How to add your hooks
+
+Open the TakeDetours.sln file in **Visual Studio 2017** and edit the **InjectDll\dllmain.cpp** file. You may want to check [Detours Wiki](https://github.com/Microsoft/Detours/wiki) first to learn how to hook methods with the Detours API.
+
+You usually start with the hook definition, for example:
+
+```cpp
+static BOOL(WINAPI * TrueCreateDirectory)(
+ LPCWSTR lpPathName,
+ LPSECURITY_ATTRIBUTES lpSecurityAttributes
+) = CreateDirectory;
+
+BOOL WINAPI TracedCreateDirectory(
+ LPCWSTR lpPathName,
+ LPSECURITY_ATTRIBUTES lpSecurityAttributes
+)
+{
+ wostringstream output;
+ output << L"Traced CreateDirectory: " << lpPathName;
+ OutputDebugString(output.str().c_str());
+
+ return TrueCreateDirectory(lpPathName, lpSecurityAttributes);
+}
+```
+
+Later, you need to enable your hooks in the DllMain method. Please modify only the `DLL_PROCESS_ATTACH` and `DLL_PROCESS_DETACH` blocks. For example:
+
+```cpp
+BOOL APIENTRY DllMain(HMODULE hModule,
+ DWORD ul_reason_for_call,
+ LPVOID lpReserved
+)
+{
+ ...
+ switch (ul_reason_for_call) {
+ case DLL_PROCESS_ATTACH:
+ DetourRestoreAfterWith();
+
+ DetourTransactionBegin();
+ DetourUpdateThread(GetCurrentThread());
+ DetourAttach(&(PVOID&)TrueCreateDirectory, TracedCreateDirectory);
+ // TODO: add your hooks here
+ error = DetourTransactionCommit();
+ if (error != NO_ERROR) {
+ wostringstream output;
+ output << L"Error detouring: " << error;
+ OutputDebugString(output.str().c_str());
+ }
+ break;
+ ...
+ case DLL_PROCESS_DETACH:
+ DetourTransactionBegin();
+ DetourUpdateThread(GetCurrentThread());
+ DetourDetach(&(PVOID&)TrueCreateDirectory, TracedCreateDirectory);
+ // TODO: add your hooks here
+ error = DetourTransactionCommit();
+ if (error != NO_ERROR) {
+ wostringstream output;
+ output << L"Error detouring: " << error;
+ OutputDebugString(output.str().c_str());
+ }
+ break;
+ }
+ ...
+}
+```
+
+## Reporting bugs
+
+If you find a bug or have an idea for improvement, please add it to the [Issues](https://github.com/lowleveldesign/takedetour/issues) list.
diff --git a/TakeDetour.sln b/TakeDetour.sln
new file mode 100644
index 0000000..2589c7b
--- /dev/null
+++ b/TakeDetour.sln
@@ -0,0 +1,48 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.28010.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TakeDetour", "TakeDetour\TakeDetour.vcxproj", "{275575D6-7FA1-42CB-9119-BCC3C548989A}"
+ ProjectSection(ProjectDependencies) = postProject
+ {202EF952-2AF9-45D7-A7D2-CF08C16EAE1E} = {202EF952-2AF9-45D7-A7D2-CF08C16EAE1E}
+ {82864E7A-BBCC-47E5-9A85-A6999B1B1560} = {82864E7A-BBCC-47E5-9A85-A6999B1B1560}
+ {9BB3F6F3-87B1-4541-A709-2C80967C97EE} = {9BB3F6F3-87B1-4541-A709-2C80967C97EE}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "InjectDll", "InjectDll\InjectDll.vcxproj", "{9BB3F6F3-87B1-4541-A709-2C80967C97EE}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "InjectDll64", "InjectDll64\InjectDll64.vcxproj", "{82864E7A-BBCC-47E5-9A85-A6999B1B1560}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TakeDetour64", "TakeDetour64\TakeDetour64.vcxproj", "{202EF952-2AF9-45D7-A7D2-CF08C16EAE1E}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x86 = Debug|x86
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {275575D6-7FA1-42CB-9119-BCC3C548989A}.Debug|x86.ActiveCfg = Debug|Win32
+ {275575D6-7FA1-42CB-9119-BCC3C548989A}.Debug|x86.Build.0 = Debug|Win32
+ {275575D6-7FA1-42CB-9119-BCC3C548989A}.Release|x86.ActiveCfg = Release|Win32
+ {275575D6-7FA1-42CB-9119-BCC3C548989A}.Release|x86.Build.0 = Release|Win32
+ {9BB3F6F3-87B1-4541-A709-2C80967C97EE}.Debug|x86.ActiveCfg = Debug|Win32
+ {9BB3F6F3-87B1-4541-A709-2C80967C97EE}.Debug|x86.Build.0 = Debug|Win32
+ {9BB3F6F3-87B1-4541-A709-2C80967C97EE}.Release|x86.ActiveCfg = Release|Win32
+ {9BB3F6F3-87B1-4541-A709-2C80967C97EE}.Release|x86.Build.0 = Release|Win32
+ {82864E7A-BBCC-47E5-9A85-A6999B1B1560}.Debug|x86.ActiveCfg = Debug|x64
+ {82864E7A-BBCC-47E5-9A85-A6999B1B1560}.Debug|x86.Build.0 = Debug|x64
+ {82864E7A-BBCC-47E5-9A85-A6999B1B1560}.Release|x86.ActiveCfg = Release|x64
+ {82864E7A-BBCC-47E5-9A85-A6999B1B1560}.Release|x86.Build.0 = Release|x64
+ {202EF952-2AF9-45D7-A7D2-CF08C16EAE1E}.Debug|x86.ActiveCfg = Debug|x64
+ {202EF952-2AF9-45D7-A7D2-CF08C16EAE1E}.Debug|x86.Build.0 = Debug|x64
+ {202EF952-2AF9-45D7-A7D2-CF08C16EAE1E}.Release|x86.ActiveCfg = Release|x64
+ {202EF952-2AF9-45D7-A7D2-CF08C16EAE1E}.Release|x86.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {2CDAF843-1DE6-4A47-95BA-58F6C3EC421F}
+ EndGlobalSection
+EndGlobal
diff --git a/TakeDetour/Detouring.cpp b/TakeDetour/Detouring.cpp
new file mode 100644
index 0000000..b8e4fe4
--- /dev/null
+++ b/TakeDetour/Detouring.cpp
@@ -0,0 +1,206 @@
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "Detouring.h"
+#include "../include/detours.h"
+
+using namespace std;
+
+string ws2s(const std::wstring& wstr)
+{
+ using convert_typeX = std::codecvt_utf8;
+ std::wstring_convert converterX;
+
+ return converterX.to_bytes(wstr);
+}
+
+//----------------------------------------------------------------
+
+void ThrowWin32Exception(const char *funcname)
+{
+ DWORD dwError = GetLastError();
+ ostringstream os;
+ os << funcname << " failed: 0x" << hex << dwError << endl;
+ throw exception(os.str().c_str());
+}
+
+//----------------------------------------------------------------
+
+HANDLE StartProcess(const string& injectdll, const wstring& exe, const wstring& args)
+{
+ STARTUPINFO si;
+ PROCESS_INFORMATION pi;
+
+ ZeroMemory(&si, sizeof(si));
+ ZeroMemory(&pi, sizeof(pi));
+ si.cb = sizeof(si);
+
+ auto command = make_unique(args.length() + 1);
+ wmemcpy_s(command.get(), args.length(), args.c_str(), args.length());
+ command.get()[args.length()] = L'\0';
+
+ if (!DetourCreateProcessWithDllEx(exe.c_str(), command.get(),
+ NULL, NULL, TRUE,
+ CREATE_DEFAULT_ERROR_MODE | CREATE_SUSPENDED,
+ NULL, NULL, &si, &pi, injectdll.c_str(), NULL)) {
+ ThrowWin32Exception("DetourCreateProcessWithDllEx");
+ }
+
+ ResumeThread(pi.hThread);
+ CloseHandle(pi.hThread);
+
+ return pi.hProcess;
+}
+
+//----------------------------------------------------------------
+
+BOOL CALLBACK EnumerateExportCallback(PVOID pContext, ULONG nOrdinal, LPCSTR pszName, PVOID pCode)
+{
+ FunctionCharacteristics* func = reinterpret_cast(pContext);
+ if (strcmp(func->FunctionName, pszName) == 0) {
+ *(func->FunctionAddress) = pCode;
+ return FALSE;
+ }
+ return TRUE;
+}
+
+//----------------------------------------------------------------
+
+HMODULE LocateModuleInRemoteProcess(HANDLE hProcess, const wstring& modulePath)
+{
+ HMODULE modules[1024];
+ DWORD cb = sizeof(modules);
+ DWORD requiredcb;
+ if (!EnumProcessModules(hProcess, modules, cb, &requiredcb)) {
+ ThrowWin32Exception("EnumProcessModules");
+ }
+
+ if (requiredcb > cb) {
+ throw exception("EnumProcessModules failed: the modules buffer was too small.");
+ }
+
+ for (DWORD i = 0; i < requiredcb / sizeof(HMODULE); i++) {
+ wchar_t moduleName[MAX_PATH];
+ DWORD moduleNameLength = GetModuleFileNameEx(hProcess, modules[i], moduleName, sizeof(moduleName) / sizeof(wchar_t));
+ // FIXME: if moduleNameLength == MAX_PATH there is chance the module name array was too small
+ if (moduleNameLength == 0) {
+ ThrowWin32Exception("GetModuleFileNameEx");
+ }
+ if (moduleNameLength >= modulePath.length()
+ && _wcsicmp(modulePath.c_str(), moduleName + moduleNameLength - modulePath.length()) == 0) {
+ return modules[i];
+ }
+ }
+ return NULL;
+}
+
+//----------------------------------------------------------------
+
+// Return address of the LoadLibrary function in the remote process
+PVOID LocateExportedFunctionInModule(HMODULE moduleHandle, const char* functionName)
+{
+ // we found the kernel32.dll
+ PVOID functionAddress = nullptr;
+ FunctionCharacteristics context = { functionName, &functionAddress };
+ if (!DetourEnumerateExports(moduleHandle, &context, EnumerateExportCallback)) {
+ ThrowWin32Exception("DetourEnumerateExports");
+ }
+ return functionAddress;
+}
+
+//----------------------------------------------------------------
+
+HANDLE AttachToProcess(DWORD pid, const wstring& injectdll)
+{
+ DWORD flags = PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION |
+ PROCESS_VM_WRITE | PROCESS_VM_READ | SYNCHRONIZE;
+ HANDLE targetProcess = OpenProcess(flags, FALSE, pid);
+ if (targetProcess == NULL) {
+ ThrowWin32Exception("OpenProcess");
+ }
+
+ HMODULE kernel32 = LocateModuleInRemoteProcess(targetProcess, L"\\kernel32.dll");
+ if (!kernel32) {
+ throw exception("Can't find kernel32.dll in the remote process.");
+ }
+
+ PVOID LoadLibraryWAddress = LocateExportedFunctionInModule(kernel32, "LoadLibraryW");
+ assert(LoadLibraryWAddress != NULL);
+
+ // allocate injection buffer
+ SIZE_T injectdllLengthInBytes = (injectdll.length() + 1) * sizeof(wchar_t);
+ PBYTE injectionBuffer = (PBYTE)VirtualAllocEx(targetProcess, NULL, injectdllLengthInBytes,
+ MEM_COMMIT, PAGE_EXECUTE_READWRITE);
+ if (!injectionBuffer) {
+ ThrowWin32Exception("VirtualAllocEx");
+ }
+ SIZE_T n;
+ if (!WriteProcessMemory(targetProcess, injectionBuffer, injectdll.c_str(), injectdllLengthInBytes, &n)
+ || n != injectdllLengthInBytes) {
+ ThrowWin32Exception("WriteProcessMemory");
+ }
+
+ HANDLE injectedThread;
+ DWORD injecteeThreadId;
+ injectedThread = CreateRemoteThread(targetProcess, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibraryWAddress,
+ injectionBuffer, 0, &injecteeThreadId);
+ if (!injectedThread) {
+ ThrowWin32Exception("CreateRemoteThread");
+ }
+
+ if (WaitForSingleObject(injectedThread, INFINITE) == WAIT_FAILED) {
+ ThrowWin32Exception("WaitForSingleObject (remote thread)");
+ }
+ CloseHandle(injectedThread);
+
+ if (!VirtualFreeEx(targetProcess, injectionBuffer, 0, MEM_RELEASE)) {
+ ThrowWin32Exception("VirtualFreeEx");
+ }
+
+ return targetProcess;
+}
+
+//----------------------------------------------------------------
+
+void DetachFromProcess(HANDLE targetProcess, const wstring& injectdll)
+{
+ HMODULE modules[1024];
+ DWORD cb = sizeof(modules);
+ DWORD requiredcb;
+ if (!EnumProcessModules(targetProcess, modules, cb, &requiredcb)) {
+ ThrowWin32Exception("EnumProcessModules");
+ }
+
+ HMODULE kernel32 = LocateModuleInRemoteProcess(targetProcess, L"\\kernel32.dll");
+ if (!kernel32) {
+ throw exception("Can't find kernel32.dll in the remote process.");
+ }
+ PVOID FreeLibraryAddress = LocateExportedFunctionInModule(kernel32, "FreeLibrary");
+ assert(FreeLibraryAddress != NULL);
+
+ HMODULE injectdllHandle = LocateModuleInRemoteProcess(targetProcess, injectdll);
+ if (injectdllHandle == NULL) {
+ throw exception("Can't find the injected dll in the remote process.");
+ }
+
+ HANDLE injectedThread;
+ DWORD injecteeThreadId;
+ injectedThread = CreateRemoteThread(targetProcess, NULL, 0, (LPTHREAD_START_ROUTINE)FreeLibraryAddress,
+ injectdllHandle, 0, &injecteeThreadId);
+ if (!injectedThread) {
+ ThrowWin32Exception("CreateRemoteThread");
+ }
+
+ if (WaitForSingleObject(injectedThread, INFINITE) == WAIT_FAILED) {
+ ThrowWin32Exception("WaitForSingleObject (remote thread)");
+ }
+ CloseHandle(injectedThread);
+}
\ No newline at end of file
diff --git a/TakeDetour/Detouring.h b/TakeDetour/Detouring.h
new file mode 100644
index 0000000..ba91920
--- /dev/null
+++ b/TakeDetour/Detouring.h
@@ -0,0 +1,12 @@
+#pragma once
+
+typedef struct {
+ PCCH FunctionName;
+ PVOID* FunctionAddress;
+} FunctionCharacteristics;
+
+void ThrowWin32Exception(const char *funcname);
+std::string ws2s(const std::wstring& wstr);
+HANDLE StartProcess(const std::string& injectdll, const std::wstring& exe, const std::wstring& args);
+HANDLE AttachToProcess(DWORD pid, const std::wstring& injectdll);
+void DetachFromProcess(HANDLE targetProcess, const std::wstring& injectdll);
diff --git a/TakeDetour/TakeDetour.cpp b/TakeDetour/TakeDetour.cpp
new file mode 100644
index 0000000..4065fde
Binary files /dev/null and b/TakeDetour/TakeDetour.cpp differ
diff --git a/TakeDetour/TakeDetour.rc b/TakeDetour/TakeDetour.rc
new file mode 100644
index 0000000..175f643
Binary files /dev/null and b/TakeDetour/TakeDetour.rc differ
diff --git a/TakeDetour/TakeDetour.vcxproj b/TakeDetour/TakeDetour.vcxproj
new file mode 100644
index 0000000..2dd7197
--- /dev/null
+++ b/TakeDetour/TakeDetour.vcxproj
@@ -0,0 +1,186 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 15.0
+ {275575D6-7FA1-42CB-9119-BCC3C548989A}
+ Win32Proj
+ TakeDetour
+ 10.0.17134.0
+
+
+
+ Application
+ true
+ v141
+ Unicode
+
+
+ Application
+ false
+ v141
+ true
+ Unicode
+
+
+ Application
+ true
+ v141
+ Unicode
+
+
+ Application
+ false
+ v141
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(SolutionDir)bin\
+
+
+ true
+ $(SolutionDir)bin.$(PlatformTarget)\
+
+
+ false
+ $(SolutionDir)bin.$(PlatformTarget)\
+
+
+ false
+ $(SolutionDir)bin.$(PlatformTarget)\
+
+
+
+ NotUsing
+ Level3
+ Disabled
+ true
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ MultiThreadedDebug
+
+
+ Console
+ true
+ $(SolutionDir)lib.$(PlatformTarget)\detours.lib;%(AdditionalDependencies)
+
+
+
+
+ NotUsing
+ Level3
+ Disabled
+ true
+ _DEBUG;_CONSOLE;%(PreprocessorDefinitions);_AMD64_
+ true
+
+
+
+
+ Console
+ true
+ $(SolutionDir)lib.$(PlatformTarget)\detours.lib;%(AdditionalDependencies)
+
+
+
+
+ NotUsing
+ Level3
+ MaxSpeed
+ true
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ MultiThreaded
+
+
+ Console
+ true
+ true
+ true
+ $(SolutionDir)lib.$(PlatformTarget)\detours.lib;%(AdditionalDependencies)
+
+
+
+
+ NotUsing
+ Level3
+ MaxSpeed
+ true
+ true
+ true
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions);_AMD64_
+ true
+
+
+
+
+ Console
+ true
+ true
+ true
+ $(SolutionDir)lib.$(PlatformTarget)\detours.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/TakeDetour/TakeDetour.vcxproj.filters b/TakeDetour/TakeDetour.vcxproj.filters
new file mode 100644
index 0000000..e575f13
--- /dev/null
+++ b/TakeDetour/TakeDetour.vcxproj.filters
@@ -0,0 +1,43 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;hm;inl;inc;ipp;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+
+
+ Resource Files
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/TakeDetour/resource.h b/TakeDetour/resource.h
new file mode 100644
index 0000000..fb44f76
--- /dev/null
+++ b/TakeDetour/resource.h
@@ -0,0 +1,18 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by TakeDetour.rc
+//
+#define IDR_BINARY2 102
+#define IDR_BINARY1 103
+#define IDR_BINARY3 104
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 106
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1001
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/TakeDetour64/TakeDetour.cpp b/TakeDetour64/TakeDetour.cpp
new file mode 100644
index 0000000..b919cb8
--- /dev/null
+++ b/TakeDetour64/TakeDetour.cpp
@@ -0,0 +1,87 @@
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "../TakeDetour/Detouring.h"
+
+#include "../include/detours.h"
+
+using namespace std;
+
+bool stopRequested = false;
+
+BOOL WINAPI HandleConsoleInterrupt(DWORD dwCtrlType);
+
+int32_t wmain(int32_t argc, wchar_t *argv[])
+{
+ assert(argc >= 2);
+
+ int argumentIndex = 1;
+ bool waitForTarget = false;
+ if (wcscmp(argv[1], L"-w") == 0) {
+ waitForTarget = true;
+ argumentIndex++;
+ }
+
+ DWORD pid = wcstoul(argv[argumentIndex], nullptr, 10);
+ // this version can only attach to a process
+ assert(pid != 0);
+ try {
+ wchar_t buffer[MAX_PATH];
+ DWORD len = GetModuleFileName(NULL, buffer, MAX_PATH);
+ // FIXME: if moduleNameLength == MAX_PATH there is chance the module name array was too small
+ if (len == 0) {
+ ThrowWin32Exception("GetModuleFileName");
+ }
+ wstring binaryPath = buffer;
+ auto separatorIndex = binaryPath.find_last_of(L"\\/");
+ assert(separatorIndex != string::npos);
+ if (separatorIndex == string::npos) {
+ throw exception("Bad entry binary path");
+ }
+ wstring injectdll = binaryPath.substr(0, separatorIndex) + L"\\InjectDll64.dll";
+ cout << "INFO: Attaching to the target process (" << pid << ")." << endl;
+ HANDLE targetProcess = AttachToProcess(pid, injectdll);
+
+ if (!SetConsoleCtrlHandler(HandleConsoleInterrupt, TRUE)) {
+ ThrowWin32Exception("SetConsoleCtrlHandler");
+ }
+ if (waitForTarget) {
+ cout << endl << "Press Ctrl + C to stop and unload the DLL from the target process." << endl;
+ while (!stopRequested) {
+ DWORD waitResult = WaitForSingleObject(targetProcess, 200);
+ if (waitResult == WAIT_OBJECT_0) {
+ cout << "INFO: Target process exited. Stopping." << endl;
+ break;
+ }
+ if (waitResult == WAIT_FAILED) {
+ ThrowWin32Exception("WaitForSingleObject");
+ }
+ }
+
+ DWORD exitCode;
+ if (stopRequested && GetExitCodeProcess(targetProcess, &exitCode) && exitCode == STILL_ACTIVE) {
+ DetachFromProcess(targetProcess, injectdll);
+ }
+ }
+ CloseHandle(targetProcess);
+ } catch (exception& ex) {
+ cerr << endl << "ERROR: " << ex.what() << endl;
+ return 1;
+ }
+
+ return 0;
+}
+
+BOOL WINAPI HandleConsoleInterrupt(DWORD dwCtrlType)
+{
+ cout << "INFO: Received Ctrl + C. Stopping." << endl;
+ stopRequested = true;
+ return TRUE;
+}
\ No newline at end of file
diff --git a/TakeDetour64/TakeDetour64.vcxproj b/TakeDetour64/TakeDetour64.vcxproj
new file mode 100644
index 0000000..9f1ebe2
--- /dev/null
+++ b/TakeDetour64/TakeDetour64.vcxproj
@@ -0,0 +1,174 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+
+
+
+
+ 15.0
+ {202EF952-2AF9-45D7-A7D2-CF08C16EAE1E}
+ Win32Proj
+ TakeDetour
+ 10.0.17134.0
+
+
+
+ Application
+ true
+ v141
+ Unicode
+
+
+ Application
+ false
+ v141
+ true
+ Unicode
+
+
+ Application
+ true
+ v141
+ Unicode
+
+
+ Application
+ false
+ v141
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(SolutionDir)bin.$(PlatformTarget)\
+
+
+ true
+ $(SolutionDir)bin\
+
+
+ false
+ $(SolutionDir)bin.$(PlatformTarget)\
+
+
+ false
+ $(SolutionDir)bin.$(PlatformTarget)\
+
+
+
+ NotUsing
+ Level3
+ Disabled
+ true
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+
+
+ Console
+ true
+ $(SolutionDir)lib.$(PlatformTarget)\detours.lib;%(AdditionalDependencies)
+
+
+
+
+ NotUsing
+ Level3
+ Disabled
+ true
+ _DEBUG;_CONSOLE;%(PreprocessorDefinitions);_AMD64_
+ true
+
+
+ MultiThreadedDebug
+
+
+ Console
+ true
+ $(SolutionDir)lib.$(PlatformTarget)\detours.lib;%(AdditionalDependencies)
+
+
+
+
+ NotUsing
+ Level3
+ MaxSpeed
+ true
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+
+
+ Console
+ true
+ true
+ true
+ $(SolutionDir)lib.$(PlatformTarget)\detours.lib;%(AdditionalDependencies)
+
+
+
+
+ NotUsing
+ Level3
+ MaxSpeed
+ true
+ true
+ true
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions);_AMD64_
+ true
+
+
+ MultiThreaded
+
+
+ Console
+ true
+ true
+ true
+ $(SolutionDir)lib.$(PlatformTarget)\detours.lib;%(AdditionalDependencies)
+
+
+
+
+
+
\ No newline at end of file
diff --git a/TakeDetour64/TakeDetour64.vcxproj.filters b/TakeDetour64/TakeDetour64.vcxproj.filters
new file mode 100644
index 0000000..0a37d01
--- /dev/null
+++ b/TakeDetour64/TakeDetour64.vcxproj.filters
@@ -0,0 +1,25 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;hm;inl;inc;ipp;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+
\ No newline at end of file
diff --git a/dbgview_output.png b/dbgview_output.png
new file mode 100644
index 0000000..aab388a
Binary files /dev/null and b/dbgview_output.png differ
diff --git a/include/detours.h b/include/detours.h
new file mode 100644
index 0000000..faff4fe
--- /dev/null
+++ b/include/detours.h
@@ -0,0 +1,1075 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// Core Detours Functionality (detours.h of detours.lib)
+//
+// Microsoft Research Detours Package, Version 4.0.1
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+
+#pragma once
+#ifndef _DETOURS_H_
+#define _DETOURS_H_
+
+#define DETOURS_VERSION 0x4c0c1 // 0xMAJORcMINORcPATCH
+
+//////////////////////////////////////////////////////////////////////////////
+//
+
+#undef DETOURS_X64
+#undef DETOURS_X86
+#undef DETOURS_IA64
+#undef DETOURS_ARM
+#undef DETOURS_ARM64
+#undef DETOURS_BITS
+#undef DETOURS_32BIT
+#undef DETOURS_64BIT
+
+#if defined(_X86_)
+#define DETOURS_X86
+#define DETOURS_OPTION_BITS 64
+
+#elif defined(_AMD64_)
+#define DETOURS_X64
+#define DETOURS_OPTION_BITS 32
+
+#elif defined(_IA64_)
+#define DETOURS_IA64
+#define DETOURS_OPTION_BITS 32
+
+#elif defined(_ARM_)
+#define DETOURS_ARM
+
+#elif defined(_ARM64_)
+#define DETOURS_ARM64
+
+#else
+#error Unknown architecture (x86, amd64, ia64, arm, arm64)
+#endif
+
+#ifdef _WIN64
+#undef DETOURS_32BIT
+#define DETOURS_64BIT 1
+#define DETOURS_BITS 64
+// If all 64bit kernels can run one and only one 32bit architecture.
+//#define DETOURS_OPTION_BITS 32
+#else
+#define DETOURS_32BIT 1
+#undef DETOURS_64BIT
+#define DETOURS_BITS 32
+// If all 64bit kernels can run one and only one 32bit architecture.
+//#define DETOURS_OPTION_BITS 32
+#endif
+
+#define VER_DETOURS_BITS DETOUR_STRINGIFY(DETOURS_BITS)
+
+//////////////////////////////////////////////////////////////////////////////
+//
+
+#if (_MSC_VER < 1299)
+typedef LONG LONG_PTR;
+typedef ULONG ULONG_PTR;
+#endif
+
+///////////////////////////////////////////////// SAL 2.0 Annotations w/o SAL.
+//
+// These definitions are include so that Detours will build even if the
+// compiler doesn't have full SAL 2.0 support.
+//
+#ifndef DETOURS_DONT_REMOVE_SAL_20
+
+#ifdef DETOURS_TEST_REMOVE_SAL_20
+#undef _Analysis_assume_
+#undef _Benign_race_begin_
+#undef _Benign_race_end_
+#undef _Field_range_
+#undef _Field_size_
+#undef _In_
+#undef _In_bytecount_
+#undef _In_count_
+#undef _In_opt_
+#undef _In_opt_bytecount_
+#undef _In_opt_count_
+#undef _In_opt_z_
+#undef _In_range_
+#undef _In_reads_
+#undef _In_reads_bytes_
+#undef _In_reads_opt_
+#undef _In_reads_opt_bytes_
+#undef _In_reads_or_z_
+#undef _In_z_
+#undef _Inout_
+#undef _Inout_opt_
+#undef _Inout_z_count_
+#undef _Out_
+#undef _Out_opt_
+#undef _Out_writes_
+#undef _Outptr_result_maybenull_
+#undef _Readable_bytes_
+#undef _Success_
+#undef _Writable_bytes_
+#undef _Pre_notnull_
+#endif
+
+#if defined(_Deref_out_opt_z_) && !defined(_Outptr_result_maybenull_)
+#define _Outptr_result_maybenull_ _Deref_out_opt_z_
+#endif
+
+#if defined(_In_count_) && !defined(_In_reads_)
+#define _In_reads_(x) _In_count_(x)
+#endif
+
+#if defined(_In_opt_count_) && !defined(_In_reads_opt_)
+#define _In_reads_opt_(x) _In_opt_count_(x)
+#endif
+
+#if defined(_In_opt_bytecount_) && !defined(_In_reads_opt_bytes_)
+#define _In_reads_opt_bytes_(x) _In_opt_bytecount_(x)
+#endif
+
+#if defined(_In_bytecount_) && !defined(_In_reads_bytes_)
+#define _In_reads_bytes_(x) _In_bytecount_(x)
+#endif
+
+#ifndef _In_
+#define _In_
+#endif
+
+#ifndef _In_bytecount_
+#define _In_bytecount_(x)
+#endif
+
+#ifndef _In_count_
+#define _In_count_(x)
+#endif
+
+#ifndef _In_opt_
+#define _In_opt_
+#endif
+
+#ifndef _In_opt_bytecount_
+#define _In_opt_bytecount_(x)
+#endif
+
+#ifndef _In_opt_count_
+#define _In_opt_count_(x)
+#endif
+
+#ifndef _In_opt_z_
+#define _In_opt_z_
+#endif
+
+#ifndef _In_range_
+#define _In_range_(x,y)
+#endif
+
+#ifndef _In_reads_
+#define _In_reads_(x)
+#endif
+
+#ifndef _In_reads_bytes_
+#define _In_reads_bytes_(x)
+#endif
+
+#ifndef _In_reads_opt_
+#define _In_reads_opt_(x)
+#endif
+
+#ifndef _In_reads_opt_bytes_
+#define _In_reads_opt_bytes_(x)
+#endif
+
+#ifndef _In_reads_or_z_
+#define _In_reads_or_z_
+#endif
+
+#ifndef _In_z_
+#define _In_z_
+#endif
+
+#ifndef _Inout_
+#define _Inout_
+#endif
+
+#ifndef _Inout_opt_
+#define _Inout_opt_
+#endif
+
+#ifndef _Inout_z_count_
+#define _Inout_z_count_(x)
+#endif
+
+#ifndef _Out_
+#define _Out_
+#endif
+
+#ifndef _Out_opt_
+#define _Out_opt_
+#endif
+
+#ifndef _Out_writes_
+#define _Out_writes_(x)
+#endif
+
+#ifndef _Outptr_result_maybenull_
+#define _Outptr_result_maybenull_
+#endif
+
+#ifndef _Writable_bytes_
+#define _Writable_bytes_(x)
+#endif
+
+#ifndef _Readable_bytes_
+#define _Readable_bytes_(x)
+#endif
+
+#ifndef _Success_
+#define _Success_(x)
+#endif
+
+#ifndef _Pre_notnull_
+#define _Pre_notnull_
+#endif
+
+#ifdef DETOURS_INTERNAL
+
+#pragma warning(disable:4615) // unknown warning type (suppress with older compilers)
+
+#ifndef _Benign_race_begin_
+#define _Benign_race_begin_
+#endif
+
+#ifndef _Benign_race_end_
+#define _Benign_race_end_
+#endif
+
+#ifndef _Field_size_
+#define _Field_size_(x)
+#endif
+
+#ifndef _Field_range_
+#define _Field_range_(x,y)
+#endif
+
+#ifndef _Analysis_assume_
+#define _Analysis_assume_(x)
+#endif
+
+#endif // DETOURS_INTERNAL
+#endif // DETOURS_DONT_REMOVE_SAL_20
+
+//////////////////////////////////////////////////////////////////////////////
+//
+#ifndef GUID_DEFINED
+#define GUID_DEFINED
+typedef struct _GUID
+{
+ DWORD Data1;
+ WORD Data2;
+ WORD Data3;
+ BYTE Data4[ 8 ];
+} GUID;
+
+#ifdef INITGUID
+#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
+ const GUID name \
+ = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
+#else
+#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
+ const GUID name
+#endif // INITGUID
+#endif // !GUID_DEFINED
+
+#if defined(__cplusplus)
+#ifndef _REFGUID_DEFINED
+#define _REFGUID_DEFINED
+#define REFGUID const GUID &
+#endif // !_REFGUID_DEFINED
+#else // !__cplusplus
+#ifndef _REFGUID_DEFINED
+#define _REFGUID_DEFINED
+#define REFGUID const GUID * const
+#endif // !_REFGUID_DEFINED
+#endif // !__cplusplus
+
+#ifndef ARRAYSIZE
+#define ARRAYSIZE(x) (sizeof(x)/sizeof(x[0]))
+#endif
+
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+/////////////////////////////////////////////////// Instruction Target Macros.
+//
+#define DETOUR_INSTRUCTION_TARGET_NONE ((PVOID)0)
+#define DETOUR_INSTRUCTION_TARGET_DYNAMIC ((PVOID)(LONG_PTR)-1)
+#define DETOUR_SECTION_HEADER_SIGNATURE 0x00727444 // "Dtr\0"
+
+extern const GUID DETOUR_EXE_RESTORE_GUID;
+extern const GUID DETOUR_EXE_HELPER_GUID;
+
+#define DETOUR_TRAMPOLINE_SIGNATURE 0x21727444 // Dtr!
+typedef struct _DETOUR_TRAMPOLINE DETOUR_TRAMPOLINE, *PDETOUR_TRAMPOLINE;
+
+/////////////////////////////////////////////////////////// Binary Structures.
+//
+#pragma pack(push, 8)
+typedef struct _DETOUR_SECTION_HEADER
+{
+ DWORD cbHeaderSize;
+ DWORD nSignature;
+ DWORD nDataOffset;
+ DWORD cbDataSize;
+
+ DWORD nOriginalImportVirtualAddress;
+ DWORD nOriginalImportSize;
+ DWORD nOriginalBoundImportVirtualAddress;
+ DWORD nOriginalBoundImportSize;
+
+ DWORD nOriginalIatVirtualAddress;
+ DWORD nOriginalIatSize;
+ DWORD nOriginalSizeOfImage;
+ DWORD cbPrePE;
+
+ DWORD nOriginalClrFlags;
+ DWORD reserved1;
+ DWORD reserved2;
+ DWORD reserved3;
+
+ // Followed by cbPrePE bytes of data.
+} DETOUR_SECTION_HEADER, *PDETOUR_SECTION_HEADER;
+
+typedef struct _DETOUR_SECTION_RECORD
+{
+ DWORD cbBytes;
+ DWORD nReserved;
+ GUID guid;
+} DETOUR_SECTION_RECORD, *PDETOUR_SECTION_RECORD;
+
+typedef struct _DETOUR_CLR_HEADER
+{
+ // Header versioning
+ ULONG cb;
+ USHORT MajorRuntimeVersion;
+ USHORT MinorRuntimeVersion;
+
+ // Symbol table and startup information
+ IMAGE_DATA_DIRECTORY MetaData;
+ ULONG Flags;
+
+ // Followed by the rest of the IMAGE_COR20_HEADER
+} DETOUR_CLR_HEADER, *PDETOUR_CLR_HEADER;
+
+typedef struct _DETOUR_EXE_RESTORE
+{
+ DWORD cb;
+ DWORD cbidh;
+ DWORD cbinh;
+ DWORD cbclr;
+
+ PBYTE pidh;
+ PBYTE pinh;
+ PBYTE pclr;
+
+ IMAGE_DOS_HEADER idh;
+ union {
+ IMAGE_NT_HEADERS inh; // all environments have this
+#ifdef IMAGE_NT_OPTIONAL_HDR32_MAGIC // some environments do not have this
+ IMAGE_NT_HEADERS32 inh32;
+#endif
+#ifdef IMAGE_NT_OPTIONAL_HDR64_MAGIC // some environments do not have this
+ IMAGE_NT_HEADERS64 inh64;
+#endif
+#ifdef IMAGE_NT_OPTIONAL_HDR64_MAGIC // some environments do not have this
+ BYTE raw[sizeof(IMAGE_NT_HEADERS64) +
+ sizeof(IMAGE_SECTION_HEADER) * 32];
+ C_ASSERT(sizeof(IMAGE_NT_HEADERS64) == 0x108);
+#else
+ BYTE raw[0x108 + sizeof(IMAGE_SECTION_HEADER) * 32];
+#endif
+ };
+ DETOUR_CLR_HEADER clr;
+
+} DETOUR_EXE_RESTORE, *PDETOUR_EXE_RESTORE;
+
+// The size can change, but assert for clarity due to the muddying #ifdefs.
+#ifdef _WIN64
+C_ASSERT(sizeof(DETOUR_EXE_RESTORE) == 0x688);
+#else
+C_ASSERT(sizeof(DETOUR_EXE_RESTORE) == 0x678);
+#endif
+
+typedef struct _DETOUR_EXE_HELPER
+{
+ DWORD cb;
+ DWORD pid;
+ DWORD nDlls;
+ CHAR rDlls[4];
+} DETOUR_EXE_HELPER, *PDETOUR_EXE_HELPER;
+
+#pragma pack(pop)
+
+#define DETOUR_SECTION_HEADER_DECLARE(cbSectionSize) \
+{ \
+ sizeof(DETOUR_SECTION_HEADER),\
+ DETOUR_SECTION_HEADER_SIGNATURE,\
+ sizeof(DETOUR_SECTION_HEADER),\
+ (cbSectionSize),\
+ \
+ 0,\
+ 0,\
+ 0,\
+ 0,\
+ \
+ 0,\
+ 0,\
+ 0,\
+ 0,\
+}
+
+/////////////////////////////////////////////////////////////// Helper Macros.
+//
+#define DETOURS_STRINGIFY(x) DETOURS_STRINGIFY_(x)
+#define DETOURS_STRINGIFY_(x) #x
+
+///////////////////////////////////////////////////////////// Binary Typedefs.
+//
+typedef BOOL (CALLBACK *PF_DETOUR_BINARY_BYWAY_CALLBACK)(
+ _In_opt_ PVOID pContext,
+ _In_opt_ LPCSTR pszFile,
+ _Outptr_result_maybenull_ LPCSTR *ppszOutFile);
+
+typedef BOOL (CALLBACK *PF_DETOUR_BINARY_FILE_CALLBACK)(
+ _In_opt_ PVOID pContext,
+ _In_ LPCSTR pszOrigFile,
+ _In_ LPCSTR pszFile,
+ _Outptr_result_maybenull_ LPCSTR *ppszOutFile);
+
+typedef BOOL (CALLBACK *PF_DETOUR_BINARY_SYMBOL_CALLBACK)(
+ _In_opt_ PVOID pContext,
+ _In_ ULONG nOrigOrdinal,
+ _In_ ULONG nOrdinal,
+ _Out_ ULONG *pnOutOrdinal,
+ _In_opt_ LPCSTR pszOrigSymbol,
+ _In_opt_ LPCSTR pszSymbol,
+ _Outptr_result_maybenull_ LPCSTR *ppszOutSymbol);
+
+typedef BOOL (CALLBACK *PF_DETOUR_BINARY_COMMIT_CALLBACK)(
+ _In_opt_ PVOID pContext);
+
+typedef BOOL (CALLBACK *PF_DETOUR_ENUMERATE_EXPORT_CALLBACK)(_In_opt_ PVOID pContext,
+ _In_ ULONG nOrdinal,
+ _In_opt_ LPCSTR pszName,
+ _In_opt_ PVOID pCode);
+
+typedef BOOL (CALLBACK *PF_DETOUR_IMPORT_FILE_CALLBACK)(_In_opt_ PVOID pContext,
+ _In_opt_ HMODULE hModule,
+ _In_opt_ LPCSTR pszFile);
+
+typedef BOOL (CALLBACK *PF_DETOUR_IMPORT_FUNC_CALLBACK)(_In_opt_ PVOID pContext,
+ _In_ DWORD nOrdinal,
+ _In_opt_ LPCSTR pszFunc,
+ _In_opt_ PVOID pvFunc);
+
+// Same as PF_DETOUR_IMPORT_FUNC_CALLBACK but extra indirection on last parameter.
+typedef BOOL (CALLBACK *PF_DETOUR_IMPORT_FUNC_CALLBACK_EX)(_In_opt_ PVOID pContext,
+ _In_ DWORD nOrdinal,
+ _In_opt_ LPCSTR pszFunc,
+ _In_opt_ PVOID* ppvFunc);
+
+typedef VOID * PDETOUR_BINARY;
+typedef VOID * PDETOUR_LOADED_BINARY;
+
+//////////////////////////////////////////////////////////// Transaction APIs.
+//
+LONG WINAPI DetourTransactionBegin(VOID);
+LONG WINAPI DetourTransactionAbort(VOID);
+LONG WINAPI DetourTransactionCommit(VOID);
+LONG WINAPI DetourTransactionCommitEx(_Out_opt_ PVOID **pppFailedPointer);
+
+LONG WINAPI DetourUpdateThread(_In_ HANDLE hThread);
+
+LONG WINAPI DetourAttach(_Inout_ PVOID *ppPointer,
+ _In_ PVOID pDetour);
+
+LONG WINAPI DetourAttachEx(_Inout_ PVOID *ppPointer,
+ _In_ PVOID pDetour,
+ _Out_opt_ PDETOUR_TRAMPOLINE *ppRealTrampoline,
+ _Out_opt_ PVOID *ppRealTarget,
+ _Out_opt_ PVOID *ppRealDetour);
+
+LONG WINAPI DetourDetach(_Inout_ PVOID *ppPointer,
+ _In_ PVOID pDetour);
+
+BOOL WINAPI DetourSetIgnoreTooSmall(_In_ BOOL fIgnore);
+BOOL WINAPI DetourSetRetainRegions(_In_ BOOL fRetain);
+PVOID WINAPI DetourSetSystemRegionLowerBound(_In_ PVOID pSystemRegionLowerBound);
+PVOID WINAPI DetourSetSystemRegionUpperBound(_In_ PVOID pSystemRegionUpperBound);
+
+////////////////////////////////////////////////////////////// Code Functions.
+//
+PVOID WINAPI DetourFindFunction(_In_ LPCSTR pszModule,
+ _In_ LPCSTR pszFunction);
+PVOID WINAPI DetourCodeFromPointer(_In_ PVOID pPointer,
+ _Out_opt_ PVOID *ppGlobals);
+PVOID WINAPI DetourCopyInstruction(_In_opt_ PVOID pDst,
+ _Inout_opt_ PVOID *ppDstPool,
+ _In_ PVOID pSrc,
+ _Out_opt_ PVOID *ppTarget,
+ _Out_opt_ LONG *plExtra);
+BOOL WINAPI DetourSetCodeModule(_In_ HMODULE hModule,
+ _In_ BOOL fLimitReferencesToModule);
+
+///////////////////////////////////////////////////// Loaded Binary Functions.
+//
+HMODULE WINAPI DetourGetContainingModule(_In_ PVOID pvAddr);
+HMODULE WINAPI DetourEnumerateModules(_In_opt_ HMODULE hModuleLast);
+PVOID WINAPI DetourGetEntryPoint(_In_opt_ HMODULE hModule);
+ULONG WINAPI DetourGetModuleSize(_In_opt_ HMODULE hModule);
+BOOL WINAPI DetourEnumerateExports(_In_ HMODULE hModule,
+ _In_opt_ PVOID pContext,
+ _In_ PF_DETOUR_ENUMERATE_EXPORT_CALLBACK pfExport);
+BOOL WINAPI DetourEnumerateImports(_In_opt_ HMODULE hModule,
+ _In_opt_ PVOID pContext,
+ _In_opt_ PF_DETOUR_IMPORT_FILE_CALLBACK pfImportFile,
+ _In_opt_ PF_DETOUR_IMPORT_FUNC_CALLBACK pfImportFunc);
+
+BOOL WINAPI DetourEnumerateImportsEx(_In_opt_ HMODULE hModule,
+ _In_opt_ PVOID pContext,
+ _In_opt_ PF_DETOUR_IMPORT_FILE_CALLBACK pfImportFile,
+ _In_opt_ PF_DETOUR_IMPORT_FUNC_CALLBACK_EX pfImportFuncEx);
+
+_Writable_bytes_(*pcbData)
+_Readable_bytes_(*pcbData)
+_Success_(return != NULL)
+PVOID WINAPI DetourFindPayload(_In_opt_ HMODULE hModule,
+ _In_ REFGUID rguid,
+ _Out_ DWORD *pcbData);
+
+_Writable_bytes_(*pcbData)
+_Readable_bytes_(*pcbData)
+_Success_(return != NULL)
+PVOID WINAPI DetourFindPayloadEx(_In_ REFGUID rguid,
+ _Out_ DWORD * pcbData);
+
+DWORD WINAPI DetourGetSizeOfPayloads(_In_opt_ HMODULE hModule);
+
+///////////////////////////////////////////////// Persistent Binary Functions.
+//
+
+PDETOUR_BINARY WINAPI DetourBinaryOpen(_In_ HANDLE hFile);
+
+_Writable_bytes_(*pcbData)
+_Readable_bytes_(*pcbData)
+_Success_(return != NULL)
+PVOID WINAPI DetourBinaryEnumeratePayloads(_In_ PDETOUR_BINARY pBinary,
+ _Out_opt_ GUID *pGuid,
+ _Out_ DWORD *pcbData,
+ _Inout_ DWORD *pnIterator);
+
+_Writable_bytes_(*pcbData)
+_Readable_bytes_(*pcbData)
+_Success_(return != NULL)
+PVOID WINAPI DetourBinaryFindPayload(_In_ PDETOUR_BINARY pBinary,
+ _In_ REFGUID rguid,
+ _Out_ DWORD *pcbData);
+
+PVOID WINAPI DetourBinarySetPayload(_In_ PDETOUR_BINARY pBinary,
+ _In_ REFGUID rguid,
+ _In_reads_opt_(cbData) PVOID pData,
+ _In_ DWORD cbData);
+BOOL WINAPI DetourBinaryDeletePayload(_In_ PDETOUR_BINARY pBinary, _In_ REFGUID rguid);
+BOOL WINAPI DetourBinaryPurgePayloads(_In_ PDETOUR_BINARY pBinary);
+BOOL WINAPI DetourBinaryResetImports(_In_ PDETOUR_BINARY pBinary);
+BOOL WINAPI DetourBinaryEditImports(_In_ PDETOUR_BINARY pBinary,
+ _In_opt_ PVOID pContext,
+ _In_opt_ PF_DETOUR_BINARY_BYWAY_CALLBACK pfByway,
+ _In_opt_ PF_DETOUR_BINARY_FILE_CALLBACK pfFile,
+ _In_opt_ PF_DETOUR_BINARY_SYMBOL_CALLBACK pfSymbol,
+ _In_opt_ PF_DETOUR_BINARY_COMMIT_CALLBACK pfCommit);
+BOOL WINAPI DetourBinaryWrite(_In_ PDETOUR_BINARY pBinary, _In_ HANDLE hFile);
+BOOL WINAPI DetourBinaryClose(_In_ PDETOUR_BINARY pBinary);
+
+/////////////////////////////////////////////////// Create Process & Load Dll.
+//
+typedef BOOL (WINAPI *PDETOUR_CREATE_PROCESS_ROUTINEA)(
+ _In_opt_ LPCSTR lpApplicationName,
+ _Inout_opt_ LPSTR lpCommandLine,
+ _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
+ _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
+ _In_ BOOL bInheritHandles,
+ _In_ DWORD dwCreationFlags,
+ _In_opt_ LPVOID lpEnvironment,
+ _In_opt_ LPCSTR lpCurrentDirectory,
+ _In_ LPSTARTUPINFOA lpStartupInfo,
+ _Out_ LPPROCESS_INFORMATION lpProcessInformation);
+
+typedef BOOL (WINAPI *PDETOUR_CREATE_PROCESS_ROUTINEW)(
+ _In_opt_ LPCWSTR lpApplicationName,
+ _Inout_opt_ LPWSTR lpCommandLine,
+ _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
+ _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
+ _In_ BOOL bInheritHandles,
+ _In_ DWORD dwCreationFlags,
+ _In_opt_ LPVOID lpEnvironment,
+ _In_opt_ LPCWSTR lpCurrentDirectory,
+ _In_ LPSTARTUPINFOW lpStartupInfo,
+ _Out_ LPPROCESS_INFORMATION lpProcessInformation);
+
+BOOL WINAPI DetourCreateProcessWithDllA(_In_opt_ LPCSTR lpApplicationName,
+ _Inout_opt_ LPSTR lpCommandLine,
+ _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
+ _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
+ _In_ BOOL bInheritHandles,
+ _In_ DWORD dwCreationFlags,
+ _In_opt_ LPVOID lpEnvironment,
+ _In_opt_ LPCSTR lpCurrentDirectory,
+ _In_ LPSTARTUPINFOA lpStartupInfo,
+ _Out_ LPPROCESS_INFORMATION lpProcessInformation,
+ _In_ LPCSTR lpDllName,
+ _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA);
+
+BOOL WINAPI DetourCreateProcessWithDllW(_In_opt_ LPCWSTR lpApplicationName,
+ _Inout_opt_ LPWSTR lpCommandLine,
+ _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
+ _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
+ _In_ BOOL bInheritHandles,
+ _In_ DWORD dwCreationFlags,
+ _In_opt_ LPVOID lpEnvironment,
+ _In_opt_ LPCWSTR lpCurrentDirectory,
+ _In_ LPSTARTUPINFOW lpStartupInfo,
+ _Out_ LPPROCESS_INFORMATION lpProcessInformation,
+ _In_ LPCSTR lpDllName,
+ _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW);
+
+#ifdef UNICODE
+#define DetourCreateProcessWithDll DetourCreateProcessWithDllW
+#define PDETOUR_CREATE_PROCESS_ROUTINE PDETOUR_CREATE_PROCESS_ROUTINEW
+#else
+#define DetourCreateProcessWithDll DetourCreateProcessWithDllA
+#define PDETOUR_CREATE_PROCESS_ROUTINE PDETOUR_CREATE_PROCESS_ROUTINEA
+#endif // !UNICODE
+
+BOOL WINAPI DetourCreateProcessWithDllExA(_In_opt_ LPCSTR lpApplicationName,
+ _Inout_opt_ LPSTR lpCommandLine,
+ _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
+ _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
+ _In_ BOOL bInheritHandles,
+ _In_ DWORD dwCreationFlags,
+ _In_opt_ LPVOID lpEnvironment,
+ _In_opt_ LPCSTR lpCurrentDirectory,
+ _In_ LPSTARTUPINFOA lpStartupInfo,
+ _Out_ LPPROCESS_INFORMATION lpProcessInformation,
+ _In_ LPCSTR lpDllName,
+ _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA);
+
+BOOL WINAPI DetourCreateProcessWithDllExW(_In_opt_ LPCWSTR lpApplicationName,
+ _Inout_opt_ LPWSTR lpCommandLine,
+ _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
+ _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
+ _In_ BOOL bInheritHandles,
+ _In_ DWORD dwCreationFlags,
+ _In_opt_ LPVOID lpEnvironment,
+ _In_opt_ LPCWSTR lpCurrentDirectory,
+ _In_ LPSTARTUPINFOW lpStartupInfo,
+ _Out_ LPPROCESS_INFORMATION lpProcessInformation,
+ _In_ LPCSTR lpDllName,
+ _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW);
+
+#ifdef UNICODE
+#define DetourCreateProcessWithDllEx DetourCreateProcessWithDllExW
+#else
+#define DetourCreateProcessWithDllEx DetourCreateProcessWithDllExA
+#endif // !UNICODE
+
+BOOL WINAPI DetourCreateProcessWithDllsA(_In_opt_ LPCSTR lpApplicationName,
+ _Inout_opt_ LPSTR lpCommandLine,
+ _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
+ _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
+ _In_ BOOL bInheritHandles,
+ _In_ DWORD dwCreationFlags,
+ _In_opt_ LPVOID lpEnvironment,
+ _In_opt_ LPCSTR lpCurrentDirectory,
+ _In_ LPSTARTUPINFOA lpStartupInfo,
+ _Out_ LPPROCESS_INFORMATION lpProcessInformation,
+ _In_ DWORD nDlls,
+ _In_reads_(nDlls) LPCSTR *rlpDlls,
+ _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA);
+
+BOOL WINAPI DetourCreateProcessWithDllsW(_In_opt_ LPCWSTR lpApplicationName,
+ _Inout_opt_ LPWSTR lpCommandLine,
+ _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
+ _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
+ _In_ BOOL bInheritHandles,
+ _In_ DWORD dwCreationFlags,
+ _In_opt_ LPVOID lpEnvironment,
+ _In_opt_ LPCWSTR lpCurrentDirectory,
+ _In_ LPSTARTUPINFOW lpStartupInfo,
+ _Out_ LPPROCESS_INFORMATION lpProcessInformation,
+ _In_ DWORD nDlls,
+ _In_reads_(nDlls) LPCSTR *rlpDlls,
+ _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW);
+
+#ifdef UNICODE
+#define DetourCreateProcessWithDlls DetourCreateProcessWithDllsW
+#else
+#define DetourCreateProcessWithDlls DetourCreateProcessWithDllsA
+#endif // !UNICODE
+
+BOOL WINAPI DetourProcessViaHelperA(_In_ DWORD dwTargetPid,
+ _In_ LPCSTR lpDllName,
+ _In_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA);
+
+BOOL WINAPI DetourProcessViaHelperW(_In_ DWORD dwTargetPid,
+ _In_ LPCSTR lpDllName,
+ _In_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW);
+
+#ifdef UNICODE
+#define DetourProcessViaHelper DetourProcessViaHelperW
+#else
+#define DetourProcessViaHelper DetourProcessViaHelperA
+#endif // !UNICODE
+
+BOOL WINAPI DetourProcessViaHelperDllsA(_In_ DWORD dwTargetPid,
+ _In_ DWORD nDlls,
+ _In_reads_(nDlls) LPCSTR *rlpDlls,
+ _In_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA);
+
+BOOL WINAPI DetourProcessViaHelperDllsW(_In_ DWORD dwTargetPid,
+ _In_ DWORD nDlls,
+ _In_reads_(nDlls) LPCSTR *rlpDlls,
+ _In_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW);
+
+#ifdef UNICODE
+#define DetourProcessViaHelperDlls DetourProcessViaHelperDllsW
+#else
+#define DetourProcessViaHelperDlls DetourProcessViaHelperDllsA
+#endif // !UNICODE
+
+BOOL WINAPI DetourUpdateProcessWithDll(_In_ HANDLE hProcess,
+ _In_reads_(nDlls) LPCSTR *rlpDlls,
+ _In_ DWORD nDlls);
+
+BOOL WINAPI DetourUpdateProcessWithDllEx(_In_ HANDLE hProcess,
+ _In_ HMODULE hImage,
+ _In_ BOOL bIs32Bit,
+ _In_reads_(nDlls) LPCSTR *rlpDlls,
+ _In_ DWORD nDlls);
+
+BOOL WINAPI DetourCopyPayloadToProcess(_In_ HANDLE hProcess,
+ _In_ REFGUID rguid,
+ _In_reads_bytes_(cbData) PVOID pvData,
+ _In_ DWORD cbData);
+BOOL WINAPI DetourRestoreAfterWith(VOID);
+BOOL WINAPI DetourRestoreAfterWithEx(_In_reads_bytes_(cbData) PVOID pvData,
+ _In_ DWORD cbData);
+BOOL WINAPI DetourIsHelperProcess(VOID);
+VOID CALLBACK DetourFinishHelperProcess(_In_ HWND,
+ _In_ HINSTANCE,
+ _In_ LPSTR,
+ _In_ INT);
+
+//
+//////////////////////////////////////////////////////////////////////////////
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+//////////////////////////////////////////////// Detours Internal Definitions.
+//
+#ifdef __cplusplus
+#ifdef DETOURS_INTERNAL
+
+#define NOTHROW
+// #define NOTHROW (nothrow)
+
+//////////////////////////////////////////////////////////////////////////////
+//
+#if (_MSC_VER < 1299)
+#include
+typedef IMAGEHLP_MODULE IMAGEHLP_MODULE64;
+typedef PIMAGEHLP_MODULE PIMAGEHLP_MODULE64;
+typedef IMAGEHLP_SYMBOL SYMBOL_INFO;
+typedef PIMAGEHLP_SYMBOL PSYMBOL_INFO;
+
+static inline
+LONG InterlockedCompareExchange(_Inout_ LONG *ptr, _In_ LONG nval, _In_ LONG oval)
+{
+ return (LONG)::InterlockedCompareExchange((PVOID*)ptr, (PVOID)nval, (PVOID)oval);
+}
+#else
+#pragma warning(push)
+#pragma warning(disable:4091) // empty typedef
+#include
+#pragma warning(pop)
+#endif
+
+#ifdef IMAGEAPI // defined by DBGHELP.H
+typedef LPAPI_VERSION (NTAPI *PF_ImagehlpApiVersionEx)(_In_ LPAPI_VERSION AppVersion);
+
+typedef BOOL (NTAPI *PF_SymInitialize)(_In_ HANDLE hProcess,
+ _In_opt_ LPCSTR UserSearchPath,
+ _In_ BOOL fInvadeProcess);
+typedef DWORD (NTAPI *PF_SymSetOptions)(_In_ DWORD SymOptions);
+typedef DWORD (NTAPI *PF_SymGetOptions)(VOID);
+typedef DWORD64 (NTAPI *PF_SymLoadModule64)(_In_ HANDLE hProcess,
+ _In_opt_ HANDLE hFile,
+ _In_ LPSTR ImageName,
+ _In_opt_ LPSTR ModuleName,
+ _In_ DWORD64 BaseOfDll,
+ _In_opt_ DWORD SizeOfDll);
+typedef BOOL (NTAPI *PF_SymGetModuleInfo64)(_In_ HANDLE hProcess,
+ _In_ DWORD64 qwAddr,
+ _Out_ PIMAGEHLP_MODULE64 ModuleInfo);
+typedef BOOL (NTAPI *PF_SymFromName)(_In_ HANDLE hProcess,
+ _In_ LPSTR Name,
+ _Out_ PSYMBOL_INFO Symbol);
+
+typedef struct _DETOUR_SYM_INFO
+{
+ HANDLE hProcess;
+ HMODULE hDbgHelp;
+ PF_ImagehlpApiVersionEx pfImagehlpApiVersionEx;
+ PF_SymInitialize pfSymInitialize;
+ PF_SymSetOptions pfSymSetOptions;
+ PF_SymGetOptions pfSymGetOptions;
+ PF_SymLoadModule64 pfSymLoadModule64;
+ PF_SymGetModuleInfo64 pfSymGetModuleInfo64;
+ PF_SymFromName pfSymFromName;
+} DETOUR_SYM_INFO, *PDETOUR_SYM_INFO;
+
+PDETOUR_SYM_INFO DetourLoadImageHlp(VOID);
+
+#endif // IMAGEAPI
+
+#if defined(_INC_STDIO) && !defined(_CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS)
+#error detours.h must be included before stdio.h (or at least define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS earlier)
+#endif
+#define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS 1
+
+#ifndef DETOUR_TRACE
+#if DETOUR_DEBUG
+#define DETOUR_TRACE(x) printf x
+#define DETOUR_BREAK() __debugbreak()
+#include
+#include
+#else
+#define DETOUR_TRACE(x)
+#define DETOUR_BREAK()
+#endif
+#endif
+
+#if 1 || defined(DETOURS_IA64)
+
+//
+// IA64 instructions are 41 bits, 3 per bundle, plus 5 bit bundle template => 128 bits per bundle.
+//
+
+#define DETOUR_IA64_INSTRUCTIONS_PER_BUNDLE (3)
+
+#define DETOUR_IA64_TEMPLATE_OFFSET (0)
+#define DETOUR_IA64_TEMPLATE_SIZE (5)
+
+#define DETOUR_IA64_INSTRUCTION_SIZE (41)
+#define DETOUR_IA64_INSTRUCTION0_OFFSET (DETOUR_IA64_TEMPLATE_SIZE)
+#define DETOUR_IA64_INSTRUCTION1_OFFSET (DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTION_SIZE)
+#define DETOUR_IA64_INSTRUCTION2_OFFSET (DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTION_SIZE + DETOUR_IA64_INSTRUCTION_SIZE)
+
+C_ASSERT(DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTIONS_PER_BUNDLE * DETOUR_IA64_INSTRUCTION_SIZE == 128);
+
+__declspec(align(16)) struct DETOUR_IA64_BUNDLE
+{
+ public:
+ union
+ {
+ BYTE data[16];
+ UINT64 wide[2];
+ };
+
+ enum {
+ A_UNIT = 1u,
+ I_UNIT = 2u,
+ M_UNIT = 3u,
+ B_UNIT = 4u,
+ F_UNIT = 5u,
+ L_UNIT = 6u,
+ X_UNIT = 7u,
+ };
+ struct DETOUR_IA64_METADATA
+ {
+ ULONG nTemplate : 8; // Instruction template.
+ ULONG nUnit0 : 4; // Unit for slot 0
+ ULONG nUnit1 : 4; // Unit for slot 1
+ ULONG nUnit2 : 4; // Unit for slot 2
+ };
+
+ protected:
+ static const DETOUR_IA64_METADATA s_rceCopyTable[33];
+
+ UINT RelocateBundle(_Inout_ DETOUR_IA64_BUNDLE* pDst, _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra) const;
+
+ bool RelocateInstruction(_Inout_ DETOUR_IA64_BUNDLE* pDst,
+ _In_ BYTE slot,
+ _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra) const;
+
+ // 120 112 104 96 88 80 72 64 56 48 40 32 24 16 8 0
+ // f. e. d. c. b. a. 9. 8. 7. 6. 5. 4. 3. 2. 1. 0.
+
+ // 00
+ // f.e. d.c. b.a. 9.8. 7.6. 5.4. 3.2. 1.0.
+ // 0000 0000 0000 0000 0000 0000 0000 001f : Template [4..0]
+ // 0000 0000 0000 0000 0000 03ff ffff ffe0 : Zero [ 41.. 5]
+ // 0000 0000 0000 0000 0000 3c00 0000 0000 : Zero [ 45.. 42]
+ // 0000 0000 0007 ffff ffff c000 0000 0000 : One [ 82.. 46]
+ // 0000 0000 0078 0000 0000 0000 0000 0000 : One [ 86.. 83]
+ // 0fff ffff ff80 0000 0000 0000 0000 0000 : Two [123.. 87]
+ // f000 0000 0000 0000 0000 0000 0000 0000 : Two [127..124]
+ BYTE GetTemplate() const;
+ // Get 4 bit opcodes.
+ BYTE GetInst0() const;
+ BYTE GetInst1() const;
+ BYTE GetInst2() const;
+ BYTE GetUnit(BYTE slot) const;
+ BYTE GetUnit0() const;
+ BYTE GetUnit1() const;
+ BYTE GetUnit2() const;
+ // Get 37 bit data.
+ UINT64 GetData0() const;
+ UINT64 GetData1() const;
+ UINT64 GetData2() const;
+
+ // Get/set the full 41 bit instructions.
+ UINT64 GetInstruction(BYTE slot) const;
+ UINT64 GetInstruction0() const;
+ UINT64 GetInstruction1() const;
+ UINT64 GetInstruction2() const;
+ void SetInstruction(BYTE slot, UINT64 instruction);
+ void SetInstruction0(UINT64 instruction);
+ void SetInstruction1(UINT64 instruction);
+ void SetInstruction2(UINT64 instruction);
+
+ // Get/set bitfields.
+ static UINT64 GetBits(UINT64 Value, UINT64 Offset, UINT64 Count);
+ static UINT64 SetBits(UINT64 Value, UINT64 Offset, UINT64 Count, UINT64 Field);
+
+ // Get specific read-only fields.
+ static UINT64 GetOpcode(UINT64 instruction); // 4bit opcode
+ static UINT64 GetX(UINT64 instruction); // 1bit opcode extension
+ static UINT64 GetX3(UINT64 instruction); // 3bit opcode extension
+ static UINT64 GetX6(UINT64 instruction); // 6bit opcode extension
+
+ // Get/set specific fields.
+ static UINT64 GetImm7a(UINT64 instruction);
+ static UINT64 SetImm7a(UINT64 instruction, UINT64 imm7a);
+ static UINT64 GetImm13c(UINT64 instruction);
+ static UINT64 SetImm13c(UINT64 instruction, UINT64 imm13c);
+ static UINT64 GetSignBit(UINT64 instruction);
+ static UINT64 SetSignBit(UINT64 instruction, UINT64 signBit);
+ static UINT64 GetImm20a(UINT64 instruction);
+ static UINT64 SetImm20a(UINT64 instruction, UINT64 imm20a);
+ static UINT64 GetImm20b(UINT64 instruction);
+ static UINT64 SetImm20b(UINT64 instruction, UINT64 imm20b);
+
+ static UINT64 SignExtend(UINT64 Value, UINT64 Offset);
+
+ BOOL IsMovlGp() const;
+
+ VOID SetInst(BYTE Slot, BYTE nInst);
+ VOID SetInst0(BYTE nInst);
+ VOID SetInst1(BYTE nInst);
+ VOID SetInst2(BYTE nInst);
+ VOID SetData(BYTE Slot, UINT64 nData);
+ VOID SetData0(UINT64 nData);
+ VOID SetData1(UINT64 nData);
+ VOID SetData2(UINT64 nData);
+ BOOL SetNop(BYTE Slot);
+ BOOL SetNop0();
+ BOOL SetNop1();
+ BOOL SetNop2();
+
+ public:
+ BOOL IsBrl() const;
+ VOID SetBrl();
+ VOID SetBrl(UINT64 target);
+ UINT64 GetBrlTarget() const;
+ VOID SetBrlTarget(UINT64 target);
+ VOID SetBrlImm(UINT64 imm);
+ UINT64 GetBrlImm() const;
+
+ UINT64 GetMovlGp() const;
+ VOID SetMovlGp(UINT64 gp);
+
+ VOID SetStop();
+
+ UINT Copy(_Out_ DETOUR_IA64_BUNDLE *pDst, _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra = NULL) const;
+};
+#endif // DETOURS_IA64
+
+#ifdef DETOURS_ARM
+
+#define DETOURS_PFUNC_TO_PBYTE(p) ((PBYTE)(((ULONG_PTR)(p)) & ~(ULONG_PTR)1))
+#define DETOURS_PBYTE_TO_PFUNC(p) ((PBYTE)(((ULONG_PTR)(p)) | (ULONG_PTR)1))
+
+#endif // DETOURS_ARM
+
+//////////////////////////////////////////////////////////////////////////////
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+#define DETOUR_OFFLINE_LIBRARY(x) \
+PVOID WINAPI DetourCopyInstruction##x(_In_opt_ PVOID pDst, \
+ _Inout_opt_ PVOID *ppDstPool, \
+ _In_ PVOID pSrc, \
+ _Out_opt_ PVOID *ppTarget, \
+ _Out_opt_ LONG *plExtra); \
+ \
+BOOL WINAPI DetourSetCodeModule##x(_In_ HMODULE hModule, \
+ _In_ BOOL fLimitReferencesToModule); \
+
+DETOUR_OFFLINE_LIBRARY(X86)
+DETOUR_OFFLINE_LIBRARY(X64)
+DETOUR_OFFLINE_LIBRARY(ARM)
+DETOUR_OFFLINE_LIBRARY(ARM64)
+DETOUR_OFFLINE_LIBRARY(IA64)
+
+#undef DETOUR_OFFLINE_LIBRARY
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// Helpers for manipulating page protection.
+//
+
+_Success_(return != FALSE)
+BOOL WINAPI DetourVirtualProtectSameExecuteEx(_In_ HANDLE hProcess,
+ _In_ PVOID pAddress,
+ _In_ SIZE_T nSize,
+ _In_ DWORD dwNewProtect,
+ _Out_ PDWORD pdwOldProtect);
+
+_Success_(return != FALSE)
+BOOL WINAPI DetourVirtualProtectSameExecute(_In_ PVOID pAddress,
+ _In_ SIZE_T nSize,
+ _In_ DWORD dwNewProtect,
+ _Out_ PDWORD pdwOldProtect);
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+//////////////////////////////////////////////////////////////////////////////
+
+#define MM_ALLOCATION_GRANULARITY 0x10000
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif // DETOURS_INTERNAL
+#endif // __cplusplus
+
+#endif // _DETOURS_H_
+//
+//////////////////////////////////////////////////////////////// End of File.
diff --git a/include/detver.h b/include/detver.h
new file mode 100644
index 0000000..f0aae9b
--- /dev/null
+++ b/include/detver.h
@@ -0,0 +1,27 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// Common version parameters.
+//
+// Microsoft Research Detours Package, Version 4.0.1
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+
+#define _USING_V110_SDK71_ 1
+#include "winver.h"
+#if 0
+#include
+#include
+#else
+#ifndef DETOURS_STRINGIFY
+#define DETOURS_STRINGIFY(x) DETOURS_STRINGIFY_(x)
+#define DETOURS_STRINGIFY_(x) #x
+#endif
+
+#define VER_FILEFLAGSMASK 0x3fL
+#define VER_FILEFLAGS 0x0L
+#define VER_FILEOS 0x00040004L
+#define VER_FILETYPE 0x00000002L
+#define VER_FILESUBTYPE 0x00000000L
+#endif
+#define VER_DETOURS_BITS DETOUR_STRINGIFY(DETOURS_BITS)
diff --git a/lib.x64/detours.lib b/lib.x64/detours.lib
new file mode 100644
index 0000000..1808562
Binary files /dev/null and b/lib.x64/detours.lib differ
diff --git a/lib.x64/detours.pdb b/lib.x64/detours.pdb
new file mode 100644
index 0000000..242f95b
Binary files /dev/null and b/lib.x64/detours.pdb differ
diff --git a/lib.x86/detours.lib b/lib.x86/detours.lib
new file mode 100644
index 0000000..29a2680
Binary files /dev/null and b/lib.x86/detours.lib differ
diff --git a/lib.x86/detours.pdb b/lib.x86/detours.pdb
new file mode 100644
index 0000000..24fa5ca
Binary files /dev/null and b/lib.x86/detours.pdb differ