mirror of
https://github.com/WinDurango/Detours.git
synced 2026-01-31 00:55:20 +01:00
Initial fork of Detours 4.0 from Detours 3.0 archive.
This commit is contained in:
115
CREDITS.TXT
Normal file
115
CREDITS.TXT
Normal 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
23
LICENSE.md
Normal 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
55
Makefile
Normal 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
26
README.md
Normal 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
282
samples/Makefile
Normal 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
26
samples/README.TXT
Normal 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
116
samples/comeasy/Makefile
Normal 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.
|
||||
69
samples/comeasy/comeasy.cpp
Normal file
69
samples/comeasy/comeasy.cpp
Normal 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
167
samples/comeasy/wrotei.cpp
Normal 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
17
samples/comeasy/wrotei.rc
Normal 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
48
samples/commem/Makefile
Normal 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
114
samples/commem/commem.cpp
Normal 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
86
samples/common.mak
Normal 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
130
samples/cping/Makefile
Normal 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
47
samples/cping/ReadMe.Txt
Normal 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
2245
samples/cping/cping.cpp
Normal file
File diff suppressed because it is too large
Load Diff
0
samples/cping/cping.dat
Normal file
0
samples/cping/cping.dat
Normal file
23
samples/cping/iping.idl
Normal file
23
samples/cping/iping.idl
Normal 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
76
samples/disas/Makefile
Normal 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
232
samples/disas/arm.asm
Normal 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
686
samples/disas/disas.cpp
Normal 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
1084
samples/disas/ia64.asm
Normal file
File diff suppressed because it is too large
Load Diff
15
samples/disas/unk.cpp
Normal file
15
samples/disas/unk.cpp
Normal 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
520
samples/disas/x64.asm
Normal 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
184
samples/disas/x86.cpp
Normal 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
107
samples/dtest/Makefile
Normal 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.
|
||||
116
samples/dtest/NORMAL_IA64.TXT
Normal file
116
samples/dtest/NORMAL_IA64.TXT
Normal 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 ()
|
||||
116
samples/dtest/NORMAL_X64.TXT
Normal file
116
samples/dtest/NORMAL_X64.TXT
Normal 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 ()
|
||||
116
samples/dtest/NORMAL_X86.TXT
Normal file
116
samples/dtest/NORMAL_X86.TXT
Normal 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
306
samples/dtest/dtarge.cpp
Normal 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
59
samples/dtest/dtarge.h
Normal 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
17
samples/dtest/dtarge.rc
Normal 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
658
samples/dtest/dtest.cpp
Normal 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
53
samples/dumpe/Makefile
Normal 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
129
samples/dumpe/dumpe.cpp
Normal 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
47
samples/dumpi/Makefile
Normal 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
274
samples/dumpi/dumpi.cpp
Normal 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
108
samples/echo/Makefile
Normal 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
60
samples/echo/echofx.cpp
Normal 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
17
samples/echo/echofx.rc
Normal 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
18
samples/echo/echonul.cpp
Normal 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
24
samples/echo/main.cpp
Normal 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
135
samples/einst/Makefile
Normal 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
55
samples/einst/edll1x.cpp
Normal 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
55
samples/einst/edll2x.cpp
Normal 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
82
samples/einst/edll3x.cpp
Normal 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
98
samples/einst/einst.cpp
Normal 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
47
samples/excep/Makefile
Normal 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
125
samples/excep/excep.cpp
Normal 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
191
samples/excep/firstexc.cpp
Normal 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
21
samples/excep/firstexc.h
Normal 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
164
samples/findfunc/Makefile
Normal 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
152
samples/findfunc/extend.cpp
Normal 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.
|
||||
17
samples/findfunc/extend.rc
Normal file
17
samples/findfunc/extend.rc
Normal 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"
|
||||
35
samples/findfunc/findfunc.cpp
Normal file
35
samples/findfunc/findfunc.cpp
Normal 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.
|
||||
385
samples/findfunc/symtest.cpp
Normal file
385
samples/findfunc/symtest.cpp
Normal 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.
|
||||
41
samples/findfunc/target.cpp
Normal file
41
samples/findfunc/target.cpp
Normal 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
13
samples/findfunc/target.h
Normal 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.
|
||||
17
samples/findfunc/target.rc
Normal file
17
samples/findfunc/target.rc
Normal 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
56
samples/impmunge/Makefile
Normal 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.
|
||||
464
samples/impmunge/impmunge.cpp
Normal file
464
samples/impmunge/impmunge.cpp
Normal 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
48
samples/member/Makefile
Normal 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
116
samples/member/member.cpp
Normal 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
112
samples/opengl/Makefile
Normal 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
74
samples/opengl/ogldet.cpp
Normal 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
17
samples/opengl/ogldet.rc
Normal 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"
|
||||
24
samples/opengl/testogl.cpp
Normal file
24
samples/opengl/testogl.cpp
Normal 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
48
samples/region/Makefile
Normal 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
105
samples/region/region.cpp
Normal 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
62
samples/setdll/Makefile
Normal 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
332
samples/setdll/setdll.cpp
Normal 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
120
samples/simple/Makefile
Normal 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
76
samples/simple/simple.cpp
Normal 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
17
samples/simple/simple.rc
Normal 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
29
samples/simple/sleep5.cpp
Normal 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
194
samples/slept/Makefile
Normal 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.
|
||||
202
samples/slept/NORMAL_IA64.TXT
Normal file
202
samples/slept/NORMAL_IA64.TXT
Normal 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. ------------------------------------------------
|
||||
202
samples/slept/NORMAL_X64.TXT
Normal file
202
samples/slept/NORMAL_X64.TXT
Normal 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. ------------------------------------------------
|
||||
202
samples/slept/NORMAL_X86.TXT
Normal file
202
samples/slept/NORMAL_X86.TXT
Normal 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
141
samples/slept/dslept.cpp
Normal 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
17
samples/slept/dslept.rc
Normal 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
103
samples/slept/sleepbed.cpp
Normal 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.
|
||||
76
samples/slept/sleepnew.cpp
Normal file
76
samples/slept/sleepnew.cpp
Normal 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.
|
||||
69
samples/slept/sleepold.cpp
Normal file
69
samples/slept/sleepold.cpp
Normal 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
130
samples/slept/slept.cpp
Normal 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
17
samples/slept/slept.h
Normal 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
17
samples/slept/slept.rc
Normal 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
74
samples/slept/verify.cpp
Normal 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
101
samples/syelog/Makefile
Normal 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
145
samples/syelog/sltest.cpp
Normal 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
104
samples/syelog/sltestp.cpp
Normal 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
847
samples/syelog/syelog.cpp
Normal 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
89
samples/syelog/syelog.h
Normal 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
556
samples/syelog/syelogd.cpp
Normal 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
332
samples/talloc/Makefile
Normal 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.
|
||||
70
samples/talloc/NORMAL_IA64.TXT
Normal file
70
samples/talloc/NORMAL_IA64.TXT
Normal 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
|
||||
66
samples/talloc/NORMAL_X64.TXT
Normal file
66
samples/talloc/NORMAL_X64.TXT
Normal 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
541
samples/talloc/talloc.cpp
Normal 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
17
samples/talloc/tdll1x.cpp
Normal 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
17
samples/talloc/tdll2x.cpp
Normal 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
Reference in New Issue
Block a user