mirror of
https://github.com/vosen/ZLUDA.git
synced 2025-04-12 10:48:53 +03:00
Squashed 'ext/detours/' content from commit 39aa864
git-subtree-dir: ext/detours git-subtree-split: 39aa864d2985099c8d847e29a5fb86618039b9c4
This commit is contained in:
72
.github/ISSUE_TEMPLATE/bug-report.md
vendored
Normal file
72
.github/ISSUE_TEMPLATE/bug-report.md
vendored
Normal 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
35
.github/ISSUE_TEMPLATE/question.md
vendored
Normal 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.
|
13
.github/PULL_REQUEST_TEMPLATE/pull_request_template.md
vendored
Normal file
13
.github/PULL_REQUEST_TEMPLATE/pull_request_template.md
vendored
Normal 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
6
.github/codeql/codeql-config.yml
vendored
Normal 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
77
.github/workflows/main.yml
vendored
Normal 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
41
.gitignore
vendored
Normal 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
118
CREDITS.TXT
Normal 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
23
LICENSE.md
Normal file
@ -0,0 +1,23 @@
|
||||
# Copyright (c) Microsoft Corporation
|
||||
|
||||
All rights reserved.
|
||||
|
||||
# MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
63
Makefile
Normal file
63
Makefile
Normal 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
56
README.md
Normal 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
307
samples/Makefile
Normal 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
65
samples/README.TXT
Normal 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
116
samples/comeasy/Makefile
Normal file
@ -0,0 +1,116 @@
|
||||
##############################################################################
|
||||
##
|
||||
## API Extension to Measure time slept.
|
||||
##
|
||||
## Microsoft Research Detours Package
|
||||
##
|
||||
## Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
##
|
||||
|
||||
!include ..\common.mak
|
||||
|
||||
LIBS=$(LIBS) kernel32.lib
|
||||
|
||||
##############################################################################
|
||||
|
||||
all: dirs \
|
||||
$(BIND)\wrotei$(DETOURS_BITS).dll \
|
||||
$(BIND)\comeasy.exe \
|
||||
!IF $(DETOURS_SOURCE_BROWSING)==1
|
||||
$(OBJD)\wrotei$(DETOURS_BITS).bsc \
|
||||
$(OBJD)\comeasy.bsc \
|
||||
!ENDIF
|
||||
option
|
||||
|
||||
##############################################################################
|
||||
|
||||
clean:
|
||||
-del $(BIND)\wrotei*.* 2>nul
|
||||
-del $(BIND)\comeasy.* 2>nul
|
||||
-del $(BIND)\wrotei.* *~ 2>nul
|
||||
-rmdir /q /s $(OBJD) 2>nul
|
||||
|
||||
realclean: clean
|
||||
-rmdir /q /s $(OBJDS) 2>nul
|
||||
|
||||
dirs:
|
||||
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
|
||||
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
|
||||
|
||||
##############################################################################
|
||||
|
||||
$(OBJD)\wrotei.obj : wrotei.cpp
|
||||
|
||||
$(OBJD)\wrotei.res : wrotei.rc
|
||||
|
||||
$(BIND)\wrotei$(DETOURS_BITS).dll $(BIND)\wrotei$(DETOURS_BITS).lib: \
|
||||
$(OBJD)\wrotei.obj $(OBJD)\wrotei.res $(DEPS)
|
||||
cl /LD $(CFLAGS) /Fe$(@R).dll /Fd$(@R).pdb \
|
||||
$(OBJD)\wrotei.obj $(OBJD)\wrotei.res \
|
||||
/link $(LINKFLAGS) /subsystem:console \
|
||||
/export:DetourFinishHelperProcess,@1,NONAME \
|
||||
$(LIBS) ole32.lib
|
||||
|
||||
$(OBJD)\wrotei$(DETOURS_BITS).bsc : $(OBJD)\wrotei.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\wrotei.sbr
|
||||
|
||||
$(OBJD)\comeasy.obj : comeasy.cpp
|
||||
|
||||
$(BIND)\comeasy.exe : $(OBJD)\comeasy.obj $(DEPS)
|
||||
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb \
|
||||
$(OBJD)\comeasy.obj \
|
||||
/link $(LINKFLAGS) $(LIBS) ole32.lib \
|
||||
/subsystem:console /fixed:no
|
||||
|
||||
$(OBJD)\comeasy.bsc : $(OBJD)\comeasy.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\comeasy.sbr
|
||||
|
||||
############################################### Install non-bit-size binaries.
|
||||
|
||||
!IF "$(DETOURS_OPTION_PROCESSOR)" != ""
|
||||
|
||||
$(OPTD)\wrotei$(DETOURS_OPTION_BITS).dll:
|
||||
$(OPTD)\wrotei$(DETOURS_OPTION_BITS).pdb:
|
||||
|
||||
$(BIND)\wrotei$(DETOURS_OPTION_BITS).dll : $(OPTD)\wrotei$(DETOURS_OPTION_BITS).dll
|
||||
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
|
||||
$(BIND)\wrotei$(DETOURS_OPTION_BITS).pdb : $(OPTD)\wrotei$(DETOURS_OPTION_BITS).pdb
|
||||
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
|
||||
|
||||
option: \
|
||||
$(BIND)\wrotei$(DETOURS_OPTION_BITS).dll \
|
||||
$(BIND)\wrotei$(DETOURS_OPTION_BITS).pdb \
|
||||
|
||||
!ELSE
|
||||
|
||||
option:
|
||||
|
||||
!ENDIF
|
||||
|
||||
##############################################################################
|
||||
|
||||
test: all
|
||||
@echo -------- Reseting test binaries to initial state. -----------------------
|
||||
$(BIND)\setdll.exe -r $(BIND)\comeasy.exe
|
||||
@echo.
|
||||
@echo -------- Should not load slept$(DETOURS_BITS).dll --------------------------------------
|
||||
$(BIND)\comeasy.exe
|
||||
@echo.
|
||||
@echo -------- Adding wrotei$(DETOURS_BITS).dll to comeasy.exe ------------------------------
|
||||
$(BIND)\setdll.exe -d:$(BIND)\wrotei$(DETOURS_BITS).dll $(BIND)\comeasy.exe
|
||||
@echo.
|
||||
@echo -------- Should load wrotei$(DETOURS_BITS).dll ----------------------------------------
|
||||
$(BIND)\comeasy.exe
|
||||
@echo.
|
||||
@echo -------- Removing wrotei$(DETOURS_BITS).dll from comeasy.exe --------------------------
|
||||
$(BIND)\setdll.exe -r $(BIND)\comeasy.exe
|
||||
@echo.
|
||||
@echo -------- Should not load wrotei$(DETOURS_BITS).dll ------------------------------------
|
||||
$(BIND)\comeasy.exe
|
||||
@echo.
|
||||
@echo -------- Should load wrotei$(DETOURS_BITS).dll dynamically using withdll.exe ----------
|
||||
$(BIND)\withdll.exe -d:$(BIND)\wrotei$(DETOURS_BITS).dll $(BIND)\comeasy.exe
|
||||
@echo.
|
||||
@echo -------- Test completed. ------------------------------------------------
|
||||
|
||||
################################################################# End of File.
|
69
samples/comeasy/comeasy.cpp
Normal file
69
samples/comeasy/comeasy.cpp
Normal file
@ -0,0 +1,69 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detour Test Program (comeasy.cpp of comeasy.exe)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
|
||||
#include <ole2.h>
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
int __cdecl main(int argc, char **argv)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
LPSTREAM pStream = NULL;
|
||||
ULARGE_INTEGER ul;
|
||||
LARGE_INTEGER li;
|
||||
|
||||
printf("comeasy.exe: Starting (at %p).\n", main);
|
||||
|
||||
CoInitialize(NULL);
|
||||
|
||||
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
|
||||
|
||||
ul.QuadPart = 512;
|
||||
hr = pStream->SetSize(ul);
|
||||
|
||||
li.QuadPart = 0;
|
||||
hr = pStream->Seek(li, STREAM_SEEK_SET, NULL);
|
||||
|
||||
printf("comeasy.exe: First write.\n");
|
||||
fflush(stdout);
|
||||
|
||||
li.QuadPart = 0;
|
||||
hr = pStream->Write(&ul, sizeof(ul), NULL);
|
||||
|
||||
printf("comeasy.exe: Second write.\n");
|
||||
fflush(stdout);
|
||||
|
||||
li.QuadPart = 1;
|
||||
hr = pStream->Write(&li, sizeof(li), NULL);
|
||||
|
||||
printf("comeasy.exe: Third write.\n");
|
||||
fflush(stdout);
|
||||
|
||||
li.QuadPart = 2;
|
||||
hr = pStream->Write(&li, sizeof(li), NULL);
|
||||
|
||||
pStream->Release();
|
||||
pStream = NULL;
|
||||
|
||||
CoUninitialize();
|
||||
|
||||
printf("comeasy.exe: Exiting.\n\n");
|
||||
fflush(stdout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
///////////////////////////////////////////////////////////////// End of File.
|
167
samples/comeasy/wrotei.cpp
Normal file
167
samples/comeasy/wrotei.cpp
Normal file
@ -0,0 +1,167 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detour Test Program (wrotei.cpp of wrotei.dll)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// An example dynamically detouring a function.
|
||||
//
|
||||
#include <stdio.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// WARNING:
|
||||
//
|
||||
// CINTERFACE must be defined so that the lpVtbl pointer is visible
|
||||
// on COM interfaces. However, once we've defined it, we must use
|
||||
// coding conventions when accessing interface members, for example:
|
||||
// i->lpVtbl->Write
|
||||
// instead of the C++ syntax:
|
||||
// i->Write.
|
||||
// We must also pass the implicit "this" parameter explicitly:
|
||||
// i->lpVtbl->Write(i, pb, 0, NULL)
|
||||
// instead of the C++ syntax:
|
||||
// i->Write(pb, 0, NULL)
|
||||
//
|
||||
#define CINTERFACE
|
||||
#include <ole2.h>
|
||||
#include <windows.h>
|
||||
#include <detours.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
LONG dwWrote = 0;
|
||||
|
||||
static int (WINAPI * TrueEntryPoint)(VOID) = NULL;
|
||||
static int (WINAPI * RawEntryPoint)(VOID) = NULL;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
HRESULT (STDMETHODCALLTYPE *RealIStreamWrite)(IStream * This,
|
||||
const void *pv,
|
||||
ULONG cb,
|
||||
ULONG *pcbWritten) = NULL;
|
||||
|
||||
HRESULT STDMETHODCALLTYPE MineIStreamWrite(IStream * This,
|
||||
const void *pv,
|
||||
ULONG cb,
|
||||
ULONG *pcbWritten)
|
||||
{
|
||||
HRESULT hr;
|
||||
ULONG cbWritten = 0;
|
||||
if (pcbWritten == NULL) {
|
||||
pcbWritten = &cbWritten;
|
||||
}
|
||||
|
||||
hr = RealIStreamWrite(This, pv, cb, pcbWritten);
|
||||
|
||||
for (;;) {
|
||||
LONG dwOld = dwWrote;
|
||||
LONG dwNew = dwOld + *pcbWritten;
|
||||
|
||||
if (InterlockedCompareExchange(&dwWrote, dwNew, dwOld) == dwOld) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
int WINAPI TimedEntryPoint(VOID)
|
||||
{
|
||||
// We couldn't call CoInitializeEx in DllMain,
|
||||
// so we detour the vtable entries here...
|
||||
LONG error;
|
||||
LPSTREAM pStream = NULL;
|
||||
|
||||
// Create a temporary object so we can get a vtable.
|
||||
CreateStreamOnHGlobal(NULL, TRUE, &pStream);
|
||||
|
||||
// Apply the detour to the vtable.
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
if (pStream != NULL) {
|
||||
RealIStreamWrite = pStream->lpVtbl->Write;
|
||||
DetourAttach(&(PVOID&)RealIStreamWrite, MineIStreamWrite);
|
||||
}
|
||||
error = DetourTransactionCommit();
|
||||
|
||||
if (pStream != NULL) {
|
||||
pStream->lpVtbl->Release(pStream);
|
||||
pStream = NULL;
|
||||
}
|
||||
|
||||
if (error == NO_ERROR) {
|
||||
printf("wrotei" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
|
||||
" Detoured IStream::Wrote() from OnHGlobal.\n");
|
||||
}
|
||||
else {
|
||||
printf("wrotei" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
|
||||
" Error detouring IStram::Wrote(): %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
17
samples/comeasy/wrotei.rc
Normal file
@ -0,0 +1,17 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version information for wrotei.rc.
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
|
||||
#include "detver.h"
|
||||
|
||||
#define VER_INTERNALNAME_STR "wrotei" DETOURS_STRINGIFY(DETOURS_BITS)
|
||||
#define VER_ORIGINALFILENAME_STR "wrotei" DETOURS_STRINGIFY(DETOURS_BITS) ".dll"
|
||||
#define VER_FILEDESCRIPTION_STR "Detours COM Easy Sample"
|
||||
#define VER_COMPANYNAME_STR "Microsoft Corporation"
|
||||
|
||||
#include "common.ver"
|
48
samples/commem/Makefile
Normal file
48
samples/commem/Makefile
Normal file
@ -0,0 +1,48 @@
|
||||
##############################################################################
|
||||
##
|
||||
## Makefile for Detours Test Programs.
|
||||
##
|
||||
## Microsoft Research Detours Package
|
||||
##
|
||||
## Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
##
|
||||
|
||||
!include ..\common.mak
|
||||
|
||||
LIBS=$(LIBS) kernel32.lib
|
||||
|
||||
all: dirs \
|
||||
$(BIND)\commem.exe \
|
||||
!IF $(DETOURS_SOURCE_BROWSING)==1
|
||||
$(OBJD)\commem.bsc
|
||||
!ENDIF
|
||||
|
||||
clean:
|
||||
-del *~ *.obj *.sbr 2> nul
|
||||
-del $(BIND)\commem.* 2> nul
|
||||
-rmdir /q /s $(OBJD) 2>nul
|
||||
|
||||
realclean: clean
|
||||
-rmdir /q /s $(OBJDS) 2>nul
|
||||
|
||||
dirs:
|
||||
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
|
||||
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
|
||||
|
||||
$(BIND)\commem.obj : commem.cpp
|
||||
|
||||
$(BIND)\commem.exe : $(OBJD)\commem.obj $(DEPS)
|
||||
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\commem.obj \
|
||||
/link $(LINKFLAGS) $(LIBS) ole32.lib /subsystem:console
|
||||
|
||||
$(OBJD)\commem.bsc : $(OBJD)\commem.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\commem.sbr
|
||||
|
||||
##############################################################################
|
||||
|
||||
test: $(BIND)\commem.exe
|
||||
@echo.
|
||||
$(BIND)\commem.exe
|
||||
@echo.
|
||||
|
||||
################################################################# End of File.
|
114
samples/commem/commem.cpp
Normal file
114
samples/commem/commem.cpp
Normal file
@ -0,0 +1,114 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detour functions of a COM interface (commem.cpp of commem.exe)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
//
|
||||
//
|
||||
#include <stdio.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// WARNING:
|
||||
//
|
||||
// CINTERFACE must be defined so that the lpVtbl pointer is visible
|
||||
// on COM interfaces. However, once we've defined it, we must use
|
||||
// coding conventions when accessing interface members, for example:
|
||||
// i->lpVtbl->Write
|
||||
// instead of the C++ syntax:
|
||||
// i->Write.
|
||||
// We must also pass the implicit "this" parameter explicitly:
|
||||
// i->lpVtbl->Write(i, pb, 0, NULL)
|
||||
// instead of the C++ syntax:
|
||||
// i->Write(pb, 0, NULL)
|
||||
//
|
||||
#define CINTERFACE
|
||||
#include <ole2.h>
|
||||
#include <windows.h>
|
||||
#include <detours.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
HRESULT (STDMETHODCALLTYPE *RealIStreamWrite)(IStream * This,
|
||||
const void *pv,
|
||||
ULONG cb,
|
||||
ULONG *pcbWritten) = NULL;
|
||||
|
||||
HRESULT STDMETHODCALLTYPE MineIStreamWrite(IStream * This,
|
||||
const void *pv,
|
||||
ULONG cb,
|
||||
ULONG *pcbWritten)
|
||||
{
|
||||
HRESULT hr;
|
||||
ULONG cbWritten = 0;
|
||||
if (pcbWritten == NULL) {
|
||||
pcbWritten = &cbWritten;
|
||||
}
|
||||
|
||||
printf("commem: %p->IStreamWrite(pv=%p, cb=%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
86
samples/common.mak
Normal file
@ -0,0 +1,86 @@
|
||||
##############################################################################
|
||||
##
|
||||
## Common makefile for Detours test programs.
|
||||
##
|
||||
## Microsoft Research Detours Package
|
||||
##
|
||||
## Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
##
|
||||
|
||||
!IF "$(ROOT)" == ""
|
||||
ROOT = ..\..
|
||||
!ENDIF
|
||||
!include "$(ROOT)\system.mak"
|
||||
|
||||
!IF "$(DETOURS_SOURCE_BROWSING)" == ""
|
||||
DETOURS_SOURCE_BROWSING=0
|
||||
!ENDIF
|
||||
|
||||
##############################################################################
|
||||
|
||||
!IFNDEF CLIB
|
||||
CLIB=/MT
|
||||
!ENDIF
|
||||
|
||||
AFLAGS=/nologo /Zi /c /Fl
|
||||
CFLAGS=/nologo /Zi $(CLIB) /Gm- /W4 /WX /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
130
samples/cping/Makefile
Normal file
@ -0,0 +1,130 @@
|
||||
##############################################################################
|
||||
##
|
||||
## Makefile for Detours Test Programs.
|
||||
##
|
||||
## Microsoft Research Detours Package
|
||||
##
|
||||
## Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
##
|
||||
|
||||
!include ..\common.mak
|
||||
|
||||
LIBS=$(LIBS) \
|
||||
kernel32.lib \
|
||||
user32.lib \
|
||||
shell32.lib \
|
||||
uuid.lib \
|
||||
ole32.lib \
|
||||
rpcrt4.lib \
|
||||
advapi32.lib \
|
||||
wsock32.lib \
|
||||
|
||||
# RpcProxy.h uses #ifdef WIN32.
|
||||
|
||||
!if "$(DETOURS_TARGET_PROCESSOR)" == "ARM"
|
||||
CFLAGS = $(CFLAGS) /D_WIN32_WINNT=0x0500
|
||||
!else
|
||||
CFLAGS = $(CFLAGS) /D_WIN32_WINNT=0x0400
|
||||
!endif
|
||||
|
||||
CFLAGS = $(CFLAGS) /Fd$(OBJD)\vc.pdb \
|
||||
/DCONST_VTABLE \
|
||||
/DCOBJMACROS -DWIN32 -DNT
|
||||
|
||||
C__FLAGS=-DENTRY_PREFIX=iping_ -DREGISTER_PROXY_DLL
|
||||
CPPFLAGS=
|
||||
|
||||
##############################################################################
|
||||
|
||||
.SUFFIXES: .c .cpp .h .idl .obj .res .rc
|
||||
|
||||
{$(OBJD)}.c{$(OBJD)}.obj:
|
||||
$(CC) $(CFLAGS:/W4=/W3) $(C__FLAGS) /I$(OBJD) /Fo$(OBJD)\ /c $<
|
||||
|
||||
!ifdef DETOURS_ANALYZE
|
||||
.cpp{$(OBJD)}.obj:
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) /I$(OBJD) /Fo$(OBJD)\ /c $<
|
||||
!else
|
||||
.cpp{$(OBJD)}.obj::
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) /I$(OBJD) /Fo$(OBJD)\ /c $<
|
||||
!endif
|
||||
|
||||
.rc{$(OBJD)}.res:
|
||||
rc /nologo /Fo$@ .\$(*B).rc
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
C__FLAGS=-DENTRY_PREFIX=iping_ -DREGISTER_PROXY_DLL
|
||||
CPPFLAGS=
|
||||
|
||||
|
||||
MIDLFLAGS=/nologo /Oif /no_format_opt
|
||||
|
||||
!IF "$(DETOURS_TARGET_PROCESSOR)" == "X86"
|
||||
MIDLFLAGS=$(MIDLFLAGS) /no_robust /win32
|
||||
!ELSEIF "$(DETOURS_TARGET_PROCESSOR)" == "IA64"
|
||||
MIDLFLAGS=$(MIDLFLAGS) /ia64
|
||||
!ELSEIF "$(DETOURS_TARGET_PROCESSOR)" == "X64"
|
||||
MIDLFLAGS=$(MIDLFLAGS) /x64
|
||||
!ELSEIF "$(DETOURS_TARGET_PROCESSOR)" == "ARM"
|
||||
MIDLFLAGS=$(MIDLFLAGS) /arm32
|
||||
!ELSEIF "$(DETOURS_TARGET_PROCESSOR)" == "ARM64"
|
||||
MIDLFLAGS=$(MIDLFLAGS) /arm64
|
||||
!ENDIF
|
||||
|
||||
OBJS = \
|
||||
$(OBJD)\cping.obj \
|
||||
\
|
||||
$(OBJD)\iping_i.obj \
|
||||
$(OBJD)\iping_p.obj \
|
||||
$(OBJD)\iping_d.obj \
|
||||
|
||||
##############################################################################
|
||||
|
||||
all: dirs \
|
||||
$(BIND)\cping.exe \
|
||||
!IF $(DETOURS_SOURCE_BROWSING)==1
|
||||
$(OBJD)\cping.bsc
|
||||
!ENDIF
|
||||
|
||||
##############################################################################
|
||||
|
||||
clean:
|
||||
-del iping.h *.c *.obj *.sbr *~ 2>nul
|
||||
-del $(BIND)\cping.* 2>nul
|
||||
-rmdir /q /s $(OBJD) 2>nul
|
||||
|
||||
realclean: clean
|
||||
-rmdir /q /s $(OBJDS) 2>nul
|
||||
|
||||
##############################################################################
|
||||
|
||||
dirs:
|
||||
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
|
||||
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
|
||||
|
||||
$(OBJD)\cping.bsc : $(OBJS)
|
||||
bscmake /v /n /o $@ $(OBJS:.obj=.sbr)
|
||||
|
||||
$(BIND)\cping.exe : $(OBJS) $(DEPS)
|
||||
cl $(CFLAGS) /Fe$@ $(OBJS) /link $(LINKFLAGS) \
|
||||
/subsystem:console $(LIBS)
|
||||
|
||||
$(OBJD)\cping.obj: cping.cpp $(OBJD)\iping.h
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
$(OBJD)\iping.h $(OBJD)\iping_d.c $(OBJD)\iping_i.c $(OBJD)\iping_p.c : iping.idl
|
||||
midl $(MIDLFLAGS) /out $(OBJD) /prefix all iping_ /dlldata iping_d.c iping.idl
|
||||
|
||||
$(OBJD)\iping_i.obj: $(OBJD)\iping_i.c
|
||||
$(OBJD)\iping_p.obj: $(OBJD)\iping_p.c $(OBJD)\iping.h
|
||||
$(OBJD)\iping_d.obj: $(OBJD)\iping_d.c
|
||||
|
||||
##############################################################################
|
||||
|
||||
test: $(BIND)\cping.exe
|
||||
start $(BIND)\cping.exe /s
|
||||
$(BIND)\cping.exe /p localhost
|
||||
|
||||
################################################################# End of File.
|
47
samples/cping/ReadMe.Txt
Normal file
47
samples/cping/ReadMe.Txt
Normal file
@ -0,0 +1,47 @@
|
||||
Microsoft Research Detours Package
|
||||
==============================================================================
|
||||
4/2/98
|
||||
|
||||
* Instrumentation:
|
||||
Read Pentium cycle counter
|
||||
|
||||
* PC configuration:
|
||||
DCOM/TCP, Windows NT Server 4.0,
|
||||
between two 300MHz Pentium boxes,
|
||||
Ethernet connecction
|
||||
|
||||
* Client test program:
|
||||
HRESULT get(SHORT, SHORT, LONG*)
|
||||
average over 1,000 calls
|
||||
midl /Oicf
|
||||
|
||||
* Results:
|
||||
get() {
|
||||
<-- (1)
|
||||
IRpcChannelBuffer::SendReceive()) {
|
||||
<-- (2)
|
||||
I_RpcSendReceive() {
|
||||
<-- (3)
|
||||
send(soc, )
|
||||
<-- (4)
|
||||
NtWaitForSingleObject(soc, )
|
||||
<-- (5)
|
||||
} // end of RPC layer
|
||||
<-- (6)
|
||||
} // end of channel object
|
||||
<-- (7)
|
||||
} // end of client call
|
||||
Average number
|
||||
of Pentium cycles
|
||||
(1) NDR marshaling overhead (2 SHORTs) 13 K
|
||||
(No! of which 11K from GetBuffer,
|
||||
of which 6.2K from I_RpcGetBuffer()!)
|
||||
(2) Channel object one-way (send) overhead 1.0 K
|
||||
(3) RPC layer one-way (send) overhead 5.3 K
|
||||
(4) TCP + all server work 200 K
|
||||
(5) RPC layer one-way (recv) overhead 5.1 K
|
||||
(6) Channel object one-way (recv) overhead 2.2 K
|
||||
(7) NDR unmarshaling overhead (2 LONGs) 4.2 K
|
||||
|
||||
(*) send() only 17 K
|
||||
TOTAL CYCLES for client get(): 230 K
|
2245
samples/cping/cping.cpp
Normal file
2245
samples/cping/cping.cpp
Normal file
File diff suppressed because it is too large
Load Diff
0
samples/cping/cping.dat
Normal file
0
samples/cping/cping.dat
Normal file
23
samples/cping/iping.idl
Normal file
23
samples/cping/iping.idl
Normal file
@ -0,0 +1,23 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Module: iping.idl (cping.exe - COM Ping)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
import "objidl.idl";
|
||||
import "oaidl.idl";
|
||||
import "oleidl.idl";
|
||||
|
||||
|
||||
[object, uuid(decdbeef-d1ac-11d1-96bc-00aa00573fb0), pointer_default(unique)]
|
||||
interface IPing : IUnknown
|
||||
{
|
||||
HRESULT Ping(void);
|
||||
HRESULT PingToServer([in] LPSTR pszString);
|
||||
HRESULT PingToClient([out] LPSTR *ppszString);
|
||||
HRESULT PingToClientSize([in] ULONG cbOut);
|
||||
};
|
||||
//
|
||||
///////////////////////////////////////////////////////////////// End of File.
|
76
samples/disas/Makefile
Normal file
76
samples/disas/Makefile
Normal file
@ -0,0 +1,76 @@
|
||||
##############################################################################
|
||||
##
|
||||
## Makefile for Detours Test Programs.
|
||||
##
|
||||
## Microsoft Research Detours Package
|
||||
##
|
||||
## Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
##
|
||||
|
||||
!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
232
samples/disas/arm.asm
Normal file
@ -0,0 +1,232 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;
|
||||
;; Detours Test Program (rlo.asm/disas.exe)
|
||||
;;
|
||||
;; Microsoft Research Detours Package
|
||||
;;
|
||||
;; Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
;;
|
||||
|
||||
MACRO
|
||||
BREAK
|
||||
DCW 0xdefe
|
||||
MEND
|
||||
|
||||
AREA |.text|,ALIGN=2,CODE,READONLY
|
||||
|
||||
AREA |.text|,CODE,READONLY
|
||||
|
||||
ALIGN 0x1000
|
||||
|
||||
EXPORT |TestCodes|
|
||||
|TestCodes|
|
||||
|
||||
; dcw 0xf8df,0xe00e ; 94 = -16 = -12 ; 94 ; 98 + e = a6
|
||||
; BREAK ; 98 = -14 = -10 ; 98 ; 9c
|
||||
; dcw 0xf8df,0xe00a ; 9a = -12 = -8 ; 98 ; 9c + a = a6
|
||||
; BREAK ; 9e = -8 = -4 ; 9c ; a0
|
||||
; dcw 0xf8df,0xe002 ; a0 = -6 = -2 ; a0 ; a4 + 2 = a6
|
||||
; BREAK ; a4 = -2 ; a4 ; a8
|
||||
; movs r2, r0 ; a6 <===
|
||||
; movs r3, r0 ;
|
||||
; BREAK
|
||||
; BREAK
|
||||
;
|
||||
; ldr lr,=0xa98765
|
||||
; ldr pc,=0xa98765
|
||||
; ldr pc,=0xa98765
|
||||
; ldr pc,=0xa98765
|
||||
; BREAK
|
||||
; BREAK
|
||||
|
||||
BREAK
|
||||
ldr lr, =0xa98765
|
||||
BREAK
|
||||
blx lr
|
||||
|
||||
BREAK
|
||||
pop pc
|
||||
BREAK
|
||||
pop {r11,pc}
|
||||
BREAK
|
||||
pop {r10,r11,pc}
|
||||
BREAK
|
||||
pop {r9,r10,r11,pc}
|
||||
BREAK
|
||||
pop {r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,pc}
|
||||
|
||||
BREAK
|
||||
ldr.w r0,=0xa98765
|
||||
BREAK
|
||||
nop
|
||||
ldr.w r0,=0xa98765
|
||||
BREAK
|
||||
nop
|
||||
nop
|
||||
ldr.w r0,=0xa98765
|
||||
|
||||
BREAK
|
||||
ldr r0,=0xa98765
|
||||
BREAK
|
||||
ldr.w r0,=0xa98765
|
||||
BREAK
|
||||
ldr.w r0,=0xa98765
|
||||
BREAK
|
||||
ldr r0,=0xa98765
|
||||
BREAK
|
||||
ldr.w r0,=0xa98765
|
||||
BREAK
|
||||
ldr.w r0,=0xa98765
|
||||
BREAK
|
||||
ldr r0,=0xa98765
|
||||
BREAK
|
||||
ldr.w r0,=0xa98765
|
||||
BREAK
|
||||
ldr.w r0,=0xa98765
|
||||
|
||||
BREAK
|
||||
ldr r0,=0xa98765
|
||||
BREAK
|
||||
nop
|
||||
ldr r0,=0xa98765
|
||||
BREAK
|
||||
nop
|
||||
nop
|
||||
ldr r0,=0xa98765
|
||||
|
||||
BREAK
|
||||
nop
|
||||
ldr r0,=0xa
|
||||
BREAK
|
||||
ldr r0,=0xa9
|
||||
BREAK
|
||||
ldr r0,=0xa98
|
||||
BREAK
|
||||
ldr r0,=0xa987
|
||||
BREAK
|
||||
ldr r0,=0xa9876
|
||||
BREAK
|
||||
ldr r0,=0xa98765
|
||||
BREAK
|
||||
ldr r0,=0xa987654
|
||||
BREAK
|
||||
ldr r0,=0xa9876543
|
||||
|
||||
;; Simple instructions.
|
||||
BREAK
|
||||
adds r0,r0, #5 ; 1d40
|
||||
BREAK
|
||||
movs r2, #0 ; 2200
|
||||
BREAK
|
||||
movs r3, #0 ; 2300
|
||||
BREAK
|
||||
bx lr ; 4770 [FFFFFFFF]
|
||||
|
||||
;; Known 16-bit instructions
|
||||
BREAK
|
||||
mov r11, sp ; 46eb
|
||||
BREAK
|
||||
movs r2, r0 ; 0002
|
||||
BREAK
|
||||
push r0, r1 ; b403
|
||||
BREAK
|
||||
str r3,[r7,#0x28] ; 62bb
|
||||
BREAK
|
||||
bx r5 ; 4728 [FFFFFFFF]
|
||||
BREAK
|
||||
blx r5 ; 47a8
|
||||
BREAK
|
||||
DCW 0x4878 ; ldr r0, [PC + 0x1E0] ; 4878
|
||||
BREAK
|
||||
str r3,[r7,#0x1C] ; 61fb
|
||||
BREAK
|
||||
ldr r3,[r7,#0x38] ; 6bbb
|
||||
BREAK
|
||||
add r3,sp,#0xCC ; ab33
|
||||
BREAK
|
||||
cbz r2,+0x56 ; b34a [00xx1510]
|
||||
BREAK
|
||||
cbnz r2,+0x56 ; bb4a [00xx1514]
|
||||
BREAK
|
||||
push {r0,r2,r4,r6,lr} ; b555
|
||||
BREAK
|
||||
nop ; bf00
|
||||
|
||||
;; Placeholder for IT instruction
|
||||
BREAK
|
||||
bne +0x6E ; d135 [00xx1538] -??? d137
|
||||
BREAK
|
||||
svc #0x24 ; df24
|
||||
BREAK
|
||||
b +0x7FE ; e3fd [00xx1cd0] -??? e3ff
|
||||
|
||||
;; 32 bit test codes
|
||||
BREAK
|
||||
adds r0,r7,#8 ; f1170008
|
||||
BREAK
|
||||
str r3,[r5,#0x677] ; f8c53677
|
||||
BREAK
|
||||
ldrsh r10,[r5,#0x5A5] ; f9b5a5a5
|
||||
BREAK
|
||||
DCW 0xf89f,0x55a5 ;ldrb r5, [+0x5A5] ; f89f55a5
|
||||
BREAK
|
||||
bls.w +0x86; 0xf240; 0x8043; // ; f2408041 [00xx157A]
|
||||
BREAK
|
||||
bl +0xFE; 0xf7ff; 0xff80; //
|
||||
BREAK
|
||||
bl +0xFFE; 0xf7ff; 0xff80; //
|
||||
BREAK
|
||||
bl +0xFFFE; 0xf7ff; 0xff80; //
|
||||
BREAK
|
||||
bl +0xFFFFE; 0xf7ff; 0xff80; //
|
||||
BREAK
|
||||
bl +0xFFFFFE; 0xf7ff; 0xff80; //
|
||||
BREAK
|
||||
bl +0xF0; 0xf7ff; 0xff80; //
|
||||
BREAK
|
||||
bl +0xFF0; 0xf7ff; 0xff80; //
|
||||
BREAK
|
||||
bl +0xFFF0; 0xf7ff; 0xff80; //
|
||||
BREAK
|
||||
bl +0xFFFF0; 0xf7ff; 0xff80; //
|
||||
BREAK
|
||||
bl +0xFFFFF0; 0xf7ff; 0xff80; //
|
||||
BREAK
|
||||
bl +0xF00; 0xf7ff; 0xff80; //
|
||||
BREAK
|
||||
bl +0xFF00; 0xf7ff; 0xff80; //
|
||||
BREAK
|
||||
bl +0xFFF00; 0xf7ff; 0xff80; //
|
||||
BREAK
|
||||
bl +0xFFFF00; 0xf7ff; 0xff80; //
|
||||
BREAK
|
||||
DCW 0xf7ff,0xff80
|
||||
;bl +0xFFFFFF00; 0xf7ff; 0xff80; //
|
||||
BREAK
|
||||
DCW 0xf7ff,0xbe02
|
||||
; b.w ; 0xf7ff; 0xbe02; // (10053528)
|
||||
BREAK
|
||||
push {r7,r11,lr}; 0xe92d; 0x4880; //
|
||||
|
||||
;; 32 bit expected results
|
||||
BREAK
|
||||
adds r0,r7,#8 ; 0xf1170008
|
||||
BREAK
|
||||
str r3,[r5,#0x677] ; 0xf8c53677
|
||||
BREAK
|
||||
ldrsh r10,[r5,#0x5A5] ; 0xf9b5a5a5
|
||||
|
||||
BREAK
|
||||
DCW 0xf6af,0xfbd2
|
||||
; bl (0008ef3c); ResultCode(4, 0xf6af, 0xfbd2, Target(ADDRESS(&g_pTestCodes32[i*2], 0xFFFFFF00))); // 0xf7ff, 0xff80: -> 0xf6affbd2
|
||||
BREAK
|
||||
bl (00090300); ResultCode(4, 0xf6af, 0xba54, Target(ADDRESS(&g_pTestCodes32[i*2], 0xFFFFFC04))); // 0xf7ff, 0xff80: -> f6afba54 bl (00090300)
|
||||
BREAK
|
||||
push {r7,r11,lr}; ResultCode(4, 0xe92d, 0x4880); // 0xe92d, 0x4880: //
|
||||
|
||||
BREAK
|
||||
BREAK
|
||||
|
||||
|TestCodes_end|
|
||||
|
||||
END
|
702
samples/disas/disas.cpp
Normal file
702
samples/disas/disas.cpp
Normal 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
1084
samples/disas/ia64.asm
Normal file
File diff suppressed because it is too large
Load Diff
15
samples/disas/unk.cpp
Normal file
15
samples/disas/unk.cpp
Normal file
@ -0,0 +1,15 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detours Test Program (x86.asm of disas.exe)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
|
||||
static int value = 0;
|
||||
|
||||
extern "C" void TestCodes()
|
||||
{
|
||||
value++;
|
||||
}
|
520
samples/disas/x64.asm
Normal file
520
samples/disas/x64.asm
Normal file
@ -0,0 +1,520 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;
|
||||
;; Detours Test Program (x64.asm/disas.exe)
|
||||
;;
|
||||
;; Microsoft Research Detours Package
|
||||
;;
|
||||
;; Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
;;
|
||||
|
||||
.xlist
|
||||
.list
|
||||
.code
|
||||
|
||||
PUBLIC TestCodes
|
||||
|
||||
_TEXT SEGMENT
|
||||
|
||||
TestCodes PROC
|
||||
|
||||
begin:
|
||||
faraway:
|
||||
int 3
|
||||
nop
|
||||
int 3
|
||||
db 066h,090h ; // 2-byte NOP.
|
||||
int 3
|
||||
db 00fh, 01fh, 000h ; // 3-byte NOP.
|
||||
int 3
|
||||
db 00fh, 01fh, 040h, 000h ; // 4-byte NOP.
|
||||
int 3
|
||||
db 00fh, 01fh, 044h, 000h, 000h ; // 5-byte NOP.
|
||||
int 3
|
||||
db 066h, 00fh, 01fh, 044h, 000h, 000h ; // 6-byte NOP.
|
||||
int 3
|
||||
db 00fh, 01fh, 080h, 000h, 000h, 000h, 000h ; // 7-byte NOP.
|
||||
int 3
|
||||
db 00fh, 01fh, 084h, 000h, 000h, 000h, 000h, 000h ; // 8-byte NOP.
|
||||
int 3
|
||||
db 066h, 00fh, 01fh, 084h, 000h, 000h, 000h, 000h, 000h ; // 9-byte NOP.
|
||||
int 3
|
||||
mov rax, cr8
|
||||
int 3
|
||||
mov rcx, cr8
|
||||
int 3
|
||||
mov rdx, cr8
|
||||
int 3
|
||||
mov rbx, cr8
|
||||
int 3
|
||||
mov rsp, cr8
|
||||
int 3
|
||||
mov rbp, cr8
|
||||
int 3
|
||||
mov rsi, cr8
|
||||
int 3
|
||||
mov rdi, cr8
|
||||
int 3
|
||||
mov r8, cr8
|
||||
int 3
|
||||
mov r9, cr8
|
||||
int 3
|
||||
mov r10, cr8
|
||||
int 3
|
||||
mov r11, cr8
|
||||
int 3
|
||||
mov r12, cr8
|
||||
int 3
|
||||
mov r13, cr8
|
||||
int 3
|
||||
mov r14, cr8
|
||||
int 3
|
||||
mov r15, cr8
|
||||
int 3
|
||||
mov cr8, rax
|
||||
int 3
|
||||
mov cr8, rcx
|
||||
int 3
|
||||
mov cr8, rdx
|
||||
int 3
|
||||
mov cr8, rbx
|
||||
int 3
|
||||
mov cr8, rsp
|
||||
int 3
|
||||
mov cr8, rbp
|
||||
int 3
|
||||
mov cr8, rsi
|
||||
int 3
|
||||
mov cr8, rdi
|
||||
int 3
|
||||
mov cr8, r8
|
||||
int 3
|
||||
mov cr8, r9
|
||||
int 3
|
||||
mov cr8, r10
|
||||
int 3
|
||||
mov cr8, r11
|
||||
int 3
|
||||
mov cr8, r12
|
||||
int 3
|
||||
mov cr8, r13
|
||||
int 3
|
||||
mov cr8, r14
|
||||
int 3
|
||||
mov cr8, r15
|
||||
int 3
|
||||
xor rax, rax
|
||||
int 3
|
||||
xor rcx, rcx
|
||||
int 3
|
||||
xor rdx, rdx
|
||||
int 3
|
||||
xor rbx, rbx
|
||||
int 3
|
||||
xor rsp, rsp
|
||||
int 3
|
||||
xor rbp, rbp
|
||||
int 3
|
||||
xor rsi, rsi
|
||||
int 3
|
||||
xor rdi, rdi
|
||||
int 3
|
||||
xor r8, r8
|
||||
int 3
|
||||
xor r9, r9
|
||||
int 3
|
||||
xor r10, r10
|
||||
int 3
|
||||
xor r11, r11
|
||||
int 3
|
||||
xor r12, r12
|
||||
int 3
|
||||
xor r13, r13
|
||||
int 3
|
||||
xor r14, r14
|
||||
int 3
|
||||
xor r15, r15
|
||||
int 3
|
||||
jmp rax
|
||||
int 3
|
||||
jmp rbx
|
||||
int 3
|
||||
jmp rcx
|
||||
int 3
|
||||
jmp rdx
|
||||
int 3
|
||||
push rax
|
||||
int 3
|
||||
push rbx
|
||||
int 3
|
||||
push rcx
|
||||
int 3
|
||||
push rdx
|
||||
int 3
|
||||
push 0
|
||||
int 3
|
||||
pop rax
|
||||
int 3
|
||||
pop rbx
|
||||
int 3
|
||||
pop rcx
|
||||
int 3
|
||||
pop rdx
|
||||
int 3
|
||||
mov rax,[value]
|
||||
int 3
|
||||
sub rsp,0418h
|
||||
int 3
|
||||
mov [rsp+0410h],rbx
|
||||
int 3
|
||||
mov [rsp+0408h],rsi
|
||||
int 3
|
||||
mov [rsp+0400h],rdi
|
||||
int 3
|
||||
mov [rsp+03f8h],r12
|
||||
int 3
|
||||
mov [rsp+03f0h],r13
|
||||
int 3
|
||||
mov [rsp+03e8h],r14
|
||||
int 3
|
||||
mov [rsp+03e0h],r15
|
||||
int 3
|
||||
add [rax],al ; 0000
|
||||
int 3
|
||||
add [rcx],al ; 0001
|
||||
int 3
|
||||
add [rbx],al ; 0003
|
||||
int 3
|
||||
add [rax+rax],al ; 000400
|
||||
int 3
|
||||
add [rdi],al ; 0007
|
||||
int 3
|
||||
add [rax],cl ; 0008
|
||||
int 3
|
||||
add [rdi],cl ; 000f
|
||||
int 3
|
||||
add [rax],dl ; 0010
|
||||
int 3
|
||||
add [rdi],bl ; 001f
|
||||
int 3
|
||||
add [rax],ah ; 0020
|
||||
int 3
|
||||
add [rdi],bh ; 003f
|
||||
int 3
|
||||
add [rax+03bh],cl ; 00483b
|
||||
int 3
|
||||
add [rdi],bh ; 007f00
|
||||
int 3
|
||||
add [rax+040000000h],al ; 008000000040
|
||||
int 3
|
||||
add bh,bh ; 00ff
|
||||
int 3
|
||||
add [rax],eax ; 0100
|
||||
int 3
|
||||
add al,[rax] ; 0200
|
||||
int 3
|
||||
add eax,06603ebc3h ; 05c3eb0366
|
||||
int 3
|
||||
syscall ; 0f05
|
||||
int 3
|
||||
prefetchw byte ptr [rcx] ; 0f0d09
|
||||
int 3
|
||||
prefetchnta byte ptr [rcx] ; 0f1801
|
||||
int 3
|
||||
prefetchnta byte ptr [rax+rdx] ; 0f180410
|
||||
int 3
|
||||
jb again ; 0f8247070000
|
||||
int 3
|
||||
jnb again ; 0f8306050000
|
||||
int 3
|
||||
je again ; 0f8432010000
|
||||
int 3
|
||||
jne again ; 0f8508010000
|
||||
int 3
|
||||
jnbe again ; 0f878a000000
|
||||
int 3
|
||||
ldmxcsr dword ptr [rcx+034h] ; 0fae5134
|
||||
int 3
|
||||
stmxcsr dword ptr [rcx+034h] ; 0fae5934
|
||||
int 3
|
||||
and ecx,[rdx+rbx*4] ; 230c9a
|
||||
int 3
|
||||
xor eax,eax ; 33c0
|
||||
int 3
|
||||
xor ecx,ecx ; 33c9
|
||||
int 3
|
||||
xor edx,ecx ; 33d1
|
||||
int 3
|
||||
xor edx,edx ; 33d2
|
||||
int 3
|
||||
add r10d,010001h ; 4181c201000100
|
||||
int 3
|
||||
and r11d,0ffffh ; 4181e3ffff0000
|
||||
int 3
|
||||
mov eax,r8d ; 418bc0
|
||||
int 3
|
||||
mov byte ptr [r11],00h ; 41c60300
|
||||
int 3
|
||||
call qword ptr [r9+030h] ; 41ff5130
|
||||
int 3
|
||||
call qword ptr [r9+r8*8] ; 43ff14c1
|
||||
int 3
|
||||
mov [rcx+034h],r8d ; 44894134
|
||||
int 3
|
||||
mov [rsp+030h],r9d ; 44894c2430
|
||||
int 3
|
||||
mov r8d,[rcx] ; 448b01
|
||||
int 3
|
||||
mov r9d,[rcx] ; 448b09
|
||||
int 3
|
||||
mov r8d,[rax+058h] ; 448b4058
|
||||
int 3
|
||||
mov r8d,[rsp+02ch] ; 448b44242c
|
||||
int 3
|
||||
mov r8d,eax ; 448bc0
|
||||
int 3
|
||||
mov r8d,edx ; 448bc2
|
||||
int 3
|
||||
xor r8b,r8b ; 4532c0
|
||||
int 3
|
||||
mov r9d,r8d ; 458bc8
|
||||
int 3
|
||||
lea r11d,[r9+rax] ; 458d1c01
|
||||
int 3
|
||||
add rdx,rcx ; 4803d1
|
||||
int 3
|
||||
or rsi,rdx ; 480bf2
|
||||
int 3
|
||||
movnti [rcx],rax ; 480fc301
|
||||
int 3
|
||||
and rax,0fe000000h ; 4825000000fe
|
||||
int 3
|
||||
sub rax,rcx ; 482bc1
|
||||
int 3
|
||||
sub rdx,rcx ; 482bd1
|
||||
int 3
|
||||
cmp rdi,rbp ; 483bfd
|
||||
int 3
|
||||
push rbp ; 4855
|
||||
int 3
|
||||
add rcx,03d0h ; 4881c1d0030000
|
||||
int 3
|
||||
add rsp,0c8h ; 4881c4c8000000
|
||||
int 3
|
||||
and rdx,0fe000000h ; 4881e2000000fe
|
||||
int 3
|
||||
sub rsp,0c8h ; 4881ecc8000000
|
||||
int 3
|
||||
sub rsp,03d0h ; 4881ecd0030000
|
||||
int 3
|
||||
add rax,040h ; 4883c040
|
||||
int 3
|
||||
add rcx,08h ; 4883c108
|
||||
int 3
|
||||
add rcx,040h ; 4883c140
|
||||
int 3
|
||||
add rsp,08h ; 4883c408
|
||||
int 3
|
||||
add rsi,09h ; 4883c609
|
||||
int 3
|
||||
add rdi,01h ; 4883c701
|
||||
int 3
|
||||
and rcx,0f8h ; 4883e1f8
|
||||
int 3
|
||||
sub rax,040h ; 4883e840
|
||||
int 3
|
||||
sub rdx,08h ; 4883ea08
|
||||
int 3
|
||||
sub rdx,040h ; 4883ea40
|
||||
int 3
|
||||
sub rsp,08h ; 4883ec08
|
||||
int 3
|
||||
sub rsi,08h ; 4883ee08
|
||||
int 3
|
||||
sub rdi,01h ; 4883ef01
|
||||
int 3
|
||||
test rax,rax ; 4885c0
|
||||
int 3
|
||||
test rdx,rdx ; 4885d2
|
||||
int 3
|
||||
mov [rsp],rax ; 48890424
|
||||
int 3
|
||||
mov [rsp],rbp ; 48892c24
|
||||
int 3
|
||||
mov [rsp],rsi ; 48893424
|
||||
int 3
|
||||
mov [rsp],rdi ; 48893c24
|
||||
int 3
|
||||
mov [rcx+08h],rax ; 48894108
|
||||
int 3
|
||||
mov [rcx+078h],rax ; 48894178
|
||||
int 3
|
||||
mov [rcx-08h],rax ; 488941f8
|
||||
int 3
|
||||
mov [rsp+018h],rax ; 4889442418
|
||||
int 3
|
||||
mov [rcx+010h],rdx ; 48895110
|
||||
int 3
|
||||
mov [rsp+08h],rbx ; 48895c2408
|
||||
int 3
|
||||
mov [rsp+018h],rsi ; 4889742418
|
||||
int 3
|
||||
mov [rsp+08h],rdi ; 48897c2408
|
||||
int 3
|
||||
mov [rsp+010h],rdi ; 48897c2410
|
||||
int 3
|
||||
mov [rcx+098h],rax ; 48898198000000
|
||||
int 3
|
||||
mov [rcx+080h],rcx ; 48898980000000
|
||||
int 3
|
||||
mov [rcx+088h],rdx ; 48899188000000
|
||||
int 3
|
||||
mov [rcx+090h],rbx ; 48899990000000
|
||||
int 3
|
||||
mov [rcx+0a0h],rbp ; 4889a9a0000000
|
||||
int 3
|
||||
mov [rcx+0a8h],rsi ; 4889b1a8000000
|
||||
int 3
|
||||
mov [rcx+0b0h],rdi ; 4889b9b0000000
|
||||
int 3
|
||||
mov rax,[rcx] ; 488b01
|
||||
int 3
|
||||
mov rax,[rcx+rdx] ; 488b0411
|
||||
int 3
|
||||
mov rax,[value] ; 488b05318c0100
|
||||
int 3
|
||||
mov rcx,[rsp] ; 488b0c24
|
||||
int 3
|
||||
mov rsi,[rsp] ; 488b3424
|
||||
int 3
|
||||
mov rdi,[rsp] ; 488b3c24
|
||||
int 3
|
||||
mov rax,[rax+018h] ; 488b4018
|
||||
int 3
|
||||
mov rax,[rcx+078h] ; 488b4178
|
||||
int 3
|
||||
mov rax,[rdx+020h] ; 488b4220
|
||||
int 3
|
||||
mov rax,[rsp+08h] ; 488b442408
|
||||
int 3
|
||||
mov rcx,[rcx+08h] ; 488b4908
|
||||
int 3
|
||||
mov rcx,[rsp+020h] ; 488b4c2420
|
||||
int 3
|
||||
mov rdx,[rsp+08h] ; 488b542408
|
||||
int 3
|
||||
mov rdi,[rsp+08h] ; 488b7c2408
|
||||
int 3
|
||||
mov rax,[rcx+098h] ; 488b8198000000
|
||||
int 3
|
||||
mov rax,[rcx+0f8h] ; 488b81f8000000
|
||||
int 3
|
||||
cmp ebx,0 ;
|
||||
int 3
|
||||
cmp rbx,0 ;
|
||||
int 3
|
||||
cmp byte ptr [value],77h ; 803d........77
|
||||
int 3
|
||||
cmp dword ptr [value],77h ; 833d........77
|
||||
int 3
|
||||
cmp qword ptr [value],77h ; 48833d........77
|
||||
int 3
|
||||
cmp dword ptr [value],77777777h ; 813d........77777777
|
||||
int 3
|
||||
cmp qword ptr [value],77777777h ; 48813d........77777777
|
||||
int 3
|
||||
nearby:
|
||||
jo nearby ; 70xx
|
||||
int 3
|
||||
jno nearby ; 71xx
|
||||
int 3
|
||||
jb nearby ; 72xx
|
||||
int 3
|
||||
jae nearby ; 73xx
|
||||
int 3
|
||||
je nearby ; 74xx
|
||||
int 3
|
||||
jne nearby ; 75xx
|
||||
int 3
|
||||
jbe nearby ; 76xx
|
||||
int 3
|
||||
ja nearby ; 77xx
|
||||
int 3
|
||||
js nearby ; 78xx
|
||||
int 3
|
||||
jns nearby ; 79xx
|
||||
int 3
|
||||
jp nearby ; 7axx
|
||||
int 3
|
||||
jnp nearby ; 7bxx
|
||||
int 3
|
||||
jl nearby ; 7cxx
|
||||
int 3
|
||||
jge nearby ; 7dxx
|
||||
int 3
|
||||
jle nearby ; 7exx
|
||||
int 3
|
||||
jg nearby ; 7fxx
|
||||
int 3
|
||||
jmp nearby ; ebxx
|
||||
|
||||
int 3
|
||||
jo faraway ; 0f80xxxxxxxx
|
||||
int 3
|
||||
jno faraway ; 0f81xxxxxxxx
|
||||
int 3
|
||||
jb faraway ; 0f82xxxxxxxx
|
||||
int 3
|
||||
jae faraway ; 0f83xxxxxxxx
|
||||
int 3
|
||||
je faraway ; 0f84xxxxxxxx
|
||||
int 3
|
||||
jne faraway ; 0f85xxxxxxxx
|
||||
int 3
|
||||
jbe faraway ; 0f86xxxxxxxx
|
||||
int 3
|
||||
ja faraway ; 0f87xxxxxxxx
|
||||
int 3
|
||||
js faraway ; 0f88xxxxxxxx
|
||||
int 3
|
||||
jns faraway ; 0f89xxxxxxxx
|
||||
int 3
|
||||
jp faraway ; 0f8axxxxxxxx
|
||||
int 3
|
||||
jnp faraway ; 0f8bxxxxxxxx
|
||||
int 3
|
||||
jl faraway ; 0f8cxxxxxxxx
|
||||
int 3
|
||||
jge faraway ; 0f8dxxxxxxxx
|
||||
int 3
|
||||
jle faraway ; 0f8exxxxxxxx
|
||||
int 3
|
||||
jg faraway ; 0f8fxxxxxxxx
|
||||
int 3
|
||||
jmp faraway ; e9xxxxxxxx
|
||||
|
||||
int 3
|
||||
lea rax,[rsp] ; 488d0424
|
||||
int 3
|
||||
mov rcx,0BADC0DEBA5Eh ; 48b95ebadec0ad0b0000
|
||||
int 3
|
||||
cmp rax,rcx ; 483bc1
|
||||
|
||||
int 3
|
||||
sub rsp, 28h
|
||||
int 3
|
||||
add rsp,28h
|
||||
int 3
|
||||
ret
|
||||
int 3
|
||||
|
||||
|
||||
;; The list is terminated by two "int 3" in a row.
|
||||
again:
|
||||
int 3
|
||||
int 3
|
||||
TestCodes ENDP
|
||||
|
||||
value QWORD 0
|
||||
|
||||
_TEXT ENDS
|
||||
END
|
184
samples/disas/x86.cpp
Normal file
184
samples/disas/x86.cpp
Normal file
@ -0,0 +1,184 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detours Test Program (x86.asm of disas.exe)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
|
||||
static int value = 0;
|
||||
|
||||
extern "C" void __declspec(naked) TestCodes()
|
||||
{
|
||||
__asm {
|
||||
// Each instruction is proceeded by an "int 3".
|
||||
faraway:
|
||||
int 3;
|
||||
nop; // 1-byte NOP.
|
||||
int 3;
|
||||
_emit 0x66; // 2-byte NOP.
|
||||
_emit 0x90;
|
||||
int 3;
|
||||
_emit 0x0f; // 3-byte NOP.
|
||||
_emit 0x1f;
|
||||
_emit 0x00;
|
||||
int 3;
|
||||
_emit 0x0f; // 4-byte NOP.
|
||||
_emit 0x1f;
|
||||
_emit 0x40;
|
||||
_emit 0x00;
|
||||
int 3;
|
||||
_emit 0x0f; // 5-byte NOP.
|
||||
_emit 0x1f;
|
||||
_emit 0x44;
|
||||
_emit 0x00;
|
||||
_emit 0x00;
|
||||
int 3;
|
||||
_emit 0x66; // 6-byte NOP.
|
||||
_emit 0x0f;
|
||||
_emit 0x1f;
|
||||
_emit 0x44;
|
||||
_emit 0x00;
|
||||
_emit 0x00;
|
||||
int 3;
|
||||
_emit 0x0f; // 7-byte NOP.
|
||||
_emit 0x1f;
|
||||
_emit 0x80;
|
||||
_emit 0x00;
|
||||
_emit 0x00;
|
||||
_emit 0x00;
|
||||
_emit 0x00;
|
||||
int 3;
|
||||
_emit 0x0f; // 8-byte NOP.
|
||||
_emit 0x1f;
|
||||
_emit 0x84;
|
||||
_emit 0x00;
|
||||
_emit 0x00;
|
||||
_emit 0x00;
|
||||
_emit 0x00;
|
||||
_emit 0x00;
|
||||
int 3;
|
||||
_emit 0x66; // 9-byte NOP.
|
||||
_emit 0x0f;
|
||||
_emit 0x1f;
|
||||
_emit 0x84;
|
||||
_emit 0x00;
|
||||
_emit 0x00;
|
||||
_emit 0x00;
|
||||
_emit 0x00;
|
||||
_emit 0x00;
|
||||
int 3;
|
||||
mov ecx, eax;
|
||||
int 3;
|
||||
mov ebx, 0ffff000eh;
|
||||
int 3;
|
||||
call ebx;
|
||||
int 3;
|
||||
call dword ptr [eax];
|
||||
int 3;
|
||||
call dword ptr [ebx];
|
||||
int 3;
|
||||
call dword ptr [ecx];
|
||||
int 3;
|
||||
call dword ptr [edx];
|
||||
int 3;
|
||||
jmp dword ptr [eax];
|
||||
int 3;
|
||||
jmp dword ptr [ebx];
|
||||
int 3;
|
||||
jmp dword ptr [ecx];
|
||||
int 3;
|
||||
jmp dword ptr [edx];
|
||||
int 3;
|
||||
call ecx;
|
||||
int 3;
|
||||
call eax;
|
||||
int 3;
|
||||
mov ebx, 0ffff000eh;
|
||||
int 3;
|
||||
push eax;
|
||||
int 3;
|
||||
call ebx;
|
||||
int 3;
|
||||
cmp ebx, 0;
|
||||
int 3;
|
||||
cmp byte ptr [value], 77h;
|
||||
int 3;
|
||||
cmp dword ptr [value], 77h;
|
||||
int 3;
|
||||
cmp dword ptr [value], 77777777h;
|
||||
nearby:
|
||||
int 3
|
||||
jo nearby ; 70xx
|
||||
int 3
|
||||
jno nearby ; 71xx
|
||||
int 3
|
||||
jb nearby ; 72xx
|
||||
int 3
|
||||
jae nearby ; 73xx
|
||||
int 3
|
||||
je nearby ; 74xx
|
||||
int 3
|
||||
jne nearby ; 75xx
|
||||
int 3
|
||||
jbe nearby ; 76xx
|
||||
int 3
|
||||
ja nearby ; 77xx
|
||||
int 3
|
||||
js nearby ; 78xx
|
||||
int 3
|
||||
jns nearby ; 79xx
|
||||
int 3
|
||||
jp nearby ; 7axx
|
||||
int 3
|
||||
jnp nearby ; 7bxx
|
||||
int 3
|
||||
jl nearby ; 7cxx
|
||||
int 3
|
||||
jge nearby ; 7dxx
|
||||
int 3
|
||||
jle nearby ; 7exx
|
||||
int 3
|
||||
jg nearby ; 7fxx
|
||||
|
||||
int 3
|
||||
jo faraway ; 0f80xx
|
||||
int 3
|
||||
jno faraway ; 0f81xx
|
||||
int 3
|
||||
jb faraway ; 0f82xx
|
||||
int 3
|
||||
jae faraway ; 0f83xx
|
||||
int 3
|
||||
je faraway ; 0f84xx
|
||||
int 3
|
||||
jne faraway ; 0f85xx
|
||||
int 3
|
||||
jbe faraway ; 0f86xx
|
||||
int 3
|
||||
ja faraway ; 0f87xx
|
||||
int 3
|
||||
js faraway ; 0f88xx
|
||||
int 3
|
||||
jns faraway ; 0f89xx
|
||||
int 3
|
||||
jp faraway ; 0f8axx
|
||||
int 3
|
||||
jnp faraway ; 0f8bxx
|
||||
int 3
|
||||
jl faraway ; 0f8cxx
|
||||
int 3
|
||||
jge faraway ; 0f8dxx
|
||||
int 3
|
||||
jle faraway ; 0f8exx
|
||||
int 3
|
||||
jg faraway ; 0f8fxx
|
||||
|
||||
// The list is terminated by two "int 3" in a row.
|
||||
int 3;
|
||||
int 3;
|
||||
ret;
|
||||
}
|
||||
}
|
||||
|
107
samples/dtest/Makefile
Normal file
107
samples/dtest/Makefile
Normal file
@ -0,0 +1,107 @@
|
||||
##############################################################################
|
||||
##
|
||||
## Makefile for Detours Test Programs.
|
||||
##
|
||||
## Microsoft Research Detours Package
|
||||
##
|
||||
## Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
##
|
||||
|
||||
!include ..\common.mak
|
||||
|
||||
LIBS=$(LIBS) kernel32.lib
|
||||
|
||||
all: dirs \
|
||||
$(BIND)\dtarge$(DETOURS_BITS).dll \
|
||||
$(BIND)\dtest.exe \
|
||||
!IF $(DETOURS_SOURCE_BROWSING)==1
|
||||
$(OBJD)\dtarge$(DETOURS_BITS).bsc \
|
||||
$(OBJD)\dtest.bsc \
|
||||
!ENDIF
|
||||
option
|
||||
|
||||
clean:
|
||||
-del *~ *.obj *.sbr 2> nul
|
||||
-del $(BIND)\dtest.* $(BIND)\dtarge*.* 2> nul
|
||||
-rmdir /q /s $(OBJD) 2>nul
|
||||
|
||||
realclean: clean
|
||||
-rmdir /q /s $(OBJDS) 2>nul
|
||||
|
||||
dirs:
|
||||
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
|
||||
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
|
||||
|
||||
$(OBJD)\dtarge.obj : dtarge.cpp
|
||||
|
||||
$(OBJD)\dtarge.res : dtarge.rc
|
||||
|
||||
$(BIND)\dtarge$(DETOURS_BITS).dll $(BIND)\dtarge$(DETOURS_BITS).lib: \
|
||||
$(OBJD)\dtarge.obj $(OBJD)\dtarge.res $(DEPS)
|
||||
cl /LD $(CFLAGS) \
|
||||
/Fe$(@R).dll \
|
||||
/Fd$(@R).pdb \
|
||||
$(OBJD)\dtarge.obj $(OBJD)\dtarge.res \
|
||||
/link $(LINKFLAGS) /subsystem:console \
|
||||
/export:Target0 \
|
||||
/export:Target1 \
|
||||
/export:Target2 \
|
||||
/export:Target3 \
|
||||
/export:Target4 \
|
||||
/export:Target5 \
|
||||
/export:Target6 \
|
||||
/export:Target7 \
|
||||
/export:Target8 \
|
||||
/export:Target9 \
|
||||
/export:Target10 \
|
||||
/export:Target11 \
|
||||
/export:Target12 \
|
||||
/export:Target13 \
|
||||
/export:Target14 \
|
||||
/export:Target15 \
|
||||
/export:Target16 \
|
||||
/export:TargetV \
|
||||
/export:TargetR \
|
||||
$(LIBS)
|
||||
|
||||
$(OBJD)\dtarge$(DETOURS_BITS).bsc : $(OBJD)\dtarge.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\dtarge.sbr
|
||||
|
||||
$(OBJD)\dtest.obj : dtest.cpp
|
||||
|
||||
$(BIND)\dtest.exe : $(OBJD)\dtest.obj $(BIND)\dtarge$(DETOURS_BITS).lib $(DEPS)
|
||||
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\dtest.obj \
|
||||
/link $(LINKFLAGS) $(LIBS) $(BIND)\dtarge$(DETOURS_BITS).lib \
|
||||
/subsystem:console /entry:WinMainCRTStartup
|
||||
|
||||
$(OBJD)\dtest.bsc : $(OBJD)\dtest.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\dtest.sbr
|
||||
|
||||
############################################### Install non-bit-size binaries.
|
||||
|
||||
!IF "$(DETOURS_OPTION_PROCESSOR)" != ""
|
||||
|
||||
$(OPTD)\dtarge$(DETOURS_OPTION_BITS).dll:
|
||||
$(OPTD)\dtarge$(DETOURS_OPTION_BITS).pdb:
|
||||
|
||||
$(BIND)\dtarge$(DETOURS_OPTION_BITS).dll : $(OPTD)\dtarge$(DETOURS_OPTION_BITS).dll
|
||||
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
|
||||
$(BIND)\dtarge$(DETOURS_OPTION_BITS).pdb : $(OPTD)\dtarge$(DETOURS_OPTION_BITS).pdb
|
||||
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
|
||||
|
||||
option: \
|
||||
$(BIND)\dtarge$(DETOURS_OPTION_BITS).dll \
|
||||
$(BIND)\dtarge$(DETOURS_OPTION_BITS).pdb \
|
||||
|
||||
!ELSE
|
||||
|
||||
option:
|
||||
|
||||
!ENDIF
|
||||
|
||||
##############################################################################
|
||||
|
||||
test: all
|
||||
$(BIND)\dtest.exe
|
||||
|
||||
################################################################# End of File.
|
116
samples/dtest/NORMAL_IA64.TXT
Normal file
116
samples/dtest/NORMAL_IA64.TXT
Normal file
@ -0,0 +1,116 @@
|
||||
..\..\bin.IA64\dtest.exe
|
||||
Calling LocalTarget1 w/o detour
|
||||
LocalTarget1 (1)
|
||||
Calling LocalTarget1 w/ detour
|
||||
MyLocalTarget1 (2)
|
||||
LocalTarget1 (2)
|
||||
Calling Target0 function.
|
||||
MyTarget0 ()
|
||||
Calling TargetN functions.
|
||||
MyLocalTarget1 (1)
|
||||
LocalTarget1 (1)
|
||||
MyTarget0 ()
|
||||
MyTarget1 (1)
|
||||
MyTarget2 (1,2)
|
||||
MyTarget3 (1,2,3)
|
||||
MyTarget4 (1,2,3,4)
|
||||
MyTarget5 (1,2,3,4,5)
|
||||
MyTarget6 (1,2,3,4,5,6)
|
||||
MyTarget7 (1,2,3,4,5,6,7)
|
||||
MyTarget8 (1,2,3,4,5,6,7,8)
|
||||
MyTarget9 (1,2,3,4,5,6,7,8,9)
|
||||
MyTarget10(1,2,3,4,5,6,7,8,9,10)
|
||||
MyTarget11(1,2,3,4,5,6,7,8,9,10,11)
|
||||
MyTarget12(1,2,3,4,5,6,7,8,9,10,11,12)
|
||||
MyTarget13(1,2,3,4,5,6,7,8,9,10,11,12,13)
|
||||
MyTarget14(1,2,3,4,5,6,7,8,9,10,11,12,13,14)
|
||||
MyTarget15(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
|
||||
MyTarget16(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
|
||||
MyTargetV (0)
|
||||
MyTargetV (0,1)
|
||||
MyTargetV (0,1,2)
|
||||
MyTargetV (0,1,2,3)
|
||||
MyTargetV (0,1,2,3,4)
|
||||
MyTargetV (0,1,2,3,4,5)
|
||||
MyTargetV (0,1,2,3,4,5,6)
|
||||
MyTargetV (0,1,2,3,4,5,6,7)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9,10)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11,12)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
|
||||
MyTargetR (0,1,2,3,4)
|
||||
MyTargetR (0,1,2,3,3)
|
||||
MyTargetR (0,1,2,3,2)
|
||||
MyTargetR (0,1,2,3,1)
|
||||
.................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................... MyTargetR (0,1,2,3,4,5,6,7,8,9,10,4)
|
||||
MyTargetR (0,1,2,3,4,5,6,7,8,9,10,3)
|
||||
MyTargetR (0,1,2,3,4,5,6,7,8,9,10,2)
|
||||
MyTargetR (0,1,2,3,4,5,6,7,8,9,10,1)
|
||||
=> 3011
|
||||
Calling Target0 again with 1 detour.
|
||||
MyTarget0 ()
|
||||
Calling Target0 again with 2 detours.
|
||||
Starting Target0_1.
|
||||
MyTarget0 ()
|
||||
End Target0_1.
|
||||
Calling Target0 again with 3 detours.
|
||||
Starting Target0_2.
|
||||
Starting Target0_1.
|
||||
MyTarget0 ()
|
||||
End Target0_1.
|
||||
End Target0_2.
|
||||
Calling Target0 again with 4 detours.
|
||||
Starting Target0_3.
|
||||
Starting Target0_2.
|
||||
Starting Target0_1.
|
||||
MyTarget0 ()
|
||||
End Target0_1.
|
||||
End Target0_2.
|
||||
End Target0_3.
|
||||
Done.
|
||||
Target0 ()
|
||||
Target0 ()
|
||||
Target1 (1)
|
||||
Target2 (1,2)
|
||||
Target3 (1,2,3)
|
||||
Target4 (1,2,3,4)
|
||||
Target5 (1,2,3,4,5)
|
||||
Target6 (1,2,3,4,5,6)
|
||||
Target7 (1,2,3,4,5,6,7)
|
||||
Target8 (1,2,3,4,5,6,7,8)
|
||||
Target9 (1,2,3,4,5,6,7,8,9)
|
||||
Target10(1,2,3,4,5,6,7,8,9,10)
|
||||
Target11(1,2,3,4,5,6,7,8,9,10,11)
|
||||
Target12(1,2,3,4,5,6,7,8,9,10,11,12)
|
||||
Target13(1,2,3,4,5,6,7,8,9,10,11,12,13)
|
||||
Target14(1,2,3,4,5,6,7,8,9,10,11,12,13,14)
|
||||
Target15(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
|
||||
Target16(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
|
||||
TargetV (0)
|
||||
TargetV (0,1)
|
||||
TargetV (0,1,2)
|
||||
TargetV (0,1,2,3)
|
||||
TargetV (0,1,2,3,4)
|
||||
TargetV (0,1,2,3,4,5)
|
||||
TargetV (0,1,2,3,4,5,6)
|
||||
TargetV (0,1,2,3,4,5,6,7)
|
||||
TargetV (0,1,2,3,4,5,6,7,8)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9,10)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9,10,11)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9,10,11,12)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
|
||||
::: TargetR (0,1,2,3,1)
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: TargetR (0,1,2,3,4,5,6,7,8,9,10,1)
|
||||
Target0 ()
|
||||
Target0 ()
|
||||
Target0 ()
|
||||
Target0 ()
|
116
samples/dtest/NORMAL_X64.TXT
Normal file
116
samples/dtest/NORMAL_X64.TXT
Normal file
@ -0,0 +1,116 @@
|
||||
..\..\bin.X64\dtest.exe
|
||||
Calling LocalTarget1 w/o detour
|
||||
LocalTarget1 (1)
|
||||
Calling LocalTarget1 w/ detour
|
||||
MyLocalTarget1 (2)
|
||||
LocalTarget1 (2)
|
||||
Calling Target0 function.
|
||||
MyTarget0 ()
|
||||
Calling TargetN functions.
|
||||
MyLocalTarget1 (1)
|
||||
LocalTarget1 (1)
|
||||
MyTarget0 ()
|
||||
MyTarget1 (1)
|
||||
MyTarget2 (1,2)
|
||||
MyTarget3 (1,2,3)
|
||||
MyTarget4 (1,2,3,4)
|
||||
MyTarget5 (1,2,3,4,5)
|
||||
MyTarget6 (1,2,3,4,5,6)
|
||||
MyTarget7 (1,2,3,4,5,6,7)
|
||||
MyTarget8 (1,2,3,4,5,6,7,8)
|
||||
MyTarget9 (1,2,3,4,5,6,7,8,9)
|
||||
MyTarget10(1,2,3,4,5,6,7,8,9,10)
|
||||
MyTarget11(1,2,3,4,5,6,7,8,9,10,11)
|
||||
MyTarget12(1,2,3,4,5,6,7,8,9,10,11,12)
|
||||
MyTarget13(1,2,3,4,5,6,7,8,9,10,11,12,13)
|
||||
MyTarget14(1,2,3,4,5,6,7,8,9,10,11,12,13,14)
|
||||
MyTarget15(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
|
||||
MyTarget16(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
|
||||
MyTargetV (0)
|
||||
MyTargetV (0,1)
|
||||
MyTargetV (0,1,2)
|
||||
MyTargetV (0,1,2,3)
|
||||
MyTargetV (0,1,2,3,4)
|
||||
MyTargetV (0,1,2,3,4,5)
|
||||
MyTargetV (0,1,2,3,4,5,6)
|
||||
MyTargetV (0,1,2,3,4,5,6,7)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9,10)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11,12)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
|
||||
MyTargetR (0,1,2,3,4)
|
||||
MyTargetR (0,1,2,3,3)
|
||||
MyTargetR (0,1,2,3,2)
|
||||
MyTargetR (0,1,2,3,1)
|
||||
.................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................... MyTargetR (0,1,2,3,4,5,6,7,8,9,10,4)
|
||||
MyTargetR (0,1,2,3,4,5,6,7,8,9,10,3)
|
||||
MyTargetR (0,1,2,3,4,5,6,7,8,9,10,2)
|
||||
MyTargetR (0,1,2,3,4,5,6,7,8,9,10,1)
|
||||
=> 3011
|
||||
Calling Target0 again with 1 detour.
|
||||
MyTarget0 ()
|
||||
Calling Target0 again with 2 detours.
|
||||
Starting Target0_1.
|
||||
MyTarget0 ()
|
||||
End Target0_1.
|
||||
Calling Target0 again with 3 detours.
|
||||
Starting Target0_2.
|
||||
Starting Target0_1.
|
||||
MyTarget0 ()
|
||||
End Target0_1.
|
||||
End Target0_2.
|
||||
Calling Target0 again with 4 detours.
|
||||
Starting Target0_3.
|
||||
Starting Target0_2.
|
||||
Starting Target0_1.
|
||||
MyTarget0 ()
|
||||
End Target0_1.
|
||||
End Target0_2.
|
||||
End Target0_3.
|
||||
Done.
|
||||
Target0 ()
|
||||
Target0 ()
|
||||
Target1 (1)
|
||||
Target2 (1,2)
|
||||
Target3 (1,2,3)
|
||||
Target4 (1,2,3,4)
|
||||
Target5 (1,2,3,4,5)
|
||||
Target6 (1,2,3,4,5,6)
|
||||
Target7 (1,2,3,4,5,6,7)
|
||||
Target8 (1,2,3,4,5,6,7,8)
|
||||
Target9 (1,2,3,4,5,6,7,8,9)
|
||||
Target10(1,2,3,4,5,6,7,8,9,10)
|
||||
Target11(1,2,3,4,5,6,7,8,9,10,11)
|
||||
Target12(1,2,3,4,5,6,7,8,9,10,11,12)
|
||||
Target13(1,2,3,4,5,6,7,8,9,10,11,12,13)
|
||||
Target14(1,2,3,4,5,6,7,8,9,10,11,12,13,14)
|
||||
Target15(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
|
||||
Target16(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
|
||||
TargetV (0)
|
||||
TargetV (0,1)
|
||||
TargetV (0,1,2)
|
||||
TargetV (0,1,2,3)
|
||||
TargetV (0,1,2,3,4)
|
||||
TargetV (0,1,2,3,4,5)
|
||||
TargetV (0,1,2,3,4,5,6)
|
||||
TargetV (0,1,2,3,4,5,6,7)
|
||||
TargetV (0,1,2,3,4,5,6,7,8)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9,10)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9,10,11)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9,10,11,12)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
|
||||
::: TargetR (0,1,2,3,1)
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: TargetR (0,1,2,3,4,5,6,7,8,9,10,1)
|
||||
Target0 ()
|
||||
Target0 ()
|
||||
Target0 ()
|
||||
Target0 ()
|
116
samples/dtest/NORMAL_X86.TXT
Normal file
116
samples/dtest/NORMAL_X86.TXT
Normal file
@ -0,0 +1,116 @@
|
||||
..\..\bin.X86\dtest.exe
|
||||
Calling LocalTarget1 w/o detour
|
||||
LocalTarget1 (1)
|
||||
Calling LocalTarget1 w/ detour
|
||||
MyLocalTarget1 (2)
|
||||
LocalTarget1 (2)
|
||||
Calling Target0 function.
|
||||
MyTarget0 ()
|
||||
Calling TargetN functions.
|
||||
MyLocalTarget1 (1)
|
||||
LocalTarget1 (1)
|
||||
MyTarget0 ()
|
||||
MyTarget1 (1)
|
||||
MyTarget2 (1,2)
|
||||
MyTarget3 (1,2,3)
|
||||
MyTarget4 (1,2,3,4)
|
||||
MyTarget5 (1,2,3,4,5)
|
||||
MyTarget6 (1,2,3,4,5,6)
|
||||
MyTarget7 (1,2,3,4,5,6,7)
|
||||
MyTarget8 (1,2,3,4,5,6,7,8)
|
||||
MyTarget9 (1,2,3,4,5,6,7,8,9)
|
||||
MyTarget10(1,2,3,4,5,6,7,8,9,10)
|
||||
MyTarget11(1,2,3,4,5,6,7,8,9,10,11)
|
||||
MyTarget12(1,2,3,4,5,6,7,8,9,10,11,12)
|
||||
MyTarget13(1,2,3,4,5,6,7,8,9,10,11,12,13)
|
||||
MyTarget14(1,2,3,4,5,6,7,8,9,10,11,12,13,14)
|
||||
MyTarget15(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
|
||||
MyTarget16(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
|
||||
MyTargetV (0)
|
||||
MyTargetV (0,1)
|
||||
MyTargetV (0,1,2)
|
||||
MyTargetV (0,1,2,3)
|
||||
MyTargetV (0,1,2,3,4)
|
||||
MyTargetV (0,1,2,3,4,5)
|
||||
MyTargetV (0,1,2,3,4,5,6)
|
||||
MyTargetV (0,1,2,3,4,5,6,7)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9,10)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11,12)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
|
||||
MyTargetR (0,1,2,3,4)
|
||||
MyTargetR (0,1,2,3,3)
|
||||
MyTargetR (0,1,2,3,2)
|
||||
MyTargetR (0,1,2,3,1)
|
||||
.................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................... MyTargetR (0,1,2,3,4,5,6,7,8,9,10,4)
|
||||
MyTargetR (0,1,2,3,4,5,6,7,8,9,10,3)
|
||||
MyTargetR (0,1,2,3,4,5,6,7,8,9,10,2)
|
||||
MyTargetR (0,1,2,3,4,5,6,7,8,9,10,1)
|
||||
=> 3011
|
||||
Calling Target0 again with 1 detour.
|
||||
MyTarget0 ()
|
||||
Calling Target0 again with 2 detours.
|
||||
Starting Target0_1.
|
||||
MyTarget0 ()
|
||||
End Target0_1.
|
||||
Calling Target0 again with 3 detours.
|
||||
Starting Target0_2.
|
||||
Starting Target0_1.
|
||||
MyTarget0 ()
|
||||
End Target0_1.
|
||||
End Target0_2.
|
||||
Calling Target0 again with 4 detours.
|
||||
Starting Target0_3.
|
||||
Starting Target0_2.
|
||||
Starting Target0_1.
|
||||
MyTarget0 ()
|
||||
End Target0_1.
|
||||
End Target0_2.
|
||||
End Target0_3.
|
||||
Done.
|
||||
Target0 ()
|
||||
Target0 ()
|
||||
Target1 (1)
|
||||
Target2 (1,2)
|
||||
Target3 (1,2,3)
|
||||
Target4 (1,2,3,4)
|
||||
Target5 (1,2,3,4,5)
|
||||
Target6 (1,2,3,4,5,6)
|
||||
Target7 (1,2,3,4,5,6,7)
|
||||
Target8 (1,2,3,4,5,6,7,8)
|
||||
Target9 (1,2,3,4,5,6,7,8,9)
|
||||
Target10(1,2,3,4,5,6,7,8,9,10)
|
||||
Target11(1,2,3,4,5,6,7,8,9,10,11)
|
||||
Target12(1,2,3,4,5,6,7,8,9,10,11,12)
|
||||
Target13(1,2,3,4,5,6,7,8,9,10,11,12,13)
|
||||
Target14(1,2,3,4,5,6,7,8,9,10,11,12,13,14)
|
||||
Target15(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
|
||||
Target16(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
|
||||
TargetV (0)
|
||||
TargetV (0,1)
|
||||
TargetV (0,1,2)
|
||||
TargetV (0,1,2,3)
|
||||
TargetV (0,1,2,3,4)
|
||||
TargetV (0,1,2,3,4,5)
|
||||
TargetV (0,1,2,3,4,5,6)
|
||||
TargetV (0,1,2,3,4,5,6,7)
|
||||
TargetV (0,1,2,3,4,5,6,7,8)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9,10)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9,10,11)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9,10,11,12)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
|
||||
::: TargetR (0,1,2,3,1)
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: TargetR (0,1,2,3,4,5,6,7,8,9,10,1)
|
||||
Target0 ()
|
||||
Target0 ()
|
||||
Target0 ()
|
||||
Target0 ()
|
306
samples/dtest/dtarge.cpp
Normal file
306
samples/dtest/dtarge.cpp
Normal file
@ -0,0 +1,306 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detours Test Program (dtarge.dll)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include "dtarge.h"
|
||||
|
||||
DWORD_PTR WINAPI Target0()
|
||||
{
|
||||
printf(" Target0 ()\n");
|
||||
return 1000;
|
||||
}
|
||||
|
||||
DWORD_PTR WINAPI Target1(DWORD_PTR v1)
|
||||
{
|
||||
printf(" Target1 (%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
60
samples/dtest/dtarge.h
Normal 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
17
samples/dtest/dtarge.rc
Normal file
@ -0,0 +1,17 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version information for dtarge.rc.
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
|
||||
#include "detver.h"
|
||||
|
||||
#define VER_INTERNALNAME_STR "dtarge" DETOURS_STRINGIFY(DETOURS_BITS)
|
||||
#define VER_ORIGINALFILENAME_STR "dtarge" DETOURS_STRINGIFY(DETOURS_BITS) ".dll"
|
||||
#define VER_FILEDESCRIPTION_STR "Detours Test Module"
|
||||
#define VER_COMPANYNAME_STR "Microsoft Corporation"
|
||||
|
||||
#include "common.ver"
|
658
samples/dtest/dtest.cpp
Normal file
658
samples/dtest/dtest.cpp
Normal file
@ -0,0 +1,658 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detours Test Program (dtest.cpp of dtest.exe)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <windows.h>
|
||||
#pragma warning(push)
|
||||
#if _MSC_VER > 1400
|
||||
#pragma warning(disable:6102 6103) // /analyze warnings
|
||||
#endif
|
||||
#include <strsafe.h>
|
||||
#pragma warning(pop)
|
||||
#include <detours.h>
|
||||
#include "dtarge.h"
|
||||
|
||||
DWORD_PTR WINAPI LocalTarget1(DWORD_PTR v1);
|
||||
|
||||
////////////////////////////////////////////////////// Multi-Argument Detours.
|
||||
//
|
||||
DWORD_PTR (WINAPI * Trampoline_LocalTarget1)(DWORD_PTR v1) = LocalTarget1;
|
||||
|
||||
DWORD_PTR (WINAPI * Trampoline_Target0)() = Target0;
|
||||
DWORD_PTR (WINAPI * Trampoline_Target1)(DWORD_PTR v1) = Target1;
|
||||
DWORD_PTR (WINAPI * Trampoline_Target2)(DWORD_PTR v1, DWORD_PTR v2) = Target2;
|
||||
DWORD_PTR (WINAPI * Trampoline_Target3)
|
||||
(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3) = Target3;
|
||||
DWORD_PTR (WINAPI * Trampoline_Target4)
|
||||
(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4) = Target4;
|
||||
DWORD_PTR (WINAPI * Trampoline_Target5)
|
||||
(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5) = Target5;
|
||||
DWORD_PTR (WINAPI * Trampoline_Target6)
|
||||
(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6) = Target6;
|
||||
DWORD_PTR (WINAPI * Trampoline_Target7)
|
||||
(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7) = Target7;
|
||||
DWORD_PTR (WINAPI * Trampoline_Target8)
|
||||
(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8) = Target8;
|
||||
DWORD_PTR (WINAPI * Trampoline_Target9)
|
||||
(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
|
||||
DWORD_PTR v9) = Target9;
|
||||
DWORD_PTR (WINAPI * Trampoline_Target10)
|
||||
(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
|
||||
DWORD_PTR v9, DWORD_PTR v10) = Target10;
|
||||
DWORD_PTR (WINAPI * Trampoline_Target11)
|
||||
(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
|
||||
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11) = Target11;
|
||||
DWORD_PTR (WINAPI * Trampoline_Target12)
|
||||
(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
|
||||
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12) = Target12;
|
||||
DWORD_PTR (WINAPI * Trampoline_Target13)
|
||||
(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
|
||||
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12,
|
||||
DWORD_PTR v13) = Target13;
|
||||
DWORD_PTR (WINAPI * Trampoline_Target14)
|
||||
(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
|
||||
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12,
|
||||
DWORD_PTR v13, DWORD_PTR v14) = Target14;
|
||||
DWORD_PTR (WINAPI * Trampoline_Target15)
|
||||
(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
|
||||
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12,
|
||||
DWORD_PTR v13, DWORD_PTR v14, DWORD_PTR v15) = Target15;
|
||||
DWORD_PTR (WINAPI * Trampoline_Target16)
|
||||
(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
|
||||
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12,
|
||||
DWORD_PTR v13, DWORD_PTR v14, DWORD_PTR v15, DWORD_PTR v16) = Target16;
|
||||
DWORD_PTR (WINAPI * Trampoline_TargetV)(DWORD_PTR v1, ...) = TargetV;
|
||||
DWORD_PTR (WINAPI * Trampoline_TargetR)(DWORD_PTR v1, ...) = TargetR;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
VOID dprintf(const char * fmt, ...)
|
||||
{
|
||||
CHAR szBuf[1024];
|
||||
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
StringCchPrintfA(szBuf, sizeof(szBuf), fmt, args);
|
||||
va_end(args);
|
||||
|
||||
OutputDebugStringA(szBuf);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
DWORD_PTR WINAPI LocalTarget1(DWORD_PTR v1)
|
||||
{
|
||||
printf(" LocalTarget1 (%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
53
samples/dumpe/Makefile
Normal file
@ -0,0 +1,53 @@
|
||||
##############################################################################
|
||||
##
|
||||
## Makefile for Detours Test Programs.
|
||||
##
|
||||
## Microsoft Research Detours Package
|
||||
##
|
||||
## Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
##
|
||||
|
||||
!include ..\common.mak
|
||||
|
||||
LIBS=$(LIBS) kernel32.lib
|
||||
|
||||
all: dirs \
|
||||
$(BIND)\dumpe.exe \
|
||||
!IF $(DETOURS_SOURCE_BROWSING)==1
|
||||
$(OBJD)\dumpe.bsc
|
||||
!ENDIF
|
||||
|
||||
clean:
|
||||
-del *~ 2>nul
|
||||
-del $(BIND)\dumpe.* 2>nul
|
||||
-rmdir /q /s $(OBJD) 2>nul
|
||||
|
||||
realclean: clean
|
||||
-rmdir /q /s $(OBJDS) 2>nul
|
||||
|
||||
dirs:
|
||||
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
|
||||
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
|
||||
|
||||
$(OBJD)\dumpe.obj : dumpe.cpp
|
||||
|
||||
$(BIND)\dumpe.exe : $(OBJD)\dumpe.obj $(DEPS)
|
||||
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\dumpe.obj \
|
||||
/link $(LINKFLAGS) $(LIBS) \
|
||||
/subsystem:console
|
||||
|
||||
$(OBJD)\dumpe.bsc : $(OBJD)\dumpe.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\dumpe.sbr
|
||||
|
||||
##############################################################################
|
||||
|
||||
test: $(BIND)\dumpe.exe
|
||||
$(BIND)\dumpe.exe $(BIND)\slept.dll
|
||||
|
||||
testx: $(BIND)\dumpe.exe
|
||||
cd $(MAKEDIR)\..\..\src
|
||||
nmake
|
||||
cd $(MAKEDIR)
|
||||
if exist $(SYSTEMROOT)\system32\browseui.dll $(BIND)\dumpe.exe browseui.dll
|
||||
|
||||
################################################################# End of File.
|
129
samples/dumpe/dumpe.cpp
Normal file
129
samples/dumpe/dumpe.cpp
Normal file
@ -0,0 +1,129 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detours Test Program (dumpe.cpp of dumpe.exe)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <windows.h>
|
||||
#include <ole2.h>
|
||||
#include <shellapi.h>
|
||||
#include "detours.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
#ifndef NODEBUG
|
||||
#undef ASSERT
|
||||
VOID DetourAssertMessage(CONST PCHAR szMsg, CONST PCHAR szFile, DWORD nLine);
|
||||
|
||||
#define ASSERT(x) \
|
||||
do { if (!(x)) { DetourAssertMessage(#x, __FILE__, __LINE__); DebugBreak(); }} while (0)
|
||||
;
|
||||
#undef ASSERTX
|
||||
#define ASSERTX(x) \
|
||||
do { if (!(x)) { DetourAssertMessage(#x, __FILE__, __LINE__); PCHAR p=(PCHAR)(x); *p = 1; }} while (0)
|
||||
;
|
||||
#else // NODEBUG
|
||||
#undef ASSERT
|
||||
#define ASSERT(x)
|
||||
#undef ASSERTX
|
||||
#define ASSERTX(x)
|
||||
#endif // NODEBUG
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////// Error Messages.
|
||||
//
|
||||
VOID DetourAssertMessage(CONST PCHAR szMsg, CONST PCHAR szFile, DWORD nLine)
|
||||
{
|
||||
printf("ASSERT(%s) failed in %s, line %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
47
samples/dumpi/Makefile
Normal file
@ -0,0 +1,47 @@
|
||||
##############################################################################
|
||||
##
|
||||
## Makefile for Detours Test Programs - Dump Imports
|
||||
##
|
||||
## Microsoft Research Detours Package
|
||||
##
|
||||
## Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
##
|
||||
|
||||
!include ..\common.mak
|
||||
|
||||
LIBS=$(LIBS) kernel32.lib
|
||||
|
||||
all: dirs \
|
||||
$(BIND)\dumpi.exe \
|
||||
!IF $(DETOURS_SOURCE_BROWSING)==1
|
||||
$(OBJD)\dumpi.bsc \
|
||||
!ENDIF
|
||||
|
||||
clean:
|
||||
-del *~ 2>nul
|
||||
-del $(BIND)\dumpi.* 2>nul
|
||||
-rmdir /q /s $(OBJD) 2>nul
|
||||
|
||||
realclean: clean
|
||||
-rmdir /q /s $(OBJDS) 2>nul
|
||||
|
||||
dirs:
|
||||
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
|
||||
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
|
||||
|
||||
$(OBJD)\dumpi.obj : dumpi.cpp
|
||||
|
||||
$(BIND)\dumpi.exe : $(OBJD)\dumpi.obj $(DEPS)
|
||||
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\dumpi.obj \
|
||||
/link $(LINKFLAGS) $(LIBS) \
|
||||
/subsystem:console
|
||||
|
||||
$(OBJD)\dumpi.bsc : $(OBJD)\dumpi.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\dumpi.sbr
|
||||
|
||||
##############################################################################
|
||||
|
||||
test: $(BIND)\dumpi.exe
|
||||
$(BIND)\dumpi.exe $(BIND)\slept.dll $(BIND)\sleepold.exe
|
||||
|
||||
################################################################# End of File.
|
270
samples/dumpi/dumpi.cpp
Normal file
270
samples/dumpi/dumpi.cpp
Normal 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
|
77
samples/dynamic_alloc/Makefile
Normal file
77
samples/dynamic_alloc/Makefile
Normal 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.
|
194
samples/dynamic_alloc/main.cpp
Normal file
194
samples/dynamic_alloc/main.cpp
Normal 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;
|
||||
}
|
25
samples/dynamic_alloc/x64.asm
Normal file
25
samples/dynamic_alloc/x64.asm
Normal 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
|
31
samples/dynamic_alloc/x86.asm
Normal file
31
samples/dynamic_alloc/x86.asm
Normal 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
108
samples/echo/Makefile
Normal file
@ -0,0 +1,108 @@
|
||||
##############################################################################
|
||||
##
|
||||
## Detours Test Program
|
||||
##
|
||||
## Microsoft Research Detours Package
|
||||
##
|
||||
## Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
##
|
||||
|
||||
!include ..\common.mak
|
||||
|
||||
LIBS=$(LIBS) kernel32.lib
|
||||
|
||||
##############################################################################
|
||||
|
||||
all: dirs \
|
||||
$(BIND)\echofx$(DETOURS_BITS).dll \
|
||||
$(BIND)\echonul.exe \
|
||||
\
|
||||
!IF $(DETOURS_SOURCE_BROWSING)==1
|
||||
$(OBJD)\echofx$(DETOURS_BITS).bsc \
|
||||
$(OBJD)\echonul.bsc \
|
||||
!ENDIF
|
||||
option
|
||||
|
||||
##############################################################################
|
||||
|
||||
dirs:
|
||||
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
|
||||
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
|
||||
|
||||
$(OBJD)\echofx.obj : echofx.cpp
|
||||
|
||||
$(OBJD)\echofx.res : echofx.rc
|
||||
|
||||
$(BIND)\echofx$(DETOURS_BITS).dll $(BIND)\echofx$(DETOURS_BITS).lib: \
|
||||
$(OBJD)\echofx.obj $(OBJD)\echofx.res $(DEPS) $(BIND)\echonul.lib
|
||||
cl /LD $(CFLAGS) /Fe$@ /Fd$(@R).pdb \
|
||||
$(OBJD)\echofx.obj $(OBJD)\echofx.res \
|
||||
/link $(LINKFLAGS) /subsystem:console \
|
||||
/export:DetourFinishHelperProcess,@1,NONAME \
|
||||
/export:Mine_Echo \
|
||||
$(LIBS) $(BIND)\echonul.lib
|
||||
|
||||
$(OBJD)\echofx$(DETOURS_BITS).bsc : $(OBJD)\echofx.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\echofx.sbr
|
||||
|
||||
$(OBJD)\echonul.obj : echonul.cpp
|
||||
$(OBJD)\main.obj : main.cpp
|
||||
|
||||
$(BIND)\echonul.exe $(BIND)\echonul.lib: $(OBJD)\main.obj $(OBJD)\echonul.obj
|
||||
cl $(CFLAGS) /Zl /Fe$(BIND)\echonul.exe /Fd$(@R).pdb \
|
||||
$(OBJD)\main.obj $(OBJD)\echonul.obj \
|
||||
/link $(LINKFLAGS) \
|
||||
/export:Echo \
|
||||
/subsystem:console
|
||||
|
||||
$(OBJD)\echonul.bsc : echonul.obj
|
||||
bscmake /v /n /o $@ echonul.sbr
|
||||
|
||||
##############################################################################
|
||||
|
||||
clean:
|
||||
-del *~ 2>nul
|
||||
-del $(BIND)\echofx*.* 2>nul
|
||||
-del $(BIND)\echonul.* 2>nul
|
||||
-rmdir /q /s $(OBJD) 2>nul
|
||||
|
||||
realclean: clean
|
||||
-rmdir /q /s $(OBJDS) 2>nul
|
||||
|
||||
############################################### Install non-bit-size binaries.
|
||||
|
||||
!IF "$(DETOURS_OPTION_PROCESSOR)" != ""
|
||||
|
||||
$(OPTD)\echofx$(DETOURS_OPTION_BITS).dll:
|
||||
$(OPTD)\echofx$(DETOURS_OPTION_BITS).pdb:
|
||||
|
||||
$(BIND)\echofx$(DETOURS_OPTION_BITS).dll : $(OPTD)\echofx$(DETOURS_OPTION_BITS).dll
|
||||
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
|
||||
$(BIND)\echofx$(DETOURS_OPTION_BITS).pdb : $(OPTD)\echofx$(DETOURS_OPTION_BITS).pdb
|
||||
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
|
||||
|
||||
option: \
|
||||
$(BIND)\echofx$(DETOURS_OPTION_BITS).dll \
|
||||
$(BIND)\echofx$(DETOURS_OPTION_BITS).pdb \
|
||||
|
||||
!ELSE
|
||||
|
||||
option:
|
||||
|
||||
!ENDIF
|
||||
|
||||
##############################################################################
|
||||
|
||||
test: all
|
||||
@echo -------- Should echo nothing. --------------------------------------
|
||||
-$(BIND)\echonul.exe
|
||||
@echo -------- Should echo Hello World. ----------------------------------
|
||||
-$(BIND)\withdll.exe -d:$(BIND)\echofx$(DETOURS_BITS).dll $(BIND)\echonul.exe
|
||||
@echo.
|
||||
|
||||
testd: all
|
||||
@echo.
|
||||
-windbg -o -g -G $(BIND)\withdll.exe -d:$(BIND)\echofx$(DETOURS_BITS).dll $(BIND)\echonul.exe
|
||||
@echo.
|
||||
|
||||
################################################################# End of File.
|
60
samples/echo/echofx.cpp
Normal file
60
samples/echo/echofx.cpp
Normal file
@ -0,0 +1,60 @@
|
||||
//
|
||||
//
|
||||
//
|
||||
#include <windows.h>
|
||||
#include <detours.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int WINAPI Echo(PCSTR pszMsg);
|
||||
|
||||
static int (WINAPI * Real_Echo)(PCSTR pszMsg) = Echo;
|
||||
|
||||
int WINAPI Mine_Echo(PCSTR pszMsg)
|
||||
{
|
||||
printf("Echo(%s)\n", pszMsg);
|
||||
return Real_Echo(pszMsg);
|
||||
}
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
|
||||
{
|
||||
LONG error;
|
||||
(void)hinst;
|
||||
(void)reserved;
|
||||
|
||||
if (DetourIsHelperProcess()) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (dwReason == DLL_PROCESS_ATTACH) {
|
||||
DetourRestoreAfterWith();
|
||||
|
||||
printf("echofx" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
|
||||
" Starting.\n");
|
||||
fflush(stdout);
|
||||
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
DetourAttach(&(PVOID&)Real_Echo, Mine_Echo);
|
||||
error = DetourTransactionCommit();
|
||||
|
||||
if (error == NO_ERROR) {
|
||||
printf("echofx" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
|
||||
" Detoured Echo().\n");
|
||||
}
|
||||
else {
|
||||
printf("echofx" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
|
||||
" Error detouring Echo(): %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
17
samples/echo/echofx.rc
Normal file
@ -0,0 +1,17 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version information for echofx.rc.
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
|
||||
#include "detver.h"
|
||||
|
||||
#define VER_INTERNALNAME_STR "echofx" DETOURS_STRINGIFY(DETOURS_BITS)
|
||||
#define VER_ORIGINALFILENAME_STR "echofx" DETOURS_STRINGIFY(DETOURS_BITS) ".dll"
|
||||
#define VER_FILEDESCRIPTION_STR "Detours Echo Interception Module"
|
||||
#define VER_COMPANYNAME_STR "Microsoft Corporation"
|
||||
|
||||
#include "common.ver"
|
18
samples/echo/echonul.cpp
Normal file
18
samples/echo/echonul.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
//
|
||||
//
|
||||
//
|
||||
#include <windows.h>
|
||||
|
||||
int WINAPI Echo(PCSTR pszMsg)
|
||||
{
|
||||
int sum = 0;
|
||||
while (*pszMsg) {
|
||||
sum = sum + *pszMsg++;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
24
samples/echo/main.cpp
Normal file
24
samples/echo/main.cpp
Normal file
@ -0,0 +1,24 @@
|
||||
//
|
||||
//
|
||||
//
|
||||
#include <windows.h>
|
||||
|
||||
int WINAPI Echo(PCSTR pszMsg);
|
||||
|
||||
extern "C" int __stdcall mainCRTStartup(HINSTANCE hInstance,
|
||||
HINSTANCE hPrevInstance,
|
||||
LPSTR lpCmdLine,
|
||||
int nCmdShow
|
||||
)
|
||||
{
|
||||
(void)hInstance;
|
||||
(void)hPrevInstance;
|
||||
(void)lpCmdLine;
|
||||
(void)nCmdShow;
|
||||
|
||||
Echo("Hello World");
|
||||
Echo("Goodbye World");
|
||||
|
||||
return 0x99;
|
||||
}
|
||||
|
148
samples/einst/Makefile
Normal file
148
samples/einst/Makefile
Normal 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
55
samples/einst/edll1x.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detours Test Program (edll1x.cpp of edll1x.dll)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include <detours.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////// DLL Stuff
|
||||
//
|
||||
struct CPrivateStuff
|
||||
{
|
||||
DETOUR_SECTION_HEADER header;
|
||||
DETOUR_SECTION_RECORD record;
|
||||
CHAR szMessage[32];
|
||||
};
|
||||
|
||||
#pragma data_seg(".detour")
|
||||
|
||||
static CPrivateStuff private_stuff = {
|
||||
DETOUR_SECTION_HEADER_DECLARE(sizeof(CPrivateStuff)),
|
||||
{
|
||||
(sizeof(CPrivateStuff) - sizeof(DETOUR_SECTION_HEADER)),
|
||||
0,
|
||||
{ /* d9ab8a40-f4cc-11d1-b6d7-006097b010e3 */
|
||||
0xd9ab8a40,
|
||||
0xf4cc,
|
||||
0x11d1,
|
||||
{0xb6, 0xd7, 0x00, 0x60, 0x97, 0xb0, 0x10, 0xe3}
|
||||
}
|
||||
},
|
||||
"The First Dll!"
|
||||
};
|
||||
#pragma data_seg()
|
||||
|
||||
__declspec(dllexport) VOID WINAPI EDll1Function(VOID)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
__declspec(dllexport) ULONG WINAPI
|
||||
DllMain(HINSTANCE hInstance, DWORD dwReason, PVOID lpReserved)
|
||||
{
|
||||
(void)hInstance;
|
||||
(void)dwReason;
|
||||
(void)lpReserved;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////// End of File.
|
55
samples/einst/edll2x.cpp
Normal file
55
samples/einst/edll2x.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detours Test Program (edll2x.cpp of einst.exe/edll2x.dll)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include <detours.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////// DLL Stuff
|
||||
//
|
||||
struct CPrivateStuff
|
||||
{
|
||||
DETOUR_SECTION_HEADER header;
|
||||
DETOUR_SECTION_RECORD record;
|
||||
CHAR szMessage[32];
|
||||
};
|
||||
|
||||
#pragma data_seg(".detour")
|
||||
|
||||
static CPrivateStuff private_stuff = {
|
||||
DETOUR_SECTION_HEADER_DECLARE(sizeof(CPrivateStuff)),
|
||||
{
|
||||
(sizeof(CPrivateStuff) - sizeof(DETOUR_SECTION_HEADER)),
|
||||
0,
|
||||
{ /* d9ab8a40-f4cc-11d1-b6d7-006097b010e3 */
|
||||
0xd9ab8a40,
|
||||
0xf4cc,
|
||||
0x11d1,
|
||||
{0xb6, 0xd7, 0x00, 0x60, 0x97, 0xb0, 0x10, 0xe3}
|
||||
}
|
||||
},
|
||||
"The Second Dll!"
|
||||
};
|
||||
#pragma data_seg()
|
||||
|
||||
__declspec(dllexport) VOID WINAPI EDll2Function(VOID)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
__declspec(dllexport) ULONG WINAPI
|
||||
DllMain(HINSTANCE hInstance, DWORD dwReason, PVOID lpReserved)
|
||||
{
|
||||
(void)hInstance;
|
||||
(void)dwReason;
|
||||
(void)lpReserved;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////// End of File.
|
82
samples/einst/edll3x.cpp
Normal file
82
samples/einst/edll3x.cpp
Normal file
@ -0,0 +1,82 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detours Test Program (edll3x.cpp of einst.exe/edll3x.dll)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include <detours.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////// DLL Stuff
|
||||
//
|
||||
struct CPrivateStuffPart1
|
||||
{
|
||||
DETOUR_SECTION_RECORD header;
|
||||
CHAR szMessage[48];
|
||||
};
|
||||
|
||||
struct CPrivateStuffPart2
|
||||
{
|
||||
DETOUR_SECTION_RECORD header;
|
||||
CHAR szMessage[64];
|
||||
};
|
||||
|
||||
struct CPrivateStuff
|
||||
{
|
||||
DETOUR_SECTION_HEADER header;
|
||||
CPrivateStuffPart1 record1;
|
||||
CPrivateStuffPart2 record2;
|
||||
};
|
||||
|
||||
#pragma data_seg(".detour")
|
||||
|
||||
static CPrivateStuff private_stuff = {
|
||||
DETOUR_SECTION_HEADER_DECLARE(sizeof(CPrivateStuff)),
|
||||
{
|
||||
{
|
||||
sizeof(CPrivateStuffPart1),
|
||||
0,
|
||||
{ /* d9ab8a41-f4cc-11d1-b6d7-006097b010e3 */
|
||||
0xd9ab8a41,
|
||||
0xf4cc,
|
||||
0x11d1,
|
||||
{0xb6, 0xd7, 0x00, 0x60, 0x97, 0xb0, 0x10, 0xe3}
|
||||
}
|
||||
},
|
||||
"The Third DLL Part One!"
|
||||
},
|
||||
{
|
||||
{
|
||||
sizeof(CPrivateStuffPart2),
|
||||
0,
|
||||
{ /* d9ab8a40-f4cc-11d1-b6d7-006097b010e3 */
|
||||
0xd9ab8a40,
|
||||
0xf4cc,
|
||||
0x11d1,
|
||||
{0xb6, 0xd7, 0x00, 0x60, 0x97, 0xb0, 0x10, 0xe3}
|
||||
}
|
||||
},
|
||||
"The Third DLL Part Two!"
|
||||
}
|
||||
};
|
||||
#pragma data_seg()
|
||||
|
||||
__declspec(dllexport) VOID WINAPI EDll3Function(VOID)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
__declspec(dllexport) ULONG WINAPI
|
||||
DllMain(HINSTANCE hInstance, DWORD dwReason, PVOID lpReserved)
|
||||
{
|
||||
(void)hInstance;
|
||||
(void)dwReason;
|
||||
(void)lpReserved;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////// End of File.
|
98
samples/einst/einst.cpp
Normal file
98
samples/einst/einst.cpp
Normal file
@ -0,0 +1,98 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detours Test Program (einst.cpp of einst.exe)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include <detours.h>
|
||||
|
||||
struct CPrivateStuff
|
||||
{
|
||||
DETOUR_SECTION_HEADER header;
|
||||
DETOUR_SECTION_RECORD record;
|
||||
CHAR szMessage[32];
|
||||
};
|
||||
|
||||
#ifdef INCLUDE_THIS
|
||||
#pragma data_seg(".detour")
|
||||
|
||||
static CPrivateStuff private_stuff = {
|
||||
DETOUR_SECTION_HEADER_DECLARE(sizeof(CPrivateStuff)),
|
||||
{
|
||||
(sizeof(CPrivateStuff) - sizeof(DETOUR_SECTION_HEADER)),
|
||||
0,
|
||||
{ /* d9ab8a40-f4cc-11d1-b6d7-006097b010e3 */
|
||||
0xd9ab8a40,
|
||||
0xf4cc,
|
||||
0x11d1,
|
||||
{0xb6, 0xd7, 0x00, 0x60, 0x97, 0xb0, 0x10, 0xe3}
|
||||
}
|
||||
},
|
||||
"The Application!"
|
||||
};
|
||||
#pragma data_seg()
|
||||
#endif
|
||||
|
||||
GUID my_guid =
|
||||
{ /* d9ab8a40-f4cc-11d1-b6d7-006097b010e3 */
|
||||
0xd9ab8a40,
|
||||
0xf4cc,
|
||||
0x11d1,
|
||||
{0xb6, 0xd7, 0x00, 0x60, 0x97, 0xb0, 0x10, 0xe3}
|
||||
};
|
||||
|
||||
__declspec(dllimport) VOID WINAPI EDll1Function(VOID);
|
||||
__declspec(dllimport) VOID WINAPI EDll2Function(VOID);
|
||||
__declspec(dllimport) VOID WINAPI EDll3Function(VOID);
|
||||
|
||||
void FindPayload(HINSTANCE hinst)
|
||||
{
|
||||
CHAR szModuleName[256];
|
||||
GetModuleFileNameA(hinst, szModuleName, ARRAYSIZE(szModuleName));
|
||||
printf(" %p : %s\n", hinst, szModuleName);
|
||||
|
||||
ULONG cbData = 0;
|
||||
PBYTE pbData = (PBYTE)DetourFindPayload(hinst, my_guid, &cbData);
|
||||
|
||||
if (pbData) {
|
||||
printf(" %08p..%08p : %50.50s\n",
|
||||
pbData,
|
||||
pbData + cbData,
|
||||
pbData);
|
||||
}
|
||||
}
|
||||
|
||||
int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hprev, LPSTR lpszCmdLine, int nCmdShow)
|
||||
{
|
||||
(void)hinst;
|
||||
(void)hprev;
|
||||
(void)lpszCmdLine;
|
||||
(void)nCmdShow;
|
||||
|
||||
printf("Source .EXE:\n");
|
||||
FindPayload(NULL);
|
||||
printf("\n");
|
||||
|
||||
printf("DLL and EXE binaries loaded:\n");
|
||||
|
||||
EDll1Function();
|
||||
EDll2Function();
|
||||
EDll3Function();
|
||||
|
||||
for (HINSTANCE hiter = NULL; (hiter = DetourEnumerateModules(hiter)) != NULL;) {
|
||||
FindPayload(hiter);
|
||||
}
|
||||
|
||||
if ((PVOID)hinst == (PVOID)lpszCmdLine) {
|
||||
DispatchMessage(NULL); // Force load of gdi32.dll
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
///////////////////////////////////////////////////////////////// End of File.
|
47
samples/excep/Makefile
Normal file
47
samples/excep/Makefile
Normal file
@ -0,0 +1,47 @@
|
||||
##############################################################################
|
||||
##
|
||||
## Makefile for Detours Test Programs.
|
||||
##
|
||||
## Microsoft Research Detours Package
|
||||
##
|
||||
## Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
##
|
||||
|
||||
!include ..\common.mak
|
||||
|
||||
LIBS=$(LIBS) kernel32.lib
|
||||
|
||||
all: dirs \
|
||||
$(BIND)\excep.exe \
|
||||
!IF $(DETOURS_SOURCE_BROWSING)==1
|
||||
$(OBJD)\excep.bsc
|
||||
!ENDIF
|
||||
|
||||
clean:
|
||||
-del *~ 2>nul
|
||||
-del $(BIND)\excep.* 2>nul
|
||||
-rmdir /q /s $(OBJD) 2>nul
|
||||
|
||||
realclean: clean
|
||||
-rmdir /q /s $(OBJDS) 2>nul
|
||||
|
||||
dirs:
|
||||
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
|
||||
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
|
||||
|
||||
$(OBJD)\excep.obj : excep.cpp
|
||||
$(OBJD)\firstexc.obj : firstexc.cpp
|
||||
|
||||
$(BIND)\excep.exe : $(OBJD)\excep.obj $(OBJD)\firstexc.obj $(DEPS)
|
||||
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\excep.obj $(OBJD)\firstexc.obj \
|
||||
/link $(LINKFLAGS) $(LIBS) /subsystem:console /entry:WinMainCRTStartup
|
||||
|
||||
$(OBJD)\excep.bsc : $(OBJD)\excep.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\excep.sbr
|
||||
|
||||
##############################################################################
|
||||
|
||||
test: $(BIND)\excep.exe
|
||||
$(BIND)\excep.exe
|
||||
|
||||
################################################################# End of File.
|
125
samples/excep/excep.cpp
Normal file
125
samples/excep/excep.cpp
Normal file
@ -0,0 +1,125 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// First Chance Exception Handling Test Program (excep.cpp of excep.exe)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// For more information on exception handling, see "A Crash Course on the
|
||||
// Depths of Win32 Structured Exception Handling," by Matt Pietrek in the
|
||||
// January 1997 issue of Microsoft Systems Journal.
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include <detours.h>
|
||||
#include "firstexc.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
static LPVOID s_pvData = NULL;
|
||||
static DWORD s_dwDataPerm = 0;
|
||||
|
||||
static LONG ExceptCatch(LONG nTry, DWORD dwException, LPEXCEPTION_POINTERS pinfo)
|
||||
{
|
||||
printf(" ExceptCatch(%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
191
samples/excep/firstexc.cpp
Normal file
@ -0,0 +1,191 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detours Test Program (firstexc.cpp of firstexc.lib)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// For more information on exception handling, see "A Crash Course on the
|
||||
// Depths of Win32 Structured Exception Handling," by Matt Pietrek in the
|
||||
// January 1997 issue of Microsoft Systems Journal.
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include "detours.h"
|
||||
#include "firstexc.h"
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma warning(disable: 4740)
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
static BOOL s_bExceptionDetourInstalled = FALSE;
|
||||
static LPTOP_LEVEL_EXCEPTION_FILTER s_pFirstChanceFilter = NULL;
|
||||
|
||||
ULONG (NTAPI *Real_NtContinue)(IN PCONTEXT ContextRecord,
|
||||
IN BOOLEAN TestAlerts) = NULL;
|
||||
|
||||
VOID (NTAPI *Real_KiUserExceptionDispatcher)(IN PEXCEPTION_RECORD ExceptionRecord,
|
||||
IN PCONTEXT ContextFrame) = NULL;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// This function effectively removes all try..catch frames for the current
|
||||
// stack. It forces all exceptions to be treated as unhandled exceptions.
|
||||
//
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4733)
|
||||
static VOID WINAPI RemoveAllExceptionHandlers(VOID)
|
||||
{
|
||||
// The basic, OS defined exception frame
|
||||
struct EXCEPTION_REGISTRATION
|
||||
{
|
||||
EXCEPTION_REGISTRATION* prev;
|
||||
FARPROC handler;
|
||||
};
|
||||
|
||||
EXCEPTION_REGISTRATION * pVCExcRec = NULL;
|
||||
EXCEPTION_REGISTRATION * pLastGood = NULL;
|
||||
|
||||
__asm mov eax, FS:[0];
|
||||
__asm mov [pVCExcRec], eax;
|
||||
|
||||
for (pLastGood = pVCExcRec; (ULONG)pVCExcRec != ~0ul; ) {
|
||||
if ((ULONG)pVCExcRec >= 0x30000000)
|
||||
break;
|
||||
|
||||
pLastGood = pVCExcRec;
|
||||
pVCExcRec = (EXCEPTION_REGISTRATION *)(pVCExcRec->prev);
|
||||
}
|
||||
|
||||
__asm mov eax, [pLastGood];
|
||||
__asm mov FS:[0], eax;
|
||||
}
|
||||
#pragma warning(pop)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Routine Description:
|
||||
//
|
||||
// This routine is entered on return from kernel mode to dispatch a user
|
||||
// mode exception. If a frame based handler handles the exception, then
|
||||
// the execution is continued. Else last chance processing is performed.
|
||||
//
|
||||
// NOTE: This procedure is not called, but rather dispatched to.
|
||||
// It depends on there not being a return address on the stack
|
||||
// (assumption w.r.t. argument offsets.)
|
||||
//
|
||||
// Arguments:
|
||||
// ExceptionRecord (esp+0) - Supplies a pointer to an exception record.
|
||||
// ContextRecord (esp+4) - Supplies a pointer to a context frame.
|
||||
//
|
||||
// Return Value:
|
||||
// None.
|
||||
//
|
||||
static VOID __declspec(naked) NTAPI
|
||||
Detour_KiUserExceptionDispatcher(PEXCEPTION_RECORD pExceptRec,
|
||||
CONTEXT *pContext)
|
||||
{
|
||||
__asm {
|
||||
xor eax, eax ; // Create fake return address on stack.
|
||||
push eax ; // (Generally, we are called by the kernel.)
|
||||
|
||||
push ebp ; // Prolog
|
||||
mov ebp, esp ;
|
||||
sub esp, __LOCAL_SIZE ;
|
||||
}
|
||||
|
||||
LPTOP_LEVEL_EXCEPTION_FILTER pFirstChanceFilter;
|
||||
EXCEPTION_POINTERS ep;
|
||||
DWORD dwReturn;
|
||||
DWORD dwError;
|
||||
|
||||
ep.ExceptionRecord = pExceptRec;
|
||||
ep.ContextRecord = pContext;
|
||||
pFirstChanceFilter = s_pFirstChanceFilter;
|
||||
dwReturn = EXCEPTION_CONTINUE_SEARCH;
|
||||
dwError = 0;
|
||||
|
||||
if (s_pFirstChanceFilter) {
|
||||
dwReturn = pFirstChanceFilter(&ep);
|
||||
}
|
||||
|
||||
if (dwReturn == EXCEPTION_CONTINUE_EXECUTION) {
|
||||
dwError = Real_NtContinue(pContext, 0);
|
||||
// This call should *NEVER* return. If it does, we want to fail to the debugger.
|
||||
RemoveAllExceptionHandlers();
|
||||
}
|
||||
|
||||
if (dwReturn == EXCEPTION_EXECUTE_HANDLER) { // Special: Call debugger.
|
||||
RemoveAllExceptionHandlers();
|
||||
}
|
||||
|
||||
__asm {
|
||||
mov ebx, pExceptRec ;
|
||||
mov ecx, pContext ;
|
||||
push ecx ;
|
||||
push ebx ;
|
||||
mov eax, [Real_KiUserExceptionDispatcher];
|
||||
jmp eax ;
|
||||
;
|
||||
; The above code should never return.
|
||||
;
|
||||
int 3 ; // Break!
|
||||
;
|
||||
mov esp, ebp ; // Epilog
|
||||
pop ebp ;
|
||||
ret ;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Set the first-chance exception filter.
|
||||
//
|
||||
// Returns the pointer to the last first-chance exception filter if there
|
||||
// was one. If this is the first first-chance exception filter, installs
|
||||
// the necessary detour and acquires the appropriate function pointers.
|
||||
// If the parameter is NULL, first-chance exception filtering is disabled.
|
||||
//
|
||||
// A first-chance exception filter should always return one of three
|
||||
// possible codes:
|
||||
//
|
||||
// EXCEPTION_CONTINUE_SEARCH:
|
||||
// The exception was not handled by this filter; continue the
|
||||
// search for the appropriate exception handler.
|
||||
//
|
||||
// EXCEPTION_CONTINUE_EXECUTION:
|
||||
// The exception was handled by this filter; continue execution
|
||||
// at the point were the exception was thrown.
|
||||
//
|
||||
// EXCEPTION_EXECUTE_HANDLER:
|
||||
// Drastic failure in the exception filter. Process the
|
||||
// exception as if no exception handlers were installed.
|
||||
// (i.e. Give the user a chance to invoke the debugger.)
|
||||
//
|
||||
LPTOP_LEVEL_EXCEPTION_FILTER WINAPI
|
||||
DetourFirstChanceExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER pNewFirstChanceFilter)
|
||||
{
|
||||
if (!s_bExceptionDetourInstalled) {
|
||||
s_bExceptionDetourInstalled = TRUE;
|
||||
|
||||
Real_NtContinue = (ULONG (NTAPI *)(IN PCONTEXT, IN BOOLEAN))
|
||||
DetourFindFunction("ntdll.dll", "NtContinue");
|
||||
Real_KiUserExceptionDispatcher =
|
||||
(VOID (NTAPI *)(IN PEXCEPTION_RECORD, IN PCONTEXT))
|
||||
DetourFindFunction("ntdll.dll", "KiUserExceptionDispatcher");
|
||||
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
DetourAttach(&(PVOID&)Real_KiUserExceptionDispatcher,
|
||||
Detour_KiUserExceptionDispatcher);
|
||||
DetourTransactionCommit();
|
||||
}
|
||||
|
||||
LPTOP_LEVEL_EXCEPTION_FILTER pOldFirstChanceFilter = s_pFirstChanceFilter;
|
||||
s_pFirstChanceFilter = pNewFirstChanceFilter;
|
||||
return pOldFirstChanceFilter;
|
||||
}
|
||||
//
|
||||
///////////////////////////////////////////////////////////////// End of File.
|
21
samples/excep/firstexc.h
Normal file
21
samples/excep/firstexc.h
Normal file
@ -0,0 +1,21 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detours Test Program (firstexc.h of firstexc.exe)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#ifndef _FIRSTEXC_H_
|
||||
#define _FIRSTEXC_H_
|
||||
|
||||
/////////////////////////////////////////////// First Chance Exception Filter.
|
||||
//
|
||||
LPTOP_LEVEL_EXCEPTION_FILTER WINAPI
|
||||
DetourFirstChanceExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelFilter);
|
||||
|
||||
#endif // _FIRSTEXC_H_
|
||||
//
|
||||
//////////////////////////////////////////////////////////////// End of File.
|
178
samples/findfunc/Makefile
Normal file
178
samples/findfunc/Makefile
Normal 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
152
samples/findfunc/extend.cpp
Normal file
@ -0,0 +1,152 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detour Test Program (extend.cpp of extend.dll)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// An example dynamically detouring a function.
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include "detours.h"
|
||||
|
||||
static LONG nExtends = 0;
|
||||
static LONG nInterns = 0;
|
||||
|
||||
static DWORD (WINAPI * TrueTarget)(DWORD dwCount) = NULL;
|
||||
static DWORD (WINAPI * TrueHidden)(DWORD dwCount) = NULL;
|
||||
static int (WINAPI * TrueEntryPoint)(VOID) = NULL;
|
||||
|
||||
// Extend is a detour for Target.
|
||||
static DWORD WINAPI Extend(DWORD dwCount)
|
||||
{
|
||||
InterlockedIncrement(&nExtends);
|
||||
|
||||
printf("extend" 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.
|
17
samples/findfunc/extend.rc
Normal file
17
samples/findfunc/extend.rc
Normal file
@ -0,0 +1,17 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version information for extend.rc.
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
|
||||
#include "detver.h"
|
||||
|
||||
#define VER_INTERNALNAME_STR "extend" DETOURS_STRINGIFY(DETOURS_BITS)
|
||||
#define VER_ORIGINALFILENAME_STR "extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll"
|
||||
#define VER_FILEDESCRIPTION_STR "Detours Dyanmic Interception Test Module"
|
||||
#define VER_COMPANYNAME_STR "Microsoft Corporation"
|
||||
|
||||
#include "common.ver"
|
35
samples/findfunc/findfunc.cpp
Normal file
35
samples/findfunc/findfunc.cpp
Normal file
@ -0,0 +1,35 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detour Test Program (findfunc.cpp of findfunc.exe)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <detours.h>
|
||||
#include "target.h"
|
||||
|
||||
int __cdecl main(void)
|
||||
{
|
||||
printf("findfunc.exe: Starting.\n");
|
||||
fflush(stdout);
|
||||
|
||||
printf("DLLs:\n");
|
||||
for (HMODULE hModule = NULL; (hModule = DetourEnumerateModules(hModule)) != NULL;) {
|
||||
CHAR szName[MAX_PATH] = { 0 };
|
||||
GetModuleFileNameA(hModule, szName, sizeof(szName) - 1);
|
||||
printf(" %p: %s\n", hModule, szName);
|
||||
}
|
||||
|
||||
DWORD dwCount = 10000;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
printf("findfunc.exe: Calling (%ld).\n", dwCount);
|
||||
dwCount = Target(dwCount) + 10000;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
//
|
||||
///////////////////////////////////////////////////////////////// End of File.
|
385
samples/findfunc/symtest.cpp
Normal file
385
samples/findfunc/symtest.cpp
Normal file
@ -0,0 +1,385 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detour Test Program (symtest.cpp of symtest.exe)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#pragma warning(push)
|
||||
#if _MSC_VER > 1400
|
||||
#pragma warning(disable:6102 6103) // /analyze warnings
|
||||
#endif
|
||||
#include <strsafe.h>
|
||||
#pragma warning(pop)
|
||||
#include <detours.h>
|
||||
#include "target.h"
|
||||
|
||||
#if (_MSC_VER < 1299)
|
||||
#include <imagehlp.h>
|
||||
typedef IMAGEHLP_MODULE IMAGEHLP_MODULE64;
|
||||
typedef PIMAGEHLP_MODULE PIMAGEHLP_MODULE64;
|
||||
typedef IMAGEHLP_SYMBOL SYMBOL_INFO;
|
||||
typedef PIMAGEHLP_SYMBOL PSYMBOL_INFO;
|
||||
#else
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4091) // empty typedef
|
||||
#include <dbghelp.h>
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
typedef LPAPI_VERSION (NTAPI *PF_ImagehlpApiVersionEx)(LPAPI_VERSION AppVersion);
|
||||
|
||||
typedef BOOL (NTAPI *PF_SymInitialize)(IN HANDLE hProcess,
|
||||
IN LPCSTR UserSearchPath,
|
||||
IN BOOL fInvadeProcess);
|
||||
typedef DWORD (NTAPI *PF_SymSetOptions)(IN DWORD SymOptions);
|
||||
typedef DWORD (NTAPI *PF_SymGetOptions)(VOID);
|
||||
typedef DWORD64 (NTAPI *PF_SymLoadModule64)(IN HANDLE hProcess,
|
||||
IN HANDLE hFile,
|
||||
IN PSTR ImageName,
|
||||
IN PSTR ModuleName,
|
||||
IN DWORD64 BaseOfDll,
|
||||
IN DWORD SizeOfDll);
|
||||
typedef BOOL (NTAPI *PF_SymGetModuleInfo64)(IN HANDLE hProcess,
|
||||
IN DWORD64 qwAddr,
|
||||
OUT PIMAGEHLP_MODULE64 ModuleInfo);
|
||||
typedef BOOL (NTAPI *PF_SymFromName)(IN HANDLE hProcess,
|
||||
IN LPSTR Name,
|
||||
OUT PSYMBOL_INFO Symbol);
|
||||
#if (_MSC_VER < 1299)
|
||||
typedef BOOL (NTAPI *PF_SymRegisterCallback64)();
|
||||
typedef BOOL (NTAPI *PF_SymEnumerateModules64)();
|
||||
typedef BOOL (NTAPI *PF_SymEnumSymbols)();
|
||||
#else
|
||||
typedef BOOL (NTAPI *PF_SymRegisterCallback64)(IN HANDLE hProcess,
|
||||
IN PSYMBOL_REGISTERED_CALLBACK64
|
||||
CallbackFunction,
|
||||
IN ULONG64 UserContext);
|
||||
typedef BOOL (NTAPI *PF_SymEnumerateModules64)(IN HANDLE hProcess,
|
||||
IN PSYM_ENUMMODULES_CALLBACK64
|
||||
EnumModulesCallback,
|
||||
IN PVOID UserContext);
|
||||
typedef BOOL (NTAPI *PF_SymEnumSymbols)(IN HANDLE hProcess,
|
||||
IN ULONG64 BaseOfDll,
|
||||
IN PCSTR Mask,
|
||||
IN PSYM_ENUMERATESYMBOLS_CALLBACK
|
||||
EnumSymbolsCallback,
|
||||
IN PVOID UserContext);
|
||||
#endif
|
||||
|
||||
PF_ImagehlpApiVersionEx pfImagehlpApiVersionEx = NULL;
|
||||
PF_SymInitialize pfSymInitialize = NULL;
|
||||
PF_SymSetOptions pfSymSetOptions = NULL;
|
||||
PF_SymGetOptions pfSymGetOptions = NULL;
|
||||
PF_SymLoadModule64 pfSymLoadModule64 = NULL;
|
||||
PF_SymGetModuleInfo64 pfSymGetModuleInfo64 = NULL;
|
||||
PF_SymFromName pfSymFromName = NULL;
|
||||
PF_SymRegisterCallback64 pfSymRegisterCallback64 = NULL;
|
||||
PF_SymEnumerateModules64 pfSymEnumerateModules64 = NULL;
|
||||
PF_SymEnumSymbols pfSymEnumSymbols = NULL;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
||||
#if (_MSC_VER > 1299)
|
||||
static BOOL WINAPI SymEnumerateCallback(
|
||||
PCSTR pszModule,
|
||||
DWORD64 base,
|
||||
PVOID pvUserContext)
|
||||
{
|
||||
(void)pvUserContext;
|
||||
printf(" %p: %s\n", (PVOID)base, pszModule);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int nSymbolCount = 0;
|
||||
static BOOL WINAPI SymEnumerateSymbols(PSYMBOL_INFO pSym,
|
||||
ULONG size,
|
||||
PVOID pvUserContext)
|
||||
{
|
||||
(void)size;
|
||||
(void)pvUserContext;
|
||||
if (strstr(pSym->Name, "Target") != NULL ||
|
||||
strstr(pSym->Name, "Hidden") != NULL) {
|
||||
printf(" %p: %s\n", (PVOID)pSym->Address, pSym->Name);
|
||||
nSymbolCount++;
|
||||
}
|
||||
else if (nSymbolCount < 5) {
|
||||
printf(" %p: %s\n", (PVOID)pSym->Address, pSym->Name);
|
||||
nSymbolCount++;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void truncate(PCHAR data)
|
||||
{
|
||||
size_t len = strlen(data);
|
||||
if (len > 0 && data[len-1] == '\r') {
|
||||
data[--len] = '\0';
|
||||
}
|
||||
if (len > 0 && data[len-1] == '\n') {
|
||||
data[--len] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
BOOL WINAPI CallbackFunction(HANDLE hProcess, ULONG action, ULONG64 data, ULONG64 context)
|
||||
{
|
||||
(void)context;
|
||||
|
||||
switch (action) {
|
||||
case CBA_DEBUG_INFO:
|
||||
truncate((PCHAR)data);
|
||||
printf("::> %s\n", (PCHAR)data);
|
||||
return TRUE;
|
||||
|
||||
case CBA_DEFERRED_SYMBOL_LOAD_CANCEL:
|
||||
printf("::> proc=%p action=%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.
|
41
samples/findfunc/target.cpp
Normal file
41
samples/findfunc/target.cpp
Normal file
@ -0,0 +1,41 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detour Test Program (target.cpp of target.dll)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include "target.h"
|
||||
|
||||
extern "C" DWORD WINAPI Hidden(DWORD dwCount)
|
||||
{
|
||||
printf("target.dll: Hidden(%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
14
samples/findfunc/target.h
Normal 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.
|
17
samples/findfunc/target.rc
Normal file
17
samples/findfunc/target.rc
Normal file
@ -0,0 +1,17 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version information for target.rc.
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
|
||||
#include "detver.h"
|
||||
|
||||
#define VER_INTERNALNAME_STR "target" DETOURS_STRINGIFY(DETOURS_BITS)
|
||||
#define VER_ORIGINALFILENAME_STR "target" DETOURS_STRINGIFY(DETOURS_BITS) ".dll"
|
||||
#define VER_FILEDESCRIPTION_STR "Detours Test Module"
|
||||
#define VER_COMPANYNAME_STR "Microsoft Corporation"
|
||||
|
||||
#include "common.ver"
|
56
samples/impmunge/Makefile
Normal file
56
samples/impmunge/Makefile
Normal file
@ -0,0 +1,56 @@
|
||||
##############################################################################
|
||||
##
|
||||
## Makefile for Detours Test Programs.
|
||||
##
|
||||
## Microsoft Research Detours Package
|
||||
##
|
||||
## Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
##
|
||||
|
||||
!include ..\common.mak
|
||||
|
||||
LIBS=$(LIBS) kernel32.lib
|
||||
|
||||
all: dirs \
|
||||
$(BIND)\impmunge.exe \
|
||||
!IF $(DETOURS_SOURCE_BROWSING)==1
|
||||
$(OBJD)\impmunge.bsc
|
||||
!ENDIF
|
||||
|
||||
##############################################################################
|
||||
|
||||
clean:
|
||||
-del *~ test.exe.* 2>nul
|
||||
-del $(BIND)\impmunge.* 2>nul
|
||||
-rmdir /q /s $(OBJD) 2>nul
|
||||
|
||||
realclean: clean
|
||||
-rmdir /q /s $(OBJDS) 2>nul
|
||||
|
||||
##############################################################################
|
||||
|
||||
dirs:
|
||||
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
|
||||
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
|
||||
|
||||
$(OBJD)\impmunge.obj : impmunge.cpp
|
||||
|
||||
$(BIND)\impmunge.exe : $(OBJD)\impmunge.obj $(DEPS)
|
||||
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\impmunge.obj \
|
||||
/link $(LINKFLAGS) $(LIBS) imagehlp.lib /subsystem:console
|
||||
|
||||
$(OBJD)\impmunge.bsc : $(OBJD)\impmunge.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\impmunge.sbr
|
||||
|
||||
##############################################################################
|
||||
|
||||
test: $(BIND)\impmunge.exe
|
||||
$(BIND)\impmunge.exe /m /o:test.exe.1 $(BIND)\impmunge.exe
|
||||
$(BIND)\impmunge.exe /m /l- /o:test.exe.2 test.exe.1
|
||||
$(BIND)\impmunge.exe /m /l- /o:test.exe.3 test.exe.2
|
||||
$(BIND)\impmunge.exe /m /l- /o:test.exe.4 test.exe.3
|
||||
$(BIND)\impmunge.exe /l test.exe.4
|
||||
$(BIND)\impmunge.exe /r /l- /o:test.exe.0 test.exe.4
|
||||
$(BIND)\impmunge.exe /l test.exe.0
|
||||
|
||||
################################################################# End of File.
|
464
samples/impmunge/impmunge.cpp
Normal file
464
samples/impmunge/impmunge.cpp
Normal file
@ -0,0 +1,464 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detours Test Program (impmunge.cpp of impmunge.exe)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <windows.h>
|
||||
#pragma warning(push)
|
||||
#if _MSC_VER > 1400
|
||||
#pragma warning(disable:6102 6103) // /analyze warnings
|
||||
#endif
|
||||
#include <strsafe.h>
|
||||
#include <detours.h>
|
||||
#pragma warning(disable:4091) // empty typedef
|
||||
#include <imagehlp.h>
|
||||
#pragma warning(pop)
|
||||
|
||||
////////////////////////////////////////////////////////////// Error Messages.
|
||||
//
|
||||
VOID AssertMessage(PCSTR szMsg, PCSTR szFile, DWORD nLine)
|
||||
{
|
||||
printf("ASSERT(%s) failed in %s, line %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
48
samples/member/Makefile
Normal file
@ -0,0 +1,48 @@
|
||||
##############################################################################
|
||||
##
|
||||
## Makefile for Detours Test Programs.
|
||||
##
|
||||
## Microsoft Research Detours Package
|
||||
##
|
||||
## Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
##
|
||||
|
||||
!include ..\common.mak
|
||||
|
||||
LIBS=$(LIBS) kernel32.lib
|
||||
|
||||
all: dirs \
|
||||
$(BIND)\member.exe \
|
||||
!IF $(DETOURS_SOURCE_BROWSING)==1
|
||||
$(OBJD)\member.bsc
|
||||
!ENDIF
|
||||
|
||||
clean:
|
||||
-del *~ 2> nul
|
||||
-del $(BIND)\member.* 2> nul
|
||||
-rmdir /q /s $(OBJD) 2>nul
|
||||
|
||||
realclean: clean
|
||||
-rmdir /q /s $(OBJDS) 2>nul
|
||||
|
||||
dirs:
|
||||
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
|
||||
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
|
||||
|
||||
$(OBJD)\member.obj : member.cpp
|
||||
|
||||
$(BIND)\member.exe : $(OBJD)\member.obj $(DEPS)
|
||||
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\member.obj \
|
||||
/link $(LINKFLAGS) $(LIBS) /subsystem:console
|
||||
|
||||
$(OBJD)\member.bsc : $(OBJD)\member.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\member.sbr
|
||||
|
||||
##############################################################################
|
||||
|
||||
test: $(BIND)\member.exe
|
||||
@echo.
|
||||
$(BIND)\member.exe
|
||||
@echo.
|
||||
|
||||
################################################################# End of File.
|
116
samples/member/member.cpp
Normal file
116
samples/member/member.cpp
Normal file
@ -0,0 +1,116 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Test a detour of a member function (member.cpp of member.exe)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// By default, C++ member functions use the __thiscall calling convention.
|
||||
// In order to Detour a member function, both the trampoline and the detour
|
||||
// must have exactly the same calling convention as the target function.
|
||||
// Unfortunately, the VC compiler does not support a __thiscall, so the only
|
||||
// way to create legal detour and trampoline functions is by making them
|
||||
// class members of a "detour" class.
|
||||
//
|
||||
// In addition, C++ does not support converting a pointer to a member
|
||||
// function to an arbitrary pointer. To get a raw pointer, the address of
|
||||
// the member function must be moved into a temporary member-function
|
||||
// pointer, then passed by taking it's address, then de-referencing it.
|
||||
// Fortunately, the compiler will optimize the code to remove the extra
|
||||
// pointer operations.
|
||||
//
|
||||
// If X::Target is a virtual function, the following code will *NOT* work
|
||||
// because &X::Target is the address of a thunk that does a virtual call,
|
||||
// not the real address of the X::Target. You can get the real address
|
||||
// of X::Target by looking directly in the VTBL for class X, but there
|
||||
// is no legal way to 1) get the address of X's VTBL or 2) get the offset
|
||||
// of ::Target within that VTBL. You can of course, figure these out for
|
||||
// a particular class and function, but there is no general way to do so.
|
||||
//
|
||||
#include <stdio.h>
|
||||
|
||||
#include <windows.h>
|
||||
#include <detours.h>
|
||||
|
||||
#include "..\slept\verify.cpp"
|
||||
|
||||
//////////////////////////////////////////////////////////////// Target Class.
|
||||
//
|
||||
class CMember
|
||||
{
|
||||
public:
|
||||
void Target(void);
|
||||
};
|
||||
|
||||
void CMember::Target(void)
|
||||
{
|
||||
printf(" CMember::Target! (this:%p)\n", this);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////// Detour Class.
|
||||
//
|
||||
class CDetour /* add ": public CMember" to enable access to member variables... */
|
||||
{
|
||||
public:
|
||||
void Mine_Target(void);
|
||||
static void (CDetour::* Real_Target)(void);
|
||||
|
||||
// Class shouldn't have any member variables or virtual functions.
|
||||
};
|
||||
|
||||
void CDetour::Mine_Target(void)
|
||||
{
|
||||
printf(" CDetour::Mine_Target! (this:%p)\n", this);
|
||||
(this->*Real_Target)();
|
||||
}
|
||||
|
||||
void (CDetour::* CDetour::Real_Target)(void) = (void (CDetour::*)(void))&CMember::Target;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
||||
void (CMember::* pfTarget)(void) = &CMember::Target;
|
||||
void (CDetour::* pfMine)(void) = &CDetour::Mine_Target;
|
||||
|
||||
Verify("CMember::Target ", *(PBYTE*)&pfTarget);
|
||||
Verify("*CDetour::Real_Target", *(PBYTE*)&CDetour::Real_Target);
|
||||
Verify("CDetour::Mine_Target ", *(PBYTE*)&pfMine);
|
||||
|
||||
printf("\n");
|
||||
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
|
||||
DetourAttach(&(PVOID&)CDetour::Real_Target,
|
||||
*(PBYTE*)&pfMine);
|
||||
|
||||
LONG l = DetourTransactionCommit();
|
||||
printf("DetourTransactionCommit = %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
112
samples/opengl/Makefile
Normal file
@ -0,0 +1,112 @@
|
||||
######################################################################
|
||||
##
|
||||
## Hook test for glFinish
|
||||
##
|
||||
|
||||
!include ..\common.mak
|
||||
|
||||
LIBS=$(LIBS) kernel32.lib gdi32.lib
|
||||
|
||||
##############################################################################
|
||||
|
||||
all: dirs \
|
||||
$(BIND)\ogldet$(DETOURS_BITS).dll \
|
||||
$(BIND)\testogl.exe \
|
||||
\
|
||||
!IF $(DETOURS_SOURCE_BROWSING)==1
|
||||
$(OBJD)\ogldet$(DETOURS_BITS).bsc \
|
||||
$(OBJD)\testogl.bsc \
|
||||
!ENDIF
|
||||
option
|
||||
|
||||
##############################################################################
|
||||
|
||||
dirs:
|
||||
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
|
||||
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
|
||||
|
||||
$(OBJD)\ogldet.obj : ogldet.cpp
|
||||
|
||||
$(OBJD)\ogldet.res : ogldet.rc
|
||||
|
||||
$(BIND)\ogldet$(DETOURS_BITS).dll $(BIND)\ogldet$(DETOURS_BITS).lib: \
|
||||
$(OBJD)\ogldet.obj $(OBJD)\ogldet.res $(DEPS)
|
||||
cl /LD $(CFLAGS) /Fe$(@R).dll /Fd$(@R).pdb \
|
||||
$(OBJD)\ogldet.obj $(OBJD)\ogldet.res \
|
||||
/link $(LINKFLAGS) /subsystem:console \
|
||||
/export:DetourFinishHelperProcess,@1,NONAME \
|
||||
/export:hookedGlFinish \
|
||||
$(LIBS) opengl32.lib
|
||||
|
||||
$(OBJD)\ogldet$(DETOURS_BITS).bsc : $(OBJD)\ogldet.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\ogldet.sbr
|
||||
|
||||
$(OBJD)\testogl.obj : testogl.cpp
|
||||
|
||||
$(BIND)\testogl.exe : $(OBJD)\testogl.obj $(DEPS)
|
||||
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\testogl.obj \
|
||||
/link $(LINKFLAGS) $(LIBS) opengl32.lib \
|
||||
/subsystem:console
|
||||
|
||||
$(OBJD)\testogl.bsc : $(OBJD)\testogl.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\testogl.sbr
|
||||
|
||||
##############################################################################
|
||||
|
||||
clean:
|
||||
-del *~ 2>nul
|
||||
-del $(BIND)\ogldet*.* 2>nul
|
||||
-del $(BIND)\testogl.* 2>nul
|
||||
-rmdir /q /s $(OBJD) 2>nul
|
||||
|
||||
realclean: clean
|
||||
-rmdir /q /s $(OBJDS) 2>nul
|
||||
|
||||
############################################### Install non-bit-size binaries.
|
||||
|
||||
!IF "$(DETOURS_OPTION_PROCESSOR)" != ""
|
||||
|
||||
$(OPTD)\olgdet$(DETOURS_OPTION_BITS).dll:
|
||||
$(OPTD)\olgdet$(DETOURS_OPTION_BITS).pdb:
|
||||
|
||||
$(BIND)\olgdet$(DETOURS_OPTION_BITS).dll : $(OPTD)\olgdet$(DETOURS_OPTION_BITS).dll
|
||||
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
|
||||
$(BIND)\olgdet$(DETOURS_OPTION_BITS).pdb : $(OPTD)\olgdet$(DETOURS_OPTION_BITS).pdb
|
||||
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
|
||||
|
||||
option: \
|
||||
$(BIND)\olgdet$(DETOURS_OPTION_BITS).dll \
|
||||
$(BIND)\olgdet$(DETOURS_OPTION_BITS).pdb \
|
||||
|
||||
!ELSE
|
||||
|
||||
option:
|
||||
|
||||
!ENDIF
|
||||
|
||||
##############################################################################
|
||||
|
||||
test: all
|
||||
@echo -------- Reseting test binaries to initial state. ---------------------
|
||||
$(BIND)\setdll.exe -r $(BIND)\testogl.exe
|
||||
@echo.
|
||||
@echo -------- Should not load ogldet$(DETOURS_BITS).dll -----------------------------------
|
||||
$(BIND)\testogl.exe
|
||||
@echo.
|
||||
@echo -------- Adding ogldet$(DETOURS_BITS).dll to testogl.exe ------------------------------
|
||||
$(BIND)\setdll.exe -d:$(BIND)\ogldet$(DETOURS_BITS).dll $(BIND)\testogl.exe
|
||||
@echo.
|
||||
@echo -------- Should load ogldet$(DETOURS_BITS).dll statically ----------------------------
|
||||
$(BIND)\testogl.exe
|
||||
@echo.
|
||||
@echo -------- Removing ogldet$(DETOURS_BITS).dll from testogl.exe --------------------------
|
||||
$(BIND)\setdll.exe -r $(BIND)\testogl.exe
|
||||
@echo.
|
||||
@echo -------- Should not load ogldet$(DETOURS_BITS).dll -----------------------------------
|
||||
$(BIND)\testogl.exe
|
||||
@echo.
|
||||
@echo -------- Should load ogldet$(DETOURS_BITS).dll dynamically using withdll.exe----------
|
||||
$(BIND)\withdll.exe -d:$(BIND)\ogldet$(DETOURS_BITS).dll $(BIND)\testogl.exe
|
||||
@echo.
|
||||
|
||||
################################################################# End of File.
|
74
samples/opengl/ogldet.cpp
Normal file
74
samples/opengl/ogldet.cpp
Normal file
@ -0,0 +1,74 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Module: ogldet.dll
|
||||
//
|
||||
// This DLL is based on the sample simple.dll. A detour is inserted for
|
||||
// the OpenGL glFinish function.
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include <GL/gl.h>
|
||||
#include "detours.h"
|
||||
|
||||
static void (WINAPI * trueGlFinish)(void) = glFinish;
|
||||
|
||||
void WINAPI hookedGlFinish(void)
|
||||
{
|
||||
printf("ogldet" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
|
||||
" hookedGlFinish Starting.\n");
|
||||
fflush(stdout);
|
||||
|
||||
trueGlFinish();
|
||||
|
||||
printf("ogldet" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
|
||||
" hookedGlFinish done.\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
|
||||
{
|
||||
LONG error;
|
||||
(void)hinst;
|
||||
(void)reserved;
|
||||
|
||||
if (DetourIsHelperProcess()) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (dwReason == DLL_PROCESS_ATTACH) {
|
||||
DetourRestoreAfterWith();
|
||||
|
||||
printf("ogldet" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
|
||||
" Starting.\n");
|
||||
fflush(stdout);
|
||||
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
DetourAttach(&(PVOID&)trueGlFinish, hookedGlFinish);
|
||||
error = DetourTransactionCommit();
|
||||
|
||||
if (error == NO_ERROR) {
|
||||
printf("ogldet" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
|
||||
" Detoured glFinish().\n");
|
||||
}
|
||||
else {
|
||||
printf("ogldet" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
|
||||
" Error detouring glFinish(): %d\n", error);
|
||||
}
|
||||
}
|
||||
else if (dwReason == DLL_PROCESS_DETACH) {
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
DetourDetach(&(PVOID&)trueGlFinish, hookedGlFinish);
|
||||
error = DetourTransactionCommit();
|
||||
|
||||
printf("ogldet" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
|
||||
" Removed detour glFinish() (result=%d)\n", error);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//
|
||||
///////////////////////////////////////////////////////////////// End of File.
|
17
samples/opengl/ogldet.rc
Normal file
17
samples/opengl/ogldet.rc
Normal file
@ -0,0 +1,17 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version information for ogldet.rc.
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
|
||||
#include "detver.h"
|
||||
|
||||
#define VER_INTERNALNAME_STR "ogldet" DETOURS_STRINGIFY(DETOURS_BITS)
|
||||
#define VER_ORIGINALFILENAME_STR "ogldet" DETOURS_STRINGIFY(DETOURS_BITS) ".dll"
|
||||
#define VER_FILEDESCRIPTION_STR "Detours Open GL Test Module"
|
||||
#define VER_COMPANYNAME_STR "Microsoft Corporation"
|
||||
|
||||
#include "common.ver"
|
24
samples/opengl/testogl.cpp
Normal file
24
samples/opengl/testogl.cpp
Normal file
@ -0,0 +1,24 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// File: testogl.cpp
|
||||
// Module: testogl.exe (oglsimple.dll)
|
||||
//
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <GL/gl.h>
|
||||
|
||||
int __cdecl main()
|
||||
{
|
||||
printf("testogl.exe: Starting\n");
|
||||
fflush(stdout);
|
||||
|
||||
glFinish();
|
||||
|
||||
printf("testogl.exe: done\n");
|
||||
fflush(stdout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
//
|
||||
///////////////////////////////////////////////////////////////// End of File.
|
48
samples/region/Makefile
Normal file
48
samples/region/Makefile
Normal file
@ -0,0 +1,48 @@
|
||||
##############################################################################
|
||||
##
|
||||
## Makefile for Detours Test Programs.
|
||||
##
|
||||
## Microsoft Research Detours Package
|
||||
##
|
||||
## Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
##
|
||||
|
||||
!include ..\common.mak
|
||||
|
||||
LIBS=$(LIBS) kernel32.lib
|
||||
|
||||
all: dirs \
|
||||
$(BIND)\region.exe \
|
||||
!IF $(DETOURS_SOURCE_BROWSING)==1
|
||||
$(OBJD)\region.bsc
|
||||
!ENDIF
|
||||
|
||||
clean:
|
||||
-del *~ 2> nul
|
||||
-del $(BIND)\region.* 2> nul
|
||||
-rmdir /q /s $(OBJD) 2>nul
|
||||
|
||||
realclean: clean
|
||||
-rmdir /q /s $(OBJDS) 2>nul
|
||||
|
||||
dirs:
|
||||
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
|
||||
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
|
||||
|
||||
$(OBJD)\region.obj : region.cpp
|
||||
|
||||
$(BIND)\region.exe : $(OBJD)\region.obj $(DEPS)
|
||||
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\region.obj \
|
||||
/link $(LINKFLAGS) $(LIBS) /subsystem:console
|
||||
|
||||
$(OBJD)\region.bsc : $(OBJD)\region.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\region.sbr
|
||||
|
||||
##############################################################################
|
||||
|
||||
test: $(BIND)\region.exe
|
||||
@echo.
|
||||
$(BIND)\region.exe
|
||||
@echo.
|
||||
|
||||
################################################################# End of File.
|
104
samples/region/region.cpp
Normal file
104
samples/region/region.cpp
Normal 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
62
samples/setdll/Makefile
Normal file
@ -0,0 +1,62 @@
|
||||
##############################################################################
|
||||
##
|
||||
## Makefile for Detours Test Programs.
|
||||
##
|
||||
## Microsoft Research Detours Package
|
||||
##
|
||||
## Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
##
|
||||
|
||||
!include ..\common.mak
|
||||
|
||||
LIBS=$(LIBS) kernel32.lib
|
||||
|
||||
all: dirs \
|
||||
$(BIND)\setdll.exe \
|
||||
!IF $(DETOURS_SOURCE_BROWSING)==1
|
||||
$(OBJD)\setdll.bsc \
|
||||
!ENDIF
|
||||
option
|
||||
|
||||
##############################################################################
|
||||
|
||||
clean:
|
||||
-del *~ 2>nul
|
||||
-del $(BIND)\setdll.* 2>nul
|
||||
-rmdir /q /s $(OBJD) 2>nul
|
||||
|
||||
realclean: clean
|
||||
-rmdir /q /s $(OBJDS) 2>nul
|
||||
|
||||
##############################################################################
|
||||
|
||||
dirs:
|
||||
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
|
||||
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
|
||||
|
||||
$(OBJD)\setdll.obj : setdll.cpp
|
||||
|
||||
$(BIND)\setdll.exe : $(OBJD)\setdll.obj $(DEPS)
|
||||
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\setdll.obj \
|
||||
/link $(LINKFLAGS) $(LIBS) /subsystem:console
|
||||
|
||||
$(OBJD)\setdll.bsc : $(OBJD)\setdll.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\setdll.sbr
|
||||
|
||||
############################################### Install non-bit-size binaries.
|
||||
|
||||
option:
|
||||
|
||||
##############################################################################
|
||||
|
||||
test: all
|
||||
@echo -------- Reseting test binaries to initial state. -----------------------
|
||||
$(BIND)\setdll.exe -d:$(BIND)\slept$(DETOURS_BITS).dll $(BIND)\sleepold.exe
|
||||
@echo -------- Should load slept$(DETOURS_BITS).dll statically -------------------------------
|
||||
$(BIND)\sleepold.exe
|
||||
@echo -------- Reseting test binaries to initial state. -----------------------
|
||||
$(BIND)\setdll.exe -r $(BIND)\sleepold.exe
|
||||
@echo -------- Should not load slept$(DETOURS_BITS).dll --------------------------------------
|
||||
$(BIND)\sleepold.exe
|
||||
|
||||
################################################################# End of File.
|
332
samples/setdll/setdll.cpp
Normal file
332
samples/setdll/setdll.cpp
Normal file
@ -0,0 +1,332 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detours Test Program (setdll.cpp of setdll.exe)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <windows.h>
|
||||
#include <shellapi.h>
|
||||
#include <detours.h>
|
||||
#pragma warning(push)
|
||||
#if _MSC_VER > 1400
|
||||
#pragma warning(disable:6102 6103) // /analyze warnings
|
||||
#endif
|
||||
#include <strsafe.h>
|
||||
#pragma warning(pop)
|
||||
|
||||
////////////////////////////////////////////////////////////// Error Messages.
|
||||
//
|
||||
VOID AssertMessage(PCSTR szMsg, PCSTR szFile, DWORD nLine)
|
||||
{
|
||||
printf("ASSERT(%s) failed in %s, line %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
120
samples/simple/Makefile
Normal file
@ -0,0 +1,120 @@
|
||||
##############################################################################
|
||||
##
|
||||
## API Extention to Measure time slept.
|
||||
##
|
||||
## Microsoft Research Detours Package
|
||||
##
|
||||
## Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
##
|
||||
|
||||
!include ..\common.mak
|
||||
|
||||
LIBS=$(LIBS) kernel32.lib
|
||||
|
||||
##############################################################################
|
||||
|
||||
all: dirs \
|
||||
$(BIND)\simple$(DETOURS_BITS).dll \
|
||||
$(BIND)\sleep5.exe \
|
||||
\
|
||||
!IF $(DETOURS_SOURCE_BROWSING)==1
|
||||
$(OBJD)\simple$(DETOURS_BITS).bsc \
|
||||
$(OBJD)\sleep5.bsc \
|
||||
!ENDIF
|
||||
option
|
||||
|
||||
##############################################################################
|
||||
|
||||
dirs:
|
||||
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
|
||||
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
|
||||
|
||||
$(OBJD)\simple.obj : simple.cpp
|
||||
|
||||
$(OBJD)\simple.res : simple.rc
|
||||
|
||||
$(BIND)\simple$(DETOURS_BITS).dll $(BIND)\simple$(DETOURS_BITS).lib: \
|
||||
$(OBJD)\simple.obj $(OBJD)\simple.res $(DEPS)
|
||||
cl /LD $(CFLAGS) /Fe$(@R).dll /Fd$(@R).pdb \
|
||||
$(OBJD)\simple.obj $(OBJD)\simple.res \
|
||||
/link $(LINKFLAGS) /subsystem:console \
|
||||
/export:DetourFinishHelperProcess,@1,NONAME \
|
||||
/export:TimedSleepEx \
|
||||
$(LIBS)
|
||||
|
||||
$(OBJD)\simple$(DETOURS_BITS).bsc : $(OBJD)\simple.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\simple.sbr
|
||||
|
||||
$(OBJD)\sleep5.obj : sleep5.cpp
|
||||
|
||||
$(BIND)\sleep5.exe : $(OBJD)\sleep5.obj $(DEPS)
|
||||
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\sleep5.obj \
|
||||
/link $(LINKFLAGS) $(LIBS) \
|
||||
/subsystem:console
|
||||
|
||||
$(OBJD)\sleep5.bsc : $(OBJD)\sleep5.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\sleep5.sbr
|
||||
|
||||
##############################################################################
|
||||
|
||||
clean:
|
||||
-del *~ 2>nul
|
||||
-del $(BIND)\simple*.* 2>nul
|
||||
-del $(BIND)\sleep5.* 2>nul
|
||||
-rmdir /q /s $(OBJD) 2>nul
|
||||
|
||||
realclean: clean
|
||||
-rmdir /q /s $(OBJDS) 2>nul
|
||||
|
||||
############################################### Install non-bit-size binaries.
|
||||
|
||||
!IF "$(DETOURS_OPTION_PROCESSOR)" != ""
|
||||
|
||||
$(OPTD)\simple$(DETOURS_OPTION_BITS).dll:
|
||||
$(OPTD)\simple$(DETOURS_OPTION_BITS).pdb:
|
||||
|
||||
$(BIND)\simple$(DETOURS_OPTION_BITS).dll : $(OPTD)\simple$(DETOURS_OPTION_BITS).dll
|
||||
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
|
||||
$(BIND)\simple$(DETOURS_OPTION_BITS).pdb : $(OPTD)\simple$(DETOURS_OPTION_BITS).pdb
|
||||
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
|
||||
|
||||
option: \
|
||||
$(BIND)\simple$(DETOURS_OPTION_BITS).dll \
|
||||
$(BIND)\simple$(DETOURS_OPTION_BITS).pdb \
|
||||
|
||||
!ELSE
|
||||
|
||||
option:
|
||||
|
||||
!ENDIF
|
||||
|
||||
##############################################################################
|
||||
|
||||
test: all
|
||||
@echo -------- Reseting test binaries to initial state. ---------------------
|
||||
$(BIND)\setdll.exe -r $(BIND)\sleep5.exe
|
||||
@echo.
|
||||
@echo -------- Should not load simple$(DETOURS_BITS).dll -----------------------------------
|
||||
$(BIND)\sleep5.exe
|
||||
@echo.
|
||||
@echo -------- Adding simple$(DETOURS_BITS).dll to sleep5.exe ------------------------------
|
||||
$(BIND)\setdll.exe -d:$(BIND)\simple$(DETOURS_BITS).dll $(BIND)\sleep5.exe
|
||||
@echo.
|
||||
@echo -------- Should load simple$(DETOURS_BITS).dll statically ----------------------------
|
||||
$(BIND)\sleep5.exe
|
||||
@echo.
|
||||
@echo -------- Removing simple$(DETOURS_BITS).dll from sleep5.exe --------------------------
|
||||
$(BIND)\setdll.exe -r $(BIND)\sleep5.exe
|
||||
@echo.
|
||||
@echo -------- Should not load simple$(DETOURS_BITS).dll -----------------------------------
|
||||
$(BIND)\sleep5.exe
|
||||
@echo.
|
||||
@echo -------- Should load simple$(DETOURS_BITS).dll dynamically using withdll.exe----------
|
||||
$(BIND)\withdll.exe -d:$(BIND)\simple$(DETOURS_BITS).dll $(BIND)\sleep5.exe
|
||||
@echo.
|
||||
|
||||
debug: all
|
||||
windbg -o $(BIND)\withdll.exe -d:$(BIND)\simple$(DETOURS_BITS).dll $(BIND)\sleep5.exe
|
||||
|
||||
|
||||
################################################################# End of File.
|
76
samples/simple/simple.cpp
Normal file
76
samples/simple/simple.cpp
Normal file
@ -0,0 +1,76 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detours Test Program (simple.cpp of simple.dll)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// This DLL will detour the Windows SleepEx API so that TimedSleep function
|
||||
// gets called instead. TimedSleepEx records the before and after times, and
|
||||
// calls the real SleepEx API through the TrueSleepEx function pointer.
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include "detours.h"
|
||||
|
||||
static LONG dwSlept = 0;
|
||||
static DWORD (WINAPI * TrueSleepEx)(DWORD dwMilliseconds, BOOL bAlertable) = SleepEx;
|
||||
|
||||
DWORD WINAPI TimedSleepEx(DWORD dwMilliseconds, BOOL bAlertable)
|
||||
{
|
||||
DWORD dwBeg = GetTickCount();
|
||||
DWORD ret = TrueSleepEx(dwMilliseconds, bAlertable);
|
||||
DWORD dwEnd = GetTickCount();
|
||||
|
||||
InterlockedExchangeAdd(&dwSlept, dwEnd - dwBeg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
|
||||
{
|
||||
LONG error;
|
||||
(void)hinst;
|
||||
(void)reserved;
|
||||
|
||||
if (DetourIsHelperProcess()) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (dwReason == DLL_PROCESS_ATTACH) {
|
||||
DetourRestoreAfterWith();
|
||||
|
||||
printf("simple" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
|
||||
" Starting.\n");
|
||||
fflush(stdout);
|
||||
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
DetourAttach(&(PVOID&)TrueSleepEx, TimedSleepEx);
|
||||
error = DetourTransactionCommit();
|
||||
|
||||
if (error == NO_ERROR) {
|
||||
printf("simple" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
|
||||
" Detoured SleepEx().\n");
|
||||
}
|
||||
else {
|
||||
printf("simple" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
|
||||
" Error detouring SleepEx(): %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
17
samples/simple/simple.rc
Normal file
@ -0,0 +1,17 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version information for simple.rc.
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
|
||||
#include "detver.h"
|
||||
|
||||
#define VER_INTERNALNAME_STR "simple" DETOURS_STRINGIFY(DETOURS_BITS)
|
||||
#define VER_ORIGINALFILENAME_STR "simple" DETOURS_STRINGIFY(DETOURS_BITS) ".dll"
|
||||
#define VER_FILEDESCRIPTION_STR "Detours Test Module"
|
||||
#define VER_COMPANYNAME_STR "Microsoft Corporation"
|
||||
|
||||
#include "common.ver"
|
29
samples/simple/sleep5.cpp
Normal file
29
samples/simple/sleep5.cpp
Normal file
@ -0,0 +1,29 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detours Test Program (sleep5.cpp of sleep5.exe)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int __cdecl main(int argc, char ** argv)
|
||||
{
|
||||
if (argc == 2) {
|
||||
Sleep(atoi(argv[1]) * 1000);
|
||||
}
|
||||
else {
|
||||
printf("sleep5.exe: Starting.\n");
|
||||
|
||||
Sleep(5000);
|
||||
|
||||
printf("sleep5.exe: Done sleeping.\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
//
|
||||
///////////////////////////////////////////////////////////////// End of File.
|
194
samples/slept/Makefile
Normal file
194
samples/slept/Makefile
Normal file
@ -0,0 +1,194 @@
|
||||
##############################################################################
|
||||
##
|
||||
## API Extension to Measure time slept.
|
||||
##
|
||||
## Microsoft Research Detours Package
|
||||
##
|
||||
## Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
##
|
||||
|
||||
!include ..\common.mak
|
||||
|
||||
CFLAGS = $(CFLAGS:/Od=/O2)
|
||||
|
||||
LIBS=$(LIBS) kernel32.lib
|
||||
|
||||
##############################################################################
|
||||
|
||||
all: dirs \
|
||||
$(BIND)\slept$(DETOURS_BITS).dll \
|
||||
$(BIND)\dslept$(DETOURS_BITS).dll \
|
||||
$(BIND)\sleepold.exe \
|
||||
$(BIND)\sleepnew.exe \
|
||||
$(BIND)\sleepbed.exe \
|
||||
\
|
||||
!IF $(DETOURS_SOURCE_BROWSING)==1
|
||||
$(OBJD)\slept$(DETOURS_BITS).bsc \
|
||||
$(OBJD)\dslept$(DETOURS_BITS).bsc \
|
||||
$(OBJD)\sleepold.bsc \
|
||||
$(OBJD)\sleepnew.bsc \
|
||||
$(OBJD)\sleepbed.bsc \
|
||||
!ENDIF
|
||||
option
|
||||
|
||||
##############################################################################
|
||||
|
||||
dirs:
|
||||
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
|
||||
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
|
||||
|
||||
$(OBJD)\slept.obj : slept.cpp verify.cpp
|
||||
|
||||
$(OBJD)\slept.res : slept.rc
|
||||
|
||||
$(BIND)\slept$(DETOURS_BITS).dll $(BIND)\slept$(DETOURS_BITS).lib: \
|
||||
$(OBJD)\slept.obj $(OBJD)\slept.res $(DEPS)
|
||||
cl /LD $(CFLAGS) /Fe$(@R).dll /Fd$(@R).pdb \
|
||||
$(OBJD)\slept.obj $(OBJD)\slept.res\
|
||||
/link $(LINKFLAGS) /subsystem:console \
|
||||
/export:DetourFinishHelperProcess,@1,NONAME \
|
||||
/export:TimedSleepEx \
|
||||
/export:UntimedSleepEx \
|
||||
/export:GetSleptTicks \
|
||||
/export:TestTicks \
|
||||
/export:TestTicksEx \
|
||||
$(LIBS)
|
||||
|
||||
$(OBJD)\slept$(DETOURS_BITS).bsc : $(OBJD)\slept.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\slept.sbr
|
||||
|
||||
$(OBJD)\dslept.obj : dslept.cpp verify.cpp
|
||||
|
||||
$(OBJD)\dslept.res : dslept.rc
|
||||
|
||||
$(BIND)\dslept$(DETOURS_BITS).dll $(BIND)\dslept$(DETOURS_BITS).lib: \
|
||||
$(OBJD)\dslept.obj $(OBJD)\dslept.res $(DEPS)
|
||||
cl /LD $(CFLAGS) /Fe$(@R).dll /Fd$(@R).pdb \
|
||||
$(OBJD)\dslept.obj $(OBJD)\dslept.res \
|
||||
/link $(LINKFLAGS) /subsystem:console \
|
||||
/export:DetourFinishHelperProcess,@1,NONAME \
|
||||
/export:TimedSleepEx \
|
||||
/export:UntimedSleepEx \
|
||||
/export:GetSleptTicks \
|
||||
$(LIBS)
|
||||
|
||||
$(OBJD)\dslept$(DETOURS_BITS).bsc : $(OBJD)\dslept.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\dslept.sbr
|
||||
|
||||
$(OBJD)\sleepold.obj : sleepold.cpp verify.cpp
|
||||
|
||||
$(BIND)\sleepold.exe : $(OBJD)\sleepold.obj $(DEPS)
|
||||
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\sleepold.obj \
|
||||
/link $(LINKFLAGS) $(LIBS) \
|
||||
/subsystem:console /fixed:no
|
||||
|
||||
$(OBJD)\sleepold.bsc : $(OBJD)\sleepold.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\sleepold.sbr
|
||||
|
||||
$(OBJD)\sleepnew.obj : sleepnew.cpp verify.cpp
|
||||
|
||||
$(BIND)\sleepnew.exe : $(OBJD)\sleepnew.obj $(BIND)\slept$(DETOURS_BITS).lib $(DEPS)
|
||||
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\sleepnew.obj \
|
||||
/link $(LINKFLAGS) $(LIBS) \
|
||||
/subsystem:console /fixed:no $(BIND)\slept$(DETOURS_BITS).lib
|
||||
|
||||
$(OBJD)\sleepnew.bsc : $(OBJD)\sleepnew.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\sleepnew.sbr
|
||||
|
||||
$(OBJD)\sleepbed.obj : sleepbed.cpp verify.cpp
|
||||
|
||||
$(BIND)\sleepbed.exe : $(OBJD)\sleepbed.obj $(DEPS)
|
||||
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\sleepbed.obj \
|
||||
/link $(LINKFLAGS) $(LIBS) \
|
||||
/subsystem:console /fixed:no
|
||||
|
||||
$(OBJD)\sleepbed.bsc : $(OBJD)\sleepbed.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\sleepbed.sbr
|
||||
|
||||
##############################################################################
|
||||
|
||||
clean:
|
||||
-del *~ 2>nul
|
||||
-del $(BIND)\slept*.* 2>nul
|
||||
-del $(BIND)\dslept*.* 2>nul
|
||||
-del $(BIND)\sleepold.* 2>nul
|
||||
-del $(BIND)\sleepnew.* 2>nul
|
||||
-del $(BIND)\sleepbed.* 2>nul
|
||||
-rmdir /q /s $(OBJD) 2>nul
|
||||
|
||||
realclean: clean
|
||||
-rmdir /q /s $(OBJDS) 2>nul
|
||||
|
||||
############################################### Install non-bit-size binaries.
|
||||
|
||||
!IF "$(DETOURS_OPTION_PROCESSOR)" != ""
|
||||
|
||||
$(OPTD)\slept$(DETOURS_OPTION_BITS).dll:
|
||||
$(OPTD)\slept$(DETOURS_OPTION_BITS).pdb:
|
||||
$(OPTD)\dslept$(DETOURS_OPTION_BITS).dll:
|
||||
$(OPTD)\dslept$(DETOURS_OPTION_BITS).pdb:
|
||||
|
||||
$(BIND)\slept$(DETOURS_OPTION_BITS).dll: $(OPTD)\slept$(DETOURS_OPTION_BITS).dll
|
||||
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
|
||||
$(BIND)\slept$(DETOURS_OPTION_BITS).pdb: $(OPTD)\slept$(DETOURS_OPTION_BITS).pdb
|
||||
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
|
||||
$(BIND)\dslept$(DETOURS_OPTION_BITS).dll: $(OPTD)\dslept$(DETOURS_OPTION_BITS).dll
|
||||
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
|
||||
$(BIND)\dslept$(DETOURS_OPTION_BITS).pdb: $(OPTD)\dslept$(DETOURS_OPTION_BITS).pdb
|
||||
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
|
||||
|
||||
option: \
|
||||
$(BIND)\slept$(DETOURS_OPTION_BITS).dll \
|
||||
$(BIND)\slept$(DETOURS_OPTION_BITS).pdb \
|
||||
$(BIND)\dslept$(DETOURS_OPTION_BITS).dll \
|
||||
$(BIND)\dslept$(DETOURS_OPTION_BITS).pdb \
|
||||
|
||||
!ELSE
|
||||
|
||||
option:
|
||||
|
||||
!ENDIF
|
||||
|
||||
##############################################################################
|
||||
|
||||
skype: all
|
||||
start windbg -G -o $(BIND)\withdll.exe -d:$(BIND)\slept$(DETOURS_BITS).dll "C:\Program Files (x86)\Skype\Phone\Skype.exe"
|
||||
|
||||
test: all
|
||||
@echo -------- Reseting test binaries to initial state. -----------------------
|
||||
$(BIND)\setdll.exe -r $(BIND)\sleepold.exe
|
||||
@echo.
|
||||
@echo -------- Should load detour self ----------------------------------------
|
||||
$(BIND)\sleepbed.exe
|
||||
@echo.
|
||||
@echo -------- Should load slept$(DETOURS_BITS).dll statically -------------------------------
|
||||
$(BIND)\sleepnew.exe
|
||||
@echo.
|
||||
@echo -------- Should not load slept$(DETOURS_BITS).dll --------------------------------------
|
||||
$(BIND)\sleepold.exe
|
||||
@echo.
|
||||
@echo -------- Adding slept$(DETOURS_BITS).dll to sleepold.exe -------------------------------
|
||||
$(BIND)\setdll.exe -d:$(BIND)\slept$(DETOURS_BITS).dll $(BIND)\sleepold.exe
|
||||
@echo.
|
||||
@echo -------- Should load slept$(DETOURS_BITS).dll statically -------------------------------
|
||||
$(BIND)\sleepold.exe
|
||||
@echo.
|
||||
@echo -------- Replacing slept$(DETOURS_BITS).dll with dslept$(DETOURS_BITS).dll in sleepold.exe ------------
|
||||
$(BIND)\setdll.exe -r $(BIND)\sleepold.exe
|
||||
$(BIND)\setdll.exe -d:$(BIND)\dslept$(DETOURS_BITS).dll $(BIND)\sleepold.exe
|
||||
@echo.
|
||||
@echo -------- Should load dslept$(DETOURS_BITS).dll instead of slept$(DETOURS_BITS).dll --------------------
|
||||
$(BIND)\sleepold.exe
|
||||
@echo.
|
||||
@echo -------- Removing dslept$(DETOURS_BITS).dll from sleepold.exe --------------------------
|
||||
$(BIND)\setdll.exe -r $(BIND)\sleepold.exe
|
||||
@echo.
|
||||
@echo -------- Should not load dslept$(DETOURS_BITS).dll or slept$(DETOURS_BITS).dll ------------------------
|
||||
$(BIND)\sleepold.exe
|
||||
@echo.
|
||||
@echo -------- Should load slept$(DETOURS_BITS).dll dynamically using withdll.exe ------------
|
||||
$(BIND)\withdll.exe -d:$(BIND)\slept$(DETOURS_BITS).dll $(BIND)\sleepold.exe
|
||||
@echo.
|
||||
@echo -------- Test completed. ------------------------------------------------
|
||||
|
||||
################################################################# End of File.
|
202
samples/slept/NORMAL_IA64.TXT
Normal file
202
samples/slept/NORMAL_IA64.TXT
Normal file
@ -0,0 +1,202 @@
|
||||
-------- Reseting test binaries to initial state. -----------------------
|
||||
..\..\bin.IA64\setdll.exe -r ..\..\bin.IA64\sleepold.exe
|
||||
Removing extra DLLs from binary files.
|
||||
..\..\bin.IA64\sleepold.exe:
|
||||
KERNEL32.dll -> KERNEL32.dll
|
||||
|
||||
-------- Should load detour self ----------------------------------------
|
||||
..\..\bin.IA64\sleepbed.exe
|
||||
sleepbed.exe: Starting.
|
||||
sleepbed.exe: ExeEntry=000000013F702DD0, DllEntry=0000000000000000
|
||||
SleepEx = 0000000077898980 [0000000077845300]
|
||||
0000000077898980: 08181d0a 80054002 04004240 0400c400
|
||||
0000000077898990: 11300142 00215002 80004200 00000020
|
||||
00000000778989A0: 13000000 01000000 00001000 80a50050
|
||||
|
||||
sleepbed.exe: Detoured SleepEx().
|
||||
sleepbed.exe: After detour.
|
||||
SleepEx = 0000000077898980 [0000000077845300]
|
||||
0000000077898980: 05000000 0100bfff ffff7f00 b879ffc8 [0000000037890330]
|
||||
0000000077898990: 11300142 00215002 80004200 00000020
|
||||
00000000778989A0: 13000000 01000000 00001000 80a50050
|
||||
|
||||
sleepbed.exe: Calling Sleep for 1 second.
|
||||
sleepbed.exe: Calling SleepEx for 1 second.
|
||||
sleepbed.exe: Calling Sleep again for 1 second.
|
||||
sleepbed.exe: Calling TimedSleepEx for 1 second.
|
||||
sleepbed.exe: Calling UntimedSleepEx for 1 second.
|
||||
sleepbed.exe: Done sleeping.
|
||||
|
||||
sleepbed.exe: Removed SleepEx() detour (0), slept 2000 ticks.
|
||||
sleepbed.exe: GetSleptTicks() = 2000
|
||||
|
||||
|
||||
-------- Should load slept64.dll statically -------------------------------
|
||||
..\..\bin.IA64\sleepnew.exe
|
||||
slept64.dll: Starting.
|
||||
slept64.dll: ExeEntry=000000013F18CA50, DllEntry=000006FAEE9F6D80
|
||||
SleepEx = 0000000077898980 [0000000077845300]
|
||||
0000000077898980: 08181d0a 80054002 04004240 0400c400
|
||||
0000000077898990: 11300142 00215002 80004200 00000020
|
||||
00000000778989A0: 13000000 01000000 00001000 80a50050
|
||||
|
||||
sleepnew.exe: Starting.
|
||||
SleepEx = 0000000077898980 [0000000077845300]
|
||||
0000000077898980: 05000000 0100bfff ffff7f00 b879ffc8 [0000000037890330]
|
||||
0000000077898990: 11300142 00215002 80004200 00000020
|
||||
00000000778989A0: 13000000 01000000 00001000 80a50050
|
||||
|
||||
sleepnew.exe: Calling Sleep for 1 second.
|
||||
sleepnew.exe: Calling SleepEx for 1 second.
|
||||
sleepnew.exe: Calling Sleep again for 1 second.
|
||||
sleepnew.exe: Calling TimedSleep for 1 second.
|
||||
sleepnew.exe: Calling UntimedSleep for 1 second.
|
||||
sleepnew.exe: Done sleeping.
|
||||
|
||||
sleepnew.exe: GetSleptTicks() = 2000
|
||||
|
||||
slept64.dll: Detoured SleepEx().
|
||||
slept64.dll: Removed SleepEx() detour (0), slept 2000 ticks.
|
||||
|
||||
-------- Should not load slept64.dll --------------------------------------
|
||||
..\..\bin.IA64\sleepold.exe
|
||||
sleepold.exe: Starting (at 000000013F80C288).
|
||||
SleepEx = 0000000077898980 [0000000077845300]
|
||||
0000000077898980: 08181d0a 80054002 04004240 0400c400
|
||||
0000000077898990: 11300142 00215002 80004200 00000020
|
||||
00000000778989A0: 13000000 01000000 00001000 80a50050
|
||||
|
||||
sleepold.exe: Calling Sleep for 1 second.
|
||||
sleepold.exe: Calling SleepEx for 1 second.
|
||||
sleepold.exe: Calling Sleep again for 1 second.
|
||||
sleepold.exe: Done sleeping.
|
||||
|
||||
|
||||
-------- Adding slept64.dll to sleepold.exe -------------------------------
|
||||
..\..\bin.IA64\setdll.exe -d:..\..\bin.IA64\slept64.dll ..\..\bin.IA64\sleepold.exe
|
||||
Adding c:\Code\Detours\bin.IA64\slept64.dll to binary files.
|
||||
..\..\bin.IA64\sleepold.exe:
|
||||
c:\Code\Detours\bin.IA64\slept64.dll
|
||||
KERNEL32.dll -> KERNEL32.dll
|
||||
|
||||
-------- Should load slept64.dll statically -------------------------------
|
||||
..\..\bin.IA64\sleepold.exe
|
||||
slept64.dll: Starting.
|
||||
slept64.dll: ExeEntry=000000013F4FCAB0, DllEntry=000006FAEE9F6D80
|
||||
SleepEx = 0000000077898980 [0000000077845300]
|
||||
0000000077898980: 08181d0a 80054002 04004240 0400c400
|
||||
0000000077898990: 11300142 00215002 80004200 00000020
|
||||
00000000778989A0: 13000000 01000000 00001000 80a50050
|
||||
|
||||
sleepold.exe: Starting (at 000000013F4FC288).
|
||||
SleepEx = 0000000077898980 [0000000077845300]
|
||||
0000000077898980: 05000000 0100bfff ffff7f00 b879ffc8 [0000000037890330]
|
||||
0000000077898990: 11300142 00215002 80004200 00000020
|
||||
00000000778989A0: 13000000 01000000 00001000 80a50050
|
||||
|
||||
sleepold.exe: Calling Sleep for 1 second.
|
||||
sleepold.exe: Calling SleepEx for 1 second.
|
||||
sleepold.exe: Calling Sleep again for 1 second.
|
||||
sleepold.exe: Done sleeping.
|
||||
|
||||
slept64.dll: Detoured SleepEx().
|
||||
slept64.dll: Removed SleepEx() detour (0), slept 1000 ticks.
|
||||
|
||||
-------- Replacing slept64.dll with dslept64.dll in sleepold.exe ------------
|
||||
..\..\bin.IA64\setdll.exe -r ..\..\bin.IA64\sleepold.exe
|
||||
Removing extra DLLs from binary files.
|
||||
..\..\bin.IA64\sleepold.exe:
|
||||
KERNEL32.dll -> KERNEL32.dll
|
||||
..\..\bin.IA64\setdll.exe -d:..\..\bin.IA64\dslept64.dll ..\..\bin.IA64\sleepold.exe
|
||||
Adding c:\Code\Detours\bin.IA64\dslept64.dll to binary files.
|
||||
..\..\bin.IA64\sleepold.exe:
|
||||
c:\Code\Detours\bin.IA64\dslept64.dll
|
||||
KERNEL32.dll -> KERNEL32.dll
|
||||
|
||||
-------- Should load dslept64.dll instead of slept64.dll --------------------
|
||||
..\..\bin.IA64\sleepold.exe
|
||||
dslept64.dll: Starting.
|
||||
SleepEx = 0000000077898980 [0000000077845300]
|
||||
0000000077898980: 08181d0a 80054002 04004240 0400c400
|
||||
0000000077898990: 11300142 00215002 80004200 00000020
|
||||
00000000778989A0: 13000000 01000000 00001000 80a50050
|
||||
|
||||
EntryPoint = 000000013F12D580 [000000013F16CAB0]
|
||||
000000013F12D580: 01080d06 80050002 00620040 04080084
|
||||
000000013F12D590: 13000000 01000000 00001000 90eb0050
|
||||
000000013F12D5A0: 13080044 00210000 00001000 c0fcff58
|
||||
EntryPoint after attach = 000000013F12D580 [000000013F16CAB0]
|
||||
000000013F12D580: 05000000 0100bfff ffff7f00 b82dffc8 [00000000FF120330]
|
||||
000000013F12D590: 13000000 01000000 00001000 90eb0050
|
||||
000000013F12D5A0: 13080044 00210000 00001000 c0fcff58
|
||||
EntryPoint trampoline = 00000000FF120300 [00000000FF1203B0]
|
||||
00000000FF120300: 05000000 01003f01 00000020 00f00267
|
||||
00000000FF120310: 01080d06 80050002 00620040 04080084
|
||||
00000000FF120320: 05000000 01004000 00000000 78d200c0 [000000013F12D590]
|
||||
dslept64.dll: Detoured EntryPoint().
|
||||
dslept64.dll: Detoured SleepEx().
|
||||
SleepEx = 0000000077898980 [0000000077845300]
|
||||
0000000077898980: 05000000 0100bfff ffff7f00 b879ffc8 [0000000037890330]
|
||||
0000000077898990: 11300142 00215002 80004200 00000020
|
||||
00000000778989A0: 13000000 01000000 00001000 80a50050
|
||||
|
||||
dslept64.dll: Calling EntryPoint
|
||||
sleepold.exe: Starting (at 000000013F16C288).
|
||||
SleepEx = 0000000077898980 [0000000077845300]
|
||||
0000000077898980: 05000000 0100bfff ffff7f00 b879ffc8 [0000000037890330]
|
||||
0000000077898990: 11300142 00215002 80004200 00000020
|
||||
00000000778989A0: 13000000 01000000 00001000 80a50050
|
||||
|
||||
sleepold.exe: Calling Sleep for 1 second.
|
||||
sleepold.exe: Calling SleepEx for 1 second.
|
||||
sleepold.exe: Calling Sleep again for 1 second.
|
||||
sleepold.exe: Done sleeping.
|
||||
|
||||
dslept64.dll: Removed Sleep() detours (0), slept 1000 ticks.
|
||||
|
||||
-------- Removing dslept64.dll from sleepold.exe --------------------------
|
||||
..\..\bin.IA64\setdll.exe -r ..\..\bin.IA64\sleepold.exe
|
||||
Removing extra DLLs from binary files.
|
||||
..\..\bin.IA64\sleepold.exe:
|
||||
KERNEL32.dll -> KERNEL32.dll
|
||||
|
||||
-------- Should not load dslept64.dll or slept64.dll ------------------------
|
||||
..\..\bin.IA64\sleepold.exe
|
||||
sleepold.exe: Starting (at 000000013FCEC288).
|
||||
SleepEx = 0000000077898980 [0000000077845300]
|
||||
0000000077898980: 08181d0a 80054002 04004240 0400c400
|
||||
0000000077898990: 11300142 00215002 80004200 00000020
|
||||
00000000778989A0: 13000000 01000000 00001000 80a50050
|
||||
|
||||
sleepold.exe: Calling Sleep for 1 second.
|
||||
sleepold.exe: Calling SleepEx for 1 second.
|
||||
sleepold.exe: Calling Sleep again for 1 second.
|
||||
sleepold.exe: Done sleeping.
|
||||
|
||||
|
||||
-------- Should load slept64.dll dynamically using withdll.exe ------------
|
||||
..\..\bin.IA64\withdll.exe -d:..\..\bin.IA64\slept64.dll ..\..\bin.IA64\sleepold.exe
|
||||
withdll.exe: Starting: `..\..\bin.IA64\sleepold.exe'
|
||||
withdll.exe: with `c:\Code\Detours\bin.IA64\slept64.dll'
|
||||
slept64.dll: Starting.
|
||||
slept64.dll: ExeEntry=000000013FBFCAB0, DllEntry=000006FAEE9F6D80
|
||||
SleepEx = 0000000077898980 [0000000077845300]
|
||||
0000000077898980: 08181d0a 80054002 04004240 0400c400
|
||||
0000000077898990: 11300142 00215002 80004200 00000020
|
||||
00000000778989A0: 13000000 01000000 00001000 80a50050
|
||||
|
||||
sleepold.exe: Starting (at 000000013FBFC288).
|
||||
SleepEx = 0000000077898980 [0000000077845300]
|
||||
0000000077898980: 05000000 0100bfff ffff7f00 b879ffc8 [0000000037890330]
|
||||
0000000077898990: 11300142 00215002 80004200 00000020
|
||||
00000000778989A0: 13000000 01000000 00001000 80a50050
|
||||
|
||||
sleepold.exe: Calling Sleep for 1 second.
|
||||
sleepold.exe: Calling SleepEx for 1 second.
|
||||
sleepold.exe: Calling Sleep again for 1 second.
|
||||
sleepold.exe: Done sleeping.
|
||||
|
||||
slept64.dll: Detoured SleepEx().
|
||||
slept64.dll: Removed SleepEx() detour (0), slept 1030 ticks.
|
||||
|
||||
-------- Test completed. ------------------------------------------------
|
202
samples/slept/NORMAL_X64.TXT
Normal file
202
samples/slept/NORMAL_X64.TXT
Normal file
@ -0,0 +1,202 @@
|
||||
-------- Reseting test binaries to initial state. -----------------------
|
||||
..\..\bin.X64\setdll.exe -r ..\..\bin.X64\sleepold.exe
|
||||
Removing extra DLLs from binary files.
|
||||
..\..\bin.X64\sleepold.exe:
|
||||
KERNEL32.dll -> KERNEL32.dll
|
||||
|
||||
-------- Should load detour self ----------------------------------------
|
||||
..\..\bin.X64\sleepbed.exe
|
||||
sleepbed.exe: Starting.
|
||||
sleepbed.exe: ExeEntry=000000013FE863E0, DllEntry=000000013FE9E610
|
||||
SleepEx = 000007FEFD541150 [0000000076912B60]
|
||||
000007FEFD541150: 4c8bdc
|
||||
000007FEFD541153: 49895b08
|
||||
000007FEFD541157: 89542410
|
||||
|
||||
sleepbed.exe: Detoured SleepEx().
|
||||
sleepbed.exe: After detour.
|
||||
SleepEx = 000007FEFD541150 [0000000076912B60]
|
||||
000007FEFD541150: e923f0ff bf [000007FEBD540178]
|
||||
000007FEFD541155: cc [FFFFFFFFFFFFFFFF]
|
||||
000007FEFD541156: cc [FFFFFFFFFFFFFFFF]
|
||||
|
||||
sleepbed.exe: Calling Sleep for 1 second.
|
||||
sleepbed.exe: Calling SleepEx for 1 second.
|
||||
sleepbed.exe: Calling Sleep again for 1 second.
|
||||
sleepbed.exe: Calling TimedSleepEx for 1 second.
|
||||
sleepbed.exe: Calling UntimedSleepEx for 1 second.
|
||||
sleepbed.exe: Done sleeping.
|
||||
|
||||
sleepbed.exe: Removed SleepEx() detour (0), slept 4056 ticks.
|
||||
sleepbed.exe: GetSleptTicks() = 4056
|
||||
|
||||
|
||||
-------- Should load slept64.dll statically -------------------------------
|
||||
..\..\bin.X64\sleepnew.exe
|
||||
slept64.dll: Starting.
|
||||
slept64.dll: ExeEntry=000000013F56484C, DllEntry=000007FEF2E78B74
|
||||
SleepEx = 000007FEFD541150 [0000000076912B60]
|
||||
000007FEFD541150: 4c8bdc
|
||||
000007FEFD541153: 49895b08
|
||||
000007FEFD541157: 89542410
|
||||
|
||||
sleepnew.exe: Starting.
|
||||
SleepEx = 000007FEFD541150 [0000000076912B60]
|
||||
000007FEFD541150: e923f0ff bf [000007FEBD540178]
|
||||
000007FEFD541155: cc [FFFFFFFFFFFFFFFF]
|
||||
000007FEFD541156: cc [FFFFFFFFFFFFFFFF]
|
||||
|
||||
sleepnew.exe: Calling Sleep for 1 second.
|
||||
sleepnew.exe: Calling SleepEx for 1 second.
|
||||
sleepnew.exe: Calling Sleep again for 1 second.
|
||||
sleepnew.exe: Calling TimedSleep for 1 second.
|
||||
sleepnew.exe: Calling UntimedSleep for 1 second.
|
||||
sleepnew.exe: Done sleeping.
|
||||
|
||||
sleepnew.exe: GetSleptTicks() = 4056
|
||||
|
||||
slept64.dll: Detoured SleepEx().
|
||||
slept64.dll: Removed SleepEx() detour (0), slept 4056 ticks.
|
||||
|
||||
-------- Should not load slept64.dll --------------------------------------
|
||||
..\..\bin.X64\sleepold.exe
|
||||
sleepold.exe: Starting (at 000000013FEF1350).
|
||||
SleepEx = 000007FEFD541150 [0000000076912B60]
|
||||
000007FEFD541150: 4c8bdc
|
||||
000007FEFD541153: 49895b08
|
||||
000007FEFD541157: 89542410
|
||||
|
||||
sleepold.exe: Calling Sleep for 1 second.
|
||||
sleepold.exe: Calling SleepEx for 1 second.
|
||||
sleepold.exe: Calling Sleep again for 1 second.
|
||||
sleepold.exe: Done sleeping.
|
||||
|
||||
|
||||
-------- Adding slept64.dll to sleepold.exe -------------------------------
|
||||
..\..\bin.X64\setdll.exe -d:..\..\bin.X64\slept64.dll ..\..\bin.X64\sleepold.exe
|
||||
Adding c:\Code\detours\bin.X64\slept64.dll to binary files.
|
||||
..\..\bin.X64\sleepold.exe:
|
||||
c:\Code\detours\bin.X64\slept64.dll
|
||||
KERNEL32.dll -> KERNEL32.dll
|
||||
|
||||
-------- Should load slept64.dll statically -------------------------------
|
||||
..\..\bin.X64\sleepold.exe
|
||||
slept64.dll: Starting.
|
||||
slept64.dll: ExeEntry=000000013F554ADC, DllEntry=000007FEF2E78B74
|
||||
SleepEx = 000007FEFD541150 [0000000076912B60]
|
||||
000007FEFD541150: 4c8bdc
|
||||
000007FEFD541153: 49895b08
|
||||
000007FEFD541157: 89542410
|
||||
|
||||
sleepold.exe: Starting (at 000000013F551350).
|
||||
SleepEx = 000007FEFD541150 [0000000076912B60]
|
||||
000007FEFD541150: e923f0ff bf [000007FEBD540178]
|
||||
000007FEFD541155: cc [FFFFFFFFFFFFFFFF]
|
||||
000007FEFD541156: cc [FFFFFFFFFFFFFFFF]
|
||||
|
||||
sleepold.exe: Calling Sleep for 1 second.
|
||||
sleepold.exe: Calling SleepEx for 1 second.
|
||||
sleepold.exe: Calling Sleep again for 1 second.
|
||||
sleepold.exe: Done sleeping.
|
||||
|
||||
slept64.dll: Detoured SleepEx().
|
||||
slept64.dll: Removed SleepEx() detour (0), slept 3042 ticks.
|
||||
|
||||
-------- Replacing slept64.dll with dslept64.dll in sleepold.exe ------------
|
||||
..\..\bin.X64\setdll.exe -r ..\..\bin.X64\sleepold.exe
|
||||
Removing extra DLLs from binary files.
|
||||
..\..\bin.X64\sleepold.exe:
|
||||
KERNEL32.dll -> KERNEL32.dll
|
||||
..\..\bin.X64\setdll.exe -d:..\..\bin.X64\dslept64.dll ..\..\bin.X64\sleepold.exe
|
||||
Adding c:\Code\detours\bin.X64\dslept64.dll to binary files.
|
||||
..\..\bin.X64\sleepold.exe:
|
||||
c:\Code\detours\bin.X64\dslept64.dll
|
||||
KERNEL32.dll -> KERNEL32.dll
|
||||
|
||||
-------- Should load dslept64.dll instead of slept64.dll --------------------
|
||||
..\..\bin.X64\sleepold.exe
|
||||
dslept64.dll: Starting.
|
||||
SleepEx = 000007FEFD541150 [0000000076912B60]
|
||||
000007FEFD541150: 4c8bdc
|
||||
000007FEFD541153: 49895b08
|
||||
000007FEFD541157: 89542410
|
||||
|
||||
EntryPoint = 000000013FB24ADC
|
||||
000000013FB24ADC: 4883ec28
|
||||
000000013FB24AE0: e8875f00 00 [000000013FB2AA6C]
|
||||
000000013FB24AE5: 4883c428
|
||||
EntryPoint after attach = 000000013FB24ADC
|
||||
000000013FB24ADC: e997b6ff bf [00000000FFB20178]
|
||||
000000013FB24AE1: cc [FFFFFFFFFFFFFFFF]
|
||||
000000013FB24AE2: cc [FFFFFFFFFFFFFFFF]
|
||||
EntryPoint trampoline = 00000000FFB20120
|
||||
00000000FFB20120: 4883ec28
|
||||
00000000FFB20124: e843a900 40 [000000013FB2AA6C]
|
||||
00000000FFB20129: ff253900 0000
|
||||
dslept64.dll: Detoured EntryPoint().
|
||||
dslept64.dll: Detoured SleepEx().
|
||||
SleepEx = 000007FEFD541150 [0000000076912B60]
|
||||
000007FEFD541150: e923f0ff bf [000007FEBD540178]
|
||||
000007FEFD541155: cc [FFFFFFFFFFFFFFFF]
|
||||
000007FEFD541156: cc [FFFFFFFFFFFFFFFF]
|
||||
|
||||
dslept64.dll: Calling EntryPoint
|
||||
sleepold.exe: Starting (at 000000013FB21350).
|
||||
SleepEx = 000007FEFD541150 [0000000076912B60]
|
||||
000007FEFD541150: e923f0ff bf [000007FEBD540178]
|
||||
000007FEFD541155: cc [FFFFFFFFFFFFFFFF]
|
||||
000007FEFD541156: cc [FFFFFFFFFFFFFFFF]
|
||||
|
||||
sleepold.exe: Calling Sleep for 1 second.
|
||||
sleepold.exe: Calling SleepEx for 1 second.
|
||||
sleepold.exe: Calling Sleep again for 1 second.
|
||||
sleepold.exe: Done sleeping.
|
||||
|
||||
dslept64.dll: Removed Sleep() detours (0), slept 3042 ticks.
|
||||
|
||||
-------- Removing dslept64.dll from sleepold.exe --------------------------
|
||||
..\..\bin.X64\setdll.exe -r ..\..\bin.X64\sleepold.exe
|
||||
Removing extra DLLs from binary files.
|
||||
..\..\bin.X64\sleepold.exe:
|
||||
KERNEL32.dll -> KERNEL32.dll
|
||||
|
||||
-------- Should not load dslept64.dll or slept64.dll ------------------------
|
||||
..\..\bin.X64\sleepold.exe
|
||||
sleepold.exe: Starting (at 000000013F551350).
|
||||
SleepEx = 000007FEFD541150 [0000000076912B60]
|
||||
000007FEFD541150: 4c8bdc
|
||||
000007FEFD541153: 49895b08
|
||||
000007FEFD541157: 89542410
|
||||
|
||||
sleepold.exe: Calling Sleep for 1 second.
|
||||
sleepold.exe: Calling SleepEx for 1 second.
|
||||
sleepold.exe: Calling Sleep again for 1 second.
|
||||
sleepold.exe: Done sleeping.
|
||||
|
||||
|
||||
-------- Should load slept64.dll dynamically using withdll.exe ------------
|
||||
..\..\bin.X64\withdll.exe -d:..\..\bin.X64\slept64.dll ..\..\bin.X64\sleepold.exe
|
||||
withdll.exe: Starting: `..\..\bin.X64\sleepold.exe'
|
||||
withdll.exe: with `c:\Code\detours\bin.X64\slept64.dll'
|
||||
slept64.dll: Starting.
|
||||
slept64.dll: ExeEntry=000000013FE84ADC, DllEntry=000007FEF3108B74
|
||||
SleepEx = 000007FEFD541150 [0000000076912B60]
|
||||
000007FEFD541150: 4c8bdc
|
||||
000007FEFD541153: 49895b08
|
||||
000007FEFD541157: 89542410
|
||||
|
||||
sleepold.exe: Starting (at 000000013FE81350).
|
||||
SleepEx = 000007FEFD541150 [0000000076912B60]
|
||||
000007FEFD541150: e923f0ff bf [000007FEBD540178]
|
||||
000007FEFD541155: cc [FFFFFFFFFFFFFFFF]
|
||||
000007FEFD541156: cc [FFFFFFFFFFFFFFFF]
|
||||
|
||||
sleepold.exe: Calling Sleep for 1 second.
|
||||
sleepold.exe: Calling SleepEx for 1 second.
|
||||
sleepold.exe: Calling Sleep again for 1 second.
|
||||
sleepold.exe: Done sleeping.
|
||||
|
||||
slept64.dll: Detoured SleepEx().
|
||||
slept64.dll: Removed SleepEx() detour (0), slept 3042 ticks.
|
||||
|
||||
-------- Test completed. ------------------------------------------------
|
202
samples/slept/NORMAL_X86.TXT
Normal file
202
samples/slept/NORMAL_X86.TXT
Normal file
@ -0,0 +1,202 @@
|
||||
-------- Reseting test binaries to initial state. -----------------------
|
||||
..\..\bin.X86\setdll.exe -r ..\..\bin.X86\sleepold.exe
|
||||
Removing extra DLLs from binary files.
|
||||
..\..\bin.X86\sleepold.exe:
|
||||
KERNEL32.dll -> KERNEL32.dll
|
||||
|
||||
-------- Should load detour self ----------------------------------------
|
||||
..\..\bin.X86\sleepbed.exe
|
||||
sleepbed.exe: Starting.
|
||||
sleepbed.exe: ExeEntry=00B1572E, DllEntry=00000000
|
||||
SleepEx = 74F51215
|
||||
74F51215: 8bff
|
||||
74F51217: 55
|
||||
74F51218: 8bec
|
||||
|
||||
sleepbed.exe: Detoured SleepEx().
|
||||
sleepbed.exe: After detour.
|
||||
SleepEx = 74F51215
|
||||
74F51215: e95600bc 8b [00B11270]
|
||||
74F5121A: 5d
|
||||
74F5121B: ebed [74F5120A]
|
||||
|
||||
sleepbed.exe: Calling Sleep for 1 second.
|
||||
sleepbed.exe: Calling SleepEx for 1 second.
|
||||
sleepbed.exe: Calling Sleep again for 1 second.
|
||||
sleepbed.exe: Calling TimedSleepEx for 1 second.
|
||||
sleepbed.exe: Calling UntimedSleepEx for 1 second.
|
||||
sleepbed.exe: Done sleeping.
|
||||
|
||||
sleepbed.exe: Removed SleepEx() detour (0), slept 2028 ticks.
|
||||
sleepbed.exe: GetSleptTicks() = 2028
|
||||
|
||||
|
||||
-------- Should load slept32.dll statically -------------------------------
|
||||
..\..\bin.X86\sleepnew.exe
|
||||
slept32.dll: Starting.
|
||||
slept32.dll: ExeEntry=012D3B1A, DllEntry=7248702E
|
||||
SleepEx = 74F51215
|
||||
74F51215: 8bff
|
||||
74F51217: 55
|
||||
74F51218: 8bec
|
||||
|
||||
sleepnew.exe: Starting.
|
||||
SleepEx = 74F51215
|
||||
74F51215: e9560053 fd [72481270]
|
||||
74F5121A: 5d
|
||||
74F5121B: ebed [74F5120A]
|
||||
|
||||
sleepnew.exe: Calling Sleep for 1 second.
|
||||
sleepnew.exe: Calling SleepEx for 1 second.
|
||||
sleepnew.exe: Calling Sleep again for 1 second.
|
||||
sleepnew.exe: Calling TimedSleep for 1 second.
|
||||
sleepnew.exe: Calling UntimedSleep for 1 second.
|
||||
sleepnew.exe: Done sleeping.
|
||||
|
||||
sleepnew.exe: GetSleptTicks() = 2028
|
||||
|
||||
slept32.dll: Detoured SleepEx().
|
||||
slept32.dll: Removed SleepEx() detour (0), slept 2028 ticks.
|
||||
|
||||
-------- Should not load slept32.dll --------------------------------------
|
||||
..\..\bin.X86\sleepold.exe
|
||||
sleepold.exe: Starting (at 00971260).
|
||||
SleepEx = 74F51215
|
||||
74F51215: 8bff
|
||||
74F51217: 55
|
||||
74F51218: 8bec
|
||||
|
||||
sleepold.exe: Calling Sleep for 1 second.
|
||||
sleepold.exe: Calling SleepEx for 1 second.
|
||||
sleepold.exe: Calling Sleep again for 1 second.
|
||||
sleepold.exe: Done sleeping.
|
||||
|
||||
|
||||
-------- Adding slept32.dll to sleepold.exe -------------------------------
|
||||
..\..\bin.X86\setdll.exe -d:..\..\bin.X86\slept32.dll ..\..\bin.X86\sleepold.exe
|
||||
Adding c:\Code\detours\bin.X86\slept32.dll to binary files.
|
||||
..\..\bin.X86\sleepold.exe:
|
||||
c:\Code\detours\bin.X86\slept32.dll
|
||||
KERNEL32.dll -> KERNEL32.dll
|
||||
|
||||
-------- Should load slept32.dll statically -------------------------------
|
||||
..\..\bin.X86\sleepold.exe
|
||||
slept32.dll: Starting.
|
||||
slept32.dll: ExeEntry=00AF3D4C, DllEntry=7248702E
|
||||
SleepEx = 74F51215
|
||||
74F51215: 8bff
|
||||
74F51217: 55
|
||||
74F51218: 8bec
|
||||
|
||||
sleepold.exe: Starting (at 00AF1260).
|
||||
SleepEx = 74F51215
|
||||
74F51215: e9560053 fd [72481270]
|
||||
74F5121A: 5d
|
||||
74F5121B: ebed [74F5120A]
|
||||
|
||||
sleepold.exe: Calling Sleep for 1 second.
|
||||
sleepold.exe: Calling SleepEx for 1 second.
|
||||
sleepold.exe: Calling Sleep again for 1 second.
|
||||
sleepold.exe: Done sleeping.
|
||||
|
||||
slept32.dll: Detoured SleepEx().
|
||||
slept32.dll: Removed SleepEx() detour (0), slept 1014 ticks.
|
||||
|
||||
-------- Replacing slept32.dll with dslept32.dll in sleepold.exe ------------
|
||||
..\..\bin.X86\setdll.exe -r ..\..\bin.X86\sleepold.exe
|
||||
Removing extra DLLs from binary files.
|
||||
..\..\bin.X86\sleepold.exe:
|
||||
KERNEL32.dll -> KERNEL32.dll
|
||||
..\..\bin.X86\setdll.exe -d:..\..\bin.X86\dslept32.dll ..\..\bin.X86\sleepold.exe
|
||||
Adding c:\Code\detours\bin.X86\dslept32.dll to binary files.
|
||||
..\..\bin.X86\sleepold.exe:
|
||||
c:\Code\detours\bin.X86\dslept32.dll
|
||||
KERNEL32.dll -> KERNEL32.dll
|
||||
|
||||
-------- Should load dslept32.dll instead of slept32.dll --------------------
|
||||
..\..\bin.X86\sleepold.exe
|
||||
dslept32.dll: Starting.
|
||||
SleepEx = 74F51215
|
||||
74F51215: 8bff
|
||||
74F51217: 55
|
||||
74F51218: 8bec
|
||||
|
||||
EntryPoint = 00263D4C
|
||||
00263D4C: e8d75400 00 [00269228]
|
||||
00263D51: e995feff ff [00263BEB]
|
||||
00263D56: 3b0d8412 2800
|
||||
EntryPoint after attach = 00263D4C
|
||||
00263D4C: e96fd502 72 [722912C0]
|
||||
00263D51: e995feff ff [00263BEB]
|
||||
00263D56: 3b0d8412 2800
|
||||
EntryPoint trampoline = 402500D8
|
||||
402500D8: e84b9101 c0 [00269228]
|
||||
402500DD: e96f3c01 c0 [00263D51]
|
||||
402500E2: cc [FFFFFFFF]
|
||||
dslept32.dll: Detoured EntryPoint().
|
||||
dslept32.dll: Detoured SleepEx().
|
||||
SleepEx = 74F51215
|
||||
74F51215: e9560034 fd [72291270]
|
||||
74F5121A: 5d
|
||||
74F5121B: ebed [74F5120A]
|
||||
|
||||
dslept32.dll: Calling EntryPoint
|
||||
sleepold.exe: Starting (at 00261260).
|
||||
SleepEx = 74F51215
|
||||
74F51215: e9560034 fd [72291270]
|
||||
74F5121A: 5d
|
||||
74F5121B: ebed [74F5120A]
|
||||
|
||||
sleepold.exe: Calling Sleep for 1 second.
|
||||
sleepold.exe: Calling SleepEx for 1 second.
|
||||
sleepold.exe: Calling Sleep again for 1 second.
|
||||
sleepold.exe: Done sleeping.
|
||||
|
||||
dslept32.dll: Removed Sleep() detours (0), slept 1014 ticks.
|
||||
|
||||
-------- Removing dslept32.dll from sleepold.exe --------------------------
|
||||
..\..\bin.X86\setdll.exe -r ..\..\bin.X86\sleepold.exe
|
||||
Removing extra DLLs from binary files.
|
||||
..\..\bin.X86\sleepold.exe:
|
||||
KERNEL32.dll -> KERNEL32.dll
|
||||
|
||||
-------- Should not load dslept32.dll or slept32.dll ------------------------
|
||||
..\..\bin.X86\sleepold.exe
|
||||
sleepold.exe: Starting (at 00E01260).
|
||||
SleepEx = 74F51215
|
||||
74F51215: 8bff
|
||||
74F51217: 55
|
||||
74F51218: 8bec
|
||||
|
||||
sleepold.exe: Calling Sleep for 1 second.
|
||||
sleepold.exe: Calling SleepEx for 1 second.
|
||||
sleepold.exe: Calling Sleep again for 1 second.
|
||||
sleepold.exe: Done sleeping.
|
||||
|
||||
|
||||
-------- Should load slept32.dll dynamically using withdll.exe ------------
|
||||
..\..\bin.X86\withdll.exe -d:..\..\bin.X86\slept32.dll ..\..\bin.X86\sleepold.exe
|
||||
withdll.exe: Starting: `..\..\bin.X86\sleepold.exe'
|
||||
withdll.exe: with `c:\Code\detours\bin.X86\slept32.dll'
|
||||
slept32.dll: Starting.
|
||||
slept32.dll: ExeEntry=011A3D4C, DllEntry=7248702E
|
||||
SleepEx = 74F51215
|
||||
74F51215: 8bff
|
||||
74F51217: 55
|
||||
74F51218: 8bec
|
||||
|
||||
sleepold.exe: Starting (at 011A1260).
|
||||
SleepEx = 74F51215
|
||||
74F51215: e9560053 fd [72481270]
|
||||
74F5121A: 5d
|
||||
74F5121B: ebed [74F5120A]
|
||||
|
||||
sleepold.exe: Calling Sleep for 1 second.
|
||||
sleepold.exe: Calling SleepEx for 1 second.
|
||||
sleepold.exe: Calling Sleep again for 1 second.
|
||||
sleepold.exe: Done sleeping.
|
||||
|
||||
slept32.dll: Detoured SleepEx().
|
||||
slept32.dll: Removed SleepEx() detour (0), slept 1014 ticks.
|
||||
|
||||
-------- Test completed. ------------------------------------------------
|
141
samples/slept/dslept.cpp
Normal file
141
samples/slept/dslept.cpp
Normal file
@ -0,0 +1,141 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detour Test Program (dslept.cpp of dslept.dll)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// An example dynamically detouring a function.
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include "detours.h"
|
||||
#include "slept.h"
|
||||
|
||||
#include "verify.cpp"
|
||||
|
||||
LONG dwSlept = 0;
|
||||
|
||||
static DWORD (WINAPI * TrueSleepEx)(DWORD dwMilliseconds, BOOL bAlertable) = NULL;
|
||||
static int (WINAPI * TrueEntryPoint)(VOID) = NULL;
|
||||
static int (WINAPI * RawEntryPoint)(VOID) = NULL;
|
||||
|
||||
DWORD WINAPI UntimedSleepEx(DWORD dwMilliseconds, BOOL bAlertable)
|
||||
{
|
||||
if (TrueSleepEx != NULL) {
|
||||
return TrueSleepEx(dwMilliseconds, bAlertable);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD WINAPI TimedSleepEx(DWORD dwMilliseconds, BOOL bAlertable)
|
||||
{
|
||||
DWORD dwBeg = GetTickCount();
|
||||
DWORD ret = TrueSleepEx(dwMilliseconds, bAlertable);
|
||||
DWORD dwEnd = GetTickCount();
|
||||
|
||||
InterlockedExchangeAdd(&dwSlept, dwEnd - dwBeg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
DWORD WINAPI GetSleptTicks(VOID)
|
||||
{
|
||||
return dwSlept;
|
||||
}
|
||||
|
||||
int WINAPI TimedEntryPoint(VOID)
|
||||
{
|
||||
// We couldn't call LoadLibrary in DllMain,
|
||||
// so we detour SleepEx here...
|
||||
LONG error;
|
||||
|
||||
TrueSleepEx = (DWORD (WINAPI *)(DWORD, BOOL))
|
||||
DetourFindFunction("kernel32.dll", "SleepEx");
|
||||
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
DetourAttach(&(PVOID&)TrueSleepEx, TimedSleepEx);
|
||||
error = DetourTransactionCommit();
|
||||
|
||||
if (error == NO_ERROR) {
|
||||
printf("dslept" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: "
|
||||
" Detoured SleepEx().\n");
|
||||
|
||||
}
|
||||
else {
|
||||
printf("dslept" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: "
|
||||
" Error detouring SleepEx(): %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
17
samples/slept/dslept.rc
Normal file
@ -0,0 +1,17 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version information for dslept.rc.
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
|
||||
#include "detver.h"
|
||||
|
||||
#define VER_INTERNALNAME_STR "dslept" DETOURS_STRINGIFY(DETOURS_BITS)
|
||||
#define VER_ORIGINALFILENAME_STR "dslept" DETOURS_STRINGIFY(DETOURS_BITS) ".dll"
|
||||
#define VER_FILEDESCRIPTION_STR "Detours Sleep Interception Module"
|
||||
#define VER_COMPANYNAME_STR "Microsoft Corporation"
|
||||
|
||||
#include "common.ver"
|
103
samples/slept/sleepbed.cpp
Normal file
103
samples/slept/sleepbed.cpp
Normal file
@ -0,0 +1,103 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detour Test Program (sleepbed.cpp of sleepbed.exe)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "verify.cpp"
|
||||
|
||||
static BOOL fBroke = FALSE;
|
||||
static LONG dwSlept = 0;
|
||||
static DWORD (WINAPI * TrueSleepEx)(DWORD dwMilliseconds, BOOL bAlertable)
|
||||
= SleepEx;
|
||||
|
||||
DWORD WINAPI UntimedSleepEx(DWORD dwMilliseconds, BOOL bAlertable)
|
||||
{
|
||||
return TrueSleepEx(dwMilliseconds, bAlertable);
|
||||
}
|
||||
|
||||
DWORD WINAPI TimedSleepEx(DWORD dwMilliseconds, BOOL bAlertable)
|
||||
{
|
||||
DWORD dwBeg = GetTickCount();
|
||||
DWORD ret = TrueSleepEx(dwMilliseconds, bAlertable);
|
||||
DWORD dwEnd = GetTickCount();
|
||||
|
||||
if (!fBroke) {
|
||||
fBroke = TRUE;
|
||||
// DebugBreak();
|
||||
}
|
||||
|
||||
InterlockedExchangeAdd(&dwSlept, dwEnd - dwBeg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
DWORD WINAPI GetSleptTicks(VOID)
|
||||
{
|
||||
return dwSlept;
|
||||
}
|
||||
|
||||
//
|
||||
///////////////////////////////////////////////////////////////// End of File.
|
||||
|
||||
int __cdecl main(void)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
printf("sleepbed.exe: Starting.\n");
|
||||
PVOID pbExeEntry = DetourGetEntryPoint(NULL);
|
||||
printf("sleepbed.exe: ExeEntry=%p\n", pbExeEntry);
|
||||
|
||||
Verify("SleepEx", (PVOID)SleepEx);
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
DetourAttach(&(PVOID&)TrueSleepEx, TimedSleepEx);
|
||||
error = DetourTransactionCommit();
|
||||
|
||||
if (error == NO_ERROR) {
|
||||
printf("sleepbed.exe: Detoured SleepEx().\n");
|
||||
}
|
||||
else {
|
||||
printf("sleepbed.exe: Error detouring SleepEx(): %d\n", error);
|
||||
return error;
|
||||
}
|
||||
fflush(stdout);
|
||||
|
||||
printf("sleepbed.exe: After detour.\n");
|
||||
Verify("SleepEx", (PBYTE)SleepEx);
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
|
||||
printf("sleepbed.exe: Calling Sleep for 1 second.\n");
|
||||
Sleep(1000);
|
||||
printf("sleepbed.exe: Calling SleepEx for 1 second.\n");
|
||||
SleepEx(1000, true);
|
||||
printf("sleepbed.exe: Calling Sleep again for 1 second.\n");
|
||||
Sleep(1000);
|
||||
printf("sleepbed.exe: Calling TimedSleepEx for 1 second.\n");
|
||||
TimedSleepEx(1000, false);
|
||||
printf("sleepbed.exe: Calling UntimedSleepEx for 1 second.\n");
|
||||
UntimedSleepEx(1000, false);
|
||||
printf("sleepbed.exe: Done sleeping.\n\n");
|
||||
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
DetourDetach(&(PVOID&)TrueSleepEx, TimedSleepEx);
|
||||
error = DetourTransactionCommit();
|
||||
printf("sleepbed.exe: Removed SleepEx() detour (%d), slept %ld ticks.\n",
|
||||
error, dwSlept);
|
||||
fflush(stdout);
|
||||
|
||||
printf("sleepbed.exe: GetSleptTicks() = %ld\n\n", GetSleptTicks());
|
||||
return error;
|
||||
}
|
||||
//
|
||||
///////////////////////////////////////////////////////////////// End of File.
|
76
samples/slept/sleepnew.cpp
Normal file
76
samples/slept/sleepnew.cpp
Normal file
@ -0,0 +1,76 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detour Test Program (sleepnew.cpp of sleepnew.exe)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include "slept.h"
|
||||
|
||||
#include "verify.cpp"
|
||||
|
||||
int __cdecl main(void)
|
||||
{
|
||||
printf("sleepnew.exe: Starting.\n");
|
||||
Verify("SleepEx", (PBYTE)SleepEx);
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
|
||||
printf("sleepnew.exe: Calling Sleep for 1 second.\n");
|
||||
Sleep(1000);
|
||||
printf("sleepnew.exe: Calling SleepEx for 1 second.\n");
|
||||
SleepEx(1000, true);
|
||||
printf("sleepnew.exe: Calling Sleep again for 1 second.\n");
|
||||
Sleep(1000);
|
||||
printf("sleepnew.exe: Calling TimedSleep for 1 second.\n");
|
||||
TimedSleepEx(1000, FALSE);
|
||||
printf("sleepnew.exe: Calling UntimedSleep for 1 second.\n");
|
||||
UntimedSleepEx(1000, FALSE);
|
||||
printf("sleepnew.exe: Done sleeping.\n\n");
|
||||
|
||||
#if 0
|
||||
// This code enumerates the virtual address space and attempts to reserve
|
||||
// all unused space below 8GB.
|
||||
//
|
||||
for (PBYTE pbTry = (PBYTE)0x10000; pbTry < (PBYTE)0x200000000;) {
|
||||
MEMORY_BASIC_INFORMATION mbi;
|
||||
|
||||
if (!VirtualQuery(pbTry, &mbi, sizeof(mbi))) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (mbi.State == MEM_FREE && mbi.RegionSize > 0x10000) {
|
||||
PBYTE pbBase = (PBYTE)((((ULONG_PTR)pbTry) + 0xffff) & 0xffffffffffff0000);
|
||||
SIZE_T cbTry = mbi.RegionSize & 0xffffffffffff0000;
|
||||
if (cbTry > 0x40000000) {
|
||||
cbTry = 0x40000000;
|
||||
}
|
||||
PVOID pvRegion = VirtualAlloc(pbBase, cbTry,
|
||||
MEM_RESERVE,
|
||||
PAGE_NOACCESS);
|
||||
if (pvRegion == NULL) {
|
||||
printf("---%p..%p failed.\n", pbBase, mbi.RegionSize - 0x10000);
|
||||
}
|
||||
else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
printf(" %p..%p %6x [%p]\n",
|
||||
mbi.BaseAddress, (PBYTE)mbi.BaseAddress + mbi.RegionSize - 1,
|
||||
mbi.State,
|
||||
pbTry);
|
||||
|
||||
pbTry = (PBYTE)mbi.BaseAddress + mbi.RegionSize;
|
||||
}
|
||||
#endif
|
||||
|
||||
printf("sleepnew.exe: GetSleptTicks() = %ld\n\n", GetSleptTicks());
|
||||
return 0;
|
||||
}
|
||||
//
|
||||
///////////////////////////////////////////////////////////////// End of File.
|
69
samples/slept/sleepold.cpp
Normal file
69
samples/slept/sleepold.cpp
Normal file
@ -0,0 +1,69 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detour Test Program (sleepold.cpp of sleepold.exe)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "verify.cpp"
|
||||
|
||||
int __cdecl main(int argc, char **argv)
|
||||
{
|
||||
BOOL fQuiet = FALSE;
|
||||
|
||||
if (argc == 2 && _stricmp(argv[1], "-quiet") == 0) {
|
||||
fQuiet = TRUE;
|
||||
}
|
||||
|
||||
//
|
||||
// Verify what the code looks like.
|
||||
//
|
||||
printf("sleepold.exe: Starting (at %p).\n", main);
|
||||
if (!fQuiet) {
|
||||
Verify("SleepEx", (PBYTE)SleepEx);
|
||||
printf("\n");
|
||||
}
|
||||
fflush(stdout);
|
||||
|
||||
//
|
||||
// See if another process wants us to wait on a shared event.
|
||||
// This helps in testing loading a DLL into a new process.
|
||||
|
||||
if (argc == 2 && _stricmp(argv[1], "-wait") == 0) {
|
||||
HANDLE hEvent = OpenEventA(SYNCHRONIZE, FALSE, "detours_load_test_event");
|
||||
if (hEvent) {
|
||||
printf("sleepold.exe: Waiting for detours_load_test_event to be set.\n");
|
||||
fflush(stdout);
|
||||
WaitForSingleObject(hEvent, INFINITE);
|
||||
}
|
||||
else {
|
||||
printf("sleepold.exe: Couldn't open detours_load_test_event.\n");
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Try out sleep (which may be detours).
|
||||
//
|
||||
printf("sleepold.exe: Calling Sleep for 1 second.\n");
|
||||
Sleep(1000);
|
||||
|
||||
printf("sleepold.exe: Calling SleepEx for 1 second.\n");
|
||||
SleepEx(1000, false);
|
||||
|
||||
printf("sleepold.exe: Calling Sleep again for 1 second.\n");
|
||||
Sleep(1000);
|
||||
|
||||
// DebugBreak();
|
||||
|
||||
printf("sleepold.exe: Done sleeping.\n\n");
|
||||
fflush(stdout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
//
|
||||
///////////////////////////////////////////////////////////////// End of File.
|
130
samples/slept/slept.cpp
Normal file
130
samples/slept/slept.cpp
Normal file
@ -0,0 +1,130 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detour Test Program (slept.cpp of slept.dll)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include "detours.h"
|
||||
#include "slept.h"
|
||||
|
||||
#include "verify.cpp"
|
||||
|
||||
static BOOL fBroke = FALSE;
|
||||
static LONG dwSlept = 0;
|
||||
static DWORD (WINAPI * TrueSleepEx)(DWORD dwMilliseconds, BOOL bAlertable) = SleepEx;
|
||||
|
||||
DWORD WINAPI UntimedSleepEx(DWORD dwMilliseconds, BOOL bAlertable)
|
||||
{
|
||||
return TrueSleepEx(dwMilliseconds, bAlertable);
|
||||
}
|
||||
|
||||
DWORD WINAPI TimedSleepEx(DWORD dwMilliseconds, BOOL bAlertable)
|
||||
{
|
||||
DWORD dwBeg = GetTickCount();
|
||||
DWORD ret = TrueSleepEx(dwMilliseconds, bAlertable);
|
||||
DWORD dwEnd = GetTickCount();
|
||||
|
||||
if (!fBroke) {
|
||||
fBroke = TRUE;
|
||||
// DebugBreak();
|
||||
}
|
||||
|
||||
InterlockedExchangeAdd(&dwSlept, dwEnd - dwBeg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
DWORD WINAPI GetSleptTicks(VOID)
|
||||
{
|
||||
return dwSlept;
|
||||
}
|
||||
|
||||
DWORD WINAPI TestTicks(VOID)
|
||||
{
|
||||
return TestTicksEx(0);
|
||||
}
|
||||
|
||||
DWORD WINAPI TestTicksEx(DWORD Add)
|
||||
{
|
||||
PDWORD pdw = new DWORD [Add + 1];
|
||||
|
||||
if (pdw != NULL) {
|
||||
pdw[0] = dwSlept;
|
||||
for (DWORD n = 1; n < Add + 1; n++) {
|
||||
pdw[n] = pdw[n-1] + 1;
|
||||
}
|
||||
|
||||
for (DWORD n = 1; n < Add + 1; n++) {
|
||||
pdw[n-1] = pdw[n-1] - 1;
|
||||
}
|
||||
|
||||
for (DWORD n = 1; n < Add + 1; n++) {
|
||||
pdw[n] = pdw[n-1] + 1;
|
||||
}
|
||||
|
||||
Add = pdw[Add] - Add;
|
||||
|
||||
delete [] pdw;
|
||||
}
|
||||
else {
|
||||
Add = dwSlept + Add;
|
||||
}
|
||||
|
||||
return Add;
|
||||
}
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
|
||||
{
|
||||
LONG error;
|
||||
(void)hinst;
|
||||
(void)reserved;
|
||||
|
||||
if (DetourIsHelperProcess()) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (dwReason == DLL_PROCESS_ATTACH) {
|
||||
DetourRestoreAfterWith();
|
||||
|
||||
printf("slept" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: "
|
||||
" Starting.\n");
|
||||
PVOID pbExeEntry = DetourGetEntryPoint(NULL);
|
||||
PVOID pbDllEntry = DetourGetEntryPoint(hinst);
|
||||
printf("slept" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: "
|
||||
" ExeEntry=%p, DllEntry=%p\n", pbExeEntry, pbDllEntry);
|
||||
|
||||
Verify("SleepEx", (PVOID)SleepEx);
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
DetourAttach(&(PVOID&)TrueSleepEx, TimedSleepEx);
|
||||
error = DetourTransactionCommit();
|
||||
|
||||
if (error == NO_ERROR) {
|
||||
printf("slept" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: "
|
||||
" Detoured SleepEx() @ %p.\n", TrueSleepEx);
|
||||
}
|
||||
else {
|
||||
printf("slept" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: "
|
||||
" Error detouring SleepEx(): %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
18
samples/slept/slept.h
Normal 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
17
samples/slept/slept.rc
Normal file
@ -0,0 +1,17 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version information for sleep.rc.
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
|
||||
#include "detver.h"
|
||||
|
||||
#define VER_INTERNALNAME_STR "sleep" DETOURS_STRINGIFY(DETOURS_BITS)
|
||||
#define VER_ORIGINALFILENAME_STR "sleep" DETOURS_STRINGIFY(DETOURS_BITS) ".dll"
|
||||
#define VER_FILEDESCRIPTION_STR "Detours Sleep Test Module"
|
||||
#define VER_COMPANYNAME_STR "Microsoft Corporation"
|
||||
|
||||
#include "common.ver"
|
74
samples/slept/verify.cpp
Normal file
74
samples/slept/verify.cpp
Normal file
@ -0,0 +1,74 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detour Test Program (verify.cpp)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
|
||||
#include <detours.h>
|
||||
|
||||
static VOID Dump(PBYTE pbBytes, LONG nBytes, PBYTE pbTarget)
|
||||
{
|
||||
for (LONG n = 0; n < nBytes; n += 16) {
|
||||
printf(" %p: ", pbBytes + n);
|
||||
for (LONG m = n; m < n + 16; m++) {
|
||||
if (m >= nBytes) {
|
||||
printf(" ");
|
||||
}
|
||||
else {
|
||||
printf("%02x", pbBytes[m]);
|
||||
}
|
||||
if (m % 4 == 3) {
|
||||
printf(" ");
|
||||
}
|
||||
}
|
||||
if (n == 0 && pbTarget != DETOUR_INSTRUCTION_TARGET_NONE) {
|
||||
printf(" [%p]", pbTarget);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
static VOID Decode(PCSTR pszDesc, PBYTE pbCode, PBYTE pbOther, PBYTE pbPointer, LONG nInst)
|
||||
{
|
||||
if (pbCode != pbPointer) {
|
||||
printf(" %s = %p [%p]\n", pszDesc, pbCode, pbPointer);
|
||||
}
|
||||
else {
|
||||
printf(" %s = %p\n", pszDesc, pbCode);
|
||||
}
|
||||
|
||||
if (pbCode == pbOther) {
|
||||
printf(" ... unchanged ...\n");
|
||||
return;
|
||||
}
|
||||
|
||||
PBYTE pbSrc = pbCode;
|
||||
PBYTE pbEnd;
|
||||
PVOID pbTarget;
|
||||
for (LONG n = 0; n < nInst; n++) {
|
||||
pbEnd = (PBYTE)DetourCopyInstruction(NULL, NULL, pbSrc, &pbTarget, NULL);
|
||||
Dump(pbSrc, (int)(pbEnd - pbSrc), (PBYTE)pbTarget);
|
||||
pbSrc = pbEnd;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
VOID WINAPI Verify(PCHAR pszFunc, PVOID pvPointer)
|
||||
{
|
||||
PVOID pvCode = DetourCodeFromPointer(pvPointer, NULL);
|
||||
|
||||
Decode(pszFunc, (PBYTE)pvCode, NULL, (PBYTE)pvPointer, 3);
|
||||
}
|
||||
|
||||
VOID WINAPI VerifyEx(PCHAR pszFunc, PVOID pvPointer, LONG nInst)
|
||||
{
|
||||
PVOID pvCode = DetourCodeFromPointer(pvPointer, NULL);
|
||||
|
||||
Decode(pszFunc, (PBYTE)pvCode, NULL, (PBYTE)pvPointer, nInst);
|
||||
}
|
||||
|
||||
//
|
||||
///////////////////////////////////////////////////////////////// End of File.
|
101
samples/syelog/Makefile
Normal file
101
samples/syelog/Makefile
Normal file
@ -0,0 +1,101 @@
|
||||
##############################################################################
|
||||
##
|
||||
## Makefile for Detours.
|
||||
##
|
||||
## Microsoft Research Detours Package
|
||||
##
|
||||
## Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
TARGETOS=WINNT
|
||||
!include ..\common.mak
|
||||
|
||||
LIBS=$(LIBS) kernel32.lib
|
||||
|
||||
##############################################################################
|
||||
|
||||
all: dirs \
|
||||
$(INCD)\syelog.h \
|
||||
$(LIBD)\syelog.lib \
|
||||
$(BIND)\syelogd.exe \
|
||||
\
|
||||
$(BIND)\sltest.exe \
|
||||
$(BIND)\sltestp.exe \
|
||||
\
|
||||
!IF $(DETOURS_SOURCE_BROWSING)==1
|
||||
$(OBJD)\syelogd.bsc \
|
||||
$(OBJD)\sltest.bsc \
|
||||
$(OBJD)\sltestp.bsc \
|
||||
!ENDIF
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
clean:
|
||||
-del *~ test.txt 2> nul
|
||||
-del $(INCD)\syelog.* 2>nul
|
||||
-del $(LIBD)\syelog.* 2>nul
|
||||
-del $(BIND)\syelogd.* 2>nul
|
||||
-del $(BIND)\sltest.* 2>nul
|
||||
-del $(BIND)\sltestp.* 2>nul
|
||||
-rmdir /q /s $(OBJD) 2>nul
|
||||
|
||||
realclean: clean
|
||||
-rmdir /q /s $(OBJDS) 2>nul
|
||||
|
||||
##############################################################################
|
||||
|
||||
dirs:
|
||||
@if not exist $(INCD) mkdir $(INCD) && echo. Created $(INCD)
|
||||
@if not exist $(LIBD) mkdir $(LIBD) && echo. Created $(LIBD)
|
||||
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
|
||||
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
|
||||
|
||||
$(OBJD)\syelog.obj : syelog.cpp syelog.h
|
||||
$(OBJD)\syelogd.obj: syelogd.cpp syelog.h
|
||||
$(OBJD)\sltest.obj: sltest.cpp syelog.h
|
||||
$(OBJD)\sltestp.obj: sltestp.cpp syelog.h
|
||||
|
||||
$(INCD)\syelog.h : syelog.h
|
||||
copy syelog.h $@
|
||||
|
||||
$(LIBD)\syelog.lib : $(OBJD)\syelog.obj
|
||||
link /lib $(LIBFLAGS) /out:$@ $(OBJD)\syelog.obj
|
||||
|
||||
$(BIND)\sltest.exe: $(OBJD)\sltest.obj $(OBJD)\syelog.obj $(DEPS)
|
||||
$(CC) $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\sltest.obj \
|
||||
/link $(LINKFLAGS) $(LIBS)
|
||||
|
||||
$(OBJD)\sltest.bsc : $(OBJD)\sltest.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\sltest.sbr
|
||||
|
||||
$(BIND)\sltestp.exe: $(OBJD)\sltestp.obj $(DEPS)
|
||||
$(CC) $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\sltestp.obj \
|
||||
/link $(LINKFLAGS) $(LIBS)
|
||||
|
||||
$(OBJD)\sltestp.bsc : $(OBJD)\sltestp.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\sltestp.sbr
|
||||
|
||||
$(LIBD)\detours.lib:
|
||||
cd $(ROOT)\src
|
||||
nmake /nologo
|
||||
cd $(MAKEDIR)
|
||||
|
||||
$(BIND)\syelogd.exe: $(OBJD)\syelogd.obj $(DEPS)
|
||||
$(CC) $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\syelogd.obj \
|
||||
/link $(LINKFLAGS) ws2_32.lib mswsock.lib advapi32.lib
|
||||
|
||||
$(OBJD)\syelogd.bsc : $(OBJD)\syelogd.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\syelogd.sbr
|
||||
|
||||
##############################################################################
|
||||
|
||||
test: $(BIND)\syelogd.exe $(BIND)\sltest.exe $(BIND)\sltestp.exe
|
||||
@echo -------- Logging output to test.txt ------------
|
||||
start $(BIND)\syelogd.exe test.txt
|
||||
$(BIND)\sleep5.exe 1
|
||||
$(BIND)\sltestp.exe
|
||||
$(BIND)\sltest.exe /x
|
||||
type test.txt
|
||||
|
||||
################################################################# End of File.
|
145
samples/syelog/sltest.cpp
Normal file
145
samples/syelog/sltest.cpp
Normal file
@ -0,0 +1,145 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detours Test Program (sltest.cpp of sltest.exe)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// Test the named-pipe-based connection with syelog.lib to the syelog
|
||||
// system-event logger.
|
||||
//
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#pragma warning(push)
|
||||
#if _MSC_VER > 1400
|
||||
#pragma warning(disable:6102 6103) // /analyze warnings
|
||||
#endif
|
||||
#include <strsafe.h>
|
||||
#pragma warning(pop)
|
||||
#include "syelog.h"
|
||||
#include "detours.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
HANDLE ( WINAPI *
|
||||
Real_CreateFileW)(LPCWSTR a0,
|
||||
DWORD a1,
|
||||
DWORD a2,
|
||||
LPSECURITY_ATTRIBUTES a3,
|
||||
DWORD a4,
|
||||
DWORD a5,
|
||||
HANDLE a6)
|
||||
= CreateFileW;
|
||||
|
||||
BOOL ( WINAPI *
|
||||
Real_WriteFile)(HANDLE hFile,
|
||||
LPCVOID lpBuffer,
|
||||
DWORD nNumberOfBytesToWrite,
|
||||
LPDWORD lpNumberOfBytesWritten,
|
||||
LPOVERLAPPED lpOverlapped)
|
||||
= WriteFile;
|
||||
BOOL ( WINAPI *
|
||||
Real_FlushFileBuffers)(HANDLE hFile)
|
||||
= FlushFileBuffers;
|
||||
BOOL ( WINAPI *
|
||||
Real_CloseHandle)(HANDLE hObject)
|
||||
= CloseHandle;
|
||||
|
||||
BOOL ( WINAPI *
|
||||
Real_WaitNamedPipeW)(LPCWSTR lpNamedPipeName, DWORD nTimeOut)
|
||||
= WaitNamedPipeW;
|
||||
BOOL ( WINAPI *
|
||||
Real_SetNamedPipeHandleState)(HANDLE hNamedPipe,
|
||||
LPDWORD lpMode,
|
||||
LPDWORD lpMaxCollectionCount,
|
||||
LPDWORD lpCollectDataTimeout)
|
||||
= SetNamedPipeHandleState;
|
||||
|
||||
DWORD ( WINAPI *
|
||||
Real_GetCurrentProcessId)(VOID)
|
||||
= GetCurrentProcessId;
|
||||
VOID ( WINAPI *
|
||||
Real_GetSystemTimeAsFileTime)(LPFILETIME lpSystemTimeAsFileTime)
|
||||
= GetSystemTimeAsFileTime;
|
||||
|
||||
VOID ( WINAPI *
|
||||
Real_InitializeCriticalSection)(LPCRITICAL_SECTION lpSection)
|
||||
= InitializeCriticalSection;
|
||||
VOID ( WINAPI *
|
||||
Real_EnterCriticalSection)(LPCRITICAL_SECTION lpSection)
|
||||
= EnterCriticalSection;
|
||||
VOID ( WINAPI *
|
||||
Real_LeaveCriticalSection)(LPCRITICAL_SECTION lpSection)
|
||||
= LeaveCriticalSection;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
BOOL fNeedHelp = FALSE;
|
||||
BOOL fRequestExitOnClose = FALSE;
|
||||
|
||||
int arg = 1;
|
||||
for (; arg < argc && (argv[arg][0] == '-' || argv[arg][0] == '/'); arg++) {
|
||||
CHAR *argn = argv[arg] + 1;
|
||||
CHAR *argp = argn;
|
||||
while (*argp && *argp != ':') {
|
||||
argp++;
|
||||
}
|
||||
if (*argp == ':') {
|
||||
*argp++ = '\0';
|
||||
}
|
||||
|
||||
switch (argn[0]) {
|
||||
|
||||
case 'x': // Request exit on close.
|
||||
case 'X':
|
||||
fRequestExitOnClose = TRUE;
|
||||
break;
|
||||
|
||||
case '?': // Help.
|
||||
fNeedHelp = TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
fNeedHelp = TRUE;
|
||||
printf("SLTEST: Bad argument: %s:%s\n", argn, argp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (fNeedHelp) {
|
||||
printf("Usage:\n"
|
||||
" sltest.exe [options] message\n"
|
||||
"Options:\n"
|
||||
" /x Ask syelogd.exe to terminate when this connect closes.\n"
|
||||
" /? Display this help message.\n"
|
||||
"\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
SyelogOpen("sltest", SYELOG_FACILITY_APPLICATION);
|
||||
if (arg >= argc) {
|
||||
Syelog(SYELOG_SEVERITY_INFORMATION, "Hello World! [1 of 4]");
|
||||
Syelog(SYELOG_SEVERITY_INFORMATION, "Hello World! [2 of 4]");
|
||||
Syelog(SYELOG_SEVERITY_INFORMATION, "Hello World! [3 of 4]");
|
||||
Syelog(SYELOG_SEVERITY_INFORMATION, "Hello World! [4 of 4]");
|
||||
}
|
||||
else {
|
||||
CHAR Buffer[1024] = "";
|
||||
|
||||
for (; arg < argc; arg++) {
|
||||
StringCchCatA(Buffer, ARRAYSIZE(Buffer), argv[arg]);
|
||||
if (arg + 1 < argc) {
|
||||
StringCchCatA(Buffer, ARRAYSIZE(Buffer), " ");
|
||||
}
|
||||
}
|
||||
Syelog(SYELOG_SEVERITY_INFORMATION, Buffer);
|
||||
}
|
||||
|
||||
SyelogClose(fRequestExitOnClose);
|
||||
|
||||
return 0;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user