Unicorn CPU emulator framework (ARM, AArch64, M68K, Mips, Sparc, PowerPC, RiscV, X86)

Overview

Unicorn Engine

Join the chat at https://gitter.im/unicorn-engine/chat Build Status pypi downloads Fuzzing Status

Unicorn is a lightweight, multi-platform, multi-architecture CPU emulator framework based on QEMU.

Unicorn offers some unparalleled features:

  • Multi-architecture: ARM, ARM64 (ARMv8), M68K, MIPS, SPARC, and X86 (16, 32, 64-bit)
  • Clean/simple/lightweight/intuitive architecture-neutral API
  • Implemented in pure C language, with bindings for Crystal, Clojure, Visual Basic, Perl, Rust, Ruby, Python, Java, .NET, Go, Delphi/Free Pascal, Haskell, Pharo, and Lua.
  • Native support for Windows & *nix (with Mac OSX, Linux, *BSD & Solaris confirmed)
  • High performance via Just-In-Time compilation
  • Support for fine-grained instrumentation at various levels
  • Thread-safety by design
  • Distributed under free software license GPLv2

Further information is available at http://www.unicorn-engine.org

License

This project is released under the GPL license.

Compilation & Docs

See docs/COMPILE.md file for how to compile and install Unicorn.

More documentation is available in docs/README.md.

Contact

Contact us via mailing list, email or twitter for any questions.

Contribute

If you want to contribute, please pick up something from our Github issues.

We also maintain a list of more challenged problems in a TODO list.

CREDITS.TXT records important contributors of our project.

Comments
  • IMUL mem/Ib DWORD; OPC_IMUL_GvEvIb;

    IMUL mem/Ib DWORD; OPC_IMUL_GvEvIb; "imul eax, [ecx+0x41], 0x10"

    In Intel IMUL opcode described in one method using different descriptions:

    • 6B / r ib IMUL r32, imm8 doubleword register = doubleword register * sign-extended immediate byte
    • imul Gv, Ev, I
    • OPC_IMUL_GvEvIb
    • imul eax, [ecx+0x41], 0x10
    • 6b414110 imul eax,DWORD PTR [ecx+0x41],0x10

    When encountering an IMUL opcode of i386 architecture, specifically when using with an immediate 8-bit multiplier, the emulator engine does not properly multiply the number 0x5151494a by 0x10 and get the expected 0x151494a0 result.

    Interesting thing, is that a standalone IMUL instruction works, but this stack-based AlphaMixed code snippet (derived from Metasploit) failed.

    Will submit working proof-of-failure code soon.

    bug 
    opened by egberts 72
  • Python 3.5 dynamic library load error

    Python 3.5 dynamic library load error

    I've been battling with running the python bindings on python 3.5.

    I keep getting a ImportError: ERROR: fail to load the dynamic library. however I have checked that all libraries are present in .\unicorn\lib

        Directory: C:\Python\Lib\site-packages\unicorn\lib
    
    
    Mode                LastWriteTime         Length Name
    ----                -------------         ------ ----
    -a----       2016/09/24   7:23 PM         122036 libgcc_s_dw2-1.dll
    -a----       2016/09/24   3:17 PM          83742 libgcc_s_seh-1.dll
    -a----       2016/10/13   7:02 PM        1124259 libglib-2.0-0.dll
    -a----       2015/06/29   1:25 PM        1050543 libiconv-2.dll
    -a----       2016/03/31   8:50 AM         132717 libintl-8.dll
    -a----       2016/10/09   5:46 PM          56978 libwinpthread-1.dll
    -a----       2016/10/31   9:10 PM       26335738 unicorn.dll
    

    The library does load the directories correctly

    [-] path: 'C:\Python\lib\site-packages\unicorn\lib'
            [+] lib_file: C:\Python\lib\site-packages\unicorn\lib\libwinpthread-1.dll
            [+] lib_file: C:\Python\lib\site-packages\unicorn\lib\libgcc_s_seh-1.dll
            [+] lib_file: C:\Python\lib\site-packages\unicorn\lib\libgcc_s_dw2-1.dll
    [-] path: 'C:\Python\lib\site-packages\unicorn\lib'
            [+] lib_file: C:\Python\lib\site-packages\unicorn\lib\libwinpthread-1.dll
            [+] lib_file: C:\Python\lib\site-packages\unicorn\lib\libgcc_s_seh-1.dll
            [+] lib_file: C:\Python\lib\site-packages\unicorn\lib\libgcc_s_dw2-1.dll
    [-] path: ''
            [+] lib_file: libwinpthread-1.dll
            [+] lib_file: libgcc_s_seh-1.dll
            [+] lib_file: libgcc_s_dw2-1.dll
            [+] lib_file: libiconv-2.dll
            [+] lib_file: libintl-8.dll
            [+] lib_file: libglib-2.0-0.dll
    [-] path: 'C:\Python\Lib\site-packages'
            [+] lib_file: C:\Python\Lib\site-packages\libwinpthread-1.dll
            [+] lib_file: C:\Python\Lib\site-packages\libgcc_s_seh-1.dll
            [+] lib_file: C:\Python\Lib\site-packages\libgcc_s_dw2-1.dll
            [+] lib_file: C:\Python\Lib\site-packages\libiconv-2.dll
            [+] lib_file: C:\Python\Lib\site-packages\libintl-8.dll
            [+] lib_file: C:\Python\Lib\site-packages\libglib-2.0-0.dll
    [-] path: 'C:\Python\Lib\site-packages\unicorn\lib'
            [+] lib_file: C:\Python\Lib\site-packages\unicorn\lib\libwinpthread-1.dll
            [+] lib_file: C:\Python\Lib\site-packages\unicorn\lib\libgcc_s_seh-1.dll
            [+] lib_file: C:\Python\Lib\site-packages\unicorn\lib\libgcc_s_dw2-1.dll
    [-] path: '/usr/lib64'
            [+] lib_file: /usr/lib64\libwinpthread-1.dll
            [+] lib_file: /usr/lib64\libgcc_s_seh-1.dll
            [+] lib_file: /usr/lib64\libgcc_s_dw2-1.dll
            [+] lib_file: /usr/lib64\libiconv-2.dll
            [+] lib_file: /usr/lib64\libintl-8.dll
            [+] lib_file: /usr/lib64\libglib-2.0-0.dll
    Traceback (most recent call last):
      File "shellcode.py", line 5, in <module>
        from unicorn import *
      File "C:\Python\lib\site-packages\unicorn\__init__.py", line 4, in <module>
        from .unicorn import Uc, uc_version, uc_arch_supported, version_bind, debug, UcError, __version__
      File "C:\Python\lib\site-packages\unicorn\unicorn.py", line 75, in <module>
        raise ImportError("ERROR: fail to load the dynamic library.")
    ImportError: ERROR: fail to load the dynamic library.
    

    Note: the extra path was a hard-coded one for debugging.

    I have no idea what the issue is here. You can see the hap-hazard file loading from a little debug print() I did :/

    Its also worth noting that I have attempt the "official" 0.9 release from the website as well as my own build. Same issue regardless.

    bug 
    opened by CryptXor 53
  • update bindings to support uc_context_save() & uc_context_restore()

    update bindings to support uc_context_save() & uc_context_restore()

    attention: @sashs, @enkomio, @adrianherrera, @cseagle, @xorstream, @lunixbochs.

    recently we have new APIs uc_context_save() & uc_context_restore(). at the moment, only Python binding supports these API.

    thus we need to update other bindings: .Net, Go, Haskell, Java, msvc & ruby.

    thanks!

    help wanted TODO IMPORTANT CHANGE 
    opened by aquynh 49
  • M1 Max jit_write_protect issue

    M1 Max jit_write_protect issue

    Moved to Unicorn 2 for M1 support. Getting this ~50% of the time

    MIPS CPU, with Go bindings if it matters. Perhaps someone has an idea.

    Process 34232 stopped
    * thread #10, stop reason = EXC_BAD_ACCESS (code=2, address=0x280000098)
        frame #0: 0x0000000101040a14 libunicorn.2.dylib`tb_gen_code_mips + 304
    libunicorn.2.dylib`tb_gen_code_mips:
    ->  0x101040a14 <+304>: str    x8, [x9, #0x18]
        0x101040a18 <+308>: ldur   w8, [x29, #-0x14]
        0x101040a1c <+312>: ldur   x9, [x29, #-0x38]
        0x101040a20 <+316>: str    w8, [x9]
    Target 0: (mipsevm.test) stopped.
    (lldb) bt
    * thread #10, stop reason = EXC_BAD_ACCESS (code=2, address=0x280000098)
      * frame #0: 0x0000000101040a14 libunicorn.2.dylib`tb_gen_code_mips + 304
        frame #1: 0x000000010102b74c libunicorn.2.dylib`tb_find + 92
        frame #2: 0x000000010102b1b0 libunicorn.2.dylib`cpu_exec_mips + 244
        frame #3: 0x0000000100fd8ce0 libunicorn.2.dylib`tcg_cpu_exec + 76
        frame #4: 0x0000000100fd8c0c libunicorn.2.dylib`resume_all_vcpus_mips + 96
        frame #5: 0x0000000100fd8dfc libunicorn.2.dylib`vm_start_mips + 24
        frame #6: 0x0000000100fc676c libunicorn.2.dylib`uc_emu_start + 352
        frame #7: 0x00000001002f7f04 mipsevm.test`_cgo_81152a5834e5_Cfunc_uc_emu_start + 44
    

    Speed isn't that important to me, is there any way to disable threading?

    bug 
    opened by geohot 48
  • Add ability to mark memory area read only. Add new API uc_mem_map_ex t…

    Add ability to mark memory area read only. Add new API uc_mem_map_ex t…

    Add ability to mark memory area read only. Add new API uc_mem_map_ex to allow permissions to be passed. Change MemoryBlock to track created MemoryRegions. Add regress/ro_mem_test.c

    This also solves the memory leak issue on uc->ram because now all MemoryRegion allocations are tracked in the uc->mapped_blocks array.

    opened by cseagle 42
  • remove glib dependency by providing compatible replacements

    remove glib dependency by providing compatible replacements

    Added glib compatible replacements for all glib functions used in unicorn. Removed glib dependencies in Makefiles. I threw the list and hash table implementations together and have paid no attention to their performance. Feel free to replace the hash table implementation with something that performs better. Need help testing. All samples and unit tests run with same results as master on the following platforms: win32 (using mingw), OS X 64, Linux 32, Linux 64. Have not done much testing beyond that.

    opened by cseagle 36
  • New feature: registers can be bulk saved/restored in an opaque blob

    New feature: registers can be bulk saved/restored in an opaque blob

    This is a feature that is required for UC integration in angr. We need to be able to efficiently roll back the state at a whim when we encounter symbolic data that cannot be processed by unicorn.

    Originally, our internal code was just including the appropriate private header files and performing this operation manually, but as we're gearing up for distribution, this won't do. So, new feature!

    I've done nothing but the bare minimum to demonstrate that it works and is useful since I don't know if this is a feature you'd appreciate having.

    opened by rhelmot 33
  • IBM Z (aka SystemZ / SysZ / s390x) architecture support

    IBM Z (aka SystemZ / SysZ / s390x) architecture support

    Hi,

    I was wondering what would it take to support IBM Z in unicorn-engine? QEMU 2.1.2 seems to have sufficient support for it, so I assume the main missing things are these?

    • UC_* defines
    • machine definition
    • hooks
    • build system support

    Also, based on https://github.com/unicorn-engine/unicorn/issues/1438, do I get it right that such contribution would have to wait until unicorn 2 is out, or would it make sense to also do this for 1.x?

    Best regards, Ilya

    pinned 
    opened by iii-i 32
  • Run Unit Test in Travis builds

    Run Unit Test in Travis builds

    osx in Travis has brew available without sudo, easy to install cmocka

    For linux and appveyor, I created a small script to download and compile cmocka.

    Unit test test_tb_x86_64_32_imul_Gv_Ev_Ib now failing on all platforms

    TODO: see if clang works in cygwin for builds, currently following up with cmocka

    What about changing the tests/unit to pass and adding it to the build process? Maybe bindings too?

    opened by stephengroat 32
  • PPC support

    PPC support

    I've made only few tests so far: basic arithmetic, and strlen(). No stack-related tests, no tests for resource leaks on multiple runs, no tests for hooks. Also it is limited to e500v2 and built only in ubuntu/amd64/gcc environment. So this is surely work in progress. However the changes to the common part of unicorn are few and easy to review and most likely they are not going to introduce any problem with non-ppc platforms. So if you accept the changes you are going to have an otherwise stable engine with experimental unstable ppc support.

    opened by simigo79 31
  • roadmap to Qemu 2.5 syncing

    roadmap to Qemu 2.5 syncing

    i wanted to straightly upgrade to Qemu 2.5, but there is a lot of code changed from Qemu 2.2.1, which Unicorn is based on.

    therefore, i will break this down in few phases to make it more manageable, and also easier to track bugs introduced by this task:

    • upgrade to 2.3.1
    • upgrade to 2.4.1
    • upgrade to 2.5

    expect more update on this work later.

    TODO 
    opened by aquynh 30
  • Pointers to sections that I get through uc_mem_map

    Pointers to sections that I get through uc_mem_map

    Hello everyone!

    uc_mem_map allocates a VA section into which Unicorn patches as the code passes, now I need to get pointers to these sections in order to write them to my .exe. Through uc_mem_regions(); I get the same VA each time and the number of blocks that does not match the allocated uc_mem_map, as well as the size that also does not match the allocated size.. well, I can't write down the data that UNICORN patched, respectively, since I can't get pointers to this whole thing

    I get this from uc_mem_regions() https://ibb.co/tLY8zVh Instead of the necessary pointers

    How can I get a pointer to the memory that uc_mem_map allocated?

    SIZE\ADDRESSES

    #define ASectionSdataDenuvo 0x140001000
    #define ASectionArchDenuvo 0x141C97000
    #define ASectionBssDenuvo 0x142AC5000
    #define ASectionPdataDenuvo 0x142D56000
    #define ASectionTraceDenuvo 0x142E78000
    #define ASectionTlsDenuvo 0x142E7A000
    #define ASectionSrdataDenuvo 0x15B220000
    #define ASectionEdataDenuvo 0x15B276000
    #define ASectionIdataDenuvo 0x15B282000
    #define ASectionXtextDenuvo 0x15B283000
    #define ASectionXtlsDenuvo 0x15B284000
    #define ASectionTextDenuvo 0x15B285000
    #define ASectionCodeDenuvo 0x15B28D000
    
    int64_t ADDRESS_TEXT_SECTION_NTDLL, ADDRESS_TEXT_SECTION_MSVCRT;
    
    uint64_t SIZE_Section_Sdata_Denuvo = 0x1C96000;
    uint64_t SIZE_Section_Arch_Denuvo = 0xE2E000;
    uint64_t SIZE_Section_Bss_Denuvo = 0x291000;
    uint64_t SIZE_Section_Pdata_Denuvo = 0x122000;
    uint64_t SIZE_Section_Trace_Denuvo = 0x2000;
    uint64_t SIZE_Section_Tls_Denuvo = 0x183A6000;
    uint64_t SIZE_Section_Srdata_Denuvo = 0x56000;
    uint64_t SIZE_Section_Edata_Denuvo = 0xC000;
    uint64_t SIZE_Section_Idata_Denuvo = 0x1000;
    uint64_t SIZE_Section_Xtext_Denuvo = 0x1000;
    uint64_t SIZE_Section_Xtls_Denuvo = 0x1000;
    uint64_t SIZE_Section_Text_Denuvo = 0x8000;
    uint64_t SIZE_Section_Code_Denuvo = 0x1B000;
    
    uint64_t SIZE_Section_Text_Ntdll = 0x119000;
    uint64_t SIZE_Section_Text_Msvcrt = 0x75000;
    

    uc_mem_map I have such a quantity and it does not correspond to 11 blocks in any way

    0) uc_mem_map(uc, STACK_ADDRESS, SIZE_OF_STACK, UC_PROT_ALL);
    
    1) uc_mem_map(uc, ASectionSdataDenuvo, SIZE_Section_Sdata_Denuvo, UC_PROT_ALL);
    2) uc_mem_map(uc, ASectionArchDenuvo, SIZE_Section_Arch_Denuvo, UC_PROT_ALL);
    3) uc_mem_map(uc, ASectionBssDenuvo, SIZE_Section_Bss_Denuvo, UC_PROT_ALL);
    4) uc_mem_map(uc, ASectionPdataDenuvo, SIZE_Section_Pdata_Denuvo, UC_PROT_ALL);
    5) uc_mem_map(uc, ASectionTraceDenuvo, SIZE_Section_Trace_Denuvo, UC_PROT_ALL);
    6) uc_mem_map(uc, ASectionTlsDenuvo, SIZE_Section_Tls_Denuvo, UC_PROT_ALL);
    7) uc_mem_map(uc, ASectionSrdataDenuvo, SIZE_Section_Srdata_Denuvo, UC_PROT_ALL);
    8) uc_mem_map(uc, ASectionEdataDenuvo, SIZE_Section_Edata_Denuvo, UC_PROT_ALL);
    9) uc_mem_map(uc, ASectionIdataDenuvo, SIZE_Section_Idata_Denuvo, UC_PROT_ALL);
    10) uc_mem_map(uc, ASectionXtextDenuvo, SIZE_Section_Xtext_Denuvo, UC_PROT_ALL);
    11) uc_mem_map(uc, ASectionXtlsDenuvo, SIZE_Section_Xtls_Denuvo, UC_PROT_ALL);
    12) uc_mem_map(uc, ASectionTextDenuvo, SIZE_Section_Text_Denuvo, UC_PROT_ALL);
    13) uc_mem_map(uc, ASectionCodeDenuvo, SIZE_Section_Code_Denuvo, UC_PROT_ALL);
    
    14) uc_mem_map(uc, ADDRESS_TEXT_SECTION_NTDLL, SIZE_Section_Text_Ntdll, UC_PROT_ALL);
    15) uc_mem_map(uc, ADDRESS_TEXT_SECTION_MSVCRT, SIZE_Section_Text_Msvcrt, UC_PROT_ALL);
    
    16) uc_mem_map(uc, GS_BASE_ADDRESS, SIZE_OF_GDT_BASE, UC_PROT_ALL);
    

    implementation of uc_mem_regions();

    if (address == 0x156265A75)
        {
            uc_err err;
            uc_mem_region* region;
            uint32_t count;
    
            if ((err = uc_mem_regions(uc, &region, &count))) {
                std::cout << "Failed on uc_mem_regions() with error returned %u: %s" << err << uc_strerror(err) << endl;
            }
    
            cout << "Starting address: 0x" << hex << region->begin << " End address: 0x" << hex << region->end << " Memory permissions: " << region->perms << " Number of memory blocks requested: " << count << endl << endl << endl << endl;
        }
    
    opened by OSPFvX 0
  • Thumb2  Instruction Not Support LDAEX

    Thumb2 Instruction Not Support LDAEX

    Code like this is Not Support public static final byte[] THUMB_CODE1 = {(byte) 0xD3, (byte) 0xE8, (byte) 0xEF, 0x4F}; // ldaex r4, [r3]

    Similar Instruction like public static final byte[] THUMB_CODE2 = {(byte) 0xC3, (byte) 0xE8, (byte) 0xE5,0x2F} // stlex r5, r2, [r3] is also not support

    These occur in simulate android "libc.so",in function "pthread_key_create".Am I wrong when using unicon?

    code is here: pthread_key_create
    .text:00047964
    .text:00047964 ; __unwind { .text:00047964 PUSH {R4,R5,R7,LR} .text:00047966 LDR.W R12, =(_ZL7key_map - 0x47972) .text:0004796A MOV.W LR, #0 .text:0004796E ADD R12, PC ; key_map .text:00047970 .text:00047970 loc_47970 ; CODE XREF: .text:000479A0↓j .text:00047970 LDR.W R2, [R12,LR,LSL#3] .text:00047974 ADD.W R3, R12, LR,LSL#3 .text:00047978 B loc_47994 .text:00047978 ; --------------------------------------------------------------------------- .text:0004797A unk_4797A DCB 0xD3 ; CODE XREF: .text:00047996↓j .text:0004797B DCB 0xE8 .text:0004797C DCB 0xEF .text:0004797D DCB 0x4F ; O .text:0004797E ; --------------------------------------------------------------------------- .text:0004797E CMP R4, R2 .text:00047980 BNE loc_4798E .text:00047982 ADDS R2, #1 .text:00047982 ; --------------------------------------------------------------------------- .text:00047984 DCB 0xC3 .text:00047985 DCB 0xE8 .text:00047986 DCB 0xE5 .text:00047987 DCB 0x2F ; / .text:00047988 ; --------------------------------------------------------------------------- .text:00047988 MOV R2, R4 .text:0004798A CBNZ R5, loc_47994 .text:0004798C B loc_479A6 .text:0004798E ; -----------------------------------------------

    opened by lykmoon 3
  • `uc_emu_start()` doesn't stop emulation at an `until` address.

    `uc_emu_start()` doesn't stop emulation at an `until` address.

    Environment

    • OS: Ubuntu 22.04.1 LTS (Linux 5.15.0)
    • Unicorn: 2.0.0 (6c1cbef6)
    • CMake: 3.22.1
    • GCC: 11.3.0

    Issue

    uc_emu_start() doesn't stop emulation at an address specified by until. Its PoC is the following C program:

    #include <stdio.h>
    #include <stdlib.h>
    
    #include <unicorn/unicorn.h>
    #include <capstone/capstone.h>
    
    // x86_64 machine code.
    const char target_code[] = \
    "\xf3\x0f\x1e\xfa\x55\x48\x89\xe5\xc7\x45\xf8\x00\x00\x00\x00\xc7" \
    "\x45\xfc\x00\x00\x00\x00\xeb\x1a\x83\x7d\xf8\x00\x75\x09\xc7\x45" \
    "\xf8\x01\x00\x00\x00\xeb\x07\xc7\x45\xf8\x00\x00\x00\x00\x83\x45" \
    "\xfc\x01\x83\x7d\xfc\x04\x7e\xe0\x90\x90\x5d\xc3";
    
    // base address.
    const uint64_t base_addr = 0x08000000;
    // .text section offset.
    const uint64_t text_offset = 0x40;
    // .text section address.
    const uint64_t text_addr = base_addr + text_offset;
    // stack top offset.
    const uint64_t stack_top_offset = 0x1fff;
    // stack top address.
    const uint64_t stack_top_addr = base_addr + stack_top_offset;
    
    //
    // a callback for tracing translation blocks.
    //
    static void
    hook_block(uc_engine *uc, uint64_t address, uint32_t size, void *user_data)
    {
        uc_err uerr;
    
        fprintf(stdout, ">>> Tracing basic block at 0x%" PRIx64 ", block size = 0x%x\n", address, size);
    
        // disassemble with capstone.
        csh handle;
        cs_err cerr;
        if ((cerr = cs_open(CS_ARCH_X86, CS_MODE_64, &handle))) {
            fprintf(stderr, "Failed to cs_open() with error returned %u: %s\n", cerr, cs_strerror(cerr));
            return;
        }
        uint8_t *code = (uint8_t *)malloc(sizeof(uint8_t) * size);
        if ((uerr = uc_mem_read(uc, address, (void *)code, size))) {
            fprintf(stderr, "Failed to uc_mem_read() with error returned %u: %s\n", uerr, uc_strerror(uerr));
            return;
        }
        size_t count = 0;
        cs_insn *insn;
        if ((count = cs_disasm(handle, code, size, address, 0, &insn)) > 0) {
            for (size_t i = 0; i < count; i++) {
                fprintf(stdout, "\t0x%"PRIx64":\t%s\t\t%s\n", insn[i].address, insn[i].mnemonic, insn[i].op_str);
            }
            cs_free(insn, count);
        } else {
            fprintf(stderr, "\tFailed to disassemble.\n");
        }
    
        free(code);
        if ((cerr = cs_close(&handle))) {
            fprintf(stderr, "Failed to cs_close() with error returned %u: %s\n", cerr, cs_strerror(cerr));
            return;
        }
    }
    
    int
    main(int argc, char *argv[])
    {
        uc_engine *uc;
        uc_err err;
        uc_hook trace;
    
        // initialize a uc_engine instance.
        if ((err = uc_open(UC_ARCH_X86, UC_MODE_64, &uc))) {
            fprintf(stderr, "Failed to uc_open() with error returned %u: %s\n", err, uc_strerror(err));
            return -1;
        }
    
        // allocate 8KiB memory for emulation.
        if ((err = uc_mem_map(uc, base_addr, 8 * 1024, UC_PROT_ALL))) {
            fprintf(stderr, "Failed to uc_mem_map() with error returned %u: %s\n", err, uc_strerror(err));
            return -1;
        }
    
        // write the target code to the memory.
        if ((err = uc_mem_write(uc, text_addr, (void *)target_code, sizeof(target_code) - 1))) {
            fprintf(stderr, "Failed to uc_mem_write() with error returned %u: %s\n", err, uc_strerror(err));
            return -1;
        }
    
        // add a block-tracing hook.
        if ((err = uc_hook_add(uc, &trace, UC_HOOK_BLOCK, hook_block, NULL, 1, 0))) {
            fprintf(stderr, "Failed to uc_hook_add() with error returned %u: %s\n", err, uc_strerror(err));
            return -1;
        }
    
        // initialize stack-related registers.
        int rbp = stack_top_addr;
        int rsp = stack_top_addr;
        if ((err = uc_reg_write(uc, UC_X86_REG_RBP, &rbp))) {  // rbp
            fprintf(stderr, "Failed to uc_reg_write() with error returned %u: %s\n", err, uc_strerror(err));
            return -1;
        }
        if ((err = uc_reg_write(uc, UC_X86_REG_RSP, &rsp))) {  // rsp
            fprintf(stderr, "Failed to uc_reg_write() with error returned %u: %s\n", err, uc_strerror(err));
            return -1;
        }
    
        fprintf(stdout, "==================== 1. Run emulation until it hits 0x08000058 or runs 0x7fff instructions. ====================\n");
        uint64_t eip = text_addr;
        if ((err = uc_emu_start(uc, eip, 0x08000058, 0, 0x7fff))) {
            fprintf(stderr, "Failed to uc_emu_start() with error returned %u: %s\n", err, uc_strerror(err));
            return -1;
        }
        fprintf(stdout, ">>> Execution stoped.\n");
        if ((err = uc_reg_read(uc, UC_X86_REG_EIP, &eip))) {
            fprintf(stderr, "Failed to uc_reg_read() with error returned %u: %s\n", err, uc_strerror(err));
            return -1;
        }
        fprintf(stdout, ">>> eip: 0x%"PRIx64"\n", eip);
        fprintf(stdout, "\n");
    
        fprintf(stdout, "==================== 2. Run just one instruction. =====================\n");
        if ((err = uc_emu_start(uc, eip, UINT64_MAX, 0, 1))) {
            fprintf(stderr, "Failed to uc_emu_start() with error returned %u: %s\n", err, uc_strerror(err));
            return -1;
        }
        fprintf(stdout, ">>> Execution stoped.\n");
        if ((err = uc_reg_read(uc, UC_X86_REG_EIP, &eip))) {
            fprintf(stderr, "Failed to uc_reg_read() with error returned %u: %s\n", err, uc_strerror(err));
            return -1;
        }
        fprintf(stdout, ">>> eip: 0x%"PRIx64"\n", eip);
        fprintf(stdout, "\n");
    
        fprintf(stdout, "==================== 3. Again, run emulation until it hits 0x08000058 or runs 0x7fff instructions. ====================\n");
        if ((err = uc_emu_start(uc, eip, 0x08000058, 0, 0x7fff))) {
            fprintf(stderr, "Failed to uc_emu_start() with error returned %u: %s\n", err, uc_strerror(err));
            return -1;
        }
        fprintf(stdout, ">>> Execution stoped.\n");
        if ((err = uc_reg_read(uc, UC_X86_REG_EIP, &eip))) {
            fprintf(stderr, "Failed to uc_reg_read() with error returned %u: %s\n", err, uc_strerror(err));
            return -1;
        }
        fprintf(stdout, ">>> eip: 0x%"PRIx64"\n", eip);
        fprintf(stdout, "\n");
    
        if ((err = uc_close(uc))) {
            fprintf(stderr, "Failed to uc_close() with error returned %u: %s\n", err, uc_strerror(err));
            return -1;
        }
    
        return 0;
    }
    
    

    This program calls uc_emu_start() three times:

    1. Run emulation until it hits 0x08000058 or runs 0x7fff instructions.
    2. Run just one instruction.
    3. Again, run emulation until it hits 0x08000058 or runs 0x7fff instructions.

    The output of this program is as follows:

    ==================== 1. Run emulation until it hits 0x08000058 or runs 0x7fff instructions. ====================
    [uc] translate tb 0x8000040: 360.094000us                     
    >>> Tracing basic block at 0x8000040, block size = 0x18
            0x8000040:      endbr64                                             
            0x8000044:      push            rbp
            0x8000045:      mov             rbp, rsp      
            0x8000048:      mov             dword ptr [rbp - 8], 0
            0x800004f:      mov             dword ptr [rbp - 4], 0
            0x8000056:      jmp             0x8000072
    [uc] exec tb 0x8000040: 2093.186000us                                       
    [uc] translate tb 0x8000072: 17.673000us              
    >>> Tracing basic block at 0x8000072, block size = 0x6        
            0x8000072:      cmp             dword ptr [rbp - 4], 4
            0x8000076:      jle             0x8000058                           
    [uc] exec tb 0x8000072: 38.650000us                                         
    [uc] translate tb 0x8000058: 2.440000us                
    >>> Execution stoped.                                                       
    >>> eip: 0x8000058                                                          
    
    ==================== 2. Run just one instruction. =====================
    [uc] translate tb 0x8000058: 12.431000us                                    
    >>> Tracing basic block at 0x8000058, block size = 0x6
            0x8000058:      cmp             dword ptr [rbp - 8], 0
            0x800005c:      jne             0x8000067
    [uc] exec tb 0x8000058: 40.663000us                                         
    >>> Execution stoped.                                                       
    >>> eip: 0x800005c
    
    ==================== 3. Again, run emulation until it hits 0x08000058 or runs 0x7fff instructions. ====================
    [uc] translate tb 0x800005c: 19.594000us
    >>> Tracing basic block at 0x800005c, block size = 0x2
            0x800005c:      jne             0x8000067
    [uc] exec tb 0x800005c: 51.028000us
    [uc] translate tb 0x800005e: 20.807000us
    >>> Tracing basic block at 0x800005e, block size = 0x9
            0x800005e:      mov             dword ptr [rbp - 8], 1
            0x8000065:      jmp             0x800006e
    [uc] exec tb 0x800005e: 63.323000us
    [uc] translate tb 0x800006e: 32.649000us
    >>> Tracing basic block at 0x800006e, block size = 0xa
            0x800006e:      add             dword ptr [rbp - 4], 1
            0x8000072:      cmp             dword ptr [rbp - 4], 4
            0x8000076:      jle             0x8000058
    [uc] exec tb 0x800006e: 69.026000us
    >>> Tracing basic block at 0x8000058, block size = 0x6
            0x8000058:      cmp             dword ptr [rbp - 8], 0
            0x800005c:      jne             0x8000067
    [uc] exec tb 0x8000058: 56.497000us
    [uc] translate tb 0x8000067: 41.810000us
    >>> Tracing basic block at 0x8000067, block size = 0x11
            0x8000067:      mov             dword ptr [rbp - 8], 0
            0x800006e:      add             dword ptr [rbp - 4], 1
            0x8000072:      cmp             dword ptr [rbp - 4], 4
            0x8000076:      jle             0x8000058
    [uc] exec tb 0x8000067: 92.436000us
    >>> Tracing basic block at 0x8000058, block size = 0x6
            0x8000058:      cmp             dword ptr [rbp - 8], 0
            0x800005c:      jne             0x8000067
    [uc] exec tb 0x8000058: 55.975000us
    >>> Tracing basic block at 0x800005e, block size = 0x9
            0x800005e:      mov             dword ptr [rbp - 8], 1
            0x8000065:      jmp             0x800006e
    >>> Tracing basic block at 0x800006e, block size = 0xa
            0x800006e:      add             dword ptr [rbp - 4], 1
            0x8000072:      cmp             dword ptr [rbp - 4], 4
            0x8000076:      jle             0x8000058
    >>> Tracing basic block at 0x8000058, block size = 0x6
            0x8000058:      cmp             dword ptr [rbp - 8], 0
            0x800005c:      jne             0x8000067
    >>> Tracing basic block at 0x8000067, block size = 0x11
            0x8000067:      mov             dword ptr [rbp - 8], 0
            0x800006e:      add             dword ptr [rbp - 4], 1
            0x8000072:      cmp             dword ptr [rbp - 4], 4
            0x8000076:      jle             0x8000058
    >>> Tracing basic block at 0x8000058, block size = 0x6
            0x8000058:      cmp             dword ptr [rbp - 8], 0
            0x800005c:      jne             0x8000067
    >>> Tracing basic block at 0x800005e, block size = 0x9
            0x800005e:      mov             dword ptr [rbp - 8], 1
            0x8000065:      jmp             0x800006e
    >>> Tracing basic block at 0x800006e, block size = 0xa
            0x800006e:      add             dword ptr [rbp - 4], 1
            0x8000072:      cmp             dword ptr [rbp - 4], 4
            0x8000076:      jle             0x8000058
    [uc] exec tb 0x800005e: 437.196000us
    [uc] translate tb 0x8000078: 34.233000us
    >>> Tracing basic block at 0x8000078, block size = 0x4
            0x8000078:      nop
            0x8000079:      nop
            0x800007a:      pop             rbp
            0x800007b:      ret
    [uc] exec tb 0x8000078: 82.262000us
    Failed to uc_emu_start() with error returned 6: Invalid memory read (UC_ERR_READ_UNMAPPED)
    

    Unfortunately, the third uc_emu_start() doesn't stop even though it has hit 0x08000058.

    Cause

    AFAIK, the cause of this issue is QEMU's TB cache. Unicorn inserts TCG-IRs, which stop emulation when it hits until, when translating guest codes. Since QEMU doesn't know about it, it can re-execute TBs on the TB cache (with no code inserted for stopping emulation).

    Solution/Workaround

    I'm looking for a solution/workaround to this issue. One of the most reasonable workarounds is removing TB cache entries, including the address until before calling uc_emu_start(). For example:

    uc_ctl_remove_cache(uc, until, until + 1);
    uc_emu_start(uc, begin, until, timeout, count);
    

    Are there any other solutions/workarounds?

    question 
    opened by vhertz 1
  • unicorn.unicorn.UcError: Invalid argument (UC_ERR_ARG)

    unicorn.unicorn.UcError: Invalid argument (UC_ERR_ARG)

    The following code will raise unicorn.unicorn.UcError: Invalid argument (UC_ERR_ARG) ··· mu = Uc(UC_ARCH_ARM64, UC_MODE_ARM) address=0x10000 mu.mem_map(address, 1024*1024) mu.mem_map(0x7dd9cfb6c0, 1024) ··· but I change the last code to mu.mem_map(0x7dd9cfb000, 1024) I will work? Why?

    question 
    opened by lyg4795 2
  • Unicron mishandles MIPS delay slots

    Unicron mishandles MIPS delay slots

    Consider a scheduling mechanism based on number of instructions (i.e. switching context every n instructions):

    while True:
         uc.restore(ctx)
         uc.emu_start(start_address, end_address, count=30000)
         ctx = uc.save()
         # do thread scheduling here
    

    It appears that there is a problem with the delay slot on MIPS: in cases where the emulation stops just betrween the branch and the delay slot (i.e. branch has been taken into account, but the delay slot wasn't), the emulation will resume in the delay slot without remembering it was a delay slot, proceeding to the next instruction (address_of_slot + 4) instead of the original branch target.

    Consider the following two runs of the same binary, where the difference is only in the switching point (i.e. count value).

    Run 1: the branch (0040adf0) is appropriately taken

    [running] 0040ace0 : jr       $ra               : state = 5ce982babced6a7e6156352e69f25317449ee14995341792121050f3209a376c
    [running] 0040ace4 : move     $v0, $zero        : state = 10fa1031d22142bbae2b3950bdb31e762ad1732ad203354c1842b8a694a3e4b2
    [running] 0040adec : lw       $gp, 0x10($sp)    : state = 10bf68088ff837760235c720ca9bb1d331d825046f59d04b03757d081993cc23
    [running] 0040adf0 : b        0xad60            : state = d52343ac9cbd6638180379d6d4c085ce23bc2ecf587bc1ef3eae94d5be070720
    [running] 0040adf4 : move     $s3, $v0          : state = dd6eb753d63e00471bfd8434e436b8065e48957c3a31823724f87c42875bd13a
    [running] 0040ad60 : addiu    $a2, $s1, 8       : state = 4c9e89248b6b43d0c4b952e735da2ed202c095910a57ddcd0f9c8cafac3f4afe
    [running] 0040ad64 : lw       $s1, -0x7e34($gp) : state = fd7a84dd509c6a34e08e11545e27c08e1a7ab2d6c5b921225f4ef6261a1b344b
    

    Run 2: context is switched just between the branch (0040adf0) and the delay slot (0040adf4)

    [running] 0040ace0 : jr       $ra               : state = 5ce982babced6a7e6156352e69f25317449ee14995341792121050f3209a376c
    [running] 0040ace4 : move     $v0, $zero        : state = 10fa1031d22142bbae2b3950bdb31e762ad1732ad203354c1842b8a694a3e4b2
    [running] 0040adec : lw       $gp, 0x10($sp)    : state = 10bf68088ff837760235c720ca9bb1d331d825046f59d04b03757d081993cc23
    [running] 0040adf0 : b        0xad60            : state = d52343ac9cbd6638180379d6d4c085ce23bc2ecf587bc1ef3eae94d5be070720
    [stopped] 0040adf4 : move     $s3, $v0          : state = 3037a37fdf5c9af1660725b978028b0eb3ce48f9585de0bdd56507dace8aa919
    [running] 0040adf4 : move     $s3, $v0          : state = 3037a37fdf5c9af1660725b978028b0eb3ce48f9585de0bdd56507dace8aa919
    [running] 0040adf8 : addiu    $v0, $zero, 1     : state = a47d219a7e22f52f0f7807f428c692baa1441b648ed24edcbd11c4c70c3ac88e
    [running] 0040adfc : lw       $s4, 0x30($sp)    : state = 28faa4e990114295d1564334e8973014e50a1e8bea7212a35fe12bb8f34dcbc1
    

    Notes:

    • The [stopped] label shows the next instruction to resume from; it has not been executed yet
    • The state is a sha256 digest of all arch registers values concatenated together

    Note that the state for delay slot (0040adf4) is different between the two runs, which may indicate that there is an information missing / not updated correctly.

    bug poc 
    opened by elicn 1
Releases(2.0.1.post1)
  • 2.0.1.post1(Nov 22, 2022)

    This is a small release to complement the previous 2.0.1 release.

    Fix:

    • Fix the endianness detection in tests.
    • Fix the version number in CMakeLists.txt.
    Source code(tar.gz)
    Source code(zip)
  • 2.0.1(Nov 1, 2022)

    Unicorn2 makes the first step to Debian packages and vcpkg! Thanks @roehling and @LilyWangL !

    Features:

    • Support building & running on BE hosts. #1710
    • Fix and support clang-cl on Windows. #1687
    • Fix python sdist and add aarch64 Linux wheels. Note pip can build Unicorn2 on M1 now!
    • C# binding is refined and upgraded to .Net 6. #1723

    Fix/Improvements:

    • Various bindings improvements. #1723
    • Improvements for tests. #1684 #1683 #1691 #1711
    • Fail explicitly when VEX.L is set. #1658
    • Fix endianness when writing PPC32 CR register. #1659
    • Fix a bug in uc_ctl_set_cpu_model check.
    • Fix Tricore PC not updating. #1668
    • Fix the mapping not updated if users modify the mappings in the hooks.
    • Handle pathological cases consistently. #1651
    • Fix memory leaks in PPC target. #1680
    • Fix memory leaks in Tricore target. #1681
    • Fix MSVC handling in cmake. #1693
    • Fix PC sync-ing problems for UC_HOOK_BLOCK hooks.
    • Fix PC sync-ed twice when users request a soft restart.
    • Prevent overflow with pre-allocated RAM blocks. #1712
    • Add FPCR and FPSR registers #1722
    • Fix ARM CPU state not deep copied.
    • Fix PC not sync-ed for memory operation on aarch64.
    • Exit invalid store operations early to avoid the target registers being overwritten.
    • Improve the support for ARM BE32.

    Thanks:

    @roehling @LilyWangL @mrexodia @zachriggle @Yu3H0 @rhelmot @relapids @sh4w1 @TSRBerry

    Source code(tar.gz)
    Source code(zip)
  • 2.0.0(Jul 7, 2022)

    Features:

    • TriCore Support (#1568)

    Fixes/Improvements:

    • Build both shared library and static archive as unicorn1 does.
    • Misc bindings improvements. #1569 #1600 #1609 #1613 #1616
    • Make sure setjmp-setjmp-wrapper-win32 participates in the build. #1604
    • Improve Rust bindings build logic.
    • Fix wrong python binding for UC_CTL_TB_REMOVE_CACHE
    • Flush translation blocks when the count hook is removed.
    • Fix unicorn crash when nested uc_emu_start deletes a hook
    • Fix CPU not fully resumed when writing PC.
    • Don't quit TB if uc_mem_protect doesn't change the protection of current TB memory.
    • Add type annotations for python bindings.
    • Add CPUID hook for python bindings. #1618
    • Don't repeat memory hooks if there is already an unhandled error. #1618
    • Support reads and writes over all Arm SIMD registers #1621
    • Fix wrong registers range in python bindings.
    • Fix uc_mem_protect on mmio regions
    • Fix a UAF caused by hook cache.
    • Fix the value collision between UC_MODE_ARMBE8 and UC_MODE_ARM926

    Thanks:

    @AfoHT @mrexodia @bet4it @lowlyw @ekilmer @ondryaso @QDucasse @PalumboN @uberwoozle

    Source code(tar.gz)
    Source code(zip)
  • 2.0.0-rc7(Apr 17, 2022)

    This release is expected to be the real last RC release of Unicorn2. ;)

    Features:

    • Correctly generate static archives for the static build and have CI auto-tested.
    • Rust bindings revised. #1584
    • Compatible with clang-cl compiler. #1581
    • Implement UC_HOOK_INSN for aarch64 MRS/MSR/SYS/SYSL

    Fixes/Improvements:

    • Several corner cases on our API. #1587 #1595
    • Fix the codegen buffer leak.
    • Rust bindins improvements. #1574 #1575
    • Add "holes" to allow unicorn lib as a drop-in replacement for older ones. #1572
    • s390x backports. #1570
    • Fix exits wrongly removed in nested uc_emu_start
    • Fix a possible endless loop for only one translation block in a multithreaded environment.
    • Fix wrong PC without UC_HOOK_CODE installed.
    • Update vb6 bindings license. #1563
    • Fix buffer allocation failure on M1. #1559
    • Fix wrong EFLAGS on startup.
    • Fix wrong internal states on nested uc_emu_start.
    • Remove armeb-softmmu and aarcheb-softmmu which are usermode targets.
    • Advance PPC32 PC. #1558
    • Support UC_PPC_REG_CR.
    • Update CI to windows-2019

    Thanks:

    @shuffle2 @liyansong2018 @rose4096 @nviennot @n1tram1 @iii-i @dzzie @yrashk @bet4it

    Source code(tar.gz)
    Source code(zip)
  • 2.0.0-rc6(Feb 13, 2022)

    This release is expected to be the last RC release of Unicorn2.

    Features:

    • SystemZ (aka. s390x) support. #1521 #1547
    • CPUID hook now may return a bool to indicate whether skipping the CPUID instruction.
    • ARM/AARCH64 coprocessor registers read/write support. #889

    Fixes/Improvements:

    • Rust improvements. More registers enums #1504 Easier to use #1543 #1545
    • M68k improvements. #1507
    • Golang improvements. Enable uc_ctl_set_model #1506
    • Unit tests improvements. #1512
    • Various ARM system mode fixes. #1500 #1520 #1525 #1531
    • Read/write arm FPSCR and FPSID. #1453
    • Fix the support for ARMv8
    • Fix a large number of memory leaks and unicorn2 now goes with google/oss-fuzz!
    • Add more X87 registers. #1524
    • Add more PPC registers.
    • Fix the exception not cleared in python bindings. #1537
    • Correctly support ARM big endian and drops armeb-softmmu and aarch64eb-softmmu
    • Fix ARM CPSR.E not reflected during runtime.
    • Resolve fuzzing speed problem on macOS.
    • Modernize CmakeFileLists.txt. #1544
    • Fix an issue in nested uc_emu_start

    Thanks:

    @Kritzefitz @zznop @QDucasse @gerph @bet4it @mrexodia @iii-i @jbcayrou @scribam

    Source code(tar.gz)
    Source code(zip)
  • 2.0.0-rc5(Nov 25, 2021)

    This release fixes a few urgent bugs and improves performance.

    Fixes/Improvements:

    • Rust bindings improvements. #1480 #1483
    • Allow R/W to cp15 registers. #1481
    • Fix UC_HOOK_EDGE_GENERATED not calling for indirect jumps.
    • Python bindings build improvements. #1486
    • Fix bindings on m1 macOS.
    • Support nested uc_emu_start calls without context save/restore
    • Fix wrong MMIO offset for 32bit targets.
    • Fix wrong uc_mem_unmap logic for both ram and mmio memory.
    • Inline uc_trace_code and PC sync to improve performance.
    • Various fixes in tests.
    • Allow writing to CPSR to switch bank registers.
    • Implement MMIO in rust bindings. #1499

    Thanks:

    • @domenukk
    • @bet4it
    • @mid-kid
    • @Kritzefitz
    Source code(tar.gz)
    Source code(zip)
  • 2.0.0-rc4(Nov 8, 2021)

    This is a big release of Unicorn and introduces a few powerful new features and a bunch of fixes.

    New Features:

    • New API: uc_ctl, by which you could control CPU models, TB caches or multiple exits etc.
    • New Hook: UC_HOOK_EDGE_GENERATED, UC_HOOK_TCG_OPCODE
    • RISCV CSR read/write.
    • Support reading MIPS hi/lo regs. 7268c2a19bce2db72b90e3ea3b133482c3ff4e58
    • OSS Fuzzing building support.
    • MSVC 32bit and Android build support.
    • Introduce clang-format.

    Fixes/Improvements:

    • Java bindings improvements. unicorn-engine/unicorn#1461
    • API Documents updates. unicorn-engine/unicorn#1459
    • Rust bindings improvements. unicorn-engine/unicorn#1462
    • Add a go.mod for go bindings.
    • CMakeLists.txt improvements as a subproject. #1373
    • Fix rust bindings build script and add CI.
    • Use binary search to find mappings. unicorn-engine/unicorn#1414
    • RISCV:
      • Update pc when exiting execution. unicorn-engine/unicorn#1465
      • Add RISCV control status registers to enable floating. unicorn-engine/unicorn#1469 unicorn-engine/unicorn#1478
      • After ecall, pc not advanced. unicorn-engine/unicorn#1477
    • Fix tb not invalidated when exiting.
    • Fix bindings makefile.
    • Fix uc_mem_protect not working. unicorn-engine/unicorn#1468

    Thanks:

    • @bet4it
    • @kabeor
    • @chfl4gs
    • @QDucasse
    • @h33p
    • @geohot
    • @cla7aye15I4nd
    • @jcalabres
    Source code(tar.gz)
    Source code(zip)
  • 2.0.0-rc3(Oct 6, 2021)

    This is an urgent pre-release regarding python bindings on older Linux systems.

    • Support older Linux distribution, e.g. prior to Ubuntu 19.04
    • Fix a memory leak in uc_close
    • Support building on Android
    • Support hooking CPUID instruction.

    Enjoy.

    Source code(tar.gz)
    Source code(zip)
  • 2.0.0-rc2(Oct 5, 2021)

    This is an urgent pre-release regarding the packaging problem of python bindings.

    • Set zip_false and is_pure to False to avoid issues on some Linux distributions.
    • Link to libm to make sure our libraries work.
    • Support to read ST registers in rust bindings.
    • Fix #1450

    Enjoy.

    Source code(tar.gz)
    Source code(zip)
  • 2.0.0-rc1(Oct 4, 2021)

    Unicorn2 first release candidate!

    • Based on Qemu 5.0.1
    • Remain backward compatible with Unicorn 1.x
    • Update ISA of all existing architectures
    • Support 2 new architectures in PowerPC & RISCV
    Source code(tar.gz)
    Source code(zip)
  • 1.0.3(May 26, 2021)

    • Fix some building issues

      • Fix build with LLVM on Powerpc64(le)
      • cmake: enable UNICORN_HAS_ARMEB when ARM is on
      • Better support MingW building
      • Better support FreeBSD host
        • Better support VS2008/VS2010
    • Fix some issues in the core

      • Fix wrong sync after UC_ERR_[READ, WRITE, FETCH]_[UNMAPPED, PROT]
      • Support querying architecture mode besides arm
      • Fix pausing within Thumb2 ITE blocks
    • Arm:

      • Support Arm BE8 mode
    • X86:

      • Fix FPIP & FTST instructions
    • Bindings:

      • Java: remove deprecated javah and build with javac
      • Python: handle exceptions raised in hook functions
      • Rust binding
    Source code(tar.gz)
    Source code(zip)
  • 1.0.2(Oct 21, 2020)

  • 1.0.2-rc6(Sep 24, 2020)

  • 1.0.2-rc5(Sep 21, 2020)

    • Add cmake option to build Unicorn as a static library
    • Fix error handling of mmap()
    • uc_emu_start() can be reentrant
    • Fix naming conflicts when built with systemd
    • Fix setjmp/longjmp on native Windows
    • Fix enabled hooks even after deleting them
    • X86:
      • Fix 64bit fstenv
      • Fix IP value of 16bit mode
    • ARM:
      • Fix APSR handling
    • Python: Remove UC_ERR_TIMEOUT
    Source code(tar.gz)
    Source code(zip)
  • 1.0.2-rc4(May 29, 2020)

    This version fixes some issues and improves over v1.0.2-rc3.

    • No longer require Python to build
    • Fix recursive UC_HOOK_MEM callbacks for cross pages access
    • Remove UC_ERR_TIMEOUT, so timeout on uc_emu_start() is not considered error
    • Added UC_QUERY_TIMEOUT to query exit reason
    • Fix UAF when deleting hook while in hook callback
    • Ensure that hooks are unaffected by a request to stop emulation.
    • Fix block hooks being called twice after an early exit from execution.
    • Fix binding install on python2 (MacOS)
    • X86:
      • Support read/write STn registers
      • Support read/write X64 base regs
    • ARM64:
      • Support some new registers
    Source code(tar.gz)
    Source code(zip)
  • 1.0.2-rc3(Apr 8, 2020)

  • 1.0.2-rc2(Feb 15, 2020)

  • 1.0.2-rc1(Oct 8, 2019)

  • 1.0.1(Apr 20, 2017)

    Stable release with some important bugfixes & new features for several architectures.

    • Properly handle build with selected-architectures.
    • Fix compilation issues on PPC & S390x.
    • Fix a memory leak on uc_mem_protect().
    • ARM:
      • Support big-endian mode.
      • Correct instruction size of Thumb/Thumb2 code.
      • Support read/write APSR register.
    • ARM64:
      • Support read/write NEON registers.
      • Support read/write NZCV registers.
    • Mips: Support read/write Mips64 registers.
    • X86: Support read/write MSR.
    • Haskell binding: update to the latest API.
    • Python: allow not having PATH setup.
    Source code(tar.gz)
    Source code(zip)
    unicorn-1.0.1-python-win32.msi(7.62 MB)
    unicorn-1.0.1-python-win64.msi(7.60 MB)
    unicorn-1.0.1-win32.zip(16.63 MB)
    unicorn-1.0.1-win64.zip(17.00 MB)
  • 1.0(Feb 23, 2017)

  • 1.0-rc3(Jan 25, 2017)

    Release Candidate 3 of Unicorn Engine 1.0

    Important changes since v1.0-RC2:

    • Core: rename API uc_context_free() to uc_free().
    • ARM:
      • uc_reg_write() now can modify CPSR register.
      • Add some ARM coproc registers.
    • ARM64: uc_reg_read|write() now handles W0-W31 registers.
    • Windows: fix a double free bug in uc_close().
    • New VB6 binding.
    • Java: update to support new APIs from v1.0-rc1.
    • Python:
      • Fix memory leaking that prevents UC instances from being GC.
      • Remove some dependencies leftover from glib time.
      • Add new method mem_regions() (linked to uc_mem_regions() API)
    Source code(tar.gz)
    Source code(zip)
    unicorn-1.0-rc3-win32.zip(15.05 MB)
    unicorn-1.0-rc3-win64.zip(15.38 MB)
  • 1.0-rc2(Jan 4, 2017)

  • 1.0-rc1(Dec 22, 2016)

    Release Candidate 1 of Unicorn Engine version 1.0

    Important changes:

    • Lots of bugfixes in all architectures.
    • Better support for ARM Thumb.
    • Fix many memory leaking issues.
    • New bindings: Haskell, MSVC.
    • Better support for Python3.
    • New APIs: uc_query, uc_reg_write_batch, uc_reg_read_batch, uc_mem_map_ptr, uc_mem_regions, uc_context_alloc, uc_context_save & uc_context_restore.
    • New memory hook type: UC_HOOK_MEM_READ_AFTER.
    • Add new version macros UC_VERSION_{MAJOR, MINOR, EXTRA}
    Source code(tar.gz)
    Source code(zip)
    unicorn-1.0-rc1-win32.zip(18.50 MB)
    unicorn-1.0-rc1-win64.zip(18.82 MB)
Owner
Unicorn Engine
Multi-arch multi-platform CPU emulator framework
Unicorn Engine
PHP Encoder, protect PHP scripts in PHP 8 and PHP 7, High Performance, Compitable with X86_64, MIPS, ARM platform and Ubuntu/Centos/OpenWRT system.

What's FRICC2? FRICC2 is a PHP Script encryption tool. When you are developing a commercial software using PHP, the script can be distributed as encry

Hoowa Sun 43 Dec 12, 2022
kianv a simple implementation of a rv32im riscv cpu and soc in verilog with firmware that runs raytracer, mandelbrot, etc.....

A very simple riscv cpu/soc one single file implementation created in my spare time! But it is full rv32im CPU :) I have wrote all from scratch to lea

splinedrive 122 Dec 26, 2022
Elven relativism -- relocation and execution of aarch64 ELF relocatable objects (REL)

elvenrel Elven Relativism -- relocation and execution of aarch64 ELF relocatable objects (REL) on Linux and macOS. Program loads a multitude of ELF RE

Martin Krastev 15 Oct 15, 2022
xv6 port to aarch64 virt board

xv6 is a re-implementation of Dennis Ritchie's and Ken Thompson's Unix Version 6 (v6). xv6 loosely follows the structure and style of v6, but is impl

mkei 7 Oct 18, 2022
An experimental operating system for x86 and ARM

Odyssey - an experimental operating system for x86 and ARM

Anuradha Weeraman 39 Dec 28, 2022
A port of the Linux x86 IOLI crackme challenges to x86-64

This is a port of the original Linux x86 IOLI crackme binaries to x86-64. The original set of IOLI crackmes can be found here: https://github.com/Maij

Julian Daeumer 4 Mar 19, 2022
repo to house various LLVM based SIHFT passes for RISCV 32/64 soft error resilience

compas-ft-riscv COMPAS: Compiler-assisted Software-implemented Hardware Fault Tolerance implemented in LLVM passes for the RISC-V backend Repo to hous

EDA@TUM 2 Jan 10, 2022
a small C library for x86 CPU detection and feature extraction

libcpuid libcpuid provides CPU identification for the x86 (and x86_64). For details about the programming API, you might want to take a look at the pr

Veselin Georgiev 358 Dec 26, 2022
MINCE is an Emacs-like text editor from Mark of the Unicorn, Inc.

MINCE Is Not Complete[ly] EMACS Overview MINCE is an Emacs-like text editor from Mark of the Unicorn, Inc. Versions were available for many oper

Jeffrey H. Johnson 20 Nov 5, 2022
IDA Debugger Module to Dynamically Synchronize Memory and Registers with third-party Backends (Tenet, Unicorn, GDB, etc.)

IDA Debug Bridge IDA Debugger Module to Dynamically Synchronize Memory and Registers with third-party Backends (Tenet, Unicorn, GDB, etc.) By synchron

null 9 Sep 5, 2022
Qnicorn: a cutting edge version of unicorn-engine.org

Qnicorn Engine Qnicorn is a cutting edge and community-driven version of unicorn-engine. Qnicorn offers the features below: All features that Unicorn2

qiling.io 4 Sep 10, 2022
x86 emulator on Raspberry Pi Pico

picox86 x86 emulator on Raspberry Pi Pico https://user-images.githubusercontent.com/10139098/110543817-13299080-812b-11eb-9c88-674cdae919fc.mp4 PCB fr

null 39 Nov 9, 2022
x86 emulator written in C++

X86_EMULATOR_2 Build make Run ./x86 -i haribote.img Language and Library C++11, SDL2.0 How to use mouse on x86 emulator Grab mouse on x86 emulator cli

Niwaka 28 Dec 30, 2022
TinyE8 - Ben Eater's 8 Bit CPU Emulator

TinyE8 - Ben Eater's 8 Bit CPU Emulator TinyE8 emulates Ben Eater's 8 bit breadboard CPU. Implemented all the Instructions except JC and JZ, I need to

null 67 Nov 10, 2022
A place to collaborate on code for the Embedded.fm book club. Currently reading "STM32 ARM Programming for Embedded Systems".

Welcome to the Book Club Code site! This is a place for the Embedded.fm book club to collaborate and learn together. Repo Structure Guide Top-level fo

Peter Griffin 11 Jul 21, 2022
A lightweight ARM reverse engineering tool.

eydis A lightweight (basic and slow) ARM reverse engineering tool. I. Requierements macOS/Linux, Basics compiling tools, The SQLite3 + readline framew

Yui Aioi 18 Aug 15, 2022
Prometheus exporter for ARM® Hardware components using HWCPipe.

ARM® HWCPipe Exporter ARM® HWCPipe Exporter is a Prometheus exporter written in Java and C++ that retrieves metrics from Android devices running on AR

Jinesi Yelizati 4 Oct 5, 2022
ARM DevSummit workshop with Portenta H7

ARM DevSummit 2021 - Edge Impulse Portenta workshop Edge Impulse enables developers to create the next generation of intelligent device solutions with

Edge Impulse 8 Oct 19, 2021
Dummy-Robot my super mini robot arm robot items

Dummy-Robot 我的超迷你机械臂机器人项目。 资料待整理 已添加3D模型设计源文件。 已添加夹爪硬件设计文件和LED灯环PCB 已添加无线空间定位控制器PCB文件 已添加无线示教器Peak软硬件工程(作为submodule) 已添加REF的硬件设计文件 已添加DummyStudio上位机 已

稚晖 8.9k Dec 30, 2022