Skip to content

Commit ec24513

Browse files
authored
Add RISC-V support to libafl_unicorn (#3134)
1 parent 8426ba5 commit ec24513

File tree

7 files changed

+41
-7
lines changed

7 files changed

+41
-7
lines changed

.github/workflows/fuzzer-tester-prepare/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ runs:
1212
with: { shared-key: "${{ runner.os }}-shared-fuzzer-cache" }
1313
- name: Install fuzzers deps
1414
shell: bash
15-
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
15+
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
1616
- name: enable mult-thread for `make`
1717
shell: bash
1818
run: export MAKEFLAGS="-j$(expr $(nproc) \+ 1)"

Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ RUN apt-get update && \
4848
gcc-i686-linux-gnu \
4949
gcc-mipsel-linux-gnu \
5050
gcc-powerpc-linux-gnu \
51+
gcc-riscv64-linux-gnu \
5152
gdb \
5253
gdb-multiarch \
5354
git \

fuzzers/full_system/unicorn/Justfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ build_bin:
2020

2121
[linux]
2222
[macos]
23-
test: fuzzer build_bin (test_single "arm") (test_single "arm64") (test_single "x86")
23+
test: fuzzer build_bin (test_single "arm") (test_single "arm64") (test_single "riscv64") (test_single "x86")
2424
echo "Done"
2525

2626
test_single arch="arm":

fuzzers/full_system/unicorn/bin/Justfile

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
arm64 := "aarch64-linux-gnu"
22
arm := "arm-linux-gnueabihf"
3+
riscv64 := "riscv64-linux-gnu"
34
x64 := "x86_64-linux-gnu"
45

56
assembly_arm64:
@@ -16,6 +17,13 @@ binary_arm:
1617
{{arm}}-as foo_arm.s -o foo_arm.elf
1718
{{arm}}-objcopy -O binary foo_arm.elf foo_arm.bin
1819

20+
assembly_riscv64:
21+
{{riscv64}}-gcc -O2 -S -c foo.c -o foo_riscv64.s
22+
23+
binary_riscv64:
24+
{{riscv64}}-as foo_riscv64.s -o foo_riscv64.elf
25+
{{riscv64}}-objcopy -O binary -j .text.startup foo_riscv64.elf foo_riscv64.bin
26+
1927
assembly_x86:
2028
{{x64}}-gcc -O2 -S -c foo.c -o foo_x86.s
2129

@@ -26,11 +34,12 @@ binary_x86:
2634

2735
build_arm: assembly_arm binary_arm
2836
build_arm64: assembly_arm64 binary_arm64
37+
build_riscv64: assembly_riscv64 binary_riscv64
2938
build_x86: assembly_x86 binary_x86
3039

3140
clean:
3241
rm foo_*
3342

3443

35-
all: build_arm build_arm64 build_x86
36-
# sudo apt install gcc-arm-linux-gnueabihf gcc-aarch64-linux-gnu
44+
all: build_arm build_arm64 build_riscv64 build_x86
45+
# sudo apt install gcc-arm-linux-gnueabihf gcc-aarch64-linux-gnu gcc-riscv64-linux-gnu

fuzzers/full_system/unicorn/src/main.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ use libafl_unicorn::{
3636
use unicorn_engine::{unicorn_const::MemType, HookType};
3737
use unicorn_engine::{
3838
unicorn_const::{Arch, SECOND_SCALE},
39-
Mode, Permission, RegisterARM, RegisterARM64, RegisterX86, Unicorn,
39+
Mode, Permission, RegisterARM, RegisterARM64, RegisterRISCV, RegisterX86, Unicorn,
4040
};
4141

4242
pub const CODE_ADDRESS: u64 = 0x9000;
@@ -64,6 +64,7 @@ fn main() {
6464
let arch = match args[1].as_str() {
6565
"arm" => Arch::ARM,
6666
"arm64" => Arch::ARM64,
67+
"riscv64" => Arch::RISCV,
6768
"x86" => Arch::X86,
6869
_ => {
6970
panic!("This arcghitecture is not supported")
@@ -86,6 +87,10 @@ pub fn init_registers(emu: &mut Unicorn<()>, sp: u64) {
8687
emu.reg_write(RegisterARM64::SP, sp)
8788
.expect("Could not setup register");
8889
}
90+
Arch::RISCV => {
91+
emu.reg_write(RegisterRISCV::SP, sp)
92+
.expect("Could not setup register");
93+
}
8994
Arch::X86 => {
9095
emu.reg_write(RegisterX86::ESP, sp)
9196
.expect("Could not setup register");
@@ -99,6 +104,7 @@ fn fuzzer(should_emulate: bool, arch: Arch) {
99104
let mode = match arch {
100105
Arch::ARM => Mode::ARM,
101106
Arch::ARM64 => Mode::ARM926,
107+
Arch::RISCV => Mode::RISCV64,
102108
Arch::X86 => Mode::MODE_64,
103109
_ => Mode::MODE_64,
104110
};
@@ -112,6 +118,7 @@ fn fuzzer(should_emulate: bool, arch: Arch) {
112118
match arch {
113119
Arch::ARM => "bin/foo_arm.bin",
114120
Arch::ARM64 => "bin/foo_arm64.bin",
121+
Arch::RISCV => "bin/foo_riscv64.bin",
115122
Arch::X86 => "bin/foo_x86.bin",
116123
_ => "",
117124
},
@@ -191,6 +198,7 @@ fn fuzzer(should_emulate: bool, arch: Arch) {
191198
match arch {
192199
Arch::ARM => emu.reg_write(RegisterARM::LR, RETURN_ADDRESS).unwrap(),
193200
Arch::ARM64 => emu.reg_write(RegisterARM64::LR, RETURN_ADDRESS).unwrap(),
201+
Arch::RISCV => emu.reg_write(RegisterRISCV::RA, RETURN_ADDRESS).unwrap(),
194202
Arch::X86 => {
195203
let bytes = u64::to_le_bytes(RETURN_ADDRESS);
196204

@@ -213,6 +221,7 @@ fn fuzzer(should_emulate: bool, arch: Arch) {
213221
let result_value = match arch {
214222
Arch::ARM => emu.reg_read(RegisterARM::R0).unwrap(),
215223
Arch::ARM64 => emu.reg_read(RegisterARM64::W0).unwrap(),
224+
Arch::RISCV => emu.reg_read(RegisterRISCV::A0).unwrap(),
216225
Arch::X86 => emu.reg_read(RegisterX86::EAX).unwrap(),
217226
_ => 0,
218227
};

libafl_unicorn/src/emu.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use capstone::{
44
};
55
pub use libafl_targets::{EDGES_MAP, EDGES_MAP_PTR};
66
use unicorn_engine::{
7-
RegisterARM, RegisterARM64, RegisterX86, Unicorn,
7+
RegisterARM, RegisterARM64, RegisterRISCV, RegisterX86, Unicorn,
88
unicorn_const::{Arch, Permission},
99
};
1010

@@ -57,6 +57,14 @@ pub fn debug_print(emu: &Unicorn<()>, thumb_mode: bool) {
5757
log::debug!("X2: {:X}", emu.reg_read(RegisterARM64::X2).unwrap());
5858
log::debug!("X3: {:X}", emu.reg_read(RegisterARM64::X3).unwrap());
5959
}
60+
Arch::RISCV => {
61+
log::debug!("SP: {:X}", emu.reg_read(RegisterRISCV::SP).unwrap());
62+
log::debug!("RA: {:X}", emu.reg_read(RegisterRISCV::RA).unwrap());
63+
log::debug!("GP: {:X}", emu.reg_read(RegisterRISCV::GP).unwrap());
64+
log::debug!("TP: {:X}", emu.reg_read(RegisterRISCV::TP).unwrap());
65+
log::debug!("A0: {:X}", emu.reg_read(RegisterRISCV::A0).unwrap());
66+
log::debug!("A1: {:X}", emu.reg_read(RegisterRISCV::A1).unwrap());
67+
}
6068
Arch::X86 => {
6169
log::debug!("ESP: {:X}", emu.reg_read(RegisterX86::ESP).unwrap());
6270
log::debug!("RAX: {:X}", emu.reg_read(RegisterX86::RAX).unwrap());
@@ -100,6 +108,12 @@ pub fn debug_print(emu: &Unicorn<()>, thumb_mode: bool) {
100108
.detail(true)
101109
.build()
102110
.expect("Failed to create Capstone object"),
111+
Arch::RISCV => Capstone::new()
112+
.riscv()
113+
.mode(arch::riscv::ArchMode::RiscV64)
114+
.detail(true)
115+
.build()
116+
.expect("Failed to create Capstone object"),
103117

104118
_ => Capstone::new()
105119
.x86()

libafl_unicorn/src/helper.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
use unicorn_engine::{RegisterARM, RegisterARM64, RegisterX86, unicorn_const::Arch};
1+
use unicorn_engine::{RegisterARM, RegisterARM64, RegisterRISCV, RegisterX86, unicorn_const::Arch};
22

33
pub fn get_stack_pointer(emu: &unicorn_engine::Unicorn<()>) -> u64 {
44
match emu.get_arch() {
55
Arch::ARM => emu.reg_read(RegisterARM::SP).unwrap(),
66
Arch::ARM64 => emu.reg_read(RegisterARM64::SP).unwrap(),
7+
Arch::RISCV => emu.reg_read(RegisterRISCV::SP).unwrap(),
78
Arch::X86 => emu.reg_read(RegisterX86::ESP).unwrap(),
89
_ => 0,
910
}

0 commit comments

Comments
 (0)