Squashed 'ext/detours/' content from commit 39aa864

git-subtree-dir: ext/detours
git-subtree-split: 39aa864d2985099c8d847e29a5fb86618039b9c4
This commit is contained in:
Andrzej Janik
2021-01-03 17:52:14 +01:00
commit dabc40cb19
178 changed files with 102613 additions and 0 deletions

72
.github/ISSUE_TEMPLATE/bug-report.md vendored Normal file
View File

@ -0,0 +1,72 @@
---
name: Bug Report
about: Report a bug in Detours
title: "<header>: Problem"
labels: 'bug'
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is. Please check that you've
read the guidelines for submitting a bug report in the
[Bug Reports](https://github.com/microsoft/Detours/wiki/FAQ#bug-reports) section
of the FAQ.
**Command-line test case**
```
C:\Temp>type repro.cpp
#include <iostream>
#include <windows.h>
#include <detours.h>
void main() {
// Replace this program with one demonstrating your actual bug report,
// along with the following compilation command. Please leave compiler
// version banners in the output (don't use /nologo), and include output
// of your test program, if any.
std::cout << "Test Case Result: ";
if (DetourIsHelperProcess()) {
std::cout << "Fail\n";
} else {
std::cout << "Pass\n";
}
}
C:\Temp>cl.exe /EHsc /W4 /WX .\repro.cpp -I. ..\lib.X64\detours.lib
Microsoft (R) C/C++ Optimizing Compiler Version 19.27.29111 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
repro.cpp
Microsoft (R) Incremental Linker Version 14.27.29111.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:repro.exe
repro.obj
..\lib.X64\detours.lib
C:\Temp>.\repro.exe
Test Case Result: Pass
```
**Expected behavior**
A clear and concise description of what you expected to happen.
Alternatively, include `static_assert` or `assert` lines in your
test case above whose failure clearly indicates the problem.
**Detours version**
* Option 1: Release version
* Displayed on the releases page: https://github.com/microsoft/Detours/releases/
* Example:
```
Version 4.0.1 of Detours
```
* Option 2: git commit hash
* Example:
```
https://github.com/microsoft/Detours/commit/2195148
```
**Additional context**
Add any other context about the problem here.

35
.github/ISSUE_TEMPLATE/question.md vendored Normal file
View File

@ -0,0 +1,35 @@
---
name: Question
about: Ask a question about Detours
title: ""
labels: question
assignees: ''
---
Instructions
============
Here, you can ask a question about Detours, and a maintainer or someone from
the community will answer. Please read the examples below, then delete all of
this text and replace it with your question. If you aren't sure whether a
question is on-topic, just go ahead and ask it! :-)
Please make sure to check the Wiki, esspecially the FAQ, to make sure your
question hasn't been answered there already:
https://github.com/microsoft/Detours/wiki/FAQ
On-Topic Examples
-----------------
* What is this code in the Detours doing? You can link to the relevant code:
https://help.github.com/en/github/managing-your-work-on-github/creating-a-permanent-link-to-a-code-snippet
* What are the preferred conventions for writing something?
* What are the maintainers planning to do in the future?
* Would the maintainers be interested in specific enhancements?
Off-Topic Examples
------------------
* Questions about non-Detours components, such as the compiler, the Windows API,
the Visual Studio IDE, etc.
* Questions about whether you've encountered a bug in Detours. Instead of this
Question template, please use the Bug Report template, because we'll need
a command-line test case and the other information requested there.

View File

@ -0,0 +1,13 @@
<!--
Before submitting a pull request, please ensure that:
* These changes introduce no known API breaks (changing the public facing
functions return types, function parameters, renaming functions, etc.).
* The changes are tested.
* Your changes are written from scratch using only this repository.
If your changes are derived from any other project, you *must* mention it
here, so we can determine whether the license is compatible and what else
needs to be done.
-->

6
.github/codeql/codeql-config.yml vendored Normal file
View File

@ -0,0 +1,6 @@
---
name: "Detours CodeQL Config"
queries:
- uses: security-and-quality
- uses: security-extended

77
.github/workflows/main.yml vendored Normal file
View File

@ -0,0 +1,77 @@
name: CI-Build
env:
# Turn on msvc analysis during build, enable once warnings are clean.
DETOURS_ANALYZE: true
# Compile in parallel where possible.
CL: /MP
# Triggers the workflow on push or pull request events for the master branch.
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [windows-2019, windows-2016]
arch: [x86, x64, x64_arm, x64_arm64]
steps:
- name: Clone Repository
uses: actions/checkout@v2
with:
# Must fetch at least the immediate parents so that if this is
# a pull request then we can checkout the head of the pull request.
# Only include this option if you are running this workflow on pull requests.
fetch-depth: 2
# If this run was triggered by a pull request event then checkout
# the head of the pull request instead of the merge commit.
# Only include this step if you are running this workflow on pull requests.
- name: Checkout head of the pull request
run: git checkout HEAD^2
if: ${{ github.event_name == 'pull_request' }}
# Setup build environment variables using vcvarsall.bat.
- name: Configure MSCV Compiler for ${{ matrix.arch }}
uses: ilammy/msvc-dev-cmd@v1.4.1
with:
arch: ${{ matrix.arch }}
- name: Initialize CodeQL for C++
uses: github/codeql-action/init@v1
if: ${{ matrix.os == 'windows-2019' }}
with:
languages: cpp
config-file: ./.github/codeql/codeql-config.yml
- name: Build Detours for ${{ matrix.arch }} on ${{ matrix.os }}
env:
# Tell detours what process to target
DETOURS_TARGET_PROCESSOR: ${{ env.VSCMD_ARG_TGT_ARCH }}
run: nmake
- name: Run unit tests for ${{ matrix.arch }} on ${{ matrix.os }}
id: run-unit-tests
run: cd tests && nmake test
if: ${{ matrix.arch == 'x86' || matrix.arch == 'x64' }}
- name: Upload artifacts for ${{ matrix.arch }} on ${{ matrix.os }}
uses: actions/upload-artifact@v2
with:
name: artifacts-${{ matrix.os }}
path: |
lib.*/
bin.*/
include/
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
if: ${{ matrix.os == 'windows-2019' }}

41
.gitignore vendored Normal file
View File

@ -0,0 +1,41 @@
# C extensions
*.so
# Unit test / coverage reports
.coverage
.tox
nosetests.xml
# Translations
*.mo
# Mr Developer
.mr.developer.cfg
.project
.pydevproject
# vim
*~
*.swp
# Visual Studio build
*.ipch
.vs/
output/
include/
*.exp
*.pdb
*.lib
*.dll
*.exe
obj.*
*.ipdb
*.iobj
*.tlog
*.log
*.obj
*.user
*.recipe
/bin.*
*.vcxproj.FileListAbsolute.txt
*.vcxprojAssemblyReference.cache

118
CREDITS.TXT Normal file
View File

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

23
LICENSE.md Normal file
View File

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

63
Makefile Normal file
View File

