Compare commits

..

No commits in common. "master" and "v1" have entirely different histories.
master ... v1

546 changed files with 34809 additions and 216421 deletions

View File

@ -1,2 +0,0 @@
[alias]
xtask = "run --package xtask --"

View File

@ -1,52 +0,0 @@
FROM nvidia/cuda:12.4.1-base-ubuntu22.04
RUN DEBIAN_FRONTEND=noninteractive apt-get update -y && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
wget \
build-essential \
cmake \
ninja-build \
python3 \
ripgrep \
git \
ltrace \
# required by llvm 17
lsb-release software-properties-common gnupg
ARG LLVM_VERSION=17
RUN wget https://apt.llvm.org/llvm.sh && \
chmod +x llvm.sh && \
./llvm.sh ${LLVM_VERSION}
# Feel free to change to a newer version if you have a newer verison on your host
ARG CUDA_PKG_VERSION=12-4
# Docker <-> host driver version compatiblity is newer host <-> older docker
# We don't care about a specific driver version, so pick oldest 5XX
ARG CUDA_DRIVER=515
RUN DEBIAN_FRONTEND=noninteractive apt-get update -y && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
# CUDA headers need it for interop
libgl-dev libegl-dev libvdpau-dev \
nvidia-utils-${CUDA_DRIVER} \
cuda-cudart-dev-${CUDA_PKG_VERSION} \
cuda-nvml-dev-${CUDA_PKG_VERSION} \
cuda-cudart-${CUDA_PKG_VERSION} \
cuda-profiler-api-${CUDA_PKG_VERSION} \
cuda-nvcc-${CUDA_PKG_VERSION}
ARG ROCM_VERSION=6.3.1
RUN mkdir --parents --mode=0755 /etc/apt/keyrings && \
wget https://repo.radeon.com/rocm/rocm.gpg.key -O - | \
gpg --dearmor | tee /etc/apt/keyrings/rocm.gpg > /dev/null && \
echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/rocm.gpg] https://repo.radeon.com/rocm/apt/${ROCM_VERSION} jammy main" > /etc/apt/sources.list.d/rocm.list && \
echo 'Package: *\nPin: release o=repo.radeon.com\nPin-Priority: 600' > /etc/apt/preferences.d/rocm-pin-600 && \
DEBIAN_FRONTEND=noninteractive apt update -y && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
rocminfo \
rocm-gdb \
rocm-smi-lib \
rocm-llvm-dev \
hip-runtime-amd \
hip-dev && \
echo '/opt/rocm/lib' > /etc/ld.so.conf.d/rocm.conf && \
ldconfig
ENV PATH=$PATH:/opt/rocm-${ROCM_VERSION}/bin

View File

@ -1,34 +0,0 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/rust
{
"name": "zluda",
"build": {
"dockerfile": "Dockerfile"
},
"securityOpt": [ "seccomp=unconfined" ],
"runArgs": [
"--runtime=nvidia",
"--device=/dev/kfd",
"--device=/dev/dri",
"--group-add=video"
],
"mounts": [
{
"source": "${localEnv:HOME}/.cargo/",
"target": "/root/.cargo",
"type": "bind"
}
],
// https://containers.dev/features.
"features": {
"ghcr.io/devcontainers/features/rust:1": {}
},
// https://aka.ms/dev-containers-non-root.
"remoteUser": "root",
//"hostRequirements": { "gpu": "optional" }
"customizations": {
"vscode": {
"extensions": [ "mhutchie.git-graph" ]
}
}
}

1
.gitattributes vendored
View File

@ -1 +0,0 @@
ext/** linguist-vendored

12
.gitmodules vendored
View File

@ -1,5 +1,7 @@
[submodule "ext/llvm-project"]
path = ext/llvm-project
url = https://github.com/llvm/llvm-project
branch = release/17.x
shallow = true
[submodule "ext/spirv-tools"]
path = ext/spirv-tools
url = https://github.com/KhronosGroup/SPIRV-Tools
branch = master
[submodule "ext/spirv-headers"]
path = ext/spirv-headers
url = https://github.com/KhronosGroup/SPIRV-Headers

1395
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,33 +1,15 @@
[workspace]
resolver = "2"
members = [
"ext/hip_runtime-sys",
"ext/amd_comgr-sys",
"comgr",
"cuda_base",
"cuda_types",
"detours-sys",
"level_zero-sys",
"level_zero",
"spirv_tools-sys",
"zluda",
"zluda_dump",
"zluda_inject",
"zluda_redirect",
"zluda_ml",
#"zluda_inject",
#"zluda_redirect",
"ptx",
"ptx_parser",
"ptx_parser_macros",
"ptx_parser_macros_impl",
"xtask",
"zluda_bindgen",
]
default-members = ["zluda", "zluda_ml", "zluda_inject", "zluda_redirect"]
[profile.release-lto]
inherits = "release"
codegen-units = 1
lto = true
[profile.dev.package.xtask]
opt-level = 2
[patch.crates-io]
rspirv = { git = 'https://github.com/vosen/rspirv', rev = '40f5aa4dedb0d9f1ec24bdd8b6019e01996d1d74' }
spirv_headers = { git = 'https://github.com/vosen/rspirv', rev = '40f5aa4dedb0d9f1ec24bdd8b6019e01996d1d74' }

1
GeekBench_5_2_3.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 101 KiB

View File

@ -1,176 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS

View File

@ -1,23 +0,0 @@
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.

113
README.md
View File

@ -1,74 +1,71 @@
[![Discord](https://img.shields.io/badge/Discord-%235865F2.svg?style=for-the-badge&logo=discord&logoColor=white)](https://discord.gg/sg6BNzXuc7)
# ZLUDA
ZLUDA is a drop-in replacement for CUDA on non-NVIDIA GPU. ZLUDA allows to run unmodified CUDA applications using non-NVIDIA GPUs with near-native performance.
ZLUDA is a drop-in replacament for CUDA on Intel GPU. ZLUDA allows to run unmodified CUDA applications using Intel GPUs with near-native performance (more below). It works with current integrated Intel UHD GPUs and will work with future Intel Xe GPUs
ZLUDA supports AMD Radeon RX 5000 series and newer GPUs (both desktop and integrated).
## Performance
![GeekBench 5.5.1 chart](geekbench.svg)
ZLUDA performance has been measured with GeekBench 5.2.3 on Intel UHD 630.\
One measurement has been done using OpenCL and another measurement has been done using CUDA with Intel GPU masquerading as a (relatively slow) NVIDIA GPU with the help of ZLUDA. Both measurements use the same GPU.
Performance below is normalized to OpenCL performance. 110% means that ZLUDA-implemented CUDA is 10% faster on Intel UHD 630.
![Performance graph](GeekBench_5_2_3.svg)
[ZLUDA detailed log on Geekbench.com](https://browser.geekbench.com/v5/compute/1918048)
[OpenCL detailed log on Geekbench.com](https://browser.geekbench.com/v5/compute/1918080)
Overall in this suite of benchmarks faster by approximately 4% on ZLUDA.
### Explanation of the results
* Why is ZLUDA faster in Stereo Matching, Gaussian Blur and Depth of Field?\
This has not been precisely pinpointed to one thing or another but it's likely a combination of things:
* ZLUDA uses Level 0, which in general is a more level, highr performance API
* Tying to the previous point, currently ZLUDA does not support asynchronous execution. This gives us an unfair advantage in a benchmark like GeekBench. GeekBench exclusively uses CUDA synchronous APIs
* There is a set of GPU instructions which are available on both NVIDIA hardware and Intel hardware, but are not exposed through OpenCL. We are comparing NVIDIA GPU optimized code with the more general OpenCL code. It's a lucky coincidence (and a credit to the underlying Intel Graphics Compiler) that this code also works well on an Intel GPU
* Why is OpenCL faster in Canny and Horizon Detection?\
Authors of CUDA benchmarks used CUDA functions `atomicInc` and `atomicDec` which have direct hardware support on NVIDIA cards, but no hardware support on Intel cards. They have to be emulated in software, which limits performance
* Why are some benchmarks failing?\
ZLUDA itself supports all the operations used in the failing benchmarks. From the limited debugging that has been done yet, the problem is most likely somewhere else. Intel GPU compiler stack is very capable when it comes to compiling OpenCL, C for Metal and DPC++. It's not yet very good at compiling ZLUDA. ZLUDA emits code patterns never seen before by the Intel GPU compiler stack and hits some rarely used (or not used before) code paths in the compiler.\
Current status of failing GeekBench tests is tracked [here](https://github.com/vosen/ZLUDA/pull/12)
## Details
* Is ZLUDA a drop-in replacement for CUDA?\
Yes, but certain applications use CUDA in ways which make it incompatible with ZLUDA.
* What is the status of the project\
This project is a Proof of Concept. About the only thing that works currently is Geekbench (and not even completely). It's amazingly buggy and incomplete. You should not rely on it for anything serious
* Is it an Intel project? Is it an NVIDIA project?\
No, it's a private project
* What is the performance?\
Performance can be clode to the performance of similarly written OpenCL code (see GeekBench results in the previous section). NVIDIA GPUs and Intel GPUs have different architecture and feature set. Consequently, certain NVIDIA features have to be emulated in ZLUDA with performance penalty. Additionally, performance of ZLUDA will be always lower than the performance of code specifically optimized for Intel GPUs
* How it's different from AMD HIP or Intel DPC++ Compatibility toolkit?\
Both are porting toolkits which require programmer's effort to port applications to the API in question. With ZLUDA existing applications "just work" on an Intel GPU (if you are lucky and ZLUDA supports the particular subset of CUDA)
* Which Intel GPU are supported?\
Intel Gen9 and newer (Skylake and newer) which are supported by Intel Level 0
* Does ZLUDA support AMD GPUs?\
Certainly not currently, but it might be technically possible
ZLUDA is work in progress. Follow development here and say hi on [Discord](https://discord.gg/sg6BNzXuc7). For more details see the announcement: https://vosen.github.io/ZLUDA/blog/zludas-third-life/
## Usage
**Warning**: This version ZLUDA is under heavy development (more [here](https://vosen.github.io/ZLUDA/blog/zludas-third-life/)) and right now only supports Geekbench. ZLUDA probably will not work with your application just yet.
**Warning**: this is a very incomplete Proof of Concept. It's probably not going to work with your application. ZLUDA currently works only with applications which use CUDA Driver API. Linux builds also work with application which use statically-linked CUDA Runtime API
### Windows
You should have recent AMD GPU driver ("AMD Software: Adrenalin Edition") installed.\
To run your application you should etiher:
* (Recommended approach) Copy ZLUDA-provided `nvcuda.dll` and `nvml.dll` from `target\release` (if built from sources) or `zluda` (if downloaded a zip package) into a path which your application uses to load CUDA. Paths vary application to application, but usually it's the directory where the .exe file is located
* Use ZLUDA launcher like below. ZLUDA launcher is known to be buggy and incomplete:
```
<ZLUDA_DIRECTORY>\zluda_with.exe -- <APPLICATION> <APPLICATIONS_ARGUMENTS>
```
You should have very recent GPU drivers installed.\
Copy `nvcuda.dll` to the application directory (the directory where .exe file is) and launch it normally
### Linux
Run your application like this:
Very recent version of [compute-runtime](https://github.com/intel/compute-runtime) is required. At the time of the writing 20.45.18403 is the recommended version.
Unpack the archive somewhere and run your application like this:
```
LD_LIBRARY_PATH=<ZLUDA_DIRECTORY> <APPLICATION> <APPLICATIONS_ARGUMENTS>
LD_LIBRARY_PATH=<PATH_TO_THE_DIRECTORY_WITH_ZLUDA_PROVIDED_LIBCUDA> <YOUR_APPLICATION>
```
where `<ZLUDA_DIRECTORY>` is the directory which contains ZLUDA-provided `libcuda.so`: `target/release` if you built from sources or `zluda` if you downloaded prebuilt package.
### MacOS
Not supported
## Building
You should have relatively recent version of Rust installed, then you just do:
### Dependencies
* Git
* CMake
* Python 3
* Rust compiler (recent version)
* C++ compiler
* (Optional, but recommended) [Ninja build system](https://ninja-build.org/)
### Build steps
* Git clone the repo (make sure to use `--recursive` option to fetch submodules):
`git clone --recursive https://github.com/vosen/ZLUDA.git`
* Enter freshly cloned `ZLUDA` directory and build with cargo (this takes a while):
`cargo xtask --release`
## Contributing
ZLUDA project has a commercial backing and _does not_ accept donations.
ZLUDA project accepts pull requests and other non-monetary contributions.
If you want to contribute a code fix or documentation update feel free to open a Pull Request.
### Getting started
There's no architecture document (yet). Two most important crates in ZLUDA are `ptx` (PTX compiler) and `zluda` (AMD GPU runtime). A good starting point to tinkering the project is to run one of the `ptx` unit tests under a debugger and understand what it is doing. `cargo test -p ptx -- ::add_hip` is a simple test that adds two numbers.
Github issues tagged with ["help wanted"](https://github.com/vosen/ZLUDA/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) are tasks that are self-containted. Their level of difficulty varies, they are not always good beginner tasks, but they defined unambiguously.
If you have questions feel free to ask on [#devtalk channel on Discord](https://discord.com/channels/1273316903783497778/1303329281409159270).
## License
This software is dual-licensed under either the Apache 2.0 license or the MIT license. See [LICENSE-APACHE](LICENSE-APACHE) or [LICENSE-MIT](LICENSE-MIT) for details
```
cargo build
```
in the main directory of the project

View File

@ -1,10 +0,0 @@
[package]
name = "comgr"
version = "0.0.0"
authors = ["Andrzej Janik <vosen@vosen.pl>"]
edition = "2021"
[lib]
[dependencies]
amd_comgr-sys = { path = "../ext/amd_comgr-sys" }

View File

@ -1,186 +0,0 @@
use amd_comgr_sys::*;
use std::{ffi::CStr, mem, ptr};
struct Data(amd_comgr_data_t);
impl Data {
fn new(
kind: amd_comgr_data_kind_t,
name: &CStr,
content: &[u8],
) -> Result<Self, amd_comgr_status_s> {
let mut data = unsafe { mem::zeroed() };
unsafe { amd_comgr_create_data(kind, &mut data) }?;
unsafe { amd_comgr_set_data_name(data, name.as_ptr()) }?;
unsafe { amd_comgr_set_data(data, content.len(), content.as_ptr().cast()) }?;
Ok(Self(data))
}
fn get(&self) -> amd_comgr_data_t {
self.0
}
fn copy_content(&self) -> Result<Vec<u8>, amd_comgr_status_s> {
let mut size = unsafe { mem::zeroed() };
unsafe { amd_comgr_get_data(self.get(), &mut size, ptr::null_mut()) }?;
let mut result: Vec<u8> = Vec::with_capacity(size);
unsafe { result.set_len(size) };
unsafe { amd_comgr_get_data(self.get(), &mut size, result.as_mut_ptr().cast()) }?;
Ok(result)
}
}
struct DataSet(amd_comgr_data_set_t);
impl DataSet {
fn new() -> Result<Self, amd_comgr_status_s> {
let mut data_set = unsafe { mem::zeroed() };
unsafe { amd_comgr_create_data_set(&mut data_set) }?;
Ok(Self(data_set))
}
fn add(&self, data: &Data) -> Result<(), amd_comgr_status_s> {
unsafe { amd_comgr_data_set_add(self.get(), data.get()) }
}
fn get(&self) -> amd_comgr_data_set_t {
self.0
}
fn get_data(
&self,
kind: amd_comgr_data_kind_t,
index: usize,
) -> Result<Data, amd_comgr_status_s> {
let mut data = unsafe { mem::zeroed() };
unsafe { amd_comgr_action_data_get_data(self.get(), kind, index, &mut data) }?;
Ok(Data(data))
}
}
impl Drop for DataSet {
fn drop(&mut self) {
unsafe { amd_comgr_destroy_data_set(self.get()).ok() };
}
}
struct ActionInfo(amd_comgr_action_info_t);
impl ActionInfo {
fn new() -> Result<Self, amd_comgr_status_s> {
let mut action = unsafe { mem::zeroed() };
unsafe { amd_comgr_create_action_info(&mut action) }?;
Ok(Self(action))
}
fn set_isa_name(&self, isa: &CStr) -> Result<(), amd_comgr_status_s> {
let mut full_isa = "amdgcn-amd-amdhsa--".to_string().into_bytes();
full_isa.extend(isa.to_bytes_with_nul());
unsafe { amd_comgr_action_info_set_isa_name(self.get(), full_isa.as_ptr().cast()) }
}
fn set_language(&self, language: amd_comgr_language_t) -> Result<(), amd_comgr_status_s> {
unsafe { amd_comgr_action_info_set_language(self.get(), language) }
}
fn set_options<'a>(
&self,
options: impl Iterator<Item = &'a CStr>,
) -> Result<(), amd_comgr_status_s> {
let options = options.map(|x| x.as_ptr()).collect::<Vec<_>>();
unsafe {
amd_comgr_action_info_set_option_list(
self.get(),
options.as_ptr().cast_mut(),
options.len(),
)
}
}
fn get(&self) -> amd_comgr_action_info_t {
self.0
}
}
impl Drop for ActionInfo {
fn drop(&mut self) {
unsafe { amd_comgr_destroy_action_info(self.get()).ok() };
}
}
pub fn compile_bitcode(
gcn_arch: &CStr,
main_buffer: &[u8],
ptx_impl: &[u8],
) -> Result<Vec<u8>, amd_comgr_status_s> {
use amd_comgr_sys::*;
let bitcode_data_set = DataSet::new()?;
let main_bitcode_data = Data::new(
amd_comgr_data_kind_t::AMD_COMGR_DATA_KIND_BC,
c"zluda.bc",
main_buffer,
)?;
bitcode_data_set.add(&main_bitcode_data)?;
let stdlib_bitcode_data = Data::new(
amd_comgr_data_kind_t::AMD_COMGR_DATA_KIND_BC,
c"ptx_impl.bc",
ptx_impl,
)?;
bitcode_data_set.add(&stdlib_bitcode_data)?;
let linking_info = ActionInfo::new()?;
let linked_data_set = do_action(
&bitcode_data_set,
&linking_info,
amd_comgr_action_kind_t::AMD_COMGR_ACTION_LINK_BC_TO_BC,
)?;
let compile_to_exec = ActionInfo::new()?;
compile_to_exec.set_isa_name(gcn_arch)?;
compile_to_exec.set_language(amd_comgr_language_t::AMD_COMGR_LANGUAGE_LLVM_IR)?;
let common_options = [
// This makes no sense, but it makes ockl linking work
c"-Xclang",
c"-mno-link-builtin-bitcode-postopt",
// Otherwise LLVM omits dynamic fp mode for ockl functions during linking
// and then fails to inline them
c"-Xclang",
c"-fdenormal-fp-math=dynamic",
c"-O3",
c"-mno-wavefrontsize64",
c"-mcumode",
// Useful for inlining reports, combined with AMD_COMGR_SAVE_TEMPS=1 AMD_COMGR_EMIT_VERBOSE_LOGS=1 AMD_COMGR_REDIRECT_LOGS=stderr
// c"-fsave-optimization-record=yaml",
]
.into_iter();
let opt_options = if cfg!(debug_assertions) {
//[c"-g", c"-mllvm", c"-print-before-all", c"", c""]
[c"-g", c"", c"", c"", c""]
} else {
[
c"-g0",
// default inlining threshold times 10
c"-mllvm",
c"-inline-threshold=2250",
c"-mllvm",
c"-inlinehint-threshold=3250",
]
};
compile_to_exec.set_options(common_options.chain(opt_options))?;
let exec_data_set = do_action(
&linked_data_set,
&compile_to_exec,
amd_comgr_action_kind_t::AMD_COMGR_ACTION_COMPILE_SOURCE_TO_EXECUTABLE,
)?;
let executable =
exec_data_set.get_data(amd_comgr_data_kind_t::AMD_COMGR_DATA_KIND_EXECUTABLE, 0)?;
executable.copy_content()
}
fn do_action(
data_set: &DataSet,
action: &ActionInfo,
kind: amd_comgr_action_kind_t,
) -> Result<DataSet, amd_comgr_status_s> {
let result = DataSet::new()?;
unsafe { amd_comgr_do_action(kind, action.get(), data_set.get(), result.get()) }?;
Ok(result)
}

View File

@ -1,14 +0,0 @@
[package]
name = "cuda_base"
version = "0.0.0"
authors = ["Andrzej Janik <vosen@vosen.pl>"]
edition = "2021"
[dependencies]
quote = "1.0"
syn = { version = "2.0", features = ["full", "visit-mut", "extra-traits"] }
proc-macro2 = "1.0"
rustc-hash = "1.1.0"
[lib]
proc-macro = true

View File

@ -1,7 +0,0 @@
#define __CUDA_API_VERSION_INTERNAL
#include <cuda.h>
#include <cudaProfiler.h>
#include <cudaGL.h>
#include <cudaEGL.h>
#include <vdpau/vdpau.h>
#include <cudaVDPAU.h>

File diff suppressed because it is too large Load Diff

View File

@ -1,233 +0,0 @@
extern crate proc_macro;
use proc_macro::TokenStream;
use proc_macro2::Span;
use quote::{quote, ToTokens};
use rustc_hash::FxHashMap;
use std::iter;
use syn::parse::{Parse, ParseStream};
use syn::punctuated::Punctuated;
use syn::visit_mut::VisitMut;
use syn::{
bracketed, parse_macro_input, File, ForeignItem, ForeignItemFn, Ident, Item, Path, Signature,
Token,
};
const CUDA_RS: &'static str = include_str! {"cuda.rs"};
const NVML_RS: &'static str = include_str! {"nvml.rs"};
// This macro accepts following arguments:
// * `normal_macro`: ident for a normal macro
// * zero or more:
// * `override_macro`: ident for an override macro
// * `override_fns`: list of override functions
// Then macro goes through every function in rust.rs, and for every fn `foo`:
// * if `foo` is contained in `override_fns` then pass it into `override_macro`
// * if `foo` is not contained in `override_fns` pass it to `normal_macro`
// Both `override_macro` and `normal_macro` expect semicolon-separated list:
// macro_foo!(
// "system" fn cuCtxDetach(ctx: CUcontext) -> CUresult;
// "system" fn cuCtxDetach(ctx: CUcontext) -> CUresult
// )
// Additionally, it does a fixup of CUDA types so they get prefixed with `type_path`
#[proc_macro]
pub fn cuda_function_declarations(tokens: TokenStream) -> TokenStream {
function_declarations(tokens, CUDA_RS)
}
fn function_declarations(tokens: TokenStream, module: &str) -> TokenStream {
let input = parse_macro_input!(tokens as FnDeclInput);
let mut cuda_module = syn::parse_str::<File>(module).unwrap();
let mut choose_macro = ChooseMacro::new(input);
syn::visit_mut::visit_file_mut(&mut FixFnSignatures, &mut cuda_module);
let extern_ = if let Item::ForeignMod(extern_) = cuda_module.items.pop().unwrap() {
extern_
} else {
unreachable!()
};
let abi = extern_.abi.name;
for mut item in extern_.items {
if let ForeignItem::Fn(ForeignItemFn {
sig: Signature { ref ident, .. },
ref mut attrs,
..
}) = item
{
*attrs = Vec::new();
choose_macro.add(ident, quote! { #abi #item });
} else {
unreachable!()
}
}
let mut result = proc_macro2::TokenStream::new();
for (path, items) in
iter::once(choose_macro.default).chain(choose_macro.override_sets.into_iter())
{
if items.is_empty() {
continue;
}
quote! {
#path ! { #(#items)* }
}
.to_tokens(&mut result);
}
result.into()
}
#[proc_macro]
pub fn nvml_function_declarations(tokens: TokenStream) -> TokenStream {
function_declarations(tokens, NVML_RS)
}
struct FnDeclInput {
normal_macro: Path,
overrides: Punctuated<OverrideMacro, Token![,]>,
}
impl Parse for FnDeclInput {
fn parse(input: ParseStream) -> syn::Result<Self> {
let normal_macro = input.parse::<Path>()?;
let overrides = if input.is_empty() {
Punctuated::new()
} else {
input.parse::<Token![,]>()?;
input.parse_terminated(OverrideMacro::parse, Token![,])?
};
Ok(Self {
normal_macro,
overrides,
})
}
}
struct OverrideMacro {
macro_: Path,
functions: Punctuated<Ident, Token![,]>,
}
impl Parse for OverrideMacro {
fn parse(input: ParseStream) -> syn::Result<Self> {
let macro_ = input.parse::<Path>()?;
input.parse::<Token![<=]>()?;
let functions_content;
bracketed!(functions_content in input);
let functions = functions_content.parse_terminated(Ident::parse, Token![,])?;
Ok(Self { macro_, functions })
}
}
struct ChooseMacro {
default: (Path, Vec<proc_macro2::TokenStream>),
override_lookup: FxHashMap<Ident, Path>,
override_sets: FxHashMap<Path, Vec<proc_macro2::TokenStream>>,
}
impl ChooseMacro {
fn new(input: FnDeclInput) -> Self {
let mut override_lookup = FxHashMap::default();
let mut override_sets = FxHashMap::default();
for OverrideMacro { macro_, functions } in input.overrides {
for ident in functions {
override_lookup.insert(ident, macro_.clone());
override_sets.insert(macro_.clone(), Vec::new());
}
}
Self {
default: (input.normal_macro, Vec::new()),
override_lookup,
override_sets,
}
}
fn add(&mut self, ident: &Ident, tokens: proc_macro2::TokenStream) {
match self.override_lookup.get(ident) {
Some(override_macro) => {
self.override_sets
.get_mut(override_macro)
.unwrap()
.push(tokens);
}
None => self.default.1.push(tokens),
}
}
}
// For some reason prettyplease will append trailing comma *only*
// if there are two or more arguments
struct FixFnSignatures;
impl VisitMut for FixFnSignatures {
fn visit_signature_mut(&mut self, s: &mut syn::Signature) {
s.inputs.pop_punct();
}
}
const MODULES: &[&str] = &[
"context", "device", "driver", "function", "link", "memory", "module", "pointer",
];
#[proc_macro]
pub fn cuda_normalize_fn(tokens: TokenStream) -> TokenStream {
let mut path = parse_macro_input!(tokens as syn::Path);
let fn_ = path
.segments
.pop()
.unwrap()
.into_tuple()
.0
.ident
.to_string();
let already_has_module = MODULES.contains(&&*path.segments.last().unwrap().ident.to_string());
let segments: Vec<String> = split(&fn_[2..]); // skip "cu"
let fn_path = join(segments, !already_has_module);
quote! {
#path #fn_path
}
.into()
}
fn split(fn_: &str) -> Vec<String> {
let mut result = Vec::new();
for c in fn_.chars() {
if c.is_ascii_uppercase() {
result.push(c.to_ascii_lowercase().to_string());
} else {
result.last_mut().unwrap().push(c);
}
}
result
}
fn join(fn_: Vec<String>, find_module: bool) -> Punctuated<Ident, Token![::]> {
fn full_form(segment: &str) -> Option<&[&str]> {
Some(match segment {
"ctx" => &["context"],
"func" => &["function"],
"mem" => &["memory"],
"memcpy" => &["memory", "copy"],
"memset" => &["memory", "set"],
_ => return None,
})
}
let mut normalized: Vec<&str> = Vec::new();
for segment in fn_.iter() {
match full_form(segment) {
Some(segments) => normalized.extend(segments.into_iter()),
None => normalized.push(&*segment),
}
}
if !find_module {
return [Ident::new(&normalized.join("_"), Span::call_site())]
.into_iter()
.collect();
}
if !MODULES.contains(&normalized[0]) {
let mut globalized = vec!["driver"];
globalized.extend(normalized);
normalized = globalized;
}
let (module, path) = normalized.split_first().unwrap();
let path = path.join("_");
[module, &&*path]
.into_iter()
.map(|s| Ident::new(s, Span::call_site()))
.collect()
}

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +0,0 @@
[package]
name = "cuda_types"
version = "0.0.0"
authors = ["Andrzej Janik <vosen@vosen.pl>"]
edition = "2018"
[dependencies]
cuda_base = { path = "../cuda_base" }
hip_runtime-sys = { path = "../ext/hip_runtime-sys" }

File diff suppressed because it is too large Load Diff

View File

@ -1,2 +0,0 @@
pub mod cuda;
pub mod nvml;

File diff suppressed because it is too large Load Diff

View File

@ -1,39 +0,0 @@
[package]
name = "detours-sys"
version = "0.1.2"
authors = ["Diana <5275194+DianaNites@users.noreply.github.com>"]
edition = "2018"
links = "detours"
# Package stuff
description = "Rust bindings to Microsoft Detours"
documentation = "https://github.com/microsoft/Detours/wiki/Reference"
homepage = "https://github.com/DianaNites/detours"
repository = "https://github.com/DianaNites/detours"
readme = "README.md"
keywords = [
"detours",
"hooking",
"injection",
]
categories = [
"external-ffi-bindings",
"os::windows-apis",
]
license = "MIT OR Apache-2.0"
exclude = [
"/.vscode/**"
]
[badges]
maintenance = { status = "as-is" }
[dev-dependencies.winapi]
version = "0.3"
features = [
"synchapi",
"processthreadsapi",
"sysinfoapi",
]
[build-dependencies]
cc = "1.0"

View File

@ -1,202 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -1,7 +0,0 @@
Copyright 2019 Diana
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.

View File

@ -1,34 +0,0 @@
# Detours-sys
[![Crates.io](https://img.shields.io/crates/v/detours-sys.svg)](https://crates.io/crates/detours-sys)
![maintenance-as-is](https://img.shields.io/badge/maintenance-as--is-yellow.svg)
Rust bindings to [Microsoft Detours](https://github.com/Microsoft/Detours)
## Usage
See the [Detours Documentation](https://github.com/Microsoft/Detours/wiki) for details.
## Details
Use the `buildtime_generation` feature to generate bindings at build time,
otherwise use pregenerated bindings.
Note that this will require a relatively recent version of Clang be installed.
## License
Licensed under either of
* Apache License, Version 2.0
([LICENSE-APACHE](LICENSE-APACHE) or <http://www.apache.org/licenses/LICENSE-2.0>)
* MIT license
([LICENSE-MIT](LICENSE-MIT) or <http://opensource.org/licenses/MIT>)
at your option.
## Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
dual licensed as above, without any additional terms or conditions.

View File

@ -1,49 +0,0 @@
#[cfg(not(target_os = "windows"))]
fn main() {}
#[cfg(target_os = "windows")]
fn main() -> Result<(), Box<dyn std::error::Error>> {
windows::main_impl()
}
#[cfg(target_os = "windows")]
mod windows {
use std::error::Error;
const CPP_FILES: [&'static str; 5] = [
"../ext/detours/src/creatwth.cpp",
"../ext/detours/src/detours.cpp",
"../ext/detours/src/disasm.cpp",
"../ext/detours/src/image.cpp",
"../ext/detours/src/modules.cpp",
];
pub fn main_impl() -> Result<(), Box<dyn Error>> {
println!("cargo:rerun-if-changed=build/wrapper.h");
for f in &CPP_FILES {
println!("cargo:rerun-if-changed={}", f);
}
build_detours()
}
fn build_detours() -> Result<(), Box<dyn Error>> {
add_target_options(
cc::Build::new()
.include("../ext/detours/src")
.files(&CPP_FILES),
)
.try_compile("detours")?;
Ok(())
}
fn add_target_options(build: &mut cc::Build) -> &mut cc::Build {
if std::env::var("CARGO_CFG_TARGET_ENV").unwrap() != "msvc" {
build
.compiler("clang")
.cpp(true)
.flag("-fms-extensions")
.flag("-Wno-everything")
} else {
build
}
}
}

View File

@ -1,2 +0,0 @@
#include <windows.h>
#include <detours.h>

File diff suppressed because it is too large Load Diff

View File

@ -1,78 +0,0 @@
#![cfg(target_os = "windows")]
//! Bindings to the Microsoft Detours API.
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
// Rebuild with:
// bindgen ..\build\wrapper.h --whitelist-function "Detour.*" -o bundled_bindings.rs -- "-fms-compatibility" "-fms-extensions" --target=x86_64-pc-windows-msvc -I ..\..\ext\detours\src\
include!("bundled_bindings.rs");
#[cfg(test)]
mod tests {
use super::*;
use std::{ffi, ptr};
use winapi::{
shared::minwindef::LPVOID,
um::{processthreadsapi::GetCurrentThread, synchapi::Sleep, sysinfoapi::GetTickCount},
};
static mut TRUE_SLEEP: unsafe extern "system" fn(DWORD) = Sleep;
static mut SLEPT: LONG = 0;
// Detour function that replaces the Sleep API.
unsafe extern "system" fn TimedSleep(dwMilliseconds: DWORD) {
// Save the before and after times around calling the Sleep API.
let dwBeg: DWORD = GetTickCount();
TRUE_SLEEP(dwMilliseconds);
let dwEnd: DWORD = GetTickCount();
SLEPT = (dwEnd - dwBeg) as i32;
}
extern "system" fn DllMain(_: HINSTANCE, reason: DWORD, _: LPVOID) -> BOOL {
if unsafe { DetourIsHelperProcess() } == 1 {
return 1;
}
let tru = unsafe { &mut TRUE_SLEEP as *mut _ as *mut *mut ffi::c_void };
let new = TimedSleep as *mut ffi::c_void;
match reason {
// DLL_PROCESS_ATTACH
1 => unsafe {
DetourRestoreAfterWith();
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread() as _);
DetourAttach(tru, new);
DetourTransactionCommit();
},
// DLL_PROCESS_DETACH
0 => unsafe {
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread() as _);
DetourDetach(tru, new);
DetourTransactionCommit();
},
_ => (),
}
1
}
#[test]
fn hook_self() {
unsafe {
DllMain(ptr::null_mut(), 1, ptr::null_mut());
let slept;
Sleep(500);
slept = SLEPT;
assert_ne!(SLEPT, 0);
DllMain(ptr::null_mut(), 0, ptr::null_mut());
Sleep(500);
assert_eq!(slept, SLEPT);
}
}
}

View File

@ -1,8 +0,0 @@
[package]
name = "amd_comgr-sys"
version = "0.0.0"
authors = ["Andrzej Janik <vosen@vosen.pl>"]
edition = "2021"
links = "amd_comgr"
[lib]

View File

@ -1 +0,0 @@
bindgen --rust-target 1.77 /opt/rocm/include/amd_comgr/amd_comgr.h -o /tmp/amd_comgr.rs --no-layout-tests --default-enum-style=newtype --allowlist-function "amd_comgr.*" --allowlist-type "amd_comgr.*" --no-derive-debug --must-use-type amd_comgr_status_t --allowlist-var "^AMD_COMGR.*$"

View File

@ -1,20 +0,0 @@
use std::env::VarError;
use std::{env, path::PathBuf};
fn main() -> Result<(), VarError> {
if cfg!(windows) {
println!("cargo:rustc-link-lib=dylib=amd_comgr_2");
let env = env::var("CARGO_CFG_TARGET_ENV")?;
if env == "msvc" {
let mut path = PathBuf::from(env::var("CARGO_MANIFEST_DIR")?);
path.push("lib");
println!("cargo:rustc-link-search=native={}", path.display());
} else {
println!("cargo:rustc-link-search=native=C:\\Windows\\System32");
};
} else {
println!("cargo:rustc-link-lib=dylib=amd_comgr");
println!("cargo:rustc-link-search=native=/opt/rocm/lib/");
}
Ok(())
}

View File

@ -1,68 +0,0 @@
;
; Definition file of amd_comgr_2.dll
; Automatic generated by gendef
; written by Kai Tietz 2008
;
LIBRARY "amd_comgr_2.dll"
EXPORTS
amd_comgr_action_data_count
amd_comgr_action_data_get_data
amd_comgr_action_info_get_isa_name
amd_comgr_action_info_get_language
amd_comgr_action_info_get_logging
amd_comgr_action_info_get_option_list_count
amd_comgr_action_info_get_option_list_item
amd_comgr_action_info_get_options
amd_comgr_action_info_get_working_directory_path
amd_comgr_action_info_set_isa_name
amd_comgr_action_info_set_language
amd_comgr_action_info_set_logging
amd_comgr_action_info_set_option_list
amd_comgr_action_info_set_options
amd_comgr_action_info_set_working_directory_path
amd_comgr_create_action_info
amd_comgr_create_data
amd_comgr_create_data_set
amd_comgr_create_disassembly_info
amd_comgr_create_symbolizer_info
amd_comgr_data_set_add
amd_comgr_data_set_remove
amd_comgr_demangle_symbol_name
amd_comgr_destroy_action_info
amd_comgr_destroy_data_set
amd_comgr_destroy_disassembly_info
amd_comgr_destroy_metadata
amd_comgr_destroy_symbolizer_info
amd_comgr_disassemble_instruction
amd_comgr_do_action
amd_comgr_get_data
amd_comgr_get_data_isa_name
amd_comgr_get_data_kind
amd_comgr_get_data_metadata
amd_comgr_get_data_name
amd_comgr_get_isa_count
amd_comgr_get_isa_metadata
amd_comgr_get_isa_name
amd_comgr_get_mangled_name
amd_comgr_get_metadata_kind
amd_comgr_get_metadata_list_size
amd_comgr_get_metadata_map_size
amd_comgr_get_metadata_string
amd_comgr_get_version
amd_comgr_index_list_metadata
amd_comgr_iterate_map_metadata
amd_comgr_iterate_symbols
amd_comgr_lookup_code_object
amd_comgr_map_elf_virtual_address_to_code_object_offset
amd_comgr_map_name_expression_to_symbol_name
amd_comgr_metadata_lookup
amd_comgr_populate_mangled_names
amd_comgr_populate_name_expression_map
amd_comgr_release_data
amd_comgr_set_data
amd_comgr_set_data_from_file_slice
amd_comgr_set_data_name
amd_comgr_status_string
amd_comgr_symbol_get_info
amd_comgr_symbol_lookup
amd_comgr_symbolize

View File

@ -1,941 +0,0 @@
/* automatically generated by rust-bindgen 0.70.1 */
pub const AMD_COMGR_INTERFACE_VERSION_MAJOR: u32 = 2;
pub const AMD_COMGR_INTERFACE_VERSION_MINOR: u32 = 7;
impl amd_comgr_status_s {
#[doc = " The function has been executed successfully."]
pub const AMD_COMGR_STATUS_SUCCESS: amd_comgr_status_s =
amd_comgr_status_s(unsafe { ::std::num::NonZeroU32::new_unchecked(0) });
}
impl amd_comgr_status_s {
#[doc = " A generic error has occurred."]
pub const AMD_COMGR_STATUS_ERROR: amd_comgr_status_s =
amd_comgr_status_s(unsafe { ::std::num::NonZeroU32::new_unchecked(1) });
}
impl amd_comgr_status_s {
#[doc = " One of the actual arguments does not meet a precondition stated\n in the documentation of the corresponding formal argument. This\n includes both invalid Action types, and invalid arguments to\n valid Action types."]
pub const AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT: amd_comgr_status_s =
amd_comgr_status_s(unsafe { ::std::num::NonZeroU32::new_unchecked(2) });
}
impl amd_comgr_status_s {
#[doc = " Failed to allocate the necessary resources."]
pub const AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES: amd_comgr_status_s =
amd_comgr_status_s(unsafe { ::std::num::NonZeroU32::new_unchecked(3) });
}
#[repr(transparent)]
#[doc = " @brief Status codes."]
#[derive(Copy, Clone, Hash, PartialEq, Eq, Debug)]
pub struct amd_comgr_status_s(pub ::std::num::NonZeroU32);
type amd_comgr_status_t = Result<(), self::amd_comgr_status_s>;
// Size check
const _: fn() = || {
let _ = std::mem::transmute::<amd_comgr_status_t, u32>;
};
impl amd_comgr_language_s {
#[doc = " No high level language."]
pub const AMD_COMGR_LANGUAGE_NONE: amd_comgr_language_s = amd_comgr_language_s(0);
}
impl amd_comgr_language_s {
#[doc = " OpenCL 1.2."]
pub const AMD_COMGR_LANGUAGE_OPENCL_1_2: amd_comgr_language_s = amd_comgr_language_s(1);
}
impl amd_comgr_language_s {
#[doc = " OpenCL 2.0."]
pub const AMD_COMGR_LANGUAGE_OPENCL_2_0: amd_comgr_language_s = amd_comgr_language_s(2);
}
impl amd_comgr_language_s {
#[doc = " AMD Hetrogeneous C++ (HC)."]
pub const AMD_COMGR_LANGUAGE_HC: amd_comgr_language_s = amd_comgr_language_s(3);
}
impl amd_comgr_language_s {
#[doc = " HIP."]
pub const AMD_COMGR_LANGUAGE_HIP: amd_comgr_language_s = amd_comgr_language_s(4);
}
impl amd_comgr_language_s {
#[doc = " LLVM IR, either textual (.ll) or bitcode (.bc) format."]
pub const AMD_COMGR_LANGUAGE_LLVM_IR: amd_comgr_language_s = amd_comgr_language_s(5);
}
impl amd_comgr_language_s {
#[doc = " Marker for last valid language."]
pub const AMD_COMGR_LANGUAGE_LAST: amd_comgr_language_s = amd_comgr_language_s(5);
}
#[repr(transparent)]
#[doc = " @brief The source languages supported by the compiler."]
#[derive(Copy, Clone, Hash, PartialEq, Eq)]
pub struct amd_comgr_language_s(pub ::std::os::raw::c_uint);
#[doc = " @brief The source languages supported by the compiler."]
pub use self::amd_comgr_language_s as amd_comgr_language_t;
extern "C" {
#[must_use]
#[doc = " @brief Query additional information about a status code.\n\n @param[in] status Status code.\n\n @param[out] status_string A NUL-terminated string that describes\n the error status.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has\n been executed successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p\n status is an invalid status code, or @p status_string is NULL."]
pub fn amd_comgr_status_string(
status: amd_comgr_status_t,
status_string: *mut *const ::std::os::raw::c_char,
) -> amd_comgr_status_t;
}
extern "C" {
#[doc = " @brief Get the version of the code object manager interface\n supported.\n\n An interface is backwards compatible with an implementation with an\n equal major version, and a greater than or equal minor version.\n\n @param[out] major Major version number.\n\n @param[out] minor Minor version number."]
pub fn amd_comgr_get_version(major: *mut usize, minor: *mut usize);
}
impl amd_comgr_data_kind_s {
#[doc = " No data is available."]
pub const AMD_COMGR_DATA_KIND_UNDEF: amd_comgr_data_kind_s = amd_comgr_data_kind_s(0);
}
impl amd_comgr_data_kind_s {
#[doc = " The data is a textual main source."]
pub const AMD_COMGR_DATA_KIND_SOURCE: amd_comgr_data_kind_s = amd_comgr_data_kind_s(1);
}
impl amd_comgr_data_kind_s {
#[doc = " The data is a textual source that is included in the main source\n or other include source."]
pub const AMD_COMGR_DATA_KIND_INCLUDE: amd_comgr_data_kind_s = amd_comgr_data_kind_s(2);
}
impl amd_comgr_data_kind_s {
#[doc = " The data is a precompiled-header source that is included in the main\n source or other include source."]
pub const AMD_COMGR_DATA_KIND_PRECOMPILED_HEADER: amd_comgr_data_kind_s =
amd_comgr_data_kind_s(3);
}
impl amd_comgr_data_kind_s {
#[doc = " The data is a diagnostic output."]
pub const AMD_COMGR_DATA_KIND_DIAGNOSTIC: amd_comgr_data_kind_s = amd_comgr_data_kind_s(4);
}
impl amd_comgr_data_kind_s {
#[doc = " The data is a textual log output."]
pub const AMD_COMGR_DATA_KIND_LOG: amd_comgr_data_kind_s = amd_comgr_data_kind_s(5);
}
impl amd_comgr_data_kind_s {
#[doc = " The data is compiler LLVM IR bit code for a specific isa."]
pub const AMD_COMGR_DATA_KIND_BC: amd_comgr_data_kind_s = amd_comgr_data_kind_s(6);
}
impl amd_comgr_data_kind_s {
#[doc = " The data is a relocatable machine code object for a specific isa."]
pub const AMD_COMGR_DATA_KIND_RELOCATABLE: amd_comgr_data_kind_s = amd_comgr_data_kind_s(7);
}
impl amd_comgr_data_kind_s {
#[doc = " The data is an executable machine code object for a specific\n isa. An executable is the kind of code object that can be loaded\n and executed."]
pub const AMD_COMGR_DATA_KIND_EXECUTABLE: amd_comgr_data_kind_s = amd_comgr_data_kind_s(8);
}
impl amd_comgr_data_kind_s {
#[doc = " The data is a block of bytes."]
pub const AMD_COMGR_DATA_KIND_BYTES: amd_comgr_data_kind_s = amd_comgr_data_kind_s(9);
}
impl amd_comgr_data_kind_s {
#[doc = " The data is a fat binary (clang-offload-bundler output)."]
pub const AMD_COMGR_DATA_KIND_FATBIN: amd_comgr_data_kind_s = amd_comgr_data_kind_s(16);
}
impl amd_comgr_data_kind_s {
#[doc = " The data is an archive."]
pub const AMD_COMGR_DATA_KIND_AR: amd_comgr_data_kind_s = amd_comgr_data_kind_s(17);
}
impl amd_comgr_data_kind_s {
#[doc = " The data is a bundled bitcode."]
pub const AMD_COMGR_DATA_KIND_BC_BUNDLE: amd_comgr_data_kind_s = amd_comgr_data_kind_s(18);
}
impl amd_comgr_data_kind_s {
#[doc = " The data is a bundled archive."]
pub const AMD_COMGR_DATA_KIND_AR_BUNDLE: amd_comgr_data_kind_s = amd_comgr_data_kind_s(19);
}
impl amd_comgr_data_kind_s {
#[doc = " Marker for last valid data kind."]
pub const AMD_COMGR_DATA_KIND_LAST: amd_comgr_data_kind_s = amd_comgr_data_kind_s(19);
}
#[repr(transparent)]
#[doc = " @brief The kinds of data supported."]
#[derive(Copy, Clone, Hash, PartialEq, Eq)]
pub struct amd_comgr_data_kind_s(pub ::std::os::raw::c_uint);
#[doc = " @brief The kinds of data supported."]
pub use self::amd_comgr_data_kind_s as amd_comgr_data_kind_t;
#[doc = " @brief A handle to a data object.\n\n Data objects are used to hold the data which is either an input or\n output of a code object manager action."]
#[repr(C)]
#[derive(Copy, Clone)]
pub struct amd_comgr_data_s {
pub handle: u64,
}
#[doc = " @brief A handle to a data object.\n\n Data objects are used to hold the data which is either an input or\n output of a code object manager action."]
pub type amd_comgr_data_t = amd_comgr_data_s;
#[doc = " @brief A handle to an action data object.\n\n An action data object holds a set of data objects. These can be\n used as inputs to an action, or produced as the result of an\n action."]
#[repr(C)]
#[derive(Copy, Clone)]
pub struct amd_comgr_data_set_s {
pub handle: u64,
}
#[doc = " @brief A handle to an action data object.\n\n An action data object holds a set of data objects. These can be\n used as inputs to an action, or produced as the result of an\n action."]
pub type amd_comgr_data_set_t = amd_comgr_data_set_s;
#[doc = " @brief A handle to an action information object.\n\n An action information object holds all the necessary information,\n excluding the input data objects, required to perform an action."]
#[repr(C)]
#[derive(Copy, Clone)]
pub struct amd_comgr_action_info_s {
pub handle: u64,
}
#[doc = " @brief A handle to an action information object.\n\n An action information object holds all the necessary information,\n excluding the input data objects, required to perform an action."]
pub type amd_comgr_action_info_t = amd_comgr_action_info_s;
#[doc = " @brief A handle to a metadata node.\n\n A metadata node handle is used to traverse the metadata associated\n with a data node."]
#[repr(C)]
#[derive(Copy, Clone)]
pub struct amd_comgr_metadata_node_s {
pub handle: u64,
}
#[doc = " @brief A handle to a metadata node.\n\n A metadata node handle is used to traverse the metadata associated\n with a data node."]
pub type amd_comgr_metadata_node_t = amd_comgr_metadata_node_s;
#[doc = " @brief A handle to a machine code object symbol.\n\n A symbol handle is used to obtain the properties of symbols of a machine code\n object. A symbol handle is invalidated when the data object containing the\n symbol is destroyed."]
#[repr(C)]
#[derive(Copy, Clone)]
pub struct amd_comgr_symbol_s {
pub handle: u64,
}
#[doc = " @brief A handle to a machine code object symbol.\n\n A symbol handle is used to obtain the properties of symbols of a machine code\n object. A symbol handle is invalidated when the data object containing the\n symbol is destroyed."]
pub type amd_comgr_symbol_t = amd_comgr_symbol_s;
#[doc = " @brief A handle to a disassembly information object.\n\n A disassembly information object holds all the necessary information,\n excluding the input data, required to perform disassembly."]
#[repr(C)]
#[derive(Copy, Clone)]
pub struct amd_comgr_disassembly_info_s {
pub handle: u64,
}
#[doc = " @brief A handle to a disassembly information object.\n\n A disassembly information object holds all the necessary information,\n excluding the input data, required to perform disassembly."]
pub type amd_comgr_disassembly_info_t = amd_comgr_disassembly_info_s;
#[doc = " @brief A handle to a symbolizer information object.\n\n A symbolizer information object holds all the necessary information\n required to perform symbolization."]
#[repr(C)]
#[derive(Copy, Clone)]
pub struct amd_comgr_symbolizer_info_s {
pub handle: u64,
}
#[doc = " @brief A handle to a symbolizer information object.\n\n A symbolizer information object holds all the necessary information\n required to perform symbolization."]
pub type amd_comgr_symbolizer_info_t = amd_comgr_symbolizer_info_s;
extern "C" {
#[must_use]
#[doc = " @brief Return the number of isa names supported by this version of\n the code object manager library.\n\n The isa name specifies the instruction set architecture that should\n be used in the actions that involve machine code generation or\n inspection.\n\n @param[out] count The number of isa names supported.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has\n been executed successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p\n count is NULL.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES\n Unable to update action info object as out of resources."]
pub fn amd_comgr_get_isa_count(count: *mut usize) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Return the Nth isa name supported by this version of the\n code object manager library.\n\n @param[in] index The index of the isa name to be returned. The\n first isa name is index 0.\n\n @param[out] isa_name A null terminated string that is the isa name\n being requested.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has\n been executed successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p\n index is greater than the number of isa name supported by this\n version of the code object manager library. @p isa_name is NULL.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES\n Unable to update action info object as out of resources."]
pub fn amd_comgr_get_isa_name(
index: usize,
isa_name: *mut *const ::std::os::raw::c_char,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Get a handle to the metadata of an isa name.\n\n The structure of the returned metadata is isa name specific and versioned\n with details specified in\n https://llvm.org/docs/AMDGPUUsage.html#code-object-metadata.\n It can include information about the\n limits for resources such as registers and memory addressing.\n\n @param[in] isa_name The isa name to query.\n\n @param[out] metadata A handle to the metadata of the isa name. If\n the isa name has no metadata then the returned handle has a kind of\n @p AMD_COMGR_METADATA_KIND_NULL. The handle must be destroyed\n using @c amd_comgr_destroy_metadata.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has\n been executed successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p\n name is NULL or is not an isa name supported by this version of the\n code object manager library. @p metadata is NULL.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES\n Unable to update the data object as out of resources."]
pub fn amd_comgr_get_isa_metadata(
isa_name: *const ::std::os::raw::c_char,
metadata: *mut amd_comgr_metadata_node_t,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Create a data object that can hold data of a specified kind.\n\n Data objects are reference counted and are destroyed when the\n reference count reaches 0. When a data object is created its\n reference count is 1, it has 0 bytes of data, it has an empty name,\n and it has no metadata.\n\n @param[in] kind The kind of data the object is intended to hold.\n\n @param[out] data A handle to the data object created. Its reference\n count is set to 1.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has\n been executed successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p\n kind is an invalid data kind, or @p\n AMD_COMGR_DATA_KIND_UNDEF. @p data is NULL.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES\n Unable to create the data object as out of resources."]
pub fn amd_comgr_create_data(
kind: amd_comgr_data_kind_t,
data: *mut amd_comgr_data_t,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Indicate that no longer using a data object handle.\n\n The reference count of the associated data object is\n decremented. If it reaches 0 it is destroyed.\n\n @param[in] data The data object to release.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has\n been executed successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p\n data is an invalid data object, or has kind @p\n AMD_COMGR_DATA_KIND_UNDEF.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES\n Unable to update the data object as out of resources."]
pub fn amd_comgr_release_data(data: amd_comgr_data_t) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Get the kind of the data object.\n\n @param[in] data The data object to query.\n\n @param[out] kind The kind of data the object.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has\n been executed successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p\n data is an invalid data object. @p kind is NULL.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES\n Unable to create the data object as out of resources."]
pub fn amd_comgr_get_data_kind(
data: amd_comgr_data_t,
kind: *mut amd_comgr_data_kind_t,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Set the data content of a data object to the specified\n bytes.\n\n Any previous value of the data object is overwritten. Any metadata\n associated with the data object is also replaced which invalidates\n all metadata handles to the old metadata.\n\n @param[in] data The data object to update.\n\n @param[in] size The number of bytes in the data specified by @p bytes.\n\n @param[in] bytes The bytes to set the data object to. The bytes are\n copied into the data object and can be freed after the call.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has\n been executed successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p\n data is an invalid data object, or has kind @p\n AMD_COMGR_DATA_KIND_UNDEF.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES\n Unable to update the data object as out of resources."]
pub fn amd_comgr_set_data(
data: amd_comgr_data_t,
size: usize,
bytes: *const ::std::os::raw::c_char,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief For the given open posix file descriptor, map a slice of the\n file into the data object. The slice is specified by @p offset and @p size.\n Internally this API calls amd_comgr_set_data and resets data object's\n current state.\n\n @param[in, out] data The data object to update.\n\n @param[in] file_descriptor The native file descriptor for an open file.\n The @p file_descriptor must not be passed into a system I/O function\n by any other thread while this function is executing. The offset in\n the file descriptor may be updated based on the requested size and\n underlying platform. The @p file_descriptor may be closed immediately\n after this function returns.\n\n @param[in] offset position relative to the start of the file\n specifying the beginning of the slice in @p file_descriptor.\n\n @param[in] size Size in bytes of the slice.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The operation is successful.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p data is an invalid or\n the map operation failed."]
pub fn amd_comgr_set_data_from_file_slice(
data: amd_comgr_data_t,
file_descriptor: ::std::os::raw::c_int,
offset: u64,
size: u64,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Set the name associated with a data object.\n\n When compiling, the full name of an include directive is used to\n reference the contents of the include data object with the same\n name. The name may also be used for other data objects in log and\n diagnostic output.\n\n @param[in] data The data object to update.\n\n @param[in] name A null terminated string that specifies the name to\n use for the data object. If NULL then the name is set to the empty\n string.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has\n been executed successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p\n data is an invalid data object, or has kind @p\n AMD_COMGR_DATA_KIND_UNDEF.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES\n Unable to update the data object as out of resources."]
pub fn amd_comgr_set_data_name(
data: amd_comgr_data_t,
name: *const ::std::os::raw::c_char,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Get the data contents, and/or the size of the data\n associated with a data object.\n\n @param[in] data The data object to query.\n\n @param[in, out] size On entry, the size of @p bytes. On return, if @p bytes\n is NULL, set to the size of the data object contents.\n\n @param[out] bytes If not NULL, then the first @p size bytes of the\n data object contents is copied. If NULL, no data is copied, and\n only @p size is updated (useful in order to find the size of buffer\n required to copy the data).\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has\n been executed successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p\n data is an invalid data object, or has kind @p\n AMD_COMGR_DATA_KIND_UNDEF. @p size is NULL.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES\n Unable to update the data object as out of resources."]
pub fn amd_comgr_get_data(
data: amd_comgr_data_t,
size: *mut usize,
bytes: *mut ::std::os::raw::c_char,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Get the data object name and/or name length.\n\n @param[in] data The data object to query.\n\n @param[in, out] size On entry, the size of @p name. On return, the size of\n the data object name including the terminating null character.\n\n @param[out] name If not NULL, then the first @p size characters of the\n data object name are copied. If @p name is NULL, only @p size is updated\n (useful in order to find the size of buffer required to copy the name).\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has\n been executed successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p\n data is an invalid data object, or has kind @p\n AMD_COMGR_DATA_KIND_UNDEF. @p size is NULL.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES\n Unable to update the data object as out of resources."]
pub fn amd_comgr_get_data_name(
data: amd_comgr_data_t,
size: *mut usize,
name: *mut ::std::os::raw::c_char,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Get the data object isa name and/or isa name length.\n\n @param[in] data The data object to query.\n\n @param[in, out] size On entry, the size of @p isa_name. On return, if @p\n isa_name is NULL, set to the size of the isa name including the terminating\n null character.\n\n @param[out] isa_name If not NULL, then the first @p size characters\n of the isa name are copied. If NULL, no isa name is copied, and\n only @p size is updated (useful in order to find the size of buffer\n required to copy the isa name).\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has\n been executed successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p\n data is an invalid data object, has kind @p\n AMD_COMGR_DATA_KIND_UNDEF, or is not an isa specific\n kind. @p size is NULL.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES\n Unable to update the data object as out of resources."]
pub fn amd_comgr_get_data_isa_name(
data: amd_comgr_data_t,
size: *mut usize,
isa_name: *mut ::std::os::raw::c_char,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Create a symbolizer info object.\n\n @param[in] code_object A data object denoting a code object for which\n symbolization should be performed. The kind of this object must be\n ::AMD_COMGR_DATA_KIND_RELOCATABLE, ::AMD_COMGR_DATA_KIND_EXECUTABLE,\n or ::AMD_COMGR_DATA_KIND_BYTES.\n\n @param[in] print_symbol_callback Function called by a successfull\n symbolize query. @p symbol is a null-terminated string containing the\n symbolization of the address and @p user_data is an arbitary user data.\n The callback does not own @p symbol, and it cannot be referenced once\n the callback returns.\n\n @param[out] symbolizer_info A handle to the symbolizer info object created.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has been executed\n successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT if @p code_object is\n invalid or @p print_symbol_callback is null.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES\n Unable to create @p symbolizer_info as out of resources."]
pub fn amd_comgr_create_symbolizer_info(
code_object: amd_comgr_data_t,
print_symbol_callback: ::std::option::Option<
unsafe extern "C" fn(
symbol: *const ::std::os::raw::c_char,
user_data: *mut ::std::os::raw::c_void,
),
>,
symbolizer_info: *mut amd_comgr_symbolizer_info_t,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Destroy symbolizer info object.\n\n @param[in] symbolizer_info A handle to symbolizer info object to destroy.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS on successful execution.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT if @p\n symbolizer_info is invalid."]
pub fn amd_comgr_destroy_symbolizer_info(
symbolizer_info: amd_comgr_symbolizer_info_t,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Symbolize an address.\n\n The @p address is symbolized using the symbol definitions of the\n @p code_object specified when the @p symbolizer_info was created.\n The @p print_symbol_callback callback function specified when the\n @p symbolizer_info was created is called passing the\n symbolization result as @p symbol and @p user_data value.\n\n If symbolization is not possible ::AMD_COMGR_STATUS_SUCCESS is returned and\n the string passed to the @p symbol argument of the @p print_symbol_callback\n specified when the @p symbolizer_info was created contains the text\n \"<invalid>\" or \"??\". This is consistent with `llvm-symbolizer` utility.\n\n @param[in] symbolizer_info A handle to symbolizer info object which should be\n used to symbolize the @p address.\n\n @param[in] address An unrelocated ELF address to which symbolization\n query should be performed.\n\n @param[in] is_code if true, the symbolizer symbolize the address as code\n and the symbolization result contains filename, function name, line number\n and column number, else the symbolizer symbolize the address as data and\n the symbolizaion result contains symbol name, symbol's starting address\n and symbol size.\n\n @param[in] user_data Arbitrary user-data passed to @p print_symbol_callback\n callback as described for @p symbolizer_info argument.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has\n been executed successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p\n symbolizer_info is an invalid data object."]
pub fn amd_comgr_symbolize(
symbolizer_info: amd_comgr_symbolizer_info_t,
address: u64,
is_code: bool,
user_data: *mut ::std::os::raw::c_void,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Get a handle to the metadata of a data object.\n\n @param[in] data The data object to query.\n\n @param[out] metadata A handle to the metadata of the data\n object. If the data object has no metadata then the returned handle\n has a kind of @p AMD_COMGR_METADATA_KIND_NULL. The\n handle must be destroyed using @c amd_comgr_destroy_metadata.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has\n been executed successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p\n data is an invalid data object, or has kind @p\n AMD_COMGR_DATA_KIND_UNDEF. @p metadata is NULL.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES\n Unable to update the data object as out of resources."]
pub fn amd_comgr_get_data_metadata(
data: amd_comgr_data_t,
metadata: *mut amd_comgr_metadata_node_t,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Destroy a metadata handle.\n\n @param[in] metadata A metadata handle to destroy.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has been executed\n successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p metadata is an invalid\n metadata handle.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES Unable to update metadata\n handle as out of resources."]
pub fn amd_comgr_destroy_metadata(metadata: amd_comgr_metadata_node_t) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Create a data set object.\n\n @param[out] data_set A handle to the data set created. Initially it\n contains no data objects.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has been executed\n successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p data_set is NULL.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES Unable to create the data\n set object as out of resources."]
pub fn amd_comgr_create_data_set(data_set: *mut amd_comgr_data_set_t) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Destroy a data set object.\n\n The reference counts of any associated data objects are decremented. Any\n handles to the data set object become invalid.\n\n @param[in] data_set A handle to the data set object to destroy.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has been executed\n successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p data_set is an invalid\n data set object.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES Unable to update data set\n object as out of resources."]
pub fn amd_comgr_destroy_data_set(data_set: amd_comgr_data_set_t) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Add a data object to a data set object if it is not already added.\n\n The reference count of the data object is incremented.\n\n @param[in] data_set A handle to the data set object to be updated.\n\n @param[in] data A handle to the data object to be added. If @p data_set\n already has the specified handle present, then it is not added. The order\n that data objects are added is preserved.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has been executed\n successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p data_set is an invalid\n data set object. @p data is an invalid data object; has undef kind; has\n include kind but does not have a name.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES Unable to update data set\n object as out of resources."]
pub fn amd_comgr_data_set_add(
data_set: amd_comgr_data_set_t,
data: amd_comgr_data_t,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Remove all data objects of a specified kind from a data set object.\n\n The reference count of the removed data objects is decremented.\n\n @param[in] data_set A handle to the data set object to be updated.\n\n @param[in] data_kind The data kind of the data objects to be removed. If @p\n AMD_COMGR_DATA_KIND_UNDEF is specified then all data objects are removed.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has been executed\n successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p data_set is an invalid\n data set object. @p data_kind is an invalid data kind.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES Unable to update data set\n object as out of resources."]
pub fn amd_comgr_data_set_remove(
data_set: amd_comgr_data_set_t,
data_kind: amd_comgr_data_kind_t,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Return the number of data objects of a specified data kind that are\n added to a data set object.\n\n @param[in] data_set A handle to the data set object to be queried.\n\n @param[in] data_kind The data kind of the data objects to be counted.\n\n @param[out] count The number of data objects of data kind @p data_kind.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has been executed\n successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p data_set is an invalid\n data set object. @p data_kind is an invalid data kind or @p\n AMD_COMGR_DATA_KIND_UNDEF. @p count is NULL.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES Unable to query data set\n object as out of resources."]
pub fn amd_comgr_action_data_count(
data_set: amd_comgr_data_set_t,
data_kind: amd_comgr_data_kind_t,
count: *mut usize,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Return the Nth data object of a specified data kind that is added to a\n data set object.\n\n The reference count of the returned data object is incremented.\n\n @param[in] data_set A handle to the data set object to be queried.\n\n @param[in] data_kind The data kind of the data object to be returned.\n\n @param[in] index The index of the data object of data kind @data_kind to be\n returned. The first data object is index 0. The order of data objects matches\n the order that they were added to the data set object.\n\n @param[out] data The data object being requested.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has been executed\n successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p data_set is an invalid\n data set object. @p data_kind is an invalid data kind or @p\n AMD_COMGR_DATA_KIND_UNDEF. @p index is greater than the number of data\n objects of kind @p data_kind. @p data is NULL.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES Unable to query data set\n object as out of resources."]
pub fn amd_comgr_action_data_get_data(
data_set: amd_comgr_data_set_t,
data_kind: amd_comgr_data_kind_t,
index: usize,
data: *mut amd_comgr_data_t,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Create an action info object.\n\n @param[out] action_info A handle to the action info object created.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has\n been executed successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p\n action_info is NULL.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES\n Unable to create the action info object as out of resources."]
pub fn amd_comgr_create_action_info(
action_info: *mut amd_comgr_action_info_t,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Destroy an action info object.\n\n @param[in] action_info A handle to the action info object to destroy.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has\n been executed successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p\n action_info is an invalid action info object.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES\n Unable to update action info object as out of resources."]
pub fn amd_comgr_destroy_action_info(
action_info: amd_comgr_action_info_t,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Set the isa name of an action info object.\n\n When an action info object is created it has no isa name. Some\n actions require that the action info object has an isa name\n defined.\n\n @param[in] action_info A handle to the action info object to be\n updated.\n\n @param[in] isa_name A null terminated string that is the isa name. If NULL\n or the empty string then the isa name is cleared. The isa name is defined as\n the Code Object Target Identification string, described at\n https://llvm.org/docs/AMDGPUUsage.html#code-object-target-identification\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has\n been executed successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p\n action_info is an invalid action info object. @p isa_name is not an\n isa name supported by this version of the code object manager\n library.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES\n Unable to update action info object as out of resources."]
pub fn amd_comgr_action_info_set_isa_name(
action_info: amd_comgr_action_info_t,
isa_name: *const ::std::os::raw::c_char,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Get the isa name and/or isa name length.\n\n @param[in] action_info The action info object to query.\n\n @param[in, out] size On entry, the size of @p isa_name. On return, if @p\n isa_name is NULL, set to the size of the isa name including the terminating\n null character.\n\n @param[out] isa_name If not NULL, then the first @p size characters of the\n isa name are copied into @p isa_name. If the isa name is not set then an\n empty string is copied into @p isa_name. If NULL, no name is copied, and\n only @p size is updated (useful in order to find the size of buffer required\n to copy the name).\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has\n been executed successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p\n action_info is an invalid action info object. @p size is NULL.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES\n Unable to update the data object as out of resources."]
pub fn amd_comgr_action_info_get_isa_name(
action_info: amd_comgr_action_info_t,
size: *mut usize,
isa_name: *mut ::std::os::raw::c_char,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Set the source language of an action info object.\n\n When an action info object is created it has no language defined\n which is represented by @p\n AMD_COMGR_LANGUAGE_NONE. Some actions require that\n the action info object has a source language defined.\n\n @param[in] action_info A handle to the action info object to be\n updated.\n\n @param[in] language The language to set. If @p\n AMD_COMGR_LANGUAGE_NONE then the language is cleared.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has\n been executed successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p\n action_info is an invalid action info object. @p language is an\n invalid language.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES\n Unable to update action info object as out of resources."]
pub fn amd_comgr_action_info_set_language(
action_info: amd_comgr_action_info_t,
language: amd_comgr_language_t,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Get the language for an action info object.\n\n @param[in] action_info The action info object to query.\n\n @param[out] language The language of the action info opject. @p\n AMD_COMGR_LANGUAGE_NONE if not defined,\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has\n been executed successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p\n action_info is an invalid action info object. @p language is NULL.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES\n Unable to update the data object as out of resources."]
pub fn amd_comgr_action_info_get_language(
action_info: amd_comgr_action_info_t,
language: *mut amd_comgr_language_t,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Set the options string of an action info object.\n\n When an action info object is created it has an empty options string.\n\n This overrides any option strings or arrays previously set by calls to this\n function or @p amd_comgr_action_info_set_option_list.\n\n An @p action_info object which had its options set with this function can\n only have its option inspected with @p amd_comgr_action_info_get_options.\n\n @param[in] action_info A handle to the action info object to be\n updated.\n\n @param[in] options A null terminated string that is the options. If\n NULL or the empty string then the options are cleared.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has\n been executed successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p\n action_info is an invalid action info object.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES\n Unable to update action info object as out of resources.\n\n @deprecated since 1.3\n @see amd_comgr_action_info_set_option_list"]
pub fn amd_comgr_action_info_set_options(
action_info: amd_comgr_action_info_t,
options: *const ::std::os::raw::c_char,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Get the options string and/or options strings length of an action\n info object.\n\n The @p action_info object must have had its options set with @p\n amd_comgr_action_info_set_options.\n\n @param[in] action_info The action info object to query.\n\n @param[in, out] size On entry, the size of @p options. On return, if @p\n options is NULL, set to the size of the options including the terminating\n null character.\n\n @param[out] options If not NULL, then the first @p size characters of\n the options are copied. If the options are not set then an empty\n string is copied. If NULL, options is not copied, and only @p size\n is updated (useful inorder to find the size of buffer required to\n copy the options).\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has\n been executed successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR The options of @p action_info were not set\n with @p amd_comgr_action_info_set_options.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p\n action_info is an invalid action info object. @p size is NULL.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES\n Unable to update the data object as out of resources.\n\n @deprecated since 1.3\n @see amd_comgr_action_info_get_option_list_count and\n amd_comgr_action_info_get_option_list_item"]
pub fn amd_comgr_action_info_get_options(
action_info: amd_comgr_action_info_t,
size: *mut usize,
options: *mut ::std::os::raw::c_char,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Set the options array of an action info object.\n\n This overrides any option strings or arrays previously set by calls to this\n function or @p amd_comgr_action_info_set_options.\n\n An @p action_info object which had its options set with this function can\n only have its option inspected with @p\n amd_comgr_action_info_get_option_list_count and @p\n amd_comgr_action_info_get_option_list_item.\n\n @param[in] action_info A handle to the action info object to be updated.\n\n @param[in] options An array of null terminated strings. May be NULL if @p\n count is zero, which will result in an empty options array.\n\n @param[in] count The number of null terminated strings in @p options.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has been executed\n successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p action_info is an\n invalid action info object, or @p options is NULL and @p count is non-zero.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES Unable to update action\n info object as out of resources."]
pub fn amd_comgr_action_info_set_option_list(
action_info: amd_comgr_action_info_t,
options: *mut *const ::std::os::raw::c_char,
count: usize,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Return the number of options in the options array.\n\n The @p action_info object must have had its options set with @p\n amd_comgr_action_info_set_option_list.\n\n @param[in] action_info The action info object to query.\n\n @param[out] count The number of options in the options array.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has been executed\n successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR The options of @p action_info were never\n set, or not set with @p amd_comgr_action_info_set_option_list.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p action_info is an\n invalid action info object, or @p count is NULL.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES Unable to query the data\n object as out of resources."]
pub fn amd_comgr_action_info_get_option_list_count(
action_info: amd_comgr_action_info_t,
count: *mut usize,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Return the Nth option string in the options array and/or that\n option's length.\n\n The @p action_info object must have had its options set with @p\n amd_comgr_action_info_set_option_list.\n\n @param[in] action_info The action info object to query.\n\n @param[in] index The index of the option to be returned. The first option\n index is 0. The order is the same as the options when they were added in @p\n amd_comgr_action_info_set_options.\n\n @param[in, out] size On entry, the size of @p option. On return, if @option\n is NULL, set to the size of the Nth option string including the terminating\n null character.\n\n @param[out] option If not NULL, then the first @p size characters of the Nth\n option string are copied into @p option. If NULL, no option string is\n copied, and only @p size is updated (useful in order to find the size of\n buffer required to copy the option string).\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has been executed\n successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR The options of @p action_info were never\n set, or not set with @p amd_comgr_action_info_set_option_list.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p action_info is an\n invalid action info object, @p index is invalid, or @p size is NULL.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES Unable to query the data\n object as out of resources."]
pub fn amd_comgr_action_info_get_option_list_item(
action_info: amd_comgr_action_info_t,
index: usize,
size: *mut usize,
option: *mut ::std::os::raw::c_char,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Set the working directory of an action info object.\n\n When an action info object is created it has an empty working\n directory. Some actions use the working directory to resolve\n relative file paths.\n\n @param[in] action_info A handle to the action info object to be\n updated.\n\n @param[in] path A null terminated string that is the working\n directory path. If NULL or the empty string then the working\n directory is cleared.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has\n been executed successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p\n action_info is an invalid action info object.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES\n Unable to update action info object as out of resources."]
pub fn amd_comgr_action_info_set_working_directory_path(
action_info: amd_comgr_action_info_t,
path: *const ::std::os::raw::c_char,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Get the working directory path and/or working directory path\n length of an action info object.\n\n @param[in] action_info The action info object to query.\n\n @param[in, out] size On entry, the size of @p path. On return, if @p path is\n NULL, set to the size of the working directory path including the\n terminating null character.\n\n @param[out] path If not NULL, then the first @p size characters of\n the working directory path is copied. If the working directory path\n is not set then an empty string is copied. If NULL, the working\n directory path is not copied, and only @p size is updated (useful\n in order to find the size of buffer required to copy the working\n directory path).\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has\n been executed successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p\n action_info is an invalid action info object. @p size is NULL.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES\n Unable to update the data object as out of resources."]
pub fn amd_comgr_action_info_get_working_directory_path(
action_info: amd_comgr_action_info_t,
size: *mut usize,
path: *mut ::std::os::raw::c_char,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Set whether logging is enabled for an action info object.\n\n @param[in] action_info A handle to the action info object to be\n updated.\n\n @param[in] logging Whether logging should be enabled or disable.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has\n been executed successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p\n action_info is an invalid action info object.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES\n Unable to update action info object as out of resources."]
pub fn amd_comgr_action_info_set_logging(
action_info: amd_comgr_action_info_t,
logging: bool,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Get whether logging is enabled for an action info object.\n\n @param[in] action_info The action info object to query.\n\n @param[out] logging Whether logging is enabled.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has\n been executed successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p\n action_info is an invalid action info object. @p logging is NULL.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES\n Unable to update the data object as out of resources."]
pub fn amd_comgr_action_info_get_logging(
action_info: amd_comgr_action_info_t,
logging: *mut bool,
) -> amd_comgr_status_t;
}
impl amd_comgr_action_kind_s {
#[doc = " Preprocess each source data object in @p input in order. For each\n successful preprocessor invocation, add a source data object to @p result.\n Resolve any include source names using the names of include data objects\n in @p input. Resolve any include relative path names using the working\n directory path in @p info. Preprocess the source for the language in @p\n info.\n\n Return @p AMD_COMGR_STATUS_ERROR if any preprocessing fails.\n\n Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT\n if isa name or language is not set in @p info."]
pub const AMD_COMGR_ACTION_SOURCE_TO_PREPROCESSOR: amd_comgr_action_kind_s =
amd_comgr_action_kind_s(0);
}
impl amd_comgr_action_kind_s {
#[doc = " Copy all existing data objects in @p input to @p output, then add the\n device-specific and language-specific precompiled headers required for\n compilation.\n\n Currently the only supported languages are @p AMD_COMGR_LANGUAGE_OPENCL_1_2\n and @p AMD_COMGR_LANGUAGE_OPENCL_2_0.\n\n Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT if isa name or language\n is not set in @p info, or the language is not supported."]
pub const AMD_COMGR_ACTION_ADD_PRECOMPILED_HEADERS: amd_comgr_action_kind_s =
amd_comgr_action_kind_s(1);
}
impl amd_comgr_action_kind_s {
#[doc = " Compile each source data object in @p input in order. For each\n successful compilation add a bc data object to @p result. Resolve\n any include source names using the names of include data objects\n in @p input. Resolve any include relative path names using the\n working directory path in @p info. Produce bc for isa name in @p\n info. Compile the source for the language in @p info.\n\n Return @p AMD_COMGR_STATUS_ERROR if any compilation\n fails.\n\n Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT\n if isa name or language is not set in @p info."]
pub const AMD_COMGR_ACTION_COMPILE_SOURCE_TO_BC: amd_comgr_action_kind_s =
amd_comgr_action_kind_s(2);
}
impl amd_comgr_action_kind_s {
#[doc = " Copy all existing data objects in @p input to @p output, then add the\n device-specific and language-specific bitcode libraries required for\n compilation.\n\n Currently the only supported languages are @p AMD_COMGR_LANGUAGE_OPENCL_1_2,\n @p AMD_COMGR_LANGUAGE_OPENCL_2_0, and @p AMD_COMGR_LANGUAGE_HIP.\n\n The options in @p info should be set to a set of language-specific flags.\n For OpenCL and HIP these include:\n\n correctly_rounded_sqrt\n daz_opt\n finite_only\n unsafe_math\n wavefrontsize64\n\n For example, to enable daz_opt and unsafe_math, the options should be set\n as:\n\n const char *options[] = {\"daz_opt, \"unsafe_math\"};\n size_t optionsCount = sizeof(options) / sizeof(options[0]);\n amd_comgr_action_info_set_option_list(info, options, optionsCount);\n\n Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT if isa name or language\n is not set in @p info, the language is not supported, an unknown\n language-specific flag is supplied, or a language-specific flag is\n repeated.\n\n @deprecated since 1.7\n @warning This action, followed by @c AMD_COMGR_ACTION_LINK_BC_TO_BC, may\n result in subtle bugs due to incorrect linking of the device libraries.\n The @c AMD_COMGR_ACTION_COMPILE_SOURCE_WITH_DEVICE_LIBS_TO_BC action can\n be used as a workaround which ensures the link occurs correctly."]
pub const AMD_COMGR_ACTION_ADD_DEVICE_LIBRARIES: amd_comgr_action_kind_s =
amd_comgr_action_kind_s(3);
}
impl amd_comgr_action_kind_s {
#[doc = " Link a collection of bitcodes, bundled bitcodes, and bundled bitcode\n archives in @p into a single composite (unbundled) bitcode @p.\n Any device library bc data object must be explicitly added to @p input if\n needed.\n\n Return @p AMD_COMGR_STATUS_ERROR if the link or unbundling fails.\n\n Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT\n if IsaName is not set in @p info and does not match the isa name\n of all bc data objects in @p input, or if the Name field is not set for\n any DataObject in the input set."]
pub const AMD_COMGR_ACTION_LINK_BC_TO_BC: amd_comgr_action_kind_s = amd_comgr_action_kind_s(4);
}
impl amd_comgr_action_kind_s {
#[doc = " Optimize each bc data object in @p input and create an optimized bc data\n object to @p result.\n\n Return @p AMD_COMGR_STATUS_ERROR if the optimization fails.\n\n Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT\n if isa name is not set in @p info and does not match the isa name\n of all bc data objects in @p input."]
pub const AMD_COMGR_ACTION_OPTIMIZE_BC_TO_BC: amd_comgr_action_kind_s =
amd_comgr_action_kind_s(5);
}
impl amd_comgr_action_kind_s {
#[doc = " Perform code generation for each bc data object in @p input in\n order. For each successful code generation add a relocatable data\n object to @p result.\n\n Return @p AMD_COMGR_STATUS_ERROR if any code\n generation fails.\n\n Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT\n if isa name is not set in @p info and does not match the isa name\n of all bc data objects in @p input."]
pub const AMD_COMGR_ACTION_CODEGEN_BC_TO_RELOCATABLE: amd_comgr_action_kind_s =
amd_comgr_action_kind_s(6);
}
impl amd_comgr_action_kind_s {
#[doc = " Perform code generation for each bc data object in @p input in\n order. For each successful code generation add an assembly source data\n object to @p result.\n\n Return @p AMD_COMGR_STATUS_ERROR if any code\n generation fails.\n\n Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT\n if isa name is not set in @p info and does not match the isa name\n of all bc data objects in @p input."]
pub const AMD_COMGR_ACTION_CODEGEN_BC_TO_ASSEMBLY: amd_comgr_action_kind_s =
amd_comgr_action_kind_s(7);
}
impl amd_comgr_action_kind_s {
#[doc = " Link each relocatable data object in @p input together and add\n the linked relocatable data object to @p result. Any device\n library relocatable data object must be explicitly added to @p\n input if needed.\n\n Return @p AMD_COMGR_STATUS_ERROR if the link fails.\n\n Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT\n if isa name is not set in @p info and does not match the isa name\n of all relocatable data objects in @p input."]
pub const AMD_COMGR_ACTION_LINK_RELOCATABLE_TO_RELOCATABLE: amd_comgr_action_kind_s =
amd_comgr_action_kind_s(8);
}
impl amd_comgr_action_kind_s {
#[doc = " Link each relocatable data object in @p input together and add\n the linked executable data object to @p result. Any device\n library relocatable data object must be explicitly added to @p\n input if needed.\n\n Return @p AMD_COMGR_STATUS_ERROR if the link fails.\n\n Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT\n if isa name is not set in @p info and does not match the isa name\n of all relocatable data objects in @p input."]
pub const AMD_COMGR_ACTION_LINK_RELOCATABLE_TO_EXECUTABLE: amd_comgr_action_kind_s =
amd_comgr_action_kind_s(9);
}
impl amd_comgr_action_kind_s {
#[doc = " Assemble each source data object in @p input in order into machine code.\n For each successful assembly add a relocatable data object to @p result.\n Resolve any include source names using the names of include data objects in\n @p input. Resolve any include relative path names using the working\n directory path in @p info. Produce relocatable for isa name in @p info.\n\n Return @p AMD_COMGR_STATUS_ERROR if any assembly fails.\n\n Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT if isa name is not set in\n @p info."]
pub const AMD_COMGR_ACTION_ASSEMBLE_SOURCE_TO_RELOCATABLE: amd_comgr_action_kind_s =
amd_comgr_action_kind_s(10);
}
impl amd_comgr_action_kind_s {
#[doc = " Disassemble each relocatable data object in @p input in\n order. For each successful disassembly add a source data object to\n @p result.\n\n Return @p AMD_COMGR_STATUS_ERROR if any disassembly\n fails.\n\n Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT\n if isa name is not set in @p info and does not match the isa name\n of all relocatable data objects in @p input."]
pub const AMD_COMGR_ACTION_DISASSEMBLE_RELOCATABLE_TO_SOURCE: amd_comgr_action_kind_s =
amd_comgr_action_kind_s(11);
}
impl amd_comgr_action_kind_s {
#[doc = " Disassemble each executable data object in @p input in order. For\n each successful disassembly add a source data object to @p result.\n\n Return @p AMD_COMGR_STATUS_ERROR if any disassembly\n fails.\n\n Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT\n if isa name is not set in @p info and does not match the isa name\n of all relocatable data objects in @p input."]
pub const AMD_COMGR_ACTION_DISASSEMBLE_EXECUTABLE_TO_SOURCE: amd_comgr_action_kind_s =
amd_comgr_action_kind_s(12);
}
impl amd_comgr_action_kind_s {
#[doc = " Disassemble each bytes data object in @p input in order. For each\n successful disassembly add a source data object to @p\n result. Only simple assembly language commands are generate that\n corresponf to raw bytes are supported, not any directives that\n control the code object layout, or symbolic branch targets or\n names.\n\n Return @p AMD_COMGR_STATUS_ERROR if any disassembly\n fails.\n\n Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT\n if isa name is not set in @p info"]
pub const AMD_COMGR_ACTION_DISASSEMBLE_BYTES_TO_SOURCE: amd_comgr_action_kind_s =
amd_comgr_action_kind_s(13);
}
impl amd_comgr_action_kind_s {
#[doc = " Compile each source data object in @p input in order. For each\n successful compilation add a fat binary to @p result. Resolve\n any include source names using the names of include data objects\n in @p input. Resolve any include relative path names using the\n working directory path in @p info. Produce fat binary for isa name in @p\n info. Compile the source for the language in @p info.\n\n Return @p AMD_COMGR_STATUS_ERROR if any compilation\n fails.\n\n Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT\n if isa name or language is not set in @p info.\n\n @deprecated since 2.5\n @see in-process compilation via AMD_COMGR_ACTION_COMPILE_SOURCE_TO_BC, etc.\n insteaad"]
pub const AMD_COMGR_ACTION_COMPILE_SOURCE_TO_FATBIN: amd_comgr_action_kind_s =
amd_comgr_action_kind_s(14);
}
impl amd_comgr_action_kind_s {
#[doc = " Compile each source data object in @p input in order. For each\n successful compilation add a bc data object to @p result. Resolve\n any include source names using the names of include data objects\n in @p input. Resolve any include relative path names using the\n working directory path in @p info. Produce bc for isa name in @p\n info. Compile the source for the language in @p info. Link against\n the device-specific and language-specific bitcode device libraries\n required for compilation.\n\n Return @p AMD_COMGR_STATUS_ERROR if any compilation\n fails.\n\n Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT\n if isa name or language is not set in @p info."]
pub const AMD_COMGR_ACTION_COMPILE_SOURCE_WITH_DEVICE_LIBS_TO_BC: amd_comgr_action_kind_s =
amd_comgr_action_kind_s(15);
}
impl amd_comgr_action_kind_s {
#[doc = " Compile a single source data object in @p input in order. For each\n successful compilation add a relocatable data object to @p result.\n Resolve any include source names using the names of include data objects\n in @p input. Resolve any include relative path names using the\n working directory path in @p info. Produce relocatable for hip name in @p\n info. Compile the source for the language in @p info. Link against\n the device-specific and language-specific bitcode device libraries\n required for compilation. Currently only supports HIP language.\n\n Return @p AMD_COMGR_STATUS_ERROR if any compilation\n fails.\n\n Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT\n if isa name or language is not set in @p info."]
pub const AMD_COMGR_ACTION_COMPILE_SOURCE_TO_RELOCATABLE: amd_comgr_action_kind_s =
amd_comgr_action_kind_s(16);
}
impl amd_comgr_action_kind_s {
#[doc = " Compile each source data object in @p input and create a single executabele\n in @p result. Resolve any include source names using the names of include\n data objects in @p input. Resolve any include relative path names using the\n working directory path in @p info. Produce executable for isa name in @p\n info. Compile the source for the language in @p info. Link against\n the device-specific and language-specific bitcode device libraries\n required for compilation.\n\n Return @p AMD_COMGR_STATUS_ERROR if any compilation\n fails.\n\n Return @p AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT\n if isa name or language is not set in @p info."]
pub const AMD_COMGR_ACTION_COMPILE_SOURCE_TO_EXECUTABLE: amd_comgr_action_kind_s =
amd_comgr_action_kind_s(17);
}
impl amd_comgr_action_kind_s {
#[doc = " Marker for last valid action kind."]
pub const AMD_COMGR_ACTION_LAST: amd_comgr_action_kind_s = amd_comgr_action_kind_s(17);
}
#[repr(transparent)]
#[doc = " @brief The kinds of actions that can be performed."]
#[derive(Copy, Clone, Hash, PartialEq, Eq)]
pub struct amd_comgr_action_kind_s(pub ::std::os::raw::c_uint);
#[doc = " @brief The kinds of actions that can be performed."]
pub use self::amd_comgr_action_kind_s as amd_comgr_action_kind_t;
extern "C" {
#[must_use]
#[doc = " @brief Perform an action.\n\n Each action ignores any data objects in @p input that it does not\n use. If logging is enabled in @info then @p result will have a log\n data object added. Any diagnostic data objects produced by the\n action will be added to @p result. See the description of each\n action in @p amd_comgr_action_kind_t.\n\n @param[in] kind The action to perform.\n\n @param[in] info The action info to use when performing the action.\n\n @param[in] input The input data objects to the @p kind action.\n\n @param[out] result Any data objects are removed before performing\n the action which then adds all data objects produced by the action.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has\n been executed successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR An error was\n reported when executing the action.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p\n kind is an invalid action kind. @p input_data or @p result_data are\n invalid action data object handles. See the description of each\n action in @p amd_comgr_action_kind_t for other\n conditions that result in this status.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES\n Unable to update the data object as out of resources."]
pub fn amd_comgr_do_action(
kind: amd_comgr_action_kind_t,
info: amd_comgr_action_info_t,
input: amd_comgr_data_set_t,
result: amd_comgr_data_set_t,
) -> amd_comgr_status_t;
}
impl amd_comgr_metadata_kind_s {
#[doc = " The NULL metadata handle."]
pub const AMD_COMGR_METADATA_KIND_NULL: amd_comgr_metadata_kind_s =
amd_comgr_metadata_kind_s(0);
}
impl amd_comgr_metadata_kind_s {
#[doc = " A sting value."]
pub const AMD_COMGR_METADATA_KIND_STRING: amd_comgr_metadata_kind_s =
amd_comgr_metadata_kind_s(1);
}
impl amd_comgr_metadata_kind_s {
#[doc = " A map that consists of a set of key and value pairs."]
pub const AMD_COMGR_METADATA_KIND_MAP: amd_comgr_metadata_kind_s = amd_comgr_metadata_kind_s(2);
}
impl amd_comgr_metadata_kind_s {
#[doc = " A list that consists of a sequence of values."]
pub const AMD_COMGR_METADATA_KIND_LIST: amd_comgr_metadata_kind_s =
amd_comgr_metadata_kind_s(3);
}
impl amd_comgr_metadata_kind_s {
#[doc = " Marker for last valid metadata kind."]
pub const AMD_COMGR_METADATA_KIND_LAST: amd_comgr_metadata_kind_s =
amd_comgr_metadata_kind_s(3);
}
#[repr(transparent)]
#[doc = " @brief The kinds of metadata nodes."]
#[derive(Copy, Clone, Hash, PartialEq, Eq)]
pub struct amd_comgr_metadata_kind_s(pub ::std::os::raw::c_uint);
#[doc = " @brief The kinds of metadata nodes."]
pub use self::amd_comgr_metadata_kind_s as amd_comgr_metadata_kind_t;
extern "C" {
#[must_use]
#[doc = " @brief Get the kind of the metadata node.\n\n @param[in] metadata The metadata node to query.\n\n @param[out] kind The kind of the metadata node.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has\n been executed successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p\n metadata is an invalid metadata node. @p kind is NULL.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES\n Unable to create the data object as out of resources."]
pub fn amd_comgr_get_metadata_kind(
metadata: amd_comgr_metadata_node_t,
kind: *mut amd_comgr_metadata_kind_t,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Get the string and/or string length from a metadata string\n node.\n\n @param[in] metadata The metadata node to query.\n\n @param[in, out] size On entry, the size of @p string. On return, if @p\n string is NULL, set to the size of the string including the terminating null\n character.\n\n @param[out] string If not NULL, then the first @p size characters\n of the string are copied. If NULL, no string is copied, and only @p\n size is updated (useful in order to find the size of buffer required\n to copy the string).\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has\n been executed successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p\n metadata is an invalid metadata node, or does not have kind @p\n AMD_COMGR_METADATA_KIND_STRING. @p size is NULL.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES\n Unable to update the data object as out of resources."]
pub fn amd_comgr_get_metadata_string(
metadata: amd_comgr_metadata_node_t,
size: *mut usize,
string: *mut ::std::os::raw::c_char,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Get the map size from a metadata map node.\n\n @param[in] metadata The metadata node to query.\n\n @param[out] size The number of entries in the map.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has\n been executed successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p\n metadata is an invalid metadata node, or not of kind @p\n AMD_COMGR_METADATA_KIND_MAP. @p size is NULL.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES\n Unable to update the data object as out of resources."]
pub fn amd_comgr_get_metadata_map_size(
metadata: amd_comgr_metadata_node_t,
size: *mut usize,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Iterate over the elements a metadata map node.\n\n @warning The metadata nodes which are passed to the callback are not owned\n by the callback, and are freed just after the callback returns. The callback\n must not save any references to its parameters between iterations.\n\n @param[in] metadata The metadata node to query.\n\n @param[in] callback The function to call for each entry in the map. The\n entry's key is passed in @p key, the entry's value is passed in @p value, and\n @p user_data is passed as @p user_data. If the function returns with a status\n other than @p AMD_COMGR_STATUS_SUCCESS then iteration is stopped.\n\n @param[in] user_data The value to pass to each invocation of @p\n callback. Allows context to be passed into the call back function.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has\n been executed successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR An error was\n reported by @p callback.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p\n metadata is an invalid metadata node, or not of kind @p\n AMD_COMGR_METADATA_KIND_MAP. @p callback is NULL.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES\n Unable to iterate the metadata as out of resources."]
pub fn amd_comgr_iterate_map_metadata(
metadata: amd_comgr_metadata_node_t,
callback: ::std::option::Option<
unsafe extern "C" fn(
key: amd_comgr_metadata_node_t,
value: amd_comgr_metadata_node_t,
user_data: *mut ::std::os::raw::c_void,
) -> amd_comgr_status_t,
>,
user_data: *mut ::std::os::raw::c_void,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Use a string key to lookup an element of a metadata map\n node and return the entry value.\n\n @param[in] metadata The metadata node to query.\n\n @param[in] key A null terminated string that is the key to lookup.\n\n @param[out] value The metadata node of the @p key element of the\n @p metadata map metadata node. The handle must be destroyed\n using @c amd_comgr_destroy_metadata.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has\n been executed successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR The map has no entry\n with a string key with the value @p key.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p\n metadata is an invalid metadata node, or not of kind @p\n AMD_COMGR_METADATA_KIND_MAP. @p key or @p value is\n NULL.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES\n Unable to lookup metadata as out of resources."]
pub fn amd_comgr_metadata_lookup(
metadata: amd_comgr_metadata_node_t,
key: *const ::std::os::raw::c_char,
value: *mut amd_comgr_metadata_node_t,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Get the list size from a metadata list node.\n\n @param[in] metadata The metadata node to query.\n\n @param[out] size The number of entries in the list.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has\n been executed successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p\n metadata is an invalid metadata node, or does nopt have kind @p\n AMD_COMGR_METADATA_KIND_LIST. @p size is NULL.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES\n Unable to update the data object as out of resources."]
pub fn amd_comgr_get_metadata_list_size(
metadata: amd_comgr_metadata_node_t,
size: *mut usize,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Return the Nth metadata node of a list metadata node.\n\n @param[in] metadata The metadata node to query.\n\n @param[in] index The index being requested. The first list element\n is index 0.\n\n @param[out] value The metadata node of the @p index element of the\n @p metadata list metadata node. The handle must be destroyed\n using @c amd_comgr_destroy_metadata.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has\n been executed successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p\n metadata is an invalid metadata node or not of kind @p\n AMD_COMGR_METADATA_INFO_LIST. @p index is greater\n than the number of list elements. @p value is NULL.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES\n Unable to update action data object as out of resources."]
pub fn amd_comgr_index_list_metadata(
metadata: amd_comgr_metadata_node_t,
index: usize,
value: *mut amd_comgr_metadata_node_t,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Iterate over the symbols of a machine code object.\n\n For a AMD_COMGR_DATA_KIND_RELOCATABLE the symbols in the ELF symtab section\n are iterated. For a AMD_COMGR_DATA_KIND_EXECUTABLE the symbols in the ELF\n dynsymtab are iterated.\n\n @param[in] data The data object to query.\n\n @param[in] callback The function to call for each symbol in the machine code\n data object. The symbol handle is passed in @p symbol and @p user_data is\n passed as @p user_data. If the function returns with a status other than @p\n AMD_COMGR_STATUS_SUCCESS then iteration is stopped.\n\n @param[in] user_data The value to pass to each invocation of @p\n callback. Allows context to be passed into the call back function.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has\n been executed successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR An error was\n reported by @p callback.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p data is an invalid data\n object, or not of kind @p AMD_COMGR_DATA_KIND_RELOCATABLE or\n AMD_COMGR_DATA_KIND_EXECUTABLE. @p callback is NULL.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES\n Unable to iterate the data object as out of resources."]
pub fn amd_comgr_iterate_symbols(
data: amd_comgr_data_t,
callback: ::std::option::Option<
unsafe extern "C" fn(
symbol: amd_comgr_symbol_t,
user_data: *mut ::std::os::raw::c_void,
) -> amd_comgr_status_t,
>,
user_data: *mut ::std::os::raw::c_void,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Lookup a symbol in a machine code object by name.\n\n For a AMD_COMGR_DATA_KIND_RELOCATABLE the symbols in the ELF symtab section\n are inspected. For a AMD_COMGR_DATA_KIND_EXECUTABLE the symbols in the ELF\n dynsymtab are inspected.\n\n @param[in] data The data object to query.\n\n @param[in] name A null terminated string that is the symbol name to lookup.\n\n @param[out] symbol The symbol with the @p name.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has\n been executed successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR The machine code object has no symbol\n with @p name.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p data is an invalid data\n object, or not of kind @p AMD_COMGR_DATA_KIND_RELOCATABLE or\n AMD_COMGR_DATA_KIND_EXECUTABLE.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES\n Unable to lookup symbol as out of resources."]
pub fn amd_comgr_symbol_lookup(
data: amd_comgr_data_t,
name: *const ::std::os::raw::c_char,
symbol: *mut amd_comgr_symbol_t,
) -> amd_comgr_status_t;
}
impl amd_comgr_symbol_type_s {
#[doc = " The symbol's type is unknown.\n\n The user should not infer any specific type for symbols which return\n `AMD_COMGR_SYMBOL_TYPE_UNKNOWN`, and these symbols may return different\n types in future releases."]
pub const AMD_COMGR_SYMBOL_TYPE_UNKNOWN: amd_comgr_symbol_type_s = amd_comgr_symbol_type_s(-1);
}
impl amd_comgr_symbol_type_s {
#[doc = " The symbol's type is not specified."]
pub const AMD_COMGR_SYMBOL_TYPE_NOTYPE: amd_comgr_symbol_type_s = amd_comgr_symbol_type_s(0);
}
impl amd_comgr_symbol_type_s {
#[doc = " The symbol is associated with a data object, such as a variable, an array,\n and so on."]
pub const AMD_COMGR_SYMBOL_TYPE_OBJECT: amd_comgr_symbol_type_s = amd_comgr_symbol_type_s(1);
}
impl amd_comgr_symbol_type_s {
#[doc = " The symbol is associated with a function or other executable code."]
pub const AMD_COMGR_SYMBOL_TYPE_FUNC: amd_comgr_symbol_type_s = amd_comgr_symbol_type_s(2);
}
impl amd_comgr_symbol_type_s {
#[doc = " The symbol is associated with a section. Symbol table entries of this type\n exist primarily for relocation."]
pub const AMD_COMGR_SYMBOL_TYPE_SECTION: amd_comgr_symbol_type_s = amd_comgr_symbol_type_s(3);
}
impl amd_comgr_symbol_type_s {
#[doc = " Conventionally, the symbol's name gives the name of the source file\n associated with the object file."]
pub const AMD_COMGR_SYMBOL_TYPE_FILE: amd_comgr_symbol_type_s = amd_comgr_symbol_type_s(4);
}
impl amd_comgr_symbol_type_s {
#[doc = " The symbol labels an uninitialized common block."]
pub const AMD_COMGR_SYMBOL_TYPE_COMMON: amd_comgr_symbol_type_s = amd_comgr_symbol_type_s(5);
}
impl amd_comgr_symbol_type_s {
#[doc = " The symbol is associated with an AMDGPU Code Object V2 kernel function."]
pub const AMD_COMGR_SYMBOL_TYPE_AMDGPU_HSA_KERNEL: amd_comgr_symbol_type_s =
amd_comgr_symbol_type_s(10);
}
#[repr(transparent)]
#[doc = " @brief Machine code object symbol type."]
#[derive(Copy, Clone, Hash, PartialEq, Eq)]
pub struct amd_comgr_symbol_type_s(pub ::std::os::raw::c_int);
#[doc = " @brief Machine code object symbol type."]
pub use self::amd_comgr_symbol_type_s as amd_comgr_symbol_type_t;
impl amd_comgr_symbol_info_s {
#[doc = " The length of the symbol name in bytes. Does not include the NUL\n terminator. The type of this attribute is uint64_t."]
pub const AMD_COMGR_SYMBOL_INFO_NAME_LENGTH: amd_comgr_symbol_info_s =
amd_comgr_symbol_info_s(0);
}
impl amd_comgr_symbol_info_s {
#[doc = " The name of the symbol. The type of this attribute is character array with\n the length equal to the value of the @p AMD_COMGR_SYMBOL_INFO_NAME_LENGTH\n attribute plus 1 for a NUL terminator."]
pub const AMD_COMGR_SYMBOL_INFO_NAME: amd_comgr_symbol_info_s = amd_comgr_symbol_info_s(1);
}
impl amd_comgr_symbol_info_s {
#[doc = " The kind of the symbol. The type of this attribute is @p\n amd_comgr_symbol_type_t."]
pub const AMD_COMGR_SYMBOL_INFO_TYPE: amd_comgr_symbol_info_s = amd_comgr_symbol_info_s(2);
}
impl amd_comgr_symbol_info_s {
#[doc = " Size of the variable. The value of this attribute is undefined if the\n symbol is not a variable. The type of this attribute is uint64_t."]
pub const AMD_COMGR_SYMBOL_INFO_SIZE: amd_comgr_symbol_info_s = amd_comgr_symbol_info_s(3);
}
impl amd_comgr_symbol_info_s {
#[doc = " Indicates whether the symbol is undefined. The type of this attribute is\n bool."]
pub const AMD_COMGR_SYMBOL_INFO_IS_UNDEFINED: amd_comgr_symbol_info_s =
amd_comgr_symbol_info_s(4);
}
impl amd_comgr_symbol_info_s {
#[doc = " The value of the symbol. The type of this attribute is uint64_t."]
pub const AMD_COMGR_SYMBOL_INFO_VALUE: amd_comgr_symbol_info_s = amd_comgr_symbol_info_s(5);
}
impl amd_comgr_symbol_info_s {
#[doc = " Marker for last valid symbol info."]
pub const AMD_COMGR_SYMBOL_INFO_LAST: amd_comgr_symbol_info_s = amd_comgr_symbol_info_s(5);
}
#[repr(transparent)]
#[doc = " @brief Machine code object symbol attributes."]
#[derive(Copy, Clone, Hash, PartialEq, Eq)]
pub struct amd_comgr_symbol_info_s(pub ::std::os::raw::c_uint);
#[doc = " @brief Machine code object symbol attributes."]
pub use self::amd_comgr_symbol_info_s as amd_comgr_symbol_info_t;
extern "C" {
#[must_use]
#[doc = " @brief Query information about a machine code object symbol.\n\n @param[in] symbol The symbol to query.\n\n @param[in] attribute Attribute to query.\n\n @param[out] value Pointer to an application-allocated buffer where to store\n the value of the attribute. If the buffer passed by the application is not\n large enough to hold the value of attribute, the behavior is undefined. The\n type of value returned is specified by @p amd_comgr_symbol_info_t.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has\n been executed successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR The @p symbol does not have the requested @p\n attribute.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p symbol is an invalid\n symbol. @p attribute is an invalid value. @p value is NULL.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES\n Unable to query symbol as out of resources."]
pub fn amd_comgr_symbol_get_info(
symbol: amd_comgr_symbol_t,
attribute: amd_comgr_symbol_info_t,
value: *mut ::std::os::raw::c_void,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Create a disassembly info object.\n\n @param[in] isa_name A null terminated string that is the isa name of the\n target to disassemble for. The isa name is defined as the Code Object Target\n Identification string, described at\n https://llvm.org/docs/AMDGPUUsage.html#code-object-target-identification\n\n @param[in] read_memory_callback Function called to request @p size bytes\n from the program address space at @p from be read into @p to. The requested\n @p size is never zero. Returns the number of bytes which could be read, with\n the guarantee that no additional bytes will be available in any subsequent\n call.\n\n @param[in] print_instruction_callback Function called after a successful\n disassembly. @p instruction is a null terminated string containing the\n disassembled instruction. The callback does not own @p instruction, and it\n cannot be referenced once the callback returns.\n\n @param[in] print_address_annotation_callback Function called after @c\n print_instruction_callback returns, once for each instruction operand which\n was resolved to an absolute address. @p address is the absolute address in\n the program address space. It is intended to append a symbolic\n form of the address, perhaps as a comment, after the instruction disassembly\n produced by @c print_instruction_callback.\n\n @param[out] disassembly_info A handle to the disassembly info object\n created.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The disassembly info object was created.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p isa_name is NULL or\n invalid; or @p read_memory_callback, @p print_instruction_callback,\n or @p print_address_annotation_callback is NULL.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES Unable to create the\n disassembly info object as out of resources."]
pub fn amd_comgr_create_disassembly_info(
isa_name: *const ::std::os::raw::c_char,
read_memory_callback: ::std::option::Option<
unsafe extern "C" fn(
from: u64,
to: *mut ::std::os::raw::c_char,
size: u64,
user_data: *mut ::std::os::raw::c_void,
) -> u64,
>,
print_instruction_callback: ::std::option::Option<
unsafe extern "C" fn(
instruction: *const ::std::os::raw::c_char,
user_data: *mut ::std::os::raw::c_void,
),
>,
print_address_annotation_callback: ::std::option::Option<
unsafe extern "C" fn(address: u64, user_data: *mut ::std::os::raw::c_void),
>,
disassembly_info: *mut amd_comgr_disassembly_info_t,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Destroy a disassembly info object.\n\n @param[in] disassembly_info A handle to the disassembly info object to\n destroy.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The disassembly info object was\n destroyed.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p disassembly_info is an\n invalid disassembly info object.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES Unable to destroy the\n disassembly info object as out of resources."]
pub fn amd_comgr_destroy_disassembly_info(
disassembly_info: amd_comgr_disassembly_info_t,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Disassemble a single instruction.\n\n @param[in] address The address of the first byte of the instruction in the\n program address space.\n\n @param[in] user_data Arbitrary user-data passed to each callback function\n during disassembly.\n\n @param[out] size The number of bytes consumed to decode the\n instruction, or consumed while failing to decode an invalid instruction.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The disassembly was successful.\n\n @retval ::AMD_COMGR_STATUS_ERROR The disassembly failed.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p disassembly_info is\n invalid or @p size is NULL.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES Unable to disassemble the\n instruction as out of resources."]
pub fn amd_comgr_disassemble_instruction(
disassembly_info: amd_comgr_disassembly_info_t,
address: u64,
user_data: *mut ::std::os::raw::c_void,
size: *mut u64,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Demangle a symbol name.\n\n @param[in] mangled_symbol_name A data object of kind @p\n AMD_COMGR_DATA_KIND_BYTES containing the mangled symbol name.\n\n @param[out] demangled_symbol_name A handle to the data object of kind @p\n AMD_COMGR_DATA_KIND_BYTES created and set to contain the demangled symbol\n name in case of successful completion. The handle must be released using\n @c amd_comgr_release_data. @p demangled_symbol_name is not updated for\n an error case.\n\n @note If the @p mangled_symbol_name cannot be demangled, it will be copied\n without changes to the @p demangled_symbol_name and AMD_COMGR_STATUS_SUCCESS\n is returned.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function executed successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p mangled_symbol_name is\n an invalid data object or not of kind @p AMD_COMGR_DATA_KIND_BYTES or\n @p demangled_symbol_name is NULL.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES Out of resources."]
pub fn amd_comgr_demangle_symbol_name(
mangled_symbol_name: amd_comgr_data_t,
demangled_symbol_name: *mut amd_comgr_data_t,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Fetch mangled symbol names from a code object.\n\n @param[in] data A data object of kind @p\n AMD_COMGR_DATA_KIND_EXECUTABLE or @p AMD_COMGR_DATA_KIND_BC\n\n @param[out] count The number of mangled names retrieved. This value\n can be used as an upper bound to the Index provided to the corresponding\n amd_comgr_get_mangled_name() call.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function executed successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p data is\n an invalid data object or not of kind @p AMD_COMGR_DATA_KIND_EXECUTABLE or\n @p AMD_COMGR_DATA_KIND_BC.\n"]
pub fn amd_comgr_populate_mangled_names(
data: amd_comgr_data_t,
count: *mut usize,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Fetch the Nth specific mangled name from a set of populated names or\n that name's length.\n\n The @p data must have had its mangled names populated with @p\n amd_comgr_populate_mangled_names.\n\n @param[in] data A data object of kind @p\n AMD_COMGR_DATA_KIND_EXECUTABLE or @p AMD_COMGR_DATA_KIND_BC used to\n identify which set of mangled names to retrive from.\n\n @param[in] index The index of the mangled name to be returned.\n\n @param[in, out] size For out, the size of @p mangled_name. For in,\n if @mangled_name is NULL, set to the size of the Nth option string including\n the terminating null character.\n\n @param[out] mangled_name If not NULL, then the first @p size characters of\n the Nth mangled name string are copied into @p mangled_name. If NULL, no\n mangled name string is copied, and only @p size is updated (useful in order\n to find the size of the buffer requried to copy the mangled_name string).\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function executed successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR @p data has not been used to\n populate a set of mangled names, or index is greater than the count of\n mangled names for that data object\n"]
pub fn amd_comgr_get_mangled_name(
data: amd_comgr_data_t,
index: usize,
size: *mut usize,
mangled_name: *mut ::std::os::raw::c_char,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Populate a name expression map from a given code object.\n\n Used to map stub names *__amdgcn_name_expr_* in bitcodes and code\n objects generated by hip runtime to an associated (unmangled) name\n expression and (mangled) symbol name.\n\n @param[in] data A data object of kind @p\n AMD_COMGR_DATA_KIND_EXECUTABLE or @p AMD_COMGR_DATA_KIND_BC\n\n @param[out] count The number of name expressions mapped. This value\n can be used as an upper bound to the Index provided to the corresponding\n amd_comgr_map_name_expression_to_symbol_name() call.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function executed successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p data is\n an invalid data object or not of kind @p AMD_COMGR_DATA_KIND_EXECUTABLE or\n @p AMD_COMGR_DATA_KIND_BC.\n\n @retval ::AMD_COMGR_STATUS_ERROR LLVM API failure, which should be\n accompanied by an LLVM error message to stderr\n"]
pub fn amd_comgr_populate_name_expression_map(
data: amd_comgr_data_t,
count: *mut usize,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @brief Fetch a related symbol name for a given name expression;\n or that name's length.\n\n The @p data must have had its name expression map populated with @p\n amd_comgr_populate_name_expression_map.\n\n @param[in] data A data object of kind @p\n AMD_COMGR_DATA_KIND_EXECUTABLE or @p AMD_COMGR_DATA_KIND_BC used to\n identify which map of name expressions to retrieve from.\n\n @param[in, out] size For out, the size of @p symbol_name. For in,\n if @symbol_name is NULL, set to the size of the Nth option string including\n the terminating null character.\n\n @param[in] name_expression A character array of a name expression. This name\n is used as the key to the name expression map in order to locate the desired\n @symbol_name.\n\n @param[out] symbol_name If not NULL, then the first @p size characters of\n the symbol name string mapped from @name_expression are copied into @p\n symbol_name. If NULL, no symbol name string is copied, and only @p size is\n updated (useful in order to find the size of the buffer required to copy the\n symbol_name string).\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function executed successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR @p data object is not valid (NULL or not of\n type bitcode or code object)\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p name_expression is not\n present in the name expression map.\n"]
pub fn amd_comgr_map_name_expression_to_symbol_name(
data: amd_comgr_data_t,
size: *mut usize,
name_expression: *mut ::std::os::raw::c_char,
symbol_name: *mut ::std::os::raw::c_char,
) -> amd_comgr_status_t;
}
#[doc = " @brief A data structure for Code object information."]
#[repr(C)]
#[derive(Copy, Clone)]
pub struct code_object_info_s {
#[doc = " ISA name representing the code object."]
pub isa: *const ::std::os::raw::c_char,
#[doc = " The size of the code object."]
pub size: usize,
pub offset: u64,
}
#[doc = " @brief A data structure for Code object information."]
pub type amd_comgr_code_object_info_t = code_object_info_s;
extern "C" {
#[must_use]
#[doc = " @ brief Given a bundled code object and list of target id strings, extract\n correponding code object information.\n\n @param[in] data The data object for bundled code object. This should be\n of kind AMD_COMGR_DATA_KIND_FATBIN or AMD_COMGR_DATA_KIND_EXECUTABLE or\n AMD_COMGR_DATA_KIND_BYTES. The API interprets the data object of kind\n AMD_COMGR_DATA_KIND_FATBIN as a clang offload bundle and of kind\n AMD_COMGR_DATA_KIND_EXECUTABLE as an executable shared object. For a data\n object of type AMD_COMGR_DATA_KIND_BYTES the API first inspects the data\n passed to determine if it is a fatbin or an executable and performs\n the lookup.\n\n @param[in, out] info_list A list of code object information structure\n initialized with null terminated target id strings. If the target id\n is matched in the code object bundle the corresponding code object\n information is updated with offset and size of the code object. If the\n target id is not found the offset and size are set to 0.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has been executed\n successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR The code object bundle header is incorrect\n or reading bundle entries failed.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p data is not of\n kind AMD_COMGR_DATA_KIND_FATBIN, or AMD_COMGR_DATA_KIND_BYTES or\n AMD_COMGR_DATA_KIND_EXECUTABLE or either @p info_list is NULL.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT if the @p data has\n invalid data."]
pub fn amd_comgr_lookup_code_object(
data: amd_comgr_data_t,
info_list: *mut amd_comgr_code_object_info_t,
info_list_size: usize,
) -> amd_comgr_status_t;
}
extern "C" {
#[must_use]
#[doc = " @ brief Given a code object and an ELF virtual address, map the ELF virtual\n address to a code object offset. Also, determine if the ELF virtual address\n maps to an offset in a data region that is defined by the ELF file, but that\n does not occupy bytes in the ELF file. This is typically true of offsets that\n that refer to runtime or heap allocated memory. For ELF files with defined\n sections, these data regions are referred to as NOBITS or .bss sections.\n\n @param[in] data The data object to be inspected for the given ELF virtual\n address. This should be of kind AMD_COMGR_DATA_KIND_EXECUTABLE.\n\n @param[in] elf_virtual_address The address used to calculate the code object\n offset.\n\n @param[out] code_object_offset The code object offset returned to the caller\n based on the given ELF virtual address.\n\n @param[out] slice_size For nobits regions: the size in bytes, starting from\n the provided virtual address up to the end of the segment. In this case, the\n slice size represents the number of contiguous unreadable addresses following\n the provided address.\n\n For bits regions: the size in bytes, starting from the provided virtual\n address up to either the end of the segment, or the start of a NOBITS region.\n In this case, slice size represents the number of contiguous readable\n addresses following the provided address.\n\n @param[out] nobits Set to true if the code object offset points to a location\n in a data region that does not occupy bytes in the ELF file, as described\n above.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has been executed\n successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR The provided code object has an invalid\n header due to a mismatch in magic, class, data, version, abi, type, or\n machine.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p data is not of\n kind AMD_COMGR_DATA_KIND_EXECUTABLE or invalid, or that the provided @p\n elf_virtual_address is not within the ranges covered by the object's\n load-type program headers."]
pub fn amd_comgr_map_elf_virtual_address_to_code_object_offset(
data: amd_comgr_data_t,
elf_virtual_address: u64,
code_object_offset: *mut u64,
slice_size: *mut u64,
nobits: *mut bool,
) -> amd_comgr_status_t;
}

View File

@ -1,3 +0,0 @@
#![allow(warnings)]
pub mod amd_comgr;
pub use amd_comgr::*;

View File

@ -1,72 +0,0 @@
---
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.

View File

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

View File

@ -1,13 +0,0 @@
<!--
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.
-->

View File

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

View File

@ -1,77 +0,0 @@
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' }}

View File

@ -1,41 +0,0 @@
# 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

View File

@ -1,118 +0,0 @@
==============================================================================
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)

View File

@ -1,23 +0,0 @@
# 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.

View File

@ -1,63 +0,0 @@
##############################################################################
##
## 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.

View File

@ -1,56 +0,0 @@
# 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.

View File

@ -1,307 +0,0 @@
##############################################################################
##
## 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.

View File

@ -1,65 +0,0 @@
##############################################################################
##
## 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.

View File

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

View File

@ -1,69 +0,0 @@
//////////////////////////////////////////////////////////////////////////////
//
// 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.

View File

@ -1,167 +0,0 @@
//////////////////////////////////////////////////////////////////////////////
//
// 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.

View File

@ -1,17 +0,0 @@
//////////////////////////////////////////////////////////////////////////////
//
// 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"

View File

@ -1,48 +0,0 @@
##############################################################################
##
## 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.

View File

@ -1,114 +0,0 @@
//////////////////////////////////////////////////////////////////////////////
//
// 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;
}

View File

@ -1,86 +0,0 @@
##############################################################################
##
## 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.

View File

@ -1,130 +0,0 @@
##############################################################################
##
## 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.

View File

@ -1,47 +0,0 @@
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

File diff suppressed because it is too large Load Diff

View File

@ -1,23 +0,0 @@
//////////////////////////////////////////////////////////////////////////////
//
// 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.

View File

@ -1,76 +0,0 @@
##############################################################################
##
## 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.

View File

@ -1,232 +0,0 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; 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

View File

@ -1,702 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
//
// 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.

File diff suppressed because it is too large Load Diff

View File

@ -1,15 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
//
// 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++;
}

View File

@ -1,520 +0,0 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; 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

View File

@ -1,184 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
//
// 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;
}
}

View File

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

View File

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

View File

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

View File

@ -1,116 +0,0 @@
..\..\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 ()

View File

@ -1,306 +0,0 @@
//////////////////////////////////////////////////////////////////////////////
//
// 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.

View File

@ -1,60 +0,0 @@
//////////////////////////////////////////////////////////////////////////////
//
// 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.

View File

@ -1,17 +0,0 @@
//////////////////////////////////////////////////////////////////////////////
//
// 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"

View File

@ -1,658 +0,0 @@
//////////////////////////////////////////////////////////////////////////////
//
// 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.

View File

@ -1,53 +0,0 @@
##############################################################################
##
## 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.

View File

@ -1,129 +0,0 @@
//////////////////////////////////////////////////////////////////////////////
//
// 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

View File

@ -1,47 +0,0 @@
##############################################################################
##
## 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.

View File

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

View File

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

View File

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

View File

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

View File

@ -1,31 +0,0 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; 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

View File

@ -1,108 +0,0 @@
##############################################################################
##
## 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.

View File

@ -1,60 +0,0 @@
//
//
//
#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;
}

View File

@ -1,17 +0,0 @@
//////////////////////////////////////////////////////////////////////////////
//
// 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"

View File

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

View File

@ -1,24 +0,0 @@
//
//
//
#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;
}

View File

@ -1,148 +0,0 @@
##############################################################################
##
## 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.

View File

@ -1,55 +0,0 @@
//////////////////////////////////////////////////////////////////////////////
//
// 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.

View File

@ -1,55 +0,0 @@
//////////////////////////////////////////////////////////////////////////////
//
// 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.

View File

@ -1,82 +0,0 @@
//////////////////////////////////////////////////////////////////////////////
//
// 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.

View File

@ -1,98 +0,0 @@
//////////////////////////////////////////////////////////////////////////////
//
// 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.

View File

@ -1,47 +0,0 @@
##############################################################################
##
## 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.

View File

@ -1,125 +0,0 @@
//////////////////////////////////////////////////////////////////////////////
//
// 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.

View File

@ -1,191 +0,0 @@
//////////////////////////////////////////////////////////////////////////////
//
// 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.

View File

@ -1,21 +0,0 @@
//////////////////////////////////////////////////////////////////////////////
//
// 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.

View File

@ -1,178 +0,0 @@
##############################################################################
##
## 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.

View File

@ -1,152 +0,0 @@
//////////////////////////////////////////////////////////////////////////////
//
// 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.

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