GithubHelp home page GithubHelp logo

unicorn-rs's Issues

Benchmarking the bindings

I remember @lunixbochs mention his go bindings were posting a 20x speedup compared to python (quoting from memory) so recreating the benchmark in unicorn-rs should make for an interesting comparison and provide some more testing.

If the benchmark is to be found somewhere, that is :)

"improper_ctypes" Build warning

Complete warning:

src/ffi.rs:37:36: 37:59 warning: found non-foreign-function-safe member in struct marked #[repr(C)]: found struct without foreign-function-safe representation annotation in foreign module, consider adding a #[repr(C)] attribute to the type, #[warn(improper_ctypes)] on by default
src/ffi.rs:37                           regions: *const *const MemRegion,
                                                 ^~~~~~~~~~~~~~~~~~~~~~~

Seems to come from the Protection bitflags that doesn't take the #[repr(C)] attribute as expected. I've got isra17@3eae40b that you might want to cherry-pick.

I want to find a maintainer

Hi @ekse , I would like to find another maintainer. In the meantime, you could
handle the ownership of this crate to me. At least I could merge the bug fix PR
if there are any.

If you want direct conversation, look for me on Rust Discord (@lzutao).

Test fails on ARM

$ RUST_BACKTRACE=1  target/debug/examples/test 
version : 1.0
Support for:
         x86: true
         arm: true
         mips: true
page size : 4096
thread '<main>' panicked at 'failed to query hardware mode: ARG', src/libcore/result.rs:746
stack backtrace:
   1: 0xb6f70eff - std::sys::backtrace::tracing::imp::write::hf68f1a220b61702c
                at src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:40
   2: 0xb6f74443 - std::panicking::default_hook::_$u7b$$u7b$closure$u7d$$u7d$::hb638acea7c29901b
                at src/libstd/panicking.rs:178
   3: 0xb6f73b13 - std::panicking::default_hook::h508c3dab3df347d6
                at src/libstd/panicking.rs:193
   4: 0xb6f6d84b - std::panicking::on_panic::h3a6e649f33b132c3
                at src/libstd/panicking.rs:227
   5: 0xb6f4fd6b - std::sys_common::unwind::begin_unwind_inner::h17f9e42de6d55309
                at src/libstd/sys/common/unwind/mod.rs:237
   6: 0xb6f526bb - std::sys_common::unwind::begin_unwind_fmt::h039d18bd8498e1d0
                at src/libstd/sys/common/unwind/mod.rs:202
   7: 0xb6f6d21b - rust_begin_unwind
                at src/libstd/sys/common/unwind/mod.rs:179
   8: 0xb6f814a7 - core::panicking::panic_fmt::h813eaa27a5810609
                at src/libcore/panicking.rs:69
   9: 0xb6f46fa7 - core::result::unwrap_failed::h419bc270f6772dcb
                at src/libcore/macros.rs:29
  10: 0xb6f47117 - _<std..result..Result<T, E>>::expect::he67c7df582d2e1e0
                at src/libcore/result.rs:708
  11: 0xb6f4673f - test::main::h1ef728500ff2f89b
                at examples/test.rs:17
  12: 0xb6f73323 - fn()::fn_pointer_shim.32839::ha52fbbed76ed0ca0
  13: 0xb6f73127 - std::panic::recover::_$u7b$$u7b$closure$u7d$$u7d$::he74338885f2bd0e2
                at src/libstd/panic.rs:318
  14: 0xb6f730f7 - std::sys_common::unwind::try::try_fn::h0f540c0db5f980f7
                at src/libstd/sys/common/unwind/mod.rs:127

rustc 1.9.0-dev (470ca1c3f 2016-04-07)

Can't build unicorn on Linux

After commit 1bdbb75, I can't build unicorn on Linux. I have installed unicorn library in my system, which is the one unicorn-rs uses before that commit. But after that change, when I try to build it, it fails. Here you have some information:

$ cargo build --verbose   # Just after that commit...
    Updating registry `https://github.com/rust-lang/crates.io-index`
   Compiling gcc v0.3.43
   Compiling libc v0.2.20
   Compiling bitflags v0.6.0
     Running `rustc /home/jmi2k/.cargo/registry/src/github.com-1ecc6299db9ec823/gcc-0.3.43/src/lib.rs --crate-name gcc --crate-type lib -g -C metadata=be7b7587fd240ec9 -C extra-filename=-be7b7587fd240ec9 --out-dir /home/jmi2k/tmp/unicorn-rs/target/debug/deps --emit=dep-info,link -L dependency=/home/jmi2k/tmp/unicorn-rs/target/debug/deps --cap-lints allow`
     Running `rustc /home/jmi2k/.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.20/src/lib.rs --crate-name libc --crate-type lib -g --cfg feature=\"use_std\" --cfg feature=\"default\" -C metadata=29ef97a68464c2b7 -C extra-filename=-29ef97a68464c2b7 --out-dir /home/jmi2k/tmp/unicorn-rs/target/debug/deps --emit=dep-info,link -L dependency=/home/jmi2k/tmp/unicorn-rs/target/debug/deps --cap-lints allow`
     Running `rustc /home/jmi2k/.cargo/registry/src/github.com-1ecc6299db9ec823/bitflags-0.6.0/src/lib.rs --crate-name bitflags --crate-type lib -g -C metadata=b8c7fb7df9b2bc2e -C extra-filename=-b8c7fb7df9b2bc2e --out-dir /home/jmi2k/tmp/unicorn-rs/target/debug/deps --emit=dep-info,link -L dependency=/home/jmi2k/tmp/unicorn-rs/target/debug/deps --cap-lints allow`
   Compiling libunicorn-sys v0.4.0 (file:///home/jmi2k/tmp/unicorn-rs/libunicorn-sys)
     Running `rustc libunicorn-sys/build.rs --crate-name build_script_build --crate-type bin -g -C metadata=1b1fea3559201b39 --out-dir /home/jmi2k/tmp/unicorn-rs/target/debug/build/libunicorn-sys-1b1fea3559201b39 --emit=dep-info,link -L dependency=/home/jmi2k/tmp/unicorn-rs/target/debug/deps --extern gcc=/home/jmi2k/tmp/unicorn-rs/target/debug/deps/libgcc-be7b7587fd240ec9.rlib`
     Running `/home/jmi2k/tmp/unicorn-rs/target/debug/build/libunicorn-sys-1b1fea3559201b39/build-script-build`
     Running `rustc libunicorn-sys/src/lib.rs --crate-name libunicorn_sys --crate-type lib -g -C metadata=1b1fea3559201b39 --out-dir /home/jmi2k/tmp/unicorn-rs/target/debug/deps --emit=dep-info,link -L dependency=/home/jmi2k/tmp/unicorn-rs/target/debug/deps --extern bitflags=/home/jmi2k/tmp/unicorn-rs/target/debug/deps/libbitflags-b8c7fb7df9b2bc2e.rlib --extern libc=/home/jmi2k/tmp/unicorn-rs/target/debug/deps/liblibc-29ef97a68464c2b7.rlib -L native=/home/jmi2k/tmp/unicorn-rs/target/debug/build/libunicorn-sys-1b1fea3559201b39/out -l static=unicorn`
error: could not find native static library `unicorn`, perhaps an -L flag is missing?

error: Could not compile `libunicorn-sys`.

Caused by:
  process didn't exit successfully: `rustc libunicorn-sys/src/lib.rs --crate-name libunicorn_sys --crate-type lib -g -C metadata=1b1fea3559201b39 --out-dir /home/jmi2k/tmp/unicorn-rs/target/debug/deps --emit=dep-info,link -L dependency=/home/jmi2k/tmp/unicorn-rs/target/debug/deps --extern bitflags=/home/jmi2k/tmp/unicorn-rs/target/debug/deps/libbitflags-b8c7fb7df9b2bc2e.rlib --extern libc=/home/jmi2k/tmp/unicorn-rs/target/debug/deps/liblibc-29ef97a68464c2b7.rlib -L native=/home/jmi2k/tmp/unicorn-rs/target/debug/build/libunicorn-sys-1b1fea3559201b39/out -l static=unicorn` (exit code: 101)

More details:

  • cargo version 0.15.0
  • rustc version 1.14.0
  • unicorn version 0.9

My system is pretty exotic, but I tried in an Arch chroot and it still happens. If you need more details, I can test it in a VM next week.

Potential unsafe in boxed hooks

Hello all,

Beside of "natural" unsafe on FFI boundary, there are still some "potential" unsafe, IMHO. For example, in add_code_hook https://github.com/ekse/unicorn-rs/blob/6aca2c329c4d221c655f111e06a71720b778b8e5/src/lib.rs#L715-L718

In boxing self (by remove it's lifetime using raw pointer), there is a "potential" unsafe because self can be moved (and then possibly reallocated). But in the current binding, we forbid the reallocation by using boxed Unicorn everywhere (so self is never reallocated by moving)
https://github.com/ekse/unicorn-rs/blob/6aca2c329c4d221c655f111e06a71720b778b8e5/src/lib.rs#L443-L452

The consequence is that we cannot have a stack-allocated Unicorn: any Unicorn is a pinned object.

Since the raw Unicorn handle is a movable raw pointer, IMHO it's possible to have a "non-box" binding, but it may break the current design.

Many thanks for any comment.

unable to install it on osx

Hi there,

I know this project is only tested on linux but as everything should work on OSX, I gave it a try. Unfortunately it did not compile and people on users.rust.com were unable to help me so before I dig deep into the rust code, I wanted to know whether you can image what the problem is. So here is what I did:

  1. I addunicorn = "0.4.1" as dependency
  2. I run cargo run --verbose but I get the following error:
$ cargo run --verbose
       Fresh libc v0.2.20
       Fresh bitflags v0.6.0
       Fresh gcc v0.3.41
       Fresh byteorder v1.0.0
   Compiling libunicorn-sys v0.4.0
     Running `rustc /Users/$username/.cargo/registry/src/github.com-1ecc6299db9ec823/libunicorn-sys-0.4.0/lib.rs --crate-name libunicorn_sys \
--crate-type lib -g -C metadata=271778d4aa553e9c -C extra-filename=-271778d4aa553e9c --out-dir \
/Users/$username/dev/$project/target/debug/deps --emit=dep-info,link -L \
dependency=/Users/$username/dev/$project/target/debug/deps --extern \
libc=/Users/$username/dev/$project/target/debug/deps/liblibc-29ef97a68464c2b7.rlib --extern \
bitflags=/Users/$username/dev/$project/target/debug/deps/libbitflags-b8c7fb7df9b2bc2e.rlib --cap-lints allow -L \
native=/Users/$username/dev/$project/target/debug/build/libunicorn-sys-fe33b86568c508cb/out -l static=unicorn`

error: failed to add native library /Users/$user/dev/$project/target/debug/build/libunicorn-sys-fe33b86568c508cb/out/libunicorn.a: failed to open archive

error: Could not compile `libunicorn-sys`.

Caused by:
  process didn't exit successfully: `rustc /Users/$user/.cargo/registry/src/github.com-1ecc6299db9ec823/libunicorn-sys-0.4.0/lib.rs --crate-name libunicorn_sys --crate-type lib -g -C metadata=271778d4aa553e9c -C extra-filename=-271778d4aa553e9c --out-dir /Users/$user/dev/$project/target/debug/deps --emit=dep-info,link -L dependency=/Users/$user/dev/$project/target/debug/deps --extern libc=/Users/$user/dev/$project/target/debug/deps/liblibc-29ef97a68464c2b7.rlib --extern bitflags=/Users/$user/dev/$project/target/debug/deps/libbitflags-b8c7fb7df9b2bc2e.rlib --cap-lints allow -L native=/Users/$user/dev/$project/target/debug/build/libunicorn-sys-fe33b86568c508cb/out -l static=unicorn` (exit code: 101)
  1. The file libunicorn.a exists and file reveals the following:
$ file /Users/$username/dev/$project/target/debug/build/libunicorn-sys-fe33b86568c508cb/out/libunicorn.a
/Users/$username/dev/$project/target/debug/build/libunicorn-sys-fe33b86568c508cb/out/libunicorn.a: Mach-O universal binary with 2 architectures: [x86_64: current ar archive random library] [i386]
/Users/$username/dev/$project/target/debug/build/libunicorn-sys-fe33b86568c508cb/out/libunicorn.a (for architecture x86_64):	current ar archive random library
/Users/$username/dev/$project/target/debug/build/libunicorn-sys-fe33b86568c508cb/out/libunicorn.a (for architecture i386):	current ar archive random library

I assume the error gets thrown here but if possible I would like to avoid digging there. RUST_BACKTRACE=1 does not reveal more information.
4. my versions:

$ rustc --version
rustc 1.14.0
$ cargo --version
cargo 0.15.0-dev (298a012 2016-12-20)

By looking at your files, it does not look like that you are doing any linux specific things, but maybe I did not see it. One thing I suspect is that rustc expects a linux .a and not an osx .a, but according to the documentation, rustc should also work on osx. I am happy to fix this bug and file a merge request afterwards, but I do not know where to start.

Broken documentation

The example should probably look more like this (renamings etc - never mind the main vs. test):

    use unicorn::{Unicorn, Arch, Mode, Protection, RegisterX86, SECOND_SCALE};
    #[test]
    fn it_works() {
        let x86_code32 : Vec<u8> = vec![0x41, 0x4a]; // INC ecx; DEC edx

        let mut emu = Unicorn::new(Arch::X86, Mode::MODE_32).expect("failed to instantiate emulator");
        emu.mem_map(0x1000, 0x4000, Protection::PROT_ALL); 
        emu.mem_write(0x1000, &x86_code32); 
        emu.reg_write_i32(RegisterX86::ECX as i32, -10);
        emu.reg_write_i32(RegisterX86::EDX as i32, -50);

        emu.emu_start(0x1000, (0x1000 + x86_code32.len()) as u64, 10 * SECOND_SCALE, 1000);
        assert_eq!(emu.reg_read_i32(RegisterX86::ECX as i32), Ok((-9)));
        assert_eq!(emu.reg_read_i32(RegisterX86::EDX as i32), Ok((-51)));
    }

Thinner wrapper for Unicorn

I still do not understand why the struct

https://github.com/ekse/unicorn-rs/blob/4814a4f41db825c8123905006e71ffa2761a34d5/src/lib.rs#L380-L389

needs to store callbacks. Indeed, I've removed them, the code still compiles but tests fail :(

Are there reasons for the existence of these callback maps? I think that they might help to keep the lifetime of callback closures? (if "yes", why isn't the compiler able to detect the problem when I remove them)

Many thanks for any response.

fix vswhere problem

please use follow arguments to run vswhere, or libunicorn-sys will not build when only install Visual Studio BuildTools

libunicorn-sys-0.9.1, build.rs, ln 11
let vswhere_output = Command::new(r"build_tools\vswhere.exe")
.args(&[
"-latest",
"-products",
"*",
"-property",
"installationPath"])
.output()
.expect("failed to execute vswhere.exe");

Tracing/logging?

use std::path::Path;
use pelite::{FileMap};
use pelite::pe64::{Pe, PeFile};
use unicorn::{Cpu, CpuX86};

fn round_to_multiple(numToRound: u64, multiple: u64) -> u64 {
    if (multiple == 0) {
        return numToRound;
    }
    let remainder = numToRound % multiple;
    if (remainder == 0) {
        return numToRound;
    }
    return numToRound + multiple - remainder;
}

fn main() {
  // emulator
  let mut emu = CpuX86::new(unicorn::Mode::MODE_64).unwrap();
  // parse PE
  let mut args = std::env::args();
  let filename = args.nth(1).unwrap();
  let path = Path::new(&filename);
  let map = FileMap::open(path).unwrap();
  let file = PeFile::from_bytes(&map).unwrap();
  let optional_header = file.optional_header();
  println!("{:02x?}", optional_header);
  let image_base = optional_header.ImageBase;
  for section in file.section_headers() {
    let section_va = image_base + section.VirtualAddress as u64;
    println!("{:02x?}", section);
    println!("{:08x}", section_va);
    let rounded_virtual_size = round_to_multiple(section.VirtualSize as u64, 4096);
    emu.mem_map(section_va, rounded_virtual_size as usize, unicorn::Protection::ALL).unwrap();
    if (section.SizeOfRawData > 0) {
      let section_bytes = file.get_section_bytes(&section).unwrap();
      emu.mem_write(section_va, &section_bytes).unwrap();
    }
  }
  let imports = file.imports().unwrap();
  for desc in imports {
    let iat = desc.iat().unwrap();
    let int = desc.int().unwrap();
    for (va, import) in Iterator::zip(iat, int) {
      println!("{:?} {:02x?} {:?}", desc, va, import);
    }
  }
  let va_entry = optional_header.ImageBase + optional_header.AddressOfEntryPoint as u64;
  emu.emu_start(
    va_entry,
    optional_header.ImageBase + (optional_header.AddressOfEntryPoint as u64) + 4,
    0,
    0
  ).unwrap();
}
IMAGE_OPTIONAL_HEADER64 { Magic: 20b, LinkerVersion: "14.0", SizeOfCode: a09a00, SizeOfInitializedData: 2081c00, SizeOfUninitializedData: 00, AddressOfEntryPoint: 4901722, BaseOfCode: 1000, ImageBase: 14000
0000, SectionAlignment: 1000, FileAlignment: 200, OperatingSystemVersion: "6.0", ImageVersion: "0.0", SubsystemVersion: "6.0", Win32VersionValue: 00, SizeOfImage: 50a4000, SizeOfHeaders: 400, CheckSum: 00, 
Subsystem: 02, DllCharacteristics: 8120, SizeOfStackReserve: 100000, SizeOfStackCommit: 1000, SizeOfHeapReserve: 100000, SizeOfHeapCommit: 1000, LoaderFlags: 00, NumberOfRvaAndSizes: 10, DataDirectory: [] }
SectionHeader { Name: ".text", VirtualAddress: 0x1000, VirtualSize: 0xa098b6, PointerToRawData: 0x0, SizeOfRawData: 0x0, Characteristics: 0x60000020 }
140001000
SectionHeader { Name: ".rdata", VirtualAddress: 0xa0b000, VirtualSize: 0x1f60058, PointerToRawData: 0x0, SizeOfRawData: 0x0, Characteristics: 0x40000040 }
140a0b000
SectionHeader { Name: ".data", VirtualAddress: 0x296c000, VirtualSize: 0x5aae4, PointerToRawData: 0x0, SizeOfRawData: 0x0, Characteristics: 0xc0000040 }
14296c000
SectionHeader { Name: ".pdata", VirtualAddress: 0x29c7000, VirtualSize: 0x38da8, PointerToRawData: 0x0, SizeOfRawData: 0x0, Characteristics: 0x40000040 }
1429c7000
SectionHeader { Name: ".qtmetad", VirtualAddress: 0x2a00000, VirtualSize: 0x536, PointerToRawData: 0x0, SizeOfRawData: 0x0, Characteristics: 0x40000040 }
142a00000
SectionHeader { Name: ".qtmimed", VirtualAddress: 0x2a01000, VirtualSize: 0x4ece5, PointerToRawData: 0x0, SizeOfRawData: 0x0, Characteristics: 0x40000040 }
142a01000
SectionHeader { Name: ".tls", VirtualAddress: 0x2a50000, VirtualSize: 0x18, PointerToRawData: 0x0, SizeOfRawData: 0x0, Characteristics: 0xc0000040 }
142a50000
SectionHeader { Name: ".jPc0", VirtualAddress: 0x2a51000, VirtualSize: 0x524792, PointerToRawData: 0x0, SizeOfRawData: 0x0, Characteristics: 0x60000020 }
142a51000
SectionHeader { Name: ".jPc1", VirtualAddress: 0x2f76000, VirtualSize: 0x1938, PointerToRawData: 0x400, SizeOfRawData: 0x1a00, Characteristics: 0xc0000040 }
142f76000
SectionHeader { Name: ".jPc2", VirtualAddress: 0x2f78000, VirtualSize: 0x20e804c, PointerToRawData: 0x1e00, SizeOfRawData: 0x20e8200, Characteristics: 0x68000060 }
142f78000
SectionHeader { Name: ".rsrc", VirtualAddress: 0x5061000, VirtualSize: 0x42bd8, PointerToRawData: 0x20ea000, SizeOfRawData: 0x42c00, Characteristics: 0x40000040 }
145061000
Imports { dll_name: Ok("KERNEL32.dll"), iat.len: Ok(1), int.len: Ok(1) } 3336408 Ok(ByName { hint: 0, name: "AcquireSRWLockExclusive" })
Imports { dll_name: Ok("api-ms-win-crt-heap-l1-1-0.dll"), iat.len: Ok(1), int.len: Ok(1) } 334fa7c Ok(ByName { hint: 0, name: "_aligned_free" })
Imports { dll_name: Ok("api-ms-win-crt-private-l1-1-0.dll"), iat.len: Ok(1), int.len: Ok(1) } 4e46904 Ok(ByName { hint: 0, name: "__intrinsic_setjmpex" })
Imports { dll_name: Ok("api-ms-win-crt-runtime-l1-1-0.dll"), iat.len: Ok(1), int.len: Ok(1) } 4941db6 Ok(ByName { hint: 0, name: "__p___argc" })
Imports { dll_name: Ok("api-ms-win-crt-stdio-l1-1-0.dll"), iat.len: Ok(1), int.len: Ok(1) } 492ac0e Ok(ByName { hint: 0, name: "__acrt_iob_func" })
Imports { dll_name: Ok("api-ms-win-crt-string-l1-1-0.dll"), iat.len: Ok(1), int.len: Ok(1) } 4e594cc Ok(ByName { hint: 0, name: "_isctype_l" })
Imports { dll_name: Ok("USER32.dll"), iat.len: Ok(1), int.len: Ok(1) } 48f1170 Ok(ByName { hint: 0, name: "AdjustWindowRectEx" })
Imports { dll_name: Ok("api-ms-win-crt-environment-l1-1-0.dll"), iat.len: Ok(1), int.len: Ok(1) } 48f6ac0 Ok(ByName { hint: 0, name: "__p__environ" })
Imports { dll_name: Ok("SHELL32.dll"), iat.len: Ok(1), int.len: Ok(1) } 48915e8 Ok(ByName { hint: 0, name: "CommandLineToArgvW" })
Imports { dll_name: Ok("ole32.dll"), iat.len: Ok(1), int.len: Ok(1) } 48e2d20 Ok(ByName { hint: 0, name: "CoCreateGuid" })
Imports { dll_name: Ok("api-ms-win-crt-math-l1-1-0.dll"), iat.len: Ok(1), int.len: Ok(1) } 490faa2 Ok(ByName { hint: 0, name: "__setusermatherr" })
Imports { dll_name: Ok("api-ms-win-crt-convert-l1-1-0.dll"), iat.len: Ok(1), int.len: Ok(1) } 335579a Ok(ByName { hint: 0, name: "_strtod_l" })
Imports { dll_name: Ok("api-ms-win-crt-time-l1-1-0.dll"), iat.len: Ok(1), int.len: Ok(1) } 3356172 Ok(ByName { hint: 0, name: "__daylight" })
Imports { dll_name: Ok("UxTheme.dll"), iat.len: Ok(1), int.len: Ok(1) } 49757a0 Ok(ByName { hint: 0, name: "CloseThemeData" })
Imports { dll_name: Ok("ADVAPI32.dll"), iat.len: Ok(1), int.len: Ok(1) } 33563a8 Ok(ByName { hint: 0, name: "AccessCheck" })
Imports { dll_name: Ok("NETAPI32.dll"), iat.len: Ok(1), int.len: Ok(1) } 4e582fe Ok(ByName { hint: 0, name: "NetApiBufferFree" })
Imports { dll_name: Ok("api-ms-win-crt-filesystem-l1-1-0.dll"), iat.len: Ok(1), int.len: Ok(1) } 49a4fac Ok(ByName { hint: 0, name: "_lock_file" })
Imports { dll_name: Ok("USERENV.dll"), iat.len: Ok(1), int.len: Ok(1) } 49812da Ok(ByName { hint: 0, name: "GetUserProfileDirectoryW" })
Imports { dll_name: Ok("api-ms-win-crt-utility-l1-1-0.dll"), iat.len: Ok(1), int.len: Ok(1) } 4e3a80a Ok(ByName { hint: 0, name: "bsearch" })
Imports { dll_name: Ok("VERSION.dll"), iat.len: Ok(1), int.len: Ok(1) } 48a76be Ok(ByName { hint: 0, name: "GetFileVersionInfoSizeW" })
Imports { dll_name: Ok("api-ms-win-crt-locale-l1-1-0.dll"), iat.len: Ok(1), int.len: Ok(1) } 4eadaf2 Ok(ByName { hint: 0, name: "___lc_codepage_func" })
Imports { dll_name: Ok("GDI32.dll"), iat.len: Ok(1), int.len: Ok(1) } 4e54c3e Ok(ByName { hint: 0, name: "AddFontMemResourceEx" })
Imports { dll_name: Ok("WS2_32.dll"), iat.len: Ok(1), int.len: Ok(1) } 48f2c4e Ok(ByName { hint: 0, name: "WSAAsyncSelect" })
Imports { dll_name: Ok("WINMM.dll"), iat.len: Ok(1), int.len: Ok(1) } 4e44ff2 Ok(ByName { hint: 0, name: "PlaySoundW" })
Imports { dll_name: Ok("WTSAPI32.dll"), iat.len: Ok(1), int.len: Ok(1) } 4906e6e Ok(ByName { hint: 0, name: "WTSFreeMemory" })
Imports { dll_name: Ok("IMM32.dll"), iat.len: Ok(1), int.len: Ok(1) } 4e2c998 Ok(ByName { hint: 0, name: "ImmAssociateContext" })
Imports { dll_name: Ok("dwmapi.dll"), iat.len: Ok(1), int.len: Ok(1) } 4e4086a Ok(ByName { hint: 0, name: "DwmEnableBlurBehindWindow" })
Imports { dll_name: Ok("api-ms-win-crt-multibyte-l1-1-0.dll"), iat.len: Ok(1), int.len: Ok(1) } 49863aa Ok(ByName { hint: 0, name: "_mbtowc_l" })
Imports { dll_name: Ok("OLEAUT32.dll"), iat.len: Ok(1), int.len: Ok(1) } 48f08aa Ok(ByName { hint: 0, name: "SafeArrayCreateVector" })
Imports { dll_name: Ok("KERNEL32.dll"), iat.len: Ok(1), int.len: Ok(1) } 4e595ca Ok(ByName { hint: 0, name: "GetSystemTimeAsFileTime" })
Imports { dll_name: Ok("USER32.dll"), iat.len: Ok(1), int.len: Ok(1) } 499c918 Ok(ByName { hint: 0, name: "CharUpperBuffW" })
Imports { dll_name: Ok("KERNEL32.dll"), iat.len: Ok(11), int.len: Ok(11) } 48ec4b0 Ok(ByName { hint: 0, name: "LocalAlloc" })
Imports { dll_name: Ok("KERNEL32.dll"), iat.len: Ok(11), int.len: Ok(11) } 494c6f6 Ok(ByName { hint: 0, name: "LocalFree" })
Imports { dll_name: Ok("KERNEL32.dll"), iat.len: Ok(11), int.len: Ok(11) } 333f566 Ok(ByName { hint: 0, name: "GetModuleFileNameW" })
Imports { dll_name: Ok("KERNEL32.dll"), iat.len: Ok(11), int.len: Ok(11) } 333cb80 Ok(ByName { hint: 0, name: "GetProcessAffinityMask" })
Imports { dll_name: Ok("KERNEL32.dll"), iat.len: Ok(11), int.len: Ok(11) } 48e52d4 Ok(ByName { hint: 0, name: "SetProcessAffinityMask" })
Imports { dll_name: Ok("KERNEL32.dll"), iat.len: Ok(11), int.len: Ok(11) } 495fd82 Ok(ByName { hint: 0, name: "SetThreadAffinityMask" })
Imports { dll_name: Ok("KERNEL32.dll"), iat.len: Ok(11), int.len: Ok(11) } 3341d1e Ok(ByName { hint: 0, name: "Sleep" })
Imports { dll_name: Ok("KERNEL32.dll"), iat.len: Ok(11), int.len: Ok(11) } 2f7f7c8 Ok(ByName { hint: 0, name: "ExitProcess" })
Imports { dll_name: Ok("KERNEL32.dll"), iat.len: Ok(11), int.len: Ok(11) } 333a9c2 Ok(ByName { hint: 0, name: "LoadLibraryA" })
Imports { dll_name: Ok("KERNEL32.dll"), iat.len: Ok(11), int.len: Ok(11) } 4e433ec Ok(ByName { hint: 0, name: "GetModuleHandleA" })
Imports { dll_name: Ok("KERNEL32.dll"), iat.len: Ok(11), int.len: Ok(11) } 495cd40 Ok(ByName { hint: 0, name: "GetProcAddress" })
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: WRITE_UNMAPPED', src\main.rs:63:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
error: process didn't exit successfully: `target\debug\pe32-emulator.exe C:\Users\Brandon\Desktop\foo.exe` (exit code: 101)

ARM Mode

Hey, thanks for doing this. It's a really useful project.
Is there a reason why UC_MODE_ARM isn't available as a Mode argument? It looks like it's been commented out in the enum listing. There seems to be a workaround -- just use LITTLE_ENDIAN as the mode argument -- but this seems unnecessarily convoluted. Maybe it would be better to just have modes as integer values, identified by global, static variables? Or strings that are translated by a hashtable into the integer/C-enum arguments needed by the engine?

error: could not find native static library `unicorn`, perhaps an -L flag is missing?

Referencing the unicorn crate as follows:

# Cargo.toml
# ...
[dependencies]
unicorn = { version = "0.9" }

Then attempting to build on Linux/amd64:

$ PYTHON=python2 cargo build --verbose

Fails as follows:

...
rustc --edition=2018 --crate-name libunicorn_sys .../.cargo/registry/src/github.com-1ecc6299db9ec823/libunicorn-sys-0.9.0/src/lib.rs --color always --crate-type lib --emit=dep-info,link -C debuginfo=2 -C metadata=3e5e84d63b293298 -C extra-filename=-3e5e84d63b293298 --out-dir .../target/debug/deps -L dependency=.../target/debug/deps --extern bitflags=.../target/debug/deps/libbitflags-f4c5ccff822b82c9.rlib --extern libc=.../target/debug/deps/liblibc-e1ff536ab604bb39.rlib --cap-lints allow -L native=.../target/debug/build/libunicorn-sys-f7184211e440bd6d/out -l static=unicorn`
error: could not find native static library `unicorn`, perhaps an -L flag is missing?

error: aborting due to previous error

error: Could not compile `libunicorn-sys`.

Caused by:
  process didn't exit successfully: `rustc --edition=2018 --crate-name libunicorn_sys .../.cargo/registry/src/github.com-1ecc6299db9ec823/libunicorn-sys-0.9.0/src/lib.rs --color always --crate-type lib --emit=dep-info,link -C debuginfo=2 -C metadata=3e5e84d63b293298 -C extra-filename=-3e5e84d63b293298 --out-dir .../target/debug/deps -L dependency=.../target/debug/deps --extern bitflags=.../target/debug/deps/libbitflags-f4c5ccff822b82c9.rlib --extern libc=.../target/debug/deps/liblibc-e1ff536ab604bb39.rlib --cap-lints allow -L native=.../target/debug/build/libunicorn-sys-f7184211e440bd6d/out -l static=unicorn` (exit code: 1)

Where

cargo 1.32.0 (8610973aa 2019-01-02)
rustc 1.32.0 (9fda7c223 2019-01-16)

Accessing the CPU in hooks

disclaimer: I'm a rust noob. I may be missing something essential, here.

Is there an intended way to access the Unicorn engine's CPU context from a code hook? The following (which more or less follows the pattern in the test routines) compiles without complaint, but then causes the emulation to hang for several seconds, until it crashes with an exit code of 1.

 53     if _DEBUG {                                                                                                                              
 54       let callback_c =                                                                                                                       
 55         move |u: &unicorn::Unicorn, addr: u64, _: u32| {                                                                                     
 56           println!("[{:08x}] SP: {:08x}", addr, u.reg_read(RegisterARM::SP.to_i32()).expect("Error reading SP"));                            
 57         };                                                                                                                                   
 58       // add some hooks if in debugging mode                                                                                                 
 59       uc.add_code_hook(CodeHookType::CODE,                                                                                                   
 60                        BASE_ADDR,                                                                                                            
 61                        BASE_ADDR+(MEM_SIZE as u64),                                                                                          
 62                        callback_c)                                                                                                           
 63         .expect("Error adding code hook");                                                                                                   
 64     }                                                                                                                                        
 65                                                                                                                                              
 66     uc                                                                                                                                       
 67   }         

edit: what I'm trying to do here is access the internal unicorn handle's reg_read() method, in lieu of the usual CPU reg_read wrapper (which takes an enum arg instead of an i32), since the Unicorn handle is all that the callback signature seems to give us to work with. This same hook works fine if I leave out the u.reg_read bit, and just print the addr value.

update: No worries. Turned out to be a scoping/lifetime issue after all, which, for reasons still unclear to me, the compiler wasn't picking up on. I moved the hook-adding routine to a separate function -- outside of the function that creates and initializes the engine -- and then called that function from the function that calls the first, initializing function, and now everything appears to be working fine. This partially makes sense to me, given what I grasp of rust's memory management system, and the rest I suppose will become clearer as I become less noobish. Closing the issue. Thanks for letting me rubber-duck debug here.

Fork for UnicornAFL / Autogenerate bindings?

I just wanted to point out I have taken your code and started to integrate the bindings into my AFL fork of unicorn.
To keep overhead low (and my sanity), I moved the bindings into the main repo.
https://github.com/domenukk/unicorn/tree/rust/bindings/rust
The changes itself can be found here
master...domenukk:unicornafl
Specifically, I have added rust to ./const_generator.py as I constantly (heh) add consts, see:
https://github.com/domenukk/unicorn/blob/rust/bindings/const_generator.py
Maybe auto generating constants could be interesting for this project, too.

A thing I changed to be able to autogenerate them is to add aliases for ENUM types that are used more than once, see
https://github.com/domenukk/unicorn-rs/blob/15e2e00a46bead6c8fea7137ad53f2a9755fa110/libunicorn-sys/src/mips_const.rs#L205

I'm open to discussions of all sorts. :)
Keep up the good work.

Possible to bind uc_mem_map_ptr?

Is it possible to bind uc_mem_map_ptr, thereby allowing the user to provide their own memory? Maybe this isn't reasonably to do with Rust, I don't know it well enough.

consider FnMut for hooks

in writing a program that uses unicorn, i ran into a problem where i wanted to initialize variables in the main function and capture them in the closure for the interrupt hook to act as sort of local static variables for the closure. i encountered a problem though, which is that add_intr_hook accepts a Fn and not a FnMut as an argument, which required me to wrap all the variables in mutexes in order to pass them in as mutable.

i was just wondering if it is a matter of limitation on the library (it would be unsafe to use FnMut) or if it was an oversight in the bindings and could be changed to allow more flexibility

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.