@ -0,0 +1,63 @@
##############################################################################
##
## 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)
cd "$(MAKEDIR)\tests"
@$(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
cd "$(MAKEDIR)\tests"
@$(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
cd "$(MAKEDIR)\tests"
@$(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)\tests"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
cd "$(MAKEDIR)"
################################################################# End of File.

56
README.md Normal file
View File

@ -0,0 +1,56 @@
# Microsoft Research Detours Package
Detours is a software package for monitoring and instrumenting API calls on Windows. Detours
has been used by many ISVs and is also used by product teams at Microsoft. Detours is now available under
a standard open source license ([MIT](https://github.com/microsoft/Detours/blob/master/LICENSE.md)). This simplifies licensing for programmers using Detours
and allows the community to support Detours using open source tools and processes.
Detours is compatible with the Windows NT family of
operating systems: Windows NT, Windows XP, Windows Server 2003, Windows 7,
Windows 8, and Windows 10. It cannot be used by Windows Store apps
because Detours requires APIs not available to those applications.
This repo contains the source code for version 4.0.1 of Detours.
For technical documentation on Detours, see the [Detours Wiki](https://github.com/microsoft/Detours/wiki).
For directions on how to build and run samples, see the
samples [README.txt](https://github.com/Microsoft/Detours/blob/master/samples/README.TXT) file.
## Contributing
The [`Detours`](https://github.com/microsoft/detours) repository is where development is done.
Here are some ways you can participate in the project:
* [Answer questions](https://github.com/microsoft/detours/issues) about using Detours.
* [Improve the Wiki](https://github.com/microsoft/detours/wiki).
* [Submit bugs](https://github.com/microsoft/detours/issues) and help us verify fixes and changes as they are checked in.
* Review [source code changes](https://github.com/microsoft/detours/pulls).
Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that
you have the right to, and actually do, grant us the rights to use your contribution.
For details, visit https://cla.opensource.microsoft.com.
When you submit a pull request, a CLA bot will automatically determine whether you need to provide
a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions
provided by the bot. You will only need to do this once across all repos using our CLA.
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.
## Issues, questions, and feedback
* Open an issue on [GitHub Issues](https://github.com/Microsoft/detours/issues).
## Mailing list for announcements
The detours-announce mailing list is a low-traffic email list for important announcements
about the project, such as the availability of new versions of Detours. To join it, send
an email to listserv@lists.research.microsoft.com with a
message body containing only the text SUBSCRIBE DETOURS-ANNOUNCE.
To leave it, send an email to listserv@lists.research.microsoft.com with a
message body containing only the text UNSUBSCRIBE DETOURS-ANNOUNCE.
## License
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the [MIT](LICENSE.md) License.

307
samples/Makefile Normal file
View File

@ -0,0 +1,307 @@
##############################################################################
##
## 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)
!IF "$(DETOURS_TARGET_PROCESSOR)" != "ARM64"
cd "$(MAKEDIR)\einst"
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
!ENDIF
!IF "$(DETOURS_TARGET_PROCESSOR)" == "X86"
cd "$(MAKEDIR)\excep"
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
!ENDIF
cd "$(MAKEDIR)\comeasy"
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
cd "$(MAKEDIR)\commem"
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
!IF "$(DETOURS_TARGET_PROCESSOR)" != "ARM64"
cd "$(MAKEDIR)\findfunc"
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
!ENDIF
!IF "$(DETOURS_TARGET_PROCESSOR)" != "ARM" && "$(DETOURS_TARGET_PROCESSOR)" != "ARM64"
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" && "$(DETOURS_TARGET_PROCESSOR)" != "ARM64"
cd "$(MAKEDIR)\tryman"
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
!ENDIF
cd "$(MAKEDIR)\impmunge"
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
cd "$(MAKEDIR)\dynamic_alloc"
@$(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)\dynamic_alloc"
@$(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)\dynamic_alloc"
@$(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
!IF "$(DETOURS_TARGET_PROCESSOR)" != "ARM64"
cd "$(MAKEDIR)\slept"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
cd "$(MAKEDIR)\setdll"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
cd "$(MAKEDIR)\withdll"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
!ENDIF
!IF "$(DETOURS_TARGET_PROCESSOR)" == "X86"
cd "$(MAKEDIR)\cping"
# @$(MAKE) /NOLOGO /$(MAKEFLAGS) test
!ENDIF
cd "$(MAKEDIR)\disas"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
!IF "$(DETOURS_TARGET_PROCESSOR)" != "ARM64"
cd "$(MAKEDIR)\dtest"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
!ENDIF
cd "$(MAKEDIR)\dumpe"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
cd "$(MAKEDIR)\dumpi"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
cd "$(MAKEDIR)\echo"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
!IF "$(DETOURS_TARGET_PROCESSOR)" != "ARM64"
cd "$(MAKEDIR)\einst"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
!ENDIF
!IF "$(DETOURS_TARGET_PROCESSOR)" == "X86"
cd "$(MAKEDIR)\excep"
# @$(MAKE) /NOLOGO /$(MAKEFLAGS) test
!ENDIF
!IF "$(DETOURS_TARGET_PROCESSOR)" != "ARM64"
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
!ENDIF
!IF "$(DETOURS_TARGET_PROCESSOR)" == "X64" || "$(DETOURS_TARGET_PROCESSOR)" == "IA64"
cd "$(MAKEDIR)\talloc"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
!ENDIF
!IF "$(DETOURS_TARGET_PROCESSOR)" != "ARM64"
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
!ENDIF
# cd "$(MAKEDIR)\tracessl"
# @$(MAKE) /NOLOGO /$(MAKEFLAGS) test
# cd "$(MAKEDIR)\tracetcp"
# @$(MAKE) /NOLOGO /$(MAKEFLAGS) test
!IF "$(DETOURS_TARGET_PROCESSOR)" != "ARM64"
cd "$(MAKEDIR)\tracelnk"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
!ENDIF
cd "$(MAKEDIR)\impmunge"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
cd "$(MAKEDIR)\dynamic_alloc"
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
cd "$(MAKEDIR)"
##
################################################################# End of File.

65
samples/README.TXT Normal file
View File

@ -0,0 +1,65 @@
##############################################################################
##
## Samples README File
##
## Microsoft Research Detours Package
##
## Copyright (c) Microsoft Corporation. All rights reserved.
##
This README file describes how to set up your build environment, build
samples, and run tests.
BUILD ENVIRONMENT:
==================
We assume that you have a version of the Visual Studio IDE installed. You can
download a free copy of the Visual Studio IDE from
https://visualstudio.microsoft.com. During Visual Studio installation, make
sure that C/C++ tools are installed and that the Windows SDK is installed.
Clone the Detours git repo to a directory on your machine. Choose a directory
that does not have spaces in the full path name.
BUILDING:
=========
Open a Developer Command Prompt for VS. Note there are several different
flavors of the command prompt for different target architectures. The
default Visual Studio Command prompt targets x86. To target x64, choose
the "X64 Native Tools Command Prompt for VS"
Change directory to the samples directory for your git repo. To build the
samples, type "nmake".
Note that you must build setdll and syslog in order to use many of the
other sample programs.
INSTALLING AND BUILDING VIA VCPKG:
==================================
You can download and install detours using the vcpkg(https://github.com/Microsoft/vcpkg) dependency manager:
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
vcpkg install detours
The detours port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please create an issue or pull request(https://github.com/Microsoft/vcpkg) on the vcpkg repository.
TESTING:
========
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.
To run all sample tests, change directory to the samples directory and type
"nmake test". Note that some samples are architecture-specific. Tests for
those samples be run only on supported architectures and will be skipped on
other architectures.
COMMENTS:
=========
The trace* samples log their output through the syelogd.exe daemon and hook
CreateProcessW to load themselves into any child processes. For example,
typing "withdll -d:traceapi.dll cmd.exe" will create a command shell under
which all processes log their API calls through traceapi.dll.

116
samples/comeasy/Makefile Normal file
View File

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

View File

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

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

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

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

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

48
samples/commem/Makefile Normal file
View File

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

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

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

86
samples/common.mak Normal file
View File

@ -0,0 +1,86 @@
##############################################################################
##
## Common makefile for Detours test programs.
##
## Microsoft Research Detours Package
##
## Copyright (c) Microsoft Corporation. All rights reserved.
##
!IF "$(ROOT)" == ""
ROOT = ..\..
!ENDIF
!include "$(ROOT)\system.mak"
!IF "$(DETOURS_SOURCE_BROWSING)" == ""
DETOURS_SOURCE_BROWSING=0
!ENDIF
##############################################################################
!IFNDEF CLIB
CLIB=/MT
!ENDIF
AFLAGS=/nologo /Zi /c /Fl
CFLAGS=/nologo /Zi $(CLIB) /Gm- /W4 /WX /we4777 /we4800 /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 /nologo /DDETOURS_BITS=$(DETOURS_BITS) /fo$(@) /i$(INCD) $(*B).rc
##
################################################################# End of File.

130
samples/cping/Makefile Normal file
View File

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

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

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

2245
samples/cping/cping.cpp Normal file

File diff suppressed because it is too large Load Diff

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

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

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

76
samples/disas/Makefile Normal file
View File

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

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

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

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

@ -0,0 +1,702 @@
/////////////////////////////////////////////////////////////////////////////
//
// Module: disas.cpp (disas.exe - Detours Test Program)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#define DETOURS_INTERNAL
#include <detours.h>
#include <stdio.h>
#include <stdlib.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;
// Bug report, but it works here.
// 07ff8`4b783054 49ba 70b3d93a d40fb998 mov r10,98B90FD43AD9B370h
//
{
static const UCHAR mov_r10_imm64[] = {0x49, 0xba, 1, 2, 3, 4, 5, 6, 7, 8 };
PVOID const after = DetourCopyInstructionX64(0, 0, const_cast<PUCHAR>(mov_r10_imm64), 0, 0);
if (after != &mov_r10_imm64 + 1)
{
printf("mov_r10_imm64 failed, expected:%p vs. got:%p\n", &mov_r10_imm64 + 1, after);
if (IsDebuggerPresent())
{
__debugbreak();
DetourCopyInstructionX64(0, 0, const_cast<PUCHAR>(mov_r10_imm64), 0, 0);
}
return 1;
}
}
#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("%08lx ", (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("%08lx ", (ULONG)(pbTest - pbBegin));
DumpMemoryFragment(pbTest, cbTest, 12);
printf("[%16p] ", pbTarget);
DumpMemoryFragment(rbDst, cbTest + lExtra, 11);
printf("\n");
if (pbTest[cbTest] != 0xcc) {
printf("failed!\n");
return 1;
}
pbTest += cbTest;
if (pbTest[0] == 0xcc && pbTest[1] == 0xcc) {
break;
}
}
#if 0
// Then we check all of the code we can find in user32.dll
//
HINSTANCE hInst = LoadLibraryA("user32.dll");
printf("Loaded: user32.dll: %p\n", hInst);
s_pbBegin = (PBYTE)hInst;
s_pbLimit = s_pbBegin + DetourGetModuleSize(hInst);
PBYTE pbEntry = DetourGetEntryPoint(hInst);
(VOID) new BasicBlockLink(pbEntry, "user32.dll");
DetourEnumerateExports(hInst, NULL, ExportCallback);
ULONG nIns = 0;
for (BasicBlockLink *pLink = BasicBlockLink::GetListHead();
pLink; pLink = pLink->Next()) {
nIns += TestDetourCopyInstruction(pLink->m_pbEntry, pLink->m_pszName);
if (nIns > 100000) {
break;
}
}
printf("Disassembled %d instructions.\n", nIns);
#endif
#endif // DETOURS_X86 || DETOURS_X64
#ifdef DETOURS_ARM
// Create an output buffer and fill it with debugbreaks.
//
PBYTE pbBuffer
= (PBYTE)VirtualAlloc(NULL, 0x400, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE);
for (PBYTE pbOut = pbBuffer; pbOut < pbBuffer + 0x400;) {
*pbOut++ = 0xfe;
*pbOut++ = 0xde;
}
PBYTE pbDst = pbBuffer;
PVOID pvDstPool = (PVOID)(pbBuffer + 0x400);
// First we check the pre-canned TestCodes from disasm.asm
//
PBYTE pbBegin = (PBYTE)DetourCodeFromPointer(TestCodes, NULL);
printf("%p: (TestCodes %p) => %p\n", pbBegin, TestCodes, pbBuffer);
for (PBYTE pbSrc = pbBegin;;) {
if (pbSrc[0] != 0xfe && pbSrc[1] != 0xde) { // BREAK
printf("%08x ", pbSrc - pbBegin);
DumpMemoryFragment(pbSrc, 8, 8);
printf("\n");
printf("failed on last.\n");
return 1;
}
pbSrc += 2;
*pbDst++ = 0xfe;
*pbDst++ = 0xde;
if ((pbSrc[0] == 0x00 && pbSrc[1] == 0xbf) && // NOP
(pbSrc[2] != 0xfe && pbSrc[3] != 0xde)) { // BREAK
// Skip over a single NOP so we can test alignment.
pbSrc += 2;
}
if ((pbSrc[0] == 0x00 && pbSrc[1] == 0xbf) && // NOP
(pbSrc[2] != 0xfe && pbSrc[3] != 0xde)) { // BREAK
// If there is a second NOP, then we insert alignment.
pbSrc += 2;
*pbDst++ = 0x00;
*pbDst++ = 0xbf;
}
LONG lExtra = 0;
PVOID pbTarget = NULL;
PBYTE pbNext = (PBYTE)DetourCopyInstruction(pbDst, &pvDstPool, pbSrc, &pbTarget, &lExtra);
LONG cbTest = (LONG)(pbNext - pbSrc);
printf("%08x ", pbSrc - pbBegin);
DumpMemoryFragment(pbSrc, cbTest, 4);
printf("[%8p] ", pbTarget);
DumpMemoryFragment(pbDst, cbTest + lExtra, 16);
printf("\n");
if (pbSrc[cbTest] != 0xfe || pbSrc[cbTest+1] != 0xde) {
printf("%p: failed! (pbSrc[n]=%02x, pbSrc[n+1]=%02x\n",
pbSrc,
pbSrc[cbTest], pbSrc[cbTest+1]);
__debugbreak();
pbNext = (PBYTE)DetourCopyInstruction(pbDst, &pvDstPool, pbSrc, &pbTarget, &lExtra);
cbTest = (LONG)(pbNext - pbSrc);
return 1;
}
pbDst += cbTest + lExtra;
pbSrc += cbTest;
if (pbSrc[0] == 0xfe && pbSrc[1] == 0xde &&
pbSrc[2] == 0xfe && pbSrc[3] == 0xde) {
break;
}
}
#if 0
// Then we check all of the code we can find in user32.dll
//
HINSTANCE hInst = LoadLibraryA("user32.dll");
printf("Loaded: user32.dll: %p\n", hInst);
s_pbBegin = (PBYTE)hInst;
s_pbLimit = s_pbBegin + DetourGetModuleSize(hInst);
PBYTE pbEntry = DetourGetEntryPoint(hInst);
(VOID) new BasicBlockLink(pbEntry, "user32.dll");
DetourEnumerateExports(hInst, NULL, ExportCallback);
ULONG nIns = 0;
for (BasicBlockLink *pLink = BasicBlockLink::GetListHead();
pLink; pLink = pLink->Next()) {
nIns += TestDetourCopyInstruction(pLink->m_pbEntry, pLink->m_pszName);
if (nIns > 100000) {
break;
}
}
printf("Disassembled %d instructions.\n", nIns);
#endif
#endif // DETOURS_ARM
return 0;
}
//
///////////////////////////////////////////////////////////////// End of File.

1084
samples/disas/ia64.asm Normal file

File diff suppressed because it is too large Load Diff

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

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

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

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

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

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

107
samples/dtest/Makefile Normal file
View File

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

View File

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

View File

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

View File

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

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

@ -0,0 +1,306 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detours Test Program (dtarge.dll)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#include <stdio.h>
#include <windows.h>
#include "dtarge.h"
DWORD_PTR WINAPI Target0()
{
printf(" Target0 ()\n");
return 1000;
}
DWORD_PTR WINAPI Target1(DWORD_PTR v1)
{
printf(" Target1 (%ld)\n",
(DWORD)v1);
return 1001;
}
DWORD_PTR WINAPI Target2(DWORD_PTR v1, DWORD_PTR v2)
{
printf(" Target2 (%ld,%ld)\n",
(DWORD)v1, (DWORD)v2);
return 1002;
}
DWORD_PTR WINAPI Target3(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3)
{
printf(" Target3 (%ld,%ld,%ld)\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 (%ld,%ld,%ld,%ld)\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 (%ld,%ld,%ld,%ld,%ld)\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 (%ld,%ld,%ld,%ld,%ld,%ld)\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 (%ld,%ld,%ld,%ld,%ld,%ld,%ld)\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 (%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)\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 (%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)\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(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)\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(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)\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(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)\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(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)\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(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)\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(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)\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(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)\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("%ld,", (DWORD)args[i]);
}
printf("%ld)\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("%ld,", (DWORD)args[i]);
}
printf("%ld)\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.

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

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

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

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

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

@ -0,0 +1,658 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detours Test Program (dtest.cpp of dtest.exe)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#include <stdio.h>
#include <stdarg.h>
#include <windows.h>
#pragma warning(push)
#if _MSC_VER > 1400
#pragma warning(disable:6102 6103) // /analyze warnings
#endif
#include <strsafe.h>
#pragma warning(pop)
#include <detours.h>
#include "dtarge.h"
DWORD_PTR WINAPI LocalTarget1(DWORD_PTR v1);
////////////////////////////////////////////////////// Multi-Argument Detours.
//
DWORD_PTR (WINAPI * Trampoline_LocalTarget1)(DWORD_PTR v1) = LocalTarget1;
DWORD_PTR (WINAPI * Trampoline_Target0)() = Target0;
DWORD_PTR (WINAPI * Trampoline_Target1)(DWORD_PTR v1) = Target1;
DWORD_PTR (WINAPI * Trampoline_Target2)(DWORD_PTR v1, DWORD_PTR v2) = Target2;
DWORD_PTR (WINAPI * Trampoline_Target3)
(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3) = Target3;
DWORD_PTR (WINAPI * Trampoline_Target4)
(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4) = Target4;
DWORD_PTR (WINAPI * Trampoline_Target5)
(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
DWORD_PTR v5) = Target5;
DWORD_PTR (WINAPI * Trampoline_Target6)
(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
DWORD_PTR v5, DWORD_PTR v6) = Target6;
DWORD_PTR (WINAPI * Trampoline_Target7)
(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7) = Target7;
DWORD_PTR (WINAPI * Trampoline_Target8)
(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8) = Target8;
DWORD_PTR (WINAPI * Trampoline_Target9)
(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
DWORD_PTR v9) = Target9;
DWORD_PTR (WINAPI * Trampoline_Target10)
(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
DWORD_PTR v9, DWORD_PTR v10) = Target10;
DWORD_PTR (WINAPI * Trampoline_Target11)
(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11) = Target11;
DWORD_PTR (WINAPI * Trampoline_Target12)
(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12) = Target12;
DWORD_PTR (WINAPI * Trampoline_Target13)
(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12,
DWORD_PTR v13) = Target13;
DWORD_PTR (WINAPI * Trampoline_Target14)
(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12,
DWORD_PTR v13, DWORD_PTR v14) = Target14;
DWORD_PTR (WINAPI * Trampoline_Target15)
(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12,
DWORD_PTR v13, DWORD_PTR v14, DWORD_PTR v15) = Target15;
DWORD_PTR (WINAPI * Trampoline_Target16)
(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12,
DWORD_PTR v13, DWORD_PTR v14, DWORD_PTR v15, DWORD_PTR v16) = Target16;
DWORD_PTR (WINAPI * Trampoline_TargetV)(DWORD_PTR v1, ...) = TargetV;
DWORD_PTR (WINAPI * Trampoline_TargetR)(DWORD_PTR v1, ...) = TargetR;
//////////////////////////////////////////////////////////////////////////////
//
VOID dprintf(const char * fmt, ...)
{
CHAR szBuf[1024];
va_list args;
va_start(args, fmt);
StringCchPrintfA(szBuf, sizeof(szBuf), fmt, args);
va_end(args);
OutputDebugStringA(szBuf);
}
//////////////////////////////////////////////////////////////////////////////
//
DWORD_PTR WINAPI LocalTarget1(DWORD_PTR v1)
{
printf(" LocalTarget1 (%ld)\n", (DWORD)v1);
// dprintf("LocalTarget1\n");
// __debugbreak();
return 9000;
}
//////////////////////////////////////////////////////////////////////////////
//
DWORD_PTR WINAPI MyLocalTarget1(DWORD_PTR v1)
{
printf(" MyLocalTarget1 (%ld)\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 (%ld)\n",
(DWORD)v1);
return Trampoline_Target1(v1);
}
DWORD_PTR WINAPI MyTarget2(DWORD_PTR v1, DWORD_PTR v2)
{
printf(" MyTarget2 (%ld,%ld)\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 (%ld,%ld,%ld)\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 (%ld,%ld,%ld,%ld)\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 (%ld,%ld,%ld,%ld,%ld)\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 (%ld,%ld,%ld,%ld,%ld,%ld)\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 (%ld,%ld,%ld,%ld,%ld,%ld,%ld)\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 (%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)\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 (%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)\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(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)\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(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)\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(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)\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(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)\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(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)\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(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)\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(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)\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("%ld,", (DWORD)args[i]);
}
printf("%ld)\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("%ld,", (DWORD)args[i]);
}
printf("%ld)\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(" => %ld\n", (DWORD)rv);
Trampoline_Target0_1 = Target0;
Trampoline_Target0_2 = Target0;
Trampoline_Target0_3 = Target0;
//dprintf("Trampoline_Target0_1 = %p\n", DetourCodeFromPointer(Trampoline_Target0_1, NULL));
//__debugbreak();
printf("Calling Target0 again with 1 detour.\n");
Target0();
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)Trampoline_Target0_1, MyTarget0_1);
DetourTransactionCommit();
//dprintf("Trampoline_Target0_2 = %p\n", DetourCodeFromPointer(Trampoline_Target0_2, NULL));
//__debugbreak();
printf("Calling Target0 again with 2 detours.\n");
Target0();
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)Trampoline_Target0_2, MyTarget0_2);
DetourTransactionCommit();
//dprintf("Trampoline_Target0_3 = %p\n", DetourCodeFromPointer(Trampoline_Target0_3, NULL));
//__debugbreak();
printf("Calling Target0 again with 3 detours.\n");
Target0();
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)Trampoline_Target0_3, MyTarget0_3);
DetourTransactionCommit();
//dprintf("Trampoline_Target0_3 = %p\n", DetourCodeFromPointer(Trampoline_Target0_3, NULL));
//__debugbreak();
printf("Calling Target0 again with 4 detours.\n");
Target0();
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)Trampoline_Target0, MyTarget0);
DetourDetach(&(PVOID&)Trampoline_Target1, MyTarget1);
DetourDetach(&(PVOID&)Trampoline_Target2, MyTarget2);
DetourDetach(&(PVOID&)Trampoline_Target3, MyTarget3);
DetourDetach(&(PVOID&)Trampoline_Target4, MyTarget4);
DetourDetach(&(PVOID&)Trampoline_Target5, MyTarget5);
DetourDetach(&(PVOID&)Trampoline_Target6, MyTarget6);
DetourDetach(&(PVOID&)Trampoline_Target7, MyTarget7);
DetourDetach(&(PVOID&)Trampoline_Target8, MyTarget8);
DetourDetach(&(PVOID&)Trampoline_Target9, MyTarget9);
DetourDetach(&(PVOID&)Trampoline_Target10, MyTarget10);
DetourDetach(&(PVOID&)Trampoline_Target11, MyTarget11);
DetourDetach(&(PVOID&)Trampoline_Target12, MyTarget12);
DetourDetach(&(PVOID&)Trampoline_Target13, MyTarget13);
DetourDetach(&(PVOID&)Trampoline_Target14, MyTarget14);
DetourDetach(&(PVOID&)Trampoline_Target15, MyTarget15);
DetourDetach(&(PVOID&)Trampoline_Target16, MyTarget16);
DetourDetach(&(PVOID&)Trampoline_TargetV, MyTargetV);
DetourDetach(&(PVOID&)Trampoline_TargetR, MyTargetR);
DetourTransactionCommit();
printf("Done.\n");
return 0;
}
//
///////////////////////////////////////////////////////////////// End of File.

53
samples/dumpe/Makefile Normal file
View File

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

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

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

47
samples/dumpi/Makefile Normal file
View File

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

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

@ -0,0 +1,270 @@
//////////////////////////////////////////////////////////////////////////////
//
// 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 %ld.", szMsg, szFile, nLine);
}
#define ASSERT(x) \
do { if (!(x)) { AssertMessage(#x, __FILE__, __LINE__); DebugBreak(); }} while (0)
;
//////////////////////////////////////////////////////////////////////////////
//
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::#%ld\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: %ld\n",
pszPath, GetLastError());
bGood = FALSE;
goto end;
}
if ((pBinary = DetourBinaryOpen(hOld)) == NULL) {
printf("%s: DetourBinaryOpen failed: %ld\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: %ld\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

View File

@ -0,0 +1,77 @@
##############################################################################
##
## Makefile for Detours Test Programs.
##
## Microsoft Research Detours Package
##
## Copyright (c) Microsoft Corporation. All rights reserved.
##
!include ..\common.mak
# This test is x86 only
!IF "$(DETOURS_TARGET_PROCESSOR)" == "X86" || "$(DETOURS_TARGET_PROCESSOR)" == "X64"
TARGET_NAME=dalloc
CFLAGS=\
$(CFLAGS)\
/EHsc\
LIBS=$(LIBS)\
user32.lib\
all: dirs $(BIND)\$(TARGET_NAME).exe
##############################################################################
clean:
-del $(BIND)\$(TARGET_NAME).* 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)" == "X64"
$(OBJD)\asm.obj : x64.asm
$(ASM) $(AFLAGS) /Fl$(OBJD)\x64.lst /Fo$(OBJD)\asm.obj x64.asm
!ELSE
$(OBJD)\asm.obj : x86.asm
$(ASM) $(AFLAGS) /Fl$(OBJD)\x86.lst /Fo$(OBJD)\asm.obj x86.asm
!ENDIF
$(OBJD)\main.obj : main.cpp
$(BIND)\$(TARGET_NAME).exe : $(OBJD)\main.obj $(OBJD)\asm.obj $(DEPS)
link\
/SUBSYSTEM:CONSOLE\
$(LINKFLAGS)\
$(LIBS)\
/PDB:"$(@R).pdb"\
/OUT:"$@"\
$**\
##############################################################################
test: all
$(BIND)\$(TARGET_NAME).exe
##############################################################################
!ELSE
all:
@echo The platform `$(DETOURS_TARGET_PROCESSOR)` is not supported. Skipping.
test:
@echo The platform `$(DETOURS_TARGET_PROCESSOR)` is not supported. Skipping.
clean:
realclean:
!ENDIF
################################################################# End of File.

View File

@ -0,0 +1,194 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detours Test Program
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// This is a test program to test the DetourAllocateRegionWithinJumpBounds
// API, that dynamically allocates an executable region adjacent to a given
// address so that we can use the region as a detour function.
//
// This test program detours the function `target_function`. Instead of
// simply specifying a code segment as a detour function, we specify a
// dynamically-allocated region into which we copy the code, altering the
// return value, from the assembly function `CodeTemplate` as a template.
//
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <functional>
#include <assert.h>
#include <windows.h>
#include <detours.h>
extern "C" {
void *CodeTemplate();
void *CodeTemplate_End();
}
void Log(PCSTR format, ...) {
char linebuf[1024];
va_list v;
va_start(v, format);
wvsprintfA(linebuf, format, v);
va_end(v);
OutputDebugStringA(linebuf);
}
// This is a target function to be detoured. When detoured, it's expected to
// return a non-nullptr value.
void *target_function() {
std::cout << '+' << __FUNCTION__ << std::endl;
return nullptr;
}
// Helper function to sandwich a given function between `DetourTransactionBegin`
// and `DetourTransactionCommit`/`DetourTransactionAbort`.
bool DetourTransaction(std::function<bool()> callback) {
LONG status = DetourTransactionBegin();
if (status != NO_ERROR) {
Log("DetourTransactionBegin failed with %08x\n", status);
return status == NO_ERROR;
}
if (callback()) {
status = DetourTransactionCommit();
if (status != NO_ERROR) {
Log("DetourTransactionCommit failed with %08x\n", status);
}
}
else {
status = DetourTransactionAbort();
if (status == NO_ERROR) {
Log("Aborted transaction.\n");
}
else {
Log("DetourTransactionAbort failed with %08x\n", status);
}
}
return status == NO_ERROR;
}
// This class manages one dynamically-allocated region that is allocated by
// the Detours API `DetourAllocateRegionWithinJumpBounds`, to which we can
// push binary data sequentially to use it as a detour function.
class CodeRegionFactory final {
template <typename T>
static const T *at(const void *base, uint32_t offset) {
return
reinterpret_cast<const T*>(
reinterpret_cast<const uint8_t*>(base) + offset);
}
template <typename T>
static T *at(void *base, uint32_t offset) {
return
reinterpret_cast<T*>(
reinterpret_cast<uint8_t*>(base) + offset);
}
void *region_ = nullptr;
uint8_t *current_ = nullptr,
*current_end_ = nullptr;
public:
CodeRegionFactory(const void *source) {
DWORD new_region_size = 0;
auto new_region_address =
DetourAllocateRegionWithinJumpBounds(source, &new_region_size);
if (new_region_address) {
region_ = current_ = at<uint8_t>(new_region_address, 0);
current_end_ = current_ + new_region_size;
}
else {
Log("Cannot find a region near %p\n", source);
}
}
~CodeRegionFactory() {
if (region_
&& !VirtualFree(region_, 0, MEM_RELEASE)) {
Log("VirtualFree failed - %08x\n", GetLastError());
}
}
// Pushes binary data to the region if there is enough space, and returns
// the start address of a copy in the region if succeeded.
void *PushTemplate(const void *start,
const void *end) {
auto diff = at<uint8_t>(end, 0) - at<uint8_t>(start, 0);
if (diff < 0 || current_ + diff > current_end_)
return nullptr;
auto start_pos = current_;
memcpy(start_pos, start, diff);
current_ += diff;
return start_pos;
}
};
int main(int, char**) {
std::cout << "1. target_function() without Detour" << std::endl;
auto ret = target_function();
std::cout << ret << std::endl;
assert(!ret);
CodeRegionFactory factory(target_function);
void *detour_destination,
*detour_target = reinterpret_cast<void*>(target_function);
// Fill the allocated page with as many instances as possible of the code
// template, and pick the last instance
while (auto p = factory.PushTemplate(CodeTemplate,
CodeTemplate_End)) {
detour_destination = p;
}
bool is_detoured = false;
DetourTransaction([&]() {
PDETOUR_TRAMPOLINE trampoline = nullptr;
void *target = nullptr,
*detour = nullptr;
auto status = DetourAttachEx(&detour_target,
detour_destination,
&trampoline,
&target,
&detour);
if (status != NO_ERROR) {
Log("DetourAttachEx failed - %08x\n", status);
return false;
}
is_detoured = true;
std::cout
<< "detour: " << target << " --> " << detour
<< " (trampoline: " << trampoline << " )"
<< std::endl;
return true;
});
// Attach failed for some reason. Bail out.
if (!is_detoured)
return 1;
std::cout << "2. target_function() with Detour" << std::endl;
ret = target_function();
std::cout << ret << std::endl;
assert(ret); // The return value is cracked by the detour function
DetourTransaction([&]() {
auto status = DetourDetach(&detour_target, detour_destination);
if (status != NO_ERROR) {
Log("DetourDetach failed - %08x\n", status);
return false;
}
return true;
});
std::cout << "3. target_function() without Detour" << std::endl;
ret = target_function();
std::cout << ret << std::endl;
assert(!ret);
return 0;
}

View File

@ -0,0 +1,25 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Detours Test Program
;;
;; Microsoft Research Detours Package
;;
;; Copyright (c) Microsoft Corporation. All rights reserved.
;;
PUBLIC CodeTemplate
PUBLIC CodeTemplate_End
_TEXT SEGMENT
CodeTemplate PROC
nop
nop
mov rax, 0deadbeef00000000h
nop
ret
CodeTemplate_End::
CodeTemplate ENDP
_TEXT ENDS
END

View File

@ -0,0 +1,31 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Detours Test Program
;;
;; Microsoft Research Detours Package
;;
;; Copyright (c) Microsoft Corporation. All rights reserved.
;;
.386
.model flat,C
PUBLIC CodeTemplate
PUBLIC CodeTemplate_End
_TEXT SEGMENT
CodeTemplate PROC
nop
nop
nop
mov eax, 0deadbeefh
nop
nop
nop
ret
CodeTemplate_End::
CodeTemplate ENDP
_TEXT ENDS
END

108
samples/echo/Makefile Normal file
View File

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

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

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

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

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

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

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

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

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

148
samples/einst/Makefile Normal file
View File

@ -0,0 +1,148 @@
##############################################################################
##
## Makefile for Detours Test Programs.
##
## Microsoft Research Detours Package
##
## Copyright (c) Microsoft Corporation. All rights reserved.
##
!include ..\common.mak
# ARM64 does not like base addresses below 4GB.
# Append two extra zeros for it.
#
!if "$(DETOURS_TARGET_PROCESSOR)" == "ARM64"
EDLL1X_BASE=0x710000000
EDLL2X_BASE=0x720000000
EDLL3X_BASE=0x730000000
!else
EDLL1X_BASE=0x7100000
EDLL2X_BASE=0x7200000
EDLL3X_BASE=0x7300000
!endif
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:$(EDLL1X_BASE)
$(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:$(EDLL2X_BASE)
$(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:$(EDLL3X_BASE)
$(OBJD)\edll3x$(DETOURS_BITS).bsc : $(OBJD)\edll3x.obj
bscmake /v /n /o $@ $(OBJD)\edll3x.sbr
############################################### Install non-bit-size binaries.
!IF "$(DETOURS_OPTION_PROCESSOR)" != ""
$(OPTD)\edll1x$(DETOURS_OPTION_BITS).dll:
$(OPTD)\edll1x$(DETOURS_OPTION_BITS).pdb:
$(OPTD)\edll2x$(DETOURS_OPTION_BITS).dll:
$(OPTD)\edll2x$(DETOURS_OPTION_BITS).pdb:
$(OPTD)\edll3x$(DETOURS_OPTION_BITS).dll:
$(OPTD)\edll3x$(DETOURS_OPTION_BITS).pdb:
$(BIND)\edll1x$(DETOURS_OPTION_BITS).dll : $(OPTD)\edll1x$(DETOURS_OPTION_BITS).dll
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
$(BIND)\edll1x$(DETOURS_OPTION_BITS).pdb : $(OPTD)\edll1x$(DETOURS_OPTION_BITS).pdb
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
$(BIND)\edll2x$(DETOURS_OPTION_BITS).dll : $(OPTD)\edll2x$(DETOURS_OPTION_BITS).dll
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
$(BIND)\edll2x$(DETOURS_OPTION_BITS).pdb : $(OPTD)\edll2x$(DETOURS_OPTION_BITS).pdb
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
$(BIND)\edll3x$(DETOURS_OPTION_BITS).dll : $(OPTD)\edll3x$(DETOURS_OPTION_BITS).dll
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
$(BIND)\edll3x$(DETOURS_OPTION_BITS).pdb : $(OPTD)\edll3x$(DETOURS_OPTION_BITS).pdb
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
option: \
$(BIND)\edll1x$(DETOURS_OPTION_BITS).dll \
$(BIND)\edll1x$(DETOURS_OPTION_BITS).pdb \
$(BIND)\edll2x$(DETOURS_OPTION_BITS).dll \
$(BIND)\edll2x$(DETOURS_OPTION_BITS).pdb \
$(BIND)\edll3x$(DETOURS_OPTION_BITS).dll \
$(BIND)\edll3x$(DETOURS_OPTION_BITS).pdb \
!ELSE
option:
!ENDIF
##############################################################################
test: all
$(BIND)\einst.exe
################################################################# End of File.

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

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

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

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

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

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

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

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

47
samples/excep/Makefile Normal file
View File

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

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

@ -0,0 +1,125 @@
//////////////////////////////////////////////////////////////////////////////
//
// First Chance Exception Handling Test Program (excep.cpp of excep.exe)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// For more information on exception handling, see "A Crash Course on the
// Depths of Win32 Structured Exception Handling," by Matt Pietrek in the
// January 1997 issue of Microsoft Systems Journal.
//
#include <stdio.h>
#include <windows.h>
#include <detours.h>
#include "firstexc.h"
//////////////////////////////////////////////////////////////////////////////
//
static LPVOID s_pvData = NULL;
static DWORD s_dwDataPerm = 0;
static LONG ExceptCatch(LONG nTry, DWORD dwException, LPEXCEPTION_POINTERS pinfo)
{
printf(" ExceptCatch(%ld, %08lx, %08lx)\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 -> %ld\n", *(PULONG)s_pvData);
((PULONG)s_pvData)[0] = 0;
printf(" BadCode -> %ld\n", *(PULONG)s_pvData);
((PULONG)s_pvData)[-1] = 0;
printf(" BadCode -> %ld\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) : %08lx\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: %ld\n", GetLastError());
return 0;
}
*(PULONG)s_pvData = 1;
VirtualProtect(s_pvData, sizeof(ULONG), PAGE_READONLY, &s_dwDataPerm);
DetourFirstChanceExceptionFilter(MyVirtualFaultFilter);
printf("main\n");
printf("--------------------------------------------------\n");
int nTry = 0;
for (; nTry < 1; nTry++) {
// safe(nTry);
}
printf("-- safe ------------------------------------------\n");
safe(nTry);
VirtualProtect(s_pvData, sizeof(ULONG), PAGE_READWRITE, &s_dwDataPerm);
*(PULONG)s_pvData = 1;
VirtualProtect(s_pvData, sizeof(ULONG), PAGE_READONLY, &s_dwDataPerm);
printf("-- raw -------------------------------------------\n");
printf("*\n");
printf("* NB: The second attempt to write will fail because it isn't handled.\n");
printf("*\n");
raw(nTry);
printf("--------------------------------------------------\n");
printf("exit\n");
return 0;
}
//
///////////////////////////////////////////////////////////////// End of File.

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

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

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

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

178
samples/findfunc/Makefile Normal file
View File

@ -0,0 +1,178 @@
##############################################################################
##
## Program to test DetourFindFunction.
##
## Microsoft Research Detours Package
##
## Copyright (c) Microsoft Corporation. All rights reserved.
##
!include ..\common.mak
# ARM64 does not like base addresses below 4GB.
# Append two extra zeros for it.
#
!if "$(DETOURS_TARGET_PROCESSOR)" == "ARM64"
TARGET_BASE=0x190000000
EXTEND_BASE=0x1a0000000
!else
TARGET_BASE=0x1900000
EXTEND_BASE=0x1a00000
!endif
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:$(TARGET_BASE) \
$(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:$(EXTEND_BASE) \
$(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 -------- Should list symbols using symtest.exe -----------
$(BIND)\symtest.exe
@echo.
@echo -------- Test completed. ------------------------------------------------
################################################################# End of File.

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

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

View File

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

View File

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

View File

@ -0,0 +1,385 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detour Test Program (symtest.cpp of symtest.exe)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#include <windows.h>
#include <stdio.h>
#pragma warning(push)
#if _MSC_VER > 1400
#pragma warning(disable:6102 6103) // /analyze warnings
#endif
#include <strsafe.h>
#pragma warning(pop)
#include <detours.h>
#include "target.h"
#if (_MSC_VER < 1299)
#include <imagehlp.h>
typedef IMAGEHLP_MODULE IMAGEHLP_MODULE64;
typedef PIMAGEHLP_MODULE PIMAGEHLP_MODULE64;
typedef IMAGEHLP_SYMBOL SYMBOL_INFO;
typedef PIMAGEHLP_SYMBOL PSYMBOL_INFO;
#else
#pragma warning(push)
#pragma warning(disable:4091) // empty typedef
#include <dbghelp.h>
#pragma warning(pop)
#endif
//////////////////////////////////////////////////////////////////////////////
//
typedef LPAPI_VERSION (NTAPI *PF_ImagehlpApiVersionEx)(LPAPI_VERSION AppVersion);
typedef BOOL (NTAPI *PF_SymInitialize)(IN HANDLE hProcess,
IN LPCSTR UserSearchPath,
IN BOOL fInvadeProcess);
typedef DWORD (NTAPI *PF_SymSetOptions)(IN DWORD SymOptions);
typedef DWORD (NTAPI *PF_SymGetOptions)(VOID);
typedef DWORD64 (NTAPI *PF_SymLoadModule64)(IN HANDLE hProcess,
IN HANDLE hFile,
IN PSTR ImageName,
IN PSTR ModuleName,
IN DWORD64 BaseOfDll,
IN DWORD SizeOfDll);
typedef BOOL (NTAPI *PF_SymGetModuleInfo64)(IN HANDLE hProcess,
IN DWORD64 qwAddr,
OUT PIMAGEHLP_MODULE64 ModuleInfo);
typedef BOOL (NTAPI *PF_SymFromName)(IN HANDLE hProcess,
IN LPSTR Name,
OUT PSYMBOL_INFO Symbol);
#if (_MSC_VER < 1299)
typedef BOOL (NTAPI *PF_SymRegisterCallback64)();
typedef BOOL (NTAPI *PF_SymEnumerateModules64)();
typedef BOOL (NTAPI *PF_SymEnumSymbols)();
#else
typedef BOOL (NTAPI *PF_SymRegisterCallback64)(IN HANDLE hProcess,
IN PSYMBOL_REGISTERED_CALLBACK64
CallbackFunction,
IN ULONG64 UserContext);
typedef BOOL (NTAPI *PF_SymEnumerateModules64)(IN HANDLE hProcess,
IN PSYM_ENUMMODULES_CALLBACK64
EnumModulesCallback,
IN PVOID UserContext);
typedef BOOL (NTAPI *PF_SymEnumSymbols)(IN HANDLE hProcess,
IN ULONG64 BaseOfDll,
IN PCSTR Mask,
IN PSYM_ENUMERATESYMBOLS_CALLBACK
EnumSymbolsCallback,
IN PVOID UserContext);
#endif
PF_ImagehlpApiVersionEx pfImagehlpApiVersionEx = NULL;
PF_SymInitialize pfSymInitialize = NULL;
PF_SymSetOptions pfSymSetOptions = NULL;
PF_SymGetOptions pfSymGetOptions = NULL;
PF_SymLoadModule64 pfSymLoadModule64 = NULL;
PF_SymGetModuleInfo64 pfSymGetModuleInfo64 = NULL;
PF_SymFromName pfSymFromName = NULL;
PF_SymRegisterCallback64 pfSymRegisterCallback64 = NULL;
PF_SymEnumerateModules64 pfSymEnumerateModules64 = NULL;
PF_SymEnumSymbols pfSymEnumSymbols = NULL;
//////////////////////////////////////////////////////////////////////////////
//
#if (_MSC_VER > 1299)
static BOOL WINAPI SymEnumerateCallback(
PCSTR pszModule,
DWORD64 base,
PVOID pvUserContext)
{
(void)pvUserContext;
printf(" %p: %s\n", (PVOID)base, pszModule);
return TRUE;
}
static int nSymbolCount = 0;
static BOOL WINAPI SymEnumerateSymbols(PSYMBOL_INFO pSym,
ULONG size,
PVOID pvUserContext)
{
(void)size;
(void)pvUserContext;
if (strstr(pSym->Name, "Target") != NULL ||
strstr(pSym->Name, "Hidden") != NULL) {
printf(" %p: %s\n", (PVOID)pSym->Address, pSym->Name);
nSymbolCount++;
}
else if (nSymbolCount < 5) {
printf(" %p: %s\n", (PVOID)pSym->Address, pSym->Name);
nSymbolCount++;
}
return TRUE;
}
static void truncate(PCHAR data)
{
size_t len = strlen(data);
if (len > 0 && data[len-1] == '\r') {
data[--len] = '\0';
}
if (len > 0 && data[len-1] == '\n') {
data[--len] = '\0';
}
}
BOOL WINAPI CallbackFunction(HANDLE hProcess, ULONG action, ULONG64 data, ULONG64 context)
{
(void)context;
switch (action) {
case CBA_DEBUG_INFO:
truncate((PCHAR)data);
printf("::> %s\n", (PCHAR)data);
return TRUE;
case CBA_DEFERRED_SYMBOL_LOAD_CANCEL:
printf("::> proc=%p action=%08lx data=%p\n",
(PVOID)hProcess,
action,
(PVOID)data);
{
PIMAGEHLP_DEFERRED_SYMBOL_LOAD64 pi = (PIMAGEHLP_DEFERRED_SYMBOL_LOAD64)data;
printf("pi->SizeOfStruct = %ld\n", pi->SizeOfStruct);
printf("pi->BaseOfImage = %p\n", (PVOID)(size_t)pi->BaseOfImage);
printf("pi->CheckSum = %8lx\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=%08lx 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: %ld\n", GetLastError());
return 1;
}
#if (_MSC_VER > 1299)
pfSymRegisterCallback64(hProcess, CallbackFunction, NULL);
#endif
DWORD dw = pfSymGetOptions();
printf("GetOptions = %08lx\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 = %08lx\n", dw);
pfSymSetOptions(dw);
/////////////////////////////////////////////// First, try GetProcAddress.
//
PCHAR pszFile = "target" DETOURS_STRINGIFY(DETOURS_BITS) ".dll";
HMODULE hModule = LoadLibraryA(pszFile);
if (hModule == NULL) {
printf("LoadLibraryA(%s) failed: %ld\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: %ld\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: %ld\n",
hProcess, hModule, GetLastError());
}
else {
printf("SymGetModuleInfo64(%p, %p) [64] succeeded: %ld\n",
hProcess, hModule, GetLastError());
StringCchCopyA(szModName, ARRAYSIZE(szModName), modinfo.ModuleName);
StringCchCatA(szModName, ARRAYSIZE(szModName), "!");
printf("NumSyms: %ld\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: %ld\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: %ld\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: %ld\n", szFullName, GetLastError());
}
if (symbol.Address != 0) {
printf("--SymFromName(%s) succeeded\n", szFullName);
}
printf("%s => %p\n\n", szFullName, (PBYTE)symbol.Address);
#endif
// We call Target once to insure it is loaded.
Target(0);
return 0;
}
//
///////////////////////////////////////////////////////////////// End of File.

View File

@ -0,0 +1,41 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detour Test Program (target.cpp of target.dll)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#include <stdio.h>
#include <windows.h>
#include "target.h"
extern "C" DWORD WINAPI Hidden(DWORD dwCount)
{
printf("target.dll: Hidden(%ld) -> %ld.\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 (%ld) -> %ld.\n", dwCount, dwCount + 100);
dwCount = SelfHidden(dwCount + 100);
printf("target.dll: Target (.....) -> %ld.\n", dwCount);
return dwCount;
}
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
{
(void)hinst;
(void)dwReason;
(void)reserved;
return TRUE;
}
//
///////////////////////////////////////////////////////////////// End of File.

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

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

View File

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

56
samples/impmunge/Makefile Normal file
View File

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

View File

@ -0,0 +1,464 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detours Test Program (impmunge.cpp of impmunge.exe)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#pragma warning(push)
#if _MSC_VER > 1400
#pragma warning(disable:6102 6103) // /analyze warnings
#endif
#include <strsafe.h>
#include <detours.h>
#pragma warning(disable:4091) // empty typedef
#include <imagehlp.h>
#pragma warning(pop)
////////////////////////////////////////////////////////////// Error Messages.
//
VOID AssertMessage(PCSTR szMsg, PCSTR szFile, DWORD nLine)
{
printf("ASSERT(%s) failed in %s, line %ld.", 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: %ld\n",
pszInput, GetLastError());
fGood = FALSE;
goto end;
}
if ((pBinary = DetourBinaryOpen(hOld)) == NULL) {
printf("DetourBinaryOpen failed: %ld\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: %ld\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: %ld\n", GetLastError());
}
}
if (s_fList) {
if (!DetourBinaryEditImports(pBinary,
NULL,
ListByway,
ListFile,
ListSymbol,
ListCommit)) {
printf("DetourBinaryEditImports for list failed: %ld\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: %ld\n",
pszOutput, GetLastError());
fGood = FALSE;
goto end;
}
if (!DetourBinaryWrite(pBinary, hNew)) {
printf("DetourBinaryWrite failed: %ld\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: %ld\n", pszOutput, GetLastError());
}
}
end:
if (pBinary) {
DetourBinaryClose(pBinary);
pBinary = NULL;
}
if (hNew != INVALID_HANDLE_VALUE) {
CloseHandle(hNew);
hNew = INVALID_HANDLE_VALUE;
}
if (hOld != INVALID_HANDLE_VALUE) {
CloseHandle(hOld);
hOld = INVALID_HANDLE_VALUE;
}
return fGood;
}
//////////////////////////////////////////////////////////////////////////////
//
void PrintUsage(void)
{
printf("Usage:\n"
" impmunge [options] binary_files\n"
"Options:\n"
" /l : List imports.\n"
" /l- : Don't list imports.\n"
" /m : Munge imports.\n"
" /r : Remove import munges.\n"
" /o:file : Set name of output file; must be include with /m or /r.\n"
" /? : This help screen.\n");
}
//////////////////////////////////////////////////////////////////////// main.
//
int CDECL main(int argc, char **argv)
{
BOOL fNeedHelp = FALSE;
PCHAR pszOutput = NULL;
int arg = 1;
for (; arg < argc && !fNeedHelp; arg++) {
if (argv[arg][0] == '-' || argv[arg][0] == '/') {
CHAR *argn = argv[arg] + 1;
CHAR *argp = argn;
while (*argp && *argp != ':')
argp++;
if (*argp == ':')
*argp++ = '\0';
switch (argn[0]) {
case 'l': // List contents of import table.
case 'L':
s_fList = (argn[1] != '-');
break;
case 'm': // Munge import table.
case 'M':
s_fMunge = (argn[1] != '-');
break;
case 'o': // Set output file name.
case 'O':
pszOutput = argp;
break;
case 'r': // Restore file to unmunged state.
case 'R':
s_fRestore = (argn[1] != '-');
break;
case 's': // Munge ordinals to symbols
case 'S':
s_fToSymbols = true;
break;
case '?': // Help
fNeedHelp = TRUE;
break;
default:
fNeedHelp = TRUE;
printf("Bad argument: %s:%s\n", argn, argp);
break;
}
}
else {
if (!s_fList && !s_fMunge && !s_fRestore) {
fNeedHelp = TRUE;
break;
}
if (pszOutput == NULL && (s_fMunge || s_fRestore)) {
fNeedHelp = TRUE;
break;
}
EditFile(argv[arg], pszOutput);
pszOutput = NULL;
}
}
if (argc == 1) {
fNeedHelp = TRUE;
}
if (fNeedHelp) {
PrintUsage();
return 1;
}
return 0;
}
// End of File

48
samples/member/Makefile Normal file
View File

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

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

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

112
samples/opengl/Makefile Normal file
View File

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

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

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

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

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

View File

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

48
samples/region/Makefile Normal file
View File

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

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

@ -0,0 +1,104 @@
//////////////////////////////////////////////////////////////////////////////
//
// 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 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 %lu 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: %ld, Trampoline: %p\n", error, TrueSleepEx);
trampoline = TrueSleepEx;
printf("\n");
printf("Sleep(%lu)\n", dwMilliseconds);
Sleep(dwMilliseconds);
printf("\n");
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)TrueSleepEx, LoudSleepEx);
error = DetourTransactionCommit();
return trampoline;
}
int main(int argc, char **argv)
{
(void)argc;
(void)argv;
// First, save the default system region.
PVOID pDefaultLower = DetourSetSystemRegionLowerBound(NULL);
PVOID pDefaultUpper = DetourSetSystemRegionUpperBound(NULL);
// Now attach the detour with the default system region.
DetourSetSystemRegionLowerBound(pDefaultLower);
DetourSetSystemRegionUpperBound(pDefaultUpper);
printf("%p..%p: ", pDefaultLower, pDefaultUpper);
PVOID pTramp1 = AttachAndDetach(10);
printf("%p..%p: ", pDefaultLower, pDefaultUpper);
PVOID pTramp2 = AttachAndDetach(10);
// Now attach the detour with a smaller system region.
PVOID pSmallerLower = (PVOID)( ((ULONG_PTR)pTramp1) & ~(ULONG_PTR)0x3fffffff );
PVOID pSmallerUpper = (PVOID)( ((ULONG_PTR)pTramp1 + 0x3fffffff) & ~(ULONG_PTR)0x3fffffff );
DetourSetSystemRegionLowerBound(pSmallerLower);
DetourSetSystemRegionUpperBound(pSmallerUpper);
printf("%p..%p: ", pSmallerLower, pSmallerUpper);
PVOID pTramp3 = AttachAndDetach(20);
printf("Sleep(30)\n");
Sleep(30);
printf("\n");
if (pTramp1 != pTramp2) {
printf("!!!!!! Trampoling allocation is not deterministic. %p != %p\n", pTramp1, pTramp2);
return 1;
}
else if (pTramp2 == pTramp3) {
printf("!!!!!! Trampoling allocation doesn't skip region. %p == %p\n", pTramp2, pTramp3);
return 2;
}
return 0;
}

62
samples/setdll/Makefile Normal file
View File

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

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

@ -0,0 +1,332 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detours Test Program (setdll.cpp of setdll.exe)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <shellapi.h>
#include <detours.h>
#pragma warning(push)
#if _MSC_VER > 1400
#pragma warning(disable:6102 6103) // /analyze warnings
#endif
#include <strsafe.h>
#pragma warning(pop)
////////////////////////////////////////////////////////////// Error Messages.
//
VOID AssertMessage(PCSTR szMsg, PCSTR szFile, DWORD nLine)
{
printf("ASSERT(%s) failed in %s, line %ld.", 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 %ld.\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: %ld\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: %ld\n",
szNew, GetLastError());
bGood = FALSE;
goto end;
}
if ((pBinary = DetourBinaryOpen(hOld)) == NULL) {
printf("DetourBinaryOpen failed: %ld\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: %ld\n", GetLastError());
}
}
if (!DetourBinaryEditImports(pBinary, NULL,
ListBywayCallback, ListFileCallback,
NULL, NULL)) {
printf("DetourBinaryEditImports failed: %ld\n", GetLastError());
}
if (!DetourBinaryWrite(pBinary, hNew)) {
printf("DetourBinaryWrite failed: %ld\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: %ld\n", szOld, dwError);
bGood = FALSE;
}
}
if (!MoveFileA(szOrg, szOld)) {
printf("Error: Couldn't back up %s to %s: %ld\n",
szOrg, szOld, GetLastError());
bGood = FALSE;
}
if (!MoveFileA(szNew, szOrg)) {
printf("Error: Couldn't install %s as %s: %ld\n",
szNew, szOrg, GetLastError());
bGood = FALSE;
}
}
DeleteFileA(szNew);
}
end:
if (pBinary) {
DetourBinaryClose(pBinary);
pBinary = NULL;
}
if (hNew != INVALID_HANDLE_VALUE) {
CloseHandle(hNew);
hNew = INVALID_HANDLE_VALUE;
}
if (hOld != INVALID_HANDLE_VALUE) {
CloseHandle(hOld);
hOld = INVALID_HANDLE_VALUE;
}
return bGood;
}
//////////////////////////////////////////////////////////////////////////////
//
void PrintUsage(void)
{
printf("Usage:\n"
" setdll [options] binary_files\n"
"Options:\n"
" /d:file.dll : Add file.dll binary files\n"
" /r : Remove extra DLLs from binary files\n"
" /? : This help screen.\n");
}
//////////////////////////////////////////////////////////////////////// main.
//
int CDECL main(int argc, char **argv)
{
BOOL fNeedHelp = FALSE;
PCHAR pszFilePart = NULL;
int arg = 1;
for (; arg < argc; arg++) {
if (argv[arg][0] == '-' || argv[arg][0] == '/') {
CHAR *argn = argv[arg] + 1;
CHAR *argp = argn;
while (*argp && *argp != ':' && *argp != '=')
argp++;
if (*argp == ':' || *argp == '=')
*argp++ = '\0';
switch (argn[0]) {
case 'd': // Set DLL
case 'D':
if ((strchr(argp, ':') != NULL || strchr(argp, '\\') != NULL) &&
GetFullPathNameA(argp, sizeof(s_szDllPath), s_szDllPath, &pszFilePart)) {
}
else {
StringCchPrintfA(s_szDllPath, sizeof(s_szDllPath), "%s", argp);
}
break;
case 'r': // Remove extra set DLLs.
case 'R':
s_fRemove = TRUE;
break;
case '?': // Help
fNeedHelp = TRUE;
break;
default:
fNeedHelp = TRUE;
printf("Bad argument: %s:%s\n", argn, argp);
break;
}
}
}
if (argc == 1) {
fNeedHelp = TRUE;
}
if (!s_fRemove && s_szDllPath[0] == 0) {
fNeedHelp = TRUE;
}
if (fNeedHelp) {
PrintUsage();
return 1;
}
if (s_fRemove) {
printf("Removing extra DLLs from binary files.\n");
}
else {
if (!DoesDllExportOrdinal1(s_szDllPath)) {
printf("Error: %hs does not export function with ordinal #1.\n",
s_szDllPath);
return 2;
}
printf("Adding %hs to binary files.\n", s_szDllPath);
}
for (arg = 1; arg < argc; arg++) {
if (argv[arg][0] != '-' && argv[arg][0] != '/') {
SetFile(argv[arg]);
}
}
return 0;
}
// End of File

120
samples/simple/Makefile Normal file
View File

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

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

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

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

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

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

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

194
samples/slept/Makefile Normal file
View File

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

View File

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

View File

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

View File

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

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

@ -0,0 +1,141 @@
//////////////////////////////////////////////////////////////////////////////
//
// Detour Test Program (dslept.cpp of dslept.dll)
//
// Microsoft Research Detours Package
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// An example dynamically detouring a function.
//
#include <stdio.h>
#include <windows.h>
#include "detours.h"
#include "slept.h"
#include "verify.cpp"
LONG dwSlept = 0;
static DWORD (WINAPI * TrueSleepEx)(DWORD dwMilliseconds, BOOL bAlertable) = NULL;
static int (WINAPI * TrueEntryPoint)(VOID) = NULL;
static int (WINAPI * RawEntryPoint)(VOID) = NULL;
DWORD WINAPI UntimedSleepEx(DWORD dwMilliseconds, BOOL bAlertable)
{
if (TrueSleepEx != NULL) {
return TrueSleepEx(dwMilliseconds, bAlertable);
}
return 0;
}
DWORD WINAPI TimedSleepEx(DWORD dwMilliseconds, BOOL bAlertable)
{
DWORD dwBeg = GetTickCount();
DWORD ret = TrueSleepEx(dwMilliseconds, bAlertable);
DWORD dwEnd = GetTickCount();
InterlockedExchangeAdd(&dwSlept, dwEnd - dwBeg);
return ret;
}
DWORD WINAPI GetSleptTicks(VOID)
{
return dwSlept;
}
int WINAPI TimedEntryPoint(VOID)
{
// We couldn't call LoadLibrary in DllMain,
// so we detour SleepEx here...
LONG error;
TrueSleepEx = (DWORD (WINAPI *)(DWORD, BOOL))
DetourFindFunction("kernel32.dll", "SleepEx");
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)TrueSleepEx, TimedSleepEx);
error = DetourTransactionCommit();
if (error == NO_ERROR) {
printf("dslept" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: "
" Detoured SleepEx().\n");
}
else {
printf("dslept" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: "
" Error detouring SleepEx(): %ld\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(): %ld\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 (%ld), slept %ld ticks.\n", error, dwSlept);
fflush(stdout);
}
return TRUE;
}
//
///////////////////////////////////////////////////////////////// End of File.

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

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

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

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

View File

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

View File

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

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

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

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

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

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

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

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

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

101
samples/syelog/Makefile Normal file
View File

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

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

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

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