Ready for rust bindings release

This commit is contained in:
mio
2021-10-17 03:26:40 +02:00
parent 6d0d0897f8
commit a11cd9c43f
4 changed files with 34 additions and 35 deletions

View File

@ -1,7 +1,7 @@
[package] [package]
name = "unicorn" name = "unicorn-engine"
version = "1.0.0" version = "2.0.0-rc3"
authors = ["Lukas Seidel"] authors = ["Ziqiao Kong", "Lukas Seidel"]
documentation = "" documentation = ""
edition = "2018" edition = "2018"
include = [ include = [
@ -10,6 +10,7 @@ include = [
"/Cargo.toml", "/Cargo.toml",
"/README.md", "/README.md",
"/src/*", "/src/*",
"build.rs"
] ]
license = "GPL-2.0" license = "GPL-2.0"
readme = "README.md" readme = "README.md"

View File

@ -1,17 +1,17 @@
# unicorn-rs # Unicorn-engine
Rust bindings for the [Unicorn](http://www.unicorn-engine.org/) emulator with utility functions. Rust bindings for the [Unicorn](http://www.unicorn-engine.org/) emulator with utility functions.
An extended version for fuzzing with AFL++ support can be found in https://github.com/aflplusplus/unicornafl. Checkout Unicorn2 source code at [dev branch](https://github.com/unicorn-engine/unicorn/tree/dev).
```rust ```rust
use unicorn::RegisterARM; use unicorn_engine::RegisterARM;
use unicorn::unicorn_const::{Arch, Mode, Permission, SECOND_SCALE}; use unicorn_engine::unicorn_const::{Arch, Mode, Permission, SECOND_SCALE};
fn main() { fn main() {
let arm_code32: Vec<u8> = vec![0x17, 0x00, 0x40, 0xe2]; // sub r0, #23 let arm_code32: Vec<u8> = vec![0x17, 0x00, 0x40, 0xe2]; // sub r0, #23
let mut unicorn = unicorn::Unicorn::new(Arch::ARM, Mode::LITTLE_ENDIAN).expect("failed to initialize Unicorn instance"); let mut unicorn = unicorn-engine::Unicorn::new(Arch::ARM, Mode::LITTLE_ENDIAN).expect("failed to initialize Unicorn instance");
let mut emu = unicorn.borrow(); let mut emu = unicorn.borrow();
emu.mem_map(0x1000, 0x4000, Permission::ALL).expect("failed to map code page"); emu.mem_map(0x1000, 0x4000, Permission::ALL).expect("failed to map code page");
emu.mem_write(0x1000, &arm_code32).expect("failed to write instructions"); emu.mem_write(0x1000, &arm_code32).expect("failed to write instructions");
@ -26,20 +26,18 @@ fn main() {
``` ```
Further sample code can be found in ```tests/unicorn.rs```. Further sample code can be found in ```tests/unicorn.rs```.
## Installation ## Usage
This project has been tested on Linux, OS X and Windows. Add this to your `Cargo.toml`:
To use unicorn-rs, simply add it as a dependency to the Cargo.toml of your program.
``` ```
[dependencies] [dependencies]
unicorn = { path = "/path/to/bindings/rust", version="1.0.0" } unicorn-engine = "2.0.0-rc3"
``` ```
## Acknowledgements ## Acknowledgements
These bindings are based on Sébastien Duquette's (@ekse) [unicorn-rs](https://github.com/unicorn-rs/unicorn-rs). These bindings are based on Sébastien Duquette's (@ekse) [unicorn-rs](https://github.com/unicorn-rs/unicorn-rs).
We picked up the project, as it is no longer maintained. We picked up the project, as it is no longer maintained.
Thanks to all contributers. Thanks to all contributors.

View File

@ -6,13 +6,13 @@
//! //!
//! ```rust //! ```rust
//! //!
//! use unicorn::RegisterARM; //! use unicorn_engine::RegisterARM;
//! use unicorn::unicorn_const::{Arch, Mode, Permission, SECOND_SCALE}; //! use unicorn_engine::unicorn_const::{Arch, Mode, Permission, SECOND_SCALE};
//! //!
//! fn main() { //! fn main() {
//! let arm_code32: Vec<u8> = vec![0x17, 0x00, 0x40, 0xe2]; // sub r0, #23 //! let arm_code32: Vec<u8> = vec![0x17, 0x00, 0x40, 0xe2]; // sub r0, #23
//! //!
//! let mut unicorn = unicorn::Unicorn::new(Arch::ARM, Mode::LITTLE_ENDIAN).expect("failed to initialize Unicorn instance"); //! let mut unicorn = unicorn_engine::Unicorn::new(Arch::ARM, Mode::LITTLE_ENDIAN).expect("failed to initialize Unicorn instance");
//! let mut emu = unicorn.borrow(); //! let mut emu = unicorn.borrow();
//! emu.mem_map(0x1000, 0x4000, Permission::ALL).expect("failed to map code page"); //! emu.mem_map(0x1000, 0x4000, Permission::ALL).expect("failed to map code page");
//! emu.mem_write(0x1000, &arm_code32).expect("failed to write instructions"); //! emu.mem_write(0x1000, &arm_code32).expect("failed to write instructions");

View File

@ -1,7 +1,7 @@
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
use unicorn::unicorn_const::{uc_error, Arch, HookType, MemType, Mode, Permission, SECOND_SCALE}; use unicorn_engine::unicorn_const::{uc_error, Arch, HookType, MemType, Mode, Permission, SECOND_SCALE};
use unicorn::{InsnSysX86, RegisterARM, RegisterMIPS, RegisterPPC, RegisterX86}; use unicorn_engine::{InsnSysX86, RegisterARM, RegisterMIPS, RegisterPPC, RegisterX86};
pub static X86_REGISTERS: [RegisterX86; 125] = [ pub static X86_REGISTERS: [RegisterX86; 125] = [
RegisterX86::AH, RegisterX86::AH,
@ -131,13 +131,13 @@ pub static X86_REGISTERS: [RegisterX86; 125] = [
RegisterX86::R15W, RegisterX86::R15W,
]; ];
type Unicorn<'a> = unicorn::UnicornHandle<'a>; type Unicorn<'a> = unicorn_engine::UnicornHandle<'a>;
#[test] #[test]
fn emulate_x86() { fn emulate_x86() {
let x86_code32: Vec<u8> = vec![0x41, 0x4a]; // INC ecx; DEC edx let x86_code32: Vec<u8> = vec![0x41, 0x4a]; // INC ecx; DEC edx
let mut unicorn = unicorn::Unicorn::new(Arch::X86, Mode::MODE_32) let mut unicorn = unicorn_engine::Unicorn::new(Arch::X86, Mode::MODE_32)
.expect("failed to initialize unicorn instance"); .expect("failed to initialize unicorn instance");
let mut emu = unicorn.borrow(); let mut emu = unicorn.borrow();
assert_eq!(emu.reg_write(RegisterX86::EAX as i32, 123), Ok(())); assert_eq!(emu.reg_write(RegisterX86::EAX as i32, 123), Ok(()));
@ -188,7 +188,7 @@ fn x86_code_callback() {
let x86_code32: Vec<u8> = vec![0x41, 0x4a]; // INC ecx; DEC edx let x86_code32: Vec<u8> = vec![0x41, 0x4a]; // INC ecx; DEC edx
let mut unicorn = unicorn::Unicorn::new(Arch::X86, Mode::MODE_32) let mut unicorn = unicorn_engine::Unicorn::new(Arch::X86, Mode::MODE_32)
.expect("failed to initialize unicorn instance"); .expect("failed to initialize unicorn instance");
let mut emu = unicorn.borrow(); let mut emu = unicorn.borrow();
assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(())); assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(()));
@ -219,7 +219,7 @@ fn x86_intr_callback() {
let x86_code32: Vec<u8> = vec![0xcd, 0x80]; // INT 0x80; let x86_code32: Vec<u8> = vec![0xcd, 0x80]; // INT 0x80;
let mut unicorn = unicorn::Unicorn::new(Arch::X86, Mode::MODE_32) let mut unicorn = unicorn_engine::Unicorn::new(Arch::X86, Mode::MODE_32)
.expect("failed to initialize unicorn instance"); .expect("failed to initialize unicorn instance");
let mut emu = unicorn.borrow(); let mut emu = unicorn.borrow();
assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(())); assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(()));
@ -274,7 +274,7 @@ fn x86_mem_callback() {
0xB8, 0xEF, 0xBE, 0xAD, 0xDE, 0xA3, 0x00, 0x20, 0x00, 0x00, 0xA1, 0x00, 0x00, 0x01, 0x00, 0xB8, 0xEF, 0xBE, 0xAD, 0xDE, 0xA3, 0x00, 0x20, 0x00, 0x00, 0xA1, 0x00, 0x00, 0x01, 0x00,
]; ];
let mut unicorn = unicorn::Unicorn::new(Arch::X86, Mode::MODE_32) let mut unicorn = unicorn_engine::Unicorn::new(Arch::X86, Mode::MODE_32)
.expect("failed to initialize unicorn instance"); .expect("failed to initialize unicorn instance");
let mut emu = unicorn.borrow(); let mut emu = unicorn.borrow();
assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(())); assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(()));
@ -312,7 +312,7 @@ fn x86_insn_in_callback() {
let x86_code32: Vec<u8> = vec![0xe5, 0x10]; // IN eax, 0x10; let x86_code32: Vec<u8> = vec![0xe5, 0x10]; // IN eax, 0x10;
let mut unicorn = unicorn::Unicorn::new(Arch::X86, Mode::MODE_32) let mut unicorn = unicorn_engine::Unicorn::new(Arch::X86, Mode::MODE_32)
.expect("failed to initialize unicorn instance"); .expect("failed to initialize unicorn instance");
let mut emu = unicorn.borrow(); let mut emu = unicorn.borrow();
assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(())); assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(()));
@ -349,7 +349,7 @@ fn x86_insn_out_callback() {
let x86_code32: Vec<u8> = vec![0xb0, 0x32, 0xe6, 0x46]; // MOV al, 0x32; OUT 0x46, al; let x86_code32: Vec<u8> = vec![0xb0, 0x32, 0xe6, 0x46]; // MOV al, 0x32; OUT 0x46, al;
let mut unicorn = unicorn::Unicorn::new(Arch::X86, Mode::MODE_32) let mut unicorn = unicorn_engine::Unicorn::new(Arch::X86, Mode::MODE_32)
.expect("failed to initialize unicorn instance"); .expect("failed to initialize unicorn instance");
let mut emu = unicorn.borrow(); let mut emu = unicorn.borrow();
assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(())); assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(()));
@ -391,7 +391,7 @@ fn x86_insn_sys_callback() {
0x48, 0xB8, 0xEF, 0xBE, 0xAD, 0xDE, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x05, 0x48, 0xB8, 0xEF, 0xBE, 0xAD, 0xDE, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x05,
]; ];
let mut unicorn = unicorn::Unicorn::new(Arch::X86, Mode::MODE_64) let mut unicorn = unicorn_engine::Unicorn::new(Arch::X86, Mode::MODE_64)
.expect("failed to initialize unicorn instance"); .expect("failed to initialize unicorn instance");
let mut emu = unicorn.borrow(); let mut emu = unicorn.borrow();
assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(())); assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(()));
@ -418,7 +418,7 @@ fn x86_insn_sys_callback() {
fn emulate_arm() { fn emulate_arm() {
let arm_code32: Vec<u8> = vec![0x83, 0xb0]; // sub sp, #0xc let arm_code32: Vec<u8> = vec![0x83, 0xb0]; // sub sp, #0xc
let mut unicorn = unicorn::Unicorn::new(Arch::ARM, Mode::THUMB) let mut unicorn = unicorn_engine::Unicorn::new(Arch::ARM, Mode::THUMB)
.expect("failed to initialize unicorn instance"); .expect("failed to initialize unicorn instance");
let mut emu = unicorn.borrow(); let mut emu = unicorn.borrow();
assert_eq!(emu.reg_write(RegisterARM::R1 as i32, 123), Ok(())); assert_eq!(emu.reg_write(RegisterARM::R1 as i32, 123), Ok(()));
@ -459,7 +459,7 @@ fn emulate_arm() {
fn emulate_mips() { fn emulate_mips() {
let mips_code32 = vec![0x56, 0x34, 0x21, 0x34]; // ori $at, $at, 0x3456; let mips_code32 = vec![0x56, 0x34, 0x21, 0x34]; // ori $at, $at, 0x3456;
let mut unicorn = unicorn::Unicorn::new(Arch::MIPS, Mode::MODE_32) let mut unicorn = unicorn_engine::Unicorn::new(Arch::MIPS, Mode::MODE_32)
.expect("failed to initialize unicorn instance"); .expect("failed to initialize unicorn instance");
let mut emu = unicorn.borrow(); let mut emu = unicorn.borrow();
assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(())); assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(()));
@ -485,7 +485,7 @@ fn emulate_mips() {
fn emulate_ppc() { fn emulate_ppc() {
let ppc_code32 = vec![0x7F, 0x46, 0x1A, 0x14]; // add 26, 6, 3 let ppc_code32 = vec![0x7F, 0x46, 0x1A, 0x14]; // add 26, 6, 3
let mut unicorn = unicorn::Unicorn::new(Arch::PPC, Mode::PPC32 | Mode::BIG_ENDIAN) let mut unicorn = unicorn_engine::Unicorn::new(Arch::PPC, Mode::PPC32 | Mode::BIG_ENDIAN)
.expect("failed to initialize unicorn instance"); .expect("failed to initialize unicorn instance");
let mut emu = unicorn.borrow(); let mut emu = unicorn.borrow();
assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(())); assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(()));
@ -510,7 +510,7 @@ fn emulate_ppc() {
#[test] #[test]
fn mem_unmapping() { fn mem_unmapping() {
let mut unicorn = unicorn::Unicorn::new(Arch::X86, Mode::MODE_32) let mut unicorn = unicorn_engine::Unicorn::new(Arch::X86, Mode::MODE_32)
.expect("failed to initialize unicorn instance"); .expect("failed to initialize unicorn instance");
let mut emu = unicorn.borrow(); let mut emu = unicorn.borrow();
assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(())); assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(()));
@ -523,7 +523,7 @@ fn mem_map_ptr() {
let mut mem: [u8; 4000] = [0; 4000]; let mut mem: [u8; 4000] = [0; 4000];
let x86_code32: Vec<u8> = vec![0x41, 0x4a]; // INC ecx; DEC edx let x86_code32: Vec<u8> = vec![0x41, 0x4a]; // INC ecx; DEC edx
let mut unicorn = unicorn::Unicorn::new(Arch::X86, Mode::MODE_32) let mut unicorn = unicorn_engine::Unicorn::new(Arch::X86, Mode::MODE_32)
.expect("failed to initialize unicorn instance"); .expect("failed to initialize unicorn instance");
let mut emu = unicorn.borrow(); let mut emu = unicorn.borrow();
@ -603,7 +603,7 @@ fn x86_context_save_and_restore() {
0x48, 0xB8, 0xEF, 0xBE, 0xAD, 0xDE, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x05, 0x48, 0xB8, 0xEF, 0xBE, 0xAD, 0xDE, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x05,
]; ];
let mut unicorn = let mut unicorn =
unicorn::Unicorn::new(Arch::X86, mode).expect("failed to initialize unicorn instance"); unicorn_engine::Unicorn::new(Arch::X86, mode).expect("failed to initialize unicorn instance");
let mut emu = unicorn.borrow(); let mut emu = unicorn.borrow();
assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(())); assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(()));
assert_eq!(emu.mem_write(0x1000, &x86_code), Ok(())); assert_eq!(emu.mem_write(0x1000, &x86_code), Ok(()));
@ -620,7 +620,7 @@ fn x86_context_save_and_restore() {
/* and create a new emulator, into which we will "restore" that context */ /* and create a new emulator, into which we will "restore" that context */
let mut unicorn2 = let mut unicorn2 =
unicorn::Unicorn::new(Arch::X86, mode).expect("failed to initialize unicorn instance"); unicorn_engine::Unicorn::new(Arch::X86, mode).expect("failed to initialize unicorn instance");
let emu2 = unicorn2.borrow(); let emu2 = unicorn2.borrow();
assert_eq!(emu2.context_restore(&context), Ok(())); assert_eq!(emu2.context_restore(&context), Ok(()));
for register in X86_REGISTERS.iter() { for register in X86_REGISTERS.iter() {
@ -649,7 +649,7 @@ fn x86_block_callback() {
let x86_code32: Vec<u8> = vec![0x41, 0x4a]; // INC ecx; DEC edx let x86_code32: Vec<u8> = vec![0x41, 0x4a]; // INC ecx; DEC edx
let mut unicorn = unicorn::Unicorn::new(Arch::X86, Mode::MODE_32) let mut unicorn = unicorn_engine::Unicorn::new(Arch::X86, Mode::MODE_32)
.expect("failed to initialize unicorn instance"); .expect("failed to initialize unicorn instance");
let mut emu = unicorn.borrow(); let mut emu = unicorn.borrow();
assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(())); assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(()));