Add RISC-V support to libafl_unicorn (#3134)
This commit is contained in:
parent
8426ba5d58
commit
ec24513c95
@ -12,7 +12,7 @@ runs:
|
||||
with: { shared-key: "${{ runner.os }}-shared-fuzzer-cache" }
|
||||
- name: Install fuzzers deps
|
||||
shell: bash
|
||||
run: sudo apt-get update && sudo apt-get install -y nasm nlohmann-json3-dev gcc-aarch64-linux-gnu g++-aarch64-linux-gnu gcc-mipsel-linux-gnu g++-mipsel-linux-gnu gcc-powerpc-linux-gnu g++-powerpc-linux-gnu libc6-dev-i386-cross libc6-dev libc6-dev-i386 lib32gcc-11-dev lib32stdc++-11-dev libgtk-3-dev pax-utils python3-msgpack python3-jinja2
|
||||
run: sudo apt-get update && sudo apt-get install -y nasm nlohmann-json3-dev gcc-aarch64-linux-gnu g++-aarch64-linux-gnu gcc-mipsel-linux-gnu g++-mipsel-linux-gnu gcc-riscv64-linux-gnu gcc-powerpc-linux-gnu g++-powerpc-linux-gnu libc6-dev-i386-cross libc6-dev libc6-dev-i386 lib32gcc-11-dev lib32stdc++-11-dev libgtk-3-dev pax-utils python3-msgpack python3-jinja2
|
||||
- name: enable mult-thread for `make`
|
||||
shell: bash
|
||||
run: export MAKEFLAGS="-j$(expr $(nproc) \+ 1)"
|
||||
|
@ -48,6 +48,7 @@ RUN apt-get update && \
|
||||
gcc-i686-linux-gnu \
|
||||
gcc-mipsel-linux-gnu \
|
||||
gcc-powerpc-linux-gnu \
|
||||
gcc-riscv64-linux-gnu \
|
||||
gdb \
|
||||
gdb-multiarch \
|
||||
git \
|
||||
|
@ -20,7 +20,7 @@ build_bin:
|
||||
|
||||
[linux]
|
||||
[macos]
|
||||
test: fuzzer build_bin (test_single "arm") (test_single "arm64") (test_single "x86")
|
||||
test: fuzzer build_bin (test_single "arm") (test_single "arm64") (test_single "riscv64") (test_single "x86")
|
||||
echo "Done"
|
||||
|
||||
test_single arch="arm":
|
||||
|
@ -1,5 +1,6 @@
|
||||
arm64 := "aarch64-linux-gnu"
|
||||
arm := "arm-linux-gnueabihf"
|
||||
riscv64 := "riscv64-linux-gnu"
|
||||
x64 := "x86_64-linux-gnu"
|
||||
|
||||
assembly_arm64:
|
||||
@ -16,6 +17,13 @@ binary_arm:
|
||||
{{arm}}-as foo_arm.s -o foo_arm.elf
|
||||
{{arm}}-objcopy -O binary foo_arm.elf foo_arm.bin
|
||||
|
||||
assembly_riscv64:
|
||||
{{riscv64}}-gcc -O2 -S -c foo.c -o foo_riscv64.s
|
||||
|
||||
binary_riscv64:
|
||||
{{riscv64}}-as foo_riscv64.s -o foo_riscv64.elf
|
||||
{{riscv64}}-objcopy -O binary -j .text.startup foo_riscv64.elf foo_riscv64.bin
|
||||
|
||||
assembly_x86:
|
||||
{{x64}}-gcc -O2 -S -c foo.c -o foo_x86.s
|
||||
|
||||
@ -26,11 +34,12 @@ binary_x86:
|
||||
|
||||
build_arm: assembly_arm binary_arm
|
||||
build_arm64: assembly_arm64 binary_arm64
|
||||
build_riscv64: assembly_riscv64 binary_riscv64
|
||||
build_x86: assembly_x86 binary_x86
|
||||
|
||||
clean:
|
||||
rm foo_*
|
||||
|
||||
|
||||
all: build_arm build_arm64 build_x86
|
||||
# sudo apt install gcc-arm-linux-gnueabihf gcc-aarch64-linux-gnu
|
||||
all: build_arm build_arm64 build_riscv64 build_x86
|
||||
# sudo apt install gcc-arm-linux-gnueabihf gcc-aarch64-linux-gnu gcc-riscv64-linux-gnu
|
||||
|
@ -36,7 +36,7 @@ use libafl_unicorn::{
|
||||
use unicorn_engine::{unicorn_const::MemType, HookType};
|
||||
use unicorn_engine::{
|
||||
unicorn_const::{Arch, SECOND_SCALE},
|
||||
Mode, Permission, RegisterARM, RegisterARM64, RegisterX86, Unicorn,
|
||||
Mode, Permission, RegisterARM, RegisterARM64, RegisterRISCV, RegisterX86, Unicorn,
|
||||
};
|
||||
|
||||
pub const CODE_ADDRESS: u64 = 0x9000;
|
||||
@ -64,6 +64,7 @@ fn main() {
|
||||
let arch = match args[1].as_str() {
|
||||
"arm" => Arch::ARM,
|
||||
"arm64" => Arch::ARM64,
|
||||
"riscv64" => Arch::RISCV,
|
||||
"x86" => Arch::X86,
|
||||
_ => {
|
||||
panic!("This arcghitecture is not supported")
|
||||
@ -86,6 +87,10 @@ pub fn init_registers(emu: &mut Unicorn<()>, sp: u64) {
|
||||
emu.reg_write(RegisterARM64::SP, sp)
|
||||
.expect("Could not setup register");
|
||||
}
|
||||
Arch::RISCV => {
|
||||
emu.reg_write(RegisterRISCV::SP, sp)
|
||||
.expect("Could not setup register");
|
||||
}
|
||||
Arch::X86 => {
|
||||
emu.reg_write(RegisterX86::ESP, sp)
|
||||
.expect("Could not setup register");
|
||||
@ -99,6 +104,7 @@ fn fuzzer(should_emulate: bool, arch: Arch) {
|
||||
let mode = match arch {
|
||||
Arch::ARM => Mode::ARM,
|
||||
Arch::ARM64 => Mode::ARM926,
|
||||
Arch::RISCV => Mode::RISCV64,
|
||||
Arch::X86 => Mode::MODE_64,
|
||||
_ => Mode::MODE_64,
|
||||
};
|
||||
@ -112,6 +118,7 @@ fn fuzzer(should_emulate: bool, arch: Arch) {
|
||||
match arch {
|
||||
Arch::ARM => "bin/foo_arm.bin",
|
||||
Arch::ARM64 => "bin/foo_arm64.bin",
|
||||
Arch::RISCV => "bin/foo_riscv64.bin",
|
||||
Arch::X86 => "bin/foo_x86.bin",
|
||||
_ => "",
|
||||
},
|
||||
@ -191,6 +198,7 @@ fn fuzzer(should_emulate: bool, arch: Arch) {
|
||||
match arch {
|
||||
Arch::ARM => emu.reg_write(RegisterARM::LR, RETURN_ADDRESS).unwrap(),
|
||||
Arch::ARM64 => emu.reg_write(RegisterARM64::LR, RETURN_ADDRESS).unwrap(),
|
||||
Arch::RISCV => emu.reg_write(RegisterRISCV::RA, RETURN_ADDRESS).unwrap(),
|
||||
Arch::X86 => {
|
||||
let bytes = u64::to_le_bytes(RETURN_ADDRESS);
|
||||
|
||||
@ -213,6 +221,7 @@ fn fuzzer(should_emulate: bool, arch: Arch) {
|
||||
let result_value = match arch {
|
||||
Arch::ARM => emu.reg_read(RegisterARM::R0).unwrap(),
|
||||
Arch::ARM64 => emu.reg_read(RegisterARM64::W0).unwrap(),
|
||||
Arch::RISCV => emu.reg_read(RegisterRISCV::A0).unwrap(),
|
||||
Arch::X86 => emu.reg_read(RegisterX86::EAX).unwrap(),
|
||||
_ => 0,
|
||||
};
|
||||
|
@ -4,7 +4,7 @@ use capstone::{
|
||||
};
|
||||
pub use libafl_targets::{EDGES_MAP, EDGES_MAP_PTR};
|
||||
use unicorn_engine::{
|
||||
RegisterARM, RegisterARM64, RegisterX86, Unicorn,
|
||||
RegisterARM, RegisterARM64, RegisterRISCV, RegisterX86, Unicorn,
|
||||
unicorn_const::{Arch, Permission},
|
||||
};
|
||||
|
||||
@ -57,6 +57,14 @@ pub fn debug_print(emu: &Unicorn<()>, thumb_mode: bool) {
|
||||
log::debug!("X2: {:X}", emu.reg_read(RegisterARM64::X2).unwrap());
|
||||
log::debug!("X3: {:X}", emu.reg_read(RegisterARM64::X3).unwrap());
|
||||
}
|
||||
Arch::RISCV => {
|
||||
log::debug!("SP: {:X}", emu.reg_read(RegisterRISCV::SP).unwrap());
|
||||
log::debug!("RA: {:X}", emu.reg_read(RegisterRISCV::RA).unwrap());
|
||||
log::debug!("GP: {:X}", emu.reg_read(RegisterRISCV::GP).unwrap());
|
||||
log::debug!("TP: {:X}", emu.reg_read(RegisterRISCV::TP).unwrap());
|
||||
log::debug!("A0: {:X}", emu.reg_read(RegisterRISCV::A0).unwrap());
|
||||
log::debug!("A1: {:X}", emu.reg_read(RegisterRISCV::A1).unwrap());
|
||||
}
|
||||
Arch::X86 => {
|
||||
log::debug!("ESP: {:X}", emu.reg_read(RegisterX86::ESP).unwrap());
|
||||
log::debug!("RAX: {:X}", emu.reg_read(RegisterX86::RAX).unwrap());
|
||||
@ -100,6 +108,12 @@ pub fn debug_print(emu: &Unicorn<()>, thumb_mode: bool) {
|
||||
.detail(true)
|
||||
.build()
|
||||
.expect("Failed to create Capstone object"),
|
||||
Arch::RISCV => Capstone::new()
|
||||
.riscv()
|
||||
.mode(arch::riscv::ArchMode::RiscV64)
|
||||
.detail(true)
|
||||
.build()
|
||||
.expect("Failed to create Capstone object"),
|
||||
|
||||
_ => Capstone::new()
|
||||
.x86()
|
||||
|
@ -1,9 +1,10 @@
|
||||
use unicorn_engine::{RegisterARM, RegisterARM64, RegisterX86, unicorn_const::Arch};
|
||||
use unicorn_engine::{RegisterARM, RegisterARM64, RegisterRISCV, RegisterX86, unicorn_const::Arch};
|
||||
|
||||
pub fn get_stack_pointer(emu: &unicorn_engine::Unicorn<()>) -> u64 {
|
||||
match emu.get_arch() {
|
||||
Arch::ARM => emu.reg_read(RegisterARM::SP).unwrap(),
|
||||
Arch::ARM64 => emu.reg_read(RegisterARM64::SP).unwrap(),
|
||||
Arch::RISCV => emu.reg_read(RegisterRISCV::SP).unwrap(),
|
||||
Arch::X86 => emu.reg_read(RegisterX86::ESP).unwrap(),
|
||||
_ => 0,
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user