// src/cargo/core/manifest.rs// Information about a binary, a library, an example, etc. that is// part of the package.pubstructTarget {
inner: Arc<TargetInner>,
}
structTargetInner {
kind: TargetKind,
name: String,
// Note that `bin_name` is used for the cargo-feature `different_binary_name`// Some(..)ならば、[[bin]]でバイナリ名が指定されている// Noneならば、バイナリ名が指定されていない
bin_name: Option<String>,
// Note that the `src_path` here is excluded from the `Hash` implementation// as it's absolute currently and is otherwise a little too brittle for// causing rebuilds. Instead the hash for the path that we send to the// compiler is handled elsewhere.
src_path: TargetSourcePath,
required_features: Option<Vec<String>>,
tested: bool,
benched: bool,
doc: bool,
doctest: bool,
harness: bool, // whether to use the test harness (--test)
for_host: bool,
proc_macro: bool,
edition: Edition,
}
pubenumTargetKind {
Lib(Vec<CrateType>),
Bin,
Test,
Bench,
ExampleLib(Vec<CrateType>),
ExampleBin,
CustomBuild,
}
pubfnbin_target(
name: &str,
bin_name: Option<String>,
src_path: PathBuf,
required_features: Option<Vec<String>>,
edition: Edition,
) -> Target {
...
}
impl Target {
...
// バイナリの名前を返すメソッドpubfnbinary_filename(&self) ->Option<String> {
self.inner.bin_name.clone()
}
// バイナリの名前をセットするメソッドpubfnset_binary_name(&mutself, bin_name: Option<String>) ->&mut Target {
Arc::make_mut(&mutself.inner).bin_name = bin_name;
self
}
...
}
// src/cargo/core/compiler/build_context/target_info.rs/// The filename for this FileType that Cargo should use when "uplifting"/// it to the destination directory.pubfnuplift_filename(&self, target: &Target) ->String {
let name =match target.binary_filename() {
// [[bin]]でバイナリの名前が指定されているのでそれを使うSome(name) => name,
// パッケージ名をバイナリの名前に使うNone=> {
// For binary crate type, `should_replace_hyphens` will always be false.// 名前に含まれるハイフンを処理するifself.should_replace_hyphens {
target.crate_name()
} else {
target.name().to_string()
}
}
};
format!("{}{}{}", self.prefix, name, self.suffix)
}
// src/cargo/core/compiler/context/compilation_files.rsimpl<'a, 'cfg:'a> CompilationFiles<'a, 'cfg> {
...
/// Returns the path where the output for the given unit and FileType/// should be uplifted to.////// Returns `None` if the unit shouldn't be uplifted (for example, a/// dependent rlib).fnuplift_to(&self, unit: &Unit, file_type: &FileType, from_path: &Path) ->Option<PathBuf> {
...
}
// rustcによって作成されたファイル情報を出力する/// Computes the actual, full pathnames for all the files generated by rustc.////// The `OutputFile` also contains the paths where those files should be/// "uplifted" to.fncalc_outputs_rustc(
&self,
unit: &Unit,
bcx: &BuildContext<'a, 'cfg>,
) -> CargoResult<Vec<OutputFile>> {
...
// Convert FileType to OutputFile.letmut outputs =Vec::new();
for file_type in file_types {
let meta =&self.metas[unit];
let meta_opt = meta.use_extra_filename.then(|| meta.meta_hash.to_string());
let path = out_dir.join(file_type.output_filename(&unit.target, meta_opt.as_deref()));
// ハードリンクで参照する名前を取得// If, the `different_binary_name` feature is enabled, the name of the hardlink will// be the name of the binary provided by the user in `Cargo.toml`.let hardlink =self.uplift_to(unit, &file_type, &path);
let export_path =if unit.target.is_custom_build() {
None
} else {
self.export_dir.as_ref().and_then(|export_dir| {
hardlink
.as_ref()
.map(|hardlink| export_dir.join(hardlink.file_name().unwrap()))
})
};
outputs.push(OutputFile {
path,
hardlink,
export_path,
flavor: file_type.flavor,
});
}
Ok(outputs)
}
...
}
cargoが最終的に生成するOutputFile構造体はこんな感じで定義されている。
// src/cargo/core/compiler/context/compilation_files.rspubstructOutputFile {
/// Absolute path to the file that will be produced by the build process.pub path: PathBuf,
/// If it should be linked into `target`, and what it should be called/// (e.g., without metadata).pub hardlink: Option<PathBuf>,
/// If `--out-dir` is specified, the absolute path to the exported file.pub export_path: Option<PathBuf>,
/// Type of the file (library / debug symbol / else).pub flavor: FileFlavor,
}
上で述べたように、Shadow StackとIBTはそれぞれ、ROPとJOP/COPの対策になっている。ここで、CETがオンのときの攻撃方法について考えてみる。ROP/COP/JOPはスタックBOFなどでリターンアドレスを書き換えることを攻撃の起点としている。つまり、プログラマが意図していないコードブロックの遷移はCETによって対策されるということである。そのため、RIPを奪うことはとても難しくなったと考えられる。一方でUse after Freeなどにより変数を書き換えることに対しては防衛策がないので、そのようなメモリの書き換えを起点とした攻撃の研究がより盛んになると思う。
pc@surface-pro-3:~/pwn/csaw2013$ ./exploit2
Got a connection from 127.0.0.1 on port 33280
$ ls
e2.py exploit2.id0 exploit2.id2 exploit2.til miteegashun
exploit2 exploit2.id1 exploit2.nam fil_chal
$
Oops! RSP is misaligned!
Some functions such as `system` use `movaps` instructions in libc-2.27 and later.
This instruction fails when RSP is not a multiple of 0x10.
Find a way to align RSP! You're almost there!