Initial fork of Detours 4.0 from Detours 3.0 archive.

This commit is contained in:
Galen Hunt
2016-11-07 17:37:52 -08:00
commit e5400b4ec5
158 changed files with 82175 additions and 0 deletions

115
CREDITS.TXT Normal file
View File

@@ -0,0 +1,115 @@
==============================================================================
The following individuals have helped identify specific bugs and improvements
in Detours. The entire Detours community has benefited from their help.
==============================================================================
* Jay Krell: Identified issue with VirtualSize == 0 files created in
NT 3.1 images. (Build_339)
* Igor Odnovorov: Identified an issue with the placement of the trampoline
region when a function is detoured twice and the second
trampoline region is outside of the +/- 2GB range of
the target. (Build_337)
* Jay Krell: Identified need for some programs to enumerate the
address of IAT entries. (Build_336)
* Calvin Hsia: Identified need for some program to change the excluded
system region. (Build_336)
* Adam Smith: Identified error in failure handling when VirtualProect
cannot make pages executable because the Prohibit
Dynamic Code Generation mitigation policy has been
applied to a process. (Build_335)
* Ben Faull: Identified fix to detour_alloc_region_from_lo and
detour_alloc_region_from_hi that preserves ASLR entropy.
(Build_334)
* Shaoxiang Su: Reported errors building with Visual Studio 2015.
(Build_332)
* Jay Krell: Identified and resolved significant gaps in the X86, X64
and IA64 disassemblers for instruction found in code,
but seldom found in function prologues. (Build_331)
* Allan Murphy: Identify error in rep and jmp ds: encodings. (Build_331)
* Philip Bacon: Identified incorrect entry point return for pure
resource-only binaries. (Build_330)
* Jay Krell: Identified failure in DetourAttachEx to update nAlign.
(Build_330)
* Sumit Sarin: Helped debug error with packed binaries.
(Build_329)
* Nitya Kumar Sharma: Reported bug in DetourAfterWithDll for 32/64 agnostic
EXEs.
(Build_327)
* Richard Black: Identified a large number of typos in documentation.
(Build_326)
* Michael Bilodeau: Identified bug in DetourUpdateProcessWithDll when the
target process contains a Detours payload *after* all
valid PE binaries.
(Build_324)
* Meera Jindal: Reported bug in identification of target address in
DetourCopyInstruction for jmp[] and call[] on x86 & x64,
the ff15 and ff25 opcodes.
(Build_323)
* Ken Johnson: Assistance with SAL 2.0 annotations.
(Build_319)
* Nick Wood: Identified bug in DetourFindFunction on ARM.
(Build_314)
* Mark Russinovich: Helped debug DetourCreateProcessWithDllEx.
(Build_314)
* John Lin: Implementation idea for DetoursCreateProcessWithDllEx.
(Build_314)
* Andrew Zawadowskiy Reported an improper memory page permissions
vulnerability in Detours 2.1. (Vulnerability does not
exist in versions later than Detours 2.1.)
(Build_223)
* Nightxie: Identified bug in detour_alloc_round_up_to_region.
(Build_310)
* Diana Milirud: Identified bug in B* instructions on ARM.
(Build_309)
* Juan Carlos Identified correct MSIL entry point for unsigned MSIL.
Luciani: (Build_308)
* Lee Hunt Suggested improvements in algorithm for allocation of
Lawrence Landauer trampoline regions on x64 to avoid collisions with
Joe Laughlin: system DLLs.
(Build_307)
* Tyler Sims Identified bug in handling of "anycpu" MSIL binaries
Darren Kennedy: on x64.
(Build_307)
* Andre Vachon: Help with optimized binaries.
(Build 301)
* Chris Mann: Identified fix not forward ported from 2.2 to 3.0.
(Build_301)
* Mark Irving: Identified bug with EXEs missing second import table.
(Build_300)
* Ben Schwarz: Identified bug in handling of multi-byte NOPs.
(Build_300)
* Aaron Giles Coded initial ARM/Thumb2 disassembler.
Jared Henderson: (Build_300)
* Doug Brubacher: Coded initial x86 disassembler.
(Build_100)

23
LICENSE.md Normal file
View File

@@ -0,0 +1,23 @@
# Copyright (c) Microsoft Corporation
All rights reserved.
# MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

55
Makefile Normal file
View File

@@ -0,0 +1,55 @@
##############################################################################
##
## Makefile for Detours.
##
## Microsoft Research Detours Package
##
## Copyright (c) Microsoft Corporation. All rights reserved.
##
ROOT = .
!include "$(ROOT)\system.mak"
all:
cd "$(MAKEDIR)"
@if exist "$(MAKEDIR)\core\makefile" cd "$(MAKEDIR)\core" && $(MAKE) /NOLOGO /$(MAKEFLAGS)
cd "$(MAKEDIR)\src"
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
cd "$(MAKEDIR)\samples"
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
@if exist "$(MAKEDIR)\bugs\makefile" cd "$(MAKEDIR)\bugs" && $(MAKE) /NOLOGO /$(MAKEFLAGS)
cd "$(MAKEDIR)"
clean:
cd "$(MAKEDIR)"
@if exist "$(MAKEDIR)\core\makefile" cd "$(MAKEDIR)\core" && $(MAKE) /NOLOGO /$(MAKEFLAGS) clean
cd "$(MAKEDIR)\src"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
cd "$(MAKEDIR)\samples"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
@if exist "$(MAKEDIR)\bugs\makefile" cd "$(MAKEDIR)\bugs" && $(MAKE) /NOLOGO /$(MAKEFLAGS) clean
cd "$(MAKEDIR)"
realclean: clean
cd "$(MAKEDIR)"
@if exist "$(MAKEDIR)\core\makefile" cd "$(MAKEDIR)\core" && $(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
cd "$(MAKEDIR)\src"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
cd "$(MAKEDIR)\samples"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
@if exist "$(MAKEDIR)\bugs\makefile" cd "$(MAKEDIR)\bugs" && $(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
cd "$(MAKEDIR)"
-rmdir /q /s $(INCDS) 2> nul
-rmdir /q /s $(LIBDS) 2> nul
-rmdir /q /s $(BINDS) 2> nul
-rmdir /q /s dist 2> nul
-del docsrc\detours.chm 2> nul
-del /q *.msi 2>nul
-del /q /f /s *~ 2>nul
test:
cd "$(MAKEDIR)\samples"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
cd "$(MAKEDIR)"
################################################################# End of File.

26
README.md Normal file
View File

@@ -0,0 +1,26 @@
# Detours, Version 4.0.1
Detours is a software package for re-routing Win32 APIs underneath applications.
Under commercial release for 15 years, Detours has been licensed by over 100 ISVs
and used within nearly every product team at Microsoft. The goodness of Detours
is now open source.
The [`detours`](https://github.com/microsoft/detours) repository is where we do
development and there are many ways you can participate in the project, for example:
* [Submit bugs and feature requests](https://github.com/microsoft/detours/issues) and help us verify as they are checked in
* Review [source code changes](https://github.com/microsoft/detours/pulls)
## Contributing
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
## Feedback
* File a bug in [GitHub Issues](https://github.com/Microsoft/detours/issues).
## License
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the [MIT](LICENSE.txt) License.

282
samples/Makefile Normal file
View File

@@ -0,0 +1,282 @@
##############################################################################
##
## Makefile for Detours Test Programs.
##
## Microsoft Research Detours Package
##
## Copyright (c) Microsoft Corporation. All rights reserved.
##
## Note:
## syelog, setdll, and withdll must be built first because a number of the
## other samples depend on them.
##
ROOT=..
!include .\common.mak
##############################################################################
all:
cd "$(MAKEDIR)\syelog"
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
cd "$(MAKEDIR)\simple"
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
cd "$(MAKEDIR)\slept"
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
cd "$(MAKEDIR)\setdll"
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
cd "$(MAKEDIR)\withdll"
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
cd "$(MAKEDIR)\cping"
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
cd "$(MAKEDIR)\disas"
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
cd "$(MAKEDIR)\dtest"
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
cd "$(MAKEDIR)\dumpe"
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
cd "$(MAKEDIR)\dumpi"
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
cd "$(MAKEDIR)\echo"
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
cd "$(MAKEDIR)\einst"
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
!IF "$(DETOURS_TARGET_PROCESSOR)" == "X86"
cd "$(MAKEDIR)\excep"
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
!ENDIF
cd "$(MAKEDIR)\comeasy"
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
cd "$(MAKEDIR)\commem"
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
cd "$(MAKEDIR)\findfunc"
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
!IF "$(DETOURS_TARGET_PROCESSOR)" != "ARM"
cd "$(MAKEDIR)\member"
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
!ENDIF
cd "$(MAKEDIR)\region"
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
!IF "$(DETOURS_TARGET_PROCESSOR)" == "X64" || "$(DETOURS_TARGET_PROCESSOR)" == "IA64"
cd "$(MAKEDIR)\talloc"
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
!ENDIF
cd "$(MAKEDIR)\traceapi"
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
cd "$(MAKEDIR)\tracebld"
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
cd "$(MAKEDIR)\tracemem"
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
cd "$(MAKEDIR)\tracereg"
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
cd "$(MAKEDIR)\traceser"
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
cd "$(MAKEDIR)\tracessl"
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
cd "$(MAKEDIR)\tracetcp"
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
cd "$(MAKEDIR)\tracelnk"
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
!IF "$(DETOURS_TARGET_PROCESSOR)" != "ARM"
cd "$(MAKEDIR)\tryman"
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
!ENDIF
cd "$(MAKEDIR)\impmunge"
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
cd "$(MAKEDIR)"
clean:
cd "$(MAKEDIR)\syelog"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
cd "$(MAKEDIR)\simple"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
cd "$(MAKEDIR)\slept"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
cd "$(MAKEDIR)\setdll"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
cd "$(MAKEDIR)\withdll"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
cd "$(MAKEDIR)\cping"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
cd "$(MAKEDIR)\disas"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
cd "$(MAKEDIR)\dtest"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
cd "$(MAKEDIR)\dumpe"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
cd "$(MAKEDIR)\dumpi"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
cd "$(MAKEDIR)\echo"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
cd "$(MAKEDIR)\einst"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
cd "$(MAKEDIR)\excep"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
cd "$(MAKEDIR)\comeasy"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
cd "$(MAKEDIR)\commem"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
cd "$(MAKEDIR)\findfunc"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
cd "$(MAKEDIR)\member"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
cd "$(MAKEDIR)\region"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
cd "$(MAKEDIR)\talloc"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
cd "$(MAKEDIR)\traceapi"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
cd "$(MAKEDIR)\tracebld"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
cd "$(MAKEDIR)\tracemem"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
cd "$(MAKEDIR)\tracereg"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
cd "$(MAKEDIR)\traceser"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
cd "$(MAKEDIR)\tracessl"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
cd "$(MAKEDIR)\tracetcp"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
cd "$(MAKEDIR)\tracelnk"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
cd "$(MAKEDIR)\tryman"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
cd "$(MAKEDIR)\impmunge"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
cd "$(MAKEDIR)"
-rmdir lib32 2>nul
-rmdir lib64 2>nul
-rmdir include 2>nul
realclean:
cd "$(MAKEDIR)\syelog"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
cd "$(MAKEDIR)\simple"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
cd "$(MAKEDIR)\slept"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
cd "$(MAKEDIR)\setdll"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
cd "$(MAKEDIR)\withdll"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
cd "$(MAKEDIR)\cping"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
cd "$(MAKEDIR)\disas"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
cd "$(MAKEDIR)\dtest"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
cd "$(MAKEDIR)\dumpe"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
cd "$(MAKEDIR)\dumpi"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
cd "$(MAKEDIR)\echo"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
cd "$(MAKEDIR)\einst"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
cd "$(MAKEDIR)\excep"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
cd "$(MAKEDIR)\comeasy"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
cd "$(MAKEDIR)\commem"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
cd "$(MAKEDIR)\findfunc"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
cd "$(MAKEDIR)\member"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
cd "$(MAKEDIR)\region"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
cd "$(MAKEDIR)\talloc"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
cd "$(MAKEDIR)\traceapi"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
cd "$(MAKEDIR)\tracebld"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
cd "$(MAKEDIR)\tracemem"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
cd "$(MAKEDIR)\tracereg"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
cd "$(MAKEDIR)\traceser"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
cd "$(MAKEDIR)\tracessl"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
cd "$(MAKEDIR)\tracetcp"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
cd "$(MAKEDIR)\tracelnk"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
cd "$(MAKEDIR)\tryman"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
cd "$(MAKEDIR)\impmunge"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
cd "$(MAKEDIR)"
-rmdir lib32 2>nul
-rmdir lib64 2>nul
-rmdir include 2>nul
test:
cd "$(MAKEDIR)\syelog"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
cd "$(MAKEDIR)\simple"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
cd "$(MAKEDIR)\slept"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
cd "$(MAKEDIR)\setdll"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
cd "$(MAKEDIR)\withdll"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
!IF "$(DETOURS_TARGET_PROCESSOR)" == "X86"
cd "$(MAKEDIR)\cping"
# @$(MAKE) /NOLOGO /$(MAKEFLAGS) test
!ENDIF
cd "$(MAKEDIR)\disas"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
cd "$(MAKEDIR)\dtest"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
cd "$(MAKEDIR)\dumpe"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
cd "$(MAKEDIR)\dumpi"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
cd "$(MAKEDIR)\echo"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
cd "$(MAKEDIR)\einst"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
!IF "$(DETOURS_TARGET_PROCESSOR)" == "X86"
cd "$(MAKEDIR)\excep"
# @$(MAKE) /NOLOGO /$(MAKEFLAGS) test
!ENDIF
cd "$(MAKEDIR)\comeasy"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
cd "$(MAKEDIR)\commem"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
cd "$(MAKEDIR)\findfunc"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
cd "$(MAKEDIR)\member"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
cd "$(MAKEDIR)\region"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
!IF "$(DETOURS_TARGET_PROCESSOR)" == "X64" || "$(DETOURS_TARGET_PROCESSOR)" == "IA64"
cd "$(MAKEDIR)\talloc"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
!ENDIF
cd "$(MAKEDIR)\traceapi"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
cd "$(MAKEDIR)\tracebld"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
cd "$(MAKEDIR)\tracemem"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
cd "$(MAKEDIR)\tracereg"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
cd "$(MAKEDIR)\traceser"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
# cd "$(MAKEDIR)\tracessl"
# @$(MAKE) /NOLOGO /$(MAKEFLAGS) test
# cd "$(MAKEDIR)\tracetcp"
# @$(MAKE) /NOLOGO /$(MAKEFLAGS) test
cd "$(MAKEDIR)\tracelnk"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
cd "$(MAKEDIR)\impmunge"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
cd "$(MAKEDIR)"
##
################################################################# End of File.

26
samples/README.TXT Normal file
View File

@@ -0,0 +1,26 @@
##############################################################################
##
## Samples README File
##
## Microsoft Research Detours Package
##
## Copyright (c) Microsoft Corporation. All rights reserved.
##
BUILDING:
=========
To build the sample applications, type "nmake" in the samples directory.
Note that you must build setdll and syslog in order to use many of the
other sample programs.
COMMENTS:
=========
Each of the sample directories has a test, which can be invoked by typing
"nmake test", to demonstrate the usage of the sample. With very few
exceptions, all of the executables also accept a "/?" command to display a
usage message.
The trace* samples log their output through the syelogd.exe daemon and hook
CreateProcessW to load themselves into any child processes. For example,
typing "withdll -d:traceapi.dll cmd.exe" will create a command shell under
which all processes log their API calls through traceapi.dll.

116
samples/comeasy/Makefile Normal file
View File

@@ -0,0 +1,116 @@
##############################################################################
##
## API Extension to Measure time slept.
##
## Microsoft Research Detours Package
##
## Copyright (c) Microsoft Corporation. All rights reserved.
##
!include ..\common.mak
LIBS=$(LIBS) kernel32.lib
##############################################################################
all: dirs \
$(BIND)\wrotei$(DETOURS_BITS).dll \
$(BIND)\comeasy.exe \
!IF $(DETOURS_SOURCE_BROWSING)==1
$(OBJD)\wrotei$(DETOURS_BITS).bsc \
$(OBJD)\comeasy.bsc \
!ENDIF
option
##############################################################################
clean:
-del $(BIND)\wrotei*.* 2>nul
-del $(BIND)\comeasy.* 2>nul
-del $(BIND)\wrotei.* *~ 2>nul
-rmdir /q /s $(OBJD) 2>nul
realclean: clean
-rmdir /q /s $(OBJDS) 2>nul
dirs:
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
##############################################################################
$(OBJD)\wrotei.obj : wrotei.cpp
$(OBJD)\wrotei.res : wrotei.rc
$(BIND)\wrotei$(DETOURS_BITS).dll $(BIND)\wrotei$(DETOURS_BITS).lib: \
$(OBJD)\wrotei.obj $(OBJD)\wrotei.res $(DEPS)
cl /LD $(CFLAGS) /Fe$(@R).dll /Fd$(@R).pdb \
$(OBJD)\wrotei.obj $(OBJD)\wrotei.res \
/link $(LINKFLAGS) /subsystem:console \
/export:DetourFinishHelperProcess,@1,NONAME \
$(LIBS) ole32.lib
$(OBJD)\wrotei$(DETOURS_BITS).bsc : $(OBJD)\wrotei.obj
bscmake /v /n /o $@ $(OBJD)\wrotei.sbr
$(OBJD)\comeasy.obj : comeasy.cpp
$(BIND)\comeasy.exe : $(OBJD)\comeasy.obj $(DEPS)
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb \
$(OBJD)\comeasy.obj \
/link $(LINKFLAGS) $(LIBS) ole32.lib \
/subsystem:console /fixed:no
$(OBJD)\comeasy.bsc : $(OBJD)\comeasy.obj
bscmake /v /n /o $@ $(OBJD)\comeasy.sbr
############################################### Install non-bit-size binaries.
!IF "$(DETOURS_OPTION_PROCESSOR)" != ""
$(OPTD)\wrotei$(DETOURS_OPTION_BITS).dll:
$(OPTD)\wrotei$(DETOURS_OPTION_BITS).pdb:
$(BIND)\wrotei$(DETOURS_OPTION_BITS).dll : $(OPTD)\wrotei$(DETOURS_OPTION_BITS).dll
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
$(BIND)\wrotei$(DETOURS_OPTION_BITS).pdb : $(OPTD)\wrotei$(DETOURS_OPTION_BITS).pdb
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
option: \
$(BIND)\wrotei$(DETOURS_OPTION_BITS).dll \
$(BIND)\wrotei$(DETOURS_OPTION_BITS).pdb \
!ELSE
option:
!ENDIF
##############################################################################
test: all
@echo -------- Reseting test binaries to initial state. -----------------------
$(BIND)\setdll.exe -r $(BIND)\comeasy.exe
@echo.
@echo -------- Should not load slept$(DETOURS_BITS).dll --------------------------------------
$(BIND)\comeasy.exe
@echo.
@echo -------- Adding wrotei$(DETOURS_BITS).dll to comeasy.exe ------------------------------
$(BIND)\setdll.exe -d:$(BIND)\wrotei$(DETOURS_BITS).dll $(BIND)\comeasy.exe
@echo.
@echo -------- Should load wrotei$(DETOURS_BITS).dll ----------------------------------------
$(BIND)\comeasy.exe
@echo.
@echo -------- Removing wrotei$(DETOURS_BITS).dll from comeasy.exe --------------------------
$(BIND)\setdll.exe -r $(BIND)\comeasy.exe
@echo.
@echo -------- Should not load wrotei$(DETOURS_BITS).dll ------------------------------------
$(BIND)\comeasy.exe
@echo.
@echo -------- Should load wrotei$(DETOURS_BITS).dll dynamically using withdll.exe ----------
$(BIND)\withdll.exe -d:$(BIND)\wrotei$(DETOURS_BITS).dll $(BIND)\comeasy.exe
@echo.
@echo -------- Test completed. ------------------------------------------------
################################################################# End of File.

View File

@@ -0,0 +1,69 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detour Test Program (comeasy.cpp of comeasy.exe)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#include <ole2.h>
#include <windows.h>
#include <stdio.h>
//////////////////////////////////////////////////////////////////////////////
//
int __cdecl main(int argc, char **argv)
{
HRESULT hr;
(void)argc;
(void)argv;
LPSTREAM pStream = NULL;
ULARGE_INTEGER ul;
LARGE_INTEGER li;
printf("comeasy.exe: Starting (at %p).\n", main);
CoInitialize(NULL);
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
ul.QuadPart = 512;
hr = pStream->SetSize(ul);
li.QuadPart = 0;
hr = pStream->Seek(li, STREAM_SEEK_SET, NULL);
printf("comeasy.exe: First write.\n");
fflush(stdout);
li.QuadPart = 0;
hr = pStream->Write(&ul, sizeof(ul), NULL);
printf("comeasy.exe: Second write.\n");
fflush(stdout);
li.QuadPart = 1;
hr = pStream->Write(&li, sizeof(li), NULL);
printf("comeasy.exe: Third write.\n");
fflush(stdout);
li.QuadPart = 2;
hr = pStream->Write(&li, sizeof(li), NULL);
pStream->Release();
pStream = NULL;
CoUninitialize();
printf("comeasy.exe: Exiting.\n\n");
fflush(stdout);
return 0;
}
//
///////////////////////////////////////////////////////////////// End of File.

167
samples/comeasy/wrotei.cpp Normal file
View File

@@ -0,0 +1,167 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detour Test Program (wrotei.cpp of wrotei.dll)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// An example dynamically detouring a function.
//
#include <stdio.h>
//////////////////////////////////////////////////////////////////////////////
//
// WARNING:
//
// CINTERFACE must be defined so that the lpVtbl pointer is visible
// on COM interfaces. However, once we've defined it, we must use
// coding conventions when accessing interface members, for example:
// i->lpVtbl->Write
// instead of the C++ syntax:
// i->Write.
// We must also pass the implicit "this" parameter explicitly:
// i->lpVtbl->Write(i, pb, 0, NULL)
// instead of the C++ syntax:
// i->Write(pb, 0, NULL)
//
#define CINTERFACE
#include <ole2.h>
#include <windows.h>
#include <detours.h>
//////////////////////////////////////////////////////////////////////////////
//
LONG dwWrote = 0;
static int (WINAPI * TrueEntryPoint)(VOID) = NULL;
static int (WINAPI * RawEntryPoint)(VOID) = NULL;
//////////////////////////////////////////////////////////////////////////////
//
HRESULT (STDMETHODCALLTYPE *RealIStreamWrite)(IStream * This,
const void *pv,
ULONG cb,
ULONG *pcbWritten) = NULL;
HRESULT STDMETHODCALLTYPE MineIStreamWrite(IStream * This,
const void *pv,
ULONG cb,
ULONG *pcbWritten)
{
HRESULT hr;
ULONG cbWritten = 0;
if (pcbWritten == NULL) {
pcbWritten = &cbWritten;
}
hr = RealIStreamWrite(This, pv, cb, pcbWritten);
for (;;) {
LONG dwOld = dwWrote;
LONG dwNew = dwOld + *pcbWritten;
if (InterlockedCompareExchange(&dwWrote, dwNew, dwOld) == dwOld) {
break;
}
}
return hr;
}
//////////////////////////////////////////////////////////////////////////////
//
int WINAPI TimedEntryPoint(VOID)
{
// We couldn't call CoInitializeEx in DllMain,
// so we detour the vtable entries here...
LONG error;
LPSTREAM pStream = NULL;
// Create a temporary object so we can get a vtable.
CreateStreamOnHGlobal(NULL, TRUE, &pStream);
// Apply the detour to the vtable.
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
if (pStream != NULL) {
RealIStreamWrite = pStream->lpVtbl->Write;
DetourAttach(&(PVOID&)RealIStreamWrite, MineIStreamWrite);
}
error = DetourTransactionCommit();
if (pStream != NULL) {
pStream->lpVtbl->Release(pStream);
pStream = NULL;
}
if (error == NO_ERROR) {
printf("wrotei" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
" Detoured IStream::Wrote() from OnHGlobal.\n");
}
else {
printf("wrotei" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
" Error detouring IStram::Wrote(): %d\n", error);
}
printf("wrotei" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
" Calling EntryPoint\n\n");
fflush(stdout);
return TrueEntryPoint();
}
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
{
LONG error;
(void)hinst;
(void)reserved;
if (DetourIsHelperProcess()) {
return TRUE;
}
if (dwReason == DLL_PROCESS_ATTACH) {
DetourRestoreAfterWith();
printf("wrotei" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
" Starting.\n");
fflush(stdout);
// NB: DllMain can't call LoadLibrary, so we hook the app entry point.
TrueEntryPoint = (int (WINAPI *)(VOID))DetourGetEntryPoint(NULL);
RawEntryPoint = TrueEntryPoint;
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)TrueEntryPoint, TimedEntryPoint);
error = DetourTransactionCommit();
if (error == NO_ERROR) {
printf("wrotei" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
" Detoured EntryPoint().\n");
}
else {
printf("wrotei" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
" Error detouring EntryPoint(): %d\n", error);
}
}
else if (dwReason == DLL_PROCESS_DETACH) {
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
if (RealIStreamWrite != NULL) {
DetourDetach(&(PVOID&)RealIStreamWrite, (PVOID)MineIStreamWrite);
}
DetourDetach(&(PVOID&)TrueEntryPoint, TimedEntryPoint);
error = DetourTransactionCommit();
printf("wrotei" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
" Removed IStream::Wrote() detours (%d), wrote %d bytes.\n",
error, dwWrote);
fflush(stdout);
}
return TRUE;
}
//
///////////////////////////////////////////////////////////////// End of File.

17
samples/comeasy/wrotei.rc Normal file
View File

@@ -0,0 +1,17 @@
//////////////////////////////////////////////////////////////////////////////
//
// Version information for wrotei.rc.
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#include "detver.h"
#define VER_INTERNALNAME_STR "wrotei" DETOURS_STRINGIFY(DETOURS_BITS)
#define VER_ORIGINALFILENAME_STR "wrotei" DETOURS_STRINGIFY(DETOURS_BITS) ".dll"
#define VER_FILEDESCRIPTION_STR "Detours COM Easy Sample"
#define VER_COMPANYNAME_STR "Microsoft Corporation"
#include "common.ver"

48
samples/commem/Makefile Normal file
View File

@@ -0,0 +1,48 @@
##############################################################################
##
## Makefile for Detours Test Programs.
##
## Microsoft Research Detours Package
##
## Copyright (c) Microsoft Corporation. All rights reserved.
##
!include ..\common.mak
LIBS=$(LIBS) kernel32.lib
all: dirs \
$(BIND)\commem.exe \
!IF $(DETOURS_SOURCE_BROWSING)==1
$(OBJD)\commem.bsc
!ENDIF
clean:
-del *~ *.obj *.sbr 2> nul
-del $(BIND)\commem.* 2> nul
-rmdir /q /s $(OBJD) 2>nul
realclean: clean
-rmdir /q /s $(OBJDS) 2>nul
dirs:
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
$(BIND)\commem.obj : commem.cpp
$(BIND)\commem.exe : $(OBJD)\commem.obj $(DEPS)
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\commem.obj \
/link $(LINKFLAGS) $(LIBS) ole32.lib /subsystem:console
$(OBJD)\commem.bsc : $(OBJD)\commem.obj
bscmake /v /n /o $@ $(OBJD)\commem.sbr
##############################################################################
test: $(BIND)\commem.exe
@echo.
$(BIND)\commem.exe
@echo.
################################################################# End of File.

114
samples/commem/commem.cpp Normal file
View File

@@ -0,0 +1,114 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detour functions of a COM interface (commem.cpp of commem.exe)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
//
#include <stdio.h>
//////////////////////////////////////////////////////////////////////////////
//
// WARNING:
//
// CINTERFACE must be defined so that the lpVtbl pointer is visible
// on COM interfaces. However, once we've defined it, we must use
// coding conventions when accessing interface members, for example:
// i->lpVtbl->Write
// instead of the C++ syntax:
// i->Write.
// We must also pass the implicit "this" parameter explicitly:
// i->lpVtbl->Write(i, pb, 0, NULL)
// instead of the C++ syntax:
// i->Write(pb, 0, NULL)
//
#define CINTERFACE
#include <ole2.h>
#include <windows.h>
#include <detours.h>
//////////////////////////////////////////////////////////////////////////////
//
HRESULT (STDMETHODCALLTYPE *RealIStreamWrite)(IStream * This,
const void *pv,
ULONG cb,
ULONG *pcbWritten) = NULL;
HRESULT STDMETHODCALLTYPE MineIStreamWrite(IStream * This,
const void *pv,
ULONG cb,
ULONG *pcbWritten)
{
HRESULT hr;
ULONG cbWritten = 0;
if (pcbWritten == NULL) {
pcbWritten = &cbWritten;
}
printf("commem: %p->IStreamWrite(pv=%p, cb=%d)\n", This, pv, cb);
hr = RealIStreamWrite(This, pv, cb, pcbWritten);
printf("commem: %p->IStreamWrite -> %08x (pcbWritten=%d)\n", This, hr, *pcbWritten);
return hr;
}
//////////////////////////////////////////////////////////////////////////////
//
int main(int argc, char **argv)
{
HRESULT hr;
(void)argc;
(void)argv;
LPSTREAM pStream = NULL;
ULARGE_INTEGER ul;
LARGE_INTEGER li;
CoInitialize(NULL);
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
RealIStreamWrite = pStream->lpVtbl->Write;
ul.QuadPart = 512;
hr = pStream->lpVtbl->SetSize(pStream, ul);
li.QuadPart = 0;
hr = pStream->lpVtbl->Seek(pStream, li, STREAM_SEEK_SET, NULL);
printf("commem: Calling Write w/o before attach.\n");
li.QuadPart = 0;
hr = pStream->lpVtbl->Write(pStream, &ul, sizeof(ul), NULL);
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)RealIStreamWrite, MineIStreamWrite);
DetourTransactionCommit();
printf("commem: Calling Write w/o after attach.\n");
li.QuadPart = 1;
hr = pStream->lpVtbl->Write(pStream, &li, sizeof(li), NULL);
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)RealIStreamWrite, MineIStreamWrite);
DetourTransactionCommit();
printf("commem: Calling Write w/o after detach.\n");
li.QuadPart = 2;
hr = pStream->lpVtbl->Write(pStream, &li, sizeof(li), NULL);
hr = pStream->lpVtbl->Release(pStream);
pStream = NULL;
CoUninitialize();
return 0;
}

86
samples/common.mak Normal file
View File

@@ -0,0 +1,86 @@
##############################################################################
##
## Common makefile for Detours test programs.
##
## Microsoft Research Detours Package
##
## Copyright (c) Microsoft Corporation. All rights reserved.
##
!IF "$(ROOT)" == ""
ROOT = ..\..
!ENDIF
!include "$(ROOT)\system.mak"
!IF "$(DETOURS_SOURCE_BROWSING)" == ""
DETOURS_SOURCE_BROWSING=0
!ENDIF
##############################################################################
!IFNDEF CLIB
CLIB=/MT
!ENDIF
AFLAGS=/nologo /Zi /c /Fl
CFLAGS=/nologo /Zi $(CLIB) /Gm- /W4 /WX /Od
!IF $(DETOURS_SOURCE_BROWSING)==1
CFLAGS=$(CFLAGS) /FR
!ELSE
CFLAGS=$(CFLAGS) /I$(INCD)
!ENDIF
LIBFLAGS=/nologo
LINKFLAGS=/release /incremental:no /profile /nodefaultlib:oldnames.lib
!if defined(DETOURS_WIN_7) && defined(DETOURS_CL_17_OR_NEWER)
CFLAGS=$(CFLAGS) /D_USING_V110_SDK71_
!endif
!IF "$(DETOURS_TARGET_PROCESSOR)" == "X86"
ASM=ml
!ELSEIF "$(DETOURS_TARGET_PROCESSOR)" == "X64"
ASM=ml64
!ELSEIF "$(DETOURS_TARGET_PROCESSOR)" == "IA64"
ASM=ias
AFLAGS=-F COFF32_PLUS
CFLAGS=$(CFLAGS) /wd4163 # intrinsic rdtebex not available; using newer Windows headers with older compiler
#CFLAGS=$(CFLAGS) /wd4996 /wd4068
!ELSEIF "$(DETOURS_TARGET_PROCESSOR)" == "ARM"
ASM=armasm
AFLAGS=-coff_thumb2_only
CFLAGS=$(CFLAGS) /D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
CFLAGS=$(CFLAGS) /D_$(DETOURS_TARGET_PROCESSOR:X64=AMD64)_ # redundant with windows.h except for midl proxies
!ENDIF
DEPS = $(LIBD)\syelog.lib $(LIBD)\detours.lib
LIBS = $(DEPS)
##############################################################################
##
.SUFFIXES: .cpp .h .obj .rc .res
!ifdef DETOURS_ANALYZE
.cpp{$(OBJD)}.obj:
$(CC) $(CFLAGS) /Fd$(OBJD)\vc.pdb /Fo$(OBJD)\ /c $<
!else
.cpp{$(OBJD)}.obj::
$(CC) $(CFLAGS) /Fd$(OBJD)\vc.pdb /Fo$(OBJD)\ /c $<
!endif
.rc{$(OBJD)}.res:
rc /DDETOURS_BITS=$(DETOURS_BITS) /fo$(@) /i$(INCD) $(*B).rc
##
################################################################# End of File.

130
samples/cping/Makefile Normal file
View File

@@ -0,0 +1,130 @@
##############################################################################
##
## Makefile for Detours Test Programs.
##
## Microsoft Research Detours Package
##
## Copyright (c) Microsoft Corporation. All rights reserved.
##
!include ..\common.mak
LIBS=$(LIBS) \
kernel32.lib \
user32.lib \
shell32.lib \
uuid.lib \
ole32.lib \
rpcrt4.lib \
advapi32.lib \
wsock32.lib \
# RpcProxy.h uses #ifdef WIN32.
!if "$(DETOURS_TARGET_PROCESSOR)" == "ARM"
CFLAGS = $(CFLAGS) /D_WIN32_WINNT=0x0500
!else
CFLAGS = $(CFLAGS) /D_WIN32_WINNT=0x0400
!endif
CFLAGS = $(CFLAGS) /Fd$(OBJD)\vc.pdb \
/DCONST_VTABLE \
/DCOBJMACROS -DWIN32 -DNT
C__FLAGS=-DENTRY_PREFIX=iping_ -DREGISTER_PROXY_DLL
CPPFLAGS=
##############################################################################
.SUFFIXES: .c .cpp .h .idl .obj .res .rc
{$(OBJD)}.c{$(OBJD)}.obj:
$(CC) $(CFLAGS:/W4=/W3) $(C__FLAGS) /I$(OBJD) /Fo$(OBJD)\ /c $<
!ifdef DETOURS_ANALYZE
.cpp{$(OBJD)}.obj:
$(CC) $(CFLAGS) $(CPPFLAGS) /I$(OBJD) /Fo$(OBJD)\ /c $<
!else
.cpp{$(OBJD)}.obj::
$(CC) $(CFLAGS) $(CPPFLAGS) /I$(OBJD) /Fo$(OBJD)\ /c $<
!endif
.rc{$(OBJD)}.res:
rc /nologo /Fo$@ .\$(*B).rc
##############################################################################
##
C__FLAGS=-DENTRY_PREFIX=iping_ -DREGISTER_PROXY_DLL
CPPFLAGS=
MIDLFLAGS=/nologo /Oif /no_format_opt
!IF "$(DETOURS_TARGET_PROCESSOR)" == "X86"
MIDLFLAGS=$(MIDLFLAGS) /no_robust /win32
!ELSEIF "$(DETOURS_TARGET_PROCESSOR)" == "IA64"
MIDLFLAGS=$(MIDLFLAGS) /ia64
!ELSEIF "$(DETOURS_TARGET_PROCESSOR)" == "X64"
MIDLFLAGS=$(MIDLFLAGS) /x64
!ELSEIF "$(DETOURS_TARGET_PROCESSOR)" == "ARM"
MIDLFLAGS=$(MIDLFLAGS) /arm32
!ELSEIF "$(DETOURS_TARGET_PROCESSOR)" == "ARM64"
MIDLFLAGS=$(MIDLFLAGS) /arm64
!ENDIF
OBJS = \
$(OBJD)\cping.obj \
\
$(OBJD)\iping_i.obj \
$(OBJD)\iping_p.obj \
$(OBJD)\iping_d.obj \
##############################################################################
all: dirs \
$(BIND)\cping.exe \
!IF $(DETOURS_SOURCE_BROWSING)==1
$(OBJD)\cping.bsc
!ENDIF
##############################################################################
clean:
-del iping.h *.c *.obj *.sbr *~ 2>nul
-del $(BIND)\cping.* 2>nul
-rmdir /q /s $(OBJD) 2>nul
realclean: clean
-rmdir /q /s $(OBJDS) 2>nul
##############################################################################
dirs:
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
$(OBJD)\cping.bsc : $(OBJS)
bscmake /v /n /o $@ $(OBJS:.obj=.sbr)
$(BIND)\cping.exe : $(OBJS) $(DEPS)
cl $(CFLAGS) /Fe$@ $(OBJS) /link $(LINKFLAGS) \
/subsystem:console $(LIBS)
$(OBJD)\cping.obj: cping.cpp $(OBJD)\iping.h
##############################################################################
##
$(OBJD)\iping.h $(OBJD)\iping_d.c $(OBJD)\iping_i.c $(OBJD)\iping_p.c : iping.idl
midl $(MIDLFLAGS) /out $(OBJD) /prefix all iping_ /dlldata iping_d.c iping.idl
$(OBJD)\iping_i.obj: $(OBJD)\iping_i.c
$(OBJD)\iping_p.obj: $(OBJD)\iping_p.c $(OBJD)\iping.h
$(OBJD)\iping_d.obj: $(OBJD)\iping_d.c
##############################################################################
test: $(BIND)\cping.exe
start $(BIND)\cping.exe /s
$(BIND)\cping.exe /p localhost
################################################################# End of File.

47
samples/cping/ReadMe.Txt Normal file
View File

@@ -0,0 +1,47 @@
Microsoft Research Detours Package
==============================================================================
4/2/98
* Instrumentation:
Read Pentium cycle counter
* PC configuration:
DCOM/TCP, Windows NT Server 4.0,
between two 300MHz Pentium boxes,
Ethernet connecction
* Client test program:
HRESULT get(SHORT, SHORT, LONG*)
average over 1,000 calls
midl /Oicf
* Results:
get() {
<-- (1)
IRpcChannelBuffer::SendReceive()) {
<-- (2)
I_RpcSendReceive() {
<-- (3)
send(soc, )
<-- (4)
NtWaitForSingleObject(soc, )
<-- (5)
} // end of RPC layer
<-- (6)
} // end of channel object
<-- (7)
} // end of client call
Average number
of Pentium cycles
(1) NDR marshaling overhead (2 SHORTs) 13 K
(No! of which 11K from GetBuffer,
of which 6.2K from I_RpcGetBuffer()!)
(2) Channel object one-way (send) overhead 1.0 K
(3) RPC layer one-way (send) overhead 5.3 K
(4) TCP + all server work 200 K
(5) RPC layer one-way (recv) overhead 5.1 K
(6) Channel object one-way (recv) overhead 2.2 K
(7) NDR unmarshaling overhead (2 LONGs) 4.2 K
(*) send() only 17 K
TOTAL CYCLES for client get(): 230 K

2245
samples/cping/cping.cpp Normal file

File diff suppressed because it is too large Load Diff

0
samples/cping/cping.dat Normal file
View File

23
samples/cping/iping.idl Normal file
View File

@@ -0,0 +1,23 @@
//////////////////////////////////////////////////////////////////////////////
//
// Module: iping.idl (cping.exe - COM Ping)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
import "objidl.idl";
import "oaidl.idl";
import "oleidl.idl";
[object, uuid(decdbeef-d1ac-11d1-96bc-00aa00573fb0), pointer_default(unique)]
interface IPing : IUnknown
{
HRESULT Ping(void);
HRESULT PingToServer([in] LPSTR pszString);
HRESULT PingToClient([out] LPSTR *ppszString);
HRESULT PingToClientSize([in] ULONG cbOut);
};
//
///////////////////////////////////////////////////////////////// End of File.

76
samples/disas/Makefile Normal file
View File

@@ -0,0 +1,76 @@
##############################################################################
##
## Makefile for Detours Test Programs.
##
## Microsoft Research Detours Package
##
## Copyright (c) Microsoft Corporation. All rights reserved.
##
# temporarily disable this test for ARM64
!if "$(DETOURS_TARGET_PROCESSOR)" != "ARM64"
!include ..\common.mak
LIBS=$(LIBS) kernel32.lib
all: dirs \
$(BIND)\disas.exe \
!IF $(DETOURS_SOURCE_BROWSING)==1
$(OBJD)\disas.bsc
!ENDIF
clean:
-del *~ *.obj *.sbr *.lst 2>nul
-del $(BIND)\disas.* 2> nul
-rmdir /q /s $(OBJD) 2>nul
realclean: clean
-rmdir /q /s $(OBJDS) 2>nul
dirs:
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
!IF "$(DETOURS_TARGET_PROCESSOR)" == "X86"
$(OBJD)\disasm.obj : x86.cpp
cl $(CFLAGS) /Fe$@ /FAcs /Fa$(OBJD)\x86.lst \
/Fd$(@R).pdb /Fo$(OBJD)\disasm.obj /c x86.cpp
!ELSEIF "$(DETOURS_TARGET_PROCESSOR)" == "X64"
$(OBJD)\disasm.obj : x64.asm
$(ASM) $(AFLAGS) /Fo$(OBJD)\disasm.obj /Fl$(OBJD)\x64.lst x64.asm
!ELSEIF "$(DETOURS_TARGET_PROCESSOR)" == "IA64"
$(OBJD)\disasm.obj : ia64.asm
$(ASM) $(AFLAGS) -o $(OBJD)\disasm.obj ia64.asm
!ELSEIF "$(DETOURS_TARGET_PROCESSOR)" == "ARM"
$(OBJD)\disasm.obj : arm.asm
$(ASM) $(AFLAGS) -list $(OBJD)\arm.lst -o $(OBJD)\disasm.obj arm.asm
!ENDIF
$(BIND)\disas.obj : disas.cpp
$(BIND)\disas.exe : $(OBJD)\disas.obj $(OBJD)\disasm.obj $(DEPS)
cl $(CFLAGS) /Fe$@ /FAcs /Fa$(OBJD)\disas.lst /Fd$(@R).pdb \
$(OBJD)\disas.obj $(OBJD)\disasm.obj \
/link $(LINKFLAGS) $(LIBS) /subsystem:console /entry:WinMainCRTStartup
$(OBJD)\disas.bsc : $(OBJD)\disas.obj
bscmake /v /n /o $@ $(OBJD)\disas.sbr
##############################################################################
test: $(BIND)\disas.exe
$(BIND)\disas.exe
##############################################################################
!else
all:
test:
clean:
realclean:
!endif
################################################################# End of File.

232
samples/disas/arm.asm Normal file
View File

@@ -0,0 +1,232 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Detours Test Program (rlo.asm/disas.exe)
;;
;; Microsoft Research Detours Package
;;
;; Copyright (c) Microsoft Corporation. All rights reserved.
;;
MACRO
BREAK
DCW 0xdefe
MEND
AREA |.text|,ALIGN=2,CODE,READONLY
AREA |.text|,CODE,READONLY
ALIGN 0x1000
EXPORT |TestCodes|
|TestCodes|
; dcw 0xf8df,0xe00e ; 94 = -16 = -12 ; 94 ; 98 + e = a6
; BREAK ; 98 = -14 = -10 ; 98 ; 9c
; dcw 0xf8df,0xe00a ; 9a = -12 = -8 ; 98 ; 9c + a = a6
; BREAK ; 9e = -8 = -4 ; 9c ; a0
; dcw 0xf8df,0xe002 ; a0 = -6 = -2 ; a0 ; a4 + 2 = a6
; BREAK ; a4 = -2 ; a4 ; a8
; movs r2, r0 ; a6 <===
; movs r3, r0 ;
; BREAK
; BREAK
;
; ldr lr,=0xa98765
; ldr pc,=0xa98765
; ldr pc,=0xa98765
; ldr pc,=0xa98765
; BREAK
; BREAK
BREAK
ldr lr, =0xa98765
BREAK
blx lr
BREAK
pop pc
BREAK
pop {r11,pc}
BREAK
pop {r10,r11,pc}
BREAK
pop {r9,r10,r11,pc}
BREAK
pop {r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,pc}
BREAK
ldr.w r0,=0xa98765
BREAK
nop
ldr.w r0,=0xa98765
BREAK
nop
nop
ldr.w r0,=0xa98765
BREAK
ldr r0,=0xa98765
BREAK
ldr.w r0,=0xa98765
BREAK
ldr.w r0,=0xa98765
BREAK
ldr r0,=0xa98765
BREAK
ldr.w r0,=0xa98765
BREAK
ldr.w r0,=0xa98765
BREAK
ldr r0,=0xa98765
BREAK
ldr.w r0,=0xa98765
BREAK
ldr.w r0,=0xa98765
BREAK
ldr r0,=0xa98765
BREAK
nop
ldr r0,=0xa98765
BREAK
nop
nop
ldr r0,=0xa98765
BREAK
nop
ldr r0,=0xa
BREAK
ldr r0,=0xa9
BREAK
ldr r0,=0xa98
BREAK
ldr r0,=0xa987
BREAK
ldr r0,=0xa9876
BREAK
ldr r0,=0xa98765
BREAK
ldr r0,=0xa987654
BREAK
ldr r0,=0xa9876543
;; Simple instructions.
BREAK
adds r0,r0, #5 ; 1d40
BREAK
movs r2, #0 ; 2200
BREAK
movs r3, #0 ; 2300
BREAK
bx lr ; 4770 [FFFFFFFF]
;; Known 16-bit instructions
BREAK
mov r11, sp ; 46eb
BREAK
movs r2, r0 ; 0002
BREAK
push r0, r1 ; b403
BREAK
str r3,[r7,#0x28] ; 62bb
BREAK
bx r5 ; 4728 [FFFFFFFF]
BREAK
blx r5 ; 47a8
BREAK
DCW 0x4878 ; ldr r0, [PC + 0x1E0] ; 4878
BREAK
str r3,[r7,#0x1C] ; 61fb
BREAK
ldr r3,[r7,#0x38] ; 6bbb
BREAK
add r3,sp,#0xCC ; ab33
BREAK
cbz r2,+0x56 ; b34a [00xx1510]
BREAK
cbnz r2,+0x56 ; bb4a [00xx1514]
BREAK
push {r0,r2,r4,r6,lr} ; b555
BREAK
nop ; bf00
;; Placeholder for IT instruction
BREAK
bne +0x6E ; d135 [00xx1538] -??? d137
BREAK
svc #0x24 ; df24
BREAK
b +0x7FE ; e3fd [00xx1cd0] -??? e3ff
;; 32 bit test codes
BREAK
adds r0,r7,#8 ; f1170008
BREAK
str r3,[r5,#0x677] ; f8c53677
BREAK
ldrsh r10,[r5,#0x5A5] ; f9b5a5a5
BREAK
DCW 0xf89f,0x55a5 ;ldrb r5, [+0x5A5] ; f89f55a5
BREAK
bls.w +0x86; 0xf240; 0x8043; // ; f2408041 [00xx157A]
BREAK
bl +0xFE; 0xf7ff; 0xff80; //
BREAK
bl +0xFFE; 0xf7ff; 0xff80; //
BREAK
bl +0xFFFE; 0xf7ff; 0xff80; //
BREAK
bl +0xFFFFE; 0xf7ff; 0xff80; //
BREAK
bl +0xFFFFFE; 0xf7ff; 0xff80; //
BREAK
bl +0xF0; 0xf7ff; 0xff80; //
BREAK
bl +0xFF0; 0xf7ff; 0xff80; //
BREAK
bl +0xFFF0; 0xf7ff; 0xff80; //
BREAK
bl +0xFFFF0; 0xf7ff; 0xff80; //
BREAK
bl +0xFFFFF0; 0xf7ff; 0xff80; //
BREAK
bl +0xF00; 0xf7ff; 0xff80; //
BREAK
bl +0xFF00; 0xf7ff; 0xff80; //
BREAK
bl +0xFFF00; 0xf7ff; 0xff80; //
BREAK
bl +0xFFFF00; 0xf7ff; 0xff80; //
BREAK
DCW 0xf7ff,0xff80
;bl +0xFFFFFF00; 0xf7ff; 0xff80; //
BREAK
DCW 0xf7ff,0xbe02
; b.w ; 0xf7ff; 0xbe02; // (10053528)
BREAK
push {r7,r11,lr}; 0xe92d; 0x4880; //
;; 32 bit expected results
BREAK
adds r0,r7,#8 ; 0xf1170008
BREAK
str r3,[r5,#0x677] ; 0xf8c53677
BREAK
ldrsh r10,[r5,#0x5A5] ; 0xf9b5a5a5
BREAK
DCW 0xf6af,0xfbd2
; bl (0008ef3c); ResultCode(4, 0xf6af, 0xfbd2, Target(ADDRESS(&g_pTestCodes32[i*2], 0xFFFFFF00))); // 0xf7ff, 0xff80: -> 0xf6affbd2
BREAK
bl (00090300); ResultCode(4, 0xf6af, 0xba54, Target(ADDRESS(&g_pTestCodes32[i*2], 0xFFFFFC04))); // 0xf7ff, 0xff80: -> f6afba54 bl (00090300)
BREAK
push {r7,r11,lr}; ResultCode(4, 0xe92d, 0x4880); // 0xe92d, 0x4880: //
BREAK
BREAK
|TestCodes_end|
END

686
samples/disas/disas.cpp Normal file
View File

@@ -0,0 +1,686 @@
/////////////////////////////////////////////////////////////////////////////
//
// Module: disas.cpp (disas.exe - Detours Test Program)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS 1
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#define DETOURS_INTERNAL
#include <detours.h>
///////////////////////////////////////////////////////////////////////// ARM.
//
#ifdef DETOURS_ARM
extern "C" BYTE TestCodes[];
void DumpMemoryFragment(PBYTE pbData, ULONG cbData, ULONG cbSpace)
{
ULONG n = 0;
if (cbData >= 4) {
printf("%04x%04x ", ((PUSHORT)pbData)[0], ((PUSHORT)pbData)[1]);
n += 4;
}
else if (cbData >= 2) {
printf("%04x ", *((PUSHORT)pbData));
n += 2;
}
for (; n < cbSpace; n++) {
if (n < cbData) {
printf("%02x", pbData[n]);
}
else {
printf(" ");
}
}
if (n < cbData) {
printf(".");
}
else {
printf(" ");
}
}
inline ULONG fetch_thumb_opcode(PBYTE pbCode)
{
ULONG Opcode = *(UINT16 *)&pbCode[0];
if (Opcode >= 0xe800) {
Opcode = (Opcode << 16) | *(UINT16 *)&pbCode[2];
}
return Opcode;
}
BOOL IsTerminate(PBYTE pbSrc)
{
ULONG opcode = fetch_thumb_opcode(pbSrc);
if ((opcode & 0xff87) == 0x4700) {
// bx r
return TRUE;
}
#if 0
if ((opcode & 0xfbf08f00) == 0xf2400c00) { // movw r12,#xxxx
return TRUE;
}
if ((opcode == 0xf8dcf000) { // ldr pc,[r12]
ULONG Immediate = ((opcode2 << 12) & 0xf7000000) |
((opcode2 << 1) & 0x08000000) |
((opcode2 << 16) & 0x00ff0000) |
((opcode >> 4) & 0x0000f700) |
((opcode >> 15) & 0x00000800) |
((opcode >> 0) & 0x000000ff);
PBYTE pbTarget = *(PBYTE *)Immediate;
if (detour_is_imported(pbCode, pbTarget)) {
PBYTE pbNew = *(PBYTE *)pbTarget;
DETOUR_TRACE(("%p->%p: skipped over import table.\n", pbCode, pbNew));
return pbNew;
}
}
}
}
#endif
return FALSE;
}
#endif // DETOURS_ARM
///////////////////////////////////////////////////////////////// X86 and X64.
//
#if defined(DETOURS_X86) || defined(DETOURS_X64)
extern "C" BYTE TestCodes[];
void DumpMemoryFragment(PBYTE pbData, ULONG cbData, ULONG cbSpace)
{
ULONG n = 0;
for (; n < cbSpace; n++) {
if (n < cbData) {
printf("%02x", pbData[n]);
}
else {
printf(" ");
}
}
if (n < cbData) {
printf(".");
}
else {
printf(" ");
}
}
BOOL IsTerminate(PBYTE pbSrc)
{
if ((0xC3 == pbSrc[0] && 0x00 == pbSrc[1]) || // bx lr
0xCB == pbSrc[0] || // RETF
0xC2 == pbSrc[0] || // RET dw
0xCA == pbSrc[0] || // RETF dw
0xEB == pbSrc[0] || // JMP ob
0xE9 == pbSrc[0] || // JMP ol
0xEA == pbSrc[0]) { // JMP ol
return TRUE;
}
if (0xff == pbSrc[0] && 0x25 == pbSrc[1]) // JMP [addr]
return TRUE;
return FALSE;
}
#endif // DETOURS_X86 || DETOURS_X64
/////////////////////////////////////////////////////////// X86, X64, and ARM.
//
#if defined(DETOURS_X86) || defined(DETOURS_X64) || defined(DETOURS_ARM)
struct BasicBlockLink
{
public:
BasicBlockLink * m_pNext;
PBYTE m_pbEntry;
PCHAR m_pszName;
public:
BasicBlockLink(PBYTE pbEntry, PCHAR pszName = NULL)
{
m_pNext = NULL;
m_pbEntry = pbEntry;
m_pszName = pszName;
*s_ppTail = this;
s_ppTail = &m_pNext;
}
BasicBlockLink * Next()
{
return m_pNext;
}
static BasicBlockLink * GetListHead()
{
return s_pHead;
}
protected:
static BasicBlockLink * s_pHead;
static BasicBlockLink ** s_ppTail;
};
BasicBlockLink * BasicBlockLink::s_pHead = NULL;
BasicBlockLink ** BasicBlockLink::s_ppTail = &BasicBlockLink::s_pHead;
static PBYTE s_pbBegin = NULL;
static PBYTE s_pbLimit = NULL;
int TestDetourCopyInstruction(PBYTE pbSrcInstruction, PCHAR pszFunction)
{
PBYTE pbSrc = pbSrcInstruction;
ULONG nIns = 0;
if (pszFunction) {
printf("%s:\n", pszFunction);
}
for (; nIns < 4096; nIns++) {
BYTE rbDst[128];
PVOID pbDstPool = (PVOID)(rbDst + sizeof(rbDst));
LONG lExtra = 0;
PVOID pbTarget = NULL;
ULONG cbStep = (ULONG)((PBYTE)DetourCopyInstruction(rbDst, &pbDstPool, pbSrc,
&pbTarget, &lExtra) - pbSrc);
printf(" %p:", pbSrc);
DumpMemoryFragment(rbDst, cbStep, 10);
printf(" ");
DumpMemoryFragment(rbDst, cbStep, 10);
if (pbTarget) {
if (pbTarget == DETOUR_INSTRUCTION_TARGET_DYNAMIC) {
printf(" Dynamic\n");
}
else {
printf(" %p%c\n", pbTarget,
(pbTarget >= s_pbBegin && pbTarget < s_pbLimit) ? ' ' : '!');
}
}
else {
printf("\n");
}
if (pbTarget && pbTarget != DETOUR_INSTRUCTION_TARGET_DYNAMIC) {
if (pbTarget > pbSrc &&
pbTarget >= s_pbBegin &&
pbTarget < s_pbLimit
) {
(void) new BasicBlockLink((PBYTE)pbTarget, NULL);
}
}
if (IsTerminate(pbSrc)) {
break;
}
pbSrc += cbStep;
}
return nIns;
}
BOOL CALLBACK ExportCallback(_In_opt_ PVOID pContext,
_In_ ULONG nOrdinal,
_In_opt_ LPCSTR pszName,
_In_opt_ PVOID pCode)
{
(void)pContext;
(void)nOrdinal;
(void)pCode;
(VOID) new BasicBlockLink((PBYTE)pCode, pszName ? pszName : "[NO NAME]");
return TRUE;
}
#endif // DETOURS_X86 || DETOURS_X64
//////////////////////////////////////////////////////////////////////// IA64.
//
#ifdef DETOURS_IA64
#pragma warning(disable: 4201) // ignore warning about unnamed sturcture in union.
void DumpHi(PBYTE pbData, ULONG cbData, ULONG cbSpace)
{
ULONG n = 0;
for (; n < cbSpace; n++) {
if (n < cbData) {
printf("%02x", pbData[(cbData - 1) - n]);
}
else {
printf(" ");
}
}
printf("\n");
}
struct DETOUR_IA64_BUNDLE_DISASSEMBLE : public DETOUR_IA64_BUNDLE
{
public:
void SetBrx(UINT64 raw)
{
SetBrl();
SetBrlImm(raw);
}
void Dis()
{
const char szUnitNames[17] = "?aimbflx?AIMBFLX";
printf("%p: ", data);
BYTE nTemplate = GetTemplate();
BYTE nInst0 = GetInst0();
BYTE nInst1 = GetInst1();
BYTE nInst2 = GetInst2();
BYTE nUnit0 = GetUnit0();
BYTE nUnit1 = GetUnit1();
BYTE nUnit2 = GetUnit2();
if (nUnit1 == L_UNIT) { // MLX instruction
UINT64 d2 = (
// 0x0000000000fffff0
((wide[1] & 0x00fffff000000000) >> 32) |
// 0x000000ffff000000
((wide[0] & 0xffff000000000000) >> 24) |
// 0x7fffff0000000000
((wide[1] & 0x00000000007fffff) << 40) |
// 0x8000000000000000
((wide[1] & 0x0800000000000000) << 4)
);
printf("%02x %c%01x %010I64lx %c%01x %016I64lx",
nTemplate,
szUnitNames[nUnit0], nInst0, GetData0(),
szUnitNames[nUnit2], nInst2, d2);
}
else {
printf("%02x %c%01x %010I64lx %c%01x %010I64lx %c%01x %010I64lx",
nTemplate,
szUnitNames[nUnit0], nInst0, GetData0(),
szUnitNames[nUnit1], nInst1, GetData1(),
szUnitNames[nUnit2], nInst2, GetData2());
}
if (IsBrl()) {
printf(" brl %p", GetBrlTarget());
}
else if (IsMovlGp()) {
printf(" movl gp=%p", GetMovlGp());
}
if ((wide[0] & 0xfffffc000603ffff) == 0x002024000200100b &&
wide[1] == 0x0004000000203008) {
ULONG64 offset =
((wide[0] & 0x0000000001fc0000) >> 18) | // imm7b
((wide[0] & 0x000001ff00000000) >> 25) | // imm9d
((wide[0] & 0x00000000f8000000) >> 11); // imm5c
if (wide[0] & 0x0000020000000000) {
offset |= 0xffffffffffe00000;
}
printf(" imm=%016I64lx", offset);
}
printf("\n");
}
};
//////////////////////////////////////////////////////////////////////////////
//
BOOL CALLBACK ExportCallbackIA64(_In_opt_ PVOID pContext,
_In_ ULONG nOrdinal,
_In_opt_ LPCSTR pszName,
_In_opt_ PVOID pCode)
{
(void)pContext;
(void)nOrdinal;
DETOUR_IA64_BUNDLE_DISASSEMBLE *pb = *(DETOUR_IA64_BUNDLE_DISASSEMBLE **)pCode;
DETOUR_IA64_BUNDLE temp;
if (!pb[0].Copy(&temp)) {
printf("%s:\n ", pszName ? pszName : "[NO NAME]");
pb[0].Dis();
}
return TRUE;
}
#if 0
void TestBoth()
{
LPVOID pvBase = VirtualAlloc((PBYTE)0x800000000, 0x10000,
MEM_RESERVE | MEM_COMMIT,
PAGE_EXECUTE_READWRITE);
DETOUR_IA64_BUNDLE *pbBase = (DETOUR_IA64_BUNDLE *)pvBase;
DETOUR_IA64_BUNDLE *pb = pbBase;
printf("TestBoth:\n");
for (UINT64 i = 0x10; i < 0x8000000000000000; i <<= 1) {
pb->SetMovlGp(i);
if (pb->GetMovlGp() != i) {
printf("Error in MovlGp!\n");
return;
}
pb++;
pb->SetBrl(i);
if (pb->GetBrlEip() != i) {
printf("Error in Brl!\n");
return;
}
pb++;
}
for (UINT64 i = (UINT64)(INT64)-0x10; i > 0; i <<= 1) {
pb->SetMovlGp(i);
if (pb->GetMovlGp() != i) {
printf("Error in MovlGp!\n");
return;
}
pb++;
pb->SetBrl(i);
if (pb->GetBrlEip() != i) {
printf("Error in Brl!\n");
return;
}
pb++;
}
printf("u %p %p\n", pbBase, pb);
}
#endif
#endif // DETOURS_IA64
int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hprev, LPSTR lpszCmdLine, int nCmdShow)
{
(void)hprev;
(void)hinst;
(void)lpszCmdLine;
(void)nCmdShow;
#ifdef DETOURS_IA64
// First we check the pre-canned TestCodes from disasm.asm
//
PBYTE pbTest = *(PBYTE*)WinMain;
for (;; pbTest += 16) {
DETOUR_IA64_BUNDLE_DISASSEMBLE *pb = (DETOUR_IA64_BUNDLE_DISASSEMBLE *)pbTest;
pb->Dis();
if (pbTest[0] == 0xff) {
break;
}
DumpHi(pbTest, 16, 16);
}
#if 0
printf("\n\n");
DETOUR_IA64_BUNDLE_DISASSEMBLE *pb = (DETOUR_IA64_BUNDLE_DISASSEMBLE *)pbTest;
DETOUR_IA64_BUNDLE_DISASSEMBLE *pbBeg = pb;
DWORD dwOld;
VirtualProtect(pb, 0x2000, PAGE_EXECUTE_READWRITE, &dwOld);
printf("%p: (%d)\n", pb, sizeof(pb));
pb++;
printf("%p: (%d)\n", pb, sizeof(pb));
pb++; pb->SetBrx(0);
pb++; pb->SetBrx(0);
pb++; pb->SetBrx(0);
pb++; pb->SetBrx(0xffffffffffffffff);
pb++; pb->SetBrx(0x0fffffffffffffff);
pb++; pb->SetBrx(0x00ffffffffffffff);
pb++; pb->SetBrx(0x000fffffffffffff);
pb++; pb->SetBrx(0x0000ffffffffffff);
pb++; pb->SetBrx(0x00000fffffffffff);
pb++; pb->SetBrx(0x000000ffffffffff);
pb++; pb->SetBrx(0x0000000fffffffff);
pb++; pb->SetBrx(0x00000000ffffffff);
pb++; pb->SetBrx(0x000000000fffffff);
pb++; pb->SetBrx(0x0000000000ffffff);
pb++; pb->SetBrx(0x00000000000fffff);
pb++; pb->SetBrx(0x000000000000ffff);
pb++; pb->SetBrx(0x0000000000000fff);
pb++; pb->SetBrx(0x00000000000000ff);
pb++; pb->SetBrx(0x000000000000000f);
pb++; pb->SetBrx(0x0000000000000000);
pb++; pb->SetBrx(0xffffffffffffffff);
pb++; pb->SetBrx(0xffffffffffffffff);
pb->SetInst0(0xff);
pb->SetData0(0xffffffffffffffff);
printf("%p:\n", pb);
DETOUR_IA64_BUNDLE_DISASSEMBLE *pbEnd = pb;
for (pb = pbBeg; pb < pbEnd; pb++) {
printf(" %p: ", pb);
DumpHi((BYTE*)pb, 16, 16);
}
#endif
#if 1
{
// Then we check all of the code we can find in user32.dll
//
printf("\n");
HINSTANCE hInst = LoadLibraryA("user32.dll");
printf("Loaded: user32.dll: %p\n", hInst);
PBYTE pbEntry = (PBYTE)DetourGetEntryPoint(hInst);
printf("Entry: %p\n", pbEntry);
ExportCallbackIA64(NULL, 0, "[Entry]", pbEntry);
DetourEnumerateExports(hInst, NULL, ExportCallbackIA64);
}
{
// Then we check all of the code we can find in opengl32.dll
//
printf("\n");
HINSTANCE hInst = LoadLibraryA("opengl32.dll");
printf("Loaded: opengl32.dll: %p\n", hInst);
PBYTE pbEntry = (PBYTE)DetourGetEntryPoint(hInst);
printf("Entry: %p\n", pbEntry);
ExportCallbackIA64(NULL, 0, "[Entry]", pbEntry);
DetourEnumerateExports(hInst, NULL, ExportCallbackIA64);
}
printf("\n");
for (HINSTANCE hInst = NULL; (hInst = DetourEnumerateModules(hInst)) != NULL;) {
CHAR szModuleName[512];
GetModuleFileNameA(hInst, szModuleName,
sizeof(szModuleName)/sizeof(szModuleName[0]));
printf("%p : %s\n", hInst, szModuleName);
DetourEnumerateExports(hInst, NULL, ExportCallbackIA64);
}
printf("\n");
#endif
#if 0
TestBoth();
#endif
#endif // DETOURS_IA64
#if defined(DETOURS_X64) || defined(DETOURS_X86)
// First we check the pre-canned TestCodes from disasm.asm
//
PBYTE pbBegin = (PBYTE)DetourCodeFromPointer(TestCodes, NULL);
printf("%p:\n", pbBegin);
for (PBYTE pbTest = pbBegin;;) {
if (pbTest[0] != 0xcc) { // int 3
printf("%08x ", (ULONG)(pbTest - pbBegin));
DumpMemoryFragment(pbTest, 8, 8);
printf("\n");
printf("failed on last.\n");
return 1;
}
pbTest++;
if (pbTest[0] == 0x70 || pbTest[0] == 0x71) {
printf("[%p]:\n", pbTest);
}
BYTE rbDst[128];
PVOID pbDstPool = (PVOID)(rbDst + sizeof(rbDst));
LONG lExtra = 0;
PVOID pbTarget = NULL;
PBYTE pbNext = (PBYTE)DetourCopyInstruction(rbDst, &pbDstPool, pbTest,
&pbTarget, &lExtra);
LONG cbTest = (LONG)(pbNext - pbTest);
printf("%08x ", (ULONG)(pbTest - pbBegin));
DumpMemoryFragment(pbTest, cbTest, 12);
printf("[%16p] ", pbTarget);
DumpMemoryFragment(rbDst, cbTest + lExtra, 11);
printf("\n");
if (pbTest[cbTest] != 0xcc) {
printf("failed!\n");
return 1;
}
pbTest += cbTest;
if (pbTest[0] == 0xcc && pbTest[1] == 0xcc) {
break;
}
}
#if 0
// Then we check all of the code we can find in user32.dll
//
HINSTANCE hInst = LoadLibraryA("user32.dll");
printf("Loaded: user32.dll: %p\n", hInst);
s_pbBegin = (PBYTE)hInst;
s_pbLimit = s_pbBegin + DetourGetModuleSize(hInst);
PBYTE pbEntry = DetourGetEntryPoint(hInst);
(VOID) new BasicBlockLink(pbEntry, "user32.dll");
DetourEnumerateExports(hInst, NULL, ExportCallback);
ULONG nIns = 0;
for (BasicBlockLink *pLink = BasicBlockLink::GetListHead();
pLink; pLink = pLink->Next()) {
nIns += TestDetourCopyInstruction(pLink->m_pbEntry, pLink->m_pszName);
if (nIns > 100000) {
break;
}
}
printf("Disassembled %d instructions.\n", nIns);
#endif
#endif // DETOURS_X86 || DETOURS_X64
#ifdef DETOURS_ARM
// Create an output buffer and fill it with debugbreaks.
//
PBYTE pbBuffer
= (PBYTE)VirtualAlloc(NULL, 0x400, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE);
for (PBYTE pbOut = pbBuffer; pbOut < pbBuffer + 0x400;) {
*pbOut++ = 0xfe;
*pbOut++ = 0xde;
}
PBYTE pbDst = pbBuffer;
PVOID pvDstPool = (PVOID)(pbBuffer + 0x400);
// First we check the pre-canned TestCodes from disasm.asm
//
PBYTE pbBegin = (PBYTE)DetourCodeFromPointer(TestCodes, NULL);
printf("%p: (TestCodes %p) => %p\n", pbBegin, TestCodes, pbBuffer);
for (PBYTE pbSrc = pbBegin;;) {
if (pbSrc[0] != 0xfe && pbSrc[1] != 0xde) { // BREAK
printf("%08x ", pbSrc - pbBegin);
DumpMemoryFragment(pbSrc, 8, 8);
printf("\n");
printf("failed on last.\n");
return 1;
}
pbSrc += 2;
*pbDst++ = 0xfe;
*pbDst++ = 0xde;
if ((pbSrc[0] == 0x00 && pbSrc[1] == 0xbf) && // NOP
(pbSrc[2] != 0xfe && pbSrc[3] != 0xde)) { // BREAK
// Skip over a single NOP so we can test alignment.
pbSrc += 2;
}
if ((pbSrc[0] == 0x00 && pbSrc[1] == 0xbf) && // NOP
(pbSrc[2] != 0xfe && pbSrc[3] != 0xde)) { // BREAK
// If there is a second NOP, then we insert alignment.
pbSrc += 2;
*pbDst++ = 0x00;
*pbDst++ = 0xbf;
}
LONG lExtra = 0;
PVOID pbTarget = NULL;
PBYTE pbNext = (PBYTE)DetourCopyInstruction(pbDst, &pvDstPool, pbSrc, &pbTarget, &lExtra);
LONG cbTest = (LONG)(pbNext - pbSrc);
printf("%08x ", pbSrc - pbBegin);
DumpMemoryFragment(pbSrc, cbTest, 4);
printf("[%8p] ", pbTarget);
DumpMemoryFragment(pbDst, cbTest + lExtra, 16);
printf("\n");
if (pbSrc[cbTest] != 0xfe || pbSrc[cbTest+1] != 0xde) {
printf("%p: failed! (pbSrc[n]=%02x, pbSrc[n+1]=%02x\n",
pbSrc,
pbSrc[cbTest], pbSrc[cbTest+1]);
__debugbreak();
pbNext = (PBYTE)DetourCopyInstruction(pbDst, &pvDstPool, pbSrc, &pbTarget, &lExtra);
cbTest = (LONG)(pbNext - pbSrc);
return 1;
}
pbDst += cbTest + lExtra;
pbSrc += cbTest;
if (pbSrc[0] == 0xfe && pbSrc[1] == 0xde &&
pbSrc[2] == 0xfe && pbSrc[3] == 0xde) {
break;
}
}
#if 0
// Then we check all of the code we can find in user32.dll
//
HINSTANCE hInst = LoadLibraryA("user32.dll");
printf("Loaded: user32.dll: %p\n", hInst);
s_pbBegin = (PBYTE)hInst;
s_pbLimit = s_pbBegin + DetourGetModuleSize(hInst);
PBYTE pbEntry = DetourGetEntryPoint(hInst);
(VOID) new BasicBlockLink(pbEntry, "user32.dll");
DetourEnumerateExports(hInst, NULL, ExportCallback);
ULONG nIns = 0;
for (BasicBlockLink *pLink = BasicBlockLink::GetListHead();
pLink; pLink = pLink->Next()) {
nIns += TestDetourCopyInstruction(pLink->m_pbEntry, pLink->m_pszName);
if (nIns > 100000) {
break;
}
}
printf("Disassembled %d instructions.\n", nIns);
#endif
#endif // DETOURS_ARM
return 0;
}
//
///////////////////////////////////////////////////////////////// End of File.

1084
samples/disas/ia64.asm Normal file

File diff suppressed because it is too large Load Diff

15
samples/disas/unk.cpp Normal file
View File

@@ -0,0 +1,15 @@
/////////////////////////////////////////////////////////////////////////////
//
// Detours Test Program (x86.asm of disas.exe)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
static int value = 0;
extern "C" void TestCodes()
{
value++;
}

520
samples/disas/x64.asm Normal file
View File

@@ -0,0 +1,520 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Detours Test Program (x64.asm/disas.exe)
;;
;; Microsoft Research Detours Package
;;
;; Copyright (c) Microsoft Corporation. All rights reserved.
;;
.xlist
.list
.code
PUBLIC TestCodes
_TEXT SEGMENT
TestCodes PROC
begin:
faraway:
int 3
nop
int 3
db 066h,090h ; // 2-byte NOP.
int 3
db 00fh, 01fh, 000h ; // 3-byte NOP.
int 3
db 00fh, 01fh, 040h, 000h ; // 4-byte NOP.
int 3
db 00fh, 01fh, 044h, 000h, 000h ; // 5-byte NOP.
int 3
db 066h, 00fh, 01fh, 044h, 000h, 000h ; // 6-byte NOP.
int 3
db 00fh, 01fh, 080h, 000h, 000h, 000h, 000h ; // 7-byte NOP.
int 3
db 00fh, 01fh, 084h, 000h, 000h, 000h, 000h, 000h ; // 8-byte NOP.
int 3
db 066h, 00fh, 01fh, 084h, 000h, 000h, 000h, 000h, 000h ; // 9-byte NOP.
int 3
mov rax, cr8
int 3
mov rcx, cr8
int 3
mov rdx, cr8
int 3
mov rbx, cr8
int 3
mov rsp, cr8
int 3
mov rbp, cr8
int 3
mov rsi, cr8
int 3
mov rdi, cr8
int 3
mov r8, cr8
int 3
mov r9, cr8
int 3
mov r10, cr8
int 3
mov r11, cr8
int 3
mov r12, cr8
int 3
mov r13, cr8
int 3
mov r14, cr8
int 3
mov r15, cr8
int 3
mov cr8, rax
int 3
mov cr8, rcx
int 3
mov cr8, rdx
int 3
mov cr8, rbx
int 3
mov cr8, rsp
int 3
mov cr8, rbp
int 3
mov cr8, rsi
int 3
mov cr8, rdi
int 3
mov cr8, r8
int 3
mov cr8, r9
int 3
mov cr8, r10
int 3
mov cr8, r11
int 3
mov cr8, r12
int 3
mov cr8, r13
int 3
mov cr8, r14
int 3
mov cr8, r15
int 3
xor rax, rax
int 3
xor rcx, rcx
int 3
xor rdx, rdx
int 3
xor rbx, rbx
int 3
xor rsp, rsp
int 3
xor rbp, rbp
int 3
xor rsi, rsi
int 3
xor rdi, rdi
int 3
xor r8, r8
int 3
xor r9, r9
int 3
xor r10, r10
int 3
xor r11, r11
int 3
xor r12, r12
int 3
xor r13, r13
int 3
xor r14, r14
int 3
xor r15, r15
int 3
jmp rax
int 3
jmp rbx
int 3
jmp rcx
int 3
jmp rdx
int 3
push rax
int 3
push rbx
int 3
push rcx
int 3
push rdx
int 3
push 0
int 3
pop rax
int 3
pop rbx
int 3
pop rcx
int 3
pop rdx
int 3
mov rax,[value]
int 3
sub rsp,0418h
int 3
mov [rsp+0410h],rbx
int 3
mov [rsp+0408h],rsi
int 3
mov [rsp+0400h],rdi
int 3
mov [rsp+03f8h],r12
int 3
mov [rsp+03f0h],r13
int 3
mov [rsp+03e8h],r14
int 3
mov [rsp+03e0h],r15
int 3
add [rax],al ; 0000
int 3
add [rcx],al ; 0001
int 3
add [rbx],al ; 0003
int 3
add [rax+rax],al ; 000400
int 3
add [rdi],al ; 0007
int 3
add [rax],cl ; 0008
int 3
add [rdi],cl ; 000f
int 3
add [rax],dl ; 0010
int 3
add [rdi],bl ; 001f
int 3
add [rax],ah ; 0020
int 3
add [rdi],bh ; 003f
int 3
add [rax+03bh],cl ; 00483b
int 3
add [rdi],bh ; 007f00
int 3
add [rax+040000000h],al ; 008000000040
int 3
add bh,bh ; 00ff
int 3
add [rax],eax ; 0100
int 3
add al,[rax] ; 0200
int 3
add eax,06603ebc3h ; 05c3eb0366
int 3
syscall ; 0f05
int 3
prefetchw byte ptr [rcx] ; 0f0d09
int 3
prefetchnta byte ptr [rcx] ; 0f1801
int 3
prefetchnta byte ptr [rax+rdx] ; 0f180410
int 3
jb again ; 0f8247070000
int 3
jnb again ; 0f8306050000
int 3
je again ; 0f8432010000
int 3
jne again ; 0f8508010000
int 3
jnbe again ; 0f878a000000
int 3
ldmxcsr dword ptr [rcx+034h] ; 0fae5134
int 3
stmxcsr dword ptr [rcx+034h] ; 0fae5934
int 3
and ecx,[rdx+rbx*4] ; 230c9a
int 3
xor eax,eax ; 33c0
int 3
xor ecx,ecx ; 33c9
int 3
xor edx,ecx ; 33d1
int 3
xor edx,edx ; 33d2
int 3
add r10d,010001h ; 4181c201000100
int 3
and r11d,0ffffh ; 4181e3ffff0000
int 3
mov eax,r8d ; 418bc0
int 3
mov byte ptr [r11],00h ; 41c60300
int 3
call qword ptr [r9+030h] ; 41ff5130
int 3
call qword ptr [r9+r8*8] ; 43ff14c1
int 3
mov [rcx+034h],r8d ; 44894134
int 3
mov [rsp+030h],r9d ; 44894c2430
int 3
mov r8d,[rcx] ; 448b01
int 3
mov r9d,[rcx] ; 448b09
int 3
mov r8d,[rax+058h] ; 448b4058
int 3
mov r8d,[rsp+02ch] ; 448b44242c
int 3
mov r8d,eax ; 448bc0
int 3
mov r8d,edx ; 448bc2
int 3
xor r8b,r8b ; 4532c0
int 3
mov r9d,r8d ; 458bc8
int 3
lea r11d,[r9+rax] ; 458d1c01
int 3
add rdx,rcx ; 4803d1
int 3
or rsi,rdx ; 480bf2
int 3
movnti [rcx],rax ; 480fc301
int 3
and rax,0fe000000h ; 4825000000fe
int 3
sub rax,rcx ; 482bc1
int 3
sub rdx,rcx ; 482bd1
int 3
cmp rdi,rbp ; 483bfd
int 3
push rbp ; 4855
int 3
add rcx,03d0h ; 4881c1d0030000
int 3
add rsp,0c8h ; 4881c4c8000000
int 3
and rdx,0fe000000h ; 4881e2000000fe
int 3
sub rsp,0c8h ; 4881ecc8000000
int 3
sub rsp,03d0h ; 4881ecd0030000
int 3
add rax,040h ; 4883c040
int 3
add rcx,08h ; 4883c108
int 3
add rcx,040h ; 4883c140
int 3
add rsp,08h ; 4883c408
int 3
add rsi,09h ; 4883c609
int 3
add rdi,01h ; 4883c701
int 3
and rcx,0f8h ; 4883e1f8
int 3
sub rax,040h ; 4883e840
int 3
sub rdx,08h ; 4883ea08
int 3
sub rdx,040h ; 4883ea40
int 3
sub rsp,08h ; 4883ec08
int 3
sub rsi,08h ; 4883ee08
int 3
sub rdi,01h ; 4883ef01
int 3
test rax,rax ; 4885c0
int 3
test rdx,rdx ; 4885d2
int 3
mov [rsp],rax ; 48890424
int 3
mov [rsp],rbp ; 48892c24
int 3
mov [rsp],rsi ; 48893424
int 3
mov [rsp],rdi ; 48893c24
int 3
mov [rcx+08h],rax ; 48894108
int 3
mov [rcx+078h],rax ; 48894178
int 3
mov [rcx-08h],rax ; 488941f8
int 3
mov [rsp+018h],rax ; 4889442418
int 3
mov [rcx+010h],rdx ; 48895110
int 3
mov [rsp+08h],rbx ; 48895c2408
int 3
mov [rsp+018h],rsi ; 4889742418
int 3
mov [rsp+08h],rdi ; 48897c2408
int 3
mov [rsp+010h],rdi ; 48897c2410
int 3
mov [rcx+098h],rax ; 48898198000000
int 3
mov [rcx+080h],rcx ; 48898980000000
int 3
mov [rcx+088h],rdx ; 48899188000000
int 3
mov [rcx+090h],rbx ; 48899990000000
int 3
mov [rcx+0a0h],rbp ; 4889a9a0000000
int 3
mov [rcx+0a8h],rsi ; 4889b1a8000000
int 3
mov [rcx+0b0h],rdi ; 4889b9b0000000
int 3
mov rax,[rcx] ; 488b01
int 3
mov rax,[rcx+rdx] ; 488b0411
int 3
mov rax,[value] ; 488b05318c0100
int 3
mov rcx,[rsp] ; 488b0c24
int 3
mov rsi,[rsp] ; 488b3424
int 3
mov rdi,[rsp] ; 488b3c24
int 3
mov rax,[rax+018h] ; 488b4018
int 3
mov rax,[rcx+078h] ; 488b4178
int 3
mov rax,[rdx+020h] ; 488b4220
int 3
mov rax,[rsp+08h] ; 488b442408
int 3
mov rcx,[rcx+08h] ; 488b4908
int 3
mov rcx,[rsp+020h] ; 488b4c2420
int 3
mov rdx,[rsp+08h] ; 488b542408
int 3
mov rdi,[rsp+08h] ; 488b7c2408
int 3
mov rax,[rcx+098h] ; 488b8198000000
int 3
mov rax,[rcx+0f8h] ; 488b81f8000000
int 3
cmp ebx,0 ;
int 3
cmp rbx,0 ;
int 3
cmp byte ptr [value],77h ; 803d........77
int 3
cmp dword ptr [value],77h ; 833d........77
int 3
cmp qword ptr [value],77h ; 48833d........77
int 3
cmp dword ptr [value],77777777h ; 813d........77777777
int 3
cmp qword ptr [value],77777777h ; 48813d........77777777
int 3
nearby:
jo nearby ; 70xx
int 3
jno nearby ; 71xx
int 3
jb nearby ; 72xx
int 3
jae nearby ; 73xx
int 3
je nearby ; 74xx
int 3
jne nearby ; 75xx
int 3
jbe nearby ; 76xx
int 3
ja nearby ; 77xx
int 3
js nearby ; 78xx
int 3
jns nearby ; 79xx
int 3
jp nearby ; 7axx
int 3
jnp nearby ; 7bxx
int 3
jl nearby ; 7cxx
int 3
jge nearby ; 7dxx
int 3
jle nearby ; 7exx
int 3
jg nearby ; 7fxx
int 3
jmp nearby ; ebxx
int 3
jo faraway ; 0f80xxxxxxxx
int 3
jno faraway ; 0f81xxxxxxxx
int 3
jb faraway ; 0f82xxxxxxxx
int 3
jae faraway ; 0f83xxxxxxxx
int 3
je faraway ; 0f84xxxxxxxx
int 3
jne faraway ; 0f85xxxxxxxx
int 3
jbe faraway ; 0f86xxxxxxxx
int 3
ja faraway ; 0f87xxxxxxxx
int 3
js faraway ; 0f88xxxxxxxx
int 3
jns faraway ; 0f89xxxxxxxx
int 3
jp faraway ; 0f8axxxxxxxx
int 3
jnp faraway ; 0f8bxxxxxxxx
int 3
jl faraway ; 0f8cxxxxxxxx
int 3
jge faraway ; 0f8dxxxxxxxx
int 3
jle faraway ; 0f8exxxxxxxx
int 3
jg faraway ; 0f8fxxxxxxxx
int 3
jmp faraway ; e9xxxxxxxx
int 3
lea rax,[rsp] ; 488d0424
int 3
mov rcx,0BADC0DEBA5Eh ; 48b95ebadec0ad0b0000
int 3
cmp rax,rcx ; 483bc1
int 3
sub rsp, 28h
int 3
add rsp,28h
int 3
ret
int 3
;; The list is terminated by two "int 3" in a row.
again:
int 3
int 3
TestCodes ENDP
value QWORD 0
_TEXT ENDS
END

184
samples/disas/x86.cpp Normal file
View File

@@ -0,0 +1,184 @@
/////////////////////////////////////////////////////////////////////////////
//
// Detours Test Program (x86.asm of disas.exe)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
static int value = 0;
extern "C" void __declspec(naked) TestCodes()
{
__asm {
// Each instruction is proceeded by an "int 3".
faraway:
int 3;
nop; // 1-byte NOP.
int 3;
_emit 0x66; // 2-byte NOP.
_emit 0x90;
int 3;
_emit 0x0f; // 3-byte NOP.
_emit 0x1f;
_emit 0x00;
int 3;
_emit 0x0f; // 4-byte NOP.
_emit 0x1f;
_emit 0x40;
_emit 0x00;
int 3;
_emit 0x0f; // 5-byte NOP.
_emit 0x1f;
_emit 0x44;
_emit 0x00;
_emit 0x00;
int 3;
_emit 0x66; // 6-byte NOP.
_emit 0x0f;
_emit 0x1f;
_emit 0x44;
_emit 0x00;
_emit 0x00;
int 3;
_emit 0x0f; // 7-byte NOP.
_emit 0x1f;
_emit 0x80;
_emit 0x00;
_emit 0x00;
_emit 0x00;
_emit 0x00;
int 3;
_emit 0x0f; // 8-byte NOP.
_emit 0x1f;
_emit 0x84;
_emit 0x00;
_emit 0x00;
_emit 0x00;
_emit 0x00;
_emit 0x00;
int 3;
_emit 0x66; // 9-byte NOP.
_emit 0x0f;
_emit 0x1f;
_emit 0x84;
_emit 0x00;
_emit 0x00;
_emit 0x00;
_emit 0x00;
_emit 0x00;
int 3;
mov ecx, eax;
int 3;
mov ebx, 0ffff000eh;
int 3;
call ebx;
int 3;
call dword ptr [eax];
int 3;
call dword ptr [ebx];
int 3;
call dword ptr [ecx];
int 3;
call dword ptr [edx];
int 3;
jmp dword ptr [eax];
int 3;
jmp dword ptr [ebx];
int 3;
jmp dword ptr [ecx];
int 3;
jmp dword ptr [edx];
int 3;
call ecx;
int 3;
call eax;
int 3;
mov ebx, 0ffff000eh;
int 3;
push eax;
int 3;
call ebx;
int 3;
cmp ebx, 0;
int 3;
cmp byte ptr [value], 77h;
int 3;
cmp dword ptr [value], 77h;
int 3;
cmp dword ptr [value], 77777777h;
nearby:
int 3
jo nearby ; 70xx
int 3
jno nearby ; 71xx
int 3
jb nearby ; 72xx
int 3
jae nearby ; 73xx
int 3
je nearby ; 74xx
int 3
jne nearby ; 75xx
int 3
jbe nearby ; 76xx
int 3
ja nearby ; 77xx
int 3
js nearby ; 78xx
int 3
jns nearby ; 79xx
int 3
jp nearby ; 7axx
int 3
jnp nearby ; 7bxx
int 3
jl nearby ; 7cxx
int 3
jge nearby ; 7dxx
int 3
jle nearby ; 7exx
int 3
jg nearby ; 7fxx
int 3
jo faraway ; 0f80xx
int 3
jno faraway ; 0f81xx
int 3
jb faraway ; 0f82xx
int 3
jae faraway ; 0f83xx
int 3
je faraway ; 0f84xx
int 3
jne faraway ; 0f85xx
int 3
jbe faraway ; 0f86xx
int 3
ja faraway ; 0f87xx
int 3
js faraway ; 0f88xx
int 3
jns faraway ; 0f89xx
int 3
jp faraway ; 0f8axx
int 3
jnp faraway ; 0f8bxx
int 3
jl faraway ; 0f8cxx
int 3
jge faraway ; 0f8dxx
int 3
jle faraway ; 0f8exx
int 3
jg faraway ; 0f8fxx
// The list is terminated by two "int 3" in a row.
int 3;
int 3;
ret;
}
}

107
samples/dtest/Makefile Normal file
View File

@@ -0,0 +1,107 @@
##############################################################################
##
## Makefile for Detours Test Programs.
##
## Microsoft Research Detours Package
##
## Copyright (c) Microsoft Corporation. All rights reserved.
##
!include ..\common.mak
LIBS=$(LIBS) kernel32.lib
all: dirs \
$(BIND)\dtarge$(DETOURS_BITS).dll \
$(BIND)\dtest.exe \
!IF $(DETOURS_SOURCE_BROWSING)==1
$(OBJD)\dtarge$(DETOURS_BITS).bsc \
$(OBJD)\dtest.bsc \
!ENDIF
option
clean:
-del *~ *.obj *.sbr 2> nul
-del $(BIND)\dtest.* $(BIND)\dtarge*.* 2> nul
-rmdir /q /s $(OBJD) 2>nul
realclean: clean
-rmdir /q /s $(OBJDS) 2>nul
dirs:
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
$(OBJD)\dtarge.obj : dtarge.cpp
$(OBJD)\dtarge.res : dtarge.rc
$(BIND)\dtarge$(DETOURS_BITS).dll $(BIND)\dtarge$(DETOURS_BITS).lib: \
$(OBJD)\dtarge.obj $(OBJD)\dtarge.res $(DEPS)
cl /LD $(CFLAGS) \
/Fe$(@R).dll \
/Fd$(@R).pdb \
$(OBJD)\dtarge.obj $(OBJD)\dtarge.res \
/link $(LINKFLAGS) /subsystem:console \
/export:Target0 \
/export:Target1 \
/export:Target2 \
/export:Target3 \
/export:Target4 \
/export:Target5 \
/export:Target6 \
/export:Target7 \
/export:Target8 \
/export:Target9 \
/export:Target10 \
/export:Target11 \
/export:Target12 \
/export:Target13 \
/export:Target14 \
/export:Target15 \
/export:Target16 \
/export:TargetV \
/export:TargetR \
$(LIBS)
$(OBJD)\dtarge$(DETOURS_BITS).bsc : $(OBJD)\dtarge.obj
bscmake /v /n /o $@ $(OBJD)\dtarge.sbr
$(OBJD)\dtest.obj : dtest.cpp
$(BIND)\dtest.exe : $(OBJD)\dtest.obj $(BIND)\dtarge$(DETOURS_BITS).lib $(DEPS)
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\dtest.obj \
/link $(LINKFLAGS) $(LIBS) $(BIND)\dtarge$(DETOURS_BITS).lib \
/subsystem:console /entry:WinMainCRTStartup
$(OBJD)\dtest.bsc : $(OBJD)\dtest.obj
bscmake /v /n /o $@ $(OBJD)\dtest.sbr
############################################### Install non-bit-size binaries.
!IF "$(DETOURS_OPTION_PROCESSOR)" != ""
$(OPTD)\dtarge$(DETOURS_OPTION_BITS).dll:
$(OPTD)\dtarge$(DETOURS_OPTION_BITS).pdb:
$(BIND)\dtarge$(DETOURS_OPTION_BITS).dll : $(OPTD)\dtarge$(DETOURS_OPTION_BITS).dll
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
$(BIND)\dtarge$(DETOURS_OPTION_BITS).pdb : $(OPTD)\dtarge$(DETOURS_OPTION_BITS).pdb
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
option: \
$(BIND)\dtarge$(DETOURS_OPTION_BITS).dll \
$(BIND)\dtarge$(DETOURS_OPTION_BITS).pdb \
!ELSE
option:
!ENDIF
##############################################################################
test: all
$(BIND)\dtest.exe
################################################################# End of File.

View File

@@ -0,0 +1,116 @@
..\..\bin.IA64\dtest.exe
Calling LocalTarget1 w/o detour
LocalTarget1 (1)
Calling LocalTarget1 w/ detour
MyLocalTarget1 (2)
LocalTarget1 (2)
Calling Target0 function.
MyTarget0 ()
Calling TargetN functions.
MyLocalTarget1 (1)
LocalTarget1 (1)
MyTarget0 ()
MyTarget1 (1)
MyTarget2 (1,2)
MyTarget3 (1,2,3)
MyTarget4 (1,2,3,4)
MyTarget5 (1,2,3,4,5)
MyTarget6 (1,2,3,4,5,6)
MyTarget7 (1,2,3,4,5,6,7)
MyTarget8 (1,2,3,4,5,6,7,8)
MyTarget9 (1,2,3,4,5,6,7,8,9)
MyTarget10(1,2,3,4,5,6,7,8,9,10)
MyTarget11(1,2,3,4,5,6,7,8,9,10,11)
MyTarget12(1,2,3,4,5,6,7,8,9,10,11,12)
MyTarget13(1,2,3,4,5,6,7,8,9,10,11,12,13)
MyTarget14(1,2,3,4,5,6,7,8,9,10,11,12,13,14)
MyTarget15(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
MyTarget16(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
MyTargetV (0)
MyTargetV (0,1)
MyTargetV (0,1,2)
MyTargetV (0,1,2,3)
MyTargetV (0,1,2,3,4)
MyTargetV (0,1,2,3,4,5)
MyTargetV (0,1,2,3,4,5,6)
MyTargetV (0,1,2,3,4,5,6,7)
MyTargetV (0,1,2,3,4,5,6,7,8)
MyTargetV (0,1,2,3,4,5,6,7,8,9)
MyTargetV (0,1,2,3,4,5,6,7,8,9,10)
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11)
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11,12)
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13)
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14)
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
MyTargetR (0,1,2,3,4)
MyTargetR (0,1,2,3,3)
MyTargetR (0,1,2,3,2)
MyTargetR (0,1,2,3,1)
.................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................... MyTargetR (0,1,2,3,4,5,6,7,8,9,10,4)
MyTargetR (0,1,2,3,4,5,6,7,8,9,10,3)
MyTargetR (0,1,2,3,4,5,6,7,8,9,10,2)
MyTargetR (0,1,2,3,4,5,6,7,8,9,10,1)
=> 3011
Calling Target0 again with 1 detour.
MyTarget0 ()
Calling Target0 again with 2 detours.
Starting Target0_1.
MyTarget0 ()
End Target0_1.
Calling Target0 again with 3 detours.
Starting Target0_2.
Starting Target0_1.
MyTarget0 ()
End Target0_1.
End Target0_2.
Calling Target0 again with 4 detours.
Starting Target0_3.
Starting Target0_2.
Starting Target0_1.
MyTarget0 ()
End Target0_1.
End Target0_2.
End Target0_3.
Done.
Target0 ()
Target0 ()
Target1 (1)
Target2 (1,2)
Target3 (1,2,3)
Target4 (1,2,3,4)
Target5 (1,2,3,4,5)
Target6 (1,2,3,4,5,6)
Target7 (1,2,3,4,5,6,7)
Target8 (1,2,3,4,5,6,7,8)
Target9 (1,2,3,4,5,6,7,8,9)
Target10(1,2,3,4,5,6,7,8,9,10)
Target11(1,2,3,4,5,6,7,8,9,10,11)
Target12(1,2,3,4,5,6,7,8,9,10,11,12)
Target13(1,2,3,4,5,6,7,8,9,10,11,12,13)
Target14(1,2,3,4,5,6,7,8,9,10,11,12,13,14)
Target15(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
Target16(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
TargetV (0)
TargetV (0,1)
TargetV (0,1,2)
TargetV (0,1,2,3)
TargetV (0,1,2,3,4)
TargetV (0,1,2,3,4,5)
TargetV (0,1,2,3,4,5,6)
TargetV (0,1,2,3,4,5,6,7)
TargetV (0,1,2,3,4,5,6,7,8)
TargetV (0,1,2,3,4,5,6,7,8,9)
TargetV (0,1,2,3,4,5,6,7,8,9,10)
TargetV (0,1,2,3,4,5,6,7,8,9,10,11)
TargetV (0,1,2,3,4,5,6,7,8,9,10,11,12)
TargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13)
TargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14)
TargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
TargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
::: TargetR (0,1,2,3,1)
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: TargetR (0,1,2,3,4,5,6,7,8,9,10,1)
Target0 ()
Target0 ()
Target0 ()
Target0 ()

View File

@@ -0,0 +1,116 @@
..\..\bin.X64\dtest.exe
Calling LocalTarget1 w/o detour
LocalTarget1 (1)
Calling LocalTarget1 w/ detour
MyLocalTarget1 (2)
LocalTarget1 (2)
Calling Target0 function.
MyTarget0 ()
Calling TargetN functions.
MyLocalTarget1 (1)
LocalTarget1 (1)
MyTarget0 ()
MyTarget1 (1)
MyTarget2 (1,2)
MyTarget3 (1,2,3)
MyTarget4 (1,2,3,4)
MyTarget5 (1,2,3,4,5)
MyTarget6 (1,2,3,4,5,6)
MyTarget7 (1,2,3,4,5,6,7)
MyTarget8 (1,2,3,4,5,6,7,8)
MyTarget9 (1,2,3,4,5,6,7,8,9)
MyTarget10(1,2,3,4,5,6,7,8,9,10)
MyTarget11(1,2,3,4,5,6,7,8,9,10,11)
MyTarget12(1,2,3,4,5,6,7,8,9,10,11,12)
MyTarget13(1,2,3,4,5,6,7,8,9,10,11,12,13)
MyTarget14(1,2,3,4,5,6,7,8,9,10,11,12,13,14)
MyTarget15(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
MyTarget16(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
MyTargetV (0)
MyTargetV (0,1)
MyTargetV (0,1,2)
MyTargetV (0,1,2,3)
MyTargetV (0,1,2,3,4)
MyTargetV (0,1,2,3,4,5)
MyTargetV (0,1,2,3,4,5,6)
MyTargetV (0,1,2,3,4,5,6,7)
MyTargetV (0,1,2,3,4,5,6,7,8)
MyTargetV (0,1,2,3,4,5,6,7,8,9)
MyTargetV (0,1,2,3,4,5,6,7,8,9,10)
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11)
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11,12)
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13)
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14)
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
MyTargetR (0,1,2,3,4)
MyTargetR (0,1,2,3,3)
MyTargetR (0,1,2,3,2)
MyTargetR (0,1,2,3,1)
.................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................... MyTargetR (0,1,2,3,4,5,6,7,8,9,10,4)
MyTargetR (0,1,2,3,4,5,6,7,8,9,10,3)
MyTargetR (0,1,2,3,4,5,6,7,8,9,10,2)
MyTargetR (0,1,2,3,4,5,6,7,8,9,10,1)
=> 3011
Calling Target0 again with 1 detour.
MyTarget0 ()
Calling Target0 again with 2 detours.
Starting Target0_1.
MyTarget0 ()
End Target0_1.
Calling Target0 again with 3 detours.
Starting Target0_2.
Starting Target0_1.
MyTarget0 ()
End Target0_1.
End Target0_2.
Calling Target0 again with 4 detours.
Starting Target0_3.
Starting Target0_2.
Starting Target0_1.
MyTarget0 ()
End Target0_1.
End Target0_2.
End Target0_3.
Done.
Target0 ()
Target0 ()
Target1 (1)
Target2 (1,2)
Target3 (1,2,3)
Target4 (1,2,3,4)
Target5 (1,2,3,4,5)
Target6 (1,2,3,4,5,6)
Target7 (1,2,3,4,5,6,7)
Target8 (1,2,3,4,5,6,7,8)
Target9 (1,2,3,4,5,6,7,8,9)
Target10(1,2,3,4,5,6,7,8,9,10)
Target11(1,2,3,4,5,6,7,8,9,10,11)
Target12(1,2,3,4,5,6,7,8,9,10,11,12)
Target13(1,2,3,4,5,6,7,8,9,10,11,12,13)
Target14(1,2,3,4,5,6,7,8,9,10,11,12,13,14)
Target15(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
Target16(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
TargetV (0)
TargetV (0,1)
TargetV (0,1,2)
TargetV (0,1,2,3)
TargetV (0,1,2,3,4)
TargetV (0,1,2,3,4,5)
TargetV (0,1,2,3,4,5,6)
TargetV (0,1,2,3,4,5,6,7)
TargetV (0,1,2,3,4,5,6,7,8)
TargetV (0,1,2,3,4,5,6,7,8,9)
TargetV (0,1,2,3,4,5,6,7,8,9,10)
TargetV (0,1,2,3,4,5,6,7,8,9,10,11)
TargetV (0,1,2,3,4,5,6,7,8,9,10,11,12)
TargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13)
TargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14)
TargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
TargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
::: TargetR (0,1,2,3,1)
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: TargetR (0,1,2,3,4,5,6,7,8,9,10,1)
Target0 ()
Target0 ()
Target0 ()
Target0 ()

View File

@@ -0,0 +1,116 @@
..\..\bin.X86\dtest.exe
Calling LocalTarget1 w/o detour
LocalTarget1 (1)
Calling LocalTarget1 w/ detour
MyLocalTarget1 (2)
LocalTarget1 (2)
Calling Target0 function.
MyTarget0 ()
Calling TargetN functions.
MyLocalTarget1 (1)
LocalTarget1 (1)
MyTarget0 ()
MyTarget1 (1)
MyTarget2 (1,2)
MyTarget3 (1,2,3)
MyTarget4 (1,2,3,4)
MyTarget5 (1,2,3,4,5)
MyTarget6 (1,2,3,4,5,6)
MyTarget7 (1,2,3,4,5,6,7)
MyTarget8 (1,2,3,4,5,6,7,8)
MyTarget9 (1,2,3,4,5,6,7,8,9)
MyTarget10(1,2,3,4,5,6,7,8,9,10)
MyTarget11(1,2,3,4,5,6,7,8,9,10,11)
MyTarget12(1,2,3,4,5,6,7,8,9,10,11,12)
MyTarget13(1,2,3,4,5,6,7,8,9,10,11,12,13)
MyTarget14(1,2,3,4,5,6,7,8,9,10,11,12,13,14)
MyTarget15(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
MyTarget16(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
MyTargetV (0)
MyTargetV (0,1)
MyTargetV (0,1,2)
MyTargetV (0,1,2,3)
MyTargetV (0,1,2,3,4)
MyTargetV (0,1,2,3,4,5)
MyTargetV (0,1,2,3,4,5,6)
MyTargetV (0,1,2,3,4,5,6,7)
MyTargetV (0,1,2,3,4,5,6,7,8)
MyTargetV (0,1,2,3,4,5,6,7,8,9)
MyTargetV (0,1,2,3,4,5,6,7,8,9,10)
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11)
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11,12)
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13)
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14)
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
MyTargetR (0,1,2,3,4)
MyTargetR (0,1,2,3,3)
MyTargetR (0,1,2,3,2)
MyTargetR (0,1,2,3,1)
.................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................... MyTargetR (0,1,2,3,4,5,6,7,8,9,10,4)
MyTargetR (0,1,2,3,4,5,6,7,8,9,10,3)
MyTargetR (0,1,2,3,4,5,6,7,8,9,10,2)
MyTargetR (0,1,2,3,4,5,6,7,8,9,10,1)
=> 3011
Calling Target0 again with 1 detour.
MyTarget0 ()
Calling Target0 again with 2 detours.
Starting Target0_1.
MyTarget0 ()
End Target0_1.
Calling Target0 again with 3 detours.
Starting Target0_2.
Starting Target0_1.
MyTarget0 ()
End Target0_1.
End Target0_2.
Calling Target0 again with 4 detours.
Starting Target0_3.
Starting Target0_2.
Starting Target0_1.
MyTarget0 ()
End Target0_1.
End Target0_2.
End Target0_3.
Done.
Target0 ()
Target0 ()
Target1 (1)
Target2 (1,2)
Target3 (1,2,3)
Target4 (1,2,3,4)
Target5 (1,2,3,4,5)
Target6 (1,2,3,4,5,6)
Target7 (1,2,3,4,5,6,7)
Target8 (1,2,3,4,5,6,7,8)
Target9 (1,2,3,4,5,6,7,8,9)
Target10(1,2,3,4,5,6,7,8,9,10)
Target11(1,2,3,4,5,6,7,8,9,10,11)
Target12(1,2,3,4,5,6,7,8,9,10,11,12)
Target13(1,2,3,4,5,6,7,8,9,10,11,12,13)
Target14(1,2,3,4,5,6,7,8,9,10,11,12,13,14)
Target15(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
Target16(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
TargetV (0)
TargetV (0,1)
TargetV (0,1,2)
TargetV (0,1,2,3)
TargetV (0,1,2,3,4)
TargetV (0,1,2,3,4,5)
TargetV (0,1,2,3,4,5,6)
TargetV (0,1,2,3,4,5,6,7)
TargetV (0,1,2,3,4,5,6,7,8)
TargetV (0,1,2,3,4,5,6,7,8,9)
TargetV (0,1,2,3,4,5,6,7,8,9,10)
TargetV (0,1,2,3,4,5,6,7,8,9,10,11)
TargetV (0,1,2,3,4,5,6,7,8,9,10,11,12)
TargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13)
TargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14)
TargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
TargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
::: TargetR (0,1,2,3,1)
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: TargetR (0,1,2,3,4,5,6,7,8,9,10,1)
Target0 ()
Target0 ()
Target0 ()
Target0 ()

306
samples/dtest/dtarge.cpp Normal file
View File

@@ -0,0 +1,306 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detours Test Program (dtarge.dll)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#include <stdio.h>
#include <windows.h>
#include "dtarge.h"
DWORD_PTR WINAPI Target0()
{
printf(" Target0 ()\n");
return 1000;
}
DWORD_PTR WINAPI Target1(DWORD_PTR v1)
{
printf(" Target1 (%d)\n",
(DWORD)v1);
return 1001;
}
DWORD_PTR WINAPI Target2(DWORD_PTR v1, DWORD_PTR v2)
{
printf(" Target2 (%d,%d)\n",
(DWORD)v1, (DWORD)v2);
return 1002;
}
DWORD_PTR WINAPI Target3(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3)
{
printf(" Target3 (%d,%d,%d)\n",
(DWORD)v1, (DWORD)v2, (DWORD)v3);
return 1003;
}
DWORD_PTR WINAPI Target4(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4)
{
printf(" Target4 (%d,%d,%d,%d)\n",
(DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4);
return 1004;
}
DWORD_PTR WINAPI Target5(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
DWORD_PTR v5)
{
printf(" Target5 (%d,%d,%d,%d,%d)\n",
(DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
(DWORD)v5);
return 1005;
}
DWORD_PTR WINAPI Target6(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
DWORD_PTR v5, DWORD_PTR v6)
{
printf(" Target6 (%d,%d,%d,%d,%d,%d)\n",
(DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
(DWORD)v5, (DWORD)v6);
return 1006;
}
DWORD_PTR WINAPI Target7(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7)
{
printf(" Target7 (%d,%d,%d,%d,%d,%d,%d)\n",
(DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
(DWORD)v5, (DWORD)v6, (DWORD)v7);
return 1007;
}
DWORD_PTR WINAPI Target8(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8)
{
printf(" Target8 (%d,%d,%d,%d,%d,%d,%d,%d)\n",
(DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
(DWORD)v5, (DWORD)v6, (DWORD)v7, (DWORD)v8);
return 1008;
}
DWORD_PTR WINAPI Target9(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
DWORD_PTR v9)
{
printf(" Target9 (%d,%d,%d,%d,%d,%d,%d,%d,%d)\n",
(DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
(DWORD)v5, (DWORD)v6, (DWORD)v7, (DWORD)v8,
(DWORD)v9);
return 1009;
}
DWORD_PTR WINAPI Target10(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
DWORD_PTR v9, DWORD_PTR v10)
{
printf(" Target10(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)\n",
(DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
(DWORD)v5, (DWORD)v6, (DWORD)v7, (DWORD)v8,
(DWORD)v9, (DWORD)v10);
return 1010;
}
DWORD_PTR WINAPI Target11(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11)
{
printf(" Target11(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)\n",
(DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
(DWORD)v5, (DWORD)v6, (DWORD)v7, (DWORD)v8,
(DWORD)v9, (DWORD)v10, (DWORD)v11);
return 1011;
}
DWORD_PTR WINAPI Target12(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12)
{
printf(" Target12(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)\n",
(DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
(DWORD)v5, (DWORD)v6, (DWORD)v7, (DWORD)v8,
(DWORD)v9, (DWORD)v10, (DWORD)v11, (DWORD)v12);
return 1012;
}
DWORD_PTR WINAPI Target13(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12,
DWORD_PTR v13)
{
printf(" Target13(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)\n",
(DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
(DWORD)v5, (DWORD)v6, (DWORD)v7, (DWORD)v8,
(DWORD)v9, (DWORD)v10, (DWORD)v11, (DWORD)v12,
(DWORD)v13);
return 1013;
}
DWORD_PTR WINAPI Target14(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12,
DWORD_PTR v13, DWORD_PTR v14)
{
printf(" Target14(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)\n",
(DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
(DWORD)v5, (DWORD)v6, (DWORD)v7, (DWORD)v8,
(DWORD)v9, (DWORD)v10, (DWORD)v11, (DWORD)v12,
(DWORD)v13, (DWORD)v14);
return 1014;
}
DWORD_PTR WINAPI Target15(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12,
DWORD_PTR v13, DWORD_PTR v14, DWORD_PTR v15)
{
printf(" Target15(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)\n",
(DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
(DWORD)v5, (DWORD)v6, (DWORD)v7, (DWORD)v8,
(DWORD)v9, (DWORD)v10, (DWORD)v11, (DWORD)v12,
(DWORD)v13, (DWORD)v14, (DWORD)v15);
return 1015;
}
DWORD_PTR WINAPI Target16(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12,
DWORD_PTR v13, DWORD_PTR v14, DWORD_PTR v15, DWORD_PTR v16)
{
printf(" Target16(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)\n",
(DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
(DWORD)v5, (DWORD)v6, (DWORD)v7, (DWORD)v8,
(DWORD)v9, (DWORD)v10, (DWORD)v11, (DWORD)v12,
(DWORD)v13, (DWORD)v14, (DWORD)v15, (DWORD)v16);
return 1016;
}
DWORD_PTR WINAPI TargetV(DWORD_PTR v1, ...)
{
DWORD_PTR args[32];
va_list va;
va_start(va, v1);
int argc = 0;
for (args[argc++] = v1; args[argc-1] != 0;) {
args[argc++] = va_arg(va, DWORD_PTR);
}
va_end(va);
printf(" TargetV (");
int i = argc - 1;
for (; i > 0; i--) {
printf("%d,", (DWORD)args[i]);
}
printf("%d)\n", (DWORD)args[0]);
return 1000 + argc;
}
DWORD_PTR WINAPI TargetR(DWORD_PTR v1, ...)
{
DWORD_PTR args[32];
va_list va;
va_start(va, v1);
int argc = 0;
for (args[argc++] = v1; args[argc-1] != 0;) {
args[argc++] = va_arg(va, DWORD_PTR);
}
va_end(va);
if (v1 > 1) {
printf(":");
switch (argc) {
default:
return TargetR(0) + 1;
case 1:
return TargetR(args[0] - 1) + 1;
case 2:
return TargetR(args[0] - 1, args[1]) + 1;
case 3:
return TargetR(args[0] - 1, args[1], args[2]) + 1;
case 4:
return TargetR(args[0] - 1, args[1], args[2], args[3]) + 1;
case 5:
return TargetR(args[0] - 1, args[1], args[2], args[3],
args[4]) + 1;
case 6:
return TargetR(args[0] - 1, args[1], args[2], args[3],
args[4], args[5]) + 1;
case 7:
return TargetR(args[0] - 1, args[1], args[2], args[3],
args[4], args[5], args[6]) + 1;
case 8:
return TargetR(args[0] - 1, args[1], args[2], args[3],
args[4], args[5], args[6], args[7]) + 1;
case 9:
return TargetR(args[0] - 1, args[1], args[2], args[3],
args[4], args[5], args[6], args[7],
args[8]) + 1;
case 10:
return TargetR(args[0] - 1, args[1], args[2], args[3],
args[4], args[5], args[6], args[7],
args[8], args[9]) + 1;
case 11:
return TargetR(args[0] - 1, args[1], args[2], args[3],
args[4], args[5], args[6], args[7],
args[8], args[9], args[10]) + 1;
case 12:
return TargetR(args[0] - 1, args[1], args[2], args[3],
args[4], args[5], args[6], args[7],
args[8], args[9], args[10], args[11]) + 1;
case 13:
return TargetR(args[0] - 1, args[1], args[2], args[3],
args[4], args[5], args[6], args[7],
args[8], args[9], args[10], args[11],
args[12]) + 1;
case 14:
return TargetR(args[0] - 1, args[1], args[2], args[3],
args[4], args[5], args[6], args[7],
args[8], args[9], args[10], args[11],
args[12], args[13]) + 1;
case 15:
return TargetR(args[0] - 1, args[1], args[2], args[3],
args[4], args[5], args[6], args[7],
args[8], args[9], args[10], args[11],
args[12], args[13], args[14]) + 1;
case 16:
return TargetR(args[0] - 1, args[1], args[2], args[3],
args[4], args[5], args[6], args[7],
args[8], args[9], args[10], args[11],
args[12], args[13], args[14], args[15]) + 1;
case 17:
return TargetR(args[0] - 1, args[1], args[2], args[3],
args[4], args[5], args[6], args[7],
args[8], args[9], args[10], args[11],
args[12], args[13], args[14], args[15],
args[16]) + 1;
}
}
printf(" TargetR (");
int i = argc - 1;
for (; i > 0; i--) {
printf("%d,", (DWORD)args[i]);
}
printf("%d)\n", (DWORD)args[0]);
return 2000 + argc;
}
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
{
(void)hinst;
(void)dwReason;
(void)reserved;
return TRUE;
}
//
///////////////////////////////////////////////////////////////// End of File.

59
samples/dtest/dtarge.h Normal file
View File

@@ -0,0 +1,59 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detours Test Program (dtarge.h of dtarge.dll)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#if (_MSC_VER < 1299)
typedef DWORD DWORD_PTR;
#endif
DWORD_PTR WINAPI Target0();
DWORD_PTR WINAPI Target1(DWORD_PTR v1);
DWORD_PTR WINAPI Target2(DWORD_PTR v1, DWORD_PTR v2);
DWORD_PTR WINAPI Target3(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3);
DWORD_PTR WINAPI Target4(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4);
DWORD_PTR WINAPI Target5(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
DWORD_PTR v5);
DWORD_PTR WINAPI Target6(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
DWORD_PTR v5, DWORD_PTR v6);
DWORD_PTR WINAPI Target7(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7);
DWORD_PTR WINAPI Target8(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8);
DWORD_PTR WINAPI Target9(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
DWORD_PTR v9);
DWORD_PTR WINAPI Target10(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
DWORD_PTR v9, DWORD_PTR v10);
DWORD_PTR WINAPI Target11(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11);
DWORD_PTR WINAPI Target12(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12);
DWORD_PTR WINAPI Target13(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12,
DWORD_PTR v13);
DWORD_PTR WINAPI Target14(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12,
DWORD_PTR v13, DWORD_PTR v14);
DWORD_PTR WINAPI Target15(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12,
DWORD_PTR v13, DWORD_PTR v14, DWORD_PTR v15);
DWORD_PTR WINAPI Target16(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12,
DWORD_PTR v13, DWORD_PTR v14, DWORD_PTR v15, DWORD_PTR v16);
DWORD_PTR WINAPI TargetV(DWORD_PTR v1, ...);
DWORD_PTR WINAPI TargetR(DWORD_PTR v1, ...);
//
///////////////////////////////////////////////////////////////// End of File.

17
samples/dtest/dtarge.rc Normal file
View File

@@ -0,0 +1,17 @@
//////////////////////////////////////////////////////////////////////////////
//
// Version information for dtarge.rc.
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#include "detver.h"
#define VER_INTERNALNAME_STR "dtarge" DETOURS_STRINGIFY(DETOURS_BITS)
#define VER_ORIGINALFILENAME_STR "dtarge" DETOURS_STRINGIFY(DETOURS_BITS) ".dll"
#define VER_FILEDESCRIPTION_STR "Detours Test Module"
#define VER_COMPANYNAME_STR "Microsoft Corporation"
#include "common.ver"

658
samples/dtest/dtest.cpp Normal file
View File

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

53
samples/dumpe/Makefile Normal file
View File

@@ -0,0 +1,53 @@
##############################################################################
##
## Makefile for Detours Test Programs.
##
## Microsoft Research Detours Package
##
## Copyright (c) Microsoft Corporation. All rights reserved.
##
!include ..\common.mak
LIBS=$(LIBS) kernel32.lib
all: dirs \
$(BIND)\dumpe.exe \
!IF $(DETOURS_SOURCE_BROWSING)==1
$(OBJD)\dumpe.bsc
!ENDIF
clean:
-del *~ 2>nul
-del $(BIND)\dumpe.* 2>nul
-rmdir /q /s $(OBJD) 2>nul
realclean: clean
-rmdir /q /s $(OBJDS) 2>nul
dirs:
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
$(OBJD)\dumpe.obj : dumpe.cpp
$(BIND)\dumpe.exe : $(OBJD)\dumpe.obj $(DEPS)
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\dumpe.obj \
/link $(LINKFLAGS) $(LIBS) \
/subsystem:console
$(OBJD)\dumpe.bsc : $(OBJD)\dumpe.obj
bscmake /v /n /o $@ $(OBJD)\dumpe.sbr
##############################################################################
test: $(BIND)\dumpe.exe
$(BIND)\dumpe.exe $(BIND)\slept.dll
testx: $(BIND)\dumpe.exe
cd $(MAKEDIR)\..\..\src
nmake
cd $(MAKEDIR)
if exist $(SYSTEMROOT)\system32\browseui.dll $(BIND)\dumpe.exe browseui.dll
################################################################# End of File.

129
samples/dumpe/dumpe.cpp Normal file
View File

@@ -0,0 +1,129 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detours Test Program (dumpe.cpp of dumpe.exe)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <ole2.h>
#include <shellapi.h>
#include "detours.h"
//////////////////////////////////////////////////////////////////////////////
//
#ifndef NODEBUG
#undef ASSERT
VOID DetourAssertMessage(CONST PCHAR szMsg, CONST PCHAR szFile, DWORD nLine);
#define ASSERT(x) \
do { if (!(x)) { DetourAssertMessage(#x, __FILE__, __LINE__); DebugBreak(); }} while (0)
;
#undef ASSERTX
#define ASSERTX(x) \
do { if (!(x)) { DetourAssertMessage(#x, __FILE__, __LINE__); PCHAR p=(PCHAR)(x); *p = 1; }} while (0)
;
#else // NODEBUG
#undef ASSERT
#define ASSERT(x)
#undef ASSERTX
#define ASSERTX(x)
#endif // NODEBUG
//
//////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////// Error Messages.
//
VOID DetourAssertMessage(CONST PCHAR szMsg, CONST PCHAR szFile, DWORD nLine)
{
printf("ASSERT(%s) failed in %s, line %d.", szMsg, szFile, nLine);
}
static BOOL CALLBACK ExportCallback(PVOID pContext,
ULONG nOrdinal,
LPCSTR pszSymbol,
PVOID pbTarget)
{
(void)pContext;
printf(" %7d %p %-30s\n",
(ULONG)nOrdinal,
pbTarget,
pszSymbol ? pszSymbol : "[NONAME]");
return TRUE;
}
BOOL DumpFile(PCHAR pszPath)
{
HINSTANCE hInst = LoadLibraryA(pszPath);
if (hInst == NULL) {
printf("Unable to load %s: Error %d\n", pszPath, GetLastError());
return FALSE;
}
printf("%s @ %p\n", pszPath, hInst);
PVOID pbEntry = DetourGetEntryPoint(hInst);
printf(" EntryPoint: %p\n", pbEntry);
printf(" Ordinal RVA Name\n");
DetourEnumerateExports(hInst, NULL, ExportCallback);
return TRUE;
}
//////////////////////////////////////////////////////////////////////////////
//
void PrintUsage(void)
{
printf("Usage:\n"
" dumpe [.dll files]\n"
"Misc. Options:\n"
" /? : Help screen.\n");
}
//////////////////////////////////////////////////////////////////////// main.
//
int CDECL main(int argc, char **argv)
{
BOOL fNeedHelp = FALSE;
int arg = 1;
for (; arg < argc; arg++) {
if (argv[arg][0] == '-' || argv[arg][0] == '/') {
CHAR *argn = argv[arg] + 1;
CHAR *argp = argn;
while (*argp && *argp != ':')
argp++;
if (*argp == ':')
*argp++ = '\0';
switch (argn[0]) {
case '?': // Help.
fNeedHelp = TRUE;
break;
default:
fNeedHelp = TRUE;
printf("Bad argument: %s:%s\n", argn, argp);
break;
}
}
else {
DumpFile(argv[arg]);
}
}
if (fNeedHelp || argc == 1) {
PrintUsage();
return 1;
}
return 0;
}
// End of File

47
samples/dumpi/Makefile Normal file
View File

@@ -0,0 +1,47 @@
##############################################################################
##
## Makefile for Detours Test Programs - Dump Imports
##
## Microsoft Research Detours Package
##
## Copyright (c) Microsoft Corporation. All rights reserved.
##
!include ..\common.mak
LIBS=$(LIBS) kernel32.lib
all: dirs \
$(BIND)\dumpi.exe \
!IF $(DETOURS_SOURCE_BROWSING)==1
$(OBJD)\dumpi.bsc \
!ENDIF
clean:
-del *~ 2>nul
-del $(BIND)\dumpi.* 2>nul
-rmdir /q /s $(OBJD) 2>nul
realclean: clean
-rmdir /q /s $(OBJDS) 2>nul
dirs:
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
$(OBJD)\dumpi.obj : dumpi.cpp
$(BIND)\dumpi.exe : $(OBJD)\dumpi.obj $(DEPS)
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\dumpi.obj \
/link $(LINKFLAGS) $(LIBS) \
/subsystem:console
$(OBJD)\dumpi.bsc : $(OBJD)\dumpi.obj
bscmake /v /n /o $@ $(OBJD)\dumpi.sbr
##############################################################################
test: $(BIND)\dumpi.exe
$(BIND)\dumpi.exe $(BIND)\slept.dll $(BIND)\sleepold.exe
################################################################# End of File.

274
samples/dumpi/dumpi.cpp Normal file
View File

@@ -0,0 +1,274 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detours Test Program (dumpi.cpp of dumpi.exe)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <shellapi.h>
#pragma warning(push)
#if _MSC_VER > 1400
#pragma warning(disable:6102 6103) // /analyze warnings
#endif
#include <strsafe.h>
#pragma warning(pop)
#include <detours.h>
////////////////////////////////////////////////////////////// Error Messages.
//
VOID AssertMessage(PCSTR szMsg, PCSTR szFile, DWORD nLine)
{
printf("ASSERT(%s) failed in %s, line %d.", szMsg, szFile, nLine);
}
#define ASSERT(x) \
do { if (!(x)) { AssertMessage(#x, __FILE__, __LINE__); DebugBreak(); }} while (0)
;
//////////////////////////////////////////////////////////////////////////////
//
static BOOL s_fSubs = FALSE;
//////////////////////////////////////////////////////////////////////////////
//
static CHAR s_szFile[MAX_PATH] = "\0";
static BOOL CALLBACK ListFileCallback(_In_opt_ PVOID pContext,
_In_z_ LPCSTR pszOrigFile,
_In_z_ LPCSTR pszFile,
_Outptr_result_maybenull_ LPCSTR *ppszOutFile)
{
(void)pContext;
(void)pszFile;
*ppszOutFile = NULL;
StringCchCopyA(s_szFile, sizeof(s_szFile), pszOrigFile);
PCHAR psz;
if ((psz = strchr(s_szFile, '.')) != NULL) {
*psz = '\0';
}
return TRUE;
}
BOOL CALLBACK ListSymbolCallback(_In_opt_ PVOID pContext,
_In_ ULONG nOrigOrdinal,
_In_ ULONG nOrdinal,
_Out_ ULONG *pnOutOrdinal,
_In_opt_z_ LPCSTR pszOrigSymbol,
_In_opt_z_ LPCSTR pszSymbol,
_Outptr_result_maybenull_ LPCSTR *ppszOutSymbol)
{
(void)pContext;
(void)nOrdinal;
(void)pszSymbol;
*ppszOutSymbol = NULL;
*pnOutOrdinal = 0;
if (nOrigOrdinal != 0) {
printf(" %s::#%d\n",
s_szFile, nOrigOrdinal);
}
else {
printf(" %s::%s\n",
s_szFile, pszOrigSymbol);
}
return TRUE;
}
BOOL DimpFile(PCHAR pszPath)
{
BOOL bGood = TRUE;
HANDLE hOld = INVALID_HANDLE_VALUE;
PDETOUR_BINARY pBinary = NULL;
hOld = CreateFileA(pszPath,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hOld == INVALID_HANDLE_VALUE) {
printf("%s: Failed to open input file with error: %d\n",
pszPath, GetLastError());
bGood = FALSE;
goto end;
}
if ((pBinary = DetourBinaryOpen(hOld)) == NULL) {
printf("%s: DetourBinaryOpen failed: %d\n", pszPath, GetLastError());
goto end;
}
if (hOld != INVALID_HANDLE_VALUE) {
CloseHandle(hOld);
hOld = INVALID_HANDLE_VALUE;
}
printf("%s:\n", pszPath);
if (!DetourBinaryEditImports(pBinary,
NULL,
NULL,
ListFileCallback,
ListSymbolCallback,
NULL)) {
printf("%s: DetourBinaryEditImports failed: %d\n", pszPath, GetLastError());
}
DetourBinaryClose(pBinary);
pBinary = NULL;
end:
if (pBinary) {
DetourBinaryClose(pBinary);
pBinary = NULL;
}
if (hOld != INVALID_HANDLE_VALUE) {
CloseHandle(hOld);
hOld = INVALID_HANDLE_VALUE;
}
return bGood;
}
//////////////////////////////////////////////////////////////////////////////
int DimpArgument(char *dir, char *argp, int fDoSubs)
{
//////////////////////////////////////////////////////////////////////////
WIN32_FIND_DATAA wfd;
HANDLE hFind = NULL;
char name[1024];
int nFound = 0;
StringCchCopyA(name, sizeof(name), dir ? dir : "");
StringCchCatA(name, sizeof(name), argp);
hFind = FindFirstFileA(name, &wfd);
if (hFind != INVALID_HANDLE_VALUE) {
do {
if (!(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
StringCchCopyA(name, sizeof(name), dir ? dir : "");
StringCchCatA(name, sizeof(name), wfd.cFileName);
nFound += DimpFile(name);
}
} while (FindNextFileA(hFind, &wfd));
FindClose(hFind);
}
if (fDoSubs) {
StringCchCopyA(name, sizeof(name), dir ? dir : "");
StringCchCatA(name, sizeof(name), "*");
hFind = FindFirstFileA(name, &wfd);
if (hFind == INVALID_HANDLE_VALUE)
return nFound;
do {
if ((wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
wfd.cFileName[0] != '.') {
StringCchCopyA(name, sizeof(name), dir ? dir : "");
StringCchCatA(name, sizeof(name), wfd.cFileName);
StringCchCatA(name, sizeof(name), "\\");
nFound += DimpArgument(name, argp, fDoSubs);
}
} while (FindNextFileA(hFind, &wfd));
FindClose(hFind);
}
return nFound;
}
//////////////////////////////////////////////////////////////////////////////
//
void PrintUsage(void)
{
printf("Usage:\n"
" dimp [options] binary_files\n"
"Options:\n"
" /s : Recurse through subdirectories.\n"
" /? : This help screen.\n"
"Examples:\n"
" dimp /s *.exe\n"
"");
}
//////////////////////////////////////////////////////////////////////// main.
//
int CDECL main(int argc, char **argv)
{
BOOL fNeedHelp = FALSE;
BOOL fSubdirs = FALSE;
int arg = 1;
for (; arg < argc; arg++) {
if (argv[arg][0] == '-' || argv[arg][0] == '/') {
CHAR *argn = argv[arg] + 1;
CHAR *argp = argn;
while (*argp && *argp != ':')
argp++;
if (*argp == ':')
*argp++ = '\0';
switch (argn[0]) {
case 's': // Do Subdirectories.
case 'S':
fSubdirs = TRUE;
break;
case '?': // Help.
fNeedHelp = TRUE;
break;
default:
fNeedHelp = TRUE;
printf("Bad argument: %s:%s\n", argn, argp);
break;
}
}
else {
CHAR szDir[MAX_PATH] = "";
CHAR szArg[MAX_PATH] = "";
PCHAR pszDir;
if ((pszDir = strrchr(argv[arg], '\\')) != NULL) {
*pszDir++ = '\0';
StringCchCopyA(szArg, sizeof(szArg), pszDir);
StringCchCopyA(szDir, sizeof(szDir), argv[arg]);
StringCchCatA(szDir, sizeof(szDir), "\\");
}
else {
if (GetCurrentDirectoryA(sizeof(szDir), szDir) > 3) {
StringCchCatA(szDir, sizeof(szDir), "\\");
}
StringCchCopyA(szArg, sizeof(szArg), argv[arg]);
}
DimpArgument(szDir, szArg, fSubdirs);
}
}
if (argc == 1) {
fNeedHelp = TRUE;
}
if (fNeedHelp) {
PrintUsage();
return 1;
}
return 0;
}
// End of File

108
samples/echo/Makefile Normal file
View File

@@ -0,0 +1,108 @@
##############################################################################
##
## Detours Test Program
##
## Microsoft Research Detours Package
##
## Copyright (c) Microsoft Corporation. All rights reserved.
##
!include ..\common.mak
LIBS=$(LIBS) kernel32.lib
##############################################################################
all: dirs \
$(BIND)\echofx$(DETOURS_BITS).dll \
$(BIND)\echonul.exe \
\
!IF $(DETOURS_SOURCE_BROWSING)==1
$(OBJD)\echofx$(DETOURS_BITS).bsc \
$(OBJD)\echonul.bsc \
!ENDIF
option
##############################################################################
dirs:
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
$(OBJD)\echofx.obj : echofx.cpp
$(OBJD)\echofx.res : echofx.rc
$(BIND)\echofx$(DETOURS_BITS).dll $(BIND)\echofx$(DETOURS_BITS).lib: \
$(OBJD)\echofx.obj $(OBJD)\echofx.res $(DEPS) $(BIND)\echonul.lib
cl /LD $(CFLAGS) /Fe$@ /Fd$(@R).pdb \
$(OBJD)\echofx.obj $(OBJD)\echofx.res \
/link $(LINKFLAGS) /subsystem:console \
/export:DetourFinishHelperProcess,@1,NONAME \
/export:Mine_Echo \
$(LIBS) $(BIND)\echonul.lib
$(OBJD)\echofx$(DETOURS_BITS).bsc : $(OBJD)\echofx.obj
bscmake /v /n /o $@ $(OBJD)\echofx.sbr
$(OBJD)\echonul.obj : echonul.cpp
$(OBJD)\main.obj : main.cpp
$(BIND)\echonul.exe $(BIND)\echonul.lib: $(OBJD)\main.obj $(OBJD)\echonul.obj
cl $(CFLAGS) /Zl /Fe$(BIND)\echonul.exe /Fd$(@R).pdb \
$(OBJD)\main.obj $(OBJD)\echonul.obj \
/link $(LINKFLAGS) \
/export:Echo \
/subsystem:console
$(OBJD)\echonul.bsc : echonul.obj
bscmake /v /n /o $@ echonul.sbr
##############################################################################
clean:
-del *~ 2>nul
-del $(BIND)\echofx*.* 2>nul
-del $(BIND)\echonul.* 2>nul
-rmdir /q /s $(OBJD) 2>nul
realclean: clean
-rmdir /q /s $(OBJDS) 2>nul
############################################### Install non-bit-size binaries.
!IF "$(DETOURS_OPTION_PROCESSOR)" != ""
$(OPTD)\echofx$(DETOURS_OPTION_BITS).dll:
$(OPTD)\echofx$(DETOURS_OPTION_BITS).pdb:
$(BIND)\echofx$(DETOURS_OPTION_BITS).dll : $(OPTD)\echofx$(DETOURS_OPTION_BITS).dll
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
$(BIND)\echofx$(DETOURS_OPTION_BITS).pdb : $(OPTD)\echofx$(DETOURS_OPTION_BITS).pdb
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
option: \
$(BIND)\echofx$(DETOURS_OPTION_BITS).dll \
$(BIND)\echofx$(DETOURS_OPTION_BITS).pdb \
!ELSE
option:
!ENDIF
##############################################################################
test: all
@echo -------- Should echo nothing. --------------------------------------
-$(BIND)\echonul.exe
@echo -------- Should echo Hello World. ----------------------------------
-$(BIND)\withdll.exe -d:$(BIND)\echofx$(DETOURS_BITS).dll $(BIND)\echonul.exe
@echo.
testd: all
@echo.
-windbg -o -g -G $(BIND)\withdll.exe -d:$(BIND)\echofx$(DETOURS_BITS).dll $(BIND)\echonul.exe
@echo.
################################################################# End of File.

60
samples/echo/echofx.cpp Normal file
View File

@@ -0,0 +1,60 @@
//
//
//
#include <windows.h>
#include <detours.h>
#include <stdio.h>
int WINAPI Echo(PCSTR pszMsg);
static int (WINAPI * Real_Echo)(PCSTR pszMsg) = Echo;
int WINAPI Mine_Echo(PCSTR pszMsg)
{
printf("Echo(%s)\n", pszMsg);
return Real_Echo(pszMsg);
}
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
{
LONG error;
(void)hinst;
(void)reserved;
if (DetourIsHelperProcess()) {
return TRUE;
}
if (dwReason == DLL_PROCESS_ATTACH) {
DetourRestoreAfterWith();
printf("echofx" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
" Starting.\n");
fflush(stdout);
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)Real_Echo, Mine_Echo);
error = DetourTransactionCommit();
if (error == NO_ERROR) {
printf("echofx" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
" Detoured Echo().\n");
}
else {
printf("echofx" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
" Error detouring Echo(): %d\n", error);
}
}
else if (dwReason == DLL_PROCESS_DETACH) {
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)Real_Echo, Mine_Echo);
error = DetourTransactionCommit();
printf("echofx" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
" Removed Echo() (result=%d)\n", error);
fflush(stdout);
}
return TRUE;
}

17
samples/echo/echofx.rc Normal file
View File

@@ -0,0 +1,17 @@
//////////////////////////////////////////////////////////////////////////////
//
// Version information for echofx.rc.
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#include "detver.h"
#define VER_INTERNALNAME_STR "echofx" DETOURS_STRINGIFY(DETOURS_BITS)
#define VER_ORIGINALFILENAME_STR "echofx" DETOURS_STRINGIFY(DETOURS_BITS) ".dll"
#define VER_FILEDESCRIPTION_STR "Detours Echo Interception Module"
#define VER_COMPANYNAME_STR "Microsoft Corporation"
#include "common.ver"

18
samples/echo/echonul.cpp Normal file
View File

@@ -0,0 +1,18 @@
//
//
//
#include <windows.h>
int WINAPI Echo(PCSTR pszMsg)
{
int sum = 0;
while (*pszMsg) {
sum = sum + *pszMsg++;
}
return sum;
}
int main()
{
return 0;
}

24
samples/echo/main.cpp Normal file
View File

@@ -0,0 +1,24 @@
//
//
//
#include <windows.h>
int WINAPI Echo(PCSTR pszMsg);
extern "C" int __stdcall mainCRTStartup(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow
)
{
(void)hInstance;
(void)hPrevInstance;
(void)lpCmdLine;
(void)nCmdShow;
Echo("Hello World");
Echo("Goodbye World");
return 0x99;
}

135
samples/einst/Makefile Normal file
View File

@@ -0,0 +1,135 @@
##############################################################################
##
## Makefile for Detours Test Programs.
##
## Microsoft Research Detours Package
##
## Copyright (c) Microsoft Corporation. All rights reserved.
##
!include ..\common.mak
LIBS=$(LIBS) kernel32.lib user32.lib
all: dirs \
$(BIND)\edll1x$(DETOURS_BITS).dll \
$(BIND)\edll2x$(DETOURS_BITS).dll \
$(BIND)\edll3x$(DETOURS_BITS).dll \
$(BIND)\einst.exe \
\
!IF $(DETOURS_SOURCE_BROWSING)==1
$(OBJD)\edll1x$(DETOURS_BITS).bsc \
$(OBJD)\edll2x$(DETOURS_BITS).bsc \
$(OBJD)\edll3x$(DETOURS_BITS).bsc \
$(OBJD)\einst.bsc \
!ENDIF
option
clean:
-del *~ 2>nul
-del $(BIND)\edll1x*.* 2>nul
-del $(BIND)\edll2x*.* 2>nul
-del $(BIND)\edll3x*.* 2>nul
-del $(BIND)\einst.* 2>nul
-rmdir /q /s $(OBJD) 2>nul
realclean: clean
-rmdir /q /s $(OBJDS) 2>nul
dirs:
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
##############################################################################
$(OBJD)\einst.obj : einst.cpp
$(BIND)\einst.exe : $(OBJD)\einst.obj $(DEPS)
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\einst.obj \
/link $(LINKFLAGS) $(LIBS) \
$(BIND)\edll1x$(DETOURS_BITS).lib $(BIND)\edll2x$(DETOURS_BITS).lib $(BIND)\edll3x$(DETOURS_BITS).lib \
/subsystem:console /entry:WinMainCRTStartup
$(OBJD)\einst.bsc : $(OBJD)\einst.obj
bscmake /v /n /o $@ $(OBJD)\einst.sbr
$(OBJD)\edll1x.obj : edll1x.cpp
$(BIND)\edll1x$(DETOURS_BITS).dll : $(OBJD)\edll1x.obj $(DEPS)
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb \
$(OBJD)\edll1x.obj /LD \
/link $(LINKFLAGS) $(LIBS) \
/subsystem:windows \
/base:0x7100000
$(OBJD)\edll1x$(DETOURS_BITS).bsc : $(OBJD)\edll1x.obj
bscmake /v /n /o $@ $(OBJD)\edll1x.sbr
$(OBJD)\edll2x.obj : edll2x.cpp
$(BIND)\edll2x$(DETOURS_BITS).dll : $(OBJD)\edll2x.obj $(DEPS)
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb \
$(OBJD)\edll2x.obj /LD \
/link $(LINKFLAGS) $(LIBS) \
/subsystem:console \
/base:0x7200000
$(OBJD)\edll2x$(DETOURS_BITS).bsc : $(OBJD)\edll2x.obj
bscmake /v /n /o $@ $(OBJD)\edll2x.sbr
$(OBJD)\edll3x.obj : edll3x.cpp
$(BIND)\edll3x$(DETOURS_BITS).dll : $(OBJD)\edll3x.obj $(DEPS)
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb \
$(OBJD)\edll3x.obj /LD \
/link $(LINKFLAGS) $(LIBS) \
/subsystem:console \
/base:0x7300000
$(OBJD)\edll3x$(DETOURS_BITS).bsc : $(OBJD)\edll3x.obj
bscmake /v /n /o $@ $(OBJD)\edll3x.sbr
############################################### Install non-bit-size binaries.
!IF "$(DETOURS_OPTION_PROCESSOR)" != ""
$(OPTD)\edll1x$(DETOURS_OPTION_BITS).dll:
$(OPTD)\edll1x$(DETOURS_OPTION_BITS).pdb:
$(OPTD)\edll2x$(DETOURS_OPTION_BITS).dll:
$(OPTD)\edll2x$(DETOURS_OPTION_BITS).pdb:
$(OPTD)\edll3x$(DETOURS_OPTION_BITS).dll:
$(OPTD)\edll3x$(DETOURS_OPTION_BITS).pdb:
$(BIND)\edll1x$(DETOURS_OPTION_BITS).dll : $(OPTD)\edll1x$(DETOURS_OPTION_BITS).dll
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
$(BIND)\edll1x$(DETOURS_OPTION_BITS).pdb : $(OPTD)\edll1x$(DETOURS_OPTION_BITS).pdb
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
$(BIND)\edll2x$(DETOURS_OPTION_BITS).dll : $(OPTD)\edll2x$(DETOURS_OPTION_BITS).dll
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
$(BIND)\edll2x$(DETOURS_OPTION_BITS).pdb : $(OPTD)\edll2x$(DETOURS_OPTION_BITS).pdb
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
$(BIND)\edll3x$(DETOURS_OPTION_BITS).dll : $(OPTD)\edll3x$(DETOURS_OPTION_BITS).dll
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
$(BIND)\edll3x$(DETOURS_OPTION_BITS).pdb : $(OPTD)\edll3x$(DETOURS_OPTION_BITS).pdb
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
option: \
$(BIND)\edll1x$(DETOURS_OPTION_BITS).dll \
$(BIND)\edll1x$(DETOURS_OPTION_BITS).pdb \
$(BIND)\edll2x$(DETOURS_OPTION_BITS).dll \
$(BIND)\edll2x$(DETOURS_OPTION_BITS).pdb \
$(BIND)\edll3x$(DETOURS_OPTION_BITS).dll \
$(BIND)\edll3x$(DETOURS_OPTION_BITS).pdb \
!ELSE
option:
!ENDIF
##############################################################################
test: all
$(BIND)\einst.exe
################################################################# End of File.

55
samples/einst/edll1x.cpp Normal file
View File

@@ -0,0 +1,55 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detours Test Program (edll1x.cpp of edll1x.dll)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#include <stdio.h>
#include <windows.h>
#include <detours.h>
//////////////////////////////////////////////////////////////////// DLL Stuff
//
struct CPrivateStuff
{
DETOUR_SECTION_HEADER header;
DETOUR_SECTION_RECORD record;
CHAR szMessage[32];
};
#pragma data_seg(".detour")
static CPrivateStuff private_stuff = {
DETOUR_SECTION_HEADER_DECLARE(sizeof(CPrivateStuff)),
{
(sizeof(CPrivateStuff) - sizeof(DETOUR_SECTION_HEADER)),
0,
{ /* d9ab8a40-f4cc-11d1-b6d7-006097b010e3 */
0xd9ab8a40,
0xf4cc,
0x11d1,
{0xb6, 0xd7, 0x00, 0x60, 0x97, 0xb0, 0x10, 0xe3}
}
},
"The First Dll!"
};
#pragma data_seg()
__declspec(dllexport) VOID WINAPI EDll1Function(VOID)
{
return;
}
__declspec(dllexport) ULONG WINAPI
DllMain(HINSTANCE hInstance, DWORD dwReason, PVOID lpReserved)
{
(void)hInstance;
(void)dwReason;
(void)lpReserved;
return TRUE;
}
///////////////////////////////////////////////////////////////// End of File.

55
samples/einst/edll2x.cpp Normal file
View File

@@ -0,0 +1,55 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detours Test Program (edll2x.cpp of einst.exe/edll2x.dll)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#include <stdio.h>
#include <windows.h>
#include <detours.h>
//////////////////////////////////////////////////////////////////// DLL Stuff
//
struct CPrivateStuff
{
DETOUR_SECTION_HEADER header;
DETOUR_SECTION_RECORD record;
CHAR szMessage[32];
};
#pragma data_seg(".detour")
static CPrivateStuff private_stuff = {
DETOUR_SECTION_HEADER_DECLARE(sizeof(CPrivateStuff)),
{
(sizeof(CPrivateStuff) - sizeof(DETOUR_SECTION_HEADER)),
0,
{ /* d9ab8a40-f4cc-11d1-b6d7-006097b010e3 */
0xd9ab8a40,
0xf4cc,
0x11d1,
{0xb6, 0xd7, 0x00, 0x60, 0x97, 0xb0, 0x10, 0xe3}
}
},
"The Second Dll!"
};
#pragma data_seg()
__declspec(dllexport) VOID WINAPI EDll2Function(VOID)
{
return;
}
__declspec(dllexport) ULONG WINAPI
DllMain(HINSTANCE hInstance, DWORD dwReason, PVOID lpReserved)
{
(void)hInstance;
(void)dwReason;
(void)lpReserved;
return TRUE;
}
///////////////////////////////////////////////////////////////// End of File.

82
samples/einst/edll3x.cpp Normal file
View File

@@ -0,0 +1,82 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detours Test Program (edll3x.cpp of einst.exe/edll3x.dll)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#include <stdio.h>
#include <windows.h>
#include <detours.h>
//////////////////////////////////////////////////////////////////// DLL Stuff
//
struct CPrivateStuffPart1
{
DETOUR_SECTION_RECORD header;
CHAR szMessage[48];
};
struct CPrivateStuffPart2
{
DETOUR_SECTION_RECORD header;
CHAR szMessage[64];
};
struct CPrivateStuff
{
DETOUR_SECTION_HEADER header;
CPrivateStuffPart1 record1;
CPrivateStuffPart2 record2;
};
#pragma data_seg(".detour")
static CPrivateStuff private_stuff = {
DETOUR_SECTION_HEADER_DECLARE(sizeof(CPrivateStuff)),
{
{
sizeof(CPrivateStuffPart1),
0,
{ /* d9ab8a41-f4cc-11d1-b6d7-006097b010e3 */
0xd9ab8a41,
0xf4cc,
0x11d1,
{0xb6, 0xd7, 0x00, 0x60, 0x97, 0xb0, 0x10, 0xe3}
}
},
"The Third DLL Part One!"
},
{
{
sizeof(CPrivateStuffPart2),
0,
{ /* d9ab8a40-f4cc-11d1-b6d7-006097b010e3 */
0xd9ab8a40,
0xf4cc,
0x11d1,
{0xb6, 0xd7, 0x00, 0x60, 0x97, 0xb0, 0x10, 0xe3}
}
},
"The Third DLL Part Two!"
}
};
#pragma data_seg()
__declspec(dllexport) VOID WINAPI EDll3Function(VOID)
{
return;
}
__declspec(dllexport) ULONG WINAPI
DllMain(HINSTANCE hInstance, DWORD dwReason, PVOID lpReserved)
{
(void)hInstance;
(void)dwReason;
(void)lpReserved;
return TRUE;
}
///////////////////////////////////////////////////////////////// End of File.

98
samples/einst/einst.cpp Normal file
View File

@@ -0,0 +1,98 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detours Test Program (einst.cpp of einst.exe)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#include <stdio.h>
#include <windows.h>
#include <detours.h>
struct CPrivateStuff
{
DETOUR_SECTION_HEADER header;
DETOUR_SECTION_RECORD record;
CHAR szMessage[32];
};
#ifdef INCLUDE_THIS
#pragma data_seg(".detour")
static CPrivateStuff private_stuff = {
DETOUR_SECTION_HEADER_DECLARE(sizeof(CPrivateStuff)),
{
(sizeof(CPrivateStuff) - sizeof(DETOUR_SECTION_HEADER)),
0,
{ /* d9ab8a40-f4cc-11d1-b6d7-006097b010e3 */
0xd9ab8a40,
0xf4cc,
0x11d1,
{0xb6, 0xd7, 0x00, 0x60, 0x97, 0xb0, 0x10, 0xe3}
}
},
"The Application!"
};
#pragma data_seg()
#endif
GUID my_guid =
{ /* d9ab8a40-f4cc-11d1-b6d7-006097b010e3 */
0xd9ab8a40,
0xf4cc,
0x11d1,
{0xb6, 0xd7, 0x00, 0x60, 0x97, 0xb0, 0x10, 0xe3}
};
__declspec(dllimport) VOID WINAPI EDll1Function(VOID);
__declspec(dllimport) VOID WINAPI EDll2Function(VOID);
__declspec(dllimport) VOID WINAPI EDll3Function(VOID);
void FindPayload(HINSTANCE hinst)
{
CHAR szModuleName[256];
GetModuleFileNameA(hinst, szModuleName, ARRAYSIZE(szModuleName));
printf(" %p : %s\n", hinst, szModuleName);
ULONG cbData = 0;
PBYTE pbData = (PBYTE)DetourFindPayload(hinst, my_guid, &cbData);
if (pbData) {
printf(" %08p..%08p : %50.50s\n",
pbData,
pbData + cbData,
pbData);
}
}
int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hprev, LPSTR lpszCmdLine, int nCmdShow)
{
(void)hinst;
(void)hprev;
(void)lpszCmdLine;
(void)nCmdShow;
printf("Source .EXE:\n");
FindPayload(NULL);
printf("\n");
printf("DLL and EXE binaries loaded:\n");
EDll1Function();
EDll2Function();
EDll3Function();
for (HINSTANCE hiter = NULL; (hiter = DetourEnumerateModules(hiter)) != NULL;) {
FindPayload(hiter);
}
if ((PVOID)hinst == (PVOID)lpszCmdLine) {
DispatchMessage(NULL); // Force load of gdi32.dll
}
return 0;
}
//
///////////////////////////////////////////////////////////////// End of File.

47
samples/excep/Makefile Normal file
View File

@@ -0,0 +1,47 @@
##############################################################################
##
## Makefile for Detours Test Programs.
##
## Microsoft Research Detours Package
##
## Copyright (c) Microsoft Corporation. All rights reserved.
##
!include ..\common.mak
LIBS=$(LIBS) kernel32.lib
all: dirs \
$(BIND)\excep.exe \
!IF $(DETOURS_SOURCE_BROWSING)==1
$(OBJD)\excep.bsc
!ENDIF
clean:
-del *~ 2>nul
-del $(BIND)\excep.* 2>nul
-rmdir /q /s $(OBJD) 2>nul
realclean: clean
-rmdir /q /s $(OBJDS) 2>nul
dirs:
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
$(OBJD)\excep.obj : excep.cpp
$(OBJD)\firstexc.obj : firstexc.cpp
$(BIND)\excep.exe : $(OBJD)\excep.obj $(OBJD)\firstexc.obj $(DEPS)
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\excep.obj $(OBJD)\firstexc.obj \
/link $(LINKFLAGS) $(LIBS) /subsystem:console /entry:WinMainCRTStartup
$(OBJD)\excep.bsc : $(OBJD)\excep.obj
bscmake /v /n /o $@ $(OBJD)\excep.sbr
##############################################################################
test: $(BIND)\excep.exe
$(BIND)\excep.exe
################################################################# End of File.

125
samples/excep/excep.cpp Normal file
View File

@@ -0,0 +1,125 @@
//////////////////////////////////////////////////////////////////////////////
//
// First Chance Exception Handling Test Program (excep.cpp of excep.exe)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// For more information on exception handling, see "A Crash Course on the
// Depths of Win32 Structured Exception Handling," by Matt Pietrek in the
// January 1997 issue of Microsoft Systems Journal.
//
#include <stdio.h>
#include <windows.h>
#include <detours.h>
#include "firstexc.h"
//////////////////////////////////////////////////////////////////////////////
//
static LPVOID s_pvData = NULL;
static DWORD s_dwDataPerm = 0;
static LONG ExceptCatch(LONG nTry, DWORD dwException, LPEXCEPTION_POINTERS pinfo)
{
printf(" ExceptCatch(%d, %08x, %08x)\n", nTry, dwException, (ULONG)pinfo);
#ifdef INCLUDE_THIS
if (nTry == 0) {
return EXCEPTION_CONTINUE_EXECUTION;
}
#endif
return EXCEPTION_EXECUTE_HANDLER;
}
static int BadCode(int nTry)
{
printf(" BadCode(Try:%d)\n", nTry);
printf(" BadCode -> %d\n", *(PULONG)s_pvData);
((PULONG)s_pvData)[0] = 0;
printf(" BadCode -> %d\n", *(PULONG)s_pvData);
((PULONG)s_pvData)[-1] = 0;
printf(" BadCode -> %d\n", *(PULONG)s_pvData);
return 0;
}
void safe(int nTry)
{
__try {
printf(" try(%d)\n", nTry);
BadCode(nTry);
printf(" good(%d)\n", nTry);
} __except(ExceptCatch(nTry,
GetExceptionCode(),
GetExceptionInformation())) {
DWORD dwExcept = GetExceptionCode();
printf(" handler(%d) : %08x\n", nTry, dwExcept);
}
}
void raw(int nTry)
{
BadCode(nTry);
}
LONG WINAPI MyVirtualFaultFilter(PEXCEPTION_POINTERS pException)
{
PEXCEPTION_RECORD pExceptRec = pException->ExceptionRecord;
if (pExceptRec->ExceptionCode == 0xc0000005) {
printf("-- Memory access exception.\n");
if (pExceptRec->NumberParameters >= 2 &&
pExceptRec->ExceptionInformation[1] >= (ULONG)s_pvData &&
pExceptRec->ExceptionInformation[1] <= (ULONG)s_pvData + sizeof(ULONG)) {
VirtualProtect(s_pvData, sizeof(ULONG), PAGE_READWRITE, &s_dwDataPerm);
printf("-- Changed permissions.\n");
return EXCEPTION_CONTINUE_EXECUTION;
}
}
return EXCEPTION_CONTINUE_SEARCH;
}
int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hprev, LPSTR lpszCmdLine, int nCmdShow)
{
(void)hinst;
(void)hprev;
(void)lpszCmdLine;
(void)nCmdShow;
s_pvData = VirtualAlloc(NULL, sizeof(ULONG), MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
if (s_pvData == NULL) {
printf("VirtualAlloc failed: %d\n", GetLastError());
return 0;
}
*(PULONG)s_pvData = 1;
VirtualProtect(s_pvData, sizeof(ULONG), PAGE_READONLY, &s_dwDataPerm);
DetourFirstChanceExceptionFilter(MyVirtualFaultFilter);
printf("main\n");
printf("--------------------------------------------------\n");
int nTry = 0;
for (; nTry < 1; nTry++) {
// safe(nTry);
}
printf("-- safe ------------------------------------------\n");
safe(nTry);
VirtualProtect(s_pvData, sizeof(ULONG), PAGE_READWRITE, &s_dwDataPerm);
*(PULONG)s_pvData = 1;
VirtualProtect(s_pvData, sizeof(ULONG), PAGE_READONLY, &s_dwDataPerm);
printf("-- raw -------------------------------------------\n");
printf("*\n");
printf("* NB: The second attempt to write will fail because it isn't handled.\n");
printf("*\n");
raw(nTry);
printf("--------------------------------------------------\n");
printf("exit\n");
return 0;
}
//
///////////////////////////////////////////////////////////////// End of File.

191
samples/excep/firstexc.cpp Normal file
View File

@@ -0,0 +1,191 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detours Test Program (firstexc.cpp of firstexc.lib)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// For more information on exception handling, see "A Crash Course on the
// Depths of Win32 Structured Exception Handling," by Matt Pietrek in the
// January 1997 issue of Microsoft Systems Journal.
//
#include <stdio.h>
#include <windows.h>
#include "detours.h"
#include "firstexc.h"
#if _MSC_VER > 1000
#pragma warning(disable: 4740)
#endif
//////////////////////////////////////////////////////////////////////////////
//
static BOOL s_bExceptionDetourInstalled = FALSE;
static LPTOP_LEVEL_EXCEPTION_FILTER s_pFirstChanceFilter = NULL;
ULONG (NTAPI *Real_NtContinue)(IN PCONTEXT ContextRecord,
IN BOOLEAN TestAlerts) = NULL;
VOID (NTAPI *Real_KiUserExceptionDispatcher)(IN PEXCEPTION_RECORD ExceptionRecord,
IN PCONTEXT ContextFrame) = NULL;
//////////////////////////////////////////////////////////////////////////////
//
// This function effectively removes all try..catch frames for the current
// stack. It forces all exceptions to be treated as unhandled exceptions.
//
#pragma warning(push)
#pragma warning(disable: 4733)
static VOID WINAPI RemoveAllExceptionHandlers(VOID)
{
// The basic, OS defined exception frame
struct EXCEPTION_REGISTRATION
{
EXCEPTION_REGISTRATION* prev;
FARPROC handler;
};
EXCEPTION_REGISTRATION * pVCExcRec = NULL;
EXCEPTION_REGISTRATION * pLastGood = NULL;
__asm mov eax, FS:[0];
__asm mov [pVCExcRec], eax;
for (pLastGood = pVCExcRec; (ULONG)pVCExcRec != ~0ul; ) {
if ((ULONG)pVCExcRec >= 0x30000000)
break;
pLastGood = pVCExcRec;
pVCExcRec = (EXCEPTION_REGISTRATION *)(pVCExcRec->prev);
}
__asm mov eax, [pLastGood];
__asm mov FS:[0], eax;
}
#pragma warning(pop)
//////////////////////////////////////////////////////////////////////////////
// Routine Description:
//
// This routine is entered on return from kernel mode to dispatch a user
// mode exception. If a frame based handler handles the exception, then
// the execution is continued. Else last chance processing is performed.
//
// NOTE: This procedure is not called, but rather dispatched to.
// It depends on there not being a return address on the stack
// (assumption w.r.t. argument offsets.)
//
// Arguments:
// ExceptionRecord (esp+0) - Supplies a pointer to an exception record.
// ContextRecord (esp+4) - Supplies a pointer to a context frame.
//
// Return Value:
// None.
//
static VOID __declspec(naked) NTAPI
Detour_KiUserExceptionDispatcher(PEXCEPTION_RECORD pExceptRec,
CONTEXT *pContext)
{
__asm {
xor eax, eax ; // Create fake return address on stack.
push eax ; // (Generally, we are called by the kernel.)
push ebp ; // Prolog
mov ebp, esp ;
sub esp, __LOCAL_SIZE ;
}
LPTOP_LEVEL_EXCEPTION_FILTER pFirstChanceFilter;
EXCEPTION_POINTERS ep;
DWORD dwReturn;
DWORD dwError;
ep.ExceptionRecord = pExceptRec;
ep.ContextRecord = pContext;
pFirstChanceFilter = s_pFirstChanceFilter;
dwReturn = EXCEPTION_CONTINUE_SEARCH;
dwError = 0;
if (s_pFirstChanceFilter) {
dwReturn = pFirstChanceFilter(&ep);
}
if (dwReturn == EXCEPTION_CONTINUE_EXECUTION) {
dwError = Real_NtContinue(pContext, 0);
// This call should *NEVER* return. If it does, we want to fail to the debugger.
RemoveAllExceptionHandlers();
}
if (dwReturn == EXCEPTION_EXECUTE_HANDLER) { // Special: Call debugger.
RemoveAllExceptionHandlers();
}
__asm {
mov ebx, pExceptRec ;
mov ecx, pContext ;
push ecx ;
push ebx ;
mov eax, [Real_KiUserExceptionDispatcher];
jmp eax ;
;
; The above code should never return.
;
int 3 ; // Break!
;
mov esp, ebp ; // Epilog
pop ebp ;
ret ;
}
}
//////////////////////////////////////////////////////////////////////////////
//
// Set the first-chance exception filter.
//
// Returns the pointer to the last first-chance exception filter if there
// was one. If this is the first first-chance exception filter, installs
// the necessary detour and acquires the appropriate function pointers.
// If the parameter is NULL, first-chance exception filtering is disabled.
//
// A first-chance exception filter should always return one of three
// possible codes:
//
// EXCEPTION_CONTINUE_SEARCH:
// The exception was not handled by this filter; continue the
// search for the appropriate exception handler.
//
// EXCEPTION_CONTINUE_EXECUTION:
// The exception was handled by this filter; continue execution
// at the point were the exception was thrown.
//
// EXCEPTION_EXECUTE_HANDLER:
// Drastic failure in the exception filter. Process the
// exception as if no exception handlers were installed.
// (i.e. Give the user a chance to invoke the debugger.)
//
LPTOP_LEVEL_EXCEPTION_FILTER WINAPI
DetourFirstChanceExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER pNewFirstChanceFilter)
{
if (!s_bExceptionDetourInstalled) {
s_bExceptionDetourInstalled = TRUE;
Real_NtContinue = (ULONG (NTAPI *)(IN PCONTEXT, IN BOOLEAN))
DetourFindFunction("ntdll.dll", "NtContinue");
Real_KiUserExceptionDispatcher =
(VOID (NTAPI *)(IN PEXCEPTION_RECORD, IN PCONTEXT))
DetourFindFunction("ntdll.dll", "KiUserExceptionDispatcher");
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)Real_KiUserExceptionDispatcher,
Detour_KiUserExceptionDispatcher);
DetourTransactionCommit();
}
LPTOP_LEVEL_EXCEPTION_FILTER pOldFirstChanceFilter = s_pFirstChanceFilter;
s_pFirstChanceFilter = pNewFirstChanceFilter;
return pOldFirstChanceFilter;
}
//
///////////////////////////////////////////////////////////////// End of File.

21
samples/excep/firstexc.h Normal file
View File

@@ -0,0 +1,21 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detours Test Program (firstexc.h of firstexc.exe)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#pragma once
#ifndef _FIRSTEXC_H_
#define _FIRSTEXC_H_
/////////////////////////////////////////////// First Chance Exception Filter.
//
LPTOP_LEVEL_EXCEPTION_FILTER WINAPI
DetourFirstChanceExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelFilter);
#endif // _FIRSTEXC_H_
//
//////////////////////////////////////////////////////////////// End of File.

164
samples/findfunc/Makefile Normal file
View File

@@ -0,0 +1,164 @@
##############################################################################
##
## Program to test DetourFindFunction.
##
## Microsoft Research Detours Package
##
## Copyright (c) Microsoft Corporation. All rights reserved.
##
!include ..\common.mak
LIBS=$(LIBS) kernel32.lib
##############################################################################
all: dirs \
$(BIND)\target$(DETOURS_BITS).dll \
$(BIND)\extend$(DETOURS_BITS).dll \
$(BIND)\findfunc.exe \
$(BIND)\symtest.exe \
$(BIND)\dbghelp.dll \
\
!IF $(DETOURS_SOURCE_BROWSING)==1
$(OBJD)\target$(DETOURS_BITS).bsc \
$(OBJD)\extend$(DETOURS_BITS).bsc \
$(OBJD)\findfunc.bsc \
$(OBJD)\symtest.bsc \
!ENDIF
option
##############################################################################
dirs:
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
$(OBJD)\target.obj : target.cpp
$(OBJD)\target.res : target.rc
$(BIND)\target$(DETOURS_BITS).dll $(BIND)\target$(DETOURS_BITS).lib: \
$(OBJD)\target.obj $(OBJD)\target.res $(DEPS)
cl /LD $(CFLAGS) /Fe$(@R).dll /Fd$(@R).pdb \
$(OBJD)\target.obj $(OBJD)\target.res \
/link $(LINKFLAGS) /subsystem:console \
/export:Target \
/base:0x1900000 \
$(LIBS)
$(OBJD)\target$(DETOURS_BITS).bsc : $(OBJD)\target.obj
bscmake /v /n /o $@ $(OBJD)\target.sbr
$(OBJD)\extend.obj : extend.cpp
$(OBJD)\extend.res : extend.rc
$(BIND)\extend$(DETOURS_BITS).dll $(BIND)\extend$(DETOURS_BITS).lib: \
$(OBJD)\extend.obj $(OBJD)\extend.res $(DEPS)
cl /LD $(CFLAGS) /Fe$(@R).dll /Fd$(@R).pdb \
$(OBJD)\extend.obj $(OBJD)\extend.res \
/link $(LINKFLAGS) /subsystem:console \
/export:DetourFinishHelperProcess,@1,NONAME \
/base:0x1a00000 \
$(LIBS)
$(OBJD)\extend$(DETOURS_BITS).bsc : $(OBJD)\extend.obj
bscmake /v /n /o $@ $(OBJD)\extend.sbr
$(OBJD)\findfunc.obj : findfunc.cpp
$(BIND)\findfunc.exe : $(OBJD)\findfunc.obj $(BIND)\target$(DETOURS_BITS).lib $(DEPS)
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\findfunc.obj \
/link $(LINKFLAGS) $(LIBS) \
/subsystem:console /fixed:no $(BIND)\target$(DETOURS_BITS).lib
$(OBJD)\findfunc.bsc : $(OBJD)\findfunc.obj
bscmake /v /n /o $@ $(OBJD)\findfunc.sbr
$(OBJD)\symtest.obj : symtest.cpp
$(BIND)\symtest.exe : $(OBJD)\symtest.obj $(BIND)\target$(DETOURS_BITS).lib $(DEPS)
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\symtest.obj \
/link $(LINKFLAGS) $(LIBS) \
/subsystem:console /fixed:no $(BIND)\target$(DETOURS_BITS).lib
$(OBJD)\symtest.bsc : $(OBJD)\symtest.obj
bscmake /v /n /o $@ $(OBJD)\symtest.sbr
# We try to get the 64-bit dbghelp first because it is a lot more useful.
$(BIND)\dbghelp.dll : {"$(PROGRAMFILES)\Debugging Tools for Windows 64-bit";$(PATH)}dbghelp.dll
-copy $** $(BIND)\dbghelp.dll
##############################################################################
clean:
-del *~ 2>nul
-del $(BIND)\target*.* $(BIND)\extend*.* 2>nul
-del $(BIND)\findfunc.* $(BIND)\symtest.* $(BIND)\dbghelp.dll 2>nul
-rmdir /q /s $(OBJD) 2>nul
realclean: clean
-rmdir /q /s $(OBJDS) 2>nul
############################################### Install non-bit-size binaries.
!IF "$(DETOURS_OPTION_PROCESSOR)" != ""
$(OPTD)\extend$(DETOURS_OPTION_BITS).dll:
$(OPTD)\extend$(DETOURS_OPTION_BITS).pdb:
$(OPTD)\target$(DETOURS_OPTION_BITS).dll:
$(OPTD)\target$(DETOURS_OPTION_BITS).pdb:
$(BIND)\extend$(DETOURS_OPTION_BITS).dll : $(OPTD)\extend$(DETOURS_OPTION_BITS).dll
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
$(BIND)\extend$(DETOURS_OPTION_BITS).pdb : $(OPTD)\extend$(DETOURS_OPTION_BITS).pdb
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
$(BIND)\target$(DETOURS_OPTION_BITS).dll : $(OPTD)\target$(DETOURS_OPTION_BITS).dll
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
$(BIND)\target$(DETOURS_OPTION_BITS).pdb : $(OPTD)\target$(DETOURS_OPTION_BITS).pdb
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
option: \
$(BIND)\extend$(DETOURS_OPTION_BITS).dll \
$(BIND)\extend$(DETOURS_OPTION_BITS).pdb \
$(BIND)\target$(DETOURS_OPTION_BITS).dll \
$(BIND)\target$(DETOURS_OPTION_BITS).pdb \
!ELSE
option:
!ENDIF
##############################################################################
verbose: all
cls
$(BIND)\symtest.exe
test: all
@echo -------- Reseting test binaries to initial state. -----------------------
$(BIND)\setdll.exe -r $(BIND)\findfunc.exe
@echo.
@echo -------- Should not load extend$(DETOURS_BITS).dll--------------------------------------
$(BIND)\findfunc.exe
@echo.
@echo -------- Adding extend$(DETOURS_BITS).dll to findfunc.exe ------------------------------
$(BIND)\setdll.exe -d:$(BIND)\extend$(DETOURS_BITS).dll $(BIND)\findfunc.exe
@echo.
@echo -------- Should load extend$(DETOURS_BITS).dll statically ------------------------------
$(BIND)\findfunc.exe
@echo.
@echo -------- Removing extend$(DETOURS_BITS).dll from findfunc.exe --------------------------
$(BIND)\setdll.exe -r $(BIND)\findfunc.exe
@echo.
@echo -------- Should not load extend$(DETOURS_BITS).dll -------------------------------------
$(BIND)\findfunc.exe
@echo.
@echo -------- Should load extend$(DETOURS_BITS).dll dynamically using withdll.exe -----------
$(BIND)\withdll.exe -d:$(BIND)\extend$(DETOURS_BITS).dll $(BIND)\findfunc.exe
@echo.
@echo -------- Test completed. ------------------------------------------------
################################################################# End of File.

152
samples/findfunc/extend.cpp Normal file
View File

@@ -0,0 +1,152 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detour Test Program (extend.cpp of extend.dll)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// An example dynamically detouring a function.
//
#include <stdio.h>
#include <windows.h>
#include "detours.h"
static LONG nExtends = 0;
static LONG nInterns = 0;
static DWORD (WINAPI * TrueTarget)(DWORD dwCount) = NULL;
static DWORD (WINAPI * TrueHidden)(DWORD dwCount) = NULL;
static int (WINAPI * TrueEntryPoint)(VOID) = NULL;
// Extend is a detour for Target.
static DWORD WINAPI Extend(DWORD dwCount)
{
InterlockedIncrement(&nExtends);
printf("extend.dll: Extend (%d) -> %d.\n", dwCount, dwCount + 1000);
dwCount = TrueTarget(dwCount + 1000);
printf("extend.dll: Extend (.....) -> %d.\n", dwCount);
return dwCount;
}
// Intern is a detour for Hidden.
static DWORD WINAPI Intern(DWORD dwCount)
{
InterlockedIncrement(&nInterns);
printf("extend.dll: Intern (%d) -> %d.\n", dwCount, dwCount + 10);
dwCount = TrueHidden(dwCount + 10);
printf("extend.dll: Intern (.....) -> %d.\n", dwCount);
return dwCount;
}
static int WINAPI ExtendEntryPoint()
{
// We couldn't call LoadLibrary in DllMain, so our functions here.
LONG error;
// We separate out the functions in the export table (Target)
// from the ones that require debug symbols (Hidden).
TrueTarget =
(DWORD (WINAPI *)(DWORD))
DetourFindFunction("target.dll", "Target");
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)TrueTarget, Extend);
error = DetourTransactionCommit();
if (error == NO_ERROR) {
printf("extend.dll: Detoured Target().\n");
}
else {
printf("extend.dll: Error detouring Target(): %d\n", error);
}
// Now try to detour the functions requiring debug symbols.
TrueHidden =
(DWORD (WINAPI *)(DWORD))
DetourFindFunction("target.dll", "Hidden");
if (TrueHidden == NULL) {
error = GetLastError();
printf("extend.dll: TrueHidden = %p (error = %d)\n", TrueHidden, error);
}
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)TrueHidden, Intern);
error = DetourTransactionCommit();
if (error == NO_ERROR) {
printf("extend.dll: Detoured Hidden().\n");
}
else {
printf("extend.dll: Error detouring Hidden(): %d\n", error);
}
// Now let the application start executing.
printf("extend.dll: Calling EntryPoint\n");
fflush(stdout);
return TrueEntryPoint();
}
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
{
LONG error;
(void)hinst;
(void)reserved;
if (DetourIsHelperProcess()) {
return TRUE;
}
if (dwReason == DLL_PROCESS_ATTACH) {
DetourRestoreAfterWith();
printf("extend.dll: Starting.\n");
fflush(stdout);
// NB: DllMain can't call LoadLibrary, so we hook the app entry point.
TrueEntryPoint = (int (WINAPI *)())DetourGetEntryPoint(NULL);
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)TrueEntryPoint, ExtendEntryPoint);
error = DetourTransactionCommit();
if (error == NO_ERROR) {
printf("extend.dll: Detoured EntryPoint().\n");
}
else {
printf("extend.dll: Error detouring EntryPoint(): %d\n", error);
}
}
else if (dwReason == DLL_PROCESS_DETACH) {
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
// Detach functions found from the export table.
if (TrueTarget != NULL) {
DetourDetach(&(PVOID&)TrueTarget, (PVOID)Extend);
}
// Detach functions found from debug symbols.
if (TrueHidden != NULL) {
DetourDetach(&(PVOID&)TrueHidden, (PVOID)Intern);
}
// Detach the entry point.
DetourDetach(&(PVOID&)TrueEntryPoint, ExtendEntryPoint);
error = DetourTransactionCommit();
printf("extend.dll: Removed Target() detours (%d), %d/%d calls.\n",
error, nExtends, nInterns);
fflush(stdout);
}
return TRUE;
}
//
///////////////////////////////////////////////////////////////// End of File.

View File

@@ -0,0 +1,17 @@
//////////////////////////////////////////////////////////////////////////////
//
// Version information for extend.rc.
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#include "detver.h"
#define VER_INTERNALNAME_STR "extend" DETOURS_STRINGIFY(DETOURS_BITS)
#define VER_ORIGINALFILENAME_STR "extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll"
#define VER_FILEDESCRIPTION_STR "Detours Dyanmic Interception Test Module"
#define VER_COMPANYNAME_STR "Microsoft Corporation"
#include "common.ver"

View File

@@ -0,0 +1,35 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detour Test Program (findfunc.cpp of findfunc.exe)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#include <windows.h>
#include <stdio.h>
#include <detours.h>
#include "target.h"
int __cdecl main(void)
{
printf("findfunc.exe: Starting.\n");
fflush(stdout);
printf("DLLs:\n");
for (HMODULE hModule = NULL; (hModule = DetourEnumerateModules(hModule)) != NULL;) {
CHAR szName[MAX_PATH] = { 0 };
GetModuleFileNameA(hModule, szName, sizeof(szName) - 1);
printf(" %p: %s\n", hModule, szName);
}
DWORD dwCount = 10000;
for (int i = 0; i < 3; i++) {
printf("findfunc.exe: Calling (%d).\n", dwCount);
dwCount = Target(dwCount) + 10000;
}
return 0;
}
//
///////////////////////////////////////////////////////////////// End of File.

View File

@@ -0,0 +1,385 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detour Test Program (symtest.cpp of symtest.exe)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#include <windows.h>
#include <stdio.h>
#pragma warning(push)
#if _MSC_VER > 1400
#pragma warning(disable:6102 6103) // /analyze warnings
#endif
#include <strsafe.h>
#pragma warning(pop)
#include <detours.h>
#include "target.h"
#if (_MSC_VER < 1299)
#include <imagehlp.h>
typedef IMAGEHLP_MODULE IMAGEHLP_MODULE64;
typedef PIMAGEHLP_MODULE PIMAGEHLP_MODULE64;
typedef IMAGEHLP_SYMBOL SYMBOL_INFO;
typedef PIMAGEHLP_SYMBOL PSYMBOL_INFO;
#else
#pragma warning(push)
#pragma warning(disable:4091) // empty typedef
#include <dbghelp.h>
#pragma warning(pop)
#endif
//////////////////////////////////////////////////////////////////////////////
//
typedef LPAPI_VERSION (NTAPI *PF_ImagehlpApiVersionEx)(LPAPI_VERSION AppVersion);
typedef BOOL (NTAPI *PF_SymInitialize)(IN HANDLE hProcess,
IN 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 HANDLE hFile,
IN PSTR ImageName,
IN PSTR ModuleName,
IN DWORD64 BaseOfDll,
IN 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);
#if (_MSC_VER < 1299)
typedef BOOL (NTAPI *PF_SymRegisterCallback64)();
typedef BOOL (NTAPI *PF_SymEnumerateModules64)();
typedef BOOL (NTAPI *PF_SymEnumSymbols)();
#else
typedef BOOL (NTAPI *PF_SymRegisterCallback64)(IN HANDLE hProcess,
IN PSYMBOL_REGISTERED_CALLBACK64
CallbackFunction,
IN ULONG64 UserContext);
typedef BOOL (NTAPI *PF_SymEnumerateModules64)(IN HANDLE hProcess,
IN PSYM_ENUMMODULES_CALLBACK64
EnumModulesCallback,
IN PVOID UserContext);
typedef BOOL (NTAPI *PF_SymEnumSymbols)(IN HANDLE hProcess,
IN ULONG64 BaseOfDll,
IN PCSTR Mask,
IN PSYM_ENUMERATESYMBOLS_CALLBACK
EnumSymbolsCallback,
IN PVOID UserContext);
#endif
PF_ImagehlpApiVersionEx pfImagehlpApiVersionEx = NULL;
PF_SymInitialize pfSymInitialize = NULL;
PF_SymSetOptions pfSymSetOptions = NULL;
PF_SymGetOptions pfSymGetOptions = NULL;
PF_SymLoadModule64 pfSymLoadModule64 = NULL;
PF_SymGetModuleInfo64 pfSymGetModuleInfo64 = NULL;
PF_SymFromName pfSymFromName = NULL;
PF_SymRegisterCallback64 pfSymRegisterCallback64 = NULL;
PF_SymEnumerateModules64 pfSymEnumerateModules64 = NULL;
PF_SymEnumSymbols pfSymEnumSymbols = NULL;
//////////////////////////////////////////////////////////////////////////////
//
#if (_MSC_VER > 1299)
static BOOL WINAPI SymEnumerateCallback(
PCSTR pszModule,
DWORD64 base,
PVOID pvUserContext)
{
(void)pvUserContext;
printf(" %p: %s\n", (PVOID)base, pszModule);
return TRUE;
}
static int nSymbolCount = 0;
static BOOL WINAPI SymEnumerateSymbols(PSYMBOL_INFO pSym,
ULONG size,
PVOID pvUserContext)
{
(void)size;
(void)pvUserContext;
if (strstr(pSym->Name, "Target") != NULL ||
strstr(pSym->Name, "Hidden") != NULL) {
printf(" %p: %s\n", (PVOID)pSym->Address, pSym->Name);
nSymbolCount++;
}
else if (nSymbolCount < 5) {
printf(" %p: %s\n", (PVOID)pSym->Address, pSym->Name);
nSymbolCount++;
}
return TRUE;
}
static void truncate(PCHAR data)
{
size_t len = strlen(data);
if (len > 0 && data[len-1] == '\r') {
data[--len] = '\0';
}
if (len > 0 && data[len-1] == '\n') {
data[--len] = '\0';
}
}
BOOL WINAPI CallbackFunction(HANDLE hProcess, ULONG action, ULONG64 data, ULONG64 context)
{
(void)context;
switch (action) {
case CBA_DEBUG_INFO:
truncate((PCHAR)data);
printf("::> %s\n", (PCHAR)data);
return TRUE;
case CBA_DEFERRED_SYMBOL_LOAD_CANCEL:
printf("::> proc=%p action=%08x data=%p\n",
(PVOID)hProcess,
action,
(PVOID)data);
{
PIMAGEHLP_DEFERRED_SYMBOL_LOAD64 pi = (PIMAGEHLP_DEFERRED_SYMBOL_LOAD64)data;
printf("pi->SizeOfStruct = %d\n", pi->SizeOfStruct);
printf("pi->BaseOfImage = %p\n", (PVOID)(size_t)pi->BaseOfImage);
printf("pi->CheckSum = %8x\n", pi->CheckSum);
printf("pi->FileName = %p [%s]\n", pi->FileName, pi->FileName);
printf("pi->Reparse = %d\n", pi->Reparse);
}
return FALSE;
default:
printf("::> proc=%p action=%08x data=%p\n",
(PVOID)hProcess,
action,
(PVOID)data);
return FALSE;
}
}
#endif
int __cdecl main(void)
{
printf("symtest.exe: Starting.\n");
fflush(stdout);
//////////////////////////////////////////////////////// Get the functions.
//
HMODULE hDbgHelp = LoadLibraryA("dbghelp.dll");
if (hDbgHelp == NULL) {
printf("Couldn't load dbghelp.dll");
return 1;
}
pfImagehlpApiVersionEx
= (PF_ImagehlpApiVersionEx)GetProcAddress(hDbgHelp,
"ImagehlpApiVersionEx");
pfSymInitialize
= (PF_SymInitialize)GetProcAddress(hDbgHelp, "SymInitialize");
pfSymSetOptions
= (PF_SymSetOptions)GetProcAddress(hDbgHelp, "SymSetOptions");
pfSymGetOptions
= (PF_SymGetOptions)GetProcAddress(hDbgHelp, "SymGetOptions");
pfSymLoadModule64
= (PF_SymLoadModule64)GetProcAddress(hDbgHelp, "SymLoadModule64");
pfSymGetModuleInfo64
= (PF_SymGetModuleInfo64)GetProcAddress(hDbgHelp, "SymGetModuleInfo64");
pfSymFromName
= (PF_SymFromName)GetProcAddress(hDbgHelp, "SymFromName");
pfSymRegisterCallback64
= (PF_SymRegisterCallback64)GetProcAddress(hDbgHelp, "SymRegisterCallback64");
pfSymEnumerateModules64
= (PF_SymEnumerateModules64)GetProcAddress(hDbgHelp, "SymEnumerateModules64");
pfSymEnumSymbols
= (PF_SymEnumSymbols)GetProcAddress(hDbgHelp, "SymEnumSymbols");
//////////////////////////////////////////////////////////////////////////////
//
HANDLE hProcess = GetCurrentProcess();
API_VERSION av;
ZeroMemory(&av, sizeof(av));
av.MajorVersion = API_VERSION_NUMBER;
pfImagehlpApiVersionEx(&av);
printf(" Version: %d.%d (%d)\n",
av.MajorVersion,
av.MinorVersion,
API_VERSION_NUMBER);
if (!pfSymInitialize(hProcess, NULL, FALSE)) {
printf("SymInitialize failed: %d\n", GetLastError());
return 1;
}
#if (_MSC_VER > 1299)
pfSymRegisterCallback64(hProcess, CallbackFunction, NULL);
#endif
DWORD dw = pfSymGetOptions();
printf("GetOptions = %08x\n", dw);
dw &= ~(SYMOPT_CASE_INSENSITIVE |
SYMOPT_UNDNAME |
SYMOPT_DEFERRED_LOADS |
0);
dw |= (
#if defined(SYMOPT_EXACT_SYMBOLS)
SYMOPT_EXACT_SYMBOLS |
#endif
#if defined(SYMOPT_DEBUG)
SYMOPT_DEBUG |
#endif
#if defined(SYMOPT_NO_UNQUALIFIED_LOADS)
SYMOPT_NO_UNQUALIFIED_LOADS |
#endif
#if defined(SYMOPT_FAIL_CRITICAL_ERRORS)
SYMOPT_FAIL_CRITICAL_ERRORS |
#endif
#if defined(SYMOPT_INCLUDE_32BIT_MODULES)
SYMOPT_INCLUDE_32BIT_MODULES |
#endif
0);
printf("SetOptions = %08x\n", dw);
pfSymSetOptions(dw);
/////////////////////////////////////////////// First, try GetProcAddress.
//
PCHAR pszFile = "target.dll";
HMODULE hModule = LoadLibraryA(pszFile);
if (hModule == NULL) {
printf("LoadLibraryA(%s) failed: %d\n", pszFile, GetLastError());
return 2;
}
////////////////////////////////////////////////////// Then try ImageHelp.
//
#if (_MSC_VER > 1299)
//CHAR szFull[MAX_PATH];
//GetModuleFileNameA(hModule, szFull, sizeof(szFull));
printf("SymLoadModule64(%s) will be called.\n", pszFile /*szFull*/);
DWORD64 loaded = pfSymLoadModule64(hProcess, NULL,
(PCHAR)pszFile/*szFull*/, NULL,
(DWORD64)hModule, 0);
if (loaded == 0) {
printf("SymLoadModule64(%p) failed: %d\n", hProcess, GetLastError());
printf("\n");
}
else {
printf("SymLoadModule64(%p) succeeded: 0x%p\n", hProcess, (PVOID)loaded);
}
CHAR szModName[512];
printf("Modules:\n");
// The first parameter of PSYM_ENUMMODULES_CALLBACK64 changed from PSTR to PCSTR
// between Windows 2003 and Windows 7. Cast here to work with either.
pfSymEnumerateModules64(hProcess, (PSYM_ENUMMODULES_CALLBACK64)SymEnumerateCallback, NULL);
printf("\n");
IMAGEHLP_MODULE64 modinfo;
ZeroMemory(&modinfo, sizeof(modinfo));
modinfo.SizeOfStruct = 512/*sizeof(modinfo)*/;
if (!pfSymGetModuleInfo64(hProcess, (DWORD64)hModule, &modinfo)) {
printf("SymGetModuleInfo64(%p, %p) [64] failed: %d\n",
hProcess, hModule, GetLastError());
}
else {
printf("SymGetModuleInfo64(%p, %p) [64] succeeded: %d\n",
hProcess, hModule, GetLastError());
StringCchCopyA(szModName, ARRAYSIZE(szModName), modinfo.ModuleName);
StringCchCatA(szModName, ARRAYSIZE(szModName), "!");
printf("NumSyms: %d\n", modinfo.NumSyms);
printf("SymType: %d\n", modinfo.SymType);
printf("ModuleName: %s\n", modinfo.ModuleName);
printf("ImageName: %s\n", modinfo.ImageName);
printf("LoadedImageName: %s\n", modinfo.LoadedImageName);
}
printf("\n");
fflush(stdout);
printf("DLLs:\n");
for (hModule = NULL; (hModule = DetourEnumerateModules(hModule)) != NULL;) {
CHAR szName[MAX_PATH];
GetModuleFileNameA(hModule, szName, sizeof(szName));
printf(" %p: %s\n", hModule, szName);
}
if (pfSymEnumSymbols == NULL) {
printf("Couldn't find SymEnumSymbols.\n");
}
else {
printf("===Enum===\n");
SetLastError(0);
nSymbolCount = 0;
if (!pfSymEnumSymbols(hProcess, (DWORD64)hModule, NULL, SymEnumerateSymbols, NULL)) {
printf("SymEnumSymbols() failed: %d\n",
GetLastError());
}
}
// Look for specific symbols.
struct CFullSymbol : SYMBOL_INFO {
CHAR szRestOfName[MAX_SYM_NAME];
} symbol;
CHAR szFullName[512];
// Look for Target
StringCchCopyA(szFullName, ARRAYSIZE(szFullName), szModName);
StringCchCatA(szFullName, ARRAYSIZE(szFullName), "Target");
printf("Symbol: [%s]\n", szFullName);
ZeroMemory(&symbol, sizeof(symbol));
symbol.SizeOfStruct = sizeof(SYMBOL_INFO);
#ifdef DBHLPAPI
symbol.MaxNameLen = MAX_SYM_NAME;
#else
symbol.MaxNameLength = MAX_SYM_NAME;
#endif
SetLastError(0);
if (!pfSymFromName(hProcess, szFullName, &symbol)) {
printf("--SymFromName(%s) failed: %d\n", szFullName, GetLastError());
}
if (symbol.Address != 0) {
printf("--SymFromName(%s) succeeded\n", szFullName);
}
printf("%s => %p\n\n", szFullName, (PBYTE)symbol.Address);
// Look for Hidden
StringCchCopyA(szFullName, ARRAYSIZE(szFullName), szModName);
StringCchCatA(szFullName, ARRAYSIZE(szFullName), "Hidden");
printf("Symbol: [%s]\n", szFullName);
ZeroMemory(&symbol, sizeof(symbol));
symbol.SizeOfStruct = sizeof(SYMBOL_INFO);
#ifdef DBHLPAPI
symbol.MaxNameLen = MAX_SYM_NAME;
#else
symbol.MaxNameLength = MAX_SYM_NAME;
#endif
SetLastError(0);
if (!pfSymFromName(hProcess, szFullName, &symbol)) {
printf("--SymFromName(%s) failed: %d\n", szFullName, GetLastError());
}
if (symbol.Address != 0) {
printf("--SymFromName(%s) succeeded\n", szFullName);
}
printf("%s => %p\n\n", szFullName, (PBYTE)symbol.Address);
#endif
// We call Target once to insure it is loaded.
Target(0);
return 0;
}
//
///////////////////////////////////////////////////////////////// End of File.

View File

@@ -0,0 +1,41 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detour Test Program (target.cpp of target.dll)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#include <stdio.h>
#include <windows.h>
#include "target.h"
extern "C" DWORD WINAPI Hidden(DWORD dwCount)
{
printf("target.dll: Hidden(%d) -> %d.\n", dwCount, dwCount + 1);
return dwCount + 1;
}
// We use this point to ensure Hidden isn't inlined.
static DWORD (WINAPI * SelfHidden)(DWORD dwCount) = Hidden;
DWORD WINAPI Target(DWORD dwCount)
{
printf("target.dll: Target (%d) -> %d.\n", dwCount, dwCount + 100);
dwCount = SelfHidden(dwCount + 100);
printf("target.dll: Target (.....) -> %d.\n", dwCount);
return dwCount;
}
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
{
(void)hinst;
(void)dwReason;
(void)reserved;
return TRUE;
}
//
///////////////////////////////////////////////////////////////// End of File.

13
samples/findfunc/target.h Normal file
View File

@@ -0,0 +1,13 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detour Test Program (target.h of target.dll)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
DWORD WINAPI Target(DWORD dwCount);
//
///////////////////////////////////////////////////////////////// End of File.

View File

@@ -0,0 +1,17 @@
//////////////////////////////////////////////////////////////////////////////
//
// Version information for target.rc.
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#include "detver.h"
#define VER_INTERNALNAME_STR "target" DETOURS_STRINGIFY(DETOURS_BITS)
#define VER_ORIGINALFILENAME_STR "target" DETOURS_STRINGIFY(DETOURS_BITS) ".dll"
#define VER_FILEDESCRIPTION_STR "Detours Test Module"
#define VER_COMPANYNAME_STR "Microsoft Corporation"
#include "common.ver"

56
samples/impmunge/Makefile Normal file
View File

@@ -0,0 +1,56 @@
##############################################################################
##
## Makefile for Detours Test Programs.
##
## Microsoft Research Detours Package
##
## Copyright (c) Microsoft Corporation. All rights reserved.
##
!include ..\common.mak
LIBS=$(LIBS) kernel32.lib
all: dirs \
$(BIND)\impmunge.exe \
!IF $(DETOURS_SOURCE_BROWSING)==1
$(OBJD)\impmunge.bsc
!ENDIF
##############################################################################
clean:
-del *~ test.exe.* 2>nul
-del $(BIND)\impmunge.* 2>nul
-rmdir /q /s $(OBJD) 2>nul
realclean: clean
-rmdir /q /s $(OBJDS) 2>nul
##############################################################################
dirs:
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
$(OBJD)\impmunge.obj : impmunge.cpp
$(BIND)\impmunge.exe : $(OBJD)\impmunge.obj $(DEPS)
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\impmunge.obj \
/link $(LINKFLAGS) $(LIBS) imagehlp.lib /subsystem:console
$(OBJD)\impmunge.bsc : $(OBJD)\impmunge.obj
bscmake /v /n /o $@ $(OBJD)\impmunge.sbr
##############################################################################
test: $(BIND)\impmunge.exe
$(BIND)\impmunge.exe /m /o:test.exe.1 $(BIND)\impmunge.exe
$(BIND)\impmunge.exe /m /l- /o:test.exe.2 test.exe.1
$(BIND)\impmunge.exe /m /l- /o:test.exe.3 test.exe.2
$(BIND)\impmunge.exe /m /l- /o:test.exe.4 test.exe.3
$(BIND)\impmunge.exe /l test.exe.4
$(BIND)\impmunge.exe /r /l- /o:test.exe.0 test.exe.4
$(BIND)\impmunge.exe /l test.exe.0
################################################################# End of File.

View File

@@ -0,0 +1,464 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detours Test Program (impmunge.cpp of impmunge.exe)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#pragma warning(push)
#if _MSC_VER > 1400
#pragma warning(disable:6102 6103) // /analyze warnings
#endif
#include <strsafe.h>
#include <detours.h>
#pragma warning(disable:4091) // empty typedef
#include <imagehlp.h>
#pragma warning(pop)
////////////////////////////////////////////////////////////// Error Messages.
//
VOID AssertMessage(PCSTR szMsg, PCSTR szFile, DWORD nLine)
{
printf("ASSERT(%s) failed in %s, line %d.", szMsg, szFile, nLine);
}
#define ASSERT(x) \
do { if (!(x)) { AssertMessage(#x, __FILE__, __LINE__); DebugBreak(); }} while (0)
;
//////////////////////////////////////////////////////////////////////////////
//
static BOOLEAN s_fRestore = FALSE;
static BOOLEAN s_fList = TRUE;
static BOOLEAN s_fMunge = FALSE;
static BOOLEAN s_fToSymbols = FALSE;
//////////////////////////////////////////////////////////////////////////////
//
static BOOL CALLBACK ListByway(_In_opt_ PVOID pContext,
_In_opt_ LPCSTR pszFile,
_Outptr_result_maybenull_ LPCSTR *ppszOutFile)
{
(void)pContext;
(void)ppszOutFile;
printf(" byway -------------------------------- %s\n", pszFile ? pszFile : "");
return TRUE;
}
static BOOL CALLBACK ListFile(_In_opt_ PVOID pContext,
_In_ LPCSTR pszOrigFile,
_In_ LPCSTR pszFile,
_Outptr_result_maybenull_ LPCSTR *ppszOutFile)
{
(void)pContext;
(void)ppszOutFile;
printf(" file %-32.32s %-32.32s\n",
pszOrigFile ? pszOrigFile : "",
pszFile ? pszFile : "");
return TRUE;
}
static BOOL CALLBACK ListSymbol(_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)
{
(void)pContext;
(void)pnOutOrdinal;
(void)ppszOutSymbol;
char szOrig[80];
char szLast[80];
if (pszOrigSymbol == NULL) {
StringCchPrintfA(szOrig, sizeof(szOrig), "#%d", nOrigOrdinal);
pszOrigSymbol = szOrig;
}
if (pszSymbol == NULL) {
StringCchPrintfA(szLast, sizeof(szLast), "#%d", nOrdinal);
pszSymbol = szLast;
}
printf(" symbol %-32.32s %-32.32s\n", pszOrigSymbol, pszSymbol);
return TRUE;
}
static BOOL CALLBACK ListCommit(PVOID pContext)
{
(void)pContext;
printf(" commit\n");
return TRUE;
}
//////////////////////////////////////////////////////////////////////////////
//
struct MUNGE_STATE
{
BOOL fLastWasByway;
LONG nBywayCount;
CHAR szBuffer[512];
};
static BOOL CALLBACK MungeByway(_In_opt_ PVOID pContext,
_In_opt_ LPCSTR pszFile,
_Outptr_result_maybenull_ LPCSTR *ppszOutFile)
{
MUNGE_STATE *pState = (MUNGE_STATE *)pContext;
printf("|");
if (pState->fLastWasByway) {
return TRUE;
}
pState->fLastWasByway = TRUE;
if (pszFile == NULL) {
StringCchPrintfA(pState->szBuffer, sizeof(pState->szBuffer), "mb_munge_%d.dll", pState->nBywayCount++);
*ppszOutFile = pState->szBuffer;
}
return TRUE;
}
static BOOL CALLBACK MungeFile(_In_opt_ PVOID pContext,
_In_ LPCSTR pszOrigFile,
_In_ LPCSTR pszFile,
_Outptr_result_maybenull_ LPCSTR *ppszOutFile)
{
(void)pszOrigFile;
MUNGE_STATE *pState = (MUNGE_STATE *)pContext;
pState->fLastWasByway = FALSE;
printf("*");
StringCchPrintfA(pState->szBuffer, sizeof(pState->szBuffer), "mf_%s", pszFile);
*ppszOutFile = pState->szBuffer;
return TRUE;
}
static BOOL CALLBACK MungeSymbol(_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)
{
(void)nOrigOrdinal;
(void)pszOrigSymbol;
MUNGE_STATE *pState = (MUNGE_STATE *)pContext;
pState->fLastWasByway = FALSE;
printf(".");
if (nOrdinal != 0) {
if (s_fToSymbols) {
StringCchPrintfA(pState->szBuffer, sizeof(pState->szBuffer), "mo_%d", (int)nOrdinal);
*pnOutOrdinal = 0;
*ppszOutSymbol = pState->szBuffer;
}
else {
*pnOutOrdinal = 10000 + nOrdinal;
*ppszOutSymbol = NULL;
}
}
else {
StringCchPrintfA(pState->szBuffer, sizeof(pState->szBuffer), "ms_%s", pszSymbol);
*pnOutOrdinal = 0;
*ppszOutSymbol = pState->szBuffer;
}
return TRUE;
}
static BOOL CALLBACK MungeCommit(PVOID pContext)
{
MUNGE_STATE *pState = (MUNGE_STATE *)pContext;
pState->fLastWasByway = FALSE;
printf("\n");
(void)pContext;
return TRUE;
}
//////////////////////////////////////////////////////////////////////////////
//
static BOOL CALLBACK RestoreByway(_In_opt_ PVOID pContext,
_In_opt_ LPCSTR pszFile,
_Outptr_result_maybenull_ LPCSTR *ppszOutFile)
{
(void)pContext;
(void)pszFile;
*ppszOutFile = NULL;
return TRUE;
}
static BOOL CALLBACK RestoreFile(_In_opt_ PVOID pContext,
_In_ LPCSTR pszOrigFile,
_In_ LPCSTR pszFile,
_Outptr_result_maybenull_ LPCSTR *ppszOutFile)
{
(void)pContext;
(void)pszFile;
*ppszOutFile = pszOrigFile;
return TRUE;
}
static BOOL CALLBACK RestoreSymbol(_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)
{
(void)pContext;
(void)nOrdinal;
(void)pszSymbol;
*pnOutOrdinal = nOrigOrdinal;
*ppszOutSymbol = pszOrigSymbol;
return TRUE;
}
static BOOL CALLBACK RestoreCommit(PVOID pContext)
{
(void)pContext;
return TRUE;
}
//////////////////////////////////////////////////////////////////////////////
//
BOOL EditFile(PCHAR pszInput, PCHAR pszOutput)
{
BOOL fGood = TRUE;
HANDLE hOld = INVALID_HANDLE_VALUE;
HANDLE hNew = INVALID_HANDLE_VALUE;
PDETOUR_BINARY pBinary = NULL;
if (pszOutput != NULL) {
printf("%s -> %s:\n", pszInput, pszOutput);
}
else {
printf("%s:\n", pszInput);
}
hOld = CreateFileA(pszInput,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hOld == INVALID_HANDLE_VALUE) {
printf("Couldn't open input file: %s, error: %d\n",
pszInput, GetLastError());
fGood = FALSE;
goto end;
}
if ((pBinary = DetourBinaryOpen(hOld)) == NULL) {
printf("DetourBinaryOpen failed: %d\n", GetLastError());
goto end;
}
if (hOld != INVALID_HANDLE_VALUE) {
CloseHandle(hOld);
hOld = INVALID_HANDLE_VALUE;
}
if (s_fRestore) {
if (!DetourBinaryEditImports(pBinary,
NULL,
RestoreByway,
RestoreFile,
RestoreSymbol,
RestoreCommit)) {
printf("DetourBinaryEditImports for munge failed: %d\n", GetLastError());
}
}
if (s_fMunge) {
MUNGE_STATE state;
state.fLastWasByway = FALSE;
state.nBywayCount = 1;
if (!DetourBinaryEditImports(pBinary,
&state,
MungeByway,
MungeFile,
MungeSymbol,
MungeCommit)) {
printf("DetourBinaryEditImports for munge failed: %d\n", GetLastError());
}
}
if (s_fList) {
if (!DetourBinaryEditImports(pBinary,
NULL,
ListByway,
ListFile,
ListSymbol,
ListCommit)) {
printf("DetourBinaryEditImports for list failed: %d\n", GetLastError());
}
}
if (pszOutput != NULL) {
hNew = CreateFileA(pszOutput,
GENERIC_WRITE | GENERIC_READ, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if (hNew == INVALID_HANDLE_VALUE) {
printf("Couldn't open output file: %s, error: %d\n",
pszOutput, GetLastError());
fGood = FALSE;
goto end;
}
if (!DetourBinaryWrite(pBinary, hNew)) {
printf("DetourBinaryWrite failed: %d\n", GetLastError());
fGood = FALSE;
}
CloseHandle(hNew);
hNew = INVALID_HANDLE_VALUE;
}
DetourBinaryClose(pBinary);
pBinary = NULL;
if (fGood && pszOutput != NULL) {
if (!BindImageEx(BIND_NO_BOUND_IMPORTS, pszOutput, ".", ".", NULL)) {
printf("Warning: Couldn't bind binary %s: %d\n", pszOutput, GetLastError());
}
}
end:
if (pBinary) {
DetourBinaryClose(pBinary);
pBinary = NULL;
}
if (hNew != INVALID_HANDLE_VALUE) {
CloseHandle(hNew);
hNew = INVALID_HANDLE_VALUE;
}
if (hOld != INVALID_HANDLE_VALUE) {
CloseHandle(hOld);
hOld = INVALID_HANDLE_VALUE;
}
return fGood;
}
//////////////////////////////////////////////////////////////////////////////
//
void PrintUsage(void)
{
printf("Usage:\n"
" impmunge [options] binary_files\n"
"Options:\n"
" /l : List imports.\n"
" /l- : Don't list imports.\n"
" /m : Munge imports.\n"
" /r : Remove import munges.\n"
" /o:file : Set name of output file; must be include with /m or /r.\n"
" /? : This help screen.\n");
}
//////////////////////////////////////////////////////////////////////// main.
//
int CDECL main(int argc, char **argv)
{
BOOL fNeedHelp = FALSE;
PCHAR pszOutput = NULL;
int arg = 1;
for (; arg < argc && !fNeedHelp; arg++) {
if (argv[arg][0] == '-' || argv[arg][0] == '/') {
CHAR *argn = argv[arg] + 1;
CHAR *argp = argn;
while (*argp && *argp != ':')
argp++;
if (*argp == ':')
*argp++ = '\0';
switch (argn[0]) {
case 'l': // List contents of import table.
case 'L':
s_fList = (argn[1] != '-');
break;
case 'm': // Munge import table.
case 'M':
s_fMunge = (argn[1] != '-');
break;
case 'o': // Set output file name.
case 'O':
pszOutput = argp;
break;
case 'r': // Restore file to unmunged state.
case 'R':
s_fRestore = (argn[1] != '-');
break;
case 's': // Munge ordinals to symbols
case 'S':
s_fToSymbols = true;
break;
case '?': // Help
fNeedHelp = TRUE;
break;
default:
fNeedHelp = TRUE;
printf("Bad argument: %s:%s\n", argn, argp);
break;
}
}
else {
if (!s_fList && !s_fMunge && !s_fRestore) {
fNeedHelp = TRUE;
break;
}
if (pszOutput == NULL && (s_fMunge || s_fRestore)) {
fNeedHelp = TRUE;
break;
}
EditFile(argv[arg], pszOutput);
pszOutput = NULL;
}
}
if (argc == 1) {
fNeedHelp = TRUE;
}
if (fNeedHelp) {
PrintUsage();
return 1;
}
return 0;
}
// End of File

48
samples/member/Makefile Normal file
View File

@@ -0,0 +1,48 @@
##############################################################################
##
## Makefile for Detours Test Programs.
##
## Microsoft Research Detours Package
##
## Copyright (c) Microsoft Corporation. All rights reserved.
##
!include ..\common.mak
LIBS=$(LIBS) kernel32.lib
all: dirs \
$(BIND)\member.exe \
!IF $(DETOURS_SOURCE_BROWSING)==1
$(OBJD)\member.bsc
!ENDIF
clean:
-del *~ 2> nul
-del $(BIND)\member.* 2> nul
-rmdir /q /s $(OBJD) 2>nul
realclean: clean
-rmdir /q /s $(OBJDS) 2>nul
dirs:
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
$(OBJD)\member.obj : member.cpp
$(BIND)\member.exe : $(OBJD)\member.obj $(DEPS)
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\member.obj \
/link $(LINKFLAGS) $(LIBS) /subsystem:console
$(OBJD)\member.bsc : $(OBJD)\member.obj
bscmake /v /n /o $@ $(OBJD)\member.sbr
##############################################################################
test: $(BIND)\member.exe
@echo.
$(BIND)\member.exe
@echo.
################################################################# End of File.

116
samples/member/member.cpp Normal file
View File

@@ -0,0 +1,116 @@
//////////////////////////////////////////////////////////////////////////////
//
// Test a detour of a member function (member.cpp of member.exe)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// By default, C++ member functions use the __thiscall calling convention.
// In order to Detour a member function, both the trampoline and the detour
// must have exactly the same calling convention as the target function.
// Unfortunately, the VC compiler does not support a __thiscall, so the only
// way to create legal detour and trampoline functions is by making them
// class members of a "detour" class.
//
// In addition, C++ does not support converting a pointer to a member
// function to an arbitrary pointer. To get a raw pointer, the address of
// the member function must be moved into a temporary member-function
// pointer, then passed by taking it's address, then de-referencing it.
// Fortunately, the compiler will optimize the code to remove the extra
// pointer operations.
//
// If X::Target is a virtual function, the following code will *NOT* work
// because &X::Target is the address of a thunk that does a virtual call,
// not the real address of the X::Target. You can get the real address
// of X::Target by looking directly in the VTBL for class X, but there
// is no legal way to 1) get the address of X's VTBL or 2) get the offset
// of ::Target within that VTBL. You can of course, figure these out for
// a particular class and function, but there is no general way to do so.
//
#include <stdio.h>
#include <windows.h>
#include <detours.h>
#include "..\slept\verify.cpp"
//////////////////////////////////////////////////////////////// Target Class.
//
class CMember
{
public:
void Target(void);
};
void CMember::Target(void)
{
printf(" CMember::Target! (this:%p)\n", this);
}
//////////////////////////////////////////////////////////////// Detour Class.
//
class CDetour /* add ": public CMember" to enable access to member variables... */
{
public:
void Mine_Target(void);
static void (CDetour::* Real_Target)(void);
// Class shouldn't have any member variables or virtual functions.
};
void CDetour::Mine_Target(void)
{
printf(" CDetour::Mine_Target! (this:%p)\n", this);
(this->*Real_Target)();
}
void (CDetour::* CDetour::Real_Target)(void) = (void (CDetour::*)(void))&CMember::Target;
//////////////////////////////////////////////////////////////////////////////
//
int main(int argc, char **argv)
{
(void)argc;
(void)argv;
//////////////////////////////////////////////////////////////////////////
//
void (CMember::* pfTarget)(void) = &CMember::Target;
void (CDetour::* pfMine)(void) = &CDetour::Mine_Target;
Verify("CMember::Target ", *(PBYTE*)&pfTarget);
Verify("*CDetour::Real_Target", *(PBYTE*)&CDetour::Real_Target);
Verify("CDetour::Mine_Target ", *(PBYTE*)&pfMine);
printf("\n");
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)CDetour::Real_Target,
*(PBYTE*)&pfMine);
LONG l = DetourTransactionCommit();
printf("DetourTransactionCommit = %d\n", l);
printf("\n");
Verify("CMember::Target ", *(PBYTE*)&pfTarget);
Verify("*CDetour::Real_Target", *(&(PBYTE&)CDetour::Real_Target));
Verify("CDetour::Mine_Target ", *(PBYTE*)&pfMine);
printf("\n");
//////////////////////////////////////////////////////////////////////////
//
CMember target;
printf("Calling CMember (w/o Detour):\n");
(((CDetour*)&target)->*CDetour::Real_Target)();
printf("Calling CMember (will be detoured):\n");
target.Target();
return 0;
}

112
samples/opengl/Makefile Normal file
View File

@@ -0,0 +1,112 @@
######################################################################
##
## Hook test for glFinish
##
!include ..\common.mak
LIBS=$(LIBS) kernel32.lib gdi32.lib
##############################################################################
all: dirs \
$(BIND)\ogldet$(DETOURS_BITS).dll \
$(BIND)\testogl.exe \
\
!IF $(DETOURS_SOURCE_BROWSING)==1
$(OBJD)\ogldet$(DETOURS_BITS).bsc \
$(OBJD)\testogl.bsc \
!ENDIF
option
##############################################################################
dirs:
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
$(OBJD)\ogldet.obj : ogldet.cpp
$(OBJD)\ogldet.res : ogldet.rc
$(BIND)\ogldet$(DETOURS_BITS).dll $(BIND)\ogldet$(DETOURS_BITS).lib: \
$(OBJD)\ogldet.obj $(OBJD)\ogldet.res $(DEPS)
cl /LD $(CFLAGS) /Fe$(@R).dll /Fd$(@R).pdb \
$(OBJD)\ogldet.obj $(OBJD)\ogldet.res \
/link $(LINKFLAGS) /subsystem:console \
/export:DetourFinishHelperProcess,@1,NONAME \
/export:hookedGlFinish \
$(LIBS) opengl32.lib
$(OBJD)\ogldet$(DETOURS_BITS).bsc : $(OBJD)\ogldet.obj
bscmake /v /n /o $@ $(OBJD)\ogldet.sbr
$(OBJD)\testogl.obj : testogl.cpp
$(BIND)\testogl.exe : $(OBJD)\testogl.obj $(DEPS)
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\testogl.obj \
/link $(LINKFLAGS) $(LIBS) opengl32.lib \
/subsystem:console
$(OBJD)\testogl.bsc : $(OBJD)\testogl.obj
bscmake /v /n /o $@ $(OBJD)\testogl.sbr
##############################################################################
clean:
-del *~ 2>nul
-del $(BIND)\ogldet*.* 2>nul
-del $(BIND)\testogl.* 2>nul
-rmdir /q /s $(OBJD) 2>nul
realclean: clean
-rmdir /q /s $(OBJDS) 2>nul
############################################### Install non-bit-size binaries.
!IF "$(DETOURS_OPTION_PROCESSOR)" != ""
$(OPTD)\olgdet$(DETOURS_OPTION_BITS).dll:
$(OPTD)\olgdet$(DETOURS_OPTION_BITS).pdb:
$(BIND)\olgdet$(DETOURS_OPTION_BITS).dll : $(OPTD)\olgdet$(DETOURS_OPTION_BITS).dll
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
$(BIND)\olgdet$(DETOURS_OPTION_BITS).pdb : $(OPTD)\olgdet$(DETOURS_OPTION_BITS).pdb
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
option: \
$(BIND)\olgdet$(DETOURS_OPTION_BITS).dll \
$(BIND)\olgdet$(DETOURS_OPTION_BITS).pdb \
!ELSE
option:
!ENDIF
##############################################################################
test: all
@echo -------- Reseting test binaries to initial state. ---------------------
$(BIND)\setdll.exe -r $(BIND)\testogl.exe
@echo.
@echo -------- Should not load ogldet$(DETOURS_BITS).dll -----------------------------------
$(BIND)\testogl.exe
@echo.
@echo -------- Adding ogldet$(DETOURS_BITS).dll to testogl.exe ------------------------------
$(BIND)\setdll.exe -d:$(BIND)\ogldet$(DETOURS_BITS).dll $(BIND)\testogl.exe
@echo.
@echo -------- Should load ogldet$(DETOURS_BITS).dll statically ----------------------------
$(BIND)\testogl.exe
@echo.
@echo -------- Removing ogldet$(DETOURS_BITS).dll from testogl.exe --------------------------
$(BIND)\setdll.exe -r $(BIND)\testogl.exe
@echo.
@echo -------- Should not load ogldet$(DETOURS_BITS).dll -----------------------------------
$(BIND)\testogl.exe
@echo.
@echo -------- Should load ogldet$(DETOURS_BITS).dll dynamically using withdll.exe----------
$(BIND)\withdll.exe -d:$(BIND)\ogldet$(DETOURS_BITS).dll $(BIND)\testogl.exe
@echo.
################################################################# End of File.

74
samples/opengl/ogldet.cpp Normal file
View File

@@ -0,0 +1,74 @@
//////////////////////////////////////////////////////////////////////////////
//
// Module: ogldet.dll
//
// This DLL is based on the sample simple.dll. A detour is inserted for
// the OpenGL glFinish function.
//
#include <stdio.h>
#include <windows.h>
#include <GL/gl.h>
#include "detours.h"
static void (WINAPI * trueGlFinish)(void) = glFinish;
void WINAPI hookedGlFinish(void)
{
printf("ogldet" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
" hookedGlFinish Starting.\n");
fflush(stdout);
trueGlFinish();
printf("ogldet" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
" hookedGlFinish done.\n");
fflush(stdout);
}
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
{
LONG error;
(void)hinst;
(void)reserved;
if (DetourIsHelperProcess()) {
return TRUE;
}
if (dwReason == DLL_PROCESS_ATTACH) {
DetourRestoreAfterWith();
printf("ogldet" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
" Starting.\n");
fflush(stdout);
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)trueGlFinish, hookedGlFinish);
error = DetourTransactionCommit();
if (error == NO_ERROR) {
printf("ogldet" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
" Detoured glFinish().\n");
}
else {
printf("ogldet" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
" Error detouring glFinish(): %d\n", error);
}
}
else if (dwReason == DLL_PROCESS_DETACH) {
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)trueGlFinish, hookedGlFinish);
error = DetourTransactionCommit();
printf("ogldet" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
" Removed detour glFinish() (result=%d)\n", error);
fflush(stdout);
}
return TRUE;
}
//
///////////////////////////////////////////////////////////////// End of File.

17
samples/opengl/ogldet.rc Normal file
View File

@@ -0,0 +1,17 @@
//////////////////////////////////////////////////////////////////////////////
//
// Version information for ogldet.rc.
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#include "detver.h"
#define VER_INTERNALNAME_STR "ogldet" DETOURS_STRINGIFY(DETOURS_BITS)
#define VER_ORIGINALFILENAME_STR "ogldet" DETOURS_STRINGIFY(DETOURS_BITS) ".dll"
#define VER_FILEDESCRIPTION_STR "Detours Open GL Test Module"
#define VER_COMPANYNAME_STR "Microsoft Corporation"
#include "common.ver"

View File

@@ -0,0 +1,24 @@
//////////////////////////////////////////////////////////////////////////////
//
// File: testogl.cpp
// Module: testogl.exe (oglsimple.dll)
//
#include <windows.h>
#include <stdio.h>
#include <GL/gl.h>
int __cdecl main()
{
printf("testogl.exe: Starting\n");
fflush(stdout);
glFinish();
printf("testogl.exe: done\n");
fflush(stdout);
return 0;
}
//
///////////////////////////////////////////////////////////////// End of File.

48
samples/region/Makefile Normal file
View File

@@ -0,0 +1,48 @@
##############################################################################
##
## Makefile for Detours Test Programs.
##
## Microsoft Research Detours Package
##
## Copyright (c) Microsoft Corporation. All rights reserved.
##
!include ..\common.mak
LIBS=$(LIBS) kernel32.lib
all: dirs \
$(BIND)\region.exe \
!IF $(DETOURS_SOURCE_BROWSING)==1
$(OBJD)\region.bsc
!ENDIF
clean:
-del *~ 2> nul
-del $(BIND)\region.* 2> nul
-rmdir /q /s $(OBJD) 2>nul
realclean: clean
-rmdir /q /s $(OBJDS) 2>nul
dirs:
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
$(OBJD)\region.obj : region.cpp
$(BIND)\region.exe : $(OBJD)\region.obj $(DEPS)
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\region.obj \
/link $(LINKFLAGS) $(LIBS) /subsystem:console
$(OBJD)\region.bsc : $(OBJD)\region.obj
bscmake /v /n /o $@ $(OBJD)\region.sbr
##############################################################################
test: $(BIND)\region.exe
@echo.
$(BIND)\region.exe
@echo.
################################################################# End of File.

105
samples/region/region.cpp Normal file
View File

@@ -0,0 +1,105 @@
//////////////////////////////////////////////////////////////////////////////
//
// Test the different system region bounds (region.cpp of region.exe)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#include <stdio.h>
#include <windows.h>
#include <detours.h>
//////////////////////////////////////////////////////////////////////////////
//
static LONG dwSlept = 0;
static DWORD (WINAPI * TrueSleepEx)(DWORD dwMilliseconds, BOOL bAlertable) = SleepEx;
DWORD WINAPI LoudSleepEx(DWORD dwMilliseconds, BOOL bAlertable)
{
DWORD dwBeg = GetTickCount();
DWORD ret = TrueSleepEx(dwMilliseconds, bAlertable);
DWORD dwEnd = GetTickCount();
printf("Slept %u ticks.\n", dwEnd - dwBeg);
return ret;
}
//////////////////////////////////////////////////////////////////////////////
//
PVOID AttachAndDetach(DWORD dwMilliseconds)
{
LONG error;
PVOID trampoline;
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)TrueSleepEx, LoudSleepEx);
error = DetourTransactionCommit();
printf("Attach: %d, Trampoline: %p\n", error, TrueSleepEx);
trampoline = TrueSleepEx;
printf("\n");
printf("Sleep(%u)\n", dwMilliseconds);
Sleep(dwMilliseconds);
printf("\n");
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)TrueSleepEx, LoudSleepEx);
error = DetourTransactionCommit();
return trampoline;
}
int main(int argc, char **argv)
{
(void)argc;
(void)argv;
// First, save the default system region.
PVOID pDefaultLower = DetourSetSystemRegionLowerBound(NULL);
PVOID pDefaultUpper = DetourSetSystemRegionUpperBound(NULL);
// Now attach the detour with the default system region.
DetourSetSystemRegionLowerBound(pDefaultLower);
DetourSetSystemRegionUpperBound(pDefaultUpper);
printf("%p..%p: ", pDefaultLower, pDefaultUpper);
PVOID pTramp1 = AttachAndDetach(10);
printf("%p..%p: ", pDefaultLower, pDefaultUpper);
PVOID pTramp2 = AttachAndDetach(10);
// Now attach the detour with a smaller system region.
PVOID pSmallerLower = (PVOID)( ((ULONG_PTR)pTramp1) & ~(ULONG_PTR)0x3fffffff );
PVOID pSmallerUpper = (PVOID)( ((ULONG_PTR)pTramp1 + 0x3fffffff) & ~(ULONG_PTR)0x3fffffff );
DetourSetSystemRegionLowerBound(pSmallerLower);
DetourSetSystemRegionUpperBound(pSmallerUpper);
printf("%p..%p: ", pSmallerLower, pSmallerUpper);
PVOID pTramp3 = AttachAndDetach(20);
printf("Sleep(30)\n");
Sleep(30);
printf("\n");
if (pTramp1 != pTramp2) {
printf("!!!!!! Trampoling allocation is not deterministic. %p != %p\n", pTramp1, pTramp2);
return 1;
}
else if (pTramp2 == pTramp3) {
printf("!!!!!! Trampoling allocation doesn't skip region. %p == %p\n", pTramp2, pTramp3);
return 2;
}
return 0;
}

62
samples/setdll/Makefile Normal file
View File

@@ -0,0 +1,62 @@
##############################################################################
##
## Makefile for Detours Test Programs.
##
## Microsoft Research Detours Package
##
## Copyright (c) Microsoft Corporation. All rights reserved.
##
!include ..\common.mak
LIBS=$(LIBS) kernel32.lib
all: dirs \
$(BIND)\setdll.exe \
!IF $(DETOURS_SOURCE_BROWSING)==1
$(OBJD)\setdll.bsc \
!ENDIF
option
##############################################################################
clean:
-del *~ 2>nul
-del $(BIND)\setdll.* 2>nul
-rmdir /q /s $(OBJD) 2>nul
realclean: clean
-rmdir /q /s $(OBJDS) 2>nul
##############################################################################
dirs:
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
$(OBJD)\setdll.obj : setdll.cpp
$(BIND)\setdll.exe : $(OBJD)\setdll.obj $(DEPS)
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\setdll.obj \
/link $(LINKFLAGS) $(LIBS) /subsystem:console
$(OBJD)\setdll.bsc : $(OBJD)\setdll.obj
bscmake /v /n /o $@ $(OBJD)\setdll.sbr
############################################### Install non-bit-size binaries.
option:
##############################################################################
test: all
@echo -------- Reseting test binaries to initial state. -----------------------
$(BIND)\setdll.exe -d:$(BIND)\slept$(DETOURS_BITS).dll $(BIND)\sleepold.exe
@echo -------- Should load slept$(DETOURS_BITS).dll statically -------------------------------
$(BIND)\sleepold.exe
@echo -------- Reseting test binaries to initial state. -----------------------
$(BIND)\setdll.exe -r $(BIND)\sleepold.exe
@echo -------- Should not load slept$(DETOURS_BITS).dll --------------------------------------
$(BIND)\sleepold.exe
################################################################# End of File.

332
samples/setdll/setdll.cpp Normal file
View File

@@ -0,0 +1,332 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detours Test Program (setdll.cpp of setdll.exe)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <shellapi.h>
#include <detours.h>
#pragma warning(push)
#if _MSC_VER > 1400
#pragma warning(disable:6102 6103) // /analyze warnings
#endif
#include <strsafe.h>
#pragma warning(pop)
////////////////////////////////////////////////////////////// Error Messages.
//
VOID AssertMessage(PCSTR szMsg, PCSTR szFile, DWORD nLine)
{
printf("ASSERT(%s) failed in %s, line %d.", szMsg, szFile, nLine);
}
#define ASSERT(x) \
do { if (!(x)) { AssertMessage(#x, __FILE__, __LINE__); DebugBreak(); }} while (0)
;
//////////////////////////////////////////////////////////////////////////////
//
static BOOLEAN s_fRemove = FALSE;
static CHAR s_szDllPath[MAX_PATH] = "";
//////////////////////////////////////////////////////////////////////////////
//
// This code verifies that the named DLL has been configured correctly
// to be imported into the target process. DLLs must export a function with
// ordinal #1 so that the import table touch-up magic works.
//
static BOOL CALLBACK ExportCallback(_In_opt_ PVOID pContext,
_In_ ULONG nOrdinal,
_In_opt_ LPCSTR pszName,
_In_opt_ PVOID pCode)
{
(void)pContext;
(void)pCode;
(void)pszName;
if (nOrdinal == 1) {
*((BOOL *)pContext) = TRUE;
}
return TRUE;
}
BOOL DoesDllExportOrdinal1(PCHAR pszDllPath)
{
HMODULE hDll = LoadLibraryExA(pszDllPath, NULL, DONT_RESOLVE_DLL_REFERENCES);
if (hDll == NULL) {
printf("setdll.exe: LoadLibraryEx(%s) failed with error %d.\n",
pszDllPath,
GetLastError());
return FALSE;
}
BOOL validFlag = FALSE;
DetourEnumerateExports(hDll, &validFlag, ExportCallback);
FreeLibrary(hDll);
return validFlag;
}
//////////////////////////////////////////////////////////////////////////////
//
static BOOL CALLBACK ListBywayCallback(_In_opt_ PVOID pContext,
_In_opt_ LPCSTR pszFile,
_Outptr_result_maybenull_ LPCSTR *ppszOutFile)
{
(void)pContext;
*ppszOutFile = pszFile;
if (pszFile) {
printf(" %s\n", pszFile);
}
return TRUE;
}
static BOOL CALLBACK ListFileCallback(_In_opt_ PVOID pContext,
_In_ LPCSTR pszOrigFile,
_In_ LPCSTR pszFile,
_Outptr_result_maybenull_ LPCSTR *ppszOutFile)
{
(void)pContext;
*ppszOutFile = pszFile;
printf(" %s -> %s\n", pszOrigFile, pszFile);
return TRUE;
}
static BOOL CALLBACK AddBywayCallback(_In_opt_ PVOID pContext,
_In_opt_ LPCSTR pszFile,
_Outptr_result_maybenull_ LPCSTR *ppszOutFile)
{
PBOOL pbAddedDll = (PBOOL)pContext;
if (!pszFile && !*pbAddedDll) { // Add new byway.
*pbAddedDll = TRUE;
*ppszOutFile = s_szDllPath;
}
return TRUE;
}
BOOL SetFile(PCHAR pszPath)
{
BOOL bGood = TRUE;
HANDLE hOld = INVALID_HANDLE_VALUE;
HANDLE hNew = INVALID_HANDLE_VALUE;
PDETOUR_BINARY pBinary = NULL;
CHAR szOrg[MAX_PATH];
CHAR szNew[MAX_PATH];
CHAR szOld[MAX_PATH];
szOld[0] = '\0';
szNew[0] = '\0';
StringCchCopyA(szOrg, sizeof(szOrg), pszPath);
StringCchCopyA(szNew, sizeof(szNew), szOrg);
StringCchCatA(szNew, sizeof(szNew), "#");
StringCchCopyA(szOld, sizeof(szOld), szOrg);
StringCchCatA(szOld, sizeof(szOld), "~");
printf(" %s:\n", pszPath);
hOld = CreateFileA(szOrg,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hOld == INVALID_HANDLE_VALUE) {
printf("Couldn't open input file: %s, error: %d\n",
szOrg, GetLastError());
bGood = FALSE;
goto end;
}
hNew = CreateFileA(szNew,
GENERIC_WRITE | GENERIC_READ, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if (hNew == INVALID_HANDLE_VALUE) {
printf("Couldn't open output file: %s, error: %d\n",
szNew, GetLastError());
bGood = FALSE;
goto end;
}
if ((pBinary = DetourBinaryOpen(hOld)) == NULL) {
printf("DetourBinaryOpen failed: %d\n", GetLastError());
goto end;
}
if (hOld != INVALID_HANDLE_VALUE) {
CloseHandle(hOld);
hOld = INVALID_HANDLE_VALUE;
}
{
BOOL bAddedDll = FALSE;
DetourBinaryResetImports(pBinary);
if (!s_fRemove) {
if (!DetourBinaryEditImports(pBinary,
&bAddedDll,
AddBywayCallback, NULL, NULL, NULL)) {
printf("DetourBinaryEditImports failed: %d\n", GetLastError());
}
}
if (!DetourBinaryEditImports(pBinary, NULL,
ListBywayCallback, ListFileCallback,
NULL, NULL)) {
printf("DetourBinaryEditImports failed: %d\n", GetLastError());
}
if (!DetourBinaryWrite(pBinary, hNew)) {
printf("DetourBinaryWrite failed: %d\n", GetLastError());
bGood = FALSE;
}
DetourBinaryClose(pBinary);
pBinary = NULL;
if (hNew != INVALID_HANDLE_VALUE) {
CloseHandle(hNew);
hNew = INVALID_HANDLE_VALUE;
}
if (bGood) {
if (!DeleteFileA(szOld)) {
DWORD dwError = GetLastError();
if (dwError != ERROR_FILE_NOT_FOUND) {
printf("Warning: Couldn't delete %s: %d\n", szOld, dwError);
bGood = FALSE;
}
}
if (!MoveFileA(szOrg, szOld)) {
printf("Error: Couldn't back up %s to %s: %d\n",
szOrg, szOld, GetLastError());
bGood = FALSE;
}
if (!MoveFileA(szNew, szOrg)) {
printf("Error: Couldn't install %s as %s: %d\n",
szNew, szOrg, GetLastError());
bGood = FALSE;
}
}
DeleteFileA(szNew);
}
end:
if (pBinary) {
DetourBinaryClose(pBinary);
pBinary = NULL;
}
if (hNew != INVALID_HANDLE_VALUE) {
CloseHandle(hNew);
hNew = INVALID_HANDLE_VALUE;
}
if (hOld != INVALID_HANDLE_VALUE) {
CloseHandle(hOld);
hOld = INVALID_HANDLE_VALUE;
}
return bGood;
}
//////////////////////////////////////////////////////////////////////////////
//
void PrintUsage(void)
{
printf("Usage:\n"
" setdll [options] binary_files\n"
"Options:\n"
" /d:file.dll : Add file.dll binary files\n"
" /r : Remove extra DLLs from binary files\n"
" /? : This help screen.\n");
}
//////////////////////////////////////////////////////////////////////// main.
//
int CDECL main(int argc, char **argv)
{
BOOL fNeedHelp = FALSE;
PCHAR pszFilePart = NULL;
int arg = 1;
for (; arg < argc; arg++) {
if (argv[arg][0] == '-' || argv[arg][0] == '/') {
CHAR *argn = argv[arg] + 1;
CHAR *argp = argn;
while (*argp && *argp != ':' && *argp != '=')
argp++;
if (*argp == ':' || *argp == '=')
*argp++ = '\0';
switch (argn[0]) {
case 'd': // Set DLL
case 'D':
if ((strchr(argp, ':') != NULL || strchr(argp, '\\') != NULL) &&
GetFullPathNameA(argp, sizeof(s_szDllPath), s_szDllPath, &pszFilePart)) {
}
else {
StringCchPrintfA(s_szDllPath, sizeof(s_szDllPath), "%s", argp);
}
break;
case 'r': // Remove extra set DLLs.
case 'R':
s_fRemove = TRUE;
break;
case '?': // Help
fNeedHelp = TRUE;
break;
default:
fNeedHelp = TRUE;
printf("Bad argument: %s:%s\n", argn, argp);
break;
}
}
}
if (argc == 1) {
fNeedHelp = TRUE;
}
if (!s_fRemove && s_szDllPath[0] == 0) {
fNeedHelp = TRUE;
}
if (fNeedHelp) {
PrintUsage();
return 1;
}
if (s_fRemove) {
printf("Removing extra DLLs from binary files.\n");
}
else {
if (!DoesDllExportOrdinal1(s_szDllPath)) {
printf("Error: %hs does not export function with ordinal #1.\n",
s_szDllPath);
return 2;
}
printf("Adding %hs to binary files.\n", s_szDllPath);
}
for (arg = 1; arg < argc; arg++) {
if (argv[arg][0] != '-' && argv[arg][0] != '/') {
SetFile(argv[arg]);
}
}
return 0;
}
// End of File

120
samples/simple/Makefile Normal file
View File

@@ -0,0 +1,120 @@
##############################################################################
##
## API Extention to Measure time slept.
##
## Microsoft Research Detours Package
##
## Copyright (c) Microsoft Corporation. All rights reserved.
##
!include ..\common.mak
LIBS=$(LIBS) kernel32.lib
##############################################################################
all: dirs \
$(BIND)\simple$(DETOURS_BITS).dll \
$(BIND)\sleep5.exe \
\
!IF $(DETOURS_SOURCE_BROWSING)==1
$(OBJD)\simple$(DETOURS_BITS).bsc \
$(OBJD)\sleep5.bsc \
!ENDIF
option
##############################################################################
dirs:
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
$(OBJD)\simple.obj : simple.cpp
$(OBJD)\simple.res : simple.rc
$(BIND)\simple$(DETOURS_BITS).dll $(BIND)\simple$(DETOURS_BITS).lib: \
$(OBJD)\simple.obj $(OBJD)\simple.res $(DEPS)
cl /LD $(CFLAGS) /Fe$(@R).dll /Fd$(@R).pdb \
$(OBJD)\simple.obj $(OBJD)\simple.res \
/link $(LINKFLAGS) /subsystem:console \
/export:DetourFinishHelperProcess,@1,NONAME \
/export:TimedSleepEx \
$(LIBS)
$(OBJD)\simple$(DETOURS_BITS).bsc : $(OBJD)\simple.obj
bscmake /v /n /o $@ $(OBJD)\simple.sbr
$(OBJD)\sleep5.obj : sleep5.cpp
$(BIND)\sleep5.exe : $(OBJD)\sleep5.obj $(DEPS)
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\sleep5.obj \
/link $(LINKFLAGS) $(LIBS) \
/subsystem:console
$(OBJD)\sleep5.bsc : $(OBJD)\sleep5.obj
bscmake /v /n /o $@ $(OBJD)\sleep5.sbr
##############################################################################
clean:
-del *~ 2>nul
-del $(BIND)\simple*.* 2>nul
-del $(BIND)\sleep5.* 2>nul
-rmdir /q /s $(OBJD) 2>nul
realclean: clean
-rmdir /q /s $(OBJDS) 2>nul
############################################### Install non-bit-size binaries.
!IF "$(DETOURS_OPTION_PROCESSOR)" != ""
$(OPTD)\simple$(DETOURS_OPTION_BITS).dll:
$(OPTD)\simple$(DETOURS_OPTION_BITS).pdb:
$(BIND)\simple$(DETOURS_OPTION_BITS).dll : $(OPTD)\simple$(DETOURS_OPTION_BITS).dll
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
$(BIND)\simple$(DETOURS_OPTION_BITS).pdb : $(OPTD)\simple$(DETOURS_OPTION_BITS).pdb
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
option: \
$(BIND)\simple$(DETOURS_OPTION_BITS).dll \
$(BIND)\simple$(DETOURS_OPTION_BITS).pdb \
!ELSE
option:
!ENDIF
##############################################################################
test: all
@echo -------- Reseting test binaries to initial state. ---------------------
$(BIND)\setdll.exe -r $(BIND)\sleep5.exe
@echo.
@echo -------- Should not load simple$(DETOURS_BITS).dll -----------------------------------
$(BIND)\sleep5.exe
@echo.
@echo -------- Adding simple$(DETOURS_BITS).dll to sleep5.exe ------------------------------
$(BIND)\setdll.exe -d:$(BIND)\simple$(DETOURS_BITS).dll $(BIND)\sleep5.exe
@echo.
@echo -------- Should load simple$(DETOURS_BITS).dll statically ----------------------------
$(BIND)\sleep5.exe
@echo.
@echo -------- Removing simple$(DETOURS_BITS).dll from sleep5.exe --------------------------
$(BIND)\setdll.exe -r $(BIND)\sleep5.exe
@echo.
@echo -------- Should not load simple$(DETOURS_BITS).dll -----------------------------------
$(BIND)\sleep5.exe
@echo.
@echo -------- Should load simple$(DETOURS_BITS).dll dynamically using withdll.exe----------
$(BIND)\withdll.exe -d:$(BIND)\simple$(DETOURS_BITS).dll $(BIND)\sleep5.exe
@echo.
debug: all
windbg -o $(BIND)\withdll.exe -d:$(BIND)\simple$(DETOURS_BITS).dll $(BIND)\sleep5.exe
################################################################# End of File.

76
samples/simple/simple.cpp Normal file
View File

@@ -0,0 +1,76 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detours Test Program (simple.cpp of simple.dll)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// This DLL will detour the Windows SleepEx API so that TimedSleep function
// gets called instead. TimedSleepEx records the before and after times, and
// calls the real SleepEx API through the TrueSleepEx function pointer.
//
#include <stdio.h>
#include <windows.h>
#include "detours.h"
static LONG dwSlept = 0;
static DWORD (WINAPI * TrueSleepEx)(DWORD dwMilliseconds, BOOL bAlertable) = SleepEx;
DWORD WINAPI TimedSleepEx(DWORD dwMilliseconds, BOOL bAlertable)
{
DWORD dwBeg = GetTickCount();
DWORD ret = TrueSleepEx(dwMilliseconds, bAlertable);
DWORD dwEnd = GetTickCount();
InterlockedExchangeAdd(&dwSlept, dwEnd - dwBeg);
return ret;
}
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
{
LONG error;
(void)hinst;
(void)reserved;
if (DetourIsHelperProcess()) {
return TRUE;
}
if (dwReason == DLL_PROCESS_ATTACH) {
DetourRestoreAfterWith();
printf("simple" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
" Starting.\n");
fflush(stdout);
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)TrueSleepEx, TimedSleepEx);
error = DetourTransactionCommit();
if (error == NO_ERROR) {
printf("simple" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
" Detoured SleepEx().\n");
}
else {
printf("simple" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
" Error detouring SleepEx(): %d\n", error);
}
}
else if (dwReason == DLL_PROCESS_DETACH) {
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)TrueSleepEx, TimedSleepEx);
error = DetourTransactionCommit();
printf("simple" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
" Removed SleepEx() (result=%d), slept %d ticks.\n", error, dwSlept);
fflush(stdout);
}
return TRUE;
}
//
///////////////////////////////////////////////////////////////// End of File.

17
samples/simple/simple.rc Normal file
View File

@@ -0,0 +1,17 @@
//////////////////////////////////////////////////////////////////////////////
//
// Version information for simple.rc.
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#include "detver.h"
#define VER_INTERNALNAME_STR "simple" DETOURS_STRINGIFY(DETOURS_BITS)
#define VER_ORIGINALFILENAME_STR "simple" DETOURS_STRINGIFY(DETOURS_BITS) ".dll"
#define VER_FILEDESCRIPTION_STR "Detours Test Module"
#define VER_COMPANYNAME_STR "Microsoft Corporation"
#include "common.ver"

29
samples/simple/sleep5.cpp Normal file
View File

@@ -0,0 +1,29 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detours Test Program (sleep5.cpp of sleep5.exe)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
int __cdecl main(int argc, char ** argv)
{
if (argc == 2) {
Sleep(atoi(argv[1]) * 1000);
}
else {
printf("sleep5.exe: Starting.\n");
Sleep(5000);
printf("sleep5.exe: Done sleeping.\n");
}
return 0;
}
//
///////////////////////////////////////////////////////////////// End of File.

194
samples/slept/Makefile Normal file
View File

@@ -0,0 +1,194 @@
##############################################################################
##
## API Extension to Measure time slept.
##
## Microsoft Research Detours Package
##
## Copyright (c) Microsoft Corporation. All rights reserved.
##
!include ..\common.mak
CFLAGS = $(CFLAGS:/Od=/O2)
LIBS=$(LIBS) kernel32.lib
##############################################################################
all: dirs \
$(BIND)\slept$(DETOURS_BITS).dll \
$(BIND)\dslept$(DETOURS_BITS).dll \
$(BIND)\sleepold.exe \
$(BIND)\sleepnew.exe \
$(BIND)\sleepbed.exe \
\
!IF $(DETOURS_SOURCE_BROWSING)==1
$(OBJD)\slept$(DETOURS_BITS).bsc \
$(OBJD)\dslept$(DETOURS_BITS).bsc \
$(OBJD)\sleepold.bsc \
$(OBJD)\sleepnew.bsc \
$(OBJD)\sleepbed.bsc \
!ENDIF
option
##############################################################################
dirs:
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
$(OBJD)\slept.obj : slept.cpp verify.cpp
$(OBJD)\slept.res : slept.rc
$(BIND)\slept$(DETOURS_BITS).dll $(BIND)\slept$(DETOURS_BITS).lib: \
$(OBJD)\slept.obj $(OBJD)\slept.res $(DEPS)
cl /LD $(CFLAGS) /Fe$(@R).dll /Fd$(@R).pdb \
$(OBJD)\slept.obj $(OBJD)\slept.res\
/link $(LINKFLAGS) /subsystem:console \
/export:DetourFinishHelperProcess,@1,NONAME \
/export:TimedSleepEx \
/export:UntimedSleepEx \
/export:GetSleptTicks \
/export:TestTicks \
/export:TestTicksEx \
$(LIBS)
$(OBJD)\slept$(DETOURS_BITS).bsc : $(OBJD)\slept.obj
bscmake /v /n /o $@ $(OBJD)\slept.sbr
$(OBJD)\dslept.obj : dslept.cpp verify.cpp
$(OBJD)\dslept.res : dslept.rc
$(BIND)\dslept$(DETOURS_BITS).dll $(BIND)\dslept$(DETOURS_BITS).lib: \
$(OBJD)\dslept.obj $(OBJD)\dslept.res $(DEPS)
cl /LD $(CFLAGS) /Fe$(@R).dll /Fd$(@R).pdb \
$(OBJD)\dslept.obj $(OBJD)\dslept.res \
/link $(LINKFLAGS) /subsystem:console \
/export:DetourFinishHelperProcess,@1,NONAME \
/export:TimedSleepEx \
/export:UntimedSleepEx \
/export:GetSleptTicks \
$(LIBS)
$(OBJD)\dslept$(DETOURS_BITS).bsc : $(OBJD)\dslept.obj
bscmake /v /n /o $@ $(OBJD)\dslept.sbr
$(OBJD)\sleepold.obj : sleepold.cpp verify.cpp
$(BIND)\sleepold.exe : $(OBJD)\sleepold.obj $(DEPS)
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\sleepold.obj \
/link $(LINKFLAGS) $(LIBS) \
/subsystem:console /fixed:no
$(OBJD)\sleepold.bsc : $(OBJD)\sleepold.obj
bscmake /v /n /o $@ $(OBJD)\sleepold.sbr
$(OBJD)\sleepnew.obj : sleepnew.cpp verify.cpp
$(BIND)\sleepnew.exe : $(OBJD)\sleepnew.obj $(BIND)\slept$(DETOURS_BITS).lib $(DEPS)
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\sleepnew.obj \
/link $(LINKFLAGS) $(LIBS) \
/subsystem:console /fixed:no $(BIND)\slept$(DETOURS_BITS).lib
$(OBJD)\sleepnew.bsc : $(OBJD)\sleepnew.obj
bscmake /v /n /o $@ $(OBJD)\sleepnew.sbr
$(OBJD)\sleepbed.obj : sleepbed.cpp verify.cpp
$(BIND)\sleepbed.exe : $(OBJD)\sleepbed.obj $(DEPS)
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\sleepbed.obj \
/link $(LINKFLAGS) $(LIBS) \
/subsystem:console /fixed:no
$(OBJD)\sleepbed.bsc : $(OBJD)\sleepbed.obj
bscmake /v /n /o $@ $(OBJD)\sleepbed.sbr
##############################################################################
clean:
-del *~ 2>nul
-del $(BIND)\slept*.* 2>nul
-del $(BIND)\dslept*.* 2>nul
-del $(BIND)\sleepold.* 2>nul
-del $(BIND)\sleepnew.* 2>nul
-del $(BIND)\sleepbed.* 2>nul
-rmdir /q /s $(OBJD) 2>nul
realclean: clean
-rmdir /q /s $(OBJDS) 2>nul
############################################### Install non-bit-size binaries.
!IF "$(DETOURS_OPTION_PROCESSOR)" != ""
$(OPTD)\slept$(DETOURS_OPTION_BITS).dll:
$(OPTD)\slept$(DETOURS_OPTION_BITS).pdb:
$(OPTD)\dslept$(DETOURS_OPTION_BITS).dll:
$(OPTD)\dslept$(DETOURS_OPTION_BITS).pdb:
$(BIND)\slept$(DETOURS_OPTION_BITS).dll: $(OPTD)\slept$(DETOURS_OPTION_BITS).dll
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
$(BIND)\slept$(DETOURS_OPTION_BITS).pdb: $(OPTD)\slept$(DETOURS_OPTION_BITS).pdb
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
$(BIND)\dslept$(DETOURS_OPTION_BITS).dll: $(OPTD)\dslept$(DETOURS_OPTION_BITS).dll
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
$(BIND)\dslept$(DETOURS_OPTION_BITS).pdb: $(OPTD)\dslept$(DETOURS_OPTION_BITS).pdb
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
option: \
$(BIND)\slept$(DETOURS_OPTION_BITS).dll \
$(BIND)\slept$(DETOURS_OPTION_BITS).pdb \
$(BIND)\dslept$(DETOURS_OPTION_BITS).dll \
$(BIND)\dslept$(DETOURS_OPTION_BITS).pdb \
!ELSE
option:
!ENDIF
##############################################################################
skype: all
start windbg -G -o $(BIND)\withdll.exe -d:$(BIND)\slept$(DETOURS_BITS).dll "C:\Program Files (x86)\Skype\Phone\Skype.exe"
test: all
@echo -------- Reseting test binaries to initial state. -----------------------
$(BIND)\setdll.exe -r $(BIND)\sleepold.exe
@echo.
@echo -------- Should load detour self ----------------------------------------
$(BIND)\sleepbed.exe
@echo.
@echo -------- Should load slept$(DETOURS_BITS).dll statically -------------------------------
$(BIND)\sleepnew.exe
@echo.
@echo -------- Should not load slept$(DETOURS_BITS).dll --------------------------------------
$(BIND)\sleepold.exe
@echo.
@echo -------- Adding slept$(DETOURS_BITS).dll to sleepold.exe -------------------------------
$(BIND)\setdll.exe -d:$(BIND)\slept$(DETOURS_BITS).dll $(BIND)\sleepold.exe
@echo.
@echo -------- Should load slept$(DETOURS_BITS).dll statically -------------------------------
$(BIND)\sleepold.exe
@echo.
@echo -------- Replacing slept$(DETOURS_BITS).dll with dslept$(DETOURS_BITS).dll in sleepold.exe ------------
$(BIND)\setdll.exe -r $(BIND)\sleepold.exe
$(BIND)\setdll.exe -d:$(BIND)\dslept$(DETOURS_BITS).dll $(BIND)\sleepold.exe
@echo.
@echo -------- Should load dslept$(DETOURS_BITS).dll instead of slept$(DETOURS_BITS).dll --------------------
$(BIND)\sleepold.exe
@echo.
@echo -------- Removing dslept$(DETOURS_BITS).dll from sleepold.exe --------------------------
$(BIND)\setdll.exe -r $(BIND)\sleepold.exe
@echo.
@echo -------- Should not load dslept$(DETOURS_BITS).dll or slept$(DETOURS_BITS).dll ------------------------
$(BIND)\sleepold.exe
@echo.
@echo -------- Should load slept$(DETOURS_BITS).dll dynamically using withdll.exe ------------
$(BIND)\withdll.exe -d:$(BIND)\slept$(DETOURS_BITS).dll $(BIND)\sleepold.exe
@echo.
@echo -------- Test completed. ------------------------------------------------
################################################################# End of File.

View File

@@ -0,0 +1,202 @@
-------- Reseting test binaries to initial state. -----------------------
..\..\bin.IA64\setdll.exe -r ..\..\bin.IA64\sleepold.exe
Removing extra DLLs from binary files.
..\..\bin.IA64\sleepold.exe:
KERNEL32.dll -> KERNEL32.dll
-------- Should load detour self ----------------------------------------
..\..\bin.IA64\sleepbed.exe
sleepbed.exe: Starting.
sleepbed.exe: ExeEntry=000000013F702DD0, DllEntry=0000000000000000
SleepEx = 0000000077898980 [0000000077845300]
0000000077898980: 08181d0a 80054002 04004240 0400c400
0000000077898990: 11300142 00215002 80004200 00000020
00000000778989A0: 13000000 01000000 00001000 80a50050
sleepbed.exe: Detoured SleepEx().
sleepbed.exe: After detour.
SleepEx = 0000000077898980 [0000000077845300]
0000000077898980: 05000000 0100bfff ffff7f00 b879ffc8 [0000000037890330]
0000000077898990: 11300142 00215002 80004200 00000020
00000000778989A0: 13000000 01000000 00001000 80a50050
sleepbed.exe: Calling Sleep for 1 second.
sleepbed.exe: Calling SleepEx for 1 second.
sleepbed.exe: Calling Sleep again for 1 second.
sleepbed.exe: Calling TimedSleepEx for 1 second.
sleepbed.exe: Calling UntimedSleepEx for 1 second.
sleepbed.exe: Done sleeping.
sleepbed.exe: Removed SleepEx() detour (0), slept 2000 ticks.
sleepbed.exe: GetSleptTicks() = 2000
-------- Should load slept64.dll statically -------------------------------
..\..\bin.IA64\sleepnew.exe
slept64.dll: Starting.
slept64.dll: ExeEntry=000000013F18CA50, DllEntry=000006FAEE9F6D80
SleepEx = 0000000077898980 [0000000077845300]
0000000077898980: 08181d0a 80054002 04004240 0400c400
0000000077898990: 11300142 00215002 80004200 00000020
00000000778989A0: 13000000 01000000 00001000 80a50050
sleepnew.exe: Starting.
SleepEx = 0000000077898980 [0000000077845300]
0000000077898980: 05000000 0100bfff ffff7f00 b879ffc8 [0000000037890330]
0000000077898990: 11300142 00215002 80004200 00000020
00000000778989A0: 13000000 01000000 00001000 80a50050
sleepnew.exe: Calling Sleep for 1 second.
sleepnew.exe: Calling SleepEx for 1 second.
sleepnew.exe: Calling Sleep again for 1 second.
sleepnew.exe: Calling TimedSleep for 1 second.
sleepnew.exe: Calling UntimedSleep for 1 second.
sleepnew.exe: Done sleeping.
sleepnew.exe: GetSleptTicks() = 2000
slept64.dll: Detoured SleepEx().
slept64.dll: Removed SleepEx() detour (0), slept 2000 ticks.
-------- Should not load slept64.dll --------------------------------------
..\..\bin.IA64\sleepold.exe
sleepold.exe: Starting (at 000000013F80C288).
SleepEx = 0000000077898980 [0000000077845300]
0000000077898980: 08181d0a 80054002 04004240 0400c400
0000000077898990: 11300142 00215002 80004200 00000020
00000000778989A0: 13000000 01000000 00001000 80a50050
sleepold.exe: Calling Sleep for 1 second.
sleepold.exe: Calling SleepEx for 1 second.
sleepold.exe: Calling Sleep again for 1 second.
sleepold.exe: Done sleeping.
-------- Adding slept64.dll to sleepold.exe -------------------------------
..\..\bin.IA64\setdll.exe -d:..\..\bin.IA64\slept64.dll ..\..\bin.IA64\sleepold.exe
Adding c:\Code\Detours\bin.IA64\slept64.dll to binary files.
..\..\bin.IA64\sleepold.exe:
c:\Code\Detours\bin.IA64\slept64.dll
KERNEL32.dll -> KERNEL32.dll
-------- Should load slept64.dll statically -------------------------------
..\..\bin.IA64\sleepold.exe
slept64.dll: Starting.
slept64.dll: ExeEntry=000000013F4FCAB0, DllEntry=000006FAEE9F6D80
SleepEx = 0000000077898980 [0000000077845300]
0000000077898980: 08181d0a 80054002 04004240 0400c400
0000000077898990: 11300142 00215002 80004200 00000020
00000000778989A0: 13000000 01000000 00001000 80a50050
sleepold.exe: Starting (at 000000013F4FC288).
SleepEx = 0000000077898980 [0000000077845300]
0000000077898980: 05000000 0100bfff ffff7f00 b879ffc8 [0000000037890330]
0000000077898990: 11300142 00215002 80004200 00000020
00000000778989A0: 13000000 01000000 00001000 80a50050
sleepold.exe: Calling Sleep for 1 second.
sleepold.exe: Calling SleepEx for 1 second.
sleepold.exe: Calling Sleep again for 1 second.
sleepold.exe: Done sleeping.
slept64.dll: Detoured SleepEx().
slept64.dll: Removed SleepEx() detour (0), slept 1000 ticks.
-------- Replacing slept64.dll with dslept64.dll in sleepold.exe ------------
..\..\bin.IA64\setdll.exe -r ..\..\bin.IA64\sleepold.exe
Removing extra DLLs from binary files.
..\..\bin.IA64\sleepold.exe:
KERNEL32.dll -> KERNEL32.dll
..\..\bin.IA64\setdll.exe -d:..\..\bin.IA64\dslept64.dll ..\..\bin.IA64\sleepold.exe
Adding c:\Code\Detours\bin.IA64\dslept64.dll to binary files.
..\..\bin.IA64\sleepold.exe:
c:\Code\Detours\bin.IA64\dslept64.dll
KERNEL32.dll -> KERNEL32.dll
-------- Should load dslept64.dll instead of slept64.dll --------------------
..\..\bin.IA64\sleepold.exe
dslept64.dll: Starting.
SleepEx = 0000000077898980 [0000000077845300]
0000000077898980: 08181d0a 80054002 04004240 0400c400
0000000077898990: 11300142 00215002 80004200 00000020
00000000778989A0: 13000000 01000000 00001000 80a50050
EntryPoint = 000000013F12D580 [000000013F16CAB0]
000000013F12D580: 01080d06 80050002 00620040 04080084
000000013F12D590: 13000000 01000000 00001000 90eb0050
000000013F12D5A0: 13080044 00210000 00001000 c0fcff58
EntryPoint after attach = 000000013F12D580 [000000013F16CAB0]
000000013F12D580: 05000000 0100bfff ffff7f00 b82dffc8 [00000000FF120330]
000000013F12D590: 13000000 01000000 00001000 90eb0050
000000013F12D5A0: 13080044 00210000 00001000 c0fcff58
EntryPoint trampoline = 00000000FF120300 [00000000FF1203B0]
00000000FF120300: 05000000 01003f01 00000020 00f00267
00000000FF120310: 01080d06 80050002 00620040 04080084
00000000FF120320: 05000000 01004000 00000000 78d200c0 [000000013F12D590]
dslept64.dll: Detoured EntryPoint().
dslept64.dll: Detoured SleepEx().
SleepEx = 0000000077898980 [0000000077845300]
0000000077898980: 05000000 0100bfff ffff7f00 b879ffc8 [0000000037890330]
0000000077898990: 11300142 00215002 80004200 00000020
00000000778989A0: 13000000 01000000 00001000 80a50050
dslept64.dll: Calling EntryPoint
sleepold.exe: Starting (at 000000013F16C288).
SleepEx = 0000000077898980 [0000000077845300]
0000000077898980: 05000000 0100bfff ffff7f00 b879ffc8 [0000000037890330]
0000000077898990: 11300142 00215002 80004200 00000020
00000000778989A0: 13000000 01000000 00001000 80a50050
sleepold.exe: Calling Sleep for 1 second.
sleepold.exe: Calling SleepEx for 1 second.
sleepold.exe: Calling Sleep again for 1 second.
sleepold.exe: Done sleeping.
dslept64.dll: Removed Sleep() detours (0), slept 1000 ticks.
-------- Removing dslept64.dll from sleepold.exe --------------------------
..\..\bin.IA64\setdll.exe -r ..\..\bin.IA64\sleepold.exe
Removing extra DLLs from binary files.
..\..\bin.IA64\sleepold.exe:
KERNEL32.dll -> KERNEL32.dll
-------- Should not load dslept64.dll or slept64.dll ------------------------
..\..\bin.IA64\sleepold.exe
sleepold.exe: Starting (at 000000013FCEC288).
SleepEx = 0000000077898980 [0000000077845300]
0000000077898980: 08181d0a 80054002 04004240 0400c400
0000000077898990: 11300142 00215002 80004200 00000020
00000000778989A0: 13000000 01000000 00001000 80a50050
sleepold.exe: Calling Sleep for 1 second.
sleepold.exe: Calling SleepEx for 1 second.
sleepold.exe: Calling Sleep again for 1 second.
sleepold.exe: Done sleeping.
-------- Should load slept64.dll dynamically using withdll.exe ------------
..\..\bin.IA64\withdll.exe -d:..\..\bin.IA64\slept64.dll ..\..\bin.IA64\sleepold.exe
withdll.exe: Starting: `..\..\bin.IA64\sleepold.exe'
withdll.exe: with `c:\Code\Detours\bin.IA64\slept64.dll'
slept64.dll: Starting.
slept64.dll: ExeEntry=000000013FBFCAB0, DllEntry=000006FAEE9F6D80
SleepEx = 0000000077898980 [0000000077845300]
0000000077898980: 08181d0a 80054002 04004240 0400c400
0000000077898990: 11300142 00215002 80004200 00000020
00000000778989A0: 13000000 01000000 00001000 80a50050
sleepold.exe: Starting (at 000000013FBFC288).
SleepEx = 0000000077898980 [0000000077845300]
0000000077898980: 05000000 0100bfff ffff7f00 b879ffc8 [0000000037890330]
0000000077898990: 11300142 00215002 80004200 00000020
00000000778989A0: 13000000 01000000 00001000 80a50050
sleepold.exe: Calling Sleep for 1 second.
sleepold.exe: Calling SleepEx for 1 second.
sleepold.exe: Calling Sleep again for 1 second.
sleepold.exe: Done sleeping.
slept64.dll: Detoured SleepEx().
slept64.dll: Removed SleepEx() detour (0), slept 1030 ticks.
-------- Test completed. ------------------------------------------------

View File

@@ -0,0 +1,202 @@
-------- Reseting test binaries to initial state. -----------------------
..\..\bin.X64\setdll.exe -r ..\..\bin.X64\sleepold.exe
Removing extra DLLs from binary files.
..\..\bin.X64\sleepold.exe:
KERNEL32.dll -> KERNEL32.dll
-------- Should load detour self ----------------------------------------
..\..\bin.X64\sleepbed.exe
sleepbed.exe: Starting.
sleepbed.exe: ExeEntry=000000013FE863E0, DllEntry=000000013FE9E610
SleepEx = 000007FEFD541150 [0000000076912B60]
000007FEFD541150: 4c8bdc
000007FEFD541153: 49895b08
000007FEFD541157: 89542410
sleepbed.exe: Detoured SleepEx().
sleepbed.exe: After detour.
SleepEx = 000007FEFD541150 [0000000076912B60]
000007FEFD541150: e923f0ff bf [000007FEBD540178]
000007FEFD541155: cc [FFFFFFFFFFFFFFFF]
000007FEFD541156: cc [FFFFFFFFFFFFFFFF]
sleepbed.exe: Calling Sleep for 1 second.
sleepbed.exe: Calling SleepEx for 1 second.
sleepbed.exe: Calling Sleep again for 1 second.
sleepbed.exe: Calling TimedSleepEx for 1 second.
sleepbed.exe: Calling UntimedSleepEx for 1 second.
sleepbed.exe: Done sleeping.
sleepbed.exe: Removed SleepEx() detour (0), slept 4056 ticks.
sleepbed.exe: GetSleptTicks() = 4056
-------- Should load slept64.dll statically -------------------------------
..\..\bin.X64\sleepnew.exe
slept64.dll: Starting.
slept64.dll: ExeEntry=000000013F56484C, DllEntry=000007FEF2E78B74
SleepEx = 000007FEFD541150 [0000000076912B60]
000007FEFD541150: 4c8bdc
000007FEFD541153: 49895b08
000007FEFD541157: 89542410
sleepnew.exe: Starting.
SleepEx = 000007FEFD541150 [0000000076912B60]
000007FEFD541150: e923f0ff bf [000007FEBD540178]
000007FEFD541155: cc [FFFFFFFFFFFFFFFF]
000007FEFD541156: cc [FFFFFFFFFFFFFFFF]
sleepnew.exe: Calling Sleep for 1 second.
sleepnew.exe: Calling SleepEx for 1 second.
sleepnew.exe: Calling Sleep again for 1 second.
sleepnew.exe: Calling TimedSleep for 1 second.
sleepnew.exe: Calling UntimedSleep for 1 second.
sleepnew.exe: Done sleeping.
sleepnew.exe: GetSleptTicks() = 4056
slept64.dll: Detoured SleepEx().
slept64.dll: Removed SleepEx() detour (0), slept 4056 ticks.
-------- Should not load slept64.dll --------------------------------------
..\..\bin.X64\sleepold.exe
sleepold.exe: Starting (at 000000013FEF1350).
SleepEx = 000007FEFD541150 [0000000076912B60]
000007FEFD541150: 4c8bdc
000007FEFD541153: 49895b08
000007FEFD541157: 89542410
sleepold.exe: Calling Sleep for 1 second.
sleepold.exe: Calling SleepEx for 1 second.
sleepold.exe: Calling Sleep again for 1 second.
sleepold.exe: Done sleeping.
-------- Adding slept64.dll to sleepold.exe -------------------------------
..\..\bin.X64\setdll.exe -d:..\..\bin.X64\slept64.dll ..\..\bin.X64\sleepold.exe
Adding c:\Code\detours\bin.X64\slept64.dll to binary files.
..\..\bin.X64\sleepold.exe:
c:\Code\detours\bin.X64\slept64.dll
KERNEL32.dll -> KERNEL32.dll
-------- Should load slept64.dll statically -------------------------------
..\..\bin.X64\sleepold.exe
slept64.dll: Starting.
slept64.dll: ExeEntry=000000013F554ADC, DllEntry=000007FEF2E78B74
SleepEx = 000007FEFD541150 [0000000076912B60]
000007FEFD541150: 4c8bdc
000007FEFD541153: 49895b08
000007FEFD541157: 89542410
sleepold.exe: Starting (at 000000013F551350).
SleepEx = 000007FEFD541150 [0000000076912B60]
000007FEFD541150: e923f0ff bf [000007FEBD540178]
000007FEFD541155: cc [FFFFFFFFFFFFFFFF]
000007FEFD541156: cc [FFFFFFFFFFFFFFFF]
sleepold.exe: Calling Sleep for 1 second.
sleepold.exe: Calling SleepEx for 1 second.
sleepold.exe: Calling Sleep again for 1 second.
sleepold.exe: Done sleeping.
slept64.dll: Detoured SleepEx().
slept64.dll: Removed SleepEx() detour (0), slept 3042 ticks.
-------- Replacing slept64.dll with dslept64.dll in sleepold.exe ------------
..\..\bin.X64\setdll.exe -r ..\..\bin.X64\sleepold.exe
Removing extra DLLs from binary files.
..\..\bin.X64\sleepold.exe:
KERNEL32.dll -> KERNEL32.dll
..\..\bin.X64\setdll.exe -d:..\..\bin.X64\dslept64.dll ..\..\bin.X64\sleepold.exe
Adding c:\Code\detours\bin.X64\dslept64.dll to binary files.
..\..\bin.X64\sleepold.exe:
c:\Code\detours\bin.X64\dslept64.dll
KERNEL32.dll -> KERNEL32.dll
-------- Should load dslept64.dll instead of slept64.dll --------------------
..\..\bin.X64\sleepold.exe
dslept64.dll: Starting.
SleepEx = 000007FEFD541150 [0000000076912B60]
000007FEFD541150: 4c8bdc
000007FEFD541153: 49895b08
000007FEFD541157: 89542410
EntryPoint = 000000013FB24ADC
000000013FB24ADC: 4883ec28
000000013FB24AE0: e8875f00 00 [000000013FB2AA6C]
000000013FB24AE5: 4883c428
EntryPoint after attach = 000000013FB24ADC
000000013FB24ADC: e997b6ff bf [00000000FFB20178]
000000013FB24AE1: cc [FFFFFFFFFFFFFFFF]
000000013FB24AE2: cc [FFFFFFFFFFFFFFFF]
EntryPoint trampoline = 00000000FFB20120
00000000FFB20120: 4883ec28
00000000FFB20124: e843a900 40 [000000013FB2AA6C]
00000000FFB20129: ff253900 0000
dslept64.dll: Detoured EntryPoint().
dslept64.dll: Detoured SleepEx().
SleepEx = 000007FEFD541150 [0000000076912B60]
000007FEFD541150: e923f0ff bf [000007FEBD540178]
000007FEFD541155: cc [FFFFFFFFFFFFFFFF]
000007FEFD541156: cc [FFFFFFFFFFFFFFFF]
dslept64.dll: Calling EntryPoint
sleepold.exe: Starting (at 000000013FB21350).
SleepEx = 000007FEFD541150 [0000000076912B60]
000007FEFD541150: e923f0ff bf [000007FEBD540178]
000007FEFD541155: cc [FFFFFFFFFFFFFFFF]
000007FEFD541156: cc [FFFFFFFFFFFFFFFF]
sleepold.exe: Calling Sleep for 1 second.
sleepold.exe: Calling SleepEx for 1 second.
sleepold.exe: Calling Sleep again for 1 second.
sleepold.exe: Done sleeping.
dslept64.dll: Removed Sleep() detours (0), slept 3042 ticks.
-------- Removing dslept64.dll from sleepold.exe --------------------------
..\..\bin.X64\setdll.exe -r ..\..\bin.X64\sleepold.exe
Removing extra DLLs from binary files.
..\..\bin.X64\sleepold.exe:
KERNEL32.dll -> KERNEL32.dll
-------- Should not load dslept64.dll or slept64.dll ------------------------
..\..\bin.X64\sleepold.exe
sleepold.exe: Starting (at 000000013F551350).
SleepEx = 000007FEFD541150 [0000000076912B60]
000007FEFD541150: 4c8bdc
000007FEFD541153: 49895b08
000007FEFD541157: 89542410
sleepold.exe: Calling Sleep for 1 second.
sleepold.exe: Calling SleepEx for 1 second.
sleepold.exe: Calling Sleep again for 1 second.
sleepold.exe: Done sleeping.
-------- Should load slept64.dll dynamically using withdll.exe ------------
..\..\bin.X64\withdll.exe -d:..\..\bin.X64\slept64.dll ..\..\bin.X64\sleepold.exe
withdll.exe: Starting: `..\..\bin.X64\sleepold.exe'
withdll.exe: with `c:\Code\detours\bin.X64\slept64.dll'
slept64.dll: Starting.
slept64.dll: ExeEntry=000000013FE84ADC, DllEntry=000007FEF3108B74
SleepEx = 000007FEFD541150 [0000000076912B60]
000007FEFD541150: 4c8bdc
000007FEFD541153: 49895b08
000007FEFD541157: 89542410
sleepold.exe: Starting (at 000000013FE81350).
SleepEx = 000007FEFD541150 [0000000076912B60]
000007FEFD541150: e923f0ff bf [000007FEBD540178]
000007FEFD541155: cc [FFFFFFFFFFFFFFFF]
000007FEFD541156: cc [FFFFFFFFFFFFFFFF]
sleepold.exe: Calling Sleep for 1 second.
sleepold.exe: Calling SleepEx for 1 second.
sleepold.exe: Calling Sleep again for 1 second.
sleepold.exe: Done sleeping.
slept64.dll: Detoured SleepEx().
slept64.dll: Removed SleepEx() detour (0), slept 3042 ticks.
-------- Test completed. ------------------------------------------------

View File

@@ -0,0 +1,202 @@
-------- Reseting test binaries to initial state. -----------------------
..\..\bin.X86\setdll.exe -r ..\..\bin.X86\sleepold.exe
Removing extra DLLs from binary files.
..\..\bin.X86\sleepold.exe:
KERNEL32.dll -> KERNEL32.dll
-------- Should load detour self ----------------------------------------
..\..\bin.X86\sleepbed.exe
sleepbed.exe: Starting.
sleepbed.exe: ExeEntry=00B1572E, DllEntry=00000000
SleepEx = 74F51215
74F51215: 8bff
74F51217: 55
74F51218: 8bec
sleepbed.exe: Detoured SleepEx().
sleepbed.exe: After detour.
SleepEx = 74F51215
74F51215: e95600bc 8b [00B11270]
74F5121A: 5d
74F5121B: ebed [74F5120A]
sleepbed.exe: Calling Sleep for 1 second.
sleepbed.exe: Calling SleepEx for 1 second.
sleepbed.exe: Calling Sleep again for 1 second.
sleepbed.exe: Calling TimedSleepEx for 1 second.
sleepbed.exe: Calling UntimedSleepEx for 1 second.
sleepbed.exe: Done sleeping.
sleepbed.exe: Removed SleepEx() detour (0), slept 2028 ticks.
sleepbed.exe: GetSleptTicks() = 2028
-------- Should load slept32.dll statically -------------------------------
..\..\bin.X86\sleepnew.exe
slept32.dll: Starting.
slept32.dll: ExeEntry=012D3B1A, DllEntry=7248702E
SleepEx = 74F51215
74F51215: 8bff
74F51217: 55
74F51218: 8bec
sleepnew.exe: Starting.
SleepEx = 74F51215
74F51215: e9560053 fd [72481270]
74F5121A: 5d
74F5121B: ebed [74F5120A]
sleepnew.exe: Calling Sleep for 1 second.
sleepnew.exe: Calling SleepEx for 1 second.
sleepnew.exe: Calling Sleep again for 1 second.
sleepnew.exe: Calling TimedSleep for 1 second.
sleepnew.exe: Calling UntimedSleep for 1 second.
sleepnew.exe: Done sleeping.
sleepnew.exe: GetSleptTicks() = 2028
slept32.dll: Detoured SleepEx().
slept32.dll: Removed SleepEx() detour (0), slept 2028 ticks.
-------- Should not load slept32.dll --------------------------------------
..\..\bin.X86\sleepold.exe
sleepold.exe: Starting (at 00971260).
SleepEx = 74F51215
74F51215: 8bff
74F51217: 55
74F51218: 8bec
sleepold.exe: Calling Sleep for 1 second.
sleepold.exe: Calling SleepEx for 1 second.
sleepold.exe: Calling Sleep again for 1 second.
sleepold.exe: Done sleeping.
-------- Adding slept32.dll to sleepold.exe -------------------------------
..\..\bin.X86\setdll.exe -d:..\..\bin.X86\slept32.dll ..\..\bin.X86\sleepold.exe
Adding c:\Code\detours\bin.X86\slept32.dll to binary files.
..\..\bin.X86\sleepold.exe:
c:\Code\detours\bin.X86\slept32.dll
KERNEL32.dll -> KERNEL32.dll
-------- Should load slept32.dll statically -------------------------------
..\..\bin.X86\sleepold.exe
slept32.dll: Starting.
slept32.dll: ExeEntry=00AF3D4C, DllEntry=7248702E
SleepEx = 74F51215
74F51215: 8bff
74F51217: 55
74F51218: 8bec
sleepold.exe: Starting (at 00AF1260).
SleepEx = 74F51215
74F51215: e9560053 fd [72481270]
74F5121A: 5d
74F5121B: ebed [74F5120A]
sleepold.exe: Calling Sleep for 1 second.
sleepold.exe: Calling SleepEx for 1 second.
sleepold.exe: Calling Sleep again for 1 second.
sleepold.exe: Done sleeping.
slept32.dll: Detoured SleepEx().
slept32.dll: Removed SleepEx() detour (0), slept 1014 ticks.
-------- Replacing slept32.dll with dslept32.dll in sleepold.exe ------------
..\..\bin.X86\setdll.exe -r ..\..\bin.X86\sleepold.exe
Removing extra DLLs from binary files.
..\..\bin.X86\sleepold.exe:
KERNEL32.dll -> KERNEL32.dll
..\..\bin.X86\setdll.exe -d:..\..\bin.X86\dslept32.dll ..\..\bin.X86\sleepold.exe
Adding c:\Code\detours\bin.X86\dslept32.dll to binary files.
..\..\bin.X86\sleepold.exe:
c:\Code\detours\bin.X86\dslept32.dll
KERNEL32.dll -> KERNEL32.dll
-------- Should load dslept32.dll instead of slept32.dll --------------------
..\..\bin.X86\sleepold.exe
dslept32.dll: Starting.
SleepEx = 74F51215
74F51215: 8bff
74F51217: 55
74F51218: 8bec
EntryPoint = 00263D4C
00263D4C: e8d75400 00 [00269228]
00263D51: e995feff ff [00263BEB]
00263D56: 3b0d8412 2800
EntryPoint after attach = 00263D4C
00263D4C: e96fd502 72 [722912C0]
00263D51: e995feff ff [00263BEB]
00263D56: 3b0d8412 2800
EntryPoint trampoline = 402500D8
402500D8: e84b9101 c0 [00269228]
402500DD: e96f3c01 c0 [00263D51]
402500E2: cc [FFFFFFFF]
dslept32.dll: Detoured EntryPoint().
dslept32.dll: Detoured SleepEx().
SleepEx = 74F51215
74F51215: e9560034 fd [72291270]
74F5121A: 5d
74F5121B: ebed [74F5120A]
dslept32.dll: Calling EntryPoint
sleepold.exe: Starting (at 00261260).
SleepEx = 74F51215
74F51215: e9560034 fd [72291270]
74F5121A: 5d
74F5121B: ebed [74F5120A]
sleepold.exe: Calling Sleep for 1 second.
sleepold.exe: Calling SleepEx for 1 second.
sleepold.exe: Calling Sleep again for 1 second.
sleepold.exe: Done sleeping.
dslept32.dll: Removed Sleep() detours (0), slept 1014 ticks.
-------- Removing dslept32.dll from sleepold.exe --------------------------
..\..\bin.X86\setdll.exe -r ..\..\bin.X86\sleepold.exe
Removing extra DLLs from binary files.
..\..\bin.X86\sleepold.exe:
KERNEL32.dll -> KERNEL32.dll
-------- Should not load dslept32.dll or slept32.dll ------------------------
..\..\bin.X86\sleepold.exe
sleepold.exe: Starting (at 00E01260).
SleepEx = 74F51215
74F51215: 8bff
74F51217: 55
74F51218: 8bec
sleepold.exe: Calling Sleep for 1 second.
sleepold.exe: Calling SleepEx for 1 second.
sleepold.exe: Calling Sleep again for 1 second.
sleepold.exe: Done sleeping.
-------- Should load slept32.dll dynamically using withdll.exe ------------
..\..\bin.X86\withdll.exe -d:..\..\bin.X86\slept32.dll ..\..\bin.X86\sleepold.exe
withdll.exe: Starting: `..\..\bin.X86\sleepold.exe'
withdll.exe: with `c:\Code\detours\bin.X86\slept32.dll'
slept32.dll: Starting.
slept32.dll: ExeEntry=011A3D4C, DllEntry=7248702E
SleepEx = 74F51215
74F51215: 8bff
74F51217: 55
74F51218: 8bec
sleepold.exe: Starting (at 011A1260).
SleepEx = 74F51215
74F51215: e9560053 fd [72481270]
74F5121A: 5d
74F5121B: ebed [74F5120A]
sleepold.exe: Calling Sleep for 1 second.
sleepold.exe: Calling SleepEx for 1 second.
sleepold.exe: Calling Sleep again for 1 second.
sleepold.exe: Done sleeping.
slept32.dll: Detoured SleepEx().
slept32.dll: Removed SleepEx() detour (0), slept 1014 ticks.
-------- Test completed. ------------------------------------------------

141
samples/slept/dslept.cpp Normal file
View File

@@ -0,0 +1,141 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detour Test Program (dslept.cpp of dslept.dll)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// An example dynamically detouring a function.
//
#include <stdio.h>
#include <windows.h>
#include "detours.h"
#include "slept.h"
#include "verify.cpp"
LONG dwSlept = 0;
static DWORD (WINAPI * TrueSleepEx)(DWORD dwMilliseconds, BOOL bAlertable) = NULL;
static int (WINAPI * TrueEntryPoint)(VOID) = NULL;
static int (WINAPI * RawEntryPoint)(VOID) = NULL;
DWORD WINAPI UntimedSleepEx(DWORD dwMilliseconds, BOOL bAlertable)
{
if (TrueSleepEx != NULL) {
return TrueSleepEx(dwMilliseconds, bAlertable);
}
return 0;
}
DWORD WINAPI TimedSleepEx(DWORD dwMilliseconds, BOOL bAlertable)
{
DWORD dwBeg = GetTickCount();
DWORD ret = TrueSleepEx(dwMilliseconds, bAlertable);
DWORD dwEnd = GetTickCount();
InterlockedExchangeAdd(&dwSlept, dwEnd - dwBeg);
return ret;
}
DWORD WINAPI GetSleptTicks(VOID)
{
return dwSlept;
}
int WINAPI TimedEntryPoint(VOID)
{
// We couldn't call LoadLibrary in DllMain,
// so we detour SleepEx here...
LONG error;
TrueSleepEx = (DWORD (WINAPI *)(DWORD, BOOL))
DetourFindFunction("kernel32.dll", "SleepEx");
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)TrueSleepEx, TimedSleepEx);
error = DetourTransactionCommit();
if (error == NO_ERROR) {
printf("dslept" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: "
" Detoured SleepEx().\n");
}
else {
printf("dslept" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: "
" Error detouring SleepEx(): %d\n", error);
}
Verify("SleepEx", (PVOID)SleepEx);
printf("\n");
fflush(stdout);
printf("dslept" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: "
" Calling EntryPoint\n");
fflush(stdout);
return TrueEntryPoint();
}
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
{
LONG error;
(void)hinst;
(void)reserved;
if (DetourIsHelperProcess()) {
return TRUE;
}
if (dwReason == DLL_PROCESS_ATTACH) {
DetourRestoreAfterWith();
printf("dslept" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: "
" Starting.\n");
Verify("SleepEx", (PVOID)SleepEx);
printf("\n");
fflush(stdout);
// NB: DllMain can't call LoadLibrary, so we hook the app entry point.
TrueEntryPoint = (int (WINAPI *)(VOID))DetourGetEntryPoint(NULL);
RawEntryPoint = TrueEntryPoint;
Verify("EntryPoint", RawEntryPoint);
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)TrueEntryPoint, TimedEntryPoint);
error = DetourTransactionCommit();
Verify("EntryPoint after attach", RawEntryPoint);
Verify("EntryPoint trampoline", TrueEntryPoint);
if (error == NO_ERROR) {
printf("dslept" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: "
" Detoured EntryPoint().\n");
}
else {
printf("dslept" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: "
" Error detouring EntryPoint(): %d\n", error);
}
}
else if (dwReason == DLL_PROCESS_DETACH) {
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
if (TrueSleepEx != NULL) {
DetourDetach(&(PVOID&)TrueSleepEx, (PVOID)TimedSleepEx);
}
DetourDetach(&(PVOID&)TrueEntryPoint, TimedEntryPoint);
error = DetourTransactionCommit();
printf("dslept" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: "
" Removed Sleep() detours (%d), slept %d ticks.\n", error, dwSlept);
fflush(stdout);
}
return TRUE;
}
//
///////////////////////////////////////////////////////////////// End of File.

17
samples/slept/dslept.rc Normal file
View File

@@ -0,0 +1,17 @@
//////////////////////////////////////////////////////////////////////////////
//
// Version information for dslept.rc.
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#include "detver.h"
#define VER_INTERNALNAME_STR "dslept" DETOURS_STRINGIFY(DETOURS_BITS)
#define VER_ORIGINALFILENAME_STR "dslept" DETOURS_STRINGIFY(DETOURS_BITS) ".dll"
#define VER_FILEDESCRIPTION_STR "Detours Sleep Interception Module"
#define VER_COMPANYNAME_STR "Microsoft Corporation"
#include "common.ver"

103
samples/slept/sleepbed.cpp Normal file
View File

@@ -0,0 +1,103 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detour Test Program (sleepbed.cpp of sleepbed.exe)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#include <windows.h>
#include <stdio.h>
#include "verify.cpp"
static BOOL fBroke = FALSE;
static LONG dwSlept = 0;
static DWORD (WINAPI * TrueSleepEx)(DWORD dwMilliseconds, BOOL bAlertable)
= SleepEx;
DWORD WINAPI UntimedSleepEx(DWORD dwMilliseconds, BOOL bAlertable)
{
return TrueSleepEx(dwMilliseconds, bAlertable);
}
DWORD WINAPI TimedSleepEx(DWORD dwMilliseconds, BOOL bAlertable)
{
DWORD dwBeg = GetTickCount();
DWORD ret = TrueSleepEx(dwMilliseconds, bAlertable);
DWORD dwEnd = GetTickCount();
if (!fBroke) {
fBroke = TRUE;
// DebugBreak();
}
InterlockedExchangeAdd(&dwSlept, dwEnd - dwBeg);
return ret;
}
DWORD WINAPI GetSleptTicks(VOID)
{
return dwSlept;
}
//
///////////////////////////////////////////////////////////////// End of File.
int __cdecl main(void)
{
int error = 0;
printf("sleepbed.exe: Starting.\n");
PVOID pbExeEntry = DetourGetEntryPoint(NULL);
printf("sleepbed.exe: ExeEntry=%p\n", pbExeEntry);
Verify("SleepEx", (PVOID)SleepEx);
printf("\n");
fflush(stdout);
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)TrueSleepEx, TimedSleepEx);
error = DetourTransactionCommit();
if (error == NO_ERROR) {
printf("sleepbed.exe: Detoured SleepEx().\n");
}
else {
printf("sleepbed.exe: Error detouring SleepEx(): %d\n", error);
return error;
}
fflush(stdout);
printf("sleepbed.exe: After detour.\n");
Verify("SleepEx", (PBYTE)SleepEx);
printf("\n");
fflush(stdout);
printf("sleepbed.exe: Calling Sleep for 1 second.\n");
Sleep(1000);
printf("sleepbed.exe: Calling SleepEx for 1 second.\n");
SleepEx(1000, true);
printf("sleepbed.exe: Calling Sleep again for 1 second.\n");
Sleep(1000);
printf("sleepbed.exe: Calling TimedSleepEx for 1 second.\n");
TimedSleepEx(1000, false);
printf("sleepbed.exe: Calling UntimedSleepEx for 1 second.\n");
UntimedSleepEx(1000, false);
printf("sleepbed.exe: Done sleeping.\n\n");
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)TrueSleepEx, TimedSleepEx);
error = DetourTransactionCommit();
printf("sleepbed.exe: Removed SleepEx() detour (%d), slept %d ticks.\n",
error, dwSlept);
fflush(stdout);
printf("sleepbed.exe: GetSleptTicks() = %d\n\n", GetSleptTicks());
return error;
}
//
///////////////////////////////////////////////////////////////// End of File.

View File

@@ -0,0 +1,76 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detour Test Program (sleepnew.cpp of sleepnew.exe)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#include <windows.h>
#include <stdio.h>
#include "slept.h"
#include "verify.cpp"
int __cdecl main(void)
{
printf("sleepnew.exe: Starting.\n");
Verify("SleepEx", (PBYTE)SleepEx);
printf("\n");
fflush(stdout);
printf("sleepnew.exe: Calling Sleep for 1 second.\n");
Sleep(1000);
printf("sleepnew.exe: Calling SleepEx for 1 second.\n");
SleepEx(1000, true);
printf("sleepnew.exe: Calling Sleep again for 1 second.\n");
Sleep(1000);
printf("sleepnew.exe: Calling TimedSleep for 1 second.\n");
TimedSleepEx(1000, FALSE);
printf("sleepnew.exe: Calling UntimedSleep for 1 second.\n");
UntimedSleepEx(1000, FALSE);
printf("sleepnew.exe: Done sleeping.\n\n");
#if 0
// This code enumerates the virtual address space and attempts to reserve
// all unused space below 8GB.
//
for (PBYTE pbTry = (PBYTE)0x10000; pbTry < (PBYTE)0x200000000;) {
MEMORY_BASIC_INFORMATION mbi;
if (!VirtualQuery(pbTry, &mbi, sizeof(mbi))) {
break;
}
if (mbi.State == MEM_FREE && mbi.RegionSize > 0x10000) {
PBYTE pbBase = (PBYTE)((((ULONG_PTR)pbTry) + 0xffff) & 0xffffffffffff0000);
SIZE_T cbTry = mbi.RegionSize & 0xffffffffffff0000;
if (cbTry > 0x40000000) {
cbTry = 0x40000000;
}
PVOID pvRegion = VirtualAlloc(pbBase, cbTry,
MEM_RESERVE,
PAGE_NOACCESS);
if (pvRegion == NULL) {
printf("---%p..%p failed.\n", pbBase, mbi.RegionSize - 0x10000);
}
else {
continue;
}
}
printf(" %p..%p %6x [%p]\n",
mbi.BaseAddress, (PBYTE)mbi.BaseAddress + mbi.RegionSize - 1,
mbi.State,
pbTry);
pbTry = (PBYTE)mbi.BaseAddress + mbi.RegionSize;
}
#endif
printf("sleepnew.exe: GetSleptTicks() = %d\n\n", GetSleptTicks());
return 0;
}
//
///////////////////////////////////////////////////////////////// End of File.

View File

@@ -0,0 +1,69 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detour Test Program (sleepold.cpp of sleepold.exe)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#include <windows.h>
#include <stdio.h>
#include "verify.cpp"
int __cdecl main(int argc, char **argv)
{
BOOL fQuiet = FALSE;
if (argc == 2 && _stricmp(argv[1], "-quiet") == 0) {
fQuiet = TRUE;
}
//
// Verify what the code looks like.
//
printf("sleepold.exe: Starting (at %p).\n", main);
if (!fQuiet) {
Verify("SleepEx", (PBYTE)SleepEx);
printf("\n");
}
fflush(stdout);
//
// See if another process wants us to wait on a shared event.
// This helps in testing loading a DLL into a new process.
if (argc == 2 && _stricmp(argv[1], "-wait") == 0) {
HANDLE hEvent = OpenEventA(SYNCHRONIZE, FALSE, "detours_load_test_event");
if (hEvent) {
printf("sleepold.exe: Waiting for detours_load_test_event to be set.\n");
fflush(stdout);
WaitForSingleObject(hEvent, INFINITE);
}
else {
printf("sleepold.exe: Couldn't open detours_load_test_event.\n");
}
}
//
// Try out sleep (which may be detours).
//
printf("sleepold.exe: Calling Sleep for 1 second.\n");
Sleep(1000);
printf("sleepold.exe: Calling SleepEx for 1 second.\n");
SleepEx(1000, false);
printf("sleepold.exe: Calling Sleep again for 1 second.\n");
Sleep(1000);
// DebugBreak();
printf("sleepold.exe: Done sleeping.\n\n");
fflush(stdout);
return 0;
}
//
///////////////////////////////////////////////////////////////// End of File.

130
samples/slept/slept.cpp Normal file
View File

@@ -0,0 +1,130 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detour Test Program (slept.cpp of slept.dll)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#include <stdio.h>
#include <windows.h>
#include "detours.h"
#include "slept.h"
#include "verify.cpp"
static BOOL fBroke = FALSE;
static LONG dwSlept = 0;
static DWORD (WINAPI * TrueSleepEx)(DWORD dwMilliseconds, BOOL bAlertable) = SleepEx;
DWORD WINAPI UntimedSleepEx(DWORD dwMilliseconds, BOOL bAlertable)
{
return TrueSleepEx(dwMilliseconds, bAlertable);
}
DWORD WINAPI TimedSleepEx(DWORD dwMilliseconds, BOOL bAlertable)
{
DWORD dwBeg = GetTickCount();
DWORD ret = TrueSleepEx(dwMilliseconds, bAlertable);
DWORD dwEnd = GetTickCount();
if (!fBroke) {
fBroke = TRUE;
// DebugBreak();
}
InterlockedExchangeAdd(&dwSlept, dwEnd - dwBeg);
return ret;
}
DWORD WINAPI GetSleptTicks(VOID)
{
return dwSlept;
}
DWORD WINAPI TestTicks(VOID)
{
return TestTicksEx(0);
}
DWORD WINAPI TestTicksEx(DWORD Add)
{
PDWORD pdw = new DWORD [Add + 1];
if (pdw != NULL) {
pdw[0] = dwSlept;
for (DWORD n = 1; n < Add + 1; n++) {
pdw[n] = pdw[n-1] + 1;
}
for (DWORD n = 1; n < Add + 1; n++) {
pdw[n-1] = pdw[n-1] - 1;
}
for (DWORD n = 1; n < Add + 1; n++) {
pdw[n] = pdw[n-1] + 1;
}
Add = pdw[Add] - Add;
delete pdw;
}
else {
Add = dwSlept + Add;
}
return Add;
}
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
{
LONG error;
(void)hinst;
(void)reserved;
if (DetourIsHelperProcess()) {
return TRUE;
}
if (dwReason == DLL_PROCESS_ATTACH) {
DetourRestoreAfterWith();
printf("slept" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: "
" Starting.\n");
PVOID pbExeEntry = DetourGetEntryPoint(NULL);
PVOID pbDllEntry = DetourGetEntryPoint(hinst);
printf("slept" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: "
" ExeEntry=%p, DllEntry=%p\n", pbExeEntry, pbDllEntry);
Verify("SleepEx", (PVOID)SleepEx);
printf("\n");
fflush(stdout);
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)TrueSleepEx, TimedSleepEx);
error = DetourTransactionCommit();
if (error == NO_ERROR) {
printf("slept" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: "
" Detoured SleepEx() @ %p.\n", TrueSleepEx);
}
else {
printf("slept" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: "
" Error detouring SleepEx(): %d\n", error);
}
}
else if (dwReason == DLL_PROCESS_DETACH) {
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)TrueSleepEx, TimedSleepEx);
error = DetourTransactionCommit();
printf("slept" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: "
" Removed SleepEx() detour (%d), slept %d ticks.\n", error, dwSlept);
fflush(stdout);
}
return TRUE;
}
//
///////////////////////////////////////////////////////////////// End of File.

17
samples/slept/slept.h Normal file
View File

@@ -0,0 +1,17 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detour Test Program (slept.h of slept.dll)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
DWORD WINAPI UntimedSleepEx(DWORD dwMilliseconds, BOOL bAlertable);
DWORD WINAPI TimedSleepEx(DWORD dwMilliseconds, BOOL bAlertable);
DWORD WINAPI GetSleptTicks(VOID);
DWORD WINAPI TestTicks(VOID);
DWORD WINAPI TestTicksEx(DWORD Add);
//
///////////////////////////////////////////////////////////////// End of File.

17
samples/slept/slept.rc Normal file
View File

@@ -0,0 +1,17 @@
//////////////////////////////////////////////////////////////////////////////
//
// Version information for sleep.rc.
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#include "detver.h"
#define VER_INTERNALNAME_STR "sleep" DETOURS_STRINGIFY(DETOURS_BITS)
#define VER_ORIGINALFILENAME_STR "sleep" DETOURS_STRINGIFY(DETOURS_BITS) ".dll"
#define VER_FILEDESCRIPTION_STR "Detours Sleep Test Module"
#define VER_COMPANYNAME_STR "Microsoft Corporation"
#include "common.ver"

74
samples/slept/verify.cpp Normal file
View File

@@ -0,0 +1,74 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detour Test Program (verify.cpp)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#include <detours.h>
static VOID Dump(PBYTE pbBytes, LONG nBytes, PBYTE pbTarget)
{
for (LONG n = 0; n < nBytes; n += 16) {
printf(" %p: ", pbBytes + n);
for (LONG m = n; m < n + 16; m++) {
if (m >= nBytes) {
printf(" ");
}
else {
printf("%02x", pbBytes[m]);
}
if (m % 4 == 3) {
printf(" ");
}
}
if (n == 0 && pbTarget != DETOUR_INSTRUCTION_TARGET_NONE) {
printf(" [%p]", pbTarget);
}
printf("\n");
}
}
static VOID Decode(PCSTR pszDesc, PBYTE pbCode, PBYTE pbOther, PBYTE pbPointer, LONG nInst)
{
if (pbCode != pbPointer) {
printf(" %s = %p [%p]\n", pszDesc, pbCode, pbPointer);
}
else {
printf(" %s = %p\n", pszDesc, pbCode);
}
if (pbCode == pbOther) {
printf(" ... unchanged ...\n");
return;
}
PBYTE pbSrc = pbCode;
PBYTE pbEnd;
PVOID pbTarget;
for (LONG n = 0; n < nInst; n++) {
pbEnd = (PBYTE)DetourCopyInstruction(NULL, NULL, pbSrc, &pbTarget, NULL);
Dump(pbSrc, (int)(pbEnd - pbSrc), (PBYTE)pbTarget);
pbSrc = pbEnd;
}
}
VOID WINAPI Verify(PCHAR pszFunc, PVOID pvPointer)
{
PVOID pvCode = DetourCodeFromPointer(pvPointer, NULL);
Decode(pszFunc, (PBYTE)pvCode, NULL, (PBYTE)pvPointer, 3);
}
VOID WINAPI VerifyEx(PCHAR pszFunc, PVOID pvPointer, LONG nInst)
{
PVOID pvCode = DetourCodeFromPointer(pvPointer, NULL);
Decode(pszFunc, (PBYTE)pvCode, NULL, (PBYTE)pvPointer, nInst);
}
//
///////////////////////////////////////////////////////////////// End of File.

101
samples/syelog/Makefile Normal file
View File

@@ -0,0 +1,101 @@
##############################################################################
##
## Makefile for Detours.
##
## Microsoft Research Detours Package
##
## Copyright (c) Microsoft Corporation. All rights reserved.
##
##############################################################################
TARGETOS=WINNT
!include ..\common.mak
LIBS=$(LIBS) kernel32.lib
##############################################################################
all: dirs \
$(INCD)\syelog.h \
$(LIBD)\syelog.lib \
$(BIND)\syelogd.exe \
\
$(BIND)\sltest.exe \
$(BIND)\sltestp.exe \
\
!IF $(DETOURS_SOURCE_BROWSING)==1
$(OBJD)\syelogd.bsc \
$(OBJD)\sltest.bsc \
$(OBJD)\sltestp.bsc \
!ENDIF
##############################################################################
##
clean:
-del *~ test.txt 2> nul
-del $(INCD)\syelog.* 2>nul
-del $(LIBD)\syelog.* 2>nul
-del $(BIND)\syelogd.* 2>nul
-del $(BIND)\sltest.* 2>nul
-del $(BIND)\sltestp.* 2>nul
-rmdir /q /s $(OBJD) 2>nul
realclean: clean
-rmdir /q /s $(OBJDS) 2>nul
##############################################################################
dirs:
@if not exist $(INCD) mkdir $(INCD) && echo. Created $(INCD)
@if not exist $(LIBD) mkdir $(LIBD) && echo. Created $(LIBD)
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
$(OBJD)\syelog.obj : syelog.cpp syelog.h
$(OBJD)\syelogd.obj: syelogd.cpp syelog.h
$(OBJD)\sltest.obj: sltest.cpp syelog.h
$(OBJD)\sltestp.obj: sltestp.cpp syelog.h
$(INCD)\syelog.h : syelog.h
copy syelog.h $@
$(LIBD)\syelog.lib : $(OBJD)\syelog.obj
link /lib $(LIBFLAGS) /out:$@ $(OBJD)\syelog.obj
$(BIND)\sltest.exe: $(OBJD)\sltest.obj $(OBJD)\syelog.obj $(DEPS)
$(CC) $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\sltest.obj \
/link $(LINKFLAGS) $(LIBS)
$(OBJD)\sltest.bsc : $(OBJD)\sltest.obj
bscmake /v /n /o $@ $(OBJD)\sltest.sbr
$(BIND)\sltestp.exe: $(OBJD)\sltestp.obj $(DEPS)
$(CC) $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\sltestp.obj \
/link $(LINKFLAGS) $(LIBS)
$(OBJD)\sltestp.bsc : $(OBJD)\sltestp.obj
bscmake /v /n /o $@ $(OBJD)\sltestp.sbr
$(LIBD)\detours.lib:
cd $(ROOT)\src
nmake /nologo
cd $(MAKEDIR)
$(BIND)\syelogd.exe: $(OBJD)\syelogd.obj $(DEPS)
$(CC) $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\syelogd.obj \
/link $(LINKFLAGS) ws2_32.lib mswsock.lib advapi32.lib
$(OBJD)\syelogd.bsc : $(OBJD)\syelogd.obj
bscmake /v /n /o $@ $(OBJD)\syelogd.sbr
##############################################################################
test: $(BIND)\syelogd.exe $(BIND)\sltest.exe $(BIND)\sltestp.exe
@echo -------- Logging output to test.txt ------------
start $(BIND)\syelogd.exe test.txt
$(BIND)\sleep5.exe 1
$(BIND)\sltestp.exe
$(BIND)\sltest.exe /x
type test.txt
################################################################# End of File.

145
samples/syelog/sltest.cpp Normal file
View File

@@ -0,0 +1,145 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detours Test Program (sltest.cpp of sltest.exe)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// Test the named-pipe-based connection with syelog.lib to the syelog
// system-event logger.
//
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#pragma warning(push)
#if _MSC_VER > 1400
#pragma warning(disable:6102 6103) // /analyze warnings
#endif
#include <strsafe.h>
#pragma warning(pop)
#include "syelog.h"
#include "detours.h"
extern "C" {
HANDLE ( WINAPI *
Real_CreateFileW)(LPCWSTR a0,
DWORD a1,
DWORD a2,
LPSECURITY_ATTRIBUTES a3,
DWORD a4,
DWORD a5,
HANDLE a6)
= CreateFileW;
BOOL ( WINAPI *
Real_WriteFile)(HANDLE hFile,
LPCVOID lpBuffer,
DWORD nNumberOfBytesToWrite,
LPDWORD lpNumberOfBytesWritten,
LPOVERLAPPED lpOverlapped)
= WriteFile;
BOOL ( WINAPI *
Real_FlushFileBuffers)(HANDLE hFile)
= FlushFileBuffers;
BOOL ( WINAPI *
Real_CloseHandle)(HANDLE hObject)
= CloseHandle;
BOOL ( WINAPI *
Real_WaitNamedPipeW)(LPCWSTR lpNamedPipeName, DWORD nTimeOut)
= WaitNamedPipeW;
BOOL ( WINAPI *
Real_SetNamedPipeHandleState)(HANDLE hNamedPipe,
LPDWORD lpMode,
LPDWORD lpMaxCollectionCount,
LPDWORD lpCollectDataTimeout)
= SetNamedPipeHandleState;
DWORD ( WINAPI *
Real_GetCurrentProcessId)(VOID)
= GetCurrentProcessId;
VOID ( WINAPI *
Real_GetSystemTimeAsFileTime)(LPFILETIME lpSystemTimeAsFileTime)
= GetSystemTimeAsFileTime;
VOID ( WINAPI *
Real_InitializeCriticalSection)(LPCRITICAL_SECTION lpSection)
= InitializeCriticalSection;
VOID ( WINAPI *
Real_EnterCriticalSection)(LPCRITICAL_SECTION lpSection)
= EnterCriticalSection;
VOID ( WINAPI *
Real_LeaveCriticalSection)(LPCRITICAL_SECTION lpSection)
= LeaveCriticalSection;
}
int main(int argc, char **argv)
{
BOOL fNeedHelp = FALSE;
BOOL fRequestExitOnClose = FALSE;
int arg = 1;
for (; arg < argc && (argv[arg][0] == '-' || argv[arg][0] == '/'); arg++) {
CHAR *argn = argv[arg] + 1;
CHAR *argp = argn;
while (*argp && *argp != ':') {
argp++;
}
if (*argp == ':') {
*argp++ = '\0';
}
switch (argn[0]) {
case 'x': // Request exit on close.
case 'X':
fRequestExitOnClose = TRUE;
break;
case '?': // Help.
fNeedHelp = TRUE;
break;
default:
fNeedHelp = TRUE;
printf("SLTEST: Bad argument: %s:%s\n", argn, argp);
break;
}
}
if (fNeedHelp) {
printf("Usage:\n"
" sltest.exe [options] message\n"
"Options:\n"
" /x Ask syelogd.exe to terminate when this connect closes.\n"
" /? Display this help message.\n"
"\n");
exit(1);
}
SyelogOpen("sltest", SYELOG_FACILITY_APPLICATION);
if (arg >= argc) {
Syelog(SYELOG_SEVERITY_INFORMATION, "Hello World! [1 of 4]");
Syelog(SYELOG_SEVERITY_INFORMATION, "Hello World! [2 of 4]");
Syelog(SYELOG_SEVERITY_INFORMATION, "Hello World! [3 of 4]");
Syelog(SYELOG_SEVERITY_INFORMATION, "Hello World! [4 of 4]");
}
else {
CHAR Buffer[1024] = "";
for (; arg < argc; arg++) {
StringCchCatA(Buffer, ARRAYSIZE(Buffer), argv[arg]);
if (arg + 1 < argc) {
StringCchCatA(Buffer, ARRAYSIZE(Buffer), " ");
}
}
Syelog(SYELOG_SEVERITY_INFORMATION, Buffer);
}
SyelogClose(fRequestExitOnClose);
return 0;
}

104
samples/syelog/sltestp.cpp Normal file
View File

@@ -0,0 +1,104 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detours Test Program (sltestp.cpp of sltestp.exe)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// Test the named-pipe-based connection to the syelog system-event logger.
//
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#pragma warning(push)
#if _MSC_VER > 1400
#pragma warning(disable:6102 6103) // /analyze warnings
#endif
#include <strsafe.h>
#pragma warning(pop)
#include "syelog.h"
VOID MyErrExit(PCSTR pszMsg)
{
fprintf(stderr, "Error %s: %d\n", pszMsg, GetLastError());
exit(1);
}
DWORD main(int argc, char *argv[])
{
HANDLE hPipe;
SYELOG_MESSAGE Message;
BOOL fSuccess;
DWORD cbWritten, dwMode;
// Try to open a named pipe; wait for it, if necessary.
TIME_ZONE_INFORMATION tzi;
GetTimeZoneInformation(&tzi);
for (;;) {
hPipe = CreateFileW(SYELOG_PIPE_NAMEW, // pipe name
GENERIC_WRITE, // write access only
0, // no sharing
NULL, // no security attributes
OPEN_EXISTING, // opens existing pipe
0, // default attributes
NULL); // no template file
// Break if the pipe handle is valid.
if (hPipe != INVALID_HANDLE_VALUE)
break;
// Exit if an error other than ERROR_PIPE_BUSY occurs.
if (GetLastError() != ERROR_PIPE_BUSY)
MyErrExit("Could not open pipe");
// All pipe instances are busy, so wait for 1 seconds.
if (!WaitNamedPipeW(SYELOG_PIPE_NAMEW, 1000))
MyErrExit("Could not open pipe");
}
// The pipe connected; change to message-read mode.
dwMode = PIPE_READMODE_MESSAGE;
fSuccess = SetNamedPipeHandleState(hPipe, // pipe handle
&dwMode, // new pipe mode
NULL, // don't set maximum bytes
NULL); // don't set maximum time
if (!fSuccess)
MyErrExit("SetNamedPipeHandleState");
// Send a message to the pipe server.
memset(&Message, 0, sizeof(Message));
StringCchCopyA(Message.szMessage, ARRAYSIZE(Message.szMessage),
(argc > 1) ? argv[1] : "sltestp: hello world!");
Message.nFacility = SYELOG_FACILITY_APPLICATION;
Message.nSeverity = SYELOG_SEVERITY_INFORMATION;
Message.nProcessId = GetCurrentProcessId();
GetSystemTimeAsFileTime(&Message.ftOccurance);
PCSTR pszEnd = Message.szMessage;
for (; *pszEnd; pszEnd++) {
// no internal contents.
}
Message.nBytes = (USHORT)(pszEnd - ((PCSTR)&Message) + 1);
fSuccess = WriteFile(hPipe, // pipe handle
&Message, // message
Message.nBytes, // message length
&cbWritten, // bytes written
NULL); // not overlapped
if (! fSuccess)
MyErrExit("WriteFile");
CloseHandle(hPipe);
GetTimeZoneInformation(&tzi);
return 0;
}

847
samples/syelog/syelog.cpp Normal file
View File

@@ -0,0 +1,847 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detours Test Program (syelog.cpp of syelog.lib)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#include <windows.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdlib.h>
#include "detours.h"
#include "syelog.h"
#include <stdio.h>
//////////////////////////////////////////////////////////////////////////////
extern "C" {
extern HANDLE ( WINAPI * Real_CreateFileW)(LPCWSTR a0,
DWORD a1,
DWORD a2,
LPSECURITY_ATTRIBUTES a3,
DWORD a4,
DWORD a5,
HANDLE a6);
extern BOOL ( WINAPI * Real_WriteFile)(HANDLE hFile,
LPCVOID lpBuffer,
DWORD nNumberOfBytesToWrite,
LPDWORD lpNumberOfBytesWritten,
LPOVERLAPPED lpOverlapped);
extern BOOL ( WINAPI * Real_FlushFileBuffers)(HANDLE hFile);
extern BOOL ( WINAPI * Real_CloseHandle)(HANDLE hObject);
extern BOOL ( WINAPI * Real_WaitNamedPipeW)(LPCWSTR lpNamedPipeName, DWORD nTimeOut);
extern BOOL ( WINAPI * Real_SetNamedPipeHandleState)(HANDLE hNamedPipe,
LPDWORD lpMode,
LPDWORD lpMaxCollectionCount,
LPDWORD lpCollectDataTimeout);
extern DWORD ( WINAPI * Real_GetCurrentProcessId)(VOID);
extern VOID ( WINAPI * Real_GetSystemTimeAsFileTime)(LPFILETIME lpSystemTimeAsFileTime);
extern VOID ( WINAPI * Real_InitializeCriticalSection)(LPCRITICAL_SECTION lpSection);
extern VOID ( WINAPI * Real_EnterCriticalSection)(LPCRITICAL_SECTION lpSection);
extern VOID ( WINAPI * Real_LeaveCriticalSection)(LPCRITICAL_SECTION lpSection);
}
///////////////////////////////////////////////////////////////////// VPrintf.
//
// Completely side-effect free printf replacement (but no FP numbers).
//
static PCHAR do_base(PCHAR pszOut, UINT64 nValue, UINT nBase, PCSTR pszDigits)
{
CHAR szTmp[96];
int nDigit = sizeof(szTmp)-2;
for (; nDigit >= 0; nDigit--) {
szTmp[nDigit] = pszDigits[nValue % nBase];
nValue /= nBase;
}
for (nDigit = 0; nDigit < sizeof(szTmp) - 2 && szTmp[nDigit] == '0'; nDigit++) {
// skip leading zeros.
}
for (; nDigit < sizeof(szTmp) - 1; nDigit++) {
*pszOut++ = szTmp[nDigit];
}
*pszOut = '\0';
return pszOut;
}
static PCHAR do_str(PCHAR pszOut, PCHAR pszEnd, PCSTR pszIn)
{
while (*pszIn && pszOut < pszEnd) {
*pszOut++ = *pszIn++;
}
*pszOut = '\0';
return pszOut;
}
static PCHAR do_wstr(PCHAR pszOut, PCHAR pszEnd, PCWSTR pszIn)
{
while (*pszIn && pszOut < pszEnd) {
*pszOut++ = (CHAR)*pszIn++;
}
*pszOut = '\0';
return pszOut;
}
static PCHAR do_estr(PCHAR pszOut, PCHAR pszEnd, PCSTR pszIn)
{
while (*pszIn && pszOut < pszEnd) {
if (*pszIn == '<') {
if (pszOut + 4 > pszEnd) {
break;
}
pszIn++;
*pszOut++ = '&';
*pszOut++ = 'l';
*pszOut++ = 't';
*pszOut++ = ';';
}
else if (*pszIn == '>') {
if (pszOut + 4 > pszEnd) {
break;
}
pszIn++;
*pszOut++ = '&';
*pszOut++ = 'g';
*pszOut++ = 't';
*pszOut++ = ';';
}
else if (*pszIn == '&') {
if (pszOut + 5 > pszEnd) {
break;
}
pszIn++;
*pszOut++ = '&';
*pszOut++ = 'a';
*pszOut++ = 'm';
*pszOut++ = 'p';
*pszOut++ = ';';
}
else if (*pszIn == '\"') {
if (pszOut + 6 > pszEnd) {
break;
}
pszIn++;
*pszOut++ = '&';
*pszOut++ = 'q';
*pszOut++ = 'u';
*pszOut++ = 'o';
*pszOut++ = 't';
*pszOut++ = ';';
}
else if (*pszIn == '\'') {
if (pszOut + 6 > pszEnd) {
break;
}
pszIn++;
*pszOut++ = '&';
*pszOut++ = 'a';
*pszOut++ = 'p';
*pszOut++ = 'o';
*pszOut++ = 's';
*pszOut++ = ';';
}
else if (*pszIn < ' ') {
BYTE c = (BYTE)(*pszIn++);
if (c < 10 && pszOut + 4 <= pszEnd) {
*pszOut++ = '&';
*pszOut++ = '#';
*pszOut++ = '0' + (c % 10);
*pszOut++ = ';';
}
else if (c < 100 && pszOut + 5 <= pszEnd) {
*pszOut++ = '&';
*pszOut++ = '#';
*pszOut++ = '0' + ((c / 10) % 10);
*pszOut++ = '0' + (c % 10);
*pszOut++ = ';';
}
else if (c < 1000 && pszOut + 6 <= pszEnd) {
*pszOut++ = '&';
*pszOut++ = '#';
*pszOut++ = '0' + ((c / 100) % 10);
*pszOut++ = '0' + ((c / 10) % 10);
*pszOut++ = '0' + (c % 10);
*pszOut++ = ';';
}
else {
break;
}
}
else {
*pszOut++ = *pszIn++;
}
}
*pszOut = '\0';
return pszOut;
}
static PCHAR do_ewstr(PCHAR pszOut, PCHAR pszEnd, PCWSTR pszIn)
{
while (*pszIn && pszOut < pszEnd) {
if (*pszIn == '<') {
if (pszOut + 4 > pszEnd) {
break;
}
pszIn++;
*pszOut++ = '&';
*pszOut++ = 'l';
*pszOut++ = 't';
*pszOut++ = ';';
}
else if (*pszIn == '>') {
if (pszOut + 4 > pszEnd) {
break;
}
pszIn++;
*pszOut++ = '&';
*pszOut++ = 'g';
*pszOut++ = 't';
*pszOut++ = ';';
}
else if (*pszIn == '&') {
if (pszOut + 5 > pszEnd) {
break;
}
pszIn++;
*pszOut++ = '&';
*pszOut++ = 'a';
*pszOut++ = 'm';
*pszOut++ = 'p';
*pszOut++ = ';';
}
else if (*pszIn == '\"') {
if (pszOut + 6 > pszEnd) {
break;
}
pszIn++;
*pszOut++ = '&';
*pszOut++ = 'q';
*pszOut++ = 'u';
*pszOut++ = 'o';
*pszOut++ = 't';
*pszOut++ = ';';
}
else if (*pszIn == '\'') {
if (pszOut + 6 > pszEnd) {
break;
}
pszIn++;
*pszOut++ = '&';
*pszOut++ = 'a';
*pszOut++ = 'p';
*pszOut++ = 'o';
*pszOut++ = 's';
*pszOut++ = ';';
}
else if (*pszIn < ' ' || *pszIn > 127) {
WCHAR c = *pszIn++;
if (c < 10 && pszOut + 4 <= pszEnd) {
*pszOut++ = '&';
*pszOut++ = '#';
*pszOut++ = '0' + (CHAR)(c % 10);
*pszOut++ = ';';
}
else if (c < 100 && pszOut + 5 <= pszEnd) {
*pszOut++ = '&';
*pszOut++ = '#';
*pszOut++ = '0' + (CHAR)((c / 10) % 10);
*pszOut++ = '0' + (CHAR)(c % 10);
*pszOut++ = ';';
}
else if (c < 1000 && pszOut + 6 <= pszEnd) {
*pszOut++ = '&';
*pszOut++ = '#';
*pszOut++ = '0' + (CHAR)((c / 100) % 10);
*pszOut++ = '0' + (CHAR)((c / 10) % 10);
*pszOut++ = '0' + (CHAR)(c % 10);
*pszOut++ = ';';
}
else {
break;
}
}
else {
*pszOut++ = (CHAR)*pszIn++;
}
}
*pszOut = '\0';
return pszOut;
}
#if _MSC_VER >= 1900
#pragma warning(push)
#pragma warning(disable:4456) // declaration hides previous local declaration
#endif
VOID VSafePrintf(PCSTR pszMsg, va_list args, PCHAR pszBuffer, LONG cbBuffer)
{
PCHAR pszOut = pszBuffer;
PCHAR pszEnd = pszBuffer + cbBuffer - 1;
pszBuffer[0] = '\0';
__try {
while (*pszMsg && pszOut < pszEnd) {
if (*pszMsg == '%') {
CHAR szHead[4] = "";
INT nLen;
INT nWidth = 0;
INT nPrecision = 0;
BOOL fLeft = FALSE;
BOOL fPositive = FALSE;
BOOL fPound = FALSE;
BOOL fBlank = FALSE;
BOOL fZero = FALSE;
BOOL fDigit = FALSE;
BOOL fSmall = FALSE;
BOOL fLarge = FALSE;
BOOL f64Bit = FALSE;
PCSTR pszArg = pszMsg;
pszMsg++;
for (; (*pszMsg == '-' ||
*pszMsg == '+' ||
*pszMsg == '#' ||
*pszMsg == ' ' ||
*pszMsg == '0'); pszMsg++) {
switch (*pszMsg) {
case '-': fLeft = TRUE; break;
case '+': fPositive = TRUE; break;
case '#': fPound = TRUE; break;
case ' ': fBlank = TRUE; break;
case '0': fZero = TRUE; break;
}
}
if (*pszMsg == '*') {
nWidth = va_arg(args, INT);
pszMsg++;
}
else {
while (*pszMsg >= '0' && *pszMsg <= '9') {
nWidth = nWidth * 10 + (*pszMsg++ - '0');
}
}
if (*pszMsg == '.') {
pszMsg++;
fDigit = TRUE;
if (*pszMsg == '*') {
nPrecision = va_arg(args, INT);
pszMsg++;
}
else {
while (*pszMsg >= '0' && *pszMsg <= '9') {
nPrecision = nPrecision * 10 + (*pszMsg++ - '0');
}
}
}
if (*pszMsg == 'h') {
fSmall = TRUE;
pszMsg++;
}
else if (*pszMsg == 'l') {
fLarge = TRUE;
pszMsg++;
}
else if (*pszMsg == 'I' && pszMsg[1] == '6' && pszMsg[2] == '4') {
f64Bit = TRUE;
pszMsg += 3;
}
if (*pszMsg == 's' || *pszMsg == 'e' || *pszMsg == 'c') {
// We ignore the length, precision, and alignment
// to avoid using a temporary buffer.
if (*pszMsg == 's') { // [GalenH] need to not use temp.
PVOID pvData = va_arg(args, PVOID);
pszMsg++;
if (fSmall) {
fLarge = FALSE;
}
__try {
if (pvData == NULL) {
pszOut = do_str(pszOut, pszEnd, "<NULL>");
}
else if (pvData < (PVOID)0x10000) {
pszOut = do_str(pszOut, pszEnd, "#");
pszOut = do_base(pszOut, (UINT64)pvData, 16,
"0123456789ABCDEF");
pszOut = do_str(pszOut, pszEnd, "#");
}
else if (fLarge) {
pszOut = do_wstr(pszOut, pszEnd, (PWCHAR)pvData);
}
else {
pszOut = do_str(pszOut, pszEnd, (PCHAR)pvData);
}
} __except(EXCEPTION_EXECUTE_HANDLER) {
pszOut = do_str(pszOut, pszEnd, "-");
pszOut = do_base(pszOut, (UINT64)pvData, 16,
"0123456789ABCDEF");
pszOut = do_str(pszOut, pszEnd, "-");
}
}
else if (*pszMsg == 'e') { // Escape the string.
PVOID pvData = va_arg(args, PVOID);
pszMsg++;
if (fSmall) {
fLarge = FALSE;
}
__try {
if (pvData == NULL) {
pszOut = do_str(pszOut, pszEnd, "<NULL>");
}
else if (pvData < (PVOID)0x10000) {
pszOut = do_str(pszOut, pszEnd, ">");
pszOut = do_base(pszOut, (UINT64)pvData, 16,
"0123456789ABCDEF");
pszOut = do_str(pszOut, pszEnd, ">");
}
else if (fLarge) {
pszOut = do_ewstr(pszOut, pszEnd, (PWCHAR)pvData);
}
else {
pszOut = do_estr(pszOut, pszEnd, (PCHAR)pvData);
}
} __except(EXCEPTION_EXECUTE_HANDLER) {
pszOut = do_str(pszOut, pszEnd, "-");
pszOut = do_base(pszOut, (UINT64)pvData, 16,
"0123456789ABCDEF");
pszOut = do_str(pszOut, pszEnd, "-");
}
}
else {
CHAR szTemp[2];
pszMsg++;
szTemp[0] = (CHAR)va_arg(args, INT);
szTemp[1] = '\0';
pszOut = do_str(pszOut, pszEnd, szTemp);
}
}
else if (*pszMsg == 'd' || *pszMsg == 'i' || *pszMsg == 'o' ||
*pszMsg == 'x' || *pszMsg == 'X' || *pszMsg == 'b' ||
*pszMsg == 'u') {
CHAR szTemp[128];
UINT64 value;
if (f64Bit) {
value = va_arg(args, UINT64);
}
else {
value = va_arg(args, UINT);
}
if (*pszMsg == 'x') {
pszMsg++;
nLen = (int)(do_base(szTemp, value, 16, "0123456789abcdef") - szTemp);
if (fPound && value) {
do_str(szHead, szHead + sizeof(szHead) - 1, "0x");
}
}
else if (*pszMsg == 'X') {
pszMsg++;
nLen = (int)(do_base(szTemp, value, 16, "0123456789ABCDEF") - szTemp);
if (fPound && value) {
do_str(szHead, szHead + sizeof(szHead) - 1, "0X");
}
}
else if (*pszMsg == 'd') {
pszMsg++;
if ((INT64)value < 0) {
value = -(INT64)value;
do_str(szHead, szHead + sizeof(szHead) - 1, "-");
}
else if (fPositive) {
if (value > 0) {
do_str(szHead, szHead + sizeof(szHead) - 1, "+");
}
}
else if (fBlank) {
if (value > 0) {
do_str(szHead, szHead + sizeof(szHead) - 1, " ");
}
}
nLen = (int)(do_base(szTemp, value, 10, "0123456789") - szTemp);
nPrecision = 0;
}
else if (*pszMsg == 'u') {
pszMsg++;
nLen = (int)(do_base(szTemp, value, 10, "0123456789") - szTemp);
nPrecision = 0;
}
else if (*pszMsg == 'o') {
pszMsg++;
nLen = (int)(do_base(szTemp, value, 8, "01234567") - szTemp);
nPrecision = 0;
if (fPound && value) {
do_str(szHead, szHead + sizeof(szHead) - 1, "0");
}
}
else if (*pszMsg == 'b') {
pszMsg++;
nLen = (int)(do_base(szTemp, value, 2, "01") - szTemp);
nPrecision = 0;
if (fPound && value) {
do_str(szHead, szHead + sizeof(szHead) - 1, "0b");
}
}
else {
pszMsg++;
if ((INT64)value < 0) {
value = -(INT64)value;
do_str(szHead, szHead + sizeof(szHead) - 1, "-");
}
else if (fPositive) {
if (value > 0) {
do_str(szHead, szHead + sizeof(szHead) - 1, "+");
}
}
else if (fBlank) {
if (value > 0) {
do_str(szHead, szHead + sizeof(szHead) - 1, " ");
}
}
nLen = (int)(do_base(szTemp, value, 10, "0123456789") - szTemp);
nPrecision = 0;
}
INT nHead = 0;
for (; szHead[nHead]; nHead++) {
// Count characters in head string.
}
if (fLeft) {
if (nHead) {
pszOut = do_str(pszOut, pszEnd, szHead);
nLen += nHead;
}
pszOut = do_str(pszOut, pszEnd, szTemp);
for (; nLen < nWidth && pszOut < pszEnd; nLen++) {
*pszOut++ = ' ';
}
}
else if (fZero) {
if (nHead) {
pszOut = do_str(pszOut, pszEnd, szHead);
nLen += nHead;
}
for (; nLen < nWidth && pszOut < pszEnd; nLen++) {
*pszOut++ = '0';
}
pszOut = do_str(pszOut, pszEnd, szTemp);
}
else {
if (nHead) {
nLen += nHead;
}
for (; nLen < nWidth && pszOut < pszEnd; nLen++) {
*pszOut++ = ' ';
}
if (nHead) {
pszOut = do_str(pszOut, pszEnd, szHead);
}
pszOut = do_str(pszOut, pszEnd, szTemp);
}
}
else if (*pszMsg == 'p') {
CHAR szTemp[64];
ULONG_PTR value;
value = va_arg(args, ULONG_PTR);
if ((INT64)value == (INT64)-1 ||
(INT64)value == (INT64)-2) {
if (*pszMsg == 'p') {
pszMsg++;
}
szTemp[0] = '-';
szTemp[1] = ((INT64)value == (INT64)-1) ? '1' : '2';
szTemp[2] = '\0';
nLen = 2;
}
else {
if (*pszMsg == 'p') {
pszMsg++;
nLen = (int)(do_base(szTemp, (UINT64)value, 16, "0123456789abcdef") - szTemp);
if (fPound && value) {
do_str(szHead, szHead + sizeof(szHead) - 1, "0x");
}
}
else {
pszMsg++;
nLen = (int)(do_base(szTemp, (UINT64)value, 16, "0123456789ABCDEF") - szTemp);
if (fPound && value) {
do_str(szHead, szHead + sizeof(szHead) - 1, "0x");
}
}
}
INT nHead = 0;
for (; szHead[nHead]; nHead++) {
// Count characters in head string.
}
if (nHead) {
pszOut = do_str(pszOut, pszEnd, szHead);
nLen += nHead;
}
for (; nLen < nWidth && pszOut < pszEnd; nLen++) {
*pszOut++ = '0';
}
pszOut = do_str(pszOut, pszEnd, szTemp);
}
else {
pszMsg++;
while (pszArg < pszMsg && pszOut < pszEnd) {
*pszOut++ = *pszArg++;
}
}
}
else {
if (pszOut < pszEnd) {
*pszOut++ = *pszMsg++;
}
}
}
*pszOut = '\0';
pszBuffer[cbBuffer - 1] = '\0';
} __except(EXCEPTION_EXECUTE_HANDLER) {
PCHAR pszOut = pszBuffer;
*pszOut = '\0';
pszOut = do_str(pszOut, pszEnd, "-exception:");
pszOut = do_base(pszOut, (UINT64)GetExceptionCode(), 10, "0123456789");
pszOut = do_str(pszOut, pszEnd, "-");
}
}
#if _MSC_VER >= 1900
#pragma warning(pop)
#endif
PCHAR SafePrintf(PCHAR pszBuffer, LONG cbBuffer, PCSTR pszMsg, ...)
{
va_list args;
va_start(args, pszMsg);
VSafePrintf(pszMsg, args, pszBuffer, cbBuffer);
va_end(args);
while (*pszBuffer) {
pszBuffer++;
}
return pszBuffer;
}
//////////////////////////////////////////////////////////////////////////////
//
static CRITICAL_SECTION s_csPipe; // Guards access to hPipe.
static HANDLE s_hPipe = INVALID_HANDLE_VALUE;
static DWORD s_nPipeError = 0;
static FILETIME s_ftRetry = {0,0};
static BYTE s_nFacility = SYELOG_FACILITY_APPLICATION;
static CHAR s_szIdent[256] = "";
static DWORD s_nProcessId = 0;
static inline INT syelogCompareTimes(CONST PFILETIME pft1, CONST PFILETIME pft2)
{
INT64 ut1 = *(PINT64)pft1;
INT64 ut2 = *(PINT64)pft2;
if (ut1 < ut2) {
return -1;
}
else if (ut1 > ut2) {
return 1;
}
else {
return 0;
}
}
static inline VOID syelogAddMilliseconds(PFILETIME pft, DWORD nMilliseconds)
{
*(PINT64&)pft += ((INT64)nMilliseconds * 10000);
}
//////////////////////////////////////////////////////////////////////////////
//
// Tries to insure that a named-pipe connection to the system log is open
// If the pipe closes, the next call will immediately try to re-open the pipe.
// If the pipe doesn't open again, we wait 5 minutes before trying again.
// We wait 5 minutes, because each attempt may take up to a full second to
// time out.
//
static BOOL syelogIsOpen(PFILETIME pftLog)
{
if (s_hPipe != INVALID_HANDLE_VALUE) {
return TRUE;
}
if (syelogCompareTimes(pftLog, &s_ftRetry) < 0) {
return FALSE;
}
s_hPipe = Real_CreateFileW(SYELOG_PIPE_NAMEW,
GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
SECURITY_ANONYMOUS, NULL);
if (s_hPipe != INVALID_HANDLE_VALUE) {
DWORD dwMode = PIPE_READMODE_MESSAGE;
if (Real_SetNamedPipeHandleState(s_hPipe, &dwMode, NULL, NULL)) {
return TRUE;
}
}
if (Real_WaitNamedPipeW(SYELOG_PIPE_NAMEW, 2000)) { // Wait 2 seconds.
// Pipe connected, change to message-read mode.
//
s_hPipe = Real_CreateFileW(SYELOG_PIPE_NAMEW,
GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
SECURITY_ANONYMOUS, NULL);
if (s_hPipe != INVALID_HANDLE_VALUE) {
DWORD dwMode = PIPE_READMODE_MESSAGE;
if (Real_SetNamedPipeHandleState(s_hPipe, &dwMode, NULL, NULL)) {
return TRUE;
}
}
}
// Couldn't open pipe.
s_ftRetry = *pftLog;
syelogAddMilliseconds(&s_ftRetry, 300000); // Wait 5 minute before retry.
return FALSE;
}
VOID SyelogOpen(PCSTR pszIdentifier, BYTE nFacility)
{
Real_InitializeCriticalSection(&s_csPipe);
if (pszIdentifier) {
PCHAR pszOut = s_szIdent;
PCHAR pszEnd = s_szIdent + ARRAYSIZE(s_szIdent) - 1;
pszOut = do_str(pszOut, pszEnd, pszIdentifier);
pszOut = do_str(pszOut, pszEnd, ": ");
*pszEnd = '\0';
}
else {
s_szIdent[0] = '\0';
}
s_nFacility = nFacility;
s_nProcessId = Real_GetCurrentProcessId();
}
VOID SyelogExV(BOOL fTerminate, BYTE nSeverity, PCSTR pszMsgf, va_list args)
{
SYELOG_MESSAGE Message;
DWORD cbWritten = 0;
Real_GetSystemTimeAsFileTime(&Message.ftOccurance);
Message.fTerminate = fTerminate;
Message.nFacility = s_nFacility;
Message.nSeverity = nSeverity;
Message.nProcessId = s_nProcessId;
PCHAR pszBuf = Message.szMessage;
PCHAR pszEnd = Message.szMessage + ARRAYSIZE(Message.szMessage) - 1;
if (s_szIdent[0]) {
pszBuf = do_str(pszBuf, pszEnd, s_szIdent);
}
*pszEnd = '\0';
VSafePrintf(pszMsgf, args,
pszBuf, (int)(Message.szMessage + sizeof(Message.szMessage) - 1 - pszBuf));
pszEnd = Message.szMessage;
for (; *pszEnd; pszEnd++) {
// no internal contents.
}
// Insure that the message always ends with a '\n'
//
if (pszEnd > Message.szMessage) {
if (pszEnd[-1] != '\n') {
*pszEnd++ = '\n';
*pszEnd++ = '\0';
}
else {
*pszEnd++ = '\0';
}
}
else {
*pszEnd++ = '\n';
*pszEnd++ = '\0';
}
Message.nBytes = (USHORT)(pszEnd - ((PCSTR)&Message));
Real_EnterCriticalSection(&s_csPipe);
if (syelogIsOpen(&Message.ftOccurance)) {
if (!Real_WriteFile(s_hPipe, &Message, Message.nBytes, &cbWritten, NULL)) {
s_nPipeError = GetLastError();
if (s_nPipeError == ERROR_BAD_IMPERSONATION_LEVEL) {
// Don't close the file just for a temporary impersonation level.
}
else {
if (s_hPipe != INVALID_HANDLE_VALUE) {
Real_CloseHandle(s_hPipe);
s_hPipe = INVALID_HANDLE_VALUE;
}
if (syelogIsOpen(&Message.ftOccurance)) {
Real_WriteFile(s_hPipe, &Message, Message.nBytes, &cbWritten, NULL);
}
}
}
}
Real_LeaveCriticalSection(&s_csPipe);
}
VOID SyelogV(BYTE nSeverity, PCSTR pszMsgf, va_list args)
{
SyelogExV(FALSE, nSeverity, pszMsgf, args);
}
VOID Syelog(BYTE nSeverity, PCSTR pszMsgf, ...)
{
va_list args;
va_start(args, pszMsgf);
SyelogExV(FALSE, nSeverity, pszMsgf, args);
va_end(args);
}
VOID SyelogEx(BOOL fTerminate, BYTE nSeverity, PCSTR pszMsgf, ...)
{
va_list args;
va_start(args, pszMsgf);
SyelogExV(fTerminate, nSeverity, pszMsgf, args);
va_end(args);
}
VOID SyelogClose(BOOL fTerminate)
{
if (fTerminate) {
SyelogEx(TRUE, SYELOG_SEVERITY_NOTICE, "Requesting exit on close.\n");
}
Real_EnterCriticalSection(&s_csPipe);
if (s_hPipe != INVALID_HANDLE_VALUE) {
Real_FlushFileBuffers(s_hPipe);
Real_CloseHandle(s_hPipe);
s_hPipe = INVALID_HANDLE_VALUE;
}
Real_LeaveCriticalSection(&s_csPipe);
}
//
///////////////////////////////////////////////////////////////// End of File.

89
samples/syelog/syelog.h Normal file
View File

@@ -0,0 +1,89 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detours Test Program (syelog.h of syelog.lib)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#pragma once
#ifndef _SYELOGD_H_
#define _SYELOGD_H_
#include <stdarg.h>
#pragma pack(push, 1)
#pragma warning(push)
#pragma warning(disable: 4200)
//////////////////////////////////////////////////////////////////////////////
//
//
#define SYELOG_PIPE_NAMEA "\\\\.\\pipe\\syelog"
#define SYELOG_PIPE_NAMEW L"\\\\.\\pipe\\syelog"
#ifdef UNICODE
#define SYELOG_PIPE_NAME SYELOG_PIPE_NAMEW
#else
#define SYELOG_PIPE_NAME SYELOG_PIPE_NAMEA
#endif
//////////////////////////////////////////////////////////////////////////////
//
#define SYELOG_MAXIMUM_MESSAGE 4086 // 4096 - sizeof(header stuff)
typedef struct _SYELOG_MESSAGE
{
USHORT nBytes;
BYTE nFacility;
BYTE nSeverity;
DWORD nProcessId;
FILETIME ftOccurance;
BOOL fTerminate;
CHAR szMessage[SYELOG_MAXIMUM_MESSAGE];
} SYELOG_MESSAGE, *PSYELOG_MESSAGE;
// Facility Codes.
//
#define SYELOG_FACILITY_KERNEL 0x10 // OS Kernel
#define SYELOG_FACILITY_SECURITY 0x20 // OS Security
#define SYELOG_FACILITY_LOGGING 0x30 // OS Logging-internal
#define SYELOG_FACILITY_SERVICE 0x40 // User-mode system daemon
#define SYELOG_FACILITY_APPLICATION 0x50 // User-mode application
#define SYELOG_FACILITY_USER 0x60 // User self-generated.
#define SYELOG_FACILITY_LOCAL0 0x70 // Locally defined.
#define SYELOG_FACILITY_LOCAL1 0x71 // Locally defined.
#define SYELOG_FACILITY_LOCAL2 0x72 // Locally defined.
#define SYELOG_FACILITY_LOCAL3 0x73 // Locally defined.
#define SYELOG_FACILITY_LOCAL4 0x74 // Locally defined.
#define SYELOG_FACILITY_LOCAL5 0x75 // Locally defined.
#define SYELOG_FACILITY_LOCAL6 0x76 // Locally defined.
#define SYELOG_FACILITY_LOCAL7 0x77 // Locally defined.
#define SYELOG_FACILITY_LOCAL8 0x78 // Locally defined.
#define SYELOG_FACILITY_LOCAL9 0x79 // Locally defined.
// Severity Codes.
//
#define SYELOG_SEVERITY_FATAL 0x00 // System is dead.
#define SYELOG_SEVERITY_ALERT 0x10 // Take action immediately.
#define SYELOG_SEVERITY_CRITICAL 0x20 // Critical condition.
#define SYELOG_SEVERITY_ERROR 0x30 // Error
#define SYELOG_SEVERITY_WARNING 0x40 // Warning
#define SYELOG_SEVERITY_NOTICE 0x50 // Significant condition.
#define SYELOG_SEVERITY_INFORMATION 0x60 // Informational
#define SYELOG_SEVERITY_AUDIT_FAIL 0x66 // Audit Failed
#define SYELOG_SEVERITY_AUDIT_PASS 0x67 // Audit Succeeeded
#define SYELOG_SEVERITY_DEBUG 0x70 // Debugging
// Logging Functions.
//
VOID SyelogOpen(PCSTR pszIdentifier, BYTE nFacility);
VOID Syelog(BYTE nSeverity, PCSTR pszMsgf, ...);
VOID SyelogV(BYTE nSeverity, PCSTR pszMsgf, va_list args);
VOID SyelogClose(BOOL fTerminate);
#pragma warning(pop)
#pragma pack(pop)
#endif // _SYELOGD_H_
//
///////////////////////////////////////////////////////////////// End of File.

556
samples/syelog/syelogd.cpp Normal file
View File

@@ -0,0 +1,556 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detours Test Program (syelogd.cpp of syelogd.exe)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#pragma warning(push)
#if _MSC_VER > 1400
#pragma warning(disable:6102 6103) // /analyze warnings
#endif
#include <strsafe.h>
#pragma warning(pop)
#include "syelog.h"
#if (_MSC_VER < 1299)
typedef ULONG * PULONG_PTR;
typedef ULONG ULONG_PTR;
typedef LONG * PLONG_PTR;
typedef LONG LONG_PTR;
#endif
enum {
CLIENT_AWAITING_PIPE_ACCEPT = 0x21,
CLIENT_AWAITING_PIPE_DATA = 0x22,
};
typedef struct _CLIENT : OVERLAPPED
{
HANDLE hPipe;
BOOL fAwaitingAccept;
PVOID Zero;
SYELOG_MESSAGE Message;
} CLIENT, *PCLIENT;
//////////////////////////////////////////////////////////////////////////////
//
BOOL s_fLogToScreen = TRUE; // Log output to screen.
BOOL s_fExitAfterOne = FALSE;
BOOL s_fDeltaTime = FALSE;
HANDLE s_hOutFile = INVALID_HANDLE_VALUE;
LONG s_nActiveClients = 0;
LONGLONG s_llStartTime = 0;
LONGLONG s_llLastTime = 0;
BOOL LogMessageV(BYTE nSeverity, PCHAR pszMsg, ...);
//////////////////////////////////////////////////////////////////////////////
//
VOID MyErrExit(PCSTR pszMsg)
{
DWORD error = GetLastError();
LogMessageV(SYELOG_SEVERITY_FATAL, "Error %d in %s.", error, pszMsg);
fprintf(stderr, "SYELOGD: Error %d in %s.\n", error, pszMsg);
fflush(stderr);
exit(1);
}
//////////////////////////////////////////////////////////////////////////////
//
static PCSTR FileTimeToString(PCHAR pszBuffer, DWORD cbBuffer, FILETIME ftTime)
{
(void)cbBuffer;
static BOOL bGotTzi = FALSE;
static DWORD dwTzi = TIME_ZONE_ID_UNKNOWN;
static TIME_ZONE_INFORMATION tzi;
if (!bGotTzi) {
dwTzi = GetTimeZoneInformation(&tzi);
if (dwTzi == TIME_ZONE_ID_UNKNOWN) {
ZeroMemory(&tzi, sizeof(tzi));
}
bGotTzi = TRUE;
}
SYSTEMTIME stUtc;
SYSTEMTIME stLocal;
pszBuffer[0] = '\0';
if (s_fDeltaTime) {
if (s_llLastTime == 0) {
s_llLastTime = s_llStartTime;
}
ULARGE_INTEGER ul;
ul.LowPart = ftTime.dwLowDateTime;
ul.HighPart = ftTime.dwHighDateTime;
ULONG64 delta = ul.QuadPart - s_llLastTime;
s_llLastTime = ul.QuadPart;
delta /= 10000;
StringCchPrintfA(pszBuffer, cbBuffer, "%7I64d", delta);
}
else {
if (!FileTimeToSystemTime(&ftTime, &stUtc)) {
StringCchPrintfA(pszBuffer, cbBuffer, "ft:%16I64d", *(LONGLONG *)&ftTime);
return pszBuffer;
}
else if (!SystemTimeToTzSpecificLocalTime(&tzi, &stUtc, &stLocal)) {
CopyMemory(&stLocal, &stUtc, sizeof(stLocal));
}
StringCchPrintfA(pszBuffer, cbBuffer, "%4d%02d%02d%02d%02d%02d%03d",
stLocal.wYear,
stLocal.wMonth,
stLocal.wDay,
stLocal.wHour,
stLocal.wMinute,
stLocal.wSecond,
stLocal.wMilliseconds);
}
return pszBuffer;
}
BOOL CloseConnection(PCLIENT pClient)
{
LogMessageV(SYELOG_SEVERITY_INFORMATION, "Client closed pipe.");
InterlockedDecrement(&s_nActiveClients);
if (pClient != NULL) {
if (pClient->hPipe != INVALID_HANDLE_VALUE) {
FlushFileBuffers(pClient->hPipe);
if (!DisconnectNamedPipe(pClient->hPipe)) {
MyErrExit("DisconnectNamedPipe");
}
CloseHandle(pClient->hPipe);
pClient->hPipe = INVALID_HANDLE_VALUE;
}
GlobalFree(pClient);
pClient = NULL;
}
if (s_fExitAfterOne) {
ExitProcess(0);
}
return TRUE;
}
// Creates a pipe instance and initiate an accept request.
//
PCLIENT CreatePipeConnection(HANDLE hCompletionPort)
{
HANDLE hPipe = CreateNamedPipe(SYELOG_PIPE_NAME, // pipe name
PIPE_ACCESS_INBOUND | // read-only access
FILE_FLAG_OVERLAPPED, // overlapped mode
PIPE_TYPE_MESSAGE | // message-type pipe
PIPE_READMODE_MESSAGE | // message read mode
PIPE_WAIT, // blocking mode
PIPE_UNLIMITED_INSTANCES, // unlimited instances
0, // output buffer size
0, // input buffer size
20000, // client time-out
NULL); // no security attributes
if (hPipe == INVALID_HANDLE_VALUE) {
MyErrExit("CreatePipe");
}
// Allocate the client data structure.
//
PCLIENT pClient = (PCLIENT) GlobalAlloc(GPTR, sizeof(CLIENT));
if (pClient == NULL) {
MyErrExit("GlobalAlloc pClient");
}
ZeroMemory(pClient, sizeof(*pClient));
pClient->hPipe = hPipe;
pClient->fAwaitingAccept = TRUE;
// Associate file with our complietion port.
//
if (!CreateIoCompletionPort(pClient->hPipe, hCompletionPort, (ULONG_PTR)pClient, 0)) {
MyErrExit("CreateIoComplietionPort pClient");
}
if (!ConnectNamedPipe(hPipe, pClient)) {
if (GetLastError() != ERROR_IO_PENDING &&
GetLastError() != ERROR_PIPE_LISTENING) {
MyErrExit("ConnectNamedPipe");
}
}
else {
LogMessageV(SYELOG_SEVERITY_INFORMATION,
"ConnectNamedPipe accepted immediately.");
}
return pClient;
}
BOOL LogMessageV(BYTE nSeverity, PCHAR pszMsg, ...)
{
FILETIME ftOccurance;
CHAR szTime[64];
GetSystemTimeAsFileTime(&ftOccurance);
FileTimeToString(szTime, sizeof(szTime), ftOccurance);
if (s_fLogToScreen) {
printf(s_fDeltaTime
? "%-7.7s ---- --.%02x: "
: "%-17.17s ---- --.%02x: "
, szTime, nSeverity);
va_list args;
va_start(args, pszMsg);
vprintf(pszMsg, args);
va_end(args);
printf("\n");
}
if (s_hOutFile != INVALID_HANDLE_VALUE) {
DWORD cbWritten = 0;
CHAR szBuf[4096] = "";
PCHAR pcchEnd = szBuf + ARRAYSIZE(szBuf) - 2;
PCHAR pcchCur = szBuf;
HRESULT hr;
hr = StringCchPrintfExA(pcchCur, pcchEnd - pcchCur,
&pcchCur, NULL, STRSAFE_NULL_ON_FAILURE,
s_fDeltaTime
? "%-7.7s ---- --.%02x: "
: "%-17.17s ---- --.%02x: "
, szTime, nSeverity);
if (FAILED(hr)) {
goto Cleanup;
}
va_list args;
va_start(args, pszMsg);
hr = StringCchPrintfExA(pcchCur, pcchEnd - pcchCur,
&pcchCur, NULL, STRSAFE_NULL_ON_FAILURE,
pszMsg, args);
va_end(args);
if (FAILED(hr)) {
goto Cleanup;
}
hr = StringCchPrintfExA(pcchCur, (szBuf + ARRAYSIZE(szBuf)) - pcchCur,
&pcchCur, NULL, STRSAFE_NULL_ON_FAILURE,
"\n");
if (FAILED(hr)) {
goto Cleanup;
}
Cleanup:
WriteFile(s_hOutFile, szBuf, (DWORD)(pcchCur - szBuf), &cbWritten, NULL);
}
return TRUE;
}
BOOL LogMessage(PSYELOG_MESSAGE pMessage, DWORD nBytes)
{
// Sanity check the size of the message.
//
if (nBytes > pMessage->nBytes) {
nBytes = pMessage->nBytes;
}
if (nBytes >= sizeof(*pMessage)) {
nBytes = sizeof(*pMessage) - 1;
}
// Don't log message if there isn't and message text.
//
if (nBytes <= offsetof(SYELOG_MESSAGE, szMessage)) {
return FALSE;
}
CHAR szTime[64];
FileTimeToString(szTime, sizeof(szTime), pMessage->ftOccurance);
PCHAR pszMsg = pMessage->szMessage;
while (*pszMsg) {
pszMsg++;
}
while (pszMsg > pMessage->szMessage && isspace(pszMsg[-1])) {
*--pszMsg = '\0';
}
if (s_fLogToScreen) {
printf(s_fDeltaTime
? "%-7.7s %4d %02x.%02x: %s\n"
: "%-17.17s %4d %02x.%02x: %s\n",
szTime,
pMessage->nProcessId,
pMessage->nFacility,
pMessage->nSeverity,
pMessage->szMessage);
}
if (s_hOutFile != INVALID_HANDLE_VALUE) {
DWORD cbWritten = 0;
CHAR szBuf[4096];
PCHAR pcchEnd = szBuf + ARRAYSIZE(szBuf);
PCHAR pcchCur = szBuf;
HRESULT hr;
hr = StringCchPrintfExA(pcchCur, pcchEnd - pcchCur,
&pcchCur, NULL, STRSAFE_NULL_ON_FAILURE,
s_fDeltaTime
? "%-7.7s %4d %02x.%02x: %s\n"
: "%-17.17s %4d %02x.%02x: %s\n",
szTime,
pMessage->nProcessId,
pMessage->nFacility,
pMessage->nSeverity,
pMessage->szMessage);
if (FAILED(hr)) {
goto Cleanup;
}
Cleanup:
WriteFile(s_hOutFile, szBuf, (DWORD)(pcchCur - szBuf), &cbWritten, NULL);
}
return TRUE;
}
DWORD WINAPI WorkerThread(LPVOID pvVoid)
{
PCLIENT pClient;
BOOL b;
LPOVERLAPPED lpo;
DWORD nBytes;
HANDLE hCompletionPort = (HANDLE)pvVoid;
for (BOOL fKeepLooping = TRUE; fKeepLooping;) {
pClient = NULL;
lpo = NULL;
nBytes = 0;
b = GetQueuedCompletionStatus(hCompletionPort,
&nBytes, (PULONG_PTR)&pClient, &lpo, INFINITE);
if (!b || lpo == NULL) {
fKeepLooping = FALSE;
MyErrExit("GetQueuedCompletionState");
break;
}
else if (!b) {
if (pClient) {
if (GetLastError() == ERROR_BROKEN_PIPE) {
LogMessageV(SYELOG_SEVERITY_INFORMATION, "Client closed pipe.");
}
else {
LogMessageV(SYELOG_SEVERITY_ERROR,
"GetQueuedCompletionStatus failed %d [%p]",
GetLastError(), pClient);
}
CloseConnection(pClient);
}
continue;
}
if (pClient->fAwaitingAccept) {
InterlockedIncrement(&s_nActiveClients);
pClient->fAwaitingAccept = FALSE;
b = ReadFile(pClient->hPipe,
&pClient->Message,
sizeof(pClient->Message),
&nBytes,
pClient);
if (!b) {
if (GetLastError() != ERROR_IO_PENDING) {
LogMessageV(SYELOG_SEVERITY_ERROR,
"ReadFile failed %d.", GetLastError());
continue;
}
}
CreatePipeConnection(hCompletionPort);
}
else {
if (nBytes < offsetof(SYELOG_MESSAGE, szMessage)) {
CloseConnection(pClient);
}
if (pClient->Message.fTerminate) {
LogMessageV(SYELOG_SEVERITY_NOTICE,
"Client requested terminate on next connection close.");
s_fExitAfterOne = TRUE;
}
LogMessage(&pClient->Message, nBytes);
b = ReadFile(pClient->hPipe,
&pClient->Message,
sizeof(pClient->Message),
&nBytes,
pClient);
if (!b && GetLastError() == ERROR_BROKEN_PIPE) {
CloseConnection(pClient);
}
}
}
return 0;
}
BOOL CreateWorkers(HANDLE hCompletionPort)
{
DWORD dwThread;
HANDLE hThread;
DWORD i;
SYSTEM_INFO SystemInfo;
GetSystemInfo(&SystemInfo);
for (i = 0; i < 2 * SystemInfo.dwNumberOfProcessors; i++) {
hThread = CreateThread(NULL, 0, WorkerThread, hCompletionPort, 0, &dwThread);
if (!hThread) {
MyErrExit("CreateThread WorkerThread");
// Unreachable: return FALSE;
}
CloseHandle(hThread);
}
return TRUE;
}
//////////////////////////////////////////////////////////////////////////////
//
BOOL WINAPI ControlHandler(DWORD dwCtrlType)
{
switch (dwCtrlType) {
case CTRL_C_EVENT:
case CTRL_BREAK_EVENT:
case CTRL_CLOSE_EVENT:
case CTRL_LOGOFF_EVENT:
case CTRL_SHUTDOWN_EVENT:
LogMessageV(SYELOG_SEVERITY_INFORMATION, "User requested stop.");
printf("\nSYELOGD: Closing connections.\n");
if (s_hOutFile != INVALID_HANDLE_VALUE) {
printf("Closing file.\n");
FlushFileBuffers(s_hOutFile);
CloseHandle(s_hOutFile);
s_hOutFile = INVALID_HANDLE_VALUE;
}
ExitProcess(0);
}
return FALSE;
}
DWORD main(int argc, char **argv)
{
HANDLE hCompletionPort;
BOOL fNeedHelp = FALSE;
GetSystemTimeAsFileTime((FILETIME *)&s_llStartTime);
SetConsoleCtrlHandler(ControlHandler, TRUE);
int arg = 1;
for (; arg < argc; arg++) {
if (argv[arg][0] == '-' || argv[arg][0] == '/') {
CHAR *argn = argv[arg] + 1;
CHAR *argp = argn;
while (*argp && *argp != ':') {
argp++;
}
if (*argp == ':') {
*argp++ = '\0';
}
switch (argn[0]) {
case 'd': // Delta time.
case 'D':
s_fDeltaTime = TRUE;
break;
case 'o': // Only one.
case 'O':
s_fExitAfterOne = TRUE;
break;
case 'q': // Quiet.
case 'Q':
s_fLogToScreen = FALSE;
break;
case '?': // Help.
fNeedHelp = TRUE;
break;
default:
fNeedHelp = TRUE;
printf("SYELOGD: Bad argument: %s:%s\n", argn, argp);
break;
}
}
else {
if (s_hOutFile != INVALID_HANDLE_VALUE) {
printf("SYELOGD: Error, more than one output file specified.\n\n");
fNeedHelp = TRUE;
break;
}
s_hOutFile = CreateFileA(argv[arg],
GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL |
FILE_FLAG_SEQUENTIAL_SCAN,
NULL);
if (s_hOutFile == INVALID_HANDLE_VALUE) {
printf("SYELOGD: Error opening output file: %s: %d\n\n",
argv[arg], GetLastError());
fNeedHelp = TRUE;
break;
}
else {
printf("SYELOGD: Logging to %s.\n", argv[arg]);
}
}
}
if (fNeedHelp) {
printf("Usage:\n"
" syelogd [options] {output_file}\n"
"Options:\n"
" /d List delta time in ms from previous event (not absolute time).\n"
" /o Exit after one client disconnects.\n"
" /q Disable event logging to screen (quiet mode).\n"
" /? Display this help message.\n"
"Summary:\n"
" If given, all events will be logged to the output file.\n"
"\n");
exit(1);
}
// Create the completion port.
hCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, NULL, 0);
if (hCompletionPort == NULL) {
MyErrExit("CreateIoCompletionPort");
}
// Create completion port worker threads.
//
CreateWorkers(hCompletionPort);
CreatePipeConnection(hCompletionPort);
printf("SYELOGD: Ready for clients. Press Ctrl-C to stop.\n");
while (argc) {
Sleep(10000);
}
SetConsoleCtrlHandler(ControlHandler, FALSE);
if (s_hOutFile != INVALID_HANDLE_VALUE) {
FlushFileBuffers(s_hOutFile);
CloseHandle(s_hOutFile);
s_hOutFile = INVALID_HANDLE_VALUE;
}
return 0;
}
//
//////////////////////////////////////////////////////////////////////////////

332
samples/talloc/Makefile Normal file
View File

@@ -0,0 +1,332 @@
##############################################################################
##
## Makefile for Detours Test Programs.
##
## Microsoft Research Detours Package
##
## Copyright (c) Microsoft Corporation. All rights reserved.
##
!include ..\common.mak
# This test tests the allocation algorithm. .dlls are carefully placed
# immediately adjacent to each other to force the algorithm to look more places.
# /noentry keeps the .dlls small, so they all fit at their bases
!if "$(DETOURS_TARGET_PROCESSOR:64=)" == "$(DETOURS_TARGET_PROCESSOR)"
# 32bit bases
DETOURS_TALLOC1=0x28000000
DETOURS_TALLOC2=0x38000000
DETOURS_TALLOC3=0x48050000
DETOURS_TALLOC4=0x58000000
DETOURS_TALLOC5=0x68000000
DETOURS_TALLOC6=0x68010000
DETOURS_TALLOC7=0x68020000
DETOURS_TALLOC8=0x68030000
DETOURS_TALLOC9=0x68040000
!else
# 64bit bases
DETOURS_TALLOC1=0x280000000
DETOURS_TALLOC2=0x380000000
DETOURS_TALLOC3=0x480050000
DETOURS_TALLOC4=0x580000000
DETOURS_TALLOC5=0x680000000
DETOURS_TALLOC6=0x680010000
DETOURS_TALLOC7=0x680020000
DETOURS_TALLOC8=0x680030000
DETOURS_TALLOC9=0x680040000
!endif
LIBS=$(LIBS) kernel32.lib psapi.lib
all: dirs \
$(BIND)\tdll1x$(DETOURS_BITS).dll \
$(BIND)\tdll2x$(DETOURS_BITS).dll \
$(BIND)\tdll3x$(DETOURS_BITS).dll \
$(BIND)\tdll4x$(DETOURS_BITS).dll \
$(BIND)\tdll5x$(DETOURS_BITS).dll \
$(BIND)\tdll6x$(DETOURS_BITS).dll \
$(BIND)\tdll7x$(DETOURS_BITS).dll \
$(BIND)\tdll8x$(DETOURS_BITS).dll \
$(BIND)\tdll9x$(DETOURS_BITS).dll \
$(BIND)\talloc.exe \
\
!IF $(DETOURS_SOURCE_BROWSING)==1
$(OBJD)\tdll1x$(DETOURS_BITS).bsc \
$(OBJD)\tdll2x$(DETOURS_BITS).bsc \
$(OBJD)\tdll3x$(DETOURS_BITS).bsc \
$(OBJD)\tdll4x$(DETOURS_BITS).bsc \
$(OBJD)\tdll5x$(DETOURS_BITS).bsc \
$(OBJD)\tdll6x$(DETOURS_BITS).bsc \
$(OBJD)\tdll7x$(DETOURS_BITS).bsc \
$(OBJD)\tdll8x$(DETOURS_BITS).bsc \
$(OBJD)\tdll9x$(DETOURS_BITS).bsc \
$(OBJD)\talloc.bsc \
!ENDIF
option
clean:
-del *~ 2>nul
-del $(BIND)\tdll1x* 2>nul
-del $(BIND)\tdll2x* 2>nul
-del $(BIND)\tdll3x* 2>nul
-del $(BIND)\tdll4x* 2>nul
-del $(BIND)\tdll5x* 2>nul
-del $(BIND)\tdll6x* 2>nul
-del $(BIND)\tdll7x* 2>nul
-del $(BIND)\tdll8x* 2>nul
-del $(BIND)\tdll9x* 2>nul
-del $(BIND)\talloc* 2>nul
-rmdir /q /s $(OBJD) 2>nul
realclean: clean
-rmdir /q /s $(OBJDS) 2>nul
dirs:
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
##############################################################################
$(OBJD)\talloc.obj : talloc.cpp
$(BIND)\talloc.exe : $(OBJD)\talloc.obj $(DEPS)
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\talloc.obj \
/link $(LINKFLAGS) $(LIBS) \
$(BIND)\tdll1x$(DETOURS_BITS).lib \
$(BIND)\tdll2x$(DETOURS_BITS).lib \
$(BIND)\tdll3x$(DETOURS_BITS).lib \
$(BIND)\tdll4x$(DETOURS_BITS).lib \
$(BIND)\tdll5x$(DETOURS_BITS).lib \
$(BIND)\tdll6x$(DETOURS_BITS).lib \
$(BIND)\tdll7x$(DETOURS_BITS).lib \
$(BIND)\tdll8x$(DETOURS_BITS).lib \
$(BIND)\tdll9x$(DETOURS_BITS).lib \
/subsystem:console /entry:WinMainCRTStartup
$(OBJD)\talloc.bsc : $(OBJD)\talloc.obj
bscmake /v /n /o $@ $(OBJD)\talloc.sbr
$(OBJD)\tdll1x.obj : tdll1x.cpp
# /noentry keeps the .dlls small, so they all fit at their bases
$(BIND)\tdll1x$(DETOURS_BITS).dll : $(OBJD)\tdll1x.obj $(DEPS)
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb \
$(OBJD)\tdll1x.obj /LD \
/link $(LINKFLAGS:/profile=/fixed) $(LIBS) \
/subsystem:windows \
/noentry \
/base:$(DETOURS_TALLOC1)
$(OBJD)\tdll1x$(DETOURS_BITS).bsc : $(OBJD)\tdll1x.obj
bscmake /v /n /o $@ $(OBJD)\tdll1x.sbr
$(OBJD)\tdll2x.obj : tdll2x.cpp
# /noentry keeps the .dlls small, so they all fit at their bases
$(BIND)\tdll2x$(DETOURS_BITS).dll : $(OBJD)\tdll2x.obj $(DEPS)
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb \
$(OBJD)\tdll2x.obj /LD \
/link $(LINKFLAGS:/profile=/fixed) $(LIBS) \
/subsystem:console \
/noentry \
/base:$(DETOURS_TALLOC2)
$(OBJD)\tdll2x$(DETOURS_BITS).bsc : $(OBJD)\tdll2x.obj
bscmake /v /n /o $@ $(OBJD)\tdll2x.sbr
$(OBJD)\tdll3x.obj : tdll3x.cpp
# /noentry keeps the .dlls small, so they all fit at their bases
$(BIND)\tdll3x$(DETOURS_BITS).dll : $(OBJD)\tdll3x.obj $(DEPS)
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb \
$(OBJD)\tdll3x.obj /LD \
/link $(LINKFLAGS:/profile=/fixed) $(LIBS) \
/subsystem:console \
/noentry \
/base:$(DETOURS_TALLOC3)
$(OBJD)\tdll3x$(DETOURS_BITS).bsc : $(OBJD)\tdll3x.obj
bscmake /v /n /o $@ $(OBJD)\tdll3x.sbr
$(OBJD)\tdll4x.obj : tdll4x.cpp
# /noentry keeps the .dlls small, so they all fit at their bases
$(BIND)\tdll4x$(DETOURS_BITS).dll : $(OBJD)\tdll4x.obj $(DEPS)
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb \
$(OBJD)\tdll4x.obj /LD \
/link $(LINKFLAGS:/profile=/fixed) $(LIBS) \
/subsystem:console \
/noentry \
/base:$(DETOURS_TALLOC4)
$(OBJD)\tdll4x$(DETOURS_BITS).bsc : $(OBJD)\tdll4x.obj
bscmake /v /n /o $@ $(OBJD)\tdll4x.sbr
$(OBJD)\tdll5x.obj : tdll5x.cpp
# /noentry keeps the .dlls small, so they all fit at their bases
$(BIND)\tdll5x$(DETOURS_BITS).dll : $(OBJD)\tdll5x.obj $(DEPS)
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb \
$(OBJD)\tdll5x.obj /LD \
/link $(LINKFLAGS:/profile=/fixed) $(LIBS) \
/subsystem:console \
/noentry \
/base:$(DETOURS_TALLOC5)
$(OBJD)\tdll5x$(DETOURS_BITS).bsc : $(OBJD)\tdll5x.obj
bscmake /v /n /o $@ $(OBJD)\tdll5x.sbr
$(OBJD)\tdll6x.obj : tdll6x.cpp
# /noentry keeps the .dlls small, so they all fit at their bases
$(BIND)\tdll6x$(DETOURS_BITS).dll : $(OBJD)\tdll6x.obj $(DEPS)
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb \
$(OBJD)\tdll6x.obj /LD \
/link $(LINKFLAGS:/profile=/fixed) $(LIBS) \
/subsystem:console \
/noentry \
/base:$(DETOURS_TALLOC6)
$(OBJD)\tdll6x$(DETOURS_BITS).bsc : $(OBJD)\tdll6x.obj
bscmake /v /n /o $@ $(OBJD)\tdll6x.sbr
$(OBJD)\tdll7x.obj : tdll7x.cpp
# /noentry keeps the .dlls small, so they all fit at their bases
$(BIND)\tdll7x$(DETOURS_BITS).dll : $(OBJD)\tdll7x.obj $(DEPS)
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb \
$(OBJD)\tdll7x.obj /LD \
/link $(LINKFLAGS:/profile=/fixed) $(LIBS) \
/subsystem:console \
/noentry \
/base:$(DETOURS_TALLOC7)
$(OBJD)\tdll7x$(DETOURS_BITS).bsc : $(OBJD)\tdll7x.obj
bscmake /v /n /o $@ $(OBJD)\tdll7x.sbr
$(OBJD)\tdll8x.obj : tdll8x.cpp
# /noentry keeps the .dlls small, so they all fit at their bases
$(BIND)\tdll8x$(DETOURS_BITS).dll : $(OBJD)\tdll8x.obj $(DEPS)
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb \
$(OBJD)\tdll8x.obj /LD \
/link $(LINKFLAGS:/profile=/fixed) $(LIBS) \
/subsystem:console \
/noentry \
/base:$(DETOURS_TALLOC8)
$(OBJD)\tdll8x$(DETOURS_BITS).bsc : $(OBJD)\tdll8x.obj
bscmake /v /n /o $@ $(OBJD)\tdll8x.sbr
$(OBJD)\tdll9x.obj : tdll9x.cpp
# /noentry keeps the .dlls small, so they all fit at their bases
$(BIND)\tdll9x$(DETOURS_BITS).dll : $(OBJD)\tdll9x.obj $(DEPS)
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb \
$(OBJD)\tdll9x.obj /LD \
/link $(LINKFLAGS:/profile=/fixed) $(LIBS) \
/subsystem:console \
/noentry \
/base:$(DETOURS_TALLOC9)
$(OBJD)\tdll9x$(DETOURS_BITS).bsc : $(OBJD)\tdll9x.obj
bscmake /v /n /o $@ $(OBJD)\tdll9x.sbr
############################################### Install non-bit-size binaries.
!IF "$(DETOURS_OPTION_PROCESSOR)" != ""
$(OPTD)\tdll1x$(DETOURS_OPTION_BITS).dll:
$(OPTD)\tdll1x$(DETOURS_OPTION_BITS).pdb:
$(OPTD)\tdll2x$(DETOURS_OPTION_BITS).dll:
$(OPTD)\tdll2x$(DETOURS_OPTION_BITS).pdb:
$(OPTD)\tdll3x$(DETOURS_OPTION_BITS).dll:
$(OPTD)\tdll3x$(DETOURS_OPTION_BITS).pdb:
$(OPTD)\tdll4x$(DETOURS_OPTION_BITS).dll:
$(OPTD)\tdll4x$(DETOURS_OPTION_BITS).pdb:
$(OPTD)\tdll5x$(DETOURS_OPTION_BITS).dll:
$(OPTD)\tdll5x$(DETOURS_OPTION_BITS).pdb:
$(OPTD)\tdll6x$(DETOURS_OPTION_BITS).dll:
$(OPTD)\tdll6x$(DETOURS_OPTION_BITS).pdb:
$(OPTD)\tdll7x$(DETOURS_OPTION_BITS).dll:
$(OPTD)\tdll7x$(DETOURS_OPTION_BITS).pdb:
$(OPTD)\tdll8x$(DETOURS_OPTION_BITS).dll:
$(OPTD)\tdll8x$(DETOURS_OPTION_BITS).pdb:
$(OPTD)\tdll9x$(DETOURS_OPTION_BITS).dll:
$(OPTD)\tdll9x$(DETOURS_OPTION_BITS).pdb:
$(BIND)\tdll1x$(DETOURS_OPTION_BITS).dll : $(OPTD)\tdll1x$(DETOURS_OPTION_BITS).dll
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
$(BIND)\tdll1x$(DETOURS_OPTION_BITS).pdb : $(OPTD)\tdll1x$(DETOURS_OPTION_BITS).pdb
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
$(BIND)\tdll2x$(DETOURS_OPTION_BITS).dll : $(OPTD)\tdll2x$(DETOURS_OPTION_BITS).dll
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
$(BIND)\tdll2x$(DETOURS_OPTION_BITS).pdb : $(OPTD)\tdll2x$(DETOURS_OPTION_BITS).pdb
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
$(BIND)\tdll3x$(DETOURS_OPTION_BITS).dll : $(OPTD)\tdll3x$(DETOURS_OPTION_BITS).dll
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
$(BIND)\tdll3x$(DETOURS_OPTION_BITS).pdb : $(OPTD)\tdll3x$(DETOURS_OPTION_BITS).pdb
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
$(BIND)\tdll4x$(DETOURS_OPTION_BITS).dll : $(OPTD)\tdll4x$(DETOURS_OPTION_BITS).dll
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
$(BIND)\tdll4x$(DETOURS_OPTION_BITS).pdb : $(OPTD)\tdll4x$(DETOURS_OPTION_BITS).pdb
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
$(BIND)\tdll5x$(DETOURS_OPTION_BITS).dll : $(OPTD)\tdll5x$(DETOURS_OPTION_BITS).dll
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
$(BIND)\tdll5x$(DETOURS_OPTION_BITS).pdb : $(OPTD)\tdll5x$(DETOURS_OPTION_BITS).pdb
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
$(BIND)\tdll6x$(DETOURS_OPTION_BITS).dll : $(OPTD)\tdll6x$(DETOURS_OPTION_BITS).dll
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
$(BIND)\tdll6x$(DETOURS_OPTION_BITS).pdb : $(OPTD)\tdll6x$(DETOURS_OPTION_BITS).pdb
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
$(BIND)\tdll7x$(DETOURS_OPTION_BITS).dll : $(OPTD)\tdll7x$(DETOURS_OPTION_BITS).dll
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
$(BIND)\tdll7x$(DETOURS_OPTION_BITS).pdb : $(OPTD)\tdll7x$(DETOURS_OPTION_BITS).pdb
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
$(BIND)\tdll8x$(DETOURS_OPTION_BITS).dll : $(OPTD)\tdll8x$(DETOURS_OPTION_BITS).dll
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
$(BIND)\tdll8x$(DETOURS_OPTION_BITS).pdb : $(OPTD)\tdll8x$(DETOURS_OPTION_BITS).pdb
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
$(BIND)\tdll9x$(DETOURS_OPTION_BITS).dll : $(OPTD)\tdll9x$(DETOURS_OPTION_BITS).dll
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
$(BIND)\tdll9x$(DETOURS_OPTION_BITS).pdb : $(OPTD)\tdll9x$(DETOURS_OPTION_BITS).pdb
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
option: \
$(BIND)\tdll1x$(DETOURS_OPTION_BITS).dll \
$(BIND)\tdll1x$(DETOURS_OPTION_BITS).pdb \
$(BIND)\tdll2x$(DETOURS_OPTION_BITS).dll \
$(BIND)\tdll2x$(DETOURS_OPTION_BITS).pdb \
$(BIND)\tdll3x$(DETOURS_OPTION_BITS).dll \
$(BIND)\tdll3x$(DETOURS_OPTION_BITS).pdb \
$(BIND)\tdll4x$(DETOURS_OPTION_BITS).dll \
$(BIND)\tdll4x$(DETOURS_OPTION_BITS).pdb \
$(BIND)\tdll5x$(DETOURS_OPTION_BITS).dll \
$(BIND)\tdll5x$(DETOURS_OPTION_BITS).pdb \
$(BIND)\tdll6x$(DETOURS_OPTION_BITS).dll \
$(BIND)\tdll6x$(DETOURS_OPTION_BITS).pdb \
$(BIND)\tdll7x$(DETOURS_OPTION_BITS).dll \
$(BIND)\tdll7x$(DETOURS_OPTION_BITS).pdb \
$(BIND)\tdll8x$(DETOURS_OPTION_BITS).dll \
$(BIND)\tdll8x$(DETOURS_OPTION_BITS).pdb \
$(BIND)\tdll9x$(DETOURS_OPTION_BITS).dll \
$(BIND)\tdll9x$(DETOURS_OPTION_BITS).pdb \
!ELSE
option:
!ENDIF
##############################################################################
test: all
$(BIND)\talloc.exe
################################################################# End of File.

View File

@@ -0,0 +1,70 @@
talloc.exe: Detoured functions.
Address Size: Typ Sta Prot Ini : Contents
------------ ------------: --- --- ---- --- : -----------------
Exe: 13f660000
100000000 3f660000: fre --- :
13f660000 2000: img com r-- rcx : TALLOC.EXE
13f6ce000 100802000: fre --- :
Dll1: 280000000
200000000 3fed0000: fre --- :
23fed0000 10000: pri com r-x rwx :
23fee0000 2000: pri res --- :
23fee2000 e000: fre --- :
23fef0000 10000: pri res --- :
23ff00000 100000: pri res --- :
240000000 40000000: pri res --- :
280000000 2000: img com r-- rcx : TDLL1X64.DLL
280028000 8000: fre --- :
280030000 7ffd0000: pri res --- :
Dll2: 380000000
300000000 80000000: pri res --- :
380000000 2000: img com r-- rcx : TDLL2X64.DLL
380028000 8000: fre --- :
380030000 40000000: pri res --- :
3c0030000 100000: pri res --- :
3c0130000 10000: pri res --- :
3c0140000 2000: pri res --- :
3c0142000 e000: fre --- :
3c0150000 10000: pri com r-x rwx :
3c0160000 3fea0000: fre --- :
Dll3: 480000000
400000000 40000000: pri res --- :
440000000 100000: pri res --- :
440100000 10000: pri res --- :
440110000 2000: pri res --- :
440112000 e000: fre --- :
440120000 10000: pri com r-x rwx :
440130000 3fed0000: fre --- :
480000000 2000: img com r-- rcx : TDLL3X64.DLL
480028000 8000: fre --- :
480030000 7ffd0000: pri res --- :
Dll4: 580000000
500000000 80000000: pri res --- :
580000000 2000: img com r-- rcx : TDLL4X64.DLL
580028000 3fea8000: fre --- :
5bfed0000 10000: pri com r-x rwx :
5bfee0000 2000: pri res --- :
5bfee2000 e000: fre --- :
5bfef0000 10000: pri res --- :
5bff00000 100000: pri res --- :
5c0000000 40000000: pri res --- :
Dll5: 680000000
600000000 f0000: fre --- :
6000f0000 10000: pri com r-x rwx :
600100000 7ff00000: pri res --- :
680000000 2000: img com r-- rcx : TDLL5X64.DLL
680028000 18000: fre --- :
680040000 2000: img com r-- rcx : TDLL6X64.DLL
680068000 18000: fre --- :
680080000 2000: img com r-- rcx : TDLL7X64.DLL
6800a8000 18000: fre --- :
6800c0000 2000: img com r-- rcx : TDLL8X64.DLL
6800e8000 18000: fre --- :
680100000 2000: img com r-- rcx : TDLL9X64.DLL
680128000 8000: fre --- :
680130000 7fe00000: pri res --- :
6fff30000 10000: pri com r-x rwx :
6fff40000 6f3fbdd0000: fre --- :
talloc.exe: 1 calls to Dll1Function

View File

@@ -0,0 +1,66 @@
talloc.exe: Detoured functions.
Address Size: Typ Sta Prot Ini : Contents
------------ ------------: --- --- ---- --- : -----------------
Exe: 13f7f0000
100000000 3f7f0000: fre --- :
13f7f0000 1000: img com r-- rcx : TALLOC.EXE
13f81e000 1006b2000: fre --- :
Dll1: 280000000
200000000 3fed0000: fre --- :
23fed0000 10000: pri com r-x rwx :
23fee0000 1000: pri res --- :
23fee1000 f000: fre --- :
23fef0000 10000: pri res --- :
23ff00000 100000: pri res --- :
240000000 40000000: pri res --- :
280000000 1000: img com r-- rcx : TDLL1X64.DLL
280010000 7fff0000: pri res --- :
Dll2: 380000000
300000000 80000000: pri res --- :
380000000 1000: img com r-- rcx : TDLL2X64.DLL
380010000 40000000: pri res --- :
3c0010000 100000: pri res --- :
3c0110000 10000: pri res --- :
3c0120000 1000: pri res --- :
3c0121000 f000: fre --- :
3c0130000 10000: pri com r-x rwx :
3c0140000 3fec0000: fre --- :
Dll3: 480000000
400000000 40000000: pri res --- :
440000000 100000: pri res --- :
440100000 10000: pri res --- :
440110000 1000: pri res --- :
440111000 f000: fre --- :
440120000 10000: pri com r-x rwx :
440130000 3fed0000: fre --- :
480000000 1000: img com r-- rcx : TDLL3X64.DLL
480010000 7fff0000: pri res --- :
Dll4: 580000000
500000000 80000000: pri res --- :
580000000 1000: img com r-- rcx : TDLL4X64.DLL
580010000 3fec0000: fre --- :
5bfed0000 10000: pri com r-x rwx :
5bfee0000 1000: pri res --- :
5bfee1000 f000: fre --- :
5bfef0000 10000: pri res --- :
5bff00000 100000: pri res --- :
5c0000000 40000000: pri res --- :
Dll5: 680000000
600000000 f0000: fre --- :
6000f0000 10000: pri com r-x rwx :
600100000 7ff00000: pri res --- :
680000000 1000: img com r-- rcx : TDLL5X64.DLL
680010000 30000: fre --- :
680040000 1000: img com r-- rcx : TDLL6X64.DLL
680050000 30000: fre --- :
680080000 1000: img com r-- rcx : TDLL7X64.DLL
680090000 30000: fre --- :
6800c0000 1000: img com r-- rcx : TDLL8X64.DLL
6800d0000 30000: fre --- :
680100000 1000: img com r-- rcx : TDLL9X64.DLL
680110000 7fe00000: pri res --- :
6fff10000 10000: pri com r-x rwx :
6fff20000 7f7fdf70000: fre --- :
talloc.exe: 1 calls to Dll1Function

541
samples/talloc/talloc.cpp Normal file
View File

@@ -0,0 +1,541 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detours Test Program (talloc.cpp of talloc.exe)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#define PSAPI_VERSION 2
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#pragma warning(push)
#if _MSC_VER > 1400
#pragma warning(disable:6102 6103) // /analyze warnings
#endif
#include <strsafe.h>
#pragma warning(pop)
#include <psapi.h>
#include <detours.h>
//////////////////////////////////////////////////////////////////////////////
void TypeToString(DWORD Type, char *pszBuffer, size_t cBuffer)
{
if (Type == MEM_IMAGE) {
StringCchPrintfA(pszBuffer, cBuffer, "img");
}
else if (Type == MEM_MAPPED) {
StringCchPrintfA(pszBuffer, cBuffer, "map");
}
else if (Type == MEM_PRIVATE) {
StringCchPrintfA(pszBuffer, cBuffer, "pri");
}
else if (Type == 0) {
StringCchPrintfA(pszBuffer, cBuffer, " ");
}
else {
StringCchPrintfA(pszBuffer, cBuffer, "%x", Type);
}
}
void StateToString(DWORD State, char *pszBuffer, size_t cBuffer)
{
if (State == MEM_COMMIT) {
StringCchPrintfA(pszBuffer, cBuffer, "com");
}
else if (State == MEM_FREE) {
StringCchPrintfA(pszBuffer, cBuffer, "fre");
}
else if (State == MEM_RESERVE) {
StringCchPrintfA(pszBuffer, cBuffer, "res");
}
else {
StringCchPrintfA(pszBuffer, cBuffer, "%x", State);
}
}
void ProtectToString(DWORD Protect, char *pszBuffer, size_t cBuffer)
{
if (Protect == 0) {
StringCchPrintfA(pszBuffer, cBuffer, "");
}
else if (Protect == PAGE_EXECUTE) {
StringCchPrintfA(pszBuffer, cBuffer, "--x");
}
else if (Protect == PAGE_EXECUTE_READ) {
StringCchPrintfA(pszBuffer, cBuffer, "r-x");
}
else if (Protect == PAGE_EXECUTE_READWRITE) {
StringCchPrintfA(pszBuffer, cBuffer, "rwx");
}
else if (Protect == PAGE_EXECUTE_WRITECOPY) {
StringCchPrintfA(pszBuffer, cBuffer, "rcx");
}
else if (Protect == PAGE_NOACCESS) {
StringCchPrintfA(pszBuffer, cBuffer, "---");
}
else if (Protect == PAGE_READONLY) {
StringCchPrintfA(pszBuffer, cBuffer, "r--");
}
else if (Protect == PAGE_READWRITE) {
StringCchPrintfA(pszBuffer, cBuffer, "rw-");
}
else if (Protect == PAGE_WRITECOPY) {
StringCchPrintfA(pszBuffer, cBuffer, "rc-");
}
else if (Protect == (PAGE_GUARD | PAGE_EXECUTE)) {
StringCchPrintfA(pszBuffer, cBuffer, "g--x");
}
else if (Protect == (PAGE_GUARD | PAGE_EXECUTE_READ)) {
StringCchPrintfA(pszBuffer, cBuffer, "gr-x");
}
else if (Protect == (PAGE_GUARD | PAGE_EXECUTE_READWRITE)) {
StringCchPrintfA(pszBuffer, cBuffer, "grwx");
}
else if (Protect == (PAGE_GUARD | PAGE_EXECUTE_WRITECOPY)) {
StringCchPrintfA(pszBuffer, cBuffer, "grcx");
}
else if (Protect == (PAGE_GUARD | PAGE_NOACCESS)) {
StringCchPrintfA(pszBuffer, cBuffer, "g---");
}
else if (Protect == (PAGE_GUARD | PAGE_READONLY)) {
StringCchPrintfA(pszBuffer, cBuffer, "gr--");
}
else if (Protect == (PAGE_GUARD | PAGE_READWRITE)) {
StringCchPrintfA(pszBuffer, cBuffer, "grw-");
}
else if (Protect == (PAGE_GUARD | PAGE_WRITECOPY)) {
StringCchPrintfA(pszBuffer, cBuffer, "grc-");
}
else {
StringCchPrintfA(pszBuffer, cBuffer, "%x", Protect);
}
}
ULONG PadToPage(ULONG Size)
{
return (Size & 0xfff)
? Size + 0x1000 - (Size & 0xfff)
: Size;
}
size_t NextAt(size_t start)
{
size_t next = start;
for (;;) {
MEMORY_BASIC_INFORMATION mbi;
ZeroMemory(&mbi, sizeof(mbi));
if (VirtualQuery((PVOID)next, &mbi, sizeof(mbi)) == 0) {
break;
}
if ((mbi.RegionSize & 0xfff) == 0xfff) {
break;
}
if ((size_t)mbi.AllocationBase != start) {
break;
}
next = (size_t)mbi.BaseAddress + mbi.RegionSize;
}
return next;
}
size_t RoundUpRegion(size_t value)
{
size_t diff = value & 0xffff;
return (diff != 0) ? value + 0x10000 - diff : value;
}
VOID DumpProcessHeaders()
{
printf(" %12s %12s: %3s %3s %4s %3s : %8s\n",
"Address", "Size", "Typ", "Sta", "Prot", "Ini", "Contents");
printf(" %12s %12s: %3s %3s %4s %3s : %8s\n",
"------------", "------------", "---", "---", "----", "---", "-----------------");
}
BOOL DumpProcess(UINT64 lo64, UINT64 hi64)
{
#ifdef _WIN64
ULONG_PTR lo = lo64;
ULONG_PTR hi = hi64;
#else
ULONG_PTR lo = (size_t)(lo64 >> 4);
ULONG_PTR hi = (size_t)(hi64 >> 4);
#endif
size_t base;
size_t next;
MEMORY_BASIC_INFORMATION mbi;
for (next = lo; next < hi;) {
base = next;
ZeroMemory(&mbi, sizeof(mbi));
if (VirtualQuery((PVOID)base, &mbi, sizeof(mbi)) == 0) {
break;
}
if ((mbi.RegionSize & 0xfff) == 0xfff) {
break;
}
if ((size_t)mbi.BaseAddress < lo) {
base = (size_t)mbi.BaseAddress;
}
size_t size = ((size_t)mbi.BaseAddress + mbi.RegionSize) - base;
next = (size_t)mbi.BaseAddress + mbi.RegionSize;
CHAR szType[16];
TypeToString(mbi.Type, szType, ARRAYSIZE(szType));
CHAR szState[16];
StateToString(mbi.State, szState, ARRAYSIZE(szState));
CHAR szProtect[16];
ProtectToString(mbi.Protect, szProtect, ARRAYSIZE(szProtect));
CHAR szAllocProtect[16];
ProtectToString(mbi.AllocationProtect, szAllocProtect, ARRAYSIZE(szAllocProtect));
CHAR szFile[MAX_PATH];
szFile[0] = '\0';
DWORD cb = 0;
PCHAR pszFile = szFile;
if (base == (size_t)mbi.AllocationBase) {
next = NextAt(base);
cb = GetMappedFileNameA(GetCurrentProcess(),
mbi.AllocationBase, szFile, ARRAYSIZE(szFile));
if (cb > 0) {
for (DWORD c = 0; c < cb; c++) {
szFile[c] = (char)toupper(szFile[c]);
}
szFile[cb] = '\0';
}
else {
szFile[0] = '\0';
}
if ((pszFile = strrchr(szFile, '\\')) == NULL) {
pszFile = szFile;
}
else {
pszFile++;
}
}
printf("%c %12Ix %12Ix: %3s %3s %4s %3s : %s\n",
" *"[base == (size_t)mbi.AllocationBase],
base,
size,
szType,
szState,
szProtect,
szAllocProtect,
pszFile);
}
return TRUE;
}
//////////////////////////////////////////////////////////////////////////////
__declspec(dllimport) DWORD WINAPI Dll1Function(DWORD Value);
__declspec(dllimport) DWORD WINAPI Dll2Function(DWORD Value);
__declspec(dllimport) DWORD WINAPI Dll3Function(DWORD Value);
__declspec(dllimport) DWORD WINAPI Dll4Function(DWORD Value);
__declspec(dllimport) DWORD WINAPI Dll5Function(DWORD Value);
__declspec(dllimport) DWORD WINAPI Dll6Function(DWORD Value);
__declspec(dllimport) DWORD WINAPI Dll7Function(DWORD Value);
__declspec(dllimport) DWORD WINAPI Dll8Function(DWORD Value);
__declspec(dllimport) DWORD WINAPI Dll9Function(DWORD Value);
static LONG dwCountDll1 = 0;
static LONG dwCountDll2 = 0;
static LONG dwCountDll3 = 0;
static LONG dwCountDll4 = 0;
static LONG dwCountDll5 = 0;
static LONG dwCountDll6 = 0;
static LONG dwCountDll7 = 0;
static LONG dwCountDll8 = 0;
static LONG dwCountDll9 = 0;
static DWORD (WINAPI * TrueDll1Function)(DWORD Value) = Dll1Function;
static DWORD (WINAPI * TrueDll2Function)(DWORD Value) = Dll2Function;
static DWORD (WINAPI * TrueDll3Function)(DWORD Value) = Dll3Function;
static DWORD (WINAPI * TrueDll4Function)(DWORD Value) = Dll4Function;
static DWORD (WINAPI * TrueDll5Function)(DWORD Value) = Dll5Function;
static DWORD (WINAPI * TrueDll6Function)(DWORD Value) = Dll6Function;
static DWORD (WINAPI * TrueDll7Function)(DWORD Value) = Dll7Function;
static DWORD (WINAPI * TrueDll8Function)(DWORD Value) = Dll8Function;
static DWORD (WINAPI * TrueDll9Function)(DWORD Value) = Dll9Function;
DWORD WINAPI MineDll1Function(DWORD Value)
{
Value = TrueDll1Function(Value);
InterlockedIncrement(&dwCountDll1);
return Value;
}
DWORD WINAPI MineDll2Function(DWORD Value)
{
Value = TrueDll2Function(Value);
InterlockedIncrement(&dwCountDll2);
return Value;
}
DWORD WINAPI MineDll3Function(DWORD Value)
{
Value = TrueDll3Function(Value);
InterlockedIncrement(&dwCountDll3);
return Value;
}
DWORD WINAPI MineDll4Function(DWORD Value)
{
Value = TrueDll4Function(Value);
InterlockedIncrement(&dwCountDll4);
return Value;
}
DWORD WINAPI MineDll5Function(DWORD Value)
{
Value = TrueDll5Function(Value);
InterlockedIncrement(&dwCountDll5);
return Value;
}
DWORD WINAPI MineDll6Function(DWORD Value)
{
Value = TrueDll6Function(Value);
InterlockedIncrement(&dwCountDll6);
return Value;
}
DWORD WINAPI MineDll7Function(DWORD Value)
{
Value = TrueDll7Function(Value);
InterlockedIncrement(&dwCountDll7);
return Value;
}
DWORD WINAPI MineDll8Function(DWORD Value)
{
Value = TrueDll8Function(Value);
InterlockedIncrement(&dwCountDll8);
return Value;
}
DWORD WINAPI MineDll9Function(DWORD Value)
{
Value = TrueDll9Function(Value);
InterlockedIncrement(&dwCountDll9);
return Value;
}
void Reserve(ULONG_PTR addr, ULONG_PTR size)
{
PVOID mem = VirtualAlloc((PVOID)addr, size, MEM_RESERVE, PAGE_NOACCESS);
if (mem != (PVOID)addr) {
printf("*** Reservation failed: %p != %p\n", mem, (PVOID)addr);
}
}
int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hprev, LPSTR lpszCmdLine, int nCmdShow)
{
(void)hinst;
(void)hprev;
(void)lpszCmdLine;
(void)nCmdShow;
DWORD error = NO_ERROR;
size_t Dll1 = (size_t)LoadLibraryA("tdll1x" DETOURS_STRINGIFY(DETOURS_BITS) ".dll");
size_t Dll2 = (size_t)LoadLibraryA("tdll2x" DETOURS_STRINGIFY(DETOURS_BITS) ".dll");
size_t Dll3 = (size_t)LoadLibraryA("tdll3x" DETOURS_STRINGIFY(DETOURS_BITS) ".dll");
size_t Dll4 = (size_t)LoadLibraryA("tdll4x" DETOURS_STRINGIFY(DETOURS_BITS) ".dll");
size_t Dll5 = (size_t)LoadLibraryA("tdll5x" DETOURS_STRINGIFY(DETOURS_BITS) ".dll");
size_t Dll6 = (size_t)LoadLibraryA("tdll6x" DETOURS_STRINGIFY(DETOURS_BITS) ".dll");
size_t Dll7 = (size_t)LoadLibraryA("tdll7x" DETOURS_STRINGIFY(DETOURS_BITS) ".dll");
size_t Dll8 = (size_t)LoadLibraryA("tdll8x" DETOURS_STRINGIFY(DETOURS_BITS) ".dll");
size_t Dll9 = (size_t)LoadLibraryA("tdll9x" DETOURS_STRINGIFY(DETOURS_BITS) ".dll");
size_t DllEnd = RoundUpRegion(NextAt(Dll1));
ULONG_PTR DllSize = (DllEnd - Dll1);
(void)Dll6;
(void)Dll7;
(void)Dll8;
// Force allocation below moving lower.
Reserve(Dll1 - 0x40000000, 0x40000000);
Reserve(Dll1 - 0x40100000, 0x00100000);
Reserve(Dll1 - 0x40110000, 0x00010000);
Reserve(Dll1 - 0x40120000, 0x00001000);
Reserve(Dll1 + DllSize, 0x80000000 - DllSize);
// Force allocation above moving higher.
Reserve(Dll2 - 0x80000000, 0x80000000);
Reserve(Dll2 + DllSize, 0x40000000);
Reserve(Dll2 + 0x40000000 + DllSize, 0x00100000);
Reserve(Dll2 + 0x40100000 + DllSize, 0x00010000);
Reserve(Dll2 + 0x40110000 + DllSize, 0x00001000);
// Force allocation below moving higher.
Reserve(Dll3 - 0x80000000, 0x40000000);
Reserve(Dll3 - 0x40000000, 0x00100000);
Reserve(Dll3 - 0x3ff00000, 0x00010000);
Reserve(Dll3 - 0x3fef0000, 0x00001000);
Reserve(Dll3 + DllSize, 0x80000000 - DllSize);
// Force allocation above moving lower.
Reserve(Dll4 - 0x80000000, 0x80000000);
Reserve(Dll4 + 0x40000000, 0x40000000);
Reserve(Dll4 + 0x3ff00000, 0x00100000);
Reserve(Dll4 + 0x3fef0000, 0x00010000);
Reserve(Dll4 + 0x3fee0000, 0x00001000);
// Force allocation above and below.
Reserve(Dll5 - 0x7ff00000, 0x7ff00000);
Reserve(Dll9 + DllSize, 0x7fe00000);
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)TrueDll1Function, MineDll1Function);
error = DetourTransactionCommit();
if (error != NO_ERROR) {
failed:
printf("talloc.exe: Error detouring functions: %d\n", error);
exit(1);
}
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)TrueDll2Function, MineDll2Function);
error = DetourTransactionCommit();
if (error != NO_ERROR) {
goto failed;
}
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)TrueDll3Function, MineDll3Function);
error = DetourTransactionCommit();
if (error != NO_ERROR) {
goto failed;
}
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)TrueDll4Function, MineDll4Function);
error = DetourTransactionCommit();
if (error != NO_ERROR) {
goto failed;
}
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)TrueDll5Function, MineDll5Function);
error = DetourTransactionCommit();
if (error != NO_ERROR) {
goto failed;
}
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)TrueDll6Function, MineDll6Function);
error = DetourTransactionCommit();
if (error != NO_ERROR) {
goto failed;
}
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)TrueDll7Function, MineDll7Function);
error = DetourTransactionCommit();
if (error != NO_ERROR) {
goto failed;
}
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)TrueDll8Function, MineDll8Function);
error = DetourTransactionCommit();
if (error != NO_ERROR) {
goto failed;
}
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)TrueDll9Function, MineDll9Function);
error = DetourTransactionCommit();
if (error != NO_ERROR) {
goto failed;
}
printf("talloc.exe: Detoured functions.\n");
printf("\n");
DumpProcessHeaders();
printf("%-47s %17Ix\n", "Exe:", (size_t)GetModuleHandleW(NULL));
DumpProcess(0x100000000, 0x200000000);
printf("%-47s %17Ix\n", "Dll1:", Dll1);
DumpProcess(0x200000000, 0x300000000);
printf("%-47s %17Ix\n", "Dll2:", Dll2);
DumpProcess(0x300000000, 0x400000000);
printf("%-47s %17Ix\n", "Dll3:", Dll3);
DumpProcess(0x400000000, 0x500000000);
printf("%-47s %17Ix\n", "Dll4:", Dll4);
DumpProcess(0x500000000, 0x600000000);
printf("%-47s %17Ix\n", "Dll5:", Dll5);
DumpProcess(0x600000000, 0x700000000);
fflush(stdout);
Dll1Function(1);
Dll2Function(2);
Dll2Function(3);
Dll3Function(4);
Dll3Function(5);
Dll3Function(6);
Dll4Function(7);
Dll5Function(8);
Dll6Function(9);
Dll7Function(10);
Dll8Function(10);
Dll9Function(10);
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)TrueDll1Function, MineDll1Function);
DetourDetach(&(PVOID&)TrueDll2Function, MineDll2Function);
DetourDetach(&(PVOID&)TrueDll3Function, MineDll3Function);
DetourDetach(&(PVOID&)TrueDll4Function, MineDll4Function);
DetourDetach(&(PVOID&)TrueDll5Function, MineDll5Function);
DetourDetach(&(PVOID&)TrueDll6Function, MineDll6Function);
DetourDetach(&(PVOID&)TrueDll7Function, MineDll7Function);
DetourDetach(&(PVOID&)TrueDll8Function, MineDll8Function);
DetourDetach(&(PVOID&)TrueDll9Function, MineDll9Function);
error = DetourTransactionCommit();
if (error != NO_ERROR) {
goto failed;
}
printf("\n");
printf("talloc.exe: %d calls to Dll1Function\n", dwCountDll1);
fflush(stdout);
return 0;
}
//
///////////////////////////////////////////////////////////////// End of File.

17
samples/talloc/tdll1x.cpp Normal file
View File

@@ -0,0 +1,17 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detours Test Program (tdll1x.cpp of talloc.exe/tdll1x.dll)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//////////////////////////////////////////////////////////////////// DLL Stuff
//
__declspec(dllexport) unsigned long __stdcall Dll1Function(unsigned long Value)
{
return Value + 1;
}
///////////////////////////////////////////////////////////////// End of File.

17
samples/talloc/tdll2x.cpp Normal file
View File

@@ -0,0 +1,17 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detours Test Program (tdll2x.cpp of talloc.exe/tdll2x.dll)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//////////////////////////////////////////////////////////////////// DLL Stuff
//
__declspec(dllexport) unsigned long __stdcall Dll2Function(unsigned long Value)
{
return Value + 1;
}
///////////////////////////////////////////////////////////////// End of File.

Some files were not shown because too many files have changed in this diff Show More