Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Cranelift dependency in headcrab_inject #140

Merged
merged 1 commit into from
Apr 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions headcrab_inject/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ readme = "../README.md"

[dependencies]
headcrab = { version = "0.2.0", path = "../" }
cranelift-codegen = "0.66.0"
cranelift-reader = "0.66.0"
cranelift-module = "0.66.0"
cranelift-codegen = "0.82.3"
cranelift-reader = "0.82.3"
cranelift-module = "0.82.3"
libc = "0.2.76"
target-lexicon = "0.10.0"

Expand Down
6 changes: 5 additions & 1 deletion headcrab_inject/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,12 @@ pub fn target_isa() -> Box<dyn TargetIsa> {
let mut flag_builder = settings::builder();
flag_builder.set("use_colocated_libcalls", "false").unwrap();
let flags = settings::Flags::new(flag_builder);

// TODO: better error handling
isa::lookup("x86_64".parse().unwrap())
.unwrap()
.finish(flags)
.unwrap()
}

fn parse_func_or_data(s: &str) -> FuncOrDataId {
Expand Down Expand Up @@ -108,7 +111,8 @@ pub fn inject_clif_code(
let flags = settings::Flags::new(flag_builder);
let isa = isa::lookup("x86_64".parse().unwrap())
.unwrap()
.finish(flags);
.finish(flags)
.unwrap();

let functions = cranelift_reader::parse_functions(code).unwrap();
let mut ctx = cranelift_codegen::Context::new();
Expand Down
52 changes: 3 additions & 49 deletions headcrab_inject/src/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,20 +95,12 @@ impl<'a> InjectionModule<'a> {

pub fn compile_clif_code(&mut self, isa: &dyn TargetIsa, ctx: &mut Context) -> CrabResult<()> {
let mut code_mem = Vec::new();
let mut relocs = VecRelocSink::default();

ctx.compile_and_emit(
isa,
&mut code_mem,
&mut relocs,
&mut binemit::NullTrapSink {},
&mut binemit::NullStackmapSink {},
)
.unwrap();
ctx.compile_and_emit(isa, &mut code_mem).unwrap();

let code_region = self.inj_ctx.allocate_code(code_mem.len() as u64, None)?;

for reloc_entry in relocs.0.drain(..) {
for reloc_entry in ctx.mach_compile_result.as_ref().unwrap().buffer.relocs() {
let sym = match reloc_entry.name {
ir::ExternalName::User {
namespace: 0,
Expand All @@ -120,7 +112,7 @@ impl<'a> InjectionModule<'a> {
} => self.lookup_data_object(DataId::from_u32(index)),
_ => todo!("{:?}", reloc_entry.name),
};
match reloc_entry.reloc {
match reloc_entry.kind {
binemit::Reloc::Abs8 => {
code_mem[reloc_entry.offset as usize..reloc_entry.offset as usize + 8]
.copy_from_slice(&u64::to_ne_bytes(
Expand Down Expand Up @@ -154,41 +146,3 @@ impl<'a> InjectionModule<'a> {
Ok(())
}
}

#[derive(Debug)]
struct RelocEntry {
offset: binemit::CodeOffset,
reloc: binemit::Reloc,
name: ir::ExternalName,
addend: binemit::Addend,
}

#[derive(Default)]
struct VecRelocSink(Vec<RelocEntry>);

impl binemit::RelocSink for VecRelocSink {
fn reloc_block(&mut self, _: binemit::CodeOffset, _: binemit::Reloc, _: binemit::CodeOffset) {
todo!()
}
fn reloc_external(
&mut self,
offset: binemit::CodeOffset,
_: ir::SourceLoc,
reloc: binemit::Reloc,
name: &ir::ExternalName,
addend: binemit::Addend,
) {
self.0.push(RelocEntry {
offset,
reloc,
name: name.clone(),
addend,
});
}
fn reloc_constant(&mut self, _: binemit::CodeOffset, _: binemit::Reloc, _: ir::ConstantOffset) {
todo!()
}
fn reloc_jt(&mut self, _: binemit::CodeOffset, _: binemit::Reloc, _: ir::entities::JumpTable) {
todo!()
}
}
24 changes: 14 additions & 10 deletions headcrab_inject/tests/inject_abort.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ mod test_utils;
#[cfg(target_os = "linux")]
use cranelift_module::FuncId;
#[cfg(target_os = "linux")]
use headcrab::{symbol::RelocatedDwarf, target::UnixTarget};
use headcrab::{
symbol::RelocatedDwarf,
target::{Registers, UnixTarget},
};
#[cfg(target_os = "linux")]
use headcrab_inject::InjectionModule;
#[cfg(target_os = "linux")]
Expand Down Expand Up @@ -61,18 +64,19 @@ fn inject_abort() -> headcrab::CrabResult<()> {
run_function, stack_region
);

let orig_regs = inj_module.target().read_regs()?;
println!("orig rip: {:016x}", orig_regs.rip);
let regs = libc::user_regs_struct {
rip: run_function,
rsp: stack_region + 0x1000,
..orig_regs
};
inj_module.target().write_regs(regs)?;
let orig_regs = inj_module.target().main_thread()?.read_regs()?;
println!("orig rip: {:016x}", orig_regs.ip());

let mut regs = orig_regs.clone();
regs.set_ip(run_function);
regs.set_sp(stack_region + 0x1000);

inj_module.target().main_thread()?.write_regs(regs)?;

let res = inj_module.target().unpause()?;
if let WaitStatus::Stopped(_, Signal::SIGABRT) = res {
} else {
println!("rip: {:016x}", inj_module.target().read_regs()?.rip);
println!("rip: {:016x}", inj_module.target().read_regs()?.ip());
panic!("{:?}", res);
}

Expand Down