Skip to content

Commit

Permalink
0.2 (#2)
Browse files Browse the repository at this point in the history
* this is a continuation of the pullrequest for pdb_wrapper (#1)

* update dependency versions

* load rva from fakepdb json

* add arg that allows passing clang args

* link the new arg into the code

* make bao compilable by providing an env var

* crash and burn only if we detect an actual error

* pull in the data from the pdb section if it exists

* rewrote parts to be more concise.

* add features to bao and wrap the pdb generation inside of a feature controlled function

* have a default return value if it fails to access the needed debug information

* implement some clippy recomendations

* correctly implement the feature

* start_rva is usize

* correctly setup rng rand

* Make the code more idiomatic, TODO: fix dependency link

* add code to get symbol location from rva_start

* revert the lib change

* update git with working link

* update git with working link

Co-authored-by: noah the goodra <peterpan0413@live.com>
Co-authored-by: jan <not-wlan@protonmail.com>

* 0.2 release, rename binary to bao-pdb for publishing

Co-authored-by: Jordan Francis Moran-Meyers <69991101+jfm535@users.noreply.github.com>
Co-authored-by: noah the goodra <peterpan0413@live.com>
  • Loading branch information
3 people committed Jul 25, 2021
1 parent 87d8c69 commit 984163e
Show file tree
Hide file tree
Showing 8 changed files with 216 additions and 106 deletions.
188 changes: 120 additions & 68 deletions Cargo.lock

Large diffs are not rendered by default.

27 changes: 20 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
[package]
name = "bao"
version = "0.1.0"
name = "bao-pdb"
version = "0.2.0"
authors = ["jan"]
edition = "2018"
build = "build.rs"
license = "Unlicense"
description = "bao-pdb can be used to generate PDB files from existing applications."
homepage = "https://github.com/not-wlan/bao"
repository = "https://github.com/not-wlan/bao"
readme = "README.md"

[dependencies]
snafu = "0.6.9"
Expand All @@ -13,18 +19,25 @@ serde_derive = "1.0"
simplelog = "0.8.0"
log = "~0.4"
clap = "2.33"
uuid = { version = "0.8", features = ["v4"] }

[dependencies.clang-sys]
version = "1.0.1"
features = ["clang_10_0"]
version = "1.2.0"
features = ["clang_11_0"]

[dependencies.pdb_wrapper]
git = "https://github.com/not-wlan/pdb_wrapper"
version = "0.2"
default-features = false

[dependencies.clang]
version = "~1.0"
version = "1.0.3"
features = ["clang_10_0"]

[dependencies.goblin]
version = "~0.2"
features = ["std"]
features = ["std"]

[features]
default = ["llvm_13"]
llvm_10 = ["pdb_wrapper/llvm_10"]
llvm_13 = ["pdb_wrapper/llvm_13"]
6 changes: 3 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ RUN printf "deb http://apt.llvm.org/buster/ llvm-toolchain-buster-10 main\ndeb-s
# Install dependencies
RUN apt-get update && apt-get install -y curl git make build-essential libllvm10 llvm-10 llvm-10-dev llvm-10-runtime \
cmake clang-10 clang-tools-10 libclang-common-10-dev libclang-10-dev libclang1-10 clang-format-10 gcc-multilib

RUN ln -s /usr/bin/llvm-config-10 /usr/bin/llvm-config
WORKDIR /app
COPY ./Cargo.toml .
COPY ./Cargo.lock .
COPY ./src/ /app/src/

COPY build.rs .
RUN cargo update -p pdb_wrapper && cargo install --path . --target-dir /app/bin

RUN ls -alh /app/bin/release
Expand All @@ -26,4 +26,4 @@ RUN bash -c "wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key|apt-key add -"
RUN printf "deb http://apt.llvm.org/buster/ llvm-toolchain-buster-10 main\ndeb-src http://apt.llvm.org/buster/ llvm-toolchain-buster-10 main" > /etc/apt/sources.list.d/backports.list
# Install dependencies
RUN apt-get update && apt-get install -y libllvm10 llvm-10-runtime libclang1-10 gcc-multilib
COPY --from=0 /app/bin/release/bao /usr/bin/
COPY --from=0 /app/bin/release/bao-pdb /usr/bin/
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ The easiest way to run _bao_ is to use [Docker](https://www.docker.com/):
~$ docker build . -t bao:latest
~$ docker run -v /path/to/project:/project -it bao:latest
#$ cd /project
#$ bao -o vac.pdb -c vac.json vac.dll structs.c
#$ bao-pdb -o vac.pdb -c vac.json vac.dll structs.c
```

The first three commands are only necessary on your first run or after an update of _bao_.
Expand Down
6 changes: 6 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
fn main() {
println!("If the build fails pass the llvm lib folder to env LLVMLIB_DIR");
if let Ok(name) = std::env::var("LLVMLIB_DIR") {
println!("cargo:rustc-link-search={}", name);
}
}
72 changes: 53 additions & 19 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::{
parsing::{BaoTU, BaoType},
pe::BaoPE,
};
use clang::diagnostic::Severity;
use clap::{App, Arg};
use log::{error, info, warn};
use simplelog::{CombinedLogger, Config, LevelFilter, TermLogger, TerminalMode};
Expand Down Expand Up @@ -58,6 +59,14 @@ pub fn main() -> Result<(), Box<dyn Error>> {
.required(true)
.index(2),
)
.arg(
Arg::with_name("coptions")
.short("d")
.long("coptions")
.required(false)
.multiple(true)
.takes_value(true),
)
.get_matches();

// Unwrapping these is fine since they're marked as required.
Expand Down Expand Up @@ -95,25 +104,50 @@ pub fn main() -> Result<(), Box<dyn Error>> {
let clang = Clang::new()?;
let index = Index::new(&clang, false, false);

let tu = BaoTU::from(
index
.parser(source)
.arguments(if pe.is_64 {
&["-Werror"]
} else {
&["-m32", "-Werror"]
})
.parse()?,
);
let mut args = matches
.values_of("coptions")
.map(|values| {
values
.map(|value| value.replace('\"', ""))
.collect::<Vec<_>>()
})
.unwrap_or_default();

if !pe.is_64 {
args.push(String::from("-m32"));
}

let tu = BaoTU::from(index.parser(source).arguments(&args).parse()?);

let mut generated = pdb_wrapper::PDB::new(false)?;
#[cfg(not(feature = "llvm_13"))]
let mut generated = pdb_wrapper::PDB::new(pe.is_64)?;

#[cfg(feature = "llvm_13")]
let mut generated = {
let guid = pe
.debug_data
.and_then(|dbg| dbg.codeview_pdb70_debug_info)
.map(|code_view| code_view.signature)
.unwrap_or_else(|| *uuid::Uuid::new_v4().as_bytes());

pdb_wrapper::PDB::new(pe.is_64, 1, 0, guid)
}?;

if tu.has_errors() {
for error in tu.get_diagnostics() {
error!("{}", error);
}
let has_errors = tu
.get_diagnostics()
.iter()
.any(|diag| diag.get_severity() > Severity::Warning);

tu.get_diagnostics()
.iter()
.for_each(|err| error!("{}", err));

info!("Please fix these errors before continuing!");
return Ok(());

if has_errors {
return Ok(());
}
}

let funcs = tu.get_entities(EntityKind::FunctionDecl);
Expand All @@ -139,7 +173,7 @@ pub fn main() -> Result<(), Box<dyn Error>> {
// aren't included in a pattern.
let func_types = funcs
.into_iter()
.map(|func| BaoFunc::try_from(func))
.map(BaoFunc::try_from)
.collect::<Result<Vec<_>, BaoError>>()?
.into_iter()
.map(|func| {
Expand All @@ -158,7 +192,7 @@ pub fn main() -> Result<(), Box<dyn Error>> {
.map(|(ty, result)| {
generated
.insert_function(result.index, result.offset, &result.name, ty.cloned())
.map_err(|e| BaoError::from(e))
.map_err(BaoError::from)
})
.collect::<Result<_, BaoError>>()?;

Expand All @@ -178,7 +212,7 @@ pub fn main() -> Result<(), Box<dyn Error>> {
.map(|(ty, result)| {
generated
.insert_global(&result.name, result.index, result.offset, ty)
.map_err(|e| BaoError::from(e))
.map_err(BaoError::from)
})
.collect::<Result<_, BaoError>>()?;

Expand All @@ -188,6 +222,6 @@ pub fn main() -> Result<(), Box<dyn Error>> {
warnings.into_iter().for_each(|err| warn!("{}", err));

// Finally, save the generated PDB to the path we calculated in the beginning
generated.commit(&path, &output)?;
generated.commit(path, &output)?;
Ok(())
}
7 changes: 6 additions & 1 deletion src/matching.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ use std::convert::TryInto;
#[derive(Serialize, Deserialize, Debug)]
pub(crate) struct BaoSymbol {
pub(crate) name: String,
#[serde(default)]
pub(crate) pattern: String,
#[serde(default)]
pub(crate) start_rva:usize,
#[serde(default)]
extra: isize,
#[serde(default)]
pub offsets: Vec<isize>,
Expand All @@ -30,7 +33,9 @@ fn add_signed(first: usize, second: isize) -> Option<usize> {
impl BaoSymbol {
pub fn find(&self, data: &[u8], imagebase: usize) -> Result<(usize, bool), BaoError> {
let mut va = false;

if self.start_rva != 0 {
return Ok((self.start_rva + imagebase, true));
}
let peek_bytes = |offset| -> Result<u32, BaoError> {
let bfr: &[u8; 4] =
&data[offset..offset + 4]
Expand Down
14 changes: 7 additions & 7 deletions src/parsing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,18 @@ pub(crate) struct BaoFunc {
pub(crate) cconv: CConv,
}

impl Into<PDBFunction> for BaoFunc {
fn into(self) -> PDBFunction {
PDBFunction::new(self.retn, &self.args, self.cconv)
impl From<BaoFunc> for PDBFunction {
fn from(s: BaoFunc) -> PDBFunction {
PDBFunction::new(s.retn, &s.args, s.cconv)
}
}

#[derive(Debug)]
pub(crate) struct BaoType(PDBType);

impl Into<PDBType> for BaoType {
fn into(self) -> PDBType {
self.0
impl From<BaoType> for PDBType {
fn from(s:BaoType) -> PDBType {
s.0
}
}

Expand Down Expand Up @@ -195,7 +195,7 @@ impl<'tu> TryFrom<Type<'tu>> for BaoFunc {
function: value.get_display_name(),
})?
.into_iter()
.map(|ty| BaoType::try_from(ty))
.map(BaoType::try_from)
.map(|ty| ty.map(|ty| ty.into()))
.collect::<Result<Vec<PDBType>, BaoError>>()?;

Expand Down

0 comments on commit 984163e

Please sign in to comment.