Skip to content

Commit

Permalink
Merge pull request headcrab-rs#140 from nbaksalyar/update-clif
Browse files Browse the repository at this point in the history
Update Cranelift dependency in headcrab_inject
  • Loading branch information
nbaksalyar authored Apr 12, 2022
2 parents c735f86 + 0fa5658 commit 5a420c5
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 63 deletions.
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

0 comments on commit 5a420c5

Please sign in to comment.