Skip to content
This repository has been archived by the owner on Nov 1, 2023. It is now read-only.

Commit

Permalink
Add crate to debug missing dynamic libraries on Windows (#1713)
Browse files Browse the repository at this point in the history
Add a CLI tool and library code to debug missing dynamic library errors on Windows.

The implementation manually edits the registry global flags for an image file to temporarily enable loader snaps, runs the target under our custom debugger to collect the debug output strings, then parses them for informative loading errors. It does not depend on the presence of `gflags.exe`.

This detects both dynamic linking (and thus process startup) errors, as well as dynamic loading (`LoadLibrary`) errors. It can report multiple missing dynamically-linked libraries.
  • Loading branch information
ranweiler authored Mar 16, 2022
1 parent 194e7d0 commit 9000a23
Show file tree
Hide file tree
Showing 6 changed files with 411 additions and 3 deletions.
20 changes: 17 additions & 3 deletions src/agent/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/agent/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ members = [
"atexit",
"coverage",
"debugger",
"dynamic-library",
"input-tester",
"onefuzz",
"onefuzz-agent",
Expand Down
33 changes: 33 additions & 0 deletions src/agent/dynamic-library/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
[package]
name = "dynamic-library"
version = "0.1.0"
edition = "2021"

[dependencies]
anyhow = "1.0"
lazy_static = "1.4"
regex = "1.5"
structopt = "0.3"
thiserror = "1.0"

[target.'cfg(windows)'.dependencies]
debugger = { path = "../debugger" }
winreg = "0.10"

[dependencies.winapi]
version = "0.3"
features = [
"dbghelp",
"debugapi",
"handleapi",
"memoryapi",
"processthreadsapi",
"securitybaseapi",
"shellapi",
"werapi",
"winbase",
"winerror"
]

[[bin]]
name = "dynamic-library"
57 changes: 57 additions & 0 deletions src/agent/dynamic-library/src/bin/dynamic-library.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

#![allow(unused, warnings)]

use std::process::{Command, Stdio};

use anyhow::Result;
use structopt::StructOpt;

#[derive(Debug, StructOpt)]
struct Opt {
#[structopt(min_values = 1)]
argv: Vec<String>,

#[structopt(short, long)]
quiet: bool,
}

#[cfg(target_os = "windows")]
fn main() -> Result<()> {
let opt = Opt::from_args();

let exe = &opt.argv[0];
let mut cmd = Command::new(exe);

if let Some(args) = opt.argv.get(1..) {
cmd.args(args);
}

if opt.quiet {
cmd.stdout(Stdio::null());
cmd.stderr(Stdio::null());
}

let missing = dynamic_library::windows::find_missing(cmd)?;

if missing.is_empty() {
println!("no missing libraries");
} else {
for lib in missing {
println!("missing library: {:x?}", lib);
}
}

Ok(())
}

#[cfg(target_os = "linux")]
fn main() -> Result<()> {
todo!()
}

#[cfg(target_os = "macos")]
fn main() -> Result<()> {
todo!()
}
5 changes: 5 additions & 0 deletions src/agent/dynamic-library/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

#[cfg(target_os = "windows")]
pub mod windows;
Loading

0 comments on commit 9000a23

Please sign in to comment.