├── .clang-format ├── .github └── README.md ├── .gitignore ├── .gitmodules ├── AUTHORS.TXT ├── Brewfile ├── CMakeLists.txt ├── COPYING ├── COPYING.LGPL2 ├── COPYING_GLIB ├── CREDITS.TXT ├── Cargo.toml ├── ChangeLog ├── README.md ├── README_intel.md ├── SECURITY.md ├── TODO ├── bindings ├── Makefile ├── README ├── const_generator.py ├── dotnet │ ├── README.md │ ├── UnicornDotNet.sln │ ├── UnicornManaged │ │ ├── Binding │ │ │ ├── BindingFactory.fs │ │ │ ├── IBinding.fs │ │ │ ├── MockBinding.fs │ │ │ └── NativeBinding.fs │ │ ├── Const │ │ │ ├── Arm.fs │ │ │ ├── Arm64.fs │ │ │ ├── Common.fs │ │ │ ├── M68k.fs │ │ │ ├── Mips.fs │ │ │ ├── Ppc.fs │ │ │ ├── Riscv.fs │ │ │ ├── S390x.fs │ │ │ ├── Sparc.fs │ │ │ ├── TriCore.fs │ │ │ └── X86.fs │ │ ├── ConvertUtility.fs │ │ ├── InternalHooks.fs │ │ ├── Unicorn.fs │ │ ├── UnicornEngineException.fs │ │ └── UnicornManaged.fsproj │ └── UnicornSamples │ │ ├── Program.cs │ │ ├── ShellcodeSample.cs │ │ ├── UnicornSamples.csproj │ │ ├── Utils.cs │ │ └── X86Sample32.cs ├── go │ ├── Makefile │ ├── README.md │ ├── sample.go │ └── unicorn │ │ ├── arm64_const.go │ │ ├── arm_const.go │ │ ├── context.go │ │ ├── context_test.go │ │ ├── hook.c │ │ ├── hook.go │ │ ├── hook.h │ │ ├── m68k_const.go │ │ ├── mips_const.go │ │ ├── ppc_const.go │ │ ├── reg_batch.go │ │ ├── riscv_const.go │ │ ├── s390x_const.go │ │ ├── sparc_const.go │ │ ├── tricore_const.go │ │ ├── uc.c │ │ ├── uc.h │ │ ├── unicorn.go │ │ ├── unicorn_const.go │ │ ├── unicorn_test.go │ │ ├── x86.go │ │ ├── x86_const.go │ │ └── x86_test.go ├── haskell │ ├── .gitignore │ ├── README.TXT │ ├── Setup.hs │ ├── samples │ │ ├── SampleArm.hs │ │ ├── SampleArm64.hs │ │ ├── SampleBatchReg.hs │ │ ├── SampleM68k.hs │ │ ├── SampleMips.hs │ │ ├── SampleSparc.hs │ │ ├── SampleX86.hs │ │ └── Shellcode.hs │ ├── src │ │ ├── Unicorn.hs │ │ ├── Unicorn │ │ │ ├── CPU │ │ │ │ ├── Arm.chs │ │ │ │ ├── Arm64.chs │ │ │ │ ├── M68k.chs │ │ │ │ ├── Mips.chs │ │ │ │ ├── Sparc.chs │ │ │ │ └── X86.chs │ │ │ ├── Hook.hs │ │ │ └── Internal │ │ │ │ ├── Core.chs │ │ │ │ ├── Hook.chs │ │ │ │ ├── Unicorn.chs │ │ │ │ └── Util.hs │ │ ├── cbits │ │ │ └── unicorn_wrapper.c │ │ └── include │ │ │ └── unicorn_wrapper.h │ └── unicorn.cabal ├── java │ ├── Makefile │ ├── Makefile.build │ ├── README.TXT │ ├── samples │ │ ├── SampleNetworkAuditing.java │ │ ├── Sample_arm.java │ │ ├── Sample_arm64.java │ │ ├── Sample_m68k.java │ │ ├── Sample_mips.java │ │ ├── Sample_sparc.java │ │ ├── Sample_x86.java │ │ ├── Sample_x86_mmr.java │ │ └── Shellcode.java │ ├── unicorn │ │ ├── Arm64Const.java │ │ ├── ArmConst.java │ │ ├── BlockHook.java │ │ ├── CodeHook.java │ │ ├── EventMemHook.java │ │ ├── Hook.java │ │ ├── InHook.java │ │ ├── InterruptHook.java │ │ ├── M68kConst.java │ │ ├── MemHook.java │ │ ├── MemRegion.java │ │ ├── MipsConst.java │ │ ├── OutHook.java │ │ ├── PpcConst.java │ │ ├── ReadHook.java │ │ ├── RiscvConst.java │ │ ├── S390xConst.java │ │ ├── SparcConst.java │ │ ├── SyscallHook.java │ │ ├── TriCoreConst.java │ │ ├── Unicorn.java │ │ ├── UnicornConst.java │ │ ├── UnicornException.java │ │ ├── WriteHook.java │ │ ├── X86Const.java │ │ └── X86_MMR.java │ └── unicorn_Unicorn.c ├── pascal │ ├── LICENSE │ ├── README.md │ ├── examples │ │ ├── x86.lpi │ │ ├── x86.lpr │ │ └── x86.lps │ └── unicorn │ │ ├── Arm64Const.pas │ │ ├── ArmConst.pas │ │ ├── M68kConst.pas │ │ ├── MipsConst.pas │ │ ├── PpcConst.pas │ │ ├── RiscvConst.pas │ │ ├── S390xConst.pas │ │ ├── SparcConst.pas │ │ ├── TriCoreConst.pas │ │ ├── UnicornConst.pas │ │ ├── Unicorn_dyn.pas │ │ └── X86Const.pas ├── python │ ├── MANIFEST.in │ ├── Makefile │ ├── README.TXT │ ├── build_wheel.sh │ ├── prebuilt │ │ └── .gitkeep │ ├── sample_all.sh │ ├── sample_arm.py │ ├── sample_arm64.py │ ├── sample_arm64eb.py │ ├── sample_armeb.py │ ├── sample_ctl.py │ ├── sample_m68k.py │ ├── sample_mips.py │ ├── sample_network_auditing.py │ ├── sample_ppc.py │ ├── sample_riscv.py │ ├── sample_s390x.py │ ├── sample_sparc.py │ ├── sample_tricore.py │ ├── sample_x86.py │ ├── setup.cfg │ ├── setup.py │ ├── shellcode.py │ └── unicorn │ │ ├── __init__.py │ │ ├── arm64_const.py │ │ ├── arm_const.py │ │ ├── m68k_const.py │ │ ├── mips_const.py │ │ ├── ppc_const.py │ │ ├── riscv_const.py │ │ ├── s390x_const.py │ │ ├── sparc_const.py │ │ ├── tricore_const.py │ │ ├── unicorn.py │ │ ├── unicorn_const.py │ │ └── x86_const.py ├── ruby │ ├── Makefile │ ├── README.md │ ├── sample_arm.rb │ ├── sample_arm64.rb │ ├── sample_m68k.rb │ ├── sample_mips.rb │ ├── sample_sparc.rb │ ├── sample_x86.rb │ ├── sample_x86_gdt.rb │ ├── test_hook_gc.rb │ └── unicorn_gem │ │ ├── Gemfile │ │ ├── Rakefile │ │ ├── ext │ │ ├── extconf.rb │ │ ├── types.h │ │ ├── unicorn.c │ │ └── unicorn.h │ │ ├── lib │ │ └── unicorn_engine │ │ │ ├── arm64_const.rb │ │ │ ├── arm_const.rb │ │ │ ├── m68k_const.rb │ │ │ ├── mips_const.rb │ │ │ ├── ppc_const.rb │ │ │ ├── riscv_const.rb │ │ │ ├── s390x_const.rb │ │ │ ├── sparc_const.rb │ │ │ ├── tricore_const.rb │ │ │ ├── unicorn_const.rb │ │ │ ├── version.rb │ │ │ └── x86_const.rb │ │ ├── pkg │ │ └── .gitignore │ │ └── unicorn-engine.gemspec ├── rust │ ├── COPYING │ ├── README.md │ ├── build.rs │ └── src │ │ ├── arm.rs │ │ ├── arm64.rs │ │ ├── ffi.rs │ │ ├── lib.rs │ │ ├── m68k.rs │ │ ├── mips.rs │ │ ├── ppc.rs │ │ ├── riscv.rs │ │ ├── s390x.rs │ │ ├── sparc.rs │ │ ├── tricore.rs │ │ ├── unicorn_const.rs │ │ └── x86.rs └── vb6 │ ├── .gitattributes │ ├── Apache_2.0_License.txt │ ├── CMemRegion.cls │ ├── Form1.frm │ ├── Project1.vbp │ ├── Project1.vbw │ ├── README.txt │ ├── example_output.txt │ ├── main.cpp │ ├── misc.bas │ ├── msvbvm60.tlh │ ├── msvbvm60.tli │ ├── screenshot.png │ ├── ucIntel32.cls │ ├── uc_def.bas │ ├── ucvbshim.sln │ └── ucvbshim.vcproj ├── bundle_static.cmake ├── docs ├── BHUSA2015-unicorn.pdf ├── COMPILE.md ├── FAQ.md ├── OPENBSD-NOTES.md ├── README.md ├── unicorn-logo-text.png ├── unicorn-logo.png ├── unicorn-logo.svg ├── unicorn1-logo.png └── unicorn1-logo.txt ├── efi ├── UnicornArm64Lib.inf ├── UnicornEngineLib.inf ├── UnicornPkg.dec ├── UnicornPkg.dsc ├── UnicornPkg.dsc.inc ├── UnicornRV32Lib.inf ├── UnicornRV64Lib.inf ├── UnicornSampleArm64.inf ├── UnicornSampleRV.inf ├── UnicornSampleStub.c ├── UnicornSampleX86.inf ├── UnicornStubLib.inf ├── UnicornX86Lib.inf ├── aarch64 │ ├── glue.c │ ├── liblto-unicorn.a │ └── liblto-unicorn.s ├── ashrti3.c ├── clrsb.c ├── divti3.c ├── dlmalloc.c ├── efi_glue.c ├── glue.c ├── include │ ├── assert.h │ ├── byteswap.h │ ├── config-host.h │ ├── config-target-aarch64.h │ ├── config-target-i386.h │ ├── config-target-riscv32.h │ ├── config-target-riscv64.h │ ├── ctype.h │ ├── errno.h │ ├── fcntl.h │ ├── float.h │ ├── glue.h │ ├── glue_internal.h │ ├── inttypes.h │ ├── limits.h │ ├── math.h │ ├── pthread.h │ ├── riscv │ │ └── stdatomic_asm.h │ ├── semaphore.h │ ├── setjmp.h │ ├── signal.h │ ├── stdarg.h │ ├── stdbool.h │ ├── stddef.h │ ├── stdint.h │ ├── stdio.h │ ├── stdlib.h │ ├── string.h │ ├── sys │ │ ├── mman.h │ │ ├── stat.h │ │ ├── time.h │ │ ├── types.h │ │ └── wait.h │ ├── time.h │ ├── unistd.h │ └── x86_64 │ │ └── cpuid.h ├── loongarch64 │ └── glue.c ├── popcount.c ├── riscv │ ├── clz.c │ ├── ctz.c │ └── glue.c ├── udivmodti4.c ├── weak.c └── x86_64 │ ├── glue.c │ ├── liblto-unicorn.a │ └── liblto-unicorn.s ├── format.sh ├── glib_compat ├── README ├── garray.c ├── garray.h ├── ghash.h ├── glib_compat.c ├── glib_compat.h ├── glist.c ├── glist.h ├── gmacros.h ├── gmem.c ├── gmem.h ├── gmessages.h ├── gnode.h ├── gpattern.c ├── gpattern.h ├── grand.c ├── grand.h ├── gslice.c ├── gslice.h ├── gtestutils.c ├── gtestutils.h ├── gtree.c ├── gtree.h └── gtypes.h ├── go.mod ├── include ├── list.h ├── qemu.h ├── uc_priv.h └── unicorn │ ├── arm.h │ ├── arm64.h │ ├── m68k.h │ ├── mips.h │ ├── platform.h │ ├── ppc.h │ ├── riscv.h │ ├── s390x.h │ ├── sparc.h │ ├── tricore.h │ ├── unicorn.h │ └── x86.h ├── list.c ├── mingw-w64.cmake ├── msvc ├── aarch64-softmmu │ └── config-target.h ├── aarch64eb-softmmu │ └── config-target.h ├── arm-softmmu │ └── config-target.h ├── armeb-softmmu │ └── config-target.h ├── config-host.h ├── m68k-softmmu │ └── config-target.h ├── mips-softmmu │ └── config-target.h ├── mips64-softmmu │ └── config-target.h ├── mips64el-softmmu │ └── config-target.h ├── mipsel-softmmu │ └── config-target.h ├── ppc-softmmu │ └── config-target.h ├── ppc64-softmmu │ └── config-target.h ├── riscv32-softmmu │ └── config-target.h ├── riscv64-softmmu │ └── config-target.h ├── s390x-softmmu │ └── config-target.h ├── sparc-softmmu │ └── config-target.h ├── sparc64-softmmu │ └── config-target.h ├── tricore-softmmu │ └── config-target.h ├── unicorn │ └── dllmain.cpp └── x86_64-softmmu │ └── config-target.h ├── qemu ├── .editorconfig ├── CODING_STYLE.rst ├── COPYING ├── COPYING.LIB ├── LICENSE ├── MAINTAINERS ├── VERSION ├── aarch64.h ├── accel │ └── tcg │ │ ├── atomic_template.h │ │ ├── cpu-exec-common.c │ │ ├── cpu-exec.c │ │ ├── cputlb.c │ │ ├── tcg-all.c │ │ ├── tcg-runtime-gvec.c │ │ ├── tcg-runtime.c │ │ ├── tcg-runtime.h │ │ ├── translate-all.c │ │ ├── translate-all.h │ │ └── translator.c ├── arm.h ├── configure ├── crypto │ ├── aes.c │ └── init.c ├── exec-vary.c ├── exec.c ├── fpu │ ├── softfloat-specialize.inc.c │ └── softfloat.c ├── hw │ ├── core │ │ └── cpu.c │ ├── i386 │ │ └── x86.c │ ├── ppc │ │ ├── ppc.c │ │ └── ppc_booke.c │ └── s390x │ │ └── s390-skeys.c ├── include │ ├── crypto │ │ ├── aes.h │ │ ├── init.h │ │ └── random.h │ ├── disas │ │ └── dis-asm.h │ ├── elf.h │ ├── exec │ │ ├── cpu-all.h │ │ ├── cpu-common.h │ │ ├── cpu-defs.h │ │ ├── cpu_ldst.h │ │ ├── cputlb.h │ │ ├── exec-all.h │ │ ├── gen-icount.h │ │ ├── helper-gen.h │ │ ├── helper-head.h │ │ ├── helper-proto.h │ │ ├── helper-tcg.h │ │ ├── hwaddr.h │ │ ├── ioport.h │ │ ├── memattrs.h │ │ ├── memop.h │ │ ├── memory-internal.h │ │ ├── memory.h │ │ ├── memory_ldst.inc.h │ │ ├── memory_ldst_cached.inc.h │ │ ├── memory_ldst_phys.inc.h │ │ ├── poison.h │ │ ├── ram_addr.h │ │ ├── ramblock.h │ │ ├── ramlist.h │ │ ├── softmmu-semi.h │ │ ├── target_page.h │ │ ├── tb-context.h │ │ ├── tb-hash.h │ │ ├── tb-lookup.h │ │ └── translator.h │ ├── fpu │ │ ├── softfloat-helpers.h │ │ ├── softfloat-macros.h │ │ ├── softfloat-types.h │ │ └── softfloat.h │ ├── hw │ │ ├── core │ │ │ └── cpu.h │ │ ├── i386 │ │ │ └── topology.h │ │ ├── mips │ │ │ └── cpudevs.h │ │ ├── ppc │ │ │ └── ppc.h │ │ ├── registerfields.h │ │ └── s390x │ │ │ ├── ebcdic.h │ │ │ ├── ioinst.h │ │ │ ├── sclp.h │ │ │ └── storage-keys.h │ ├── libdecnumber │ │ ├── dconfig.h │ │ ├── decContext.h │ │ ├── decDPD.h │ │ ├── decNumber.h │ │ ├── decNumberLocal.h │ │ └── dpd │ │ │ ├── decimal128.h │ │ │ ├── decimal128Local.h │ │ │ ├── decimal32.h │ │ │ └── decimal64.h │ ├── qemu-common.h │ ├── qemu │ │ ├── atomic.h │ │ ├── atomic128.h │ │ ├── bitmap.h │ │ ├── bitops.h │ │ ├── bswap.h │ │ ├── compiler.h │ │ ├── cpuid.h │ │ ├── crc32c.h │ │ ├── ctype.h │ │ ├── cutils.h │ │ ├── guest-random.h │ │ ├── host-utils.h │ │ ├── int128.h │ │ ├── log.h │ │ ├── osdep.h │ │ ├── processor.h │ │ ├── qdist.h │ │ ├── qht.h │ │ ├── queue.h │ │ ├── range.h │ │ ├── rcu_queue.h │ │ ├── thread-posix.h │ │ ├── thread-win32.h │ │ ├── thread.h │ │ ├── timer.h │ │ ├── typedefs.h │ │ ├── units.h │ │ └── xxhash.h │ ├── sysemu │ │ ├── cpus.h │ │ ├── memory_mapping.h │ │ ├── os-win32.h │ │ ├── sysemu.h │ │ └── tcg.h │ └── tcg │ │ ├── tcg-apple-jit.h │ │ ├── tcg-gvec-desc.h │ │ ├── tcg-mo.h │ │ ├── tcg-op-gvec.h │ │ ├── tcg-op.h │ │ ├── tcg-opc.h │ │ └── tcg.h ├── libdecnumber │ ├── decContext.c │ ├── decNumber.c │ └── dpd │ │ ├── decimal128.c │ │ ├── decimal32.c │ │ └── decimal64.c ├── m68k.h ├── memory_ldst.inc.c ├── mips.h ├── mips64.h ├── mips64el.h ├── mipsel.h ├── ppc.h ├── ppc64.h ├── riscv32.h ├── riscv64.h ├── rules.mak ├── s390x.h ├── scripts │ └── create_config ├── softmmu │ ├── cpus.c │ ├── ioport.c │ ├── memory.c │ ├── memory_mapping.c │ └── vl.c ├── sparc.h ├── sparc64.h ├── target │ ├── arm │ │ ├── README │ │ ├── arm-powerctl.c │ │ ├── arm-powerctl.h │ │ ├── arm-semi.c │ │ ├── arm_ldst.h │ │ ├── cpu-param.h │ │ ├── cpu-qom.h │ │ ├── cpu.c │ │ ├── cpu.h │ │ ├── cpu64.c │ │ ├── crypto_helper.c │ │ ├── debug_helper.c │ │ ├── decode-a32-uncond.inc.c │ │ ├── decode-a32.inc.c │ │ ├── decode-sve.inc.c │ │ ├── decode-t16.inc.c │ │ ├── decode-t32.inc.c │ │ ├── decode-vfp-uncond.inc.c │ │ ├── decode-vfp.inc.c │ │ ├── helper-a64.c │ │ ├── helper-a64.h │ │ ├── helper-sve.h │ │ ├── helper.c │ │ ├── helper.h │ │ ├── internals.h │ │ ├── iwmmxt_helper.c │ │ ├── kvm-consts.h │ │ ├── m_helper.c │ │ ├── neon_helper.c │ │ ├── op_addsub.h │ │ ├── op_helper.c │ │ ├── pauth_helper.c │ │ ├── psci.c │ │ ├── sve_helper.c │ │ ├── tlb_helper.c │ │ ├── translate-a64.c │ │ ├── translate-a64.h │ │ ├── translate-sve.c │ │ ├── translate-vfp.inc.c │ │ ├── translate.c │ │ ├── translate.h │ │ ├── unicorn.h │ │ ├── unicorn_aarch64.c │ │ ├── unicorn_arm.c │ │ ├── vec_helper.c │ │ └── vfp_helper.c │ ├── i386 │ │ ├── TODO │ │ ├── arch_memory_mapping.c │ │ ├── bpt_helper.c │ │ ├── cc_helper.c │ │ ├── cc_helper_template.h │ │ ├── cpu-param.h │ │ ├── cpu-qom.h │ │ ├── cpu.c │ │ ├── cpu.h │ │ ├── excp_helper.c │ │ ├── fpu_helper.c │ │ ├── helper.c │ │ ├── helper.h │ │ ├── int_helper.c │ │ ├── machine.c │ │ ├── mem_helper.c │ │ ├── misc_helper.c │ │ ├── mpx_helper.c │ │ ├── ops_sse.h │ │ ├── ops_sse_header.h │ │ ├── seg_helper.c │ │ ├── shift_helper_template.h │ │ ├── smm_helper.c │ │ ├── svm.h │ │ ├── svm_helper.c │ │ ├── translate.c │ │ ├── unicorn.c │ │ ├── unicorn.h │ │ └── xsave_helper.c │ ├── m68k │ │ ├── cpu-param.h │ │ ├── cpu-qom.h │ │ ├── cpu.c │ │ ├── cpu.h │ │ ├── fpu_helper.c │ │ ├── helper.c │ │ ├── helper.h │ │ ├── op_helper.c │ │ ├── qregs.def │ │ ├── softfloat.c │ │ ├── softfloat.h │ │ ├── softfloat_fpsp_tables.h │ │ ├── translate.c │ │ ├── unicorn.c │ │ └── unicorn.h │ ├── mips │ │ ├── TODO │ │ ├── cp0_helper.c │ │ ├── cp0_timer.c │ │ ├── cpu-param.h │ │ ├── cpu-qom.h │ │ ├── cpu.c │ │ ├── cpu.h │ │ ├── dsp_helper.c │ │ ├── fpu_helper.c │ │ ├── helper.c │ │ ├── helper.h │ │ ├── internal.h │ │ ├── lmi_helper.c │ │ ├── mips-defs.h │ │ ├── msa_helper.c │ │ ├── op_helper.c │ │ ├── translate.c │ │ ├── translate_init.inc.c │ │ ├── unicorn.c │ │ └── unicorn.h │ ├── ppc │ │ ├── compat.c │ │ ├── cpu-models.c │ │ ├── cpu-models.h │ │ ├── cpu-param.h │ │ ├── cpu-qom.h │ │ ├── cpu.c │ │ ├── cpu.h │ │ ├── dfp_helper.c │ │ ├── excp_helper.c │ │ ├── fpu_helper.c │ │ ├── helper.h │ │ ├── helper_regs.h │ │ ├── int_helper.c │ │ ├── internal.h │ │ ├── kvm_ppc.h │ │ ├── machine.c │ │ ├── mem_helper.c │ │ ├── mfrom_table.inc.c │ │ ├── mfrom_table_gen.c │ │ ├── misc_helper.c │ │ ├── mmu-book3s-v3.c │ │ ├── mmu-book3s-v3.h │ │ ├── mmu-hash32.c │ │ ├── mmu-hash32.h │ │ ├── mmu-hash64.c │ │ ├── mmu-hash64.h │ │ ├── mmu-radix64.c │ │ ├── mmu-radix64.h │ │ ├── mmu_helper.c │ │ ├── timebase_helper.c │ │ ├── translate.c │ │ ├── translate │ │ │ ├── dfp-impl.inc.c │ │ │ ├── dfp-ops.inc.c │ │ │ ├── fp-impl.inc.c │ │ │ ├── fp-ops.inc.c │ │ │ ├── spe-impl.inc.c │ │ │ ├── spe-ops.inc.c │ │ │ ├── vmx-impl.inc.c │ │ │ ├── vmx-ops.inc.c │ │ │ ├── vsx-impl.inc.c │ │ │ └── vsx-ops.inc.c │ │ ├── translate_init.inc.c │ │ ├── unicorn.c │ │ └── unicorn.h │ ├── riscv │ │ ├── README │ │ ├── cpu-param.h │ │ ├── cpu.c │ │ ├── cpu.h │ │ ├── cpu_bits.h │ │ ├── cpu_helper.c │ │ ├── cpu_user.h │ │ ├── csr.c │ │ ├── fpu_helper.c │ │ ├── helper.h │ │ ├── insn_trans │ │ │ ├── trans_privileged.inc.c │ │ │ ├── trans_rva.inc.c │ │ │ ├── trans_rvd.inc.c │ │ │ ├── trans_rvf.inc.c │ │ │ ├── trans_rvi.inc.c │ │ │ └── trans_rvm.inc.c │ │ ├── instmap.h │ │ ├── op_helper.c │ │ ├── pmp.c │ │ ├── pmp.h │ │ ├── riscv32 │ │ │ ├── decode_insn16.inc.c │ │ │ └── decode_insn32.inc.c │ │ ├── riscv64 │ │ │ ├── decode_insn16.inc.c │ │ │ └── decode_insn32.inc.c │ │ ├── translate.c │ │ ├── unicorn.c │ │ └── unicorn.h │ ├── s390x │ │ ├── cc_helper.c │ │ ├── cpu-param.h │ │ ├── cpu-qom.h │ │ ├── cpu.c │ │ ├── cpu.h │ │ ├── cpu_features.c │ │ ├── cpu_features.h │ │ ├── cpu_features_def.h │ │ ├── cpu_features_def.inc.h │ │ ├── cpu_models.c │ │ ├── cpu_models.h │ │ ├── crypto_helper.c │ │ ├── excp_helper.c │ │ ├── fpu_helper.c │ │ ├── gen-features.c │ │ ├── gen-features.h │ │ ├── helper.c │ │ ├── helper.h │ │ ├── insn-data.def │ │ ├── insn-format.def │ │ ├── int_helper.c │ │ ├── internal.h │ │ ├── interrupt.c │ │ ├── ioinst.c │ │ ├── mem_helper.c │ │ ├── misc_helper.c │ │ ├── mmu_helper.c │ │ ├── s390-tod.h │ │ ├── sigp.c │ │ ├── tcg-stub.c │ │ ├── tcg_s390x.h │ │ ├── translate.c │ │ ├── translate_vx.inc.c │ │ ├── unicorn.c │ │ ├── unicorn.h │ │ ├── vec.h │ │ ├── vec_fpu_helper.c │ │ ├── vec_helper.c │ │ ├── vec_int_helper.c │ │ └── vec_string_helper.c │ ├── sparc │ │ ├── asi.h │ │ ├── cc_helper.c │ │ ├── cpu-param.h │ │ ├── cpu-qom.h │ │ ├── cpu.c │ │ ├── cpu.h │ │ ├── fop_helper.c │ │ ├── helper.c │ │ ├── helper.h │ │ ├── int32_helper.c │ │ ├── int64_helper.c │ │ ├── ldst_helper.c │ │ ├── mmu_helper.c │ │ ├── translate.c │ │ ├── unicorn.c │ │ ├── unicorn.h │ │ ├── unicorn64.c │ │ ├── vis_helper.c │ │ └── win_helper.c │ └── tricore │ │ ├── cpu-param.h │ │ ├── cpu-qom.h │ │ ├── cpu.c │ │ ├── cpu.h │ │ ├── csfr.def │ │ ├── fpu_helper.c │ │ ├── helper.c │ │ ├── helper.h │ │ ├── op_helper.c │ │ ├── translate.c │ │ ├── tricore-defs.h │ │ ├── tricore-opcodes.h │ │ ├── unicorn.c │ │ └── unicorn.h ├── tcg │ ├── README │ ├── aarch64 │ │ ├── tcg-target.h │ │ ├── tcg-target.inc.c │ │ └── tcg-target.opc.h │ ├── arm │ │ ├── tcg-target.h │ │ └── tcg-target.inc.c │ ├── i386 │ │ ├── tcg-target.h │ │ ├── tcg-target.inc.c │ │ └── tcg-target.opc.h │ ├── loongarch64 │ │ ├── tcg-insn-defs.c.inc │ │ ├── tcg-target.h │ │ └── tcg-target.inc.c │ ├── mips │ │ ├── tcg-target.h │ │ └── tcg-target.inc.c │ ├── optimize.c │ ├── ppc │ │ ├── tcg-target.h │ │ ├── tcg-target.inc.c │ │ └── tcg-target.opc.h │ ├── riscv │ │ ├── tcg-target.h │ │ └── tcg-target.inc.c │ ├── s390 │ │ ├── tcg-target.h │ │ └── tcg-target.inc.c │ ├── sparc │ │ ├── tcg-target.h │ │ └── tcg-target.inc.c │ ├── tcg-ldst.inc.c │ ├── tcg-op-gvec.c │ ├── tcg-op-vec.c │ ├── tcg-op.c │ ├── tcg-pool.inc.c │ └── tcg.c ├── trace │ ├── mem-internal.h │ └── mem.h ├── tricore.h ├── unicorn_common.h ├── util │ ├── bitmap.c │ ├── bitops.c │ ├── cacheinfo.c │ ├── crc32c.c │ ├── cutils.c │ ├── getauxval.c │ ├── guest-random.c │ ├── host-utils.c │ ├── osdep.c │ ├── oslib-efi.c │ ├── oslib-posix.c │ ├── oslib-win32.c │ ├── pagesize.c │ ├── qdist.c │ ├── qemu-thread-posix.c │ ├── qemu-thread-win32.c │ ├── qemu-timer-common.c │ ├── qemu-timer.c │ ├── qht.c │ ├── range.c │ └── setjmp-wrapper-win32.asm ├── vl.h └── x86_64.h ├── samples ├── Makefile ├── mem_apis.c ├── sample_all.sh ├── sample_arm.c ├── sample_arm64.c ├── sample_batch_reg.c ├── sample_ctl.c ├── sample_m68k.c ├── sample_mips.c ├── sample_ppc.c ├── sample_riscv.c ├── sample_s390x.c ├── sample_sparc.c ├── sample_tricore.c ├── sample_x86.c ├── sample_x86_32_gdt_and_seg_regs.c └── shellcode.c ├── symbols.sh ├── tests ├── fuzz │ ├── Makefile │ ├── dlcorpus.sh │ ├── fuzz_emu.options │ ├── fuzz_emu_arm64_arm.c │ ├── fuzz_emu_arm64_armbe.c │ ├── fuzz_emu_arm_arm.c │ ├── fuzz_emu_arm_armbe.c │ ├── fuzz_emu_arm_thumb.c │ ├── fuzz_emu_m68k_be.c │ ├── fuzz_emu_mips_32be.c │ ├── fuzz_emu_mips_32le.c │ ├── fuzz_emu_s390x_be.c │ ├── fuzz_emu_sparc_32be.c │ ├── fuzz_emu_x86_16.c │ ├── fuzz_emu_x86_32.c │ ├── fuzz_emu_x86_64.c │ ├── gentargets.sh │ ├── onedir.c │ └── onefile.c ├── regress │ ├── .gitignore │ ├── 001-bad_condition_code_0xe.c │ ├── 002-qemu__fatal__unimplemented_control_register_write_0xffb___0x0.c │ ├── 003-qemu__fatal__wdebug_not_implemented.c │ ├── 004-segmentation_fault_1.c │ ├── 005-qemu__fatal__illegal_instruction__0000___00000404.c │ ├── 006-qemu__fatal__illegal_instruction__0421___00040026.c │ ├── 00opcode_uc_crash.c │ ├── LICENSE │ ├── Makefile │ ├── arm64_reg_rw_w0_w30.py │ ├── arm_bx_unmapped.py │ ├── arm_bxeq_hang.py │ ├── arm_enable_vfp.c │ ├── arm_fp_vfp_disabled.py │ ├── arm_init_input_crash.py │ ├── arm_memcpy_neon.py │ ├── arm_movr12_hang.py │ ├── arm_vldr_invalid.py │ ├── arm_wfi_first_insn_of_tb.py │ ├── bad_ram.py │ ├── block_test.c │ ├── callback-pc.py │ ├── crash_tb.py │ ├── deadlock_1.py │ ├── eflags_noset.c │ ├── eflags_nosync.c │ ├── emu_clear_errors.c │ ├── emu_clear_errors.py │ ├── emu_stop_in_hook_overrun.c │ ├── emu_stop_segfault.py │ ├── ensure_typedef_consts_generated.py │ ├── fpu_ip.py │ ├── fpu_mem_write.py │ ├── hang.py │ ├── hook_add_crash.py │ ├── hook_code_add_del.py │ ├── hook_code_stop_emu.py │ ├── hook_extrainvoke.c │ ├── hook_raises_exception.py │ ├── hook_readonly_write_local.py │ ├── init.py │ ├── invalid_read_in_cpu_tb_exec.c │ ├── invalid_read_in_tb_flush_x86_64.c │ ├── invalid_write.py │ ├── invalid_write_in_cpu_tb_exec_x86_64.c │ ├── jmp_ebx_hang.py │ ├── jumping.py │ ├── leaked_refs.py │ ├── map_crash.c │ ├── map_write.c │ ├── memmap.py │ ├── memmap_segfault.py │ ├── mips_branch_delay.py │ ├── mips_branch_likely_issue.c │ ├── mips_cp1.py │ ├── mips_delay_slot_code_hook.c │ ├── mips_except.py │ ├── mips_invalid_read_of_size_4_when_tracing.c │ ├── mips_kernel_mmu.py │ ├── mips_kseg0_1.c │ ├── mips_single_step_sp.py │ ├── mips_syscall_pc.py │ ├── mov_gs_eax.py │ ├── movsd.py │ ├── nr_mem_test.c │ ├── osx_qemu_thread_create_crash.py │ ├── potential_memory_leak.py │ ├── pshufb.py │ ├── reg_write_sign_extension.py │ ├── regress.py │ ├── regress.sh │ ├── rep_hook.py │ ├── rep_movsb.c │ ├── ro_mem_test.c │ ├── run_across_bb.py │ ├── rw_hookstack.c │ ├── segfault_on_stop.py │ ├── sigill.c │ ├── sigill2.c │ ├── sparc64.py │ ├── sparc_jump_to_zero.c │ ├── sparc_reg.py │ ├── sysenter_hook_x86.c │ ├── tcg_liveness_analysis_bug_issue-287.py │ ├── threaded_emu_start.c │ ├── timeout_segfault.c │ ├── translator_buffer.py │ ├── vld.py │ ├── write_before_map.py │ ├── wrong_rip.py │ ├── wrong_rip_arm.py │ ├── wrong_sp_arm.py │ ├── x86_16_segfault.c │ ├── x86_64_conditional_jump.py │ ├── x86_64_eflags.py │ ├── x86_64_msr.py │ ├── x86_eflags.py │ ├── x86_fldt_fsqrt.py │ ├── x86_gdt.py │ ├── x86_ld_crash.py │ ├── x86_self_modifying.elf │ ├── x86_self_modifying.py │ ├── x86_self_modifying.s │ ├── x86_set_ip.py │ └── x86_vex.c ├── rust-tests │ └── main.rs └── unit │ ├── acutest.h │ ├── endian.h │ ├── test_arm.c │ ├── test_arm64.c │ ├── test_ctl.c │ ├── test_m68k.c │ ├── test_mem.c │ ├── test_mips.c │ ├── test_ppc.c │ ├── test_riscv.c │ ├── test_s390x.c │ ├── test_sparc.c │ ├── test_tricore.c │ ├── test_x86.c │ └── unicorn_test.h └── uc.c /.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: LLVM 2 | IndentWidth: 4 3 | UseTab: Never 4 | BreakBeforeBraces: Linux 5 | AllowShortIfStatementsOnASingleLine: Never 6 | AllowShortCaseLabelsOnASingleLine: false 7 | AllowShortBlocksOnASingleLine: Empty 8 | AllowShortFunctionsOnASingleLine: Empty 9 | AllowShortLoopsOnASingleLine: false 10 | IndentCaseLabels: false 11 | ColumnLimit: 80 12 | SortIncludes: false 13 | AllowShortLambdasOnASingleLine: Inline 14 | AlwaysBreakBeforeMultilineStrings: false 15 | BreakStringLiterals: true 16 | PointerAlignment: Right 17 | -------------------------------------------------------------------------------- /.github/README.md: -------------------------------------------------------------------------------- 1 | ../README_intel.md -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "docs/Unicorn_Engine_Documentation"] 2 | path = docs/Unicorn_Engine_Documentation 3 | url = https://github.com/kabeor/Unicorn-Engine-Documentation 4 | -------------------------------------------------------------------------------- /AUTHORS.TXT: -------------------------------------------------------------------------------- 1 | Nguyen Anh Quynh 2 | Dang Hoang Vu 3 | -------------------------------------------------------------------------------- /Brewfile: -------------------------------------------------------------------------------- 1 | # Travis CI setup for MacOS Brew 2 | 3 | # used for testing framework 4 | brew "cmocka" 5 | # used for cross assembly of code for testing 6 | brew "crosstool-ng" 7 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "unicorn-engine" 3 | version = "2.0.1" 4 | authors = ["Ziqiao Kong", "Lukas Seidel"] 5 | documentation = "https://github.com/unicorn-engine/unicorn/wiki" 6 | edition = "2021" 7 | license = "GPL-2.0" 8 | readme = "README.md" 9 | repository = "https://github.com/unicorn-engine/unicorn" 10 | description = "Rust bindings for the Unicorn emulator with utility functions" 11 | build = "bindings/rust/build.rs" 12 | links = "unicorn" 13 | # use `cargo publish --list` to see files to be included 14 | # the resulting list what cargo uses to check for out-of-date files during build 15 | exclude = [ 16 | "/docs", 17 | "/bindings/dotnet", 18 | "/bindings/go", 19 | "/bindings/haskell", 20 | "/bindings/java", 21 | "/bindings/pascal", 22 | "/bindings/python", 23 | "/bindings/ruby", 24 | "/bindings/vb6", 25 | "/samples", 26 | "/tests", 27 | ] 28 | 29 | [lib] 30 | path = "bindings/rust/src/lib.rs" 31 | 32 | [dependencies] 33 | bitflags = "1.3" 34 | libc = "0.2" 35 | 36 | [build-dependencies] 37 | cc = { version = "1.0" } 38 | cmake = { version = "0.1" } 39 | pkg-config = { version = "0.3" } 40 | 41 | [features] 42 | default = [] 43 | dynamic_linkage = [] -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | Intel is committed to rapidly addressing security vulnerabilities affecting our customers and providing clear guidance on the solution, impact, severity and mitigation. 3 | 4 | ## Reporting a Vulnerability 5 | Please report any security vulnerabilities in this project utilizing the guidelines [here](https://www.intel.com/content/www/us/en/security-center/vulnerability-handling-guidelines.html). 6 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | Moved to https://github.com/unicorn-engine/unicorn/milestones -------------------------------------------------------------------------------- /bindings/dotnet/README.md: -------------------------------------------------------------------------------- 1 | This documentation explains how to use the .NET binding for Unicorn 2 | from source. 3 | 4 | 0. Install the core engine as a dependency 5 | 6 | Follow README in the root directory to compile & install the core. 7 | 8 | 1. Compile the code 9 | 10 | You need to have at least version 5.0 of .NET installed. 11 | 12 | 1. Windows 13 | 14 | To compile the code open the UnicornSln.sln with Microsoft Visual 15 | Studio 12 or with a newer version and just press Ctrl+Shift+B to build 16 | the solution. 17 | 18 | 2. Linux 19 | 20 | To compile the code open a terminal in this directory 21 | and enter the following command to build the solution: 22 | `dotnet build` 23 | 24 | 2. Usage 25 | 26 | The solution includes the testing project UnicornTests with examples 27 | of usage. 28 | 29 | In order to use the library in your project just add a reference to 30 | the .NET library and be sure to copy the unmanaged unicorn.dll 31 | library in the output directory. 32 | 33 | The naming convention used is the Upper Camel Case, this mean that to 34 | invoke the uc_mem_read method you have to search for the MemRead method. 35 | -------------------------------------------------------------------------------- /bindings/dotnet/UnicornManaged/Binding/BindingFactory.fs: -------------------------------------------------------------------------------- 1 | namespace UnicornManaged.Binding 2 | 3 | 4 | module BindingFactory = 5 | let mutable _instance = NativeBinding.instance 6 | 7 | let setDefaultBinding(binding: IBinding) = 8 | _instance <- binding 9 | 10 | let getDefault() = 11 | _instance 12 | -------------------------------------------------------------------------------- /bindings/dotnet/UnicornManaged/Const/M68k.fs: -------------------------------------------------------------------------------- 1 | // For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT 2 | 3 | namespace UnicornManaged.Const 4 | 5 | open System 6 | 7 | [] 8 | module M68k = 9 | 10 | // M68K CPU 11 | 12 | let UC_CPU_M68K_M5206 = 0 13 | let UC_CPU_M68K_M68000 = 1 14 | let UC_CPU_M68K_M68020 = 2 15 | let UC_CPU_M68K_M68030 = 3 16 | let UC_CPU_M68K_M68040 = 4 17 | let UC_CPU_M68K_M68060 = 5 18 | let UC_CPU_M68K_M5208 = 6 19 | let UC_CPU_M68K_CFV4E = 7 20 | let UC_CPU_M68K_ANY = 8 21 | let UC_CPU_M68K_ENDING = 9 22 | 23 | // M68K registers 24 | 25 | let UC_M68K_REG_INVALID = 0 26 | let UC_M68K_REG_A0 = 1 27 | let UC_M68K_REG_A1 = 2 28 | let UC_M68K_REG_A2 = 3 29 | let UC_M68K_REG_A3 = 4 30 | let UC_M68K_REG_A4 = 5 31 | let UC_M68K_REG_A5 = 6 32 | let UC_M68K_REG_A6 = 7 33 | let UC_M68K_REG_A7 = 8 34 | let UC_M68K_REG_D0 = 9 35 | let UC_M68K_REG_D1 = 10 36 | let UC_M68K_REG_D2 = 11 37 | let UC_M68K_REG_D3 = 12 38 | let UC_M68K_REG_D4 = 13 39 | let UC_M68K_REG_D5 = 14 40 | let UC_M68K_REG_D6 = 15 41 | let UC_M68K_REG_D7 = 16 42 | let UC_M68K_REG_SR = 17 43 | let UC_M68K_REG_PC = 18 44 | let UC_M68K_REG_ENDING = 19 45 | 46 | -------------------------------------------------------------------------------- /bindings/dotnet/UnicornManaged/ConvertUtility.fs: -------------------------------------------------------------------------------- 1 | namespace UnicornManaged 2 | 3 | open System 4 | 5 | [] 6 | module internal ConvertUtility = 7 | 8 | let int64ToBytes(v: Int64) = 9 | let res = Array.zeroCreate 8 10 | let mutable uv = uint64 v 11 | for i = 0 to res.Length-1 do 12 | res.[i] <- byte (uv &&& uint64 0xFF) 13 | uv <- uv >>> 8 14 | res 15 | 16 | let bytesToInt64(v: Byte array) = 17 | let mutable res = uint64 0 18 | for i = 0 to v.Length-1 do 19 | let tmpV = v.[i] &&& byte 0xFF 20 | res <- res + (uint64 tmpV <<< (i * 8)) 21 | int64 res -------------------------------------------------------------------------------- /bindings/dotnet/UnicornManaged/UnicornEngineException.fs: -------------------------------------------------------------------------------- 1 | namespace UnicornManaged 2 | 3 | open System 4 | 5 | type UnicornEngineException(errNo: Int32, msg: String) = 6 | inherit ApplicationException(msg) 7 | 8 | member this.ErrorNo = errNo 9 | 10 | -------------------------------------------------------------------------------- /bindings/dotnet/UnicornSamples/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace UnicornSamples 4 | { 5 | internal static class Program 6 | { 7 | private static void Main(string[] args) 8 | { 9 | // X86 tests 32bit 10 | X86Sample32.X86Code32(); 11 | X86Sample32.X86Code32InvalidMemRead(); 12 | X86Sample32.X86Code32InvalidMemWriteWithRuntimeFix(); 13 | X86Sample32.X86Code32InOut(); 14 | 15 | // Run all shellcode tests 16 | ShellcodeSample.X86Code32Self(); 17 | ShellcodeSample.X86Code32(); 18 | 19 | Console.Write("Tests completed"); 20 | Console.ReadLine(); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /bindings/dotnet/UnicornSamples/UnicornSamples.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | net6.0 4 | Exe 5 | UnicornSamples 6 | UnicornSamples 7 | Copyright © Antonio Parata 2016 8 | https://github.com/unicorn-engine/unicorn 9 | 2.0.0 10 | {B80B5987-1E24-4309-8BF9-C4F91270F21C} 11 | true 12 | 13 | 14 | 15 | prompt 16 | 4 17 | 18 | 19 | 20 | 21 | {0c21f1c1-2725-4a46-9022-1905f85822a5} 22 | UnicornManaged 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /bindings/dotnet/UnicornSamples/Utils.cs: -------------------------------------------------------------------------------- 1 | using Gee.External.Capstone.X86; 2 | using System; 3 | using System.Text; 4 | 5 | namespace UnicornSamples 6 | { 7 | internal static class Utils 8 | { 9 | public static long ToInt(byte[] val) 10 | { 11 | ulong res = 0; 12 | for (var i = 0; i < val.Length; i++) 13 | { 14 | var v = val[i] & 0xFF; 15 | res += (ulong)(v << (i * 8)); 16 | } 17 | return (long)res; 18 | } 19 | 20 | public static byte[] Int64ToBytes(long intVal) 21 | { 22 | var res = new byte[8]; 23 | var uval = (ulong)intVal; 24 | for (var i = 0; i < res.Length; i++) 25 | { 26 | res[i] = (byte)(uval & 0xff); 27 | uval = uval >> 8; 28 | } 29 | return res; 30 | } 31 | 32 | public static string Disassemble(CapstoneX86Disassembler disassembler, byte[] code) 33 | { 34 | var sb = new StringBuilder(); 35 | var instructions = disassembler.Disassemble(code); 36 | foreach (var instruction in instructions) 37 | { 38 | sb.AppendFormat($"{instruction.Mnemonic} {instruction.Operand}{Environment.NewLine}"); 39 | } 40 | return sb.ToString().Trim(); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /bindings/go/Makefile: -------------------------------------------------------------------------------- 1 | # Go binding for Unicorn engine. Ryan Hileman 2 | 3 | .PHONY: all gen_const test 4 | 5 | all: gen_const 6 | cd unicorn && go build 7 | 8 | gen_const: 9 | cd .. && python3 const_generator.py go 10 | 11 | test: all 12 | cd unicorn && LD_LIBRARY_PATH=../../../ DYLD_LIBRARY_PATH=../../../ go test 13 | -------------------------------------------------------------------------------- /bindings/go/README.md: -------------------------------------------------------------------------------- 1 | To download/update the Unicorn Go bindings, run: 2 | 3 | go get -u github.com/unicorn-engine/unicorn/bindings/go 4 | 5 | A very basic usage example follows 6 | 7 | _(Does not handle most errors for brevity. Please see sample.go for a more hygenic example):_ 8 | 9 | package main 10 | 11 | import ( 12 | "fmt" 13 | uc "github.com/unicorn-engine/unicorn/bindings/go/unicorn" 14 | ) 15 | 16 | func main() { 17 | mu, _ := uc.NewUnicorn(uc.ARCH_X86, uc.MODE_32) 18 | // mov eax, 1234 19 | code := []byte{184, 210, 4, 0, 0} 20 | mu.MemMap(0x1000, 0x1000) 21 | mu.MemWrite(0x1000, code) 22 | if err := mu.Start(0x1000, 0x1000+uint64(len(code))); err != nil { 23 | panic(err) 24 | } 25 | eax, _ := mu.RegRead(uc.X86_REG_EAX) 26 | fmt.Printf("EAX is now: %d\n", eax) 27 | } 28 | 29 | An example program exercising far more Unicorn functionality and error handling can be found in sample.go. 30 | -------------------------------------------------------------------------------- /bindings/go/unicorn/context.go: -------------------------------------------------------------------------------- 1 | package unicorn 2 | 3 | import ( 4 | "runtime" 5 | "unsafe" 6 | ) 7 | 8 | // #include 9 | import "C" 10 | 11 | type Context **C.uc_context 12 | 13 | func (u *uc) ContextSave(reuse Context) (Context, error) { 14 | ctx := reuse 15 | if ctx == nil { 16 | ctx = new(*C.uc_context) 17 | } 18 | if err := errReturn(C.uc_context_alloc(u.handle, ctx)); err != nil { 19 | return nil, err 20 | } 21 | runtime.SetFinalizer(ctx, func(p Context) { C.uc_free(unsafe.Pointer(*p)) }) 22 | if err := errReturn(C.uc_context_save(u.handle, *ctx)); err != nil { 23 | } 24 | return ctx, nil 25 | } 26 | 27 | func (u *uc) ContextRestore(ctx Context) error { 28 | return errReturn(C.uc_context_restore(u.handle, *ctx)) 29 | } 30 | -------------------------------------------------------------------------------- /bindings/go/unicorn/context_test.go: -------------------------------------------------------------------------------- 1 | package unicorn 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestContext(t *testing.T) { 8 | u, err := NewUnicorn(ARCH_X86, MODE_32) 9 | if err != nil { 10 | t.Fatal(err) 11 | } 12 | u.RegWrite(X86_REG_EBP, 100) 13 | ctx, err := u.ContextSave(nil) 14 | if err != nil { 15 | t.Fatal(err) 16 | } 17 | u.RegWrite(X86_REG_EBP, 200) 18 | err = u.ContextRestore(ctx) 19 | if err != nil { 20 | t.Fatal(err) 21 | } 22 | val, _ := u.RegRead(X86_REG_EBP) 23 | if val != 100 { 24 | t.Fatal("context restore failed") 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /bindings/go/unicorn/hook.h: -------------------------------------------------------------------------------- 1 | uc_err uc_hook_add_wrap(uc_engine *handle, uc_hook *h2, uc_hook_type type, void *callback, uintptr_t user, uint64_t begin, uint64_t end); 2 | uc_err uc_hook_add_insn(uc_engine *handle, uc_hook *h2, uc_hook_type type, void *callback, uintptr_t user, uint64_t begin, uint64_t end, int insn); 3 | void hookCode_cgo(uc_engine *handle, uint64_t addr, uint32_t size, uintptr_t user); 4 | bool hookMemInvalid_cgo(uc_engine *handle, uc_mem_type type, uint64_t addr, int size, int64_t value, uintptr_t user); 5 | void hookMemAccess_cgo(uc_engine *handle, uc_mem_type type, uint64_t addr, int size, int64_t value, uintptr_t user); 6 | void hookInterrupt_cgo(uc_engine *handle, uint32_t intno, uintptr_t user); 7 | uint32_t hookX86In_cgo(uc_engine *handle, uint32_t port, uint32_t size, uintptr_t user); 8 | void hookX86Out_cgo(uc_engine *handle, uint32_t port, uint32_t size, uint32_t value, uintptr_t user); 9 | void hookX86Syscall_cgo(uc_engine *handle, uintptr_t user); 10 | -------------------------------------------------------------------------------- /bindings/go/unicorn/m68k_const.go: -------------------------------------------------------------------------------- 1 | package unicorn 2 | // For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT [m68k_const.go] 3 | const ( 4 | 5 | // M68K CPU 6 | 7 | CPU_M68K_M5206 = 0 8 | CPU_M68K_M68000 = 1 9 | CPU_M68K_M68020 = 2 10 | CPU_M68K_M68030 = 3 11 | CPU_M68K_M68040 = 4 12 | CPU_M68K_M68060 = 5 13 | CPU_M68K_M5208 = 6 14 | CPU_M68K_CFV4E = 7 15 | CPU_M68K_ANY = 8 16 | CPU_M68K_ENDING = 9 17 | 18 | // M68K registers 19 | 20 | M68K_REG_INVALID = 0 21 | M68K_REG_A0 = 1 22 | M68K_REG_A1 = 2 23 | M68K_REG_A2 = 3 24 | M68K_REG_A3 = 4 25 | M68K_REG_A4 = 5 26 | M68K_REG_A5 = 6 27 | M68K_REG_A6 = 7 28 | M68K_REG_A7 = 8 29 | M68K_REG_D0 = 9 30 | M68K_REG_D1 = 10 31 | M68K_REG_D2 = 11 32 | M68K_REG_D3 = 12 33 | M68K_REG_D4 = 13 34 | M68K_REG_D5 = 14 35 | M68K_REG_D6 = 15 36 | M68K_REG_D7 = 16 37 | M68K_REG_SR = 17 38 | M68K_REG_PC = 18 39 | M68K_REG_ENDING = 19 40 | ) -------------------------------------------------------------------------------- /bindings/go/unicorn/uc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "_cgo_export.h" 4 | 5 | uc_err uc_reg_read_batch_helper(uc_engine *handle, int *regs, uint64_t *val_out, int count) { 6 | void **val_ref = malloc(sizeof(void *) * count); 7 | int i; 8 | for (i = 0; i < count; i++) { 9 | val_ref[i] = (void *)&val_out[i]; 10 | } 11 | uc_err ret = uc_reg_read_batch(handle, regs, val_ref, count); 12 | free(val_ref); 13 | return ret; 14 | } 15 | 16 | uc_err uc_reg_write_batch_helper(uc_engine *handle, int *regs, uint64_t *val_in, int count) { 17 | void **val_ref = malloc(sizeof(void *) * count); 18 | int i; 19 | for (i = 0; i < count; i++) { 20 | val_ref[i] = (void *)&val_in[i]; 21 | } 22 | uc_err ret = uc_reg_write_batch(handle, regs, (void *const *)val_ref, count); 23 | free(val_ref); 24 | return ret; 25 | } 26 | 27 | uc_err uc_ctl_set_cpu_model_helper(uc_engine *handle, int model) { 28 | return uc_ctl_set_cpu_model(handle, model); 29 | } 30 | -------------------------------------------------------------------------------- /bindings/go/unicorn/uc.h: -------------------------------------------------------------------------------- 1 | uc_err uc_reg_read_batch_helper(uc_engine *handle, int *regs, uint64_t *val_out, int count); 2 | uc_err uc_reg_write_batch_helper(uc_engine *handle, int *regs, uint64_t *val_in, int count); 3 | uc_err uc_ctl_set_cpu_model_helper(uc_engine *handle, int model); 4 | -------------------------------------------------------------------------------- /bindings/haskell/.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | cabal-dev 3 | *.o 4 | *.hi 5 | *.chi 6 | *.chs.h 7 | *.dyn_o 8 | *.dyn_hi 9 | .virtualenv 10 | .hpc 11 | .hsenv 12 | .cabal-sandbox/ 13 | cabal.sandbox.config 14 | *.prof 15 | *.aux 16 | *.hp 17 | SampleArm 18 | SampleArm64 19 | SampleM68k 20 | SampleMips 21 | SampleSparc 22 | SampleX86 23 | Shellcode 24 | SampleBatchReg 25 | -------------------------------------------------------------------------------- /bindings/haskell/README.TXT: -------------------------------------------------------------------------------- 1 | This documentation explains how to install Haskell binding for Unicorn 2 | from source. 3 | 4 | 5 | 0. Install the core engine as dependency 6 | 7 | Follow README in the root directory to compile & install the core. 8 | 9 | On *nix, this can simply be done by (project root directory): 10 | 11 | $ sudo ./make.sh install 12 | 13 | 14 | 1. Change directories into the Haskell bindings, build and install 15 | 16 | $ cd bindings/haskell 17 | $ cabal install 18 | 19 | 20 | If you are installing into a sandbox, run `cabal sandbox init` before 21 | installing Unicorn's dependencies. 22 | 23 | If the build fails, install c2hs manually `cabal install c2hs` (note that this 24 | will probably also require you to run `cabal install alex` and `cabal install 25 | happy` as well). If you are NOT using a sandbox, ensure that `$HOME/.cabal/bin` 26 | is on your PATH. 27 | 28 | To build a sample (after having built and installed the Haskell bindings) 29 | 30 | $ cd bindings/haskell 31 | $ ghc --make samples/SampleArm.hs 32 | -------------------------------------------------------------------------------- /bindings/haskell/Setup.hs: -------------------------------------------------------------------------------- 1 | import Distribution.Simple 2 | main = defaultMain 3 | -------------------------------------------------------------------------------- /bindings/haskell/src/Unicorn/CPU/Arm.chs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE ForeignFunctionInterface #-} 2 | 3 | {-| 4 | Module : Unicorn.CPU.Arm 5 | Description : Definitions for the ARM architecture. 6 | Copyright : (c) Adrian Herrera, 2016 7 | License : GPL-2 8 | 9 | Definitions for the ARM architecture. 10 | -} 11 | module Unicorn.CPU.Arm 12 | ( 13 | Register(..) 14 | ) where 15 | 16 | import Unicorn.Internal.Core (Reg) 17 | 18 | {# context lib = "unicorn" #} 19 | 20 | #include 21 | 22 | -- | ARM registers. 23 | {# enum uc_arm_reg as Register 24 | { underscoreToCase } 25 | omit ( UC_ARM_REG_INVALID 26 | , UC_ARM_REG_ENDING 27 | ) 28 | with prefix = "UC_ARM_REG_" 29 | deriving (Show, Eq, Bounded) 30 | #} 31 | 32 | instance Reg Register 33 | -------------------------------------------------------------------------------- /bindings/haskell/src/Unicorn/CPU/Arm64.chs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE ForeignFunctionInterface #-} 2 | 3 | {-| 4 | Module : Unicorn.CPU.Arm64 5 | Description : Definitions for the ARM64 (ARMv8) architecture. 6 | Copyright : (c) Adrian Herrera, 2016 7 | License : GPL-2 8 | 9 | Definitions for the ARM64 (ARMv8) architecture. 10 | -} 11 | module Unicorn.CPU.Arm64 12 | ( 13 | Register(..) 14 | ) where 15 | 16 | import Unicorn.Internal.Core (Reg) 17 | 18 | {# context lib = "unicorn" #} 19 | 20 | #include 21 | 22 | -- | ARM64 registers. 23 | {# enum uc_arm64_reg as Register 24 | { underscoreToCase } 25 | omit ( UC_ARM64_REG_INVALID 26 | , UC_ARM64_REG_ENDING 27 | ) 28 | with prefix = "UC_ARM64_REG_" 29 | deriving (Show, Eq, Bounded) 30 | #} 31 | 32 | instance Reg Register 33 | -------------------------------------------------------------------------------- /bindings/haskell/src/Unicorn/CPU/M68k.chs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE ForeignFunctionInterface #-} 2 | 3 | {-| 4 | Module : Unicorn.CPU.Mk68k 5 | Description : Definitions for the MK68K architecture. 6 | Copyright : (c) Adrian Herrera, 2016 7 | License : GPL-2 8 | 9 | Definitions for the MK68K architecture. 10 | -} 11 | module Unicorn.CPU.M68k 12 | ( 13 | Register(..) 14 | ) where 15 | 16 | import Unicorn.Internal.Core (Reg) 17 | 18 | {# context lib = "unicorn" #} 19 | 20 | #include 21 | 22 | -- | M68K registers. 23 | {# enum uc_m68k_reg as Register 24 | { underscoreToCase } 25 | omit ( UC_M68K_REG_INVALID 26 | , UC_M68K_REG_ENDING 27 | ) 28 | with prefix = "UC_M68K_REG_" 29 | deriving (Show, Eq, Bounded) 30 | #} 31 | 32 | instance Reg Register 33 | -------------------------------------------------------------------------------- /bindings/haskell/src/Unicorn/CPU/Sparc.chs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE ForeignFunctionInterface #-} 2 | 3 | {-| 4 | Module : Unicorn.CPU.Sparc 5 | Description : Definitions for the SPARC architecture. 6 | Copyright : (c) Adrian Herrera, 2016 7 | License : GPL-2 8 | 9 | Definitions for the SPARC architecture. 10 | -} 11 | module Unicorn.CPU.Sparc 12 | ( 13 | Register(..) 14 | ) where 15 | 16 | import Unicorn.Internal.Core (Reg) 17 | 18 | {# context lib = "unicorn" #} 19 | 20 | #include 21 | 22 | -- | SPARC registers. 23 | {# enum uc_sparc_reg as Register 24 | { underscoreToCase } 25 | omit (UC_SPARC_REG_INVALID 26 | , UC_SPARC_REG_ENDING 27 | ) 28 | with prefix = "UC_SPARC_REG_" 29 | deriving (Show, Eq, Bounded) 30 | #} 31 | 32 | instance Reg Register 33 | -------------------------------------------------------------------------------- /bindings/haskell/src/Unicorn/Internal/Util.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module : Unicorn.Internal.Util 3 | Description : Utility (aka helper) functions for the Unicorn emulator. 4 | Copyright : (c) Adrian Herrera, 2016 5 | License : GPL-2 6 | -} 7 | module Unicorn.Internal.Util where 8 | 9 | import Data.Bits 10 | import Foreign 11 | 12 | -- | Combine a list of Enums by performing a bitwise-OR. 13 | combineEnums :: (Enum a, Num b, Bits b) 14 | => [a] 15 | -> b 16 | combineEnums = 17 | foldr ((.|.) <$> enumToNum) 0 18 | 19 | -- | Cast a pointer and then peek inside it. 20 | castPtrAndPeek :: Storable a 21 | => Ptr b 22 | -> IO a 23 | castPtrAndPeek = 24 | peek . castPtr 25 | 26 | -- | Convert an 'Eum' to a 'Num'. 27 | enumToNum :: (Enum a, Num b) 28 | => a 29 | -> b 30 | enumToNum = 31 | fromIntegral . fromEnum 32 | -------------------------------------------------------------------------------- /bindings/haskell/src/cbits/unicorn_wrapper.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "unicorn_wrapper.h" 4 | 5 | void uc_close_wrapper(uc_engine *uc) { 6 | uc_close(uc); 7 | } 8 | 9 | void uc_close_dummy(uc_engine *uc) { 10 | } 11 | 12 | uc_err uc_reg_write_wrapper(uc_engine *uc, int regid, const int64_t *value) { 13 | return uc_reg_write(uc, regid, (const void*) value); 14 | } 15 | 16 | uc_err uc_reg_read_wrapper(uc_engine *uc, int regid, int64_t *value) { 17 | return uc_reg_read(uc, regid, (void*) value); 18 | } 19 | 20 | uc_err uc_reg_write_batch_wrapper(uc_engine *uc, int *regs, int64_t *vals, int count) { 21 | void **valsPtr = malloc(sizeof(void*) * count); 22 | int i; 23 | 24 | for (i = 0; i < count; ++i) { 25 | valsPtr[i] = (void*) &vals[i]; 26 | } 27 | 28 | uc_err ret = uc_reg_write_batch(uc, regs, (void *const*) valsPtr, count); 29 | free(valsPtr); 30 | 31 | return ret; 32 | } 33 | 34 | uc_err uc_reg_read_batch_wrapper(uc_engine *uc, int *regs, int64_t *vals, int count) { 35 | void **valsPtr = malloc(sizeof(void*) * count); 36 | int i; 37 | 38 | for (i = 0; i < count; ++i) { 39 | valsPtr[i] = (void*) &vals[i]; 40 | } 41 | 42 | uc_err ret = uc_reg_read_batch(uc, regs, valsPtr, count); 43 | free(valsPtr); 44 | 45 | return ret; 46 | } 47 | 48 | void uc_free_wrapper(void *mem) { 49 | uc_free(mem); 50 | } 51 | -------------------------------------------------------------------------------- /bindings/haskell/src/include/unicorn_wrapper.h: -------------------------------------------------------------------------------- 1 | #ifndef UNICORN_WRAPPER_H 2 | #define UNICORN_WRAPPER_H 3 | 4 | #include 5 | #include 6 | 7 | /* 8 | * Wrap Unicorn's uc_close function and ignore the returned error code. 9 | */ 10 | void uc_close_wrapper(uc_engine *uc); 11 | 12 | /* 13 | * Doesn't actually do anything. 14 | */ 15 | void uc_close_dummy(uc_engine *uc); 16 | 17 | /* 18 | * Wrappers for register read/write functions that accept int64_t pointers. 19 | */ 20 | uc_err uc_reg_write_wrapper(uc_engine *uc, int regid, const int64_t *value); 21 | uc_err uc_reg_read_wrapper(uc_engine *uc, int regid, int64_t *value); 22 | uc_err uc_reg_write_batch_wrapper(uc_engine *uc, int *regs, int64_t *vals, int count); 23 | uc_err uc_reg_read_batch_wrapper(uc_engine *uc, int *regs, int64_t *vals, int count); 24 | 25 | /* 26 | * Wrap Unicorn's uc_free function and ignore the returned error code. 27 | */ 28 | void uc_free_wrapper(void *context); 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /bindings/java/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: gen_const clean jar all lib samples install 2 | 3 | all: gen_const 4 | $(MAKE) -f Makefile.build all 5 | 6 | lib: 7 | $(MAKE) -f Makefile.build lib 8 | 9 | samples: 10 | $(MAKE) -f Makefile.build samples 11 | 12 | jar: 13 | $(MAKE) -f Makefile.build jar 14 | 15 | install: lib jar 16 | $(MAKE) -f Makefile.build install 17 | 18 | uninstall: 19 | $(MAKE) -f Makefile.build uninstall 20 | 21 | gen_const: 22 | cd .. && python3 const_generator.py java 23 | 24 | clean: 25 | rm -f unicorn/*.class 26 | rm -f samples/*.class 27 | rm -f *.so 28 | rm -f *.dylib 29 | rm -f *.dll 30 | -------------------------------------------------------------------------------- /bindings/java/README.TXT: -------------------------------------------------------------------------------- 1 | This documentation explains how to install the Java binding for Unicorn 2 | from source. 3 | 4 | 0. Install the core engine as dependency 5 | 6 | Follow README in the root directory to compile & install the core. 7 | 8 | On *nix, this can simply done by: 9 | 10 | $ sudo ./make.sh install 11 | 12 | 13 | 1. Install a JDK for your platform. When done, make sure the JDK tools 14 | are in your PATH. 15 | 16 | 2. Change directories into the java bindings, build and install 17 | 18 | $ cd bindings/java 19 | $ make 20 | $ sudo make install 21 | $ make samples 22 | 23 | The samples directory contains some sample code to show how to use Unicorn API. 24 | 25 | - Sample_.java 26 | These show how to access architecture-specific information for each 27 | architecture. 28 | 29 | - Shellcode.java 30 | This shows how to analyze a Linux shellcode. 31 | 32 | - SampleNetworkAuditing.java 33 | Unicorn sample for auditing network connection and file handling in shellcode. 34 | 35 | To uninstall Java binding for Unicorn: 36 | 37 | $ sudo make uninstall 38 | -------------------------------------------------------------------------------- /bindings/java/unicorn/BlockHook.java: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Java bindings for the Unicorn Emulator Engine 4 | 5 | Copyright(c) 2015 Chris Eagle 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License 9 | version 2 as published by the Free Software Foundation. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | 20 | */ 21 | 22 | package unicorn; 23 | 24 | public interface BlockHook extends Hook { 25 | 26 | public void hook(Unicorn u, long address, int size, Object user); 27 | 28 | } 29 | 30 | -------------------------------------------------------------------------------- /bindings/java/unicorn/CodeHook.java: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Java bindings for the Unicorn Emulator Engine 4 | 5 | Copyright(c) 2015 Chris Eagle 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License 9 | version 2 as published by the Free Software Foundation. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | 20 | */ 21 | 22 | package unicorn; 23 | 24 | public interface CodeHook extends Hook { 25 | 26 | public void hook(Unicorn u, long address, int size, Object user); 27 | 28 | } 29 | 30 | -------------------------------------------------------------------------------- /bindings/java/unicorn/EventMemHook.java: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Java bindings for the Unicorn Emulator Engine 4 | 5 | Copyright(c) 2015 Chris Eagle 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License 9 | version 2 as published by the Free Software Foundation. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | 20 | */ 21 | 22 | package unicorn; 23 | 24 | public interface EventMemHook extends Hook { 25 | 26 | public boolean hook(Unicorn u, long address, int size, long value, Object user); 27 | 28 | } 29 | 30 | -------------------------------------------------------------------------------- /bindings/java/unicorn/Hook.java: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Java bindings for the Unicorn Emulator Engine 4 | 5 | Copyright(c) 2015 Chris Eagle 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License 9 | version 2 as published by the Free Software Foundation. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | 20 | */ 21 | 22 | package unicorn; 23 | 24 | /** 25 | * Base class for all unicorn hooking interfaces 26 | */ 27 | 28 | public interface Hook { 29 | } 30 | -------------------------------------------------------------------------------- /bindings/java/unicorn/InHook.java: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Java bindings for the Unicorn Emulator Engine 4 | 5 | Copyright(c) 2015 Chris Eagle 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License 9 | version 2 as published by the Free Software Foundation. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | 20 | */ 21 | 22 | package unicorn; 23 | 24 | public interface InHook extends Hook { 25 | 26 | public int hook(Unicorn u, int port, int size, Object user); 27 | 28 | } 29 | 30 | -------------------------------------------------------------------------------- /bindings/java/unicorn/InterruptHook.java: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Java bindings for the Unicorn Emulator Engine 4 | 5 | Copyright(c) 2015 Chris Eagle 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License 9 | version 2 as published by the Free Software Foundation. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | 20 | */ 21 | 22 | package unicorn; 23 | 24 | public interface InterruptHook extends Hook { 25 | 26 | public void hook(Unicorn u, int intno, Object user); 27 | 28 | } 29 | 30 | -------------------------------------------------------------------------------- /bindings/java/unicorn/MemHook.java: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Java bindings for the Unicorn Emulator Engine 4 | 5 | Copyright(c) 2015 Chris Eagle 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License 9 | version 2 as published by the Free Software Foundation. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | 20 | */ 21 | 22 | package unicorn; 23 | 24 | public interface MemHook extends ReadHook,WriteHook { 25 | 26 | } 27 | 28 | -------------------------------------------------------------------------------- /bindings/java/unicorn/MemRegion.java: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Java bindings for the Unicorn Emulator Engine 4 | 5 | Copyright(c) 2016 Chris Eagle 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License 9 | version 2 as published by the Free Software Foundation. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | 20 | */ 21 | 22 | package unicorn; 23 | 24 | public class MemRegion { 25 | 26 | public long begin; 27 | public long end; 28 | public int perms; 29 | 30 | public MemRegion(long begin, long end, int perms) { 31 | this.begin = begin; 32 | this.end = end; 33 | this.perms = perms; 34 | } 35 | 36 | } 37 | 38 | -------------------------------------------------------------------------------- /bindings/java/unicorn/OutHook.java: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Java bindings for the Unicorn Emulator Engine 4 | 5 | Copyright(c) 2015 Chris Eagle 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License 9 | version 2 as published by the Free Software Foundation. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | 20 | */ 21 | 22 | package unicorn; 23 | 24 | public interface OutHook extends Hook { 25 | 26 | public void hook(Unicorn u, int port, int size, int value, Object user); 27 | 28 | } 29 | 30 | -------------------------------------------------------------------------------- /bindings/java/unicorn/ReadHook.java: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Java bindings for the Unicorn Emulator Engine 4 | 5 | Copyright(c) 2015 Chris Eagle 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License 9 | version 2 as published by the Free Software Foundation. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | 20 | */ 21 | 22 | package unicorn; 23 | 24 | public interface ReadHook extends Hook { 25 | 26 | public void hook(Unicorn u, long address, int size, Object user); 27 | 28 | } 29 | 30 | -------------------------------------------------------------------------------- /bindings/java/unicorn/SyscallHook.java: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Java bindings for the Unicorn Emulator Engine 4 | 5 | Copyright(c) 2015 Chris Eagle 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License 9 | version 2 as published by the Free Software Foundation. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | 20 | */ 21 | 22 | package unicorn; 23 | 24 | public interface SyscallHook extends Hook { 25 | 26 | public void hook(Unicorn u, Object user); 27 | 28 | } 29 | 30 | -------------------------------------------------------------------------------- /bindings/java/unicorn/UnicornException.java: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Java bindings for the Unicorn Emulator Engine 4 | 5 | Copyright(c) 2015 Chris Eagle 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License 9 | version 2 as published by the Free Software Foundation. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | 20 | */ 21 | 22 | package unicorn; 23 | 24 | public class UnicornException extends RuntimeException { 25 | 26 | public UnicornException() { 27 | super(); 28 | } 29 | 30 | public UnicornException(String msg) { 31 | super(msg); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /bindings/java/unicorn/WriteHook.java: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Java bindings for the Unicorn Emulator Engine 4 | 5 | Copyright(c) 2015 Chris Eagle 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License 9 | version 2 as published by the Free Software Foundation. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | 20 | */ 21 | 22 | package unicorn; 23 | 24 | public interface WriteHook extends Hook { 25 | 26 | public void hook(Unicorn u, long address, int size, long value, Object user); 27 | 28 | } 29 | 30 | -------------------------------------------------------------------------------- /bindings/java/unicorn/X86_MMR.java: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Java bindings for the Unicorn Emulator Engine 4 | 5 | Copyright(c) 2016 Chris Eagle 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License 9 | version 2 as published by the Free Software Foundation. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | 20 | */ 21 | 22 | package unicorn; 23 | 24 | public class X86_MMR { 25 | 26 | public long base; 27 | public int limit; 28 | public int flags; 29 | public short selector; 30 | 31 | public X86_MMR(long base, int limit, int flags, short selector) { 32 | this.base = base; 33 | this.limit = limit; 34 | this.flags = flags; 35 | this.selector = selector; 36 | } 37 | 38 | public X86_MMR(long base, int limit) { 39 | this.base = base; 40 | this.limit = limit; 41 | selector = 0; 42 | flags = 0; 43 | } 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /bindings/pascal/unicorn/M68kConst.pas: -------------------------------------------------------------------------------- 1 | // For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT 2 | 3 | unit M68kConst; 4 | 5 | interface 6 | 7 | const 8 | // M68K CPU 9 | 10 | UC_CPU_M68K_M5206 = 0; 11 | UC_CPU_M68K_M68000 = 1; 12 | UC_CPU_M68K_M68020 = 2; 13 | UC_CPU_M68K_M68030 = 3; 14 | UC_CPU_M68K_M68040 = 4; 15 | UC_CPU_M68K_M68060 = 5; 16 | UC_CPU_M68K_M5208 = 6; 17 | UC_CPU_M68K_CFV4E = 7; 18 | UC_CPU_M68K_ANY = 8; 19 | UC_CPU_M68K_ENDING = 9; 20 | 21 | // M68K registers 22 | 23 | UC_M68K_REG_INVALID = 0; 24 | UC_M68K_REG_A0 = 1; 25 | UC_M68K_REG_A1 = 2; 26 | UC_M68K_REG_A2 = 3; 27 | UC_M68K_REG_A3 = 4; 28 | UC_M68K_REG_A4 = 5; 29 | UC_M68K_REG_A5 = 6; 30 | UC_M68K_REG_A6 = 7; 31 | UC_M68K_REG_A7 = 8; 32 | UC_M68K_REG_D0 = 9; 33 | UC_M68K_REG_D1 = 10; 34 | UC_M68K_REG_D2 = 11; 35 | UC_M68K_REG_D3 = 12; 36 | UC_M68K_REG_D4 = 13; 37 | UC_M68K_REG_D5 = 14; 38 | UC_M68K_REG_D6 = 15; 39 | UC_M68K_REG_D7 = 16; 40 | UC_M68K_REG_SR = 17; 41 | UC_M68K_REG_PC = 18; 42 | UC_M68K_REG_ENDING = 19; 43 | 44 | implementation 45 | end. -------------------------------------------------------------------------------- /bindings/python/MANIFEST.in: -------------------------------------------------------------------------------- 1 | recursive-include src * 2 | recursive-include prebuilt * 3 | include LICENSE.TXT 4 | include README.TXT 5 | -------------------------------------------------------------------------------- /bindings/python/README.TXT: -------------------------------------------------------------------------------- 1 | This documentation explains how to install the python binding for Unicorn 2 | from source. 3 | 4 | 1. Installing on Linux: 5 | 6 | $ sudo python setup.py install 7 | 8 | This will build the core C library, package it with the python bindings, 9 | and install it to your system. 10 | 11 | If you want to prevent the build of the native library during the python installation, 12 | set the environment variable LIBUNICORN_PATH. You may also set this to a directory 13 | containing libunicorn.so if you wish to use a verison of the native library other than 14 | the globally installed one. 15 | 16 | 17 | 2. Installing on Windows: 18 | 19 | Run the following command in command prompt: 20 | 21 | C:\> C:\location_to_python\python.exe setup.py install 22 | 23 | Next, copy all the DLL files from the 'Core engine for Windows' package available 24 | on the Unicorn download page and paste it in the path: 25 | 26 | C:\location_to_python\Lib\site-packages\unicorn\ 27 | 28 | 29 | 3. Sample code 30 | 31 | This directory contains some sample code to show how to use Unicorn API. 32 | 33 | - sample_.py 34 | These code show how to access architecture-specific information for each 35 | architecture. 36 | 37 | - shellcode.py 38 | This shows how to analyze a Linux shellcode. 39 | 40 | - sample_network_auditing.py 41 | This shows how to analyze & interpret Linux shellcode. 42 | -------------------------------------------------------------------------------- /bindings/python/build_wheel.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e -x 3 | 4 | cd bindings/python 5 | 6 | # Compile wheels 7 | if [ -f /opt/python/cp36-cp36m/bin/python ];then 8 | /opt/python/cp36-cp36m/bin/python setup.py bdist_wheel $@ 9 | else 10 | python3 setup.py bdist_wheel $@ 11 | fi 12 | cd dist 13 | 14 | # We can't repair an aarch64 wheel on x64 hosts 15 | # https://github.com/pypa/auditwheel/issues/244 16 | if [[ ! "$*" =~ "aarch64" ]];then 17 | auditwheel repair *.whl 18 | mv -f wheelhouse/*.whl . 19 | fi -------------------------------------------------------------------------------- /bindings/python/prebuilt/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/unicorn-for-efi/40a8d07ba3cef067d9a6455c163dbed8d94f8e38/bindings/python/prebuilt/.gitkeep -------------------------------------------------------------------------------- /bindings/python/sample_all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ./sample_x86.py 4 | echo "==========================" 5 | ./shellcode.py 6 | echo "==========================" 7 | ./sample_arm.py 8 | echo "==========================" 9 | ./sample_arm64.py 10 | echo "==========================" 11 | ./sample_mips.py 12 | echo "==========================" 13 | ./sample_sparc.py 14 | echo "==========================" 15 | ./sample_m68k.py 16 | -------------------------------------------------------------------------------- /bindings/python/setup.cfg: -------------------------------------------------------------------------------- 1 | [bdist_wheel] 2 | universal=1 3 | -------------------------------------------------------------------------------- /bindings/python/unicorn/__init__.py: -------------------------------------------------------------------------------- 1 | # Unicorn Python bindings, by Nguyen Anh Quynnh 2 | from . import arm_const, arm64_const, mips_const, sparc_const, m68k_const, x86_const 3 | from .unicorn_const import * 4 | from .unicorn import Uc, uc_version, uc_arch_supported, version_bind, debug, UcError, __version__ 5 | -------------------------------------------------------------------------------- /bindings/python/unicorn/m68k_const.py: -------------------------------------------------------------------------------- 1 | # For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT [m68k_const.py] 2 | 3 | # M68K CPU 4 | 5 | UC_CPU_M68K_M5206 = 0 6 | UC_CPU_M68K_M68000 = 1 7 | UC_CPU_M68K_M68020 = 2 8 | UC_CPU_M68K_M68030 = 3 9 | UC_CPU_M68K_M68040 = 4 10 | UC_CPU_M68K_M68060 = 5 11 | UC_CPU_M68K_M5208 = 6 12 | UC_CPU_M68K_CFV4E = 7 13 | UC_CPU_M68K_ANY = 8 14 | UC_CPU_M68K_ENDING = 9 15 | 16 | # M68K registers 17 | 18 | UC_M68K_REG_INVALID = 0 19 | UC_M68K_REG_A0 = 1 20 | UC_M68K_REG_A1 = 2 21 | UC_M68K_REG_A2 = 3 22 | UC_M68K_REG_A3 = 4 23 | UC_M68K_REG_A4 = 5 24 | UC_M68K_REG_A5 = 6 25 | UC_M68K_REG_A6 = 7 26 | UC_M68K_REG_A7 = 8 27 | UC_M68K_REG_D0 = 9 28 | UC_M68K_REG_D1 = 10 29 | UC_M68K_REG_D2 = 11 30 | UC_M68K_REG_D3 = 12 31 | UC_M68K_REG_D4 = 13 32 | UC_M68K_REG_D5 = 14 33 | UC_M68K_REG_D6 = 15 34 | UC_M68K_REG_D7 = 16 35 | UC_M68K_REG_SR = 17 36 | UC_M68K_REG_PC = 18 37 | UC_M68K_REG_ENDING = 19 38 | -------------------------------------------------------------------------------- /bindings/ruby/Makefile: -------------------------------------------------------------------------------- 1 | # Ruby binding for Unicorn engine. Sascha Schirra 2 | 3 | .PHONY: gen_const 4 | 5 | # Use bundle install && rake to install gem and test 6 | install: gen_const 7 | cd unicorn_gem && rake build 8 | cd unicorn_gem && gem install --local pkg/unicorn-engine-2.0.0.gem 9 | 10 | gen_const: 11 | cd .. && python3 const_generator.py ruby 12 | -------------------------------------------------------------------------------- /bindings/ruby/README.md: -------------------------------------------------------------------------------- 1 | # Installation 2 | 3 | ## Software requirements 4 | 5 | ### Linux 6 | - ruby >= 1.9.3 7 | - rubygems 8 | - make 9 | - gcc 10 | 11 | ### Mac OS 12 | - ruby >= 1.9.3 13 | - rubygems 14 | - make 15 | - XCode 16 | 17 | ## Install unicorn 18 | * cd path_to_unicorn 19 | * ./make.sh install 20 | 21 | ## Install ruby binding 22 | * cd bindings/ruby 23 | * make install 24 | -------------------------------------------------------------------------------- /bindings/ruby/unicorn_gem/Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gemspec 4 | -------------------------------------------------------------------------------- /bindings/ruby/unicorn_gem/Rakefile: -------------------------------------------------------------------------------- 1 | require "bundler/gem_tasks" 2 | task :default => :spec 3 | -------------------------------------------------------------------------------- /bindings/ruby/unicorn_gem/ext/extconf.rb: -------------------------------------------------------------------------------- 1 | require 'mkmf' 2 | 3 | extension_name = 'unicorn_engine' 4 | 5 | dir_config(extension_name) 6 | pkg_config('unicorn') 7 | have_library('unicorn') 8 | 9 | create_makefile(extension_name) 10 | -------------------------------------------------------------------------------- /bindings/ruby/unicorn_gem/ext/types.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Ruby bindings for the Unicorn Emulator Engine 4 | 5 | Copyright(c) 2016 Sascha Schirra 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License 9 | version 2 as published by the Free Software Foundation. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | 20 | */ 21 | 22 | typedef struct uc_x86_float80 { 23 | uint64_t mantissa; 24 | uint16_t exponent; 25 | } uc_x86_float80; 26 | 27 | 28 | struct hook { 29 | uc_hook trace; 30 | VALUE cb; 31 | VALUE ud; 32 | VALUE rUc; 33 | }; 34 | -------------------------------------------------------------------------------- /bindings/ruby/unicorn_gem/lib/unicorn_engine/m68k_const.rb: -------------------------------------------------------------------------------- 1 | # For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT [m68k_const.rb] 2 | 3 | module UnicornEngine 4 | 5 | # M68K CPU 6 | 7 | UC_CPU_M68K_M5206 = 0 8 | UC_CPU_M68K_M68000 = 1 9 | UC_CPU_M68K_M68020 = 2 10 | UC_CPU_M68K_M68030 = 3 11 | UC_CPU_M68K_M68040 = 4 12 | UC_CPU_M68K_M68060 = 5 13 | UC_CPU_M68K_M5208 = 6 14 | UC_CPU_M68K_CFV4E = 7 15 | UC_CPU_M68K_ANY = 8 16 | UC_CPU_M68K_ENDING = 9 17 | 18 | # M68K registers 19 | 20 | UC_M68K_REG_INVALID = 0 21 | UC_M68K_REG_A0 = 1 22 | UC_M68K_REG_A1 = 2 23 | UC_M68K_REG_A2 = 3 24 | UC_M68K_REG_A3 = 4 25 | UC_M68K_REG_A4 = 5 26 | UC_M68K_REG_A5 = 6 27 | UC_M68K_REG_A6 = 7 28 | UC_M68K_REG_A7 = 8 29 | UC_M68K_REG_D0 = 9 30 | UC_M68K_REG_D1 = 10 31 | UC_M68K_REG_D2 = 11 32 | UC_M68K_REG_D3 = 12 33 | UC_M68K_REG_D4 = 13 34 | UC_M68K_REG_D5 = 14 35 | UC_M68K_REG_D6 = 15 36 | UC_M68K_REG_D7 = 16 37 | UC_M68K_REG_SR = 17 38 | UC_M68K_REG_PC = 18 39 | UC_M68K_REG_ENDING = 19 40 | end -------------------------------------------------------------------------------- /bindings/ruby/unicorn_gem/lib/unicorn_engine/version.rb: -------------------------------------------------------------------------------- 1 | module Unicorn 2 | VERSION = "2.0.0" 3 | end 4 | -------------------------------------------------------------------------------- /bindings/ruby/unicorn_gem/pkg/.gitignore: -------------------------------------------------------------------------------- 1 | /.bundle/ 2 | /.yardoc 3 | /Gemfile.lock 4 | /_yardoc/ 5 | /coverage/ 6 | /doc/ 7 | /pkg/ 8 | /spec/reports/ 9 | /tmp/ 10 | *.gem 11 | -------------------------------------------------------------------------------- /bindings/ruby/unicorn_gem/unicorn-engine.gemspec: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | lib = File.expand_path('../lib', __FILE__) 3 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 4 | require 'unicorn_engine/version' 5 | 6 | Gem::Specification.new do |spec| 7 | spec.name = "unicorn-engine" 8 | spec.version = Unicorn::VERSION 9 | spec.authors = ["Sascha Schirra"] 10 | spec.email = ["sashs@scoding.de"] 11 | spec.license = 'GPL-2.0' 12 | spec.summary = %q{Ruby binding for Unicorn-Engine} 13 | spec.description = %q{Ruby binding for Unicorn-Engine } 14 | spec.homepage = "https://unicorn-engine.org" 15 | 16 | spec.files = Dir["lib/unicorn_engine/*.rb"] + Dir["ext/unicorn.c"] + Dir["ext/unicorn.h"] + Dir["ext/types.h"] + Dir["ext/extconf.rb"] 17 | spec.require_paths = ["lib","ext"] 18 | spec.extensions = ["ext/extconf.rb"] 19 | spec.add_development_dependency "bundler", "~> 1.11" 20 | spec.add_development_dependency "rake", "~> 10.0" 21 | end 22 | -------------------------------------------------------------------------------- /bindings/rust/src/m68k.rs: -------------------------------------------------------------------------------- 1 | // M68K registers 2 | #[repr(C)] 3 | #[derive(PartialEq, Debug, Clone, Copy)] 4 | pub enum RegisterM68K { 5 | INVALID = 0, 6 | A0, 7 | A1, 8 | A2, 9 | A3, 10 | A4, 11 | A5, 12 | A6, 13 | A7, 14 | D0, 15 | D1, 16 | D2, 17 | D3, 18 | D4, 19 | D5, 20 | D6, 21 | D7, 22 | SR, 23 | PC, 24 | ENDING, 25 | } 26 | 27 | impl From for i32 { 28 | fn from(r: RegisterM68K) -> Self { 29 | r as i32 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /bindings/vb6/.gitattributes: -------------------------------------------------------------------------------- 1 | *.frm eol=crlf 2 | *.bas eol=crlf 3 | *.cls eol=crlf 4 | *.ctl eol=crlf 5 | *.vbp eol=crlf 6 | *.txt eol=crlf 7 | *.cpp eol=crlf 8 | *.tli eol=crlf 9 | *.tlh eol=crlf 10 | *.vcproj eol=crlf 11 | *.sln eol=crlf 12 | -------------------------------------------------------------------------------- /bindings/vb6/Project1.vbp: -------------------------------------------------------------------------------- 1 | Type=Exe 2 | Form=Form1.frm 3 | Reference=*\G{00020430-0000-0000-C000-000000000046}#2.0#0#C:\Windows\SysWOW64\stdole2.tlb#OLE Automation 4 | Module=uc_def; uc_def.bas 5 | Module=misc; misc.bas 6 | Class=ucIntel32; ucIntel32.cls 7 | Class=CMemRegion; CMemRegion.cls 8 | IconForm="Form1" 9 | Startup="Form1" 10 | HelpFile="" 11 | ExeName32="vb6Test.exe" 12 | Command32="" 13 | Name="Project1" 14 | HelpContextID="0" 15 | CompatibleMode="0" 16 | MajorVer=1 17 | MinorVer=0 18 | RevisionVer=0 19 | AutoIncrementVer=0 20 | ServerSupportFiles=0 21 | VersionCompanyName="sandsprite" 22 | CompilationType=0 23 | OptimizationType=0 24 | FavorPentiumPro(tm)=0 25 | CodeViewDebugInfo=-1 26 | NoAliasing=0 27 | BoundsCheck=0 28 | OverflowCheck=0 29 | FlPointCheck=0 30 | FDIVCheck=0 31 | UnroundedFP=0 32 | StartMode=0 33 | Unattended=0 34 | Retained=0 35 | ThreadPerObject=0 36 | MaxNumberOfThreads=1 37 | 38 | [MS Transaction Server] 39 | AutoRefresh=1 40 | 41 | [fastBuild] 42 | fullPath=%ap%\vb6Test.exe 43 | -------------------------------------------------------------------------------- /bindings/vb6/Project1.vbw: -------------------------------------------------------------------------------- 1 | Form1 = 39, 35, 1148, 674, , 22, 22, 1090, 631, C 2 | uc_def = 56, 12, 1177, 758, 3 | misc = 44, 44, 1121, 685, 4 | ucIntel32 = 88, 33, 1136, 684, 5 | CMemRegion = 110, 110, 1026, 639, 6 | -------------------------------------------------------------------------------- /bindings/vb6/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/unicorn-for-efi/40a8d07ba3cef067d9a6455c163dbed8d94f8e38/bindings/vb6/screenshot.png -------------------------------------------------------------------------------- /bindings/vb6/ucvbshim.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 10.00 3 | # Visual Studio 2008 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ucvbshim", "ucvbshim.vcproj", "{6FC797B7-2985-49C8-92CD-CA985AF3511C}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Release|Win32 = Release|Win32 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {6FC797B7-2985-49C8-92CD-CA985AF3511C}.Debug|Win32.ActiveCfg = Debug|Win32 13 | {6FC797B7-2985-49C8-92CD-CA985AF3511C}.Debug|Win32.Build.0 = Debug|Win32 14 | {6FC797B7-2985-49C8-92CD-CA985AF3511C}.Release|Win32.ActiveCfg = Release|Win32 15 | {6FC797B7-2985-49C8-92CD-CA985AF3511C}.Release|Win32.Build.0 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /docs/BHUSA2015-unicorn.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/unicorn-for-efi/40a8d07ba3cef067d9a6455c163dbed8d94f8e38/docs/BHUSA2015-unicorn.pdf -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | Documention of Unicorn engine. 2 | 3 | * How to compile & install Unicorn. 4 | 5 | http://unicorn-engine.org/docs/ 6 | 7 | * Tutorial on programming with C & Python languages. 8 | 9 | http://unicorn-engine.org/docs/tutorial.html 10 | 11 | * Compare Unicorn & QEMU 12 | 13 | http://unicorn-engine.org/docs/beyond_qemu.html 14 | 15 | * Uncorn-Engine Documentation 16 | 17 | https://github.com/kabeor/Unicorn-Engine-Documentation 18 | -------------------------------------------------------------------------------- /docs/unicorn-logo-text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/unicorn-for-efi/40a8d07ba3cef067d9a6455c163dbed8d94f8e38/docs/unicorn-logo-text.png -------------------------------------------------------------------------------- /docs/unicorn-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/unicorn-for-efi/40a8d07ba3cef067d9a6455c163dbed8d94f8e38/docs/unicorn-logo.png -------------------------------------------------------------------------------- /docs/unicorn1-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/unicorn-for-efi/40a8d07ba3cef067d9a6455c163dbed8d94f8e38/docs/unicorn1-logo.png -------------------------------------------------------------------------------- /docs/unicorn1-logo.txt: -------------------------------------------------------------------------------- 1 | /\'. _,. 2 | |:\ \. .'_/ 3 | _.- |(\\ \ .'_.' 4 | _.-' ,__\\ \\_),/ _/ 5 | _:.' .:::::::.___ ,' 6 | // ' ./::::::\ 4 | # 5 | # This library is free software; you can redistribute it and/or 6 | # modify it under the terms of the GNU Lesser General Public 7 | # License as published by the Free Software Foundation; either 8 | # version 2 of the License, or (at your option) any later version. 9 | # 10 | ## 11 | 12 | [Defines] 13 | DEC_SPECIFICATION = 0x00010005 14 | PACKAGE_NAME = UnicornPkg 15 | PACKAGE_GUID = 1E73767F-8F52-4603-AEB4-F29B510B6755 16 | PACKAGE_VERSION = 1.00 17 | 18 | [Includes] 19 | include 20 | ../include/unicorn 21 | 22 | [Includes.X64] 23 | include/x86_64 24 | 25 | [Includes.RISCV64] 26 | include/riscv 27 | 28 | -------------------------------------------------------------------------------- /efi/UnicornSampleArm64.inf: -------------------------------------------------------------------------------- 1 | ## @file 2 | # 3 | # Copyright (c) 2022, Intel Corporation. All rights reserved.
4 | # 5 | # This library is free software; you can redistribute it and/or 6 | # modify it under the terms of the GNU Lesser General Public 7 | # License as published by the Free Software Foundation; either 8 | # version 2 of the License, or (at your option) any later version. 9 | # 10 | ## 11 | 12 | [Defines] 13 | INF_VERSION = 0x00010005 14 | BASE_NAME = UnicornSampleArm64 15 | FILE_GUID = 6987936E-ED34-44da-AB97-1FA5E4ED2B16 16 | MODULE_TYPE = UEFI_APPLICATION 17 | VERSION_STRING = 1.0 18 | ENTRY_POINT = UefiMain 19 | 20 | [Sources] 21 | ../samples/sample_arm64.c 22 | UnicornSampleStub.c 23 | 24 | [Packages] 25 | MdePkg/MdePkg.dec 26 | MdeModulePkg/MdeModulePkg.dec 27 | unicorn/efi/UnicornPkg.dec 28 | 29 | [LibraryClasses] 30 | UefiApplicationEntryPoint 31 | UnicornArm64Lib 32 | UnicornStubLib 33 | UnicornEngineLib 34 | 35 | [FeaturePcd] 36 | 37 | [Pcd] 38 | 39 | [BuildOptions] 40 | GCC:*_*_*_CC_FLAGS = -I$(WORKSPACE)/unicorn/include -DUNICORN_FOR_EFI_INTERNAL 41 | -------------------------------------------------------------------------------- /efi/UnicornSampleRV.inf: -------------------------------------------------------------------------------- 1 | ## @file 2 | # 3 | # Copyright (c) 2022, Intel Corporation. All rights reserved.
4 | # 5 | # This library is free software; you can redistribute it and/or 6 | # modify it under the terms of the GNU Lesser General Public 7 | # License as published by the Free Software Foundation; either 8 | # version 2 of the License, or (at your option) any later version. 9 | # 10 | ## 11 | 12 | [Defines] 13 | INF_VERSION = 0x00010005 14 | BASE_NAME = UnicornSampleRV 15 | FILE_GUID = 6987936E-ED34-44da-AB97-1FA5E4ED2116 16 | MODULE_TYPE = UEFI_APPLICATION 17 | VERSION_STRING = 1.0 18 | ENTRY_POINT = UefiMain 19 | 20 | [Sources] 21 | ../samples/sample_riscv.c 22 | UnicornSampleStub.c 23 | 24 | [Packages] 25 | MdePkg/MdePkg.dec 26 | MdeModulePkg/MdeModulePkg.dec 27 | unicorn/efi/UnicornPkg.dec 28 | 29 | [LibraryClasses] 30 | UefiApplicationEntryPoint 31 | UnicornRV64Lib 32 | UnicornRV32Lib 33 | UnicornStubLib 34 | UnicornEngineLib 35 | 36 | [FeaturePcd] 37 | 38 | [Pcd] 39 | 40 | [BuildOptions] 41 | GCC:*_*_*_CC_FLAGS = -I$(WORKSPACE)/unicorn/include -DUNICORN_FOR_EFI_INTERNAL 42 | -------------------------------------------------------------------------------- /efi/UnicornSampleStub.c: -------------------------------------------------------------------------------- 1 | /** @file 2 | 3 | Copyright (c) 2022, Intel Corporation. All rights reserved.
4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2 of the License, or (at your option) any later version. 9 | 10 | **/ 11 | 12 | #include "glue.h" 13 | 14 | int main(int argc, char **argv, char **envp); 15 | 16 | EFI_STATUS 17 | EFIAPI 18 | UefiMain ( 19 | IN EFI_HANDLE ImageHandle, 20 | IN EFI_SYSTEM_TABLE *SystemTable 21 | ) 22 | { 23 | char *argv[] = { "sample", NULL }; 24 | int argc = ARRAY_SIZE(argv) - 1; 25 | 26 | main(argc, argv, NULL); 27 | 28 | return EFI_SUCCESS; 29 | } 30 | -------------------------------------------------------------------------------- /efi/UnicornSampleX86.inf: -------------------------------------------------------------------------------- 1 | ## @file 2 | # 3 | # Copyright (c) 2022, Intel Corporation. All rights reserved.
4 | # 5 | # This library is free software; you can redistribute it and/or 6 | # modify it under the terms of the GNU Lesser General Public 7 | # License as published by the Free Software Foundation; either 8 | # version 2 of the License, or (at your option) any later version. 9 | # 10 | ## 11 | 12 | [Defines] 13 | INF_VERSION = 0x00010005 14 | BASE_NAME = UnicornSampleX86 15 | FILE_GUID = 6987936E-ED34-44db-AE97-1FA5E4ED2116 16 | MODULE_TYPE = UEFI_APPLICATION 17 | VERSION_STRING = 1.0 18 | ENTRY_POINT = UefiMain 19 | 20 | [Sources] 21 | ../samples/sample_x86.c 22 | UnicornSampleStub.c 23 | 24 | [Packages] 25 | MdePkg/MdePkg.dec 26 | MdeModulePkg/MdeModulePkg.dec 27 | unicorn/efi/UnicornPkg.dec 28 | 29 | [LibraryClasses] 30 | UefiApplicationEntryPoint 31 | UnicornX86Lib 32 | UnicornStubLib 33 | UnicornEngineLib 34 | 35 | [FeaturePcd] 36 | 37 | [Pcd] 38 | 39 | [BuildOptions] 40 | GCC:*_*_*_CC_FLAGS = -I$(WORKSPACE)/unicorn/include -DUNICORN_FOR_EFI_INTERNAL 41 | -------------------------------------------------------------------------------- /efi/UnicornStubLib.inf: -------------------------------------------------------------------------------- 1 | ## @file 2 | # 3 | # Copyright (c) 2022, Intel Corporation. All rights reserved.
4 | # 5 | # This library is free software; you can redistribute it and/or 6 | # modify it under the terms of the GNU Lesser General Public 7 | # License as published by the Free Software Foundation; either 8 | # version 2 of the License, or (at your option) any later version. 9 | # 10 | ## 11 | 12 | [Defines] 13 | INF_VERSION = 0x00010005 14 | BASE_NAME = UnicornStubLib 15 | FILE_GUID = 6987936E-BBBB-45db-AE97-1FA5E4ED2116 16 | MODULE_TYPE = UEFI_DRIVER 17 | VERSION_STRING = 1.0 18 | LIBRARY_CLASS = UnicornStubLib 19 | 20 | [Sources] 21 | weak.c 22 | 23 | [Packages] 24 | MdePkg/MdePkg.dec 25 | MdeModulePkg/MdeModulePkg.dec 26 | unicorn/efi/UnicornPkg.dec 27 | 28 | [LibraryClasses] 29 | 30 | [FeaturePcd] 31 | 32 | [Pcd] 33 | 34 | [Guids] 35 | 36 | [BuildOptions] 37 | GCC:*_*_*_CC_FLAGS = -nostdinc -DUNICORN_FOR_EFI_INTERNAL 38 | -------------------------------------------------------------------------------- /efi/aarch64/glue.c: -------------------------------------------------------------------------------- 1 | /** @file 2 | 3 | Copyright (c) 2022, Intel Corporation. All rights reserved.
4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2 of the License, or (at your option) any later version. 9 | 10 | **/ 11 | 12 | #include "glue.h" 13 | #include 14 | 15 | void __clear_cache(void *start, void *end) 16 | { 17 | InvalidateInstructionCacheRange(start, (UINTN) end - (UINTN) start); 18 | } 19 | 20 | void abort(void) 21 | { 22 | asm ("hlt #0x86"); 23 | while (1); 24 | } 25 | -------------------------------------------------------------------------------- /efi/aarch64/liblto-unicorn.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/unicorn-for-efi/40a8d07ba3cef067d9a6455c163dbed8d94f8e38/efi/aarch64/liblto-unicorn.a -------------------------------------------------------------------------------- /efi/aarch64/liblto-unicorn.s: -------------------------------------------------------------------------------- 1 | ## @file 2 | # 3 | # Copyright (c) 2023, Intel Corporation. All rights reserved.
4 | # 5 | # This library is free software; you can redistribute it and/or 6 | # modify it under the terms of the GNU Lesser General Public 7 | # License as published by the Free Software Foundation; either 8 | # version 2 of the License, or (at your option) any later version. 9 | # 10 | ## 11 | .long __divti3 - . 12 | .long __ashrti3 - . 13 | -------------------------------------------------------------------------------- /efi/ashrti3.c: -------------------------------------------------------------------------------- 1 | /* ===-- ashrti3.c - Implement __ashrti3 -----------------------------------=== 2 | * 3 | * The LLVM Compiler Infrastructure 4 | * 5 | * This file is dual licensed under the MIT and the University of Illinois Open 6 | * Source Licenses. See LICENSE.TXT for details. 7 | * 8 | * ===----------------------------------------------------------------------=== 9 | * 10 | * This file implements __ashrti3 for the compiler_rt library. 11 | * 12 | * ===----------------------------------------------------------------------=== 13 | */ 14 | 15 | #include "glue.h" 16 | 17 | ti_int 18 | __ashrti3(ti_int a, si_int b) 19 | { 20 | const int bits_in_dword = (int)(sizeof(di_int) * CHAR_BIT); 21 | twords input; 22 | twords result; 23 | input.all = a; 24 | if (b & bits_in_dword) /* bits_in_dword <= b < bits_in_tword */ 25 | { 26 | /* result.s.high = input.s.high < 0 ? -1 : 0 */ 27 | result.s.high = input.s.high >> (bits_in_dword - 1); 28 | result.s.low = input.s.high >> (b - bits_in_dword); 29 | } 30 | else /* 0 <= b < bits_in_dword */ 31 | { 32 | if (b == 0) 33 | return a; 34 | result.s.high = input.s.high >> b; 35 | result.s.low = (input.s.high << (bits_in_dword - b)) | (input.s.low >> b); 36 | } 37 | return result.all; 38 | } 39 | -------------------------------------------------------------------------------- /efi/clrsb.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This comes from https://github.com/TinyCC/tinycc/blob/mob/lib/builtin.c 3 | * 4 | * The TinyCC code is licensed under GNU Lesser General Public License v2.1. 5 | */ 6 | 7 | #include "glue.h" 8 | 9 | /* 10 | * Returns the number of leading redundant sign bits 11 | * in x, i.e. the number of bits following the most 12 | * significant bit that are identical to it. There are 13 | * no special cases for 0 or other values. 14 | */ 15 | int __clrsbdi2(UINT64 x) 16 | { 17 | if (x < 0) { 18 | x = ~x; 19 | } 20 | 21 | x <<= 1; 22 | 23 | return __builtin_clzll(x); 24 | } 25 | -------------------------------------------------------------------------------- /efi/divti3.c: -------------------------------------------------------------------------------- 1 | /* ===-- divti3.c - Implement __divti3 -------------------------------------=== 2 | * 3 | * The LLVM Compiler Infrastructure 4 | * 5 | * This file is dual licensed under the MIT and the University of Illinois Open 6 | * Source Licenses. See LICENSE.TXT for details. 7 | * 8 | * ===----------------------------------------------------------------------=== 9 | * 10 | * This file implements __divti3 for the compiler_rt library. 11 | * 12 | * ===----------------------------------------------------------------------=== 13 | */ 14 | 15 | #include "glue.h" 16 | 17 | tu_int __udivmodti4(tu_int a, tu_int b, tu_int* rem); 18 | 19 | ti_int 20 | __divti3(ti_int a, ti_int b) 21 | { 22 | const int bits_in_tword_m1 = (int)(sizeof(ti_int) * CHAR_BIT) - 1; 23 | ti_int s_a = a >> bits_in_tword_m1; /* s_a = a < 0 ? -1 : 0 */ 24 | ti_int s_b = b >> bits_in_tword_m1; /* s_b = b < 0 ? -1 : 0 */ 25 | a = (a ^ s_a) - s_a; /* negate if s_a == -1 */ 26 | b = (b ^ s_b) - s_b; /* negate if s_b == -1 */ 27 | s_a ^= s_b; /* sign of quotient */ 28 | return (__udivmodti4(a, b, (tu_int*)0) ^ s_a) - s_a; /* negate if s_a == -1 */ 29 | } 30 | -------------------------------------------------------------------------------- /efi/include/assert.h: -------------------------------------------------------------------------------- 1 | /** @file 2 | 3 | Copyright (c) 2022, Intel Corporation. All rights reserved.
4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2 of the License, or (at your option) any later version. 9 | 10 | **/ 11 | 12 | #include "glue.h" 13 | -------------------------------------------------------------------------------- /efi/include/byteswap.h: -------------------------------------------------------------------------------- 1 | /** @file 2 | 3 | Copyright (c) 2022, Intel Corporation. All rights reserved.
4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2 of the License, or (at your option) any later version. 9 | 10 | **/ 11 | 12 | #include "glue.h" 13 | -------------------------------------------------------------------------------- /efi/include/config-host.h: -------------------------------------------------------------------------------- 1 | /** @file 2 | 3 | Copyright (c) 2022, Intel Corporation. All rights reserved.
4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2 of the License, or (at your option) any later version. 9 | 10 | **/ 11 | 12 | #if defined (MDE_CPU_X64) 13 | #define CONFIG_CPUID_H 1 14 | #endif 15 | 16 | #define CONFIG_INT128 1 17 | #define CONFIG_CMPXCHG128 1 18 | #define CONFIG_ATOMIC64 1 19 | 20 | #define CONFIG_PRAGMA_DIAGNOSTIC_AVAILABLE 1 21 | #define CONFIG_STATIC_ASSERT 1 22 | -------------------------------------------------------------------------------- /efi/include/config-target-aarch64.h: -------------------------------------------------------------------------------- 1 | /** @file 2 | 3 | Copyright (c) 2023, Intel Corporation. All rights reserved.
4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2 of the License, or (at your option) any later version. 9 | 10 | **/ 11 | 12 | #define TARGET_AARCH64 1 13 | #define TARGET_ARM 1 14 | #define CONFIG_SOFTMMU 1 15 | -------------------------------------------------------------------------------- /efi/include/config-target-i386.h: -------------------------------------------------------------------------------- 1 | /** @file 2 | 3 | Copyright (c) 2022, Intel Corporation. All rights reserved.
4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2 of the License, or (at your option) any later version. 9 | 10 | **/ 11 | 12 | #define TARGET_X86_64 1 13 | #define TARGET_I386 1 14 | #define CONFIG_SOFTMMU 1 15 | -------------------------------------------------------------------------------- /efi/include/config-target-riscv32.h: -------------------------------------------------------------------------------- 1 | /** @file 2 | 3 | Copyright (c) 2022, Intel Corporation. All rights reserved.
4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2 of the License, or (at your option) any later version. 9 | 10 | **/ 11 | 12 | #define TARGET_RISCV32 1 13 | #define TARGET_RISCV 1 14 | #define CONFIG_SOFTMMU 1 15 | -------------------------------------------------------------------------------- /efi/include/config-target-riscv64.h: -------------------------------------------------------------------------------- 1 | /** @file 2 | 3 | Copyright (c) 2022, Intel Corporation. All rights reserved.
4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2 of the License, or (at your option) any later version. 9 | 10 | **/ 11 | 12 | #define TARGET_RISCV64 1 13 | #define TARGET_RISCV 1 14 | #define CONFIG_SOFTMMU 1 15 | -------------------------------------------------------------------------------- /efi/include/ctype.h: -------------------------------------------------------------------------------- 1 | /** @file 2 | 3 | Copyright (c) 2022, Intel Corporation. All rights reserved.
4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2 of the License, or (at your option) any later version. 9 | 10 | **/ 11 | 12 | #include "glue.h" 13 | -------------------------------------------------------------------------------- /efi/include/errno.h: -------------------------------------------------------------------------------- 1 | /** @file 2 | 3 | Copyright (c) 2022, Intel Corporation. All rights reserved.
4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2 of the License, or (at your option) any later version. 9 | 10 | **/ 11 | 12 | #include "glue.h" 13 | -------------------------------------------------------------------------------- /efi/include/fcntl.h: -------------------------------------------------------------------------------- 1 | /** @file 2 | 3 | Copyright (c) 2022, Intel Corporation. All rights reserved.
4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2 of the License, or (at your option) any later version. 9 | 10 | **/ 11 | 12 | #include "glue.h" 13 | -------------------------------------------------------------------------------- /efi/include/float.h: -------------------------------------------------------------------------------- 1 | /** @file 2 | 3 | Copyright (c) 2022, Intel Corporation. All rights reserved.
4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2 of the License, or (at your option) any later version. 9 | 10 | **/ 11 | 12 | #include "glue.h" 13 | -------------------------------------------------------------------------------- /efi/include/inttypes.h: -------------------------------------------------------------------------------- 1 | /** @file 2 | 3 | Copyright (c) 2022, Intel Corporation. All rights reserved.
4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2 of the License, or (at your option) any later version. 9 | 10 | **/ 11 | 12 | #include "glue.h" 13 | -------------------------------------------------------------------------------- /efi/include/limits.h: -------------------------------------------------------------------------------- 1 | /** @file 2 | 3 | Copyright (c) 2022, Intel Corporation. All rights reserved.
4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2 of the License, or (at your option) any later version. 9 | 10 | **/ 11 | 12 | #include "glue.h" 13 | -------------------------------------------------------------------------------- /efi/include/math.h: -------------------------------------------------------------------------------- 1 | /** @file 2 | 3 | Copyright (c) 2022, Intel Corporation. All rights reserved.
4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2 of the License, or (at your option) any later version. 9 | 10 | **/ 11 | 12 | #include "glue.h" 13 | -------------------------------------------------------------------------------- /efi/include/pthread.h: -------------------------------------------------------------------------------- 1 | /** @file 2 | 3 | Copyright (c) 2022, Intel Corporation. All rights reserved.
4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2 of the License, or (at your option) any later version. 9 | 10 | **/ 11 | 12 | #include "glue.h" 13 | -------------------------------------------------------------------------------- /efi/include/semaphore.h: -------------------------------------------------------------------------------- 1 | /** @file 2 | 3 | Copyright (c) 2022, Intel Corporation. All rights reserved.
4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2 of the License, or (at your option) any later version. 9 | 10 | **/ 11 | 12 | #include "glue.h" 13 | -------------------------------------------------------------------------------- /efi/include/setjmp.h: -------------------------------------------------------------------------------- 1 | /** @file 2 | 3 | Copyright (c) 2022, Intel Corporation. All rights reserved.
4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2 of the License, or (at your option) any later version. 9 | 10 | **/ 11 | 12 | #include "glue.h" 13 | -------------------------------------------------------------------------------- /efi/include/signal.h: -------------------------------------------------------------------------------- 1 | /** @file 2 | 3 | Copyright (c) 2022, Intel Corporation. All rights reserved.
4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2 of the License, or (at your option) any later version. 9 | 10 | **/ 11 | 12 | #include "glue.h" 13 | -------------------------------------------------------------------------------- /efi/include/stdarg.h: -------------------------------------------------------------------------------- 1 | /** @file 2 | 3 | Copyright (c) 2022, Intel Corporation. All rights reserved.
4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2 of the License, or (at your option) any later version. 9 | 10 | **/ 11 | 12 | #include "glue.h" 13 | -------------------------------------------------------------------------------- /efi/include/stdbool.h: -------------------------------------------------------------------------------- 1 | /** @file 2 | 3 | Copyright (c) 2022, Intel Corporation. All rights reserved.
4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2 of the License, or (at your option) any later version. 9 | 10 | **/ 11 | 12 | #include "glue.h" 13 | -------------------------------------------------------------------------------- /efi/include/stddef.h: -------------------------------------------------------------------------------- 1 | /** @file 2 | 3 | Copyright (c) 2022, Intel Corporation. All rights reserved.
4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2 of the License, or (at your option) any later version. 9 | 10 | **/ 11 | 12 | #include "glue.h" 13 | -------------------------------------------------------------------------------- /efi/include/stdint.h: -------------------------------------------------------------------------------- 1 | /** @file 2 | 3 | Copyright (c) 2022, Intel Corporation. All rights reserved.
4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2 of the License, or (at your option) any later version. 9 | 10 | **/ 11 | 12 | #include "glue.h" 13 | -------------------------------------------------------------------------------- /efi/include/stdio.h: -------------------------------------------------------------------------------- 1 | /** @file 2 | 3 | Copyright (c) 2022, Intel Corporation. All rights reserved.
4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2 of the License, or (at your option) any later version. 9 | 10 | **/ 11 | 12 | #include "glue.h" 13 | -------------------------------------------------------------------------------- /efi/include/stdlib.h: -------------------------------------------------------------------------------- 1 | /** @file 2 | 3 | Copyright (c) 2022, Intel Corporation. All rights reserved.
4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2 of the License, or (at your option) any later version. 9 | 10 | **/ 11 | 12 | #include "glue.h" 13 | -------------------------------------------------------------------------------- /efi/include/string.h: -------------------------------------------------------------------------------- 1 | /** @file 2 | 3 | Copyright (c) 2022, Intel Corporation. All rights reserved.
4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2 of the License, or (at your option) any later version. 9 | 10 | **/ 11 | 12 | #include "glue.h" 13 | -------------------------------------------------------------------------------- /efi/include/sys/mman.h: -------------------------------------------------------------------------------- 1 | /** @file 2 | 3 | Copyright (c) 2022, Intel Corporation. All rights reserved.
4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2 of the License, or (at your option) any later version. 9 | 10 | **/ 11 | 12 | #include "glue.h" 13 | -------------------------------------------------------------------------------- /efi/include/sys/stat.h: -------------------------------------------------------------------------------- 1 | /** @file 2 | 3 | Copyright (c) 2022, Intel Corporation. All rights reserved.
4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2 of the License, or (at your option) any later version. 9 | 10 | **/ 11 | 12 | #include "glue.h" 13 | -------------------------------------------------------------------------------- /efi/include/sys/time.h: -------------------------------------------------------------------------------- 1 | /** @file 2 | 3 | Copyright (c) 2022, Intel Corporation. All rights reserved.
4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2 of the License, or (at your option) any later version. 9 | 10 | **/ 11 | 12 | #include "glue.h" 13 | -------------------------------------------------------------------------------- /efi/include/sys/types.h: -------------------------------------------------------------------------------- 1 | /** @file 2 | 3 | Copyright (c) 2022, Intel Corporation. All rights reserved.
4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2 of the License, or (at your option) any later version. 9 | 10 | **/ 11 | 12 | #include "glue.h" 13 | -------------------------------------------------------------------------------- /efi/include/sys/wait.h: -------------------------------------------------------------------------------- 1 | /** @file 2 | 3 | Copyright (c) 2022, Intel Corporation. All rights reserved.
4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2 of the License, or (at your option) any later version. 9 | 10 | **/ 11 | 12 | #include "glue.h" 13 | -------------------------------------------------------------------------------- /efi/include/time.h: -------------------------------------------------------------------------------- 1 | /** @file 2 | 3 | Copyright (c) 2022, Intel Corporation. All rights reserved.
4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2 of the License, or (at your option) any later version. 9 | 10 | **/ 11 | 12 | #include "glue.h" 13 | -------------------------------------------------------------------------------- /efi/include/unistd.h: -------------------------------------------------------------------------------- 1 | /** @file 2 | 3 | Copyright (c) 2022, Intel Corporation. All rights reserved.
4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2 of the License, or (at your option) any later version. 9 | 10 | **/ 11 | 12 | #include "glue.h" 13 | -------------------------------------------------------------------------------- /efi/loongarch64/glue.c: -------------------------------------------------------------------------------- 1 | /** @file 2 | 3 | Copyright (c) 2022, Intel Corporation. All rights reserved.
4 | Copyright (c) 2024, Intel Loongson Technology Corporation Limited. All rights reserved.
5 | 6 | This library is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU Lesser General Public 8 | License as published by the Free Software Foundation; either 9 | version 2 of the License, or (at your option) any later version. 10 | 11 | **/ 12 | 13 | #include "glue.h" 14 | 15 | void abort(void) 16 | { 17 | printf("Abort from 0x%lx!\n", __builtin_return_address(0)); 18 | asm ("break 0"); 19 | while (1); 20 | } 21 | -------------------------------------------------------------------------------- /efi/popcount.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This comes from https://github.com/TinyCC/tinycc/blob/mob/lib/builtin.c 3 | * 4 | * The TinyCC code is licensed under GNU Lesser General Public License v2.1. 5 | */ 6 | 7 | #include "glue.h" 8 | 9 | #define POPCOUNTL(x, m) \ 10 | x = x - ((x >> 1) & 0x5555555555555555ull); \ 11 | x = (x & 0x3333333333333333ull) + ((x >> 2) & 0x3333333333333333ull); \ 12 | x = (x + (x >> 4)) & 0xf0f0f0f0f0f0f0full; \ 13 | return ((x * 0x0101010101010101ull) >> 56) & m; 14 | 15 | int __popcountdi2(INT64 x) 16 | { 17 | return POPCOUNTL(x, 0x7f); 18 | } 19 | -------------------------------------------------------------------------------- /efi/x86_64/glue.c: -------------------------------------------------------------------------------- 1 | /** @file 2 | Copyright (c) 2023, Intel Corporation. All rights reserved.
3 | This library is free software; you can redistribute it and/or 4 | modify it under the terms of the GNU Lesser General Public 5 | License as published by the Free Software Foundation; either 6 | version 2 of the License, or (at your option) any later version. 7 | **/ 8 | 9 | #include "glue.h" 10 | 11 | void abort(void) 12 | { 13 | printf("Abort from 0x%lx!\n", __builtin_return_address(0)); 14 | asm("hlt"); 15 | while (1); 16 | } 17 | -------------------------------------------------------------------------------- /efi/x86_64/liblto-unicorn.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/unicorn-for-efi/40a8d07ba3cef067d9a6455c163dbed8d94f8e38/efi/x86_64/liblto-unicorn.a -------------------------------------------------------------------------------- /efi/x86_64/liblto-unicorn.s: -------------------------------------------------------------------------------- 1 | ## @file 2 | # 3 | # Copyright (c) 2022, Intel Corporation. All rights reserved.
4 | # 5 | # This library is free software; you can redistribute it and/or 6 | # modify it under the terms of the GNU Lesser General Public 7 | # License as published by the Free Software Foundation; either 8 | # version 2 of the License, or (at your option) any later version. 9 | # 10 | ## 11 | .long __clrsbdi2 - . 12 | .long __popcountdi2 - . 13 | -------------------------------------------------------------------------------- /format.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | find . -maxdepth 1 "(" -name "*.c" -or -name "*.h" ")" -exec clang-format -i -style=file "{}" ";" 4 | find ./msvc -maxdepth 1 "(" -name "*.c" -or -name "*.h" ")" -exec clang-format -i -style=file "{}" ";" 5 | find ./include -maxdepth 2 "(" -name "*.c" -or -name "*.h" ")" -exec clang-format -i -style=file "{}" ";" 6 | find ./tests/unit -maxdepth 1 "(" -name "*.c" -or -name "*.h" ")" -exec clang-format -i -style=file "{}" ";" 7 | find ./samples -maxdepth 1 "(" -name "*.c" -or -name "*.h" ")" -exec clang-format -i -style=file "{}" ";" 8 | find ./qemu "(" -name "unicorn.c" -or -name "unicorn.h" -or -name "unicorn_arm.c" -or -name "unicorn_aarch64.c" ")" -exec clang-format -i -style=file "{}" ";" 9 | -------------------------------------------------------------------------------- /glib_compat/README: -------------------------------------------------------------------------------- 1 | This is a compatible glib library, customized for Unicorn. 2 | Based on glib 2.64.4. 3 | -------------------------------------------------------------------------------- /glib_compat/gtestutils.c: -------------------------------------------------------------------------------- 1 | /* GLib testing utilities 2 | * Copyright (C) 2007 Imendio AB 3 | * Authors: Tim Janik, Sven Herzberg 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, see . 17 | */ 18 | 19 | #include "gtestutils.h" 20 | #include 21 | #include 22 | 23 | void 24 | g_assertion_message_expr (const char *file, 25 | int line, 26 | const char *expr) 27 | { 28 | if (!expr) 29 | printf("%s:%d code should not be reached", file, line); 30 | else 31 | printf("%s:%d assertion failed: %s", file, line, expr); 32 | 33 | abort(); 34 | } 35 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/unicorn-engine/unicorn 2 | 3 | go 1.17 4 | 5 | -------------------------------------------------------------------------------- /include/list.h: -------------------------------------------------------------------------------- 1 | #ifndef UC_LLIST_H 2 | #define UC_LLIST_H 3 | 4 | #include "unicorn/platform.h" 5 | 6 | typedef void (*delete_fn)(void *data); 7 | 8 | struct list_item { 9 | struct list_item *next; 10 | void *data; 11 | }; 12 | 13 | struct list { 14 | struct list_item *head, *tail; 15 | delete_fn delete_fn; 16 | }; 17 | 18 | // create a new list 19 | struct list *list_new(void); 20 | 21 | // removed linked list nodes but does not free their content 22 | void list_clear(struct list *list); 23 | 24 | // insert a new item at the begin of the list. 25 | void *list_insert(struct list *list, void *data); 26 | 27 | // append a new item at the end of the list. 28 | void *list_append(struct list *list, void *data); 29 | 30 | // returns true if entry was removed, false otherwise 31 | bool list_remove(struct list *list, void *data); 32 | 33 | // returns true if the data exists in the list 34 | bool list_exists(struct list *list, void *data); 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /include/qemu.h: -------------------------------------------------------------------------------- 1 | /* By Dang Hoang Vu , 2015 */ 2 | /* Modified for Unicorn Engine by Chen Huitao, 2020 */ 3 | 4 | #ifndef UC_QEMU_H 5 | #define UC_QEMU_H 6 | 7 | struct uc_struct; 8 | 9 | #define OPC_BUF_SIZE 640 10 | 11 | #include "sysemu/sysemu.h" 12 | #include "sysemu/cpus.h" 13 | #include "exec/cpu-common.h" 14 | #include "exec/memory.h" 15 | 16 | #include "qemu/thread.h" 17 | #include "hw/core/cpu.h" 18 | 19 | #include "vl.h" 20 | 21 | // This struct is originally from qemu/include/exec/ramblock.h 22 | // Temporarily moved here since there is circular inclusion. 23 | struct RAMBlock { 24 | struct MemoryRegion *mr; 25 | uint8_t *host; 26 | ram_addr_t offset; 27 | ram_addr_t used_length; 28 | ram_addr_t max_length; 29 | uint32_t flags; 30 | /* RCU-enabled, writes protected by the ramlist lock */ 31 | QLIST_ENTRY(RAMBlock) next; 32 | size_t page_size; 33 | }; 34 | 35 | typedef struct { 36 | MemoryRegion *mr; 37 | void *buffer; 38 | hwaddr addr; 39 | hwaddr len; 40 | } BounceBuffer; 41 | 42 | // This struct is originally from qemu/include/exec/ramlist.h 43 | typedef struct RAMList { 44 | RAMBlock *mru_block; 45 | QLIST_HEAD(, RAMBlock) blocks; 46 | } RAMList; 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /mingw-w64.cmake: -------------------------------------------------------------------------------- 1 | # cross compile 2 | SET(CMAKE_SYSTEM_NAME Windows) 3 | 4 | # set the compiler 5 | SET(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc) 6 | SET(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++) 7 | SET(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres) 8 | 9 | # set the compiler search path 10 | SET(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32) 11 | 12 | # adjust the default behaviour of the FIND_XXX() commands: 13 | # search headers and libraries in the target environment, search 14 | # programs in the host environment 15 | set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) 16 | set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) 17 | set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) 18 | -------------------------------------------------------------------------------- /msvc/aarch64-softmmu/config-target.h: -------------------------------------------------------------------------------- 1 | /* Automatically generated by create_config - do not modify */ 2 | #define TARGET_AARCH64 1 3 | #define TARGET_NAME "aarch64" 4 | #define TARGET_ARM 1 5 | #define CONFIG_SOFTMMU 1 6 | -------------------------------------------------------------------------------- /msvc/aarch64eb-softmmu/config-target.h: -------------------------------------------------------------------------------- 1 | /* Automatically generated by create_config - do not modify */ 2 | #define TARGET_AARCH64 1 3 | #define TARGET_NAME "aarch64eb" 4 | #define TARGET_ARM 1 5 | #define TARGET_WORDS_BIGENDIAN 1 6 | #define CONFIG_SOFTMMU 1 7 | -------------------------------------------------------------------------------- /msvc/arm-softmmu/config-target.h: -------------------------------------------------------------------------------- 1 | /* Automatically generated by create_config - do not modify */ 2 | #define TARGET_ARM 1 3 | #define TARGET_NAME "arm" 4 | #define TARGET_ARM 1 5 | #define CONFIG_SOFTMMU 1 6 | -------------------------------------------------------------------------------- /msvc/armeb-softmmu/config-target.h: -------------------------------------------------------------------------------- 1 | /* Automatically generated by create_config - do not modify */ 2 | #define TARGET_ARM 1 3 | #define TARGET_NAME "armeb" 4 | #define TARGET_ARM 1 5 | #define TARGET_WORDS_BIGENDIAN 1 6 | #define CONFIG_SOFTMMU 1 7 | -------------------------------------------------------------------------------- /msvc/config-host.h: -------------------------------------------------------------------------------- 1 | /* Automatically generated by create_config - do not modify */ 2 | #define HOST_I386 1 3 | #define CONFIG_WIN32 1 4 | #define CONFIG_TCG 1 5 | #define CONFIG_CPUID_H 1 6 | // #define CONFIG_INT128 1 7 | #define CONFIG_CMPXCHG128 1 8 | // #define CONFIG_ATOMIC64 1 9 | #define CONFIG_PLUGIN 1 10 | -------------------------------------------------------------------------------- /msvc/m68k-softmmu/config-target.h: -------------------------------------------------------------------------------- 1 | /* Automatically generated by create_config - do not modify */ 2 | #define TARGET_M68K 1 3 | #define TARGET_NAME "m68k" 4 | #define TARGET_M68K 1 5 | #define TARGET_WORDS_BIGENDIAN 1 6 | #define CONFIG_SOFTMMU 1 7 | -------------------------------------------------------------------------------- /msvc/mips-softmmu/config-target.h: -------------------------------------------------------------------------------- 1 | /* Automatically generated by create_config - do not modify */ 2 | #define TARGET_ABI_MIPSO32 1 3 | #define TARGET_MIPS 1 4 | #define TARGET_NAME "mips" 5 | #define TARGET_MIPS 1 6 | #define TARGET_WORDS_BIGENDIAN 1 7 | #define CONFIG_SOFTMMU 1 8 | -------------------------------------------------------------------------------- /msvc/mips64-softmmu/config-target.h: -------------------------------------------------------------------------------- 1 | /* Automatically generated by create_config - do not modify */ 2 | #define TARGET_ABI_MIPSN64 1 3 | #define TARGET_MIPS64 1 4 | #define TARGET_NAME "mips64" 5 | #define TARGET_MIPS 1 6 | #define TARGET_WORDS_BIGENDIAN 1 7 | #define CONFIG_SOFTMMU 1 8 | -------------------------------------------------------------------------------- /msvc/mips64el-softmmu/config-target.h: -------------------------------------------------------------------------------- 1 | /* Automatically generated by create_config - do not modify */ 2 | #define TARGET_ABI_MIPSN64 1 3 | #define TARGET_MIPS64 1 4 | #define TARGET_NAME "mips64el" 5 | #define TARGET_MIPS 1 6 | #define CONFIG_SOFTMMU 1 7 | -------------------------------------------------------------------------------- /msvc/mipsel-softmmu/config-target.h: -------------------------------------------------------------------------------- 1 | /* Automatically generated by create_config - do not modify */ 2 | #define TARGET_ABI_MIPSO32 1 3 | #define TARGET_MIPS 1 4 | #define TARGET_NAME "mipsel" 5 | #define TARGET_MIPS 1 6 | #define CONFIG_SOFTMMU 1 7 | -------------------------------------------------------------------------------- /msvc/ppc-softmmu/config-target.h: -------------------------------------------------------------------------------- 1 | /* Automatically generated by create_config - do not modify */ 2 | #define TARGET_PPC 1 3 | #define TARGET_NAME "ppc" 4 | #define TARGET_PPC 1 5 | #define TARGET_WORDS_BIGENDIAN 1 6 | #define CONFIG_SOFTMMU 1 7 | -------------------------------------------------------------------------------- /msvc/ppc64-softmmu/config-target.h: -------------------------------------------------------------------------------- 1 | /* Automatically generated by create_config - do not modify */ 2 | #define TARGET_PPC64 1 3 | #define TARGET_NAME "ppc64" 4 | #define TARGET_PPC 1 5 | #define TARGET_WORDS_BIGENDIAN 1 6 | #define CONFIG_SOFTMMU 1 7 | -------------------------------------------------------------------------------- /msvc/riscv32-softmmu/config-target.h: -------------------------------------------------------------------------------- 1 | /* Automatically generated by create_config - do not modify */ 2 | #define TARGET_RISCV32 1 3 | #define TARGET_NAME "riscv32" 4 | #define TARGET_RISCV 1 5 | #define CONFIG_SOFTMMU 1 6 | #define TARGET_SUPPORTS_MTTCG 1 7 | -------------------------------------------------------------------------------- /msvc/riscv64-softmmu/config-target.h: -------------------------------------------------------------------------------- 1 | /* Automatically generated by create_config - do not modify */ 2 | #define TARGET_RISCV64 1 3 | #define TARGET_NAME "riscv64" 4 | #define TARGET_RISCV 1 5 | #define CONFIG_SOFTMMU 1 6 | #define TARGET_SUPPORTS_MTTCG 1 7 | -------------------------------------------------------------------------------- /msvc/s390x-softmmu/config-target.h: -------------------------------------------------------------------------------- 1 | /* Automatically generated by create_config - do not modify */ 2 | #define TARGET_S390X 1 3 | #define TARGET_NAME "s390x" 4 | #define TARGET_S390X 1 5 | #define TARGET_SYSTBL_ABI common,64 6 | #define TARGET_WORDS_BIGENDIAN 1 7 | #define CONFIG_SOFTMMU 1 8 | #define TARGET_SUPPORTS_MTTCG 1 9 | -------------------------------------------------------------------------------- /msvc/sparc-softmmu/config-target.h: -------------------------------------------------------------------------------- 1 | /* Automatically generated by create_config - do not modify */ 2 | #define TARGET_SPARC 1 3 | #define TARGET_NAME "sparc" 4 | #define TARGET_SPARC 1 5 | #define TARGET_WORDS_BIGENDIAN 1 6 | #define CONFIG_SOFTMMU 1 7 | -------------------------------------------------------------------------------- /msvc/sparc64-softmmu/config-target.h: -------------------------------------------------------------------------------- 1 | /* Automatically generated by create_config - do not modify */ 2 | #define TARGET_SPARC64 1 3 | #define TARGET_NAME "sparc64" 4 | #define TARGET_SPARC 1 5 | #define TARGET_WORDS_BIGENDIAN 1 6 | #define CONFIG_SOFTMMU 1 7 | -------------------------------------------------------------------------------- /msvc/tricore-softmmu/config-target.h: -------------------------------------------------------------------------------- 1 | /* Automatically generated by create_config - do not modify */ 2 | #define TARGET_TRICORE 1 3 | #define TARGET_NAME "tricore" 4 | #define TARGET_TRICORE 1 5 | #define CONFIG_SOFTMMU 1 6 | -------------------------------------------------------------------------------- /msvc/unicorn/dllmain.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | BOOL APIENTRY DllMain( HMODULE hModule, 4 | DWORD ul_reason_for_call, 5 | LPVOID lpReserved 6 | ) 7 | { 8 | switch (ul_reason_for_call) 9 | { 10 | case DLL_PROCESS_ATTACH: 11 | case DLL_THREAD_ATTACH: 12 | case DLL_THREAD_DETACH: 13 | case DLL_PROCESS_DETACH: 14 | break; 15 | } 16 | return TRUE; 17 | } 18 | 19 | -------------------------------------------------------------------------------- /msvc/x86_64-softmmu/config-target.h: -------------------------------------------------------------------------------- 1 | /* Automatically generated by create_config - do not modify */ 2 | #define TARGET_X86_64 1 3 | #define TARGET_NAME "x86_64" 4 | #define TARGET_I386 1 5 | #define CONFIG_SOFTMMU 1 6 | -------------------------------------------------------------------------------- /qemu/.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is a file format and collection of text editor plugins 2 | # for maintaining consistent coding styles between different editors 3 | # and IDEs. Most popular editors support this either natively or via 4 | # plugin. 5 | # 6 | # Check https://editorconfig.org for details. 7 | 8 | root = true 9 | 10 | [*] 11 | end_of_line = lf 12 | insert_final_newline = true 13 | charset = utf-8 14 | 15 | [*.mak] 16 | indent_style = tab 17 | indent_size = 8 18 | file_type_emacs = makefile 19 | 20 | [Makefile*] 21 | indent_style = tab 22 | indent_size = 8 23 | file_type_emacs = makefile 24 | 25 | [*.{c,h}] 26 | indent_style = space 27 | indent_size = 4 28 | 29 | [*.sh] 30 | indent_style = space 31 | indent_size = 4 32 | 33 | [*.{s,S}] 34 | indent_style = tab 35 | indent_size = 8 36 | file_type_emacs = asm 37 | 38 | [*.{vert,frag}] 39 | file_type_emacs = glsl 40 | 41 | [*.json] 42 | indent_style = space 43 | file_type_emacs = python 44 | -------------------------------------------------------------------------------- /qemu/LICENSE: -------------------------------------------------------------------------------- 1 | The QEMU distribution includes both the QEMU emulator and 2 | various firmware files. These are separate programs that are 3 | distributed together for our users' convenience, and they have 4 | separate licenses. 5 | 6 | The following points clarify the license of the QEMU emulator: 7 | 8 | 1) The QEMU emulator as a whole is released under the GNU General 9 | Public License, version 2. 10 | 11 | 2) Parts of the QEMU emulator have specific licenses which are compatible 12 | with the GNU General Public License, version 2. Hence each source file 13 | contains its own licensing information. Source files with no licensing 14 | information are released under the GNU General Public License, version 15 | 2 or (at your option) any later version. 16 | 17 | As of July 2013, contributions under version 2 of the GNU General Public 18 | License (and no later version) are only accepted for the following files 19 | or directories: bsd-user/, linux-user/, hw/vfio/, hw/xen/xen_pt*. 20 | 21 | 3) The Tiny Code Generator (TCG) is mostly under the BSD or MIT licenses; 22 | but some parts may be GPLv2 or other licenses. Again, see the 23 | specific licensing information in each source file. 24 | 25 | 4) QEMU is a trademark of Fabrice Bellard. 26 | 27 | Fabrice Bellard and the QEMU team 28 | -------------------------------------------------------------------------------- /qemu/VERSION: -------------------------------------------------------------------------------- 1 | 5.0.1 2 | -------------------------------------------------------------------------------- /qemu/include/crypto/init.h: -------------------------------------------------------------------------------- 1 | /* 2 | * QEMU Crypto initialization 3 | * 4 | * Copyright (c) 2015 Red Hat, Inc. 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, see . 18 | * 19 | */ 20 | 21 | #ifndef QCRYPTO_INIT_H 22 | #define QCRYPTO_INIT_H 23 | 24 | #include "qapi/error.h" 25 | 26 | int qcrypto_init(Error **errp); 27 | 28 | #endif /* QCRYPTO_INIT_H */ 29 | -------------------------------------------------------------------------------- /qemu/include/crypto/random.h: -------------------------------------------------------------------------------- 1 | /* 2 | * QEMU Crypto random number provider 3 | * 4 | * Copyright (c) 2015-2016 Red Hat, Inc. 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, see . 18 | * 19 | */ 20 | 21 | #ifndef QCRYPTO_RANDOM_H 22 | #define QCRYPTO_RANDOM_H 23 | 24 | /** 25 | * qcrypto_random_init: 26 | * 27 | * Initializes the handles used by qcrypto_random_bytes 28 | * 29 | * Returns 0 on success, -1 on error 30 | */ 31 | int qcrypto_random_init(void); 32 | 33 | #endif /* QCRYPTO_RANDOM_H */ 34 | -------------------------------------------------------------------------------- /qemu/include/exec/cputlb.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Common CPU TLB handling 3 | * 4 | * Copyright (c) 2003 Fabrice Bellard 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, see . 18 | */ 19 | 20 | #ifndef CPUTLB_H 21 | #define CPUTLB_H 22 | 23 | #include "exec/cpu-common.h" 24 | 25 | /* cputlb.c */ 26 | void tlb_protect_code(struct uc_struct *uc, ram_addr_t ram_addr); 27 | void tlb_unprotect_code(struct uc_struct *uc, ram_addr_t ram_addr); 28 | #endif 29 | -------------------------------------------------------------------------------- /qemu/include/exec/hwaddr.h: -------------------------------------------------------------------------------- 1 | /* Define hwaddr if it exists. */ 2 | 3 | #ifndef HWADDR_H 4 | #define HWADDR_H 5 | 6 | 7 | #define HWADDR_BITS 64 8 | /* hwaddr is the type of a physical address (its size can 9 | be different from 'target_ulong'). */ 10 | 11 | typedef uint64_t hwaddr; 12 | #define HWADDR_MAX UINT64_MAX 13 | #define TARGET_FMT_plx "%016" PRIx64 14 | #define HWADDR_PRId PRId64 15 | #define HWADDR_PRIi PRIi64 16 | #define HWADDR_PRIo PRIo64 17 | #define HWADDR_PRIu PRIu64 18 | #define HWADDR_PRIx PRIx64 19 | #define HWADDR_PRIX PRIX64 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /qemu/include/exec/ramblock.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Declarations for cpu physical memory functions 3 | * 4 | * Copyright 2011 Red Hat, Inc. and/or its affiliates 5 | * 6 | * Authors: 7 | * Avi Kivity 8 | * 9 | * This work is licensed under the terms of the GNU GPL, version 2 or 10 | * later. See the COPYING file in the top-level directory. 11 | * 12 | */ 13 | 14 | /* 15 | * This header is for use by exec.c and memory.c ONLY. Do not include it. 16 | * The functions declared here will be removed soon. 17 | */ 18 | 19 | #ifndef QEMU_EXEC_RAMBLOCK_H 20 | #define QEMU_EXEC_RAMBLOCK_H 21 | 22 | #include "cpu-common.h" 23 | #include "qemu.h" 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /qemu/include/exec/ramlist.h: -------------------------------------------------------------------------------- 1 | #ifndef RAMLIST_H 2 | #define RAMLIST_H 3 | 4 | #include "qemu/queue.h" 5 | #include "qemu/thread.h" 6 | //#include "qemu/rcu.h" 7 | //#include "qemu/rcu_queue.h" 8 | 9 | #define DIRTY_MEMORY_VGA 0 10 | #define DIRTY_MEMORY_CODE 1 11 | #define DIRTY_MEMORY_MIGRATION 2 12 | #define DIRTY_MEMORY_NUM 3 /* num of dirty bits */ 13 | 14 | #define INTERNAL_RAMBLOCK_FOREACH(block) \ 15 | QLIST_FOREACH(block, &uc->ram_list.blocks, next) 16 | /* Never use the INTERNAL_ version except for defining other macros */ 17 | #define RAMBLOCK_FOREACH(block) INTERNAL_RAMBLOCK_FOREACH(block) 18 | 19 | #endif /* RAMLIST_H */ 20 | -------------------------------------------------------------------------------- /qemu/include/exec/target_page.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Target page sizes and friends for non target files 3 | * 4 | * Copyright (c) 2017 Red Hat Inc 5 | * 6 | * Authors: 7 | * David Alan Gilbert 8 | * Juan Quintela 9 | * 10 | * This work is licensed under the terms of the GNU GPL, version 2 or later. 11 | * See the COPYING file in the top-level directory. 12 | */ 13 | 14 | #ifndef EXEC_TARGET_PAGE_H 15 | #define EXEC_TARGET_PAGE_H 16 | 17 | struct uc_struct; 18 | 19 | size_t qemu_target_page_size(struct uc_struct *uc); 20 | int qemu_target_page_bits(struct uc_struct *uc); 21 | int qemu_target_page_bits_min(void); 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /qemu/include/exec/tb-context.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Internal structs that QEMU exports to TCG 3 | * 4 | * Copyright (c) 2003 Fabrice Bellard 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, see . 18 | */ 19 | 20 | #ifndef QEMU_TB_CONTEXT_H 21 | #define QEMU_TB_CONTEXT_H 22 | 23 | #include "qemu/thread.h" 24 | #include "qemu/qht.h" 25 | 26 | #define CODE_GEN_HTABLE_BITS 15 27 | #define CODE_GEN_HTABLE_SIZE (1 << CODE_GEN_HTABLE_BITS) 28 | 29 | typedef struct TranslationBlock TranslationBlock; 30 | typedef struct TBContext TBContext; 31 | 32 | struct TBContext { 33 | struct qht htable; 34 | 35 | /* statistics */ 36 | unsigned tb_flush_count; 37 | }; 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /qemu/include/hw/mips/cpudevs.h: -------------------------------------------------------------------------------- 1 | #ifndef HW_MIPS_CPUDEVS_H 2 | #define HW_MIPS_CPUDEVS_H 3 | 4 | #include "target/mips/cpu-qom.h" 5 | 6 | /* Definitions for MIPS CPU internal devices. */ 7 | 8 | /* addr.c */ 9 | uint64_t cpu_mips_kseg0_to_phys(void *opaque, uint64_t addr); 10 | uint64_t cpu_mips_phys_to_kseg0(void *opaque, uint64_t addr); 11 | uint64_t cpu_mips_kvm_um_phys_to_kseg0(void *opaque, uint64_t addr); 12 | bool mips_um_ksegs_enabled(void); 13 | void mips_um_ksegs_enable(void); 14 | 15 | /* mips_int.c */ 16 | void cpu_mips_irq_init_cpu(MIPSCPU *cpu); 17 | 18 | /* mips_timer.c */ 19 | void cpu_mips_clock_init(MIPSCPU *cpu); 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /qemu/include/qemu/crc32c.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Castagnoli CRC32C Checksum Algorithm 3 | * 4 | * Polynomial: 0x11EDC6F41 5 | * 6 | * Castagnoli93: Guy Castagnoli and Stefan Braeuer and Martin Herrman 7 | * "Optimization of Cyclic Redundancy-Check Codes with 24 8 | * and 32 Parity Bits",IEEE Transactions on Communication, 9 | * Volume 41, Number 6, June 1993 10 | * 11 | * Copyright (c) 2013 Red Hat, Inc., 12 | * 13 | * Authors: 14 | * Jeff Cody 15 | * 16 | * Based on the Linux kernel cryptographic crc32c module, 17 | * 18 | * Copyright (c) 2004 Cisco Systems, Inc. 19 | * Copyright (c) 2008 Herbert Xu 20 | * 21 | * This program is free software; you can redistribute it and/or modify it 22 | * under the terms of the GNU General Public License as published by the Free 23 | * Software Foundation; either version 2 of the License, or (at your option) 24 | * any later version. 25 | * 26 | */ 27 | 28 | #ifndef QEMU_CRC32C_H 29 | #define QEMU_CRC32C_H 30 | 31 | 32 | uint32_t crc32c(uint32_t crc, const uint8_t *data, unsigned int length); 33 | 34 | uint32_t crc32(uint32_t crc, const uint8_t *data, unsigned int length); 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /qemu/include/qemu/ctype.h: -------------------------------------------------------------------------------- 1 | /* 2 | * QEMU TCG support 3 | * 4 | * This work is licensed under the terms of the GNU GPL, version 2 or later. 5 | * See the COPYING file in the top-level directory. 6 | */ 7 | 8 | #ifndef QEMU_CTYPE_H 9 | #define QEMU_CTYPE_H 10 | 11 | #define qemu_isalnum(c) isalnum((unsigned char)(c)) 12 | #define qemu_isalpha(c) isalpha((unsigned char)(c)) 13 | #define qemu_iscntrl(c) iscntrl((unsigned char)(c)) 14 | #define qemu_isdigit(c) isdigit((unsigned char)(c)) 15 | #define qemu_isgraph(c) isgraph((unsigned char)(c)) 16 | #define qemu_islower(c) islower((unsigned char)(c)) 17 | #define qemu_isprint(c) isprint((unsigned char)(c)) 18 | #define qemu_ispunct(c) ispunct((unsigned char)(c)) 19 | #define qemu_isspace(c) isspace((unsigned char)(c)) 20 | #define qemu_isupper(c) isupper((unsigned char)(c)) 21 | #define qemu_isxdigit(c) isxdigit((unsigned char)(c)) 22 | #define qemu_tolower(c) tolower((unsigned char)(c)) 23 | #define qemu_toupper(c) toupper((unsigned char)(c)) 24 | #define qemu_isascii(c) isascii((unsigned char)(c)) 25 | #define qemu_toascii(c) toascii((unsigned char)(c)) 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /qemu/include/qemu/processor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016, Emilio G. Cota 3 | * 4 | * License: GNU GPL, version 2. 5 | * See the COPYING file in the top-level directory. 6 | */ 7 | #ifndef QEMU_PROCESSOR_H 8 | #define QEMU_PROCESSOR_H 9 | 10 | #include "qemu/atomic.h" 11 | 12 | #if defined(__i386__) || defined(__x86_64__) 13 | # define cpu_relax() asm volatile("rep; nop" ::: "memory") 14 | 15 | #elif defined(__aarch64__) 16 | # define cpu_relax() asm volatile("yield" ::: "memory") 17 | 18 | #elif defined(__powerpc64__) 19 | /* set Hardware Multi-Threading (HMT) priority to low; then back to medium */ 20 | # define cpu_relax() asm volatile("or 1, 1, 1;" \ 21 | "or 2, 2, 2;" ::: "memory") 22 | 23 | #else 24 | # define cpu_relax() barrier() 25 | #endif 26 | 27 | #endif /* QEMU_PROCESSOR_H */ 28 | -------------------------------------------------------------------------------- /qemu/include/qemu/thread-posix.h: -------------------------------------------------------------------------------- 1 | #ifndef QEMU_THREAD_POSIX_H 2 | #define QEMU_THREAD_POSIX_H 3 | 4 | #include 5 | #include 6 | 7 | struct QemuThread { 8 | pthread_t thread; 9 | }; 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /qemu/include/qemu/thread-win32.h: -------------------------------------------------------------------------------- 1 | #ifndef QEMU_THREAD_WIN32_H 2 | #define QEMU_THREAD_WIN32_H 3 | 4 | #include 5 | 6 | typedef struct QemuThreadData QemuThreadData; 7 | struct QemuThread { 8 | QemuThreadData *data; 9 | unsigned tid; 10 | }; 11 | 12 | /* Only valid for joinable threads. */ 13 | HANDLE qemu_thread_get_handle(struct QemuThread *thread); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /qemu/include/qemu/thread.h: -------------------------------------------------------------------------------- 1 | #ifndef QEMU_THREAD_H 2 | #define QEMU_THREAD_H 3 | 4 | #include "unicorn/platform.h" 5 | #include "qemu/processor.h" 6 | 7 | struct uc_struct; 8 | typedef struct QemuThread QemuThread; 9 | 10 | #if defined(_WIN32) && !defined(__MINGW32__) 11 | #include "qemu/thread-win32.h" 12 | #else 13 | #include "qemu/thread-posix.h" 14 | #endif 15 | 16 | #define QEMU_THREAD_JOINABLE 0 17 | #define QEMU_THREAD_DETACHED 1 18 | 19 | int qemu_thread_create(struct uc_struct *uc, QemuThread *thread, const char *name, 20 | void *(*start_routine)(void *), 21 | void *arg, int mode); 22 | void *qemu_thread_join(QemuThread *thread); 23 | void qemu_thread_exit(struct uc_struct *uc, void *retval); 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /qemu/include/qemu/units.h: -------------------------------------------------------------------------------- 1 | /* 2 | * IEC binary prefixes definitions 3 | * 4 | * Copyright (C) 2015 Nikunj A Dadhania, IBM Corporation 5 | * Copyright (C) 2018 Philippe Mathieu-Daudé 6 | * 7 | * SPDX-License-Identifier: GPL-2.0-or-later 8 | */ 9 | 10 | #ifndef QEMU_UNITS_H 11 | #define QEMU_UNITS_H 12 | 13 | #define KiB (INT64_C(1) << 10) 14 | #define MiB (INT64_C(1) << 20) 15 | #define GiB (INT64_C(1) << 30) 16 | #define TiB (INT64_C(1) << 40) 17 | #define PiB (INT64_C(1) << 50) 18 | #define EiB (INT64_C(1) << 60) 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /qemu/include/sysemu/cpus.h: -------------------------------------------------------------------------------- 1 | #ifndef QEMU_CPUS_H 2 | #define QEMU_CPUS_H 3 | 4 | #include "qemu/timer.h" 5 | 6 | /* cpus.c */ 7 | bool qemu_in_vcpu_thread(void); 8 | void qemu_init_cpu_loop(void); 9 | void resume_all_vcpus(struct uc_struct* uc); 10 | void cpu_stop_current(struct uc_struct* uc); 11 | void cpu_ticks_init(void); 12 | 13 | /* Unblock cpu */ 14 | void qemu_cpu_kick_self(void); 15 | 16 | void cpu_synchronize_all_states(void); 17 | void cpu_synchronize_all_post_reset(void); 18 | void cpu_synchronize_all_post_init(void); 19 | void cpu_synchronize_all_pre_loadvm(void); 20 | 21 | void qtest_clock_warp(int64_t dest); 22 | 23 | void list_cpus(const char *optarg); 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /qemu/include/sysemu/sysemu.h: -------------------------------------------------------------------------------- 1 | #ifndef SYSEMU_H 2 | #define SYSEMU_H 3 | 4 | struct uc_struct; 5 | 6 | void qemu_system_reset_request(struct uc_struct*); 7 | void qemu_system_shutdown_request(struct uc_struct*); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /qemu/include/sysemu/tcg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * QEMU TCG support 3 | * 4 | * This work is licensed under the terms of the GNU GPL, version 2 or later. 5 | * See the COPYING file in the top-level directory. 6 | */ 7 | 8 | #ifndef SYSEMU_TCG_H 9 | #define SYSEMU_TCG_H 10 | 11 | #include "uc_priv.h" 12 | 13 | void tcg_exec_init(struct uc_struct *uc, unsigned long tb_size); 14 | 15 | uc_err tcg_set_native_thunks(uc_engine *uc, 16 | uc_cb_is_native_t is_native, 17 | uc_cb_call_native_t call_native); 18 | 19 | void tcg_get_code_gen_buf(struct uc_struct *uc, 20 | void **code_gen_buf, 21 | size_t *code_gen_size); 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /qemu/target/arm/README: -------------------------------------------------------------------------------- 1 | code under arm/ is from arm-softmmu/target/arm/*.inc.c 2 | code under aarch64/ is from aarch64-softmmu/target/aarch64/*.inc.c 3 | 4 | WARNING: these code are autogen from scripts/decodetree.py, DO NOT modify them. 5 | 6 | -------------------------------------------------------------------------------- /qemu/target/arm/cpu-param.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ARM cpu parameters for qemu. 3 | * 4 | * Copyright (c) 2003 Fabrice Bellard 5 | * SPDX-License-Identifier: LGPL-2.0+ 6 | */ 7 | 8 | #ifndef ARM_CPU_PARAM_H 9 | #define ARM_CPU_PARAM_H 1 10 | 11 | #ifdef TARGET_AARCH64 12 | # define TARGET_LONG_BITS 64 13 | # define TARGET_PHYS_ADDR_SPACE_BITS 48 14 | # define TARGET_VIRT_ADDR_SPACE_BITS 48 15 | #else 16 | # define TARGET_LONG_BITS 32 17 | # define TARGET_PHYS_ADDR_SPACE_BITS 40 18 | # define TARGET_VIRT_ADDR_SPACE_BITS 32 19 | #endif 20 | 21 | /* 22 | * ARMv7 and later CPUs have 4K pages minimum, but ARMv5 and v6 23 | * have to support 1K tiny pages. 24 | */ 25 | # define TARGET_PAGE_BITS_VARY 26 | # define TARGET_PAGE_BITS_MIN 10 27 | 28 | #define NB_MMU_MODES 12 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /qemu/target/i386/TODO: -------------------------------------------------------------------------------- 1 | Correctness issues: 2 | 3 | - some eflags manipulation incorrectly reset the bit 0x2. 4 | - SVM: test, cpu save/restore, SMM save/restore. 5 | - x86_64: lcall/ljmp intel/amd differences ? 6 | - better code fetch (different exception handling + CS.limit support) 7 | - user/kernel PUSHL/POPL in helper.c 8 | - add missing cpuid tests 9 | - return UD exception if LOCK prefix incorrectly used 10 | - test ldt limit < 7 ? 11 | - fix some 16 bit sp push/pop overflow (pusha/popa, lcall lret) 12 | - full support of segment limit/rights 13 | - full x87 exception support 14 | - improve x87 bit exactness (use bochs code ?) 15 | - DRx register support 16 | - CR0.AC emulation 17 | - SSE alignment checks 18 | 19 | Optimizations/Features: 20 | 21 | - add SVM nested paging support 22 | - add VMX support 23 | - add AVX support 24 | - add SSE5 support 25 | - fxsave/fxrstor AMD extensions 26 | - improve monitor/mwait support 27 | - faster EFLAGS update: consider SZAP, C, O can be updated separately 28 | with a bit field in CC_OP and more state variables. 29 | - evaluate x87 stack pointer statically 30 | - find a way to avoid translating several time the same TB if CR0.TS 31 | is set or not. 32 | -------------------------------------------------------------------------------- /qemu/target/i386/cpu-param.h: -------------------------------------------------------------------------------- 1 | /* 2 | * i386 cpu parameters for qemu. 3 | * 4 | * Copyright (c) 2003 Fabrice Bellard 5 | * SPDX-License-Identifier: LGPL-2.0+ 6 | */ 7 | 8 | #ifndef I386_CPU_PARAM_H 9 | #define I386_CPU_PARAM_H 1 10 | 11 | #ifdef TARGET_X86_64 12 | # define TARGET_LONG_BITS 64 13 | # define TARGET_PHYS_ADDR_SPACE_BITS 52 14 | /* 15 | * ??? This is really 48 bits, sign-extended, but the only thing 16 | * accessible to userland with bit 48 set is the VSYSCALL, and that 17 | * is handled via other mechanisms. 18 | */ 19 | # define TARGET_VIRT_ADDR_SPACE_BITS 47 20 | #else 21 | # define TARGET_LONG_BITS 32 22 | # define TARGET_PHYS_ADDR_SPACE_BITS 36 23 | # define TARGET_VIRT_ADDR_SPACE_BITS 32 24 | #endif 25 | #define TARGET_PAGE_BITS 12 26 | #define NB_MMU_MODES 3 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /qemu/target/i386/machine.c: -------------------------------------------------------------------------------- 1 | #include "qemu/osdep.h" 2 | #include "cpu.h" 3 | #include "exec/exec-all.h" 4 | 5 | #include "sysemu/tcg.h" 6 | 7 | void cpu_get_fp80(uint64_t *pmant, uint16_t *pexp, floatx80 f) 8 | { 9 | CPU_LDoubleU temp; 10 | 11 | temp.d = f; 12 | *pmant = temp.l.lower; 13 | *pexp = temp.l.upper; 14 | } 15 | 16 | floatx80 cpu_set_fp80(uint64_t mant, uint16_t upper) 17 | { 18 | CPU_LDoubleU temp; 19 | 20 | temp.l.upper = upper; 21 | temp.l.lower = mant; 22 | return temp.d; 23 | } 24 | -------------------------------------------------------------------------------- /qemu/target/i386/unicorn.h: -------------------------------------------------------------------------------- 1 | /* Unicorn Emulator Engine */ 2 | /* By Nguyen Anh Quynh , 2015 */ 3 | /* Modified for Unicorn Engine by Chen Huitao, 2020 */ 4 | 5 | #ifndef UC_QEMU_TARGET_I386_H 6 | #define UC_QEMU_TARGET_I386_H 7 | 8 | // functions to read & write registers 9 | int x86_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, 10 | int count); 11 | int x86_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, 12 | int count); 13 | int x86_context_reg_read(struct uc_context *ctx, unsigned int *regs, 14 | void **vals, int count); 15 | int x86_context_reg_write(struct uc_context *ctx, unsigned int *regs, 16 | void *const *vals, int count); 17 | 18 | void x86_reg_reset(struct uc_struct *uc); 19 | 20 | void x86_uc_init(struct uc_struct *uc); 21 | #endif 22 | -------------------------------------------------------------------------------- /qemu/target/m68k/cpu-param.h: -------------------------------------------------------------------------------- 1 | /* 2 | * m68k cpu parameters for qemu. 3 | * 4 | * Copyright (c) 2005-2007 CodeSourcery 5 | * SPDX-License-Identifier: LGPL-2.0+ 6 | */ 7 | 8 | #ifndef M68K_CPU_PARAM_H 9 | #define M68K_CPU_PARAM_H 1 10 | 11 | #define TARGET_LONG_BITS 32 12 | /* 13 | * Coldfire Linux uses 8k pages 14 | * and m68k linux uses 4k pages 15 | * use the smallest one 16 | */ 17 | #define TARGET_PAGE_BITS 12 18 | #define TARGET_PHYS_ADDR_SPACE_BITS 32 19 | #define TARGET_VIRT_ADDR_SPACE_BITS 32 20 | #define NB_MMU_MODES 2 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /qemu/target/m68k/qregs.def: -------------------------------------------------------------------------------- 1 | DEFO32(PC, pc) 2 | DEFO32(SR, sr) 3 | DEFO32(CC_OP, cc_op) 4 | DEFO32(CC_X, cc_x) 5 | DEFO32(CC_C, cc_c) 6 | DEFO32(CC_N, cc_n) 7 | DEFO32(CC_V, cc_v) 8 | DEFO32(CC_Z, cc_z) 9 | DEFO32(MACSR, macsr) 10 | DEFO32(MAC_MASK, mac_mask) 11 | -------------------------------------------------------------------------------- /qemu/target/m68k/unicorn.h: -------------------------------------------------------------------------------- 1 | /* Unicorn Emulator Engine */ 2 | /* By Nguyen Anh Quynh , 2015 */ 3 | 4 | #ifndef UC_QEMU_TARGET_M68K_H 5 | #define UC_QEMU_TARGET_M68K_H 6 | 7 | // functions to read & write registers 8 | int m68k_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, 9 | int count); 10 | int m68k_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, 11 | int count); 12 | int m68k_context_reg_read(struct uc_context *ctx, unsigned int *regs, 13 | void **vals, int count); 14 | int m68k_context_reg_write(struct uc_context *ctx, unsigned int *regs, 15 | void *const *vals, int count); 16 | 17 | void m68k_reg_reset(struct uc_struct *uc); 18 | 19 | void m68k_uc_init(struct uc_struct *uc); 20 | #endif 21 | -------------------------------------------------------------------------------- /qemu/target/mips/cpu-param.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MIPS cpu parameters for qemu. 3 | * 4 | * SPDX-License-Identifier: LGPL-2.0+ 5 | */ 6 | 7 | #ifndef MIPS_CPU_PARAM_H 8 | #define MIPS_CPU_PARAM_H 1 9 | 10 | #ifdef TARGET_MIPS64 11 | # define TARGET_LONG_BITS 64 12 | #else 13 | # define TARGET_LONG_BITS 32 14 | #endif 15 | #ifdef TARGET_MIPS64 16 | #define TARGET_PHYS_ADDR_SPACE_BITS 48 17 | #define TARGET_VIRT_ADDR_SPACE_BITS 48 18 | #else 19 | #define TARGET_PHYS_ADDR_SPACE_BITS 40 20 | #define TARGET_VIRT_ADDR_SPACE_BITS 32 21 | #endif 22 | #define TARGET_PAGE_BITS 12 23 | #define NB_MMU_MODES 4 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /qemu/target/ppc/cpu-param.h: -------------------------------------------------------------------------------- 1 | /* 2 | * PowerPC cpu parameters for qemu. 3 | * 4 | * Copyright (c) 2007 Jocelyn Mayer 5 | * SPDX-License-Identifier: LGPL-2.0+ 6 | */ 7 | 8 | #ifndef PPC_CPU_PARAM_H 9 | #define PPC_CPU_PARAM_H 1 10 | 11 | #ifdef TARGET_PPC64 12 | # define TARGET_LONG_BITS 64 13 | /* 14 | * Note that the official physical address space bits is 62-M where M 15 | * is implementation dependent. I've not looked up M for the set of 16 | * cpus we emulate at the system level. 17 | */ 18 | #define TARGET_PHYS_ADDR_SPACE_BITS 62 19 | /* 20 | * Note that the PPC environment architecture talks about 80 bit virtual 21 | * addresses, with segmentation. Obviously that's not all visible to a 22 | * single process, which is all we're concerned with here. 23 | */ 24 | # ifdef TARGET_ABI32 25 | # define TARGET_VIRT_ADDR_SPACE_BITS 32 26 | # else 27 | # define TARGET_VIRT_ADDR_SPACE_BITS 64 28 | # endif 29 | #else 30 | # define TARGET_LONG_BITS 32 31 | # define TARGET_PHYS_ADDR_SPACE_BITS 36 32 | # define TARGET_VIRT_ADDR_SPACE_BITS 32 33 | #endif 34 | #define TARGET_PAGE_BITS 12 35 | #define NB_MMU_MODES 10 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /qemu/target/ppc/mfrom_table_gen.c: -------------------------------------------------------------------------------- 1 | #define _GNU_SOURCE 2 | #include "qemu/osdep.h" 3 | #include 4 | 5 | int main(void) 6 | { 7 | double d; 8 | uint8_t n; 9 | int i; 10 | 11 | printf("static const uint8_t mfrom_ROM_table[602] =\n{\n "); 12 | for (i = 0; i < 602; i++) { 13 | /* 14 | * Extremely decomposed: 15 | * -T0 / 256 16 | * T0 = 256 * log10(10 + 1.0) + 0.5 17 | */ 18 | d = -i; 19 | d /= 256.0; 20 | d = exp10(d); 21 | d += 1.0; 22 | d = log10(d); 23 | d *= 256; 24 | d += 0.5; 25 | n = d; 26 | printf("%3d, ", n); 27 | if ((i & 7) == 7) { 28 | printf("\n "); 29 | } 30 | } 31 | printf("\n};\n"); 32 | 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /qemu/target/ppc/unicorn.h: -------------------------------------------------------------------------------- 1 | /* Unicorn Emulator Engine */ 2 | /* By Nguyen Anh Quynh , 2015 */ 3 | 4 | #ifndef UC_QEMU_TARGET_PPC_H 5 | #define UC_QEMU_TARGET_PPC_H 6 | 7 | // functions to read & write registers 8 | int ppc_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, 9 | int count); 10 | int ppc_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, 11 | int count); 12 | 13 | int ppc_context_reg_read(struct uc_context *ctx, unsigned int *regs, 14 | void **vals, int count); 15 | int ppc_context_reg_write(struct uc_context *ctx, unsigned int *regs, 16 | void *const *vals, int count); 17 | int ppc64_context_reg_read(struct uc_context *ctx, unsigned int *regs, 18 | void **vals, int count); 19 | int ppc64_context_reg_write(struct uc_context *ctx, unsigned int *regs, 20 | void *const *vals, int count); 21 | 22 | void ppc_reg_reset(struct uc_struct *uc); 23 | 24 | void ppc_uc_init(struct uc_struct *uc); 25 | void ppc64_uc_init(struct uc_struct *uc); 26 | #endif 27 | -------------------------------------------------------------------------------- /qemu/target/riscv/README: -------------------------------------------------------------------------------- 1 | code under riscv32/ is from riscv32-softmmu/target/riscv/*.inc.c 2 | code under riscv64/ is from riscv64-softmmu/target/riscv/*.inc.c 3 | 4 | WARNING: these code are autogen from scripts/decodetree.py, DO NOT modify them. 5 | -------------------------------------------------------------------------------- /qemu/target/riscv/cpu-param.h: -------------------------------------------------------------------------------- 1 | /* 2 | * RISC-V cpu parameters for qemu. 3 | * 4 | * Copyright (c) 2017-2018 SiFive, Inc. 5 | * SPDX-License-Identifier: GPL-2.0+ 6 | */ 7 | 8 | #ifndef RISCV_CPU_PARAM_H 9 | #define RISCV_CPU_PARAM_H 1 10 | 11 | #if defined(TARGET_RISCV64) 12 | # define TARGET_LONG_BITS 64 13 | # define TARGET_PHYS_ADDR_SPACE_BITS 56 /* 44-bit PPN */ 14 | # define TARGET_VIRT_ADDR_SPACE_BITS 48 /* sv48 */ 15 | #elif defined(TARGET_RISCV32) 16 | # define TARGET_LONG_BITS 32 17 | # define TARGET_PHYS_ADDR_SPACE_BITS 34 /* 22-bit PPN */ 18 | # define TARGET_VIRT_ADDR_SPACE_BITS 32 /* sv32 */ 19 | #endif 20 | #define TARGET_PAGE_BITS 12 /* 4 KiB Pages */ 21 | #define NB_MMU_MODES 4 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /qemu/target/riscv/cpu_user.h: -------------------------------------------------------------------------------- 1 | #ifndef TARGET_RISCV_CPU_USER_H 2 | #define TARGET_RISCV_CPU_USER_H 3 | 4 | #define xRA 1 /* return address (aka link register) */ 5 | #define xSP 2 /* stack pointer */ 6 | #define xGP 3 /* global pointer */ 7 | #define xTP 4 /* thread pointer */ 8 | 9 | #define xA0 10 /* gpr[10-17] are syscall arguments */ 10 | #define xA1 11 11 | #define xA2 12 12 | #define xA3 13 13 | #define xA4 14 14 | #define xA5 15 15 | #define xA6 16 16 | #define xA7 17 /* syscall number for RVI ABI */ 17 | #define xT0 5 /* syscall number for RVE ABI */ 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /qemu/target/riscv/unicorn.h: -------------------------------------------------------------------------------- 1 | /* Unicorn Emulator Engine */ 2 | /* By Nguyen Anh Quynh , 2015 */ 3 | /* Modified for Unicorn Engine by Chen Huitao, 2020 */ 4 | 5 | #ifndef UC_QEMU_TARGET_RISCV_H 6 | #define UC_QEMU_TARGET_RISCV_H 7 | 8 | // functions to read & write registers 9 | int riscv_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, 10 | int count); 11 | int riscv_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, 12 | int count); 13 | 14 | int riscv32_context_reg_read(struct uc_context *ctx, unsigned int *regs, 15 | void **vals, int count); 16 | int riscv32_context_reg_write(struct uc_context *ctx, unsigned int *regs, 17 | void *const *vals, int count); 18 | int riscv64_context_reg_read(struct uc_context *ctx, unsigned int *regs, 19 | void **vals, int count); 20 | int riscv64_context_reg_write(struct uc_context *ctx, unsigned int *regs, 21 | void *const *vals, int count); 22 | 23 | void riscv_reg_reset(struct uc_struct *uc); 24 | 25 | void riscv32_uc_init(struct uc_struct *uc); 26 | void riscv64_uc_init(struct uc_struct *uc); 27 | #endif 28 | -------------------------------------------------------------------------------- /qemu/target/s390x/cpu-param.h: -------------------------------------------------------------------------------- 1 | /* 2 | * S/390 cpu parameters for qemu. 3 | * 4 | * Copyright (c) 2009 Ulrich Hecht 5 | * SPDX-License-Identifier: GPL-2.0+ 6 | */ 7 | 8 | #ifndef S390_CPU_PARAM_H 9 | #define S390_CPU_PARAM_H 1 10 | 11 | #define TARGET_LONG_BITS 64 12 | #define TARGET_PAGE_BITS 12 13 | #define TARGET_PHYS_ADDR_SPACE_BITS 64 14 | #define TARGET_VIRT_ADDR_SPACE_BITS 64 15 | #define NB_MMU_MODES 4 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /qemu/target/s390x/cpu_features_def.h: -------------------------------------------------------------------------------- 1 | /* 2 | * CPU features/facilities for s390 3 | * 4 | * Copyright IBM Corp. 2016, 2018 5 | * Copyright Red Hat, Inc. 2019 6 | * 7 | * Author(s): Michael Mueller 8 | * David Hildenbrand 9 | * 10 | * This work is licensed under the terms of the GNU GPL, version 2 or (at 11 | * your option) any later version. See the COPYING file in the top-level 12 | * directory. 13 | */ 14 | 15 | #ifndef TARGET_S390X_CPU_FEATURES_DEF_H 16 | #define TARGET_S390X_CPU_FEATURES_DEF_H 17 | 18 | #define DEF_FEAT(_FEAT, ...) S390_FEAT_##_FEAT, 19 | typedef enum { 20 | #include "cpu_features_def.inc.h" 21 | S390_FEAT_MAX, 22 | } S390Feat; 23 | #undef DEF_FEAT 24 | 25 | #endif /* TARGET_S390X_CPU_FEATURES_DEF_H */ 26 | -------------------------------------------------------------------------------- /qemu/target/s390x/s390-tod.h: -------------------------------------------------------------------------------- 1 | /* 2 | * TOD (Time Of Day) clock 3 | * 4 | * Copyright 2018 Red Hat, Inc. 5 | * Author(s): David Hildenbrand 6 | * 7 | * This work is licensed under the terms of the GNU GPL, version 2 or later. 8 | * See the COPYING file in the top-level directory. 9 | */ 10 | 11 | #ifndef TARGET_S390_TOD_H 12 | #define TARGET_S390_TOD_H 13 | 14 | /* The value of the TOD clock for 1.1.1970. */ 15 | #define TOD_UNIX_EPOCH 0x7d91048bca000000ULL 16 | 17 | /* Converts ns to s390's clock format */ 18 | static inline uint64_t time2tod(uint64_t ns) 19 | { 20 | return (ns << 9) / 125 + (((ns & 0xff80000000000000ull) / 125) << 9); 21 | } 22 | 23 | /* Converts s390's clock format to ns */ 24 | static inline uint64_t tod2time(uint64_t t) 25 | { 26 | return ((t >> 9) * 125) + (((t & 0x1ff) * 125) >> 9); 27 | } 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /qemu/target/s390x/tcg-stub.c: -------------------------------------------------------------------------------- 1 | /* 2 | * QEMU TCG support -- s390x specific function stubs. 3 | * 4 | * Copyright (C) 2018 Red Hat Inc 5 | * 6 | * Authors: 7 | * David Hildenbrand 8 | * 9 | * This work is licensed under the terms of the GNU GPL, version 2 or later. 10 | * See the COPYING file in the top-level directory. 11 | */ 12 | 13 | #include "qemu/osdep.h" 14 | #include "qemu-common.h" 15 | #include "cpu.h" 16 | #include "tcg_s390x.h" -------------------------------------------------------------------------------- /qemu/target/s390x/tcg_s390x.h: -------------------------------------------------------------------------------- 1 | /* 2 | * QEMU TCG support -- s390x specific functions. 3 | * 4 | * Copyright 2018 Red Hat, Inc. 5 | * 6 | * Authors: 7 | * David Hildenbrand 8 | * 9 | * This work is licensed under the terms of the GNU GPL, version 2 or later. 10 | * See the COPYING file in the top-level directory. 11 | */ 12 | 13 | #ifndef TCG_S390X_H 14 | #define TCG_S390X_H 15 | 16 | void tcg_s390_tod_updated(CPUState *cs, run_on_cpu_data opaque); 17 | void QEMU_NORETURN tcg_s390_program_interrupt(CPUS390XState *env, 18 | uint32_t code, uintptr_t ra); 19 | void QEMU_NORETURN tcg_s390_data_exception(CPUS390XState *env, uint32_t dxc, 20 | uintptr_t ra); 21 | void QEMU_NORETURN tcg_s390_vector_exception(CPUS390XState *env, uint32_t vxc, 22 | uintptr_t ra); 23 | 24 | #endif /* TCG_S390X_H */ 25 | -------------------------------------------------------------------------------- /qemu/target/s390x/unicorn.h: -------------------------------------------------------------------------------- 1 | /* Unicorn Emulator Engine */ 2 | /* By Nguyen Anh Quynh , 2015-2021 */ 3 | 4 | #ifndef UC_QEMU_TARGET_S390X_H 5 | #define UC_QEMU_TARGET_S390X_H 6 | 7 | // functions to read & write registers 8 | // int s390_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int 9 | // count); int s390_reg_write(struct uc_struct *uc, unsigned int *regs, void 10 | // *const *vals, int count); 11 | int s390_context_reg_read(struct uc_context *ctx, unsigned int *regs, 12 | void **vals, int count); 13 | int s390_context_reg_write(struct uc_context *ctx, unsigned int *regs, 14 | void *const *vals, int count); 15 | 16 | void s390_reg_reset(struct uc_struct *uc); 17 | 18 | void s390_uc_init(struct uc_struct *uc); 19 | #endif 20 | -------------------------------------------------------------------------------- /qemu/target/sparc/cpu-param.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Sparc cpu parameters for qemu. 3 | * 4 | * SPDX-License-Identifier: LGPL-2.0+ 5 | */ 6 | 7 | #ifndef SPARC_CPU_PARAM_H 8 | #define SPARC_CPU_PARAM_H 1 9 | 10 | #ifdef TARGET_SPARC64 11 | # define TARGET_LONG_BITS 64 12 | # define TARGET_PAGE_BITS 13 /* 8k */ 13 | # define TARGET_PHYS_ADDR_SPACE_BITS 41 14 | # ifdef TARGET_ABI32 15 | # define TARGET_VIRT_ADDR_SPACE_BITS 32 16 | # else 17 | # define TARGET_VIRT_ADDR_SPACE_BITS 44 18 | # endif 19 | # define NB_MMU_MODES 6 20 | #else 21 | # define TARGET_LONG_BITS 32 22 | # define TARGET_PAGE_BITS 12 /* 4k */ 23 | # define TARGET_PHYS_ADDR_SPACE_BITS 36 24 | # define TARGET_VIRT_ADDR_SPACE_BITS 32 25 | # define NB_MMU_MODES 3 26 | #endif 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /qemu/target/sparc/unicorn.h: -------------------------------------------------------------------------------- 1 | /* Unicorn Emulator Engine */ 2 | /* By Nguyen Anh Quynh , 2015 */ 3 | 4 | #ifndef UC_QEMU_TARGET_SPARC_H 5 | #define UC_QEMU_TARGET_SPARC_H 6 | 7 | // functions to read & write registers 8 | int sparc_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, 9 | int count); 10 | int sparc_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, 11 | int count); 12 | 13 | int sparc_context_reg_read(struct uc_context *ctx, unsigned int *regs, 14 | void **vals, int count); 15 | int sparc_context_reg_write(struct uc_context *ctx, unsigned int *regs, 16 | void *const *vals, int count); 17 | int sparc64_context_reg_read(struct uc_context *ctx, unsigned int *regs, 18 | void **vals, int count); 19 | int sparc64_context_reg_write(struct uc_context *ctx, unsigned int *regs, 20 | void *const *vals, int count); 21 | 22 | void sparc_reg_reset(struct uc_struct *uc); 23 | 24 | void sparc_uc_init(struct uc_struct *uc); 25 | void sparc64_uc_init(struct uc_struct *uc); 26 | #endif 27 | -------------------------------------------------------------------------------- /qemu/target/tricore/cpu-param.h: -------------------------------------------------------------------------------- 1 | /* 2 | * TriCore cpu parameters for qemu. 3 | * 4 | * Copyright (c) 2012-2014 Bastian Koppelmann C-Lab/University Paderborn 5 | * SPDX-License-Identifier: LGPL-2.1+ 6 | */ 7 | 8 | #ifndef TRICORE_CPU_PARAM_H 9 | #define TRICORE_CPU_PARAM_H 1 10 | 11 | #define TARGET_LONG_BITS 32 12 | #define TARGET_PAGE_BITS 14 13 | #define TARGET_PHYS_ADDR_SPACE_BITS 32 14 | #define TARGET_VIRT_ADDR_SPACE_BITS 32 15 | #define NB_MMU_MODES 3 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /qemu/target/tricore/tricore-defs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012-2014 Bastian Koppelmann C-Lab/University Paderborn 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, see . 16 | */ 17 | 18 | #ifndef QEMU_TRICORE_DEFS_H 19 | #define QEMU_TRICORE_DEFS_H 20 | 21 | #define TRICORE_TLB_MAX 128 22 | 23 | #endif /* QEMU_TRICORE_DEFS_H */ 24 | -------------------------------------------------------------------------------- /qemu/target/tricore/unicorn.h: -------------------------------------------------------------------------------- 1 | /* Unicorn Emulator Engine */ 2 | /* By Nguyen Anh Quynh , 2015 */ 3 | 4 | /* 5 | Modified for Unicorn Engine by Eric Poole , 2022 6 | Copyright 2022 Aptiv 7 | */ 8 | 9 | #ifndef UC_QEMU_TARGET_TRICORE_H 10 | #define UC_QEMU_TARGET_TRICORE_H 11 | 12 | // functions to read & write registers 13 | int tricore_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, 14 | int count); 15 | int tricore_reg_write(struct uc_struct *uc, unsigned int *regs, 16 | void *const *vals, int count); 17 | 18 | int tricore_context_reg_read(struct uc_context *uc, unsigned int *regs, 19 | void **vals, int count); 20 | int tricore_context_reg_write(struct uc_context *uc, unsigned int *regs, 21 | void *const *vals, int count); 22 | 23 | void tricore_reg_reset(struct uc_struct *uc); 24 | 25 | void tricore_uc_init(struct uc_struct *uc); 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /qemu/tcg/aarch64/tcg-target.opc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019 Linaro 3 | * 4 | * This work is licensed under the terms of the GNU GPL, version 2 or 5 | * (at your option) any later version. 6 | * 7 | * See the COPYING file in the top-level directory for details. 8 | * 9 | * Target-specific opcodes for host vector expansion. These will be 10 | * emitted by tcg_expand_vec_op. For those familiar with GCC internals, 11 | * consider these to be UNSPEC with names. 12 | */ 13 | 14 | DEF(aa64_sshl_vec, 1, 2, 0, IMPLVEC) 15 | -------------------------------------------------------------------------------- /qemu/trace/mem.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Helper functions for guest memory tracing 3 | * 4 | * Copyright (C) 2016 Lluís Vilanova 5 | * 6 | * This work is licensed under the terms of the GNU GPL, version 2 or later. 7 | * See the COPYING file in the top-level directory. 8 | */ 9 | 10 | #ifndef TRACE__MEM_H 11 | #define TRACE__MEM_H 12 | 13 | #include "tcg/tcg.h" 14 | 15 | 16 | /** 17 | * trace_mem_get_info: 18 | * 19 | * Return a value for the 'info' argument in guest memory access traces. 20 | */ 21 | static uint16_t trace_mem_get_info(MemOp op, unsigned int mmu_idx, bool store); 22 | 23 | /** 24 | * trace_mem_build_info: 25 | * 26 | * Return a value for the 'info' argument in guest memory access traces. 27 | */ 28 | static uint16_t trace_mem_build_info(int size_shift, bool sign_extend, 29 | MemOp endianness, bool store, 30 | unsigned int mmuidx); 31 | 32 | 33 | #include "mem-internal.h" 34 | 35 | #endif /* TRACE__MEM_H */ 36 | -------------------------------------------------------------------------------- /qemu/util/oslib-efi.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "qemu/osdep.h" 3 | 4 | void qemu_anon_ram_free(struct uc_struct *uc, void *ptr, size_t size) 5 | { 6 | FreePages (ptr, EFI_SIZE_TO_PAGES (size)); 7 | } 8 | 9 | void *qemu_anon_ram_alloc(struct uc_struct *uc, size_t size, uint64_t *align) 10 | { 11 | void *ptr; 12 | 13 | ptr = AllocatePages (EFI_SIZE_TO_PAGES (size)); 14 | if (ptr == NULL) { 15 | return ptr; 16 | } 17 | 18 | *align = EFI_PAGE_SIZE; 19 | return ptr; 20 | } 21 | 22 | void qemu_vfree(void *ptr) 23 | { 24 | free(ptr); 25 | } 26 | 27 | void *qemu_memalign(size_t alignment, size_t size) 28 | { 29 | return memalign(alignment, size); 30 | } 31 | -------------------------------------------------------------------------------- /qemu/util/pagesize.c: -------------------------------------------------------------------------------- 1 | /* 2 | * pagesize.c - query the host about its page size 3 | * 4 | * Copyright (C) 2017, Emilio G. Cota 5 | * License: GNU GPL, version 2 or later. 6 | * See the COPYING file in the top-level directory. 7 | */ 8 | 9 | #include "qemu/osdep.h" 10 | 11 | #include 12 | 13 | void init_real_host_page_size(struct uc_struct *uc) 14 | { 15 | uc->qemu_real_host_page_size = getpagesize(); 16 | } 17 | -------------------------------------------------------------------------------- /qemu/util/setjmp-wrapper-win32.asm: -------------------------------------------------------------------------------- 1 | EXTERN _setjmp: proc 2 | PUBLIC _setjmp_wrapper 3 | 4 | _TEXT SEGMENT 5 | 6 | _setjmp_wrapper PROC 7 | 8 | ; Why do we need this wrapper? 9 | ; Short answer: Windows default implementation of setjmp/longjmp is incompatible with generated code. 10 | ; A longer answer: https://blog.lazym.io/2020/09/21/Unicorn-Devblog-setjmp-longjmp-on-Windows/. 11 | 12 | ; From qemu os-win32 comments: 13 | ; > On w64, setjmp is implemented by _setjmp which needs a second parameter. 14 | ; > If this parameter is NULL, longjump does no stack unwinding. 15 | ; > That is what we need for QEMU. Passing the value of register rsp (default) 16 | ; > lets longjmp try a stack unwinding which will crash with generated code. 17 | ; It's true indeed, but MSVC doesn't has a setjmp signature which receives two arguements. 18 | ; Therefore, we add a wrapper to keep the second argument zero. 19 | xor rdx, rdx 20 | jmp _setjmp 21 | 22 | _setjmp_wrapper ENDP 23 | 24 | _TEXT ENDS 25 | 26 | END -------------------------------------------------------------------------------- /qemu/vl.h: -------------------------------------------------------------------------------- 1 | #ifndef VL_H_ 2 | #define VL_H_ 3 | 4 | int machine_initialize(struct uc_struct *uc); 5 | 6 | #endif 7 | 8 | -------------------------------------------------------------------------------- /tests/fuzz/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS += -L ../../ -I ../../include -g 2 | 3 | UNAME_S := $(shell uname -s) 4 | LDFLAGS += -pthread 5 | ifeq ($(UNAME_S), Linux) 6 | LDFLAGS += -lrt 7 | endif 8 | 9 | LDFLAGS += ../../build/libunicorn.a -lm 10 | 11 | 12 | ALL_TESTS_SOURCES = $(wildcard fuzz*.c) 13 | ALL_TESTS = $(ALL_TESTS_SOURCES:%.c=%) 14 | 15 | .PHONY: all 16 | all: ${ALL_TESTS} 17 | 18 | .PHONY: clean 19 | clean: 20 | rm -rf ${ALL_TESTS} 21 | 22 | fuzz%: fuzz%.c 23 | $(CC) $(CFLAGS) $^ onedir.c $(LDFLAGS) -o $@ 24 | -------------------------------------------------------------------------------- /tests/fuzz/dlcorpus.sh: -------------------------------------------------------------------------------- 1 | #/bin/sh 2 | # 3 | # Change to script directory using a subshell (like pushd/popd, 4 | # but for regular sh). 5 | # 6 | ( 7 | cd `dirname $0` 8 | 9 | while test $# -gt 0 10 | do 11 | case "$1" in 12 | --clean) echo "Cleaning any existing corpus data" 13 | rm -rf corpus_* 14 | ;; 15 | esac 16 | shift 17 | done 18 | 19 | ls fuzz_emu*.c | sed 's/\.c//' | while read target 20 | do 21 | if [ ! -d corpus_$target ]; then 22 | # 23 | # Download public corups 24 | # 25 | rm -f public.zip 26 | echo Fetching corpus_$target data... 27 | wget "https://storage.googleapis.com/unicorn-backup.clusterfuzz-external.appspot.com/corpus/libFuzzer/unicorn_$target/public.zip" >/dev/null 2>&1 28 | unzip -q public.zip -d corpus_$target 29 | fi 30 | 31 | ./$target corpus_$target 32 | done 33 | ) 34 | -------------------------------------------------------------------------------- /tests/fuzz/fuzz_emu.options: -------------------------------------------------------------------------------- 1 | [libfuzzer] 2 | max_len = 4096 3 | -------------------------------------------------------------------------------- /tests/fuzz/onefile.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size); 6 | 7 | int main(int argc, char** argv) 8 | { 9 | FILE * fp; 10 | uint8_t *Data; 11 | size_t Size; 12 | 13 | if (argc != 2) { 14 | return 1; 15 | } 16 | //opens the file, get its size, and reads it into a buffer 17 | fp = fopen(argv[1], "rb"); 18 | if (fp == NULL) { 19 | return 2; 20 | } 21 | if (fseek(fp, 0L, SEEK_END) != 0) { 22 | fclose(fp); 23 | return 2; 24 | } 25 | Size = ftell(fp); 26 | if (Size == (size_t) -1) { 27 | fclose(fp); 28 | return 2; 29 | } 30 | if (fseek(fp, 0L, SEEK_SET) != 0) { 31 | fclose(fp); 32 | return 2; 33 | } 34 | Data = malloc(Size); 35 | if (Data == NULL) { 36 | fclose(fp); 37 | return 2; 38 | } 39 | if (fread(Data, Size, 1, fp) != 1) { 40 | fclose(fp); 41 | return 2; 42 | } 43 | 44 | //lauch fuzzer 45 | LLVMFuzzerTestOneInput(Data, Size); 46 | fclose(fp); 47 | return 0; 48 | } 49 | 50 | -------------------------------------------------------------------------------- /tests/regress/.gitignore: -------------------------------------------------------------------------------- 1 | !*.c 2 | 3 | arm_enable_vfp 4 | map_crash 5 | sigill 6 | sigill2 7 | block_test 8 | map_write 9 | ro_mem_test 10 | nr_mem_test 11 | timeout_segfault 12 | rep_movsb 13 | mips_kseg0_1 14 | eflags_nosync 15 | 00opcode_uc_crash 16 | eflags_noset 17 | invalid_read_in_cpu_tb_exec 18 | invalid_write_in_cpu_tb_exec_x86_64 19 | x86_16_segfault 20 | mips_invalid_read_of_size_4_when_tracing 21 | invalid_read_in_tb_flush_x86_64 22 | sparc_jump_to_zero 23 | mips_delay_slot_code_hook 24 | threaded_emu_start 25 | emu_stop_in_hook_overrun 26 | mips_branch_likely_issue 27 | emu_clear_errors 28 | 001-bad_condition_code_0xe 29 | 002-qemu__fatal__unimplemented_control_register_write_0xffb___0x0 30 | 003-qemu__fatal__wdebug_not_implemented 31 | 004-segmentation_fault_1 32 | 005-qemu__fatal__illegal_instruction__0000___00000404 33 | 006-qemu__fatal__illegal_instruction__0421___00040026 34 | 35 | rw_hookstack 36 | hook_extrainvoke 37 | sysenter_hook_x86 38 | 39 | memleak_* 40 | mem_* 41 | -------------------------------------------------------------------------------- /tests/regress/001-bad_condition_code_0xe.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define HARDWARE_ARCHITECTURE UC_ARCH_ARM 4 | #define HARDWARE_MODE 16 5 | #define MEMORY_STARTING_ADDRESS 8192 6 | #define MEMORY_SIZE 4096 7 | #define MEMORY_PERMISSIONS 6 8 | #define BINARY_CODE "\x56\xe8\x46\x46\x80\xf6\x8c\x56\xff\xbf\xcd\x90\xda\xa0\xed\xe8\x46\x43\x45\xe5\x80\x90\x44\x46\x04" 9 | 10 | static void hook_code(uc_engine *uc, uint64_t address, uint32_t size, void *user_data) { 11 | printf("hook_code(…) called\n"); 12 | } 13 | 14 | int main(int argc, char **argv, char **envp) { 15 | uc_engine *uc; 16 | if (uc_open(HARDWARE_ARCHITECTURE, HARDWARE_MODE, &uc)) { 17 | printf("uc_open(…) failed\n"); 18 | return 1; 19 | } 20 | uc_mem_map(uc, MEMORY_STARTING_ADDRESS, MEMORY_SIZE, MEMORY_PERMISSIONS); 21 | if (uc_mem_write(uc, MEMORY_STARTING_ADDRESS, BINARY_CODE, sizeof(BINARY_CODE) - 1)) { 22 | printf("uc_mem_write(…) failed\n"); 23 | return 1; 24 | } 25 | uc_hook trace; 26 | uc_hook_add(uc, &trace, UC_HOOK_CODE, hook_code, NULL, (uint64_t)MEMORY_STARTING_ADDRESS, (uint64_t)(MEMORY_STARTING_ADDRESS + 1)); 27 | printf("uc_emu_start(…)\n"); 28 | uc_emu_start(uc, MEMORY_STARTING_ADDRESS, MEMORY_STARTING_ADDRESS + sizeof(BINARY_CODE) - 1, 0, 0); 29 | printf("done\n"); 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /tests/regress/002-qemu__fatal__unimplemented_control_register_write_0xffb___0x0.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define HARDWARE_ARCHITECTURE UC_ARCH_M68K 4 | #define HARDWARE_MODE 1073741824 5 | #define MEMORY_STARTING_ADDRESS 8388608 6 | #define MEMORY_SIZE 2097152 7 | #define MEMORY_PERMISSIONS 7 8 | #define BINARY_CODE "\xaf\x80\x4e\x7b\xff\xfb\x80\x4e\x3e\x80" 9 | 10 | static void hook_code(uc_engine *uc, uint64_t address, uint32_t size, void *user_data) { 11 | printf("hook_code(…) called\n"); 12 | } 13 | 14 | int main(int argc, char **argv, char **envp) { 15 | uc_engine *uc; 16 | if (uc_open(HARDWARE_ARCHITECTURE, HARDWARE_MODE, &uc)) { 17 | printf("uc_open(…) failed\n"); 18 | return 1; 19 | } 20 | uc_mem_map(uc, MEMORY_STARTING_ADDRESS, MEMORY_SIZE, MEMORY_PERMISSIONS); 21 | if (uc_mem_write(uc, MEMORY_STARTING_ADDRESS, BINARY_CODE, sizeof(BINARY_CODE) - 1)) { 22 | printf("uc_mem_write(…) failed\n"); 23 | return 1; 24 | } 25 | uc_hook trace; 26 | uc_hook_add(uc, &trace, UC_HOOK_CODE, hook_code, NULL, (uint64_t)MEMORY_STARTING_ADDRESS, (uint64_t)(MEMORY_STARTING_ADDRESS + 1)); 27 | printf("uc_emu_start(…)\n"); 28 | uc_emu_start(uc, MEMORY_STARTING_ADDRESS, MEMORY_STARTING_ADDRESS + sizeof(BINARY_CODE) - 1, 0, 0); 29 | printf("done\n"); 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /tests/regress/003-qemu__fatal__wdebug_not_implemented.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define HARDWARE_ARCHITECTURE UC_ARCH_M68K 4 | #define HARDWARE_MODE 1073741824 5 | #define MEMORY_STARTING_ADDRESS 1048576 6 | #define MEMORY_SIZE 403456 7 | #define MEMORY_PERMISSIONS 7 8 | #define BINARY_CODE "\x42\xc7\xfb\xfb\x54\x36" 9 | 10 | static void hook_code(uc_engine *uc, uint64_t address, uint32_t size, void *user_data) { 11 | printf("hook_code(…) called\n"); 12 | } 13 | 14 | int main(int argc, char **argv, char **envp) { 15 | uc_engine *uc; 16 | if (uc_open(HARDWARE_ARCHITECTURE, HARDWARE_MODE, &uc)) { 17 | printf("uc_open(…) failed\n"); 18 | return 1; 19 | } 20 | uc_mem_map(uc, MEMORY_STARTING_ADDRESS, MEMORY_SIZE, MEMORY_PERMISSIONS); 21 | if (uc_mem_write(uc, MEMORY_STARTING_ADDRESS, BINARY_CODE, sizeof(BINARY_CODE) - 1)) { 22 | printf("uc_mem_write(…) failed\n"); 23 | return 1; 24 | } 25 | uc_hook trace; 26 | uc_hook_add(uc, &trace, UC_HOOK_CODE, hook_code, NULL, (uint64_t)MEMORY_STARTING_ADDRESS, (uint64_t)(MEMORY_STARTING_ADDRESS + 1)); 27 | printf("uc_emu_start(…)\n"); 28 | uc_emu_start(uc, MEMORY_STARTING_ADDRESS, MEMORY_STARTING_ADDRESS + sizeof(BINARY_CODE) - 1, 0, 0); 29 | printf("done\n"); 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /tests/regress/004-segmentation_fault_1.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define HARDWARE_ARCHITECTURE UC_ARCH_ARM 4 | #define HARDWARE_MODE 16 5 | #define MEMORY_STARTING_ADDRESS 1024 6 | #define MEMORY_SIZE 1796096 7 | #define MEMORY_PERMISSIONS 7 8 | #define BINARY_CODE "\x20\xbf\xbf\xbf\xbf\xdd\x5d\x74\x5e\x66\x72\x10" 9 | 10 | static void hook_code(uc_engine *uc, uint64_t address, uint32_t size, void *user_data) { 11 | printf("hook_code(…) called\n"); 12 | } 13 | 14 | int main(int argc, char **argv, char **envp) { 15 | uc_engine *uc; 16 | if (uc_open(HARDWARE_ARCHITECTURE, HARDWARE_MODE, &uc)) { 17 | printf("uc_open(…) failed\n"); 18 | return 1; 19 | } 20 | uc_mem_map(uc, MEMORY_STARTING_ADDRESS, MEMORY_SIZE, MEMORY_PERMISSIONS); 21 | if (uc_mem_write(uc, MEMORY_STARTING_ADDRESS, BINARY_CODE, sizeof(BINARY_CODE) - 1)) { 22 | printf("uc_mem_write(…) failed\n"); 23 | return 1; 24 | } 25 | uc_hook trace; 26 | uc_hook_add(uc, &trace, UC_HOOK_CODE, hook_code, NULL, (uint64_t)MEMORY_STARTING_ADDRESS, (uint64_t)(MEMORY_STARTING_ADDRESS + 1)); 27 | printf("uc_emu_start(…)\n"); 28 | uc_emu_start(uc, MEMORY_STARTING_ADDRESS, MEMORY_STARTING_ADDRESS + sizeof(BINARY_CODE) - 1, 0, 0); 29 | printf("done\n"); 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /tests/regress/005-qemu__fatal__illegal_instruction__0000___00000404.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define HARDWARE_ARCHITECTURE UC_ARCH_M68K 4 | #define HARDWARE_MODE 1073741824 5 | #define MEMORY_STARTING_ADDRESS 1024 6 | #define MEMORY_SIZE 1044480 7 | #define MEMORY_PERMISSIONS 5 8 | #define BINARY_CODE "\x4c\x4c" 9 | 10 | static void hook_code(uc_engine *uc, uint64_t address, uint32_t size, void *user_data) { 11 | printf("hook_code(…) called\n"); 12 | } 13 | 14 | int main(int argc, char **argv, char **envp) { 15 | uc_engine *uc; 16 | if (uc_open(HARDWARE_ARCHITECTURE, HARDWARE_MODE, &uc)) { 17 | printf("uc_open(…) failed\n"); 18 | return 1; 19 | } 20 | uc_mem_map(uc, MEMORY_STARTING_ADDRESS, MEMORY_SIZE, MEMORY_PERMISSIONS); 21 | if (uc_mem_write(uc, MEMORY_STARTING_ADDRESS, BINARY_CODE, sizeof(BINARY_CODE) - 1)) { 22 | printf("uc_mem_write(…) failed\n"); 23 | return 1; 24 | } 25 | uc_hook trace; 26 | uc_hook_add(uc, &trace, UC_HOOK_CODE, hook_code, NULL, (uint64_t)MEMORY_STARTING_ADDRESS, (uint64_t)(MEMORY_STARTING_ADDRESS + 1)); 27 | printf("uc_emu_start(…)\n"); 28 | uc_emu_start(uc, MEMORY_STARTING_ADDRESS, MEMORY_STARTING_ADDRESS + sizeof(BINARY_CODE) - 1, 0, 0); 29 | printf("done\n"); 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /tests/regress/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS += -Wall -Werror -I../../include 2 | CFLAGS += -D__USE_MINGW_ANSI_STDIO=1 3 | LDLIBS += -L../../ -lm -lunicorn 4 | 5 | UNAME_S := $(shell uname -s) 6 | LDLIBS += -pthread 7 | ifeq ($(UNAME_S), Linux) 8 | LDLIBS += -lrt 9 | endif 10 | 11 | EXECUTE_VARS = LD_LIBRARY_PATH=../../cmocka/src:../../ DYLD_LIBRARY_PATH=../../ 12 | 13 | TESTS_SOURCE = $(wildcard *.c) 14 | TESTS = $(TESTS_SOURCE:%.c=%) 15 | 16 | .PHONY: all clean test 17 | 18 | test: $(TESTS) 19 | 20 | all: $(TESTS) 21 | 22 | clean: 23 | rm -f $(TESTS) 24 | -------------------------------------------------------------------------------- /tests/regress/arm64_reg_rw_w0_w30.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | from unicorn import * 4 | from unicorn.arm64_const import * 5 | from unicorn.x86_const import * 6 | 7 | import regress 8 | 9 | class Arm64RegReadWriteW0ThroughW30(regress.RegressTest): 10 | """ 11 | Testing the functionality to read/write 32-bit registers in AArch64 12 | See issue #716 13 | """ 14 | 15 | def runTest(self): 16 | uc = Uc(UC_ARCH_ARM64, UC_MODE_ARM) 17 | 18 | uc.reg_write(UC_ARM64_REG_X0, 0x1234567890abcdef) 19 | self.assertEquals(uc.reg_read(UC_ARM64_REG_X0), 0x1234567890abcdef) 20 | self.assertEquals(uc.reg_read(UC_ARM64_REG_W0), 0x90abcdef) 21 | 22 | uc.reg_write(UC_ARM64_REG_X30, 0xa1b2c3d4e5f6a7b8) 23 | self.assertEquals(uc.reg_read(UC_ARM64_REG_W30), 0xe5f6a7b8) 24 | 25 | uc.reg_write(UC_ARM64_REG_W30, 0xaabbccdd) 26 | self.assertEquals(uc.reg_read(UC_ARM64_REG_X30), 0xa1b2c3d4aabbccdd) 27 | self.assertEquals(uc.reg_read(UC_ARM64_REG_W30), 0xaabbccdd) 28 | 29 | if __name__ == '__main__': 30 | regress.main() 31 | -------------------------------------------------------------------------------- /tests/regress/arm_bxeq_hang.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | from unicorn import * 4 | from unicorn.arm_const import * 5 | 6 | import regress 7 | 8 | class BxHang(regress.RegressTest): 9 | 10 | def runTest(self): 11 | uc = Uc(UC_ARCH_ARM, UC_MODE_ARM) 12 | uc.mem_map(0x1000, 0x1000) 13 | uc.mem_write(0x1000, '1eff2f010000a0e1'.decode('hex')) # bxeq lr; mov r0, r0 14 | uc.count = 0 15 | 16 | def hook_block(uc, addr, *args): 17 | print 'enter block 0x%04x' % addr 18 | uc.count += 1 19 | 20 | uc.reg_write(UC_ARM_REG_LR, 0x1004) 21 | uc.hook_add(UC_HOOK_BLOCK, hook_block) 22 | print 'block should only run once' 23 | uc.emu_start(0x1000, 0x1004) 24 | 25 | self.assertEqual(uc.count, 1) 26 | 27 | if __name__ == '__main__': 28 | regress.main() 29 | -------------------------------------------------------------------------------- /tests/regress/arm_fp_vfp_disabled.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # coding=utf8 3 | 4 | # Added by Peter Mackay, relating to issue 571 5 | # "ARM NEON/VFP support seems to exist but is disabled by default" 6 | # https://github.com/unicorn-engine/unicorn/issues/571 7 | 8 | from unicorn import * 9 | from unicorn.arm_const import * 10 | 11 | import regress 12 | 13 | class FpVfpDisabled(regress.RegressTest): 14 | 15 | def runTest(self): 16 | # MRC p15, #0, r1, c1, c0, #2 17 | # ORR r1, r1, #(0xf << 20) 18 | # MCR p15, #0, r1, c1, c0, #2 19 | # MOV r1, #0 20 | # MCR p15, #0, r1, c7, c5, #4 21 | # MOV r0,#0x40000000 22 | # FMXR FPEXC, r0 23 | code = '11EE501F' 24 | code += '41F47001' 25 | code += '01EE501F' 26 | code += '4FF00001' 27 | code += '07EE951F' 28 | code += '4FF08040' 29 | code += 'E8EE100A' 30 | # vpush {d8} 31 | code += '2ded028b' 32 | 33 | address = 0x1000 34 | mem_size = 0x1000 35 | code_bytes = code.decode('hex') 36 | 37 | uc = Uc(UC_ARCH_ARM, UC_MODE_THUMB) 38 | uc.mem_map(address, mem_size) 39 | uc.mem_write(address, code_bytes) 40 | uc.reg_write(UC_ARM_REG_SP, address + mem_size) 41 | uc.emu_start(address + 1, address + len(code_bytes)) 42 | 43 | if __name__ == '__main__': 44 | regress.main() 45 | -------------------------------------------------------------------------------- /tests/regress/arm_movr12_hang.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | from unicorn import * 4 | from unicorn.arm_const import * 5 | 6 | import regress 7 | 8 | class MovHang(regress.RegressTest): 9 | 10 | def runTest(self): 11 | uc = Uc(UC_ARCH_ARM, UC_MODE_ARM) 12 | uc.mem_map(0x1000, 0x1000) 13 | uc.mem_write(0x1000, '00c000e3'.decode('hex')) # movw r12, #0 14 | 15 | def hook_block(uc, addr, *args): 16 | print 'enter block 0x%04x' % addr 17 | uc.count += 1 18 | 19 | uc.reg_write(UC_ARM_REG_R12, 0x123) 20 | self.assertEquals(uc.reg_read(UC_ARM_REG_R12), 0x123) 21 | 22 | uc.hook_add(UC_HOOK_BLOCK, hook_block) 23 | uc.count = 0 24 | 25 | #print 'block should only run once' 26 | uc.emu_start(0x1000, 0x1004, timeout=500) 27 | 28 | self.assertEquals(uc.reg_read(UC_ARM_REG_R12), 0x0) 29 | self.assertEquals(uc.count, 1) 30 | 31 | if __name__ == '__main__': 32 | regress.main() 33 | -------------------------------------------------------------------------------- /tests/regress/arm_vldr_invalid.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | from unicorn import * 4 | from unicorn.arm_const import * 5 | 6 | import regress 7 | 8 | class VldrPcInsn(regress.RegressTest): 9 | 10 | def runTest(self): 11 | uc = Uc(UC_ARCH_ARM, UC_MODE_ARM) 12 | uc.mem_map(0x1000, 0x1000) 13 | uc.mem_write(0x1000, 'ed9f8a3d'.decode('hex')) # vldr s16, [pc, #244] 14 | # this will raise invalid insn 15 | uc.emu_start(0x1000, 0x1004) 16 | 17 | if __name__ == '__main__': 18 | regress.main() 19 | -------------------------------------------------------------------------------- /tests/regress/arm_wfi_first_insn_of_tb.py: -------------------------------------------------------------------------------- 1 | from unicorn import * 2 | from unicorn.arm_const import * 3 | 4 | # ADD R0, R10, R0; 5 | # B L0; 6 | # L0: 7 | # ADD R0, R10, R0; <--- we stop at here, the first instruction of the next TB. 8 | 9 | code = b'\x00\x00\x8a\xe0\xff\xff\xff\xea\x00\x00\x8a\xe0' 10 | address = 0x1000 11 | 12 | mu = Uc(UC_ARCH_ARM, UC_MODE_ARM) 13 | mu.mem_map(address, 0x1000) 14 | mu.mem_write(address, code) 15 | mu.emu_start(address, address + len(code) - 4) -------------------------------------------------------------------------------- /tests/regress/bad_ram.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | from unicorn import * 4 | from unicorn.x86_const import * 5 | 6 | import regress 7 | 8 | 9 | class Hang(regress.RegressTest): 10 | 11 | def runTest(self): 12 | PAGE_SIZE = 0x5000 13 | CODE_ADDR = 0x400000 14 | RSP_ADDR = 0x200000 15 | binary1 = "\xCA\x24\x5D" # retf 0x5d24 16 | mu = Uc(UC_ARCH_X86, UC_MODE_64) 17 | 18 | mu.mem_map(CODE_ADDR, PAGE_SIZE) 19 | mu.mem_map(RSP_ADDR, PAGE_SIZE) 20 | 21 | mu.mem_write(CODE_ADDR, binary1) 22 | mu.reg_write(UC_X86_REG_RSP, RSP_ADDR) 23 | try: 24 | self.assertEqual(mu.emu_start(CODE_ADDR, CODE_ADDR + PAGE_SIZE, 0), UC_ERR_FETCH_INVALID) 25 | except UcError as e: 26 | print("ERROR: %s" % e) 27 | 28 | 29 | if __name__ == '__main__': 30 | regress.main() 31 | -------------------------------------------------------------------------------- /tests/regress/crash_tb.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | from unicorn import * 4 | from unicorn.x86_const import * 5 | 6 | import regress 7 | 8 | CODE_ADDR = 0x0 9 | binary1 = b'\xb8\x02\x00\x00\x00' 10 | binary2 = b'\xb8\x01\x00\x00\x00' 11 | 12 | class CrashTB(regress.RegressTest): 13 | 14 | def runTest(self): 15 | mu = Uc(UC_ARCH_X86, UC_MODE_64) 16 | 17 | mu.mem_map(CODE_ADDR, 2 * 1024 * 1024) 18 | 19 | # write machine code to be emulated to memory 20 | mu.mem_write(CODE_ADDR, binary1) 21 | 22 | # emu for maximum 1 sec. 23 | mu.emu_start(CODE_ADDR, len(binary1), UC_SECOND_SCALE) 24 | 25 | self.assertEqual(0x2, mu.reg_read(UC_X86_REG_RAX)) 26 | 27 | # write machine code to be emulated to memory 28 | mu.mem_write(CODE_ADDR, binary2) 29 | 30 | # emu for maximum 1 sec. 31 | mu.emu_start(CODE_ADDR, len(binary2), UC_SECOND_SCALE) 32 | 33 | self.assertEqual(0x1, mu.reg_read(UC_X86_REG_RAX)) 34 | 35 | if __name__ == '__main__': 36 | regress.main() 37 | 38 | -------------------------------------------------------------------------------- /tests/regress/deadlock_1.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # From issue #1 of Ryan Hileman 3 | 4 | from unicorn import * 5 | import regress 6 | 7 | CODE = b"\x90\x91\x92" 8 | 9 | class DeadLock(regress.RegressTest): 10 | 11 | def runTest(self): 12 | mu = Uc(UC_ARCH_X86, UC_MODE_64) 13 | mu.mem_map(0x100000, 4 * 1024) 14 | mu.mem_write(0x100000, CODE) 15 | 16 | with self.assertRaises(UcError): 17 | mu.emu_start(0x100000, 0x1000 + len(CODE)) 18 | 19 | if __name__ == '__main__': 20 | regress.main() 21 | -------------------------------------------------------------------------------- /tests/regress/emu_stop_segfault.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """See https://github.com/unicorn-engine/unicorn/issues/65""" 4 | 5 | import unicorn 6 | import regress 7 | 8 | class EmuStopSegFault(regress.RegressTest): 9 | 10 | def runTest(self): 11 | ADDR = 0x10101000 12 | mu = unicorn.Uc(unicorn.UC_ARCH_X86, unicorn.UC_MODE_32) 13 | mu.mem_map(ADDR, 1024 * 4) 14 | mu.mem_write(ADDR, b'\x41') 15 | mu.emu_start(ADDR, ADDR + 1, count=1) 16 | # The following should not trigger a null pointer dereference 17 | self.assertEqual(None, mu.emu_stop()) 18 | 19 | if __name__ == '__main__': 20 | regress.main() 21 | -------------------------------------------------------------------------------- /tests/regress/ensure_typedef_consts_generated.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """See https://github.com/unicorn-engine/unicorn/issues/161 4 | 5 | Ensure that constants which are specified via a typedef, rather than an enum, 6 | are included in the bindings by the script for autogenerating mappings for 7 | constants. 8 | """ 9 | 10 | import unicorn 11 | 12 | try: 13 | unicorn.UC_HOOK_MEM_UNMAPPED 14 | except AttributeError: 15 | assert(False and "Definition for UC_HOOK_MEM_UNMAPPED not generated") 16 | -------------------------------------------------------------------------------- /tests/regress/fpu_mem_write.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | from unicorn import * 3 | from unicorn.x86_const import * 4 | 5 | import regress 6 | 7 | ESP = 0x2000 8 | PAGE_SIZE = 1 * 1024 * 1024 9 | 10 | # wait 11 | # fnstcw word ptr [esp] 12 | # pop ecx 13 | CODE = b'\x9B\xD9\x3C\x24\x59' 14 | 15 | def hook_mem_write(uc, access, address, size, value, user_data): 16 | print("mem WRITE: 0x%x, data size = %u, data value = 0x%x" % (address, size, value)) 17 | return True 18 | 19 | class FpuWrite(regress.RegressTest): 20 | 21 | def mem_reader(self, mu, addr, size, expected): 22 | tmp = mu.mem_read(addr, size) 23 | for i, e in zip(tmp, expected): 24 | self.assertEquals(e, i) 25 | 26 | def runTest(self): 27 | mu = Uc(UC_ARCH_X86, UC_MODE_32) 28 | mu.mem_map(0, PAGE_SIZE) 29 | mu.mem_write(0, CODE) 30 | mu.reg_write(UC_X86_REG_ESP, ESP) 31 | 32 | mu.hook_add(UC_HOOK_MEM_WRITE, hook_mem_write) 33 | mu.emu_start(0x0, 5, 0, 2) 34 | esp = mu.reg_read(UC_X86_REG_ESP) 35 | self.mem_reader(mu, esp, 10, [0] * 10) 36 | 37 | if __name__ == '__main__': 38 | regress.main() 39 | -------------------------------------------------------------------------------- /tests/regress/hook_add_crash.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """https://github.com/unicorn-engine/unicorn/issues/165""" 4 | 5 | import unicorn 6 | 7 | def hook_mem_read_unmapped(mu, access, address, size, value, user_data): 8 | pass 9 | 10 | mu = unicorn.Uc(unicorn.UC_ARCH_X86, unicorn.UC_MODE_32) 11 | 12 | try: 13 | for x in range(0, 1000): 14 | mu.hook_add(unicorn.UC_HOOK_MEM_READ_UNMAPPED, hook_mem_read_unmapped, None) 15 | except unicorn.UcError as e: 16 | print("ERROR: %s" % e) 17 | -------------------------------------------------------------------------------- /tests/regress/hook_raises_exception.py: -------------------------------------------------------------------------------- 1 | import regress 2 | from unicorn import Uc, UC_ARCH_X86, UC_MODE_64, UC_HOOK_CODE 3 | 4 | CODE = b"\x90" * 3 5 | CODE_ADDR = 0x1000 6 | 7 | 8 | class HookCounter(object): 9 | """Counts number of hook calls.""" 10 | 11 | def __init__(self): 12 | self.hook_calls = 0 13 | 14 | def bad_code_hook(self, uc, address, size, data): 15 | self.hook_calls += 1 16 | raise ValueError("Something went wrong") 17 | 18 | def good_code_hook(self, uc, address, size, data): 19 | self.hook_calls += 1 20 | 21 | 22 | class TestExceptionInHook(regress.RegressTest): 23 | 24 | def test_exception_in_hook(self): 25 | uc = Uc(UC_ARCH_X86, UC_MODE_64) 26 | uc.mem_map(CODE_ADDR, 0x1000) 27 | uc.mem_write(CODE_ADDR, CODE) 28 | 29 | counter = HookCounter() 30 | uc.hook_add(UC_HOOK_CODE, counter.good_code_hook, begin=CODE_ADDR, end=CODE_ADDR + len(CODE)) 31 | uc.hook_add(UC_HOOK_CODE, counter.bad_code_hook, begin=CODE_ADDR, end=CODE_ADDR + len(CODE)) 32 | 33 | self.assertRaises(ValueError, uc.emu_start, CODE_ADDR, CODE_ADDR + len(CODE)) 34 | # Make sure hooks calls finish before raising (hook_calls == 2) 35 | self.assertEqual(counter.hook_calls, 2) 36 | 37 | 38 | if __name__ == "__main__": 39 | regress.main() 40 | -------------------------------------------------------------------------------- /tests/regress/hook_readonly_write_local.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | from unicorn import * 3 | from unicorn.x86_const import * 4 | import regress 5 | 6 | PAGE_SIZE = 4 * 1024 7 | ACCESS_ADDR = 0x1000 8 | 9 | # mov eax, [0x1000] 10 | # mov eax, [0x1000] 11 | CODE = b'\xA1\x00\x10\x00\x00\xA1\x00\x10\x00\x00' 12 | 13 | def hook_mem_read(uc, access, address, size, value, data): 14 | print("Reading at " + str(address)) 15 | uc.mem_write(address, CODE); 16 | 17 | class REP(regress.RegressTest): 18 | 19 | def test_rep(self): 20 | mu = Uc(UC_ARCH_X86, UC_MODE_32) 21 | 22 | mu.mem_map(0, PAGE_SIZE) 23 | mu.mem_write(0, CODE) 24 | mu.mem_map(ACCESS_ADDR, PAGE_SIZE, UC_PROT_READ); 25 | mu.hook_add(UC_HOOK_MEM_READ, hook_mem_read, begin = ACCESS_ADDR, end = ACCESS_ADDR + PAGE_SIZE) 26 | 27 | mu.emu_start(0, len(CODE)) 28 | 29 | if __name__ == '__main__': 30 | regress.main() 31 | -------------------------------------------------------------------------------- /tests/regress/invalid_read_in_cpu_tb_exec.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | static void hook_block(uc_engine *uc, uint64_t address, uint32_t size, void *user_data) { 4 | printf("hook_block(%p, %"PRIx64", %d, %p)\n", uc, address, size, user_data); 5 | } 6 | 7 | /* 8 | * Disassembly according to capstone: 9 | * add byte ptr [rip - 1], 0x30 10 | * jmp 0x1000000 11 | */ 12 | #define BINARY "\x80\x05\xff\xff\xff\xff\x30\xeb\xf7\x30" 13 | #define MEMORY_SIZE 2 * 1024 * 1024 14 | #define STARTING_ADDRESS 0x1000000 15 | 16 | int main(int argc, char **argv, char **envp) { 17 | uc_engine *uc; 18 | if (uc_open(UC_ARCH_X86, UC_MODE_64, &uc)) { 19 | printf("uc_open(…) failed\n"); 20 | return 1; 21 | } 22 | uc_mem_map(uc, STARTING_ADDRESS, MEMORY_SIZE, UC_PROT_ALL); 23 | if (uc_mem_write(uc, STARTING_ADDRESS, BINARY, sizeof(BINARY) - 1)) { 24 | printf("uc_mem_write(…) failed\n"); 25 | return 1; 26 | } 27 | uc_hook hook; 28 | uc_hook_add(uc, &hook, UC_HOOK_BLOCK, hook_block, NULL, 1, 0); 29 | printf("uc_emu_start(…)\n"); 30 | uc_emu_start(uc, STARTING_ADDRESS, STARTING_ADDRESS + sizeof(BINARY) - 1, 0, 20); 31 | printf("done\n"); 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /tests/regress/invalid_read_in_tb_flush_x86_64.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define HARDWARE_ARCHITECTURE UC_ARCH_X86 4 | #define HARDWARE_MODE UC_MODE_64 5 | 6 | #define MEMORY_STARTING_ADDRESS 0x1000000 7 | #define MEMORY_SIZE 2 * 1024 * 1024 8 | #define MEMORY_PERMISSIONS UC_PROT_READ 9 | 10 | #define BINARY_CODE "\x90" 11 | 12 | int main(int argc, char **argv, char **envp) { 13 | uc_engine *uc; 14 | if (uc_open(HARDWARE_ARCHITECTURE, HARDWARE_MODE, &uc)) { 15 | printf("uc_open(…) failed\n"); 16 | return 1; 17 | } 18 | uc_mem_map(uc, MEMORY_STARTING_ADDRESS, MEMORY_SIZE, MEMORY_PERMISSIONS); 19 | if (uc_mem_write(uc, MEMORY_STARTING_ADDRESS, BINARY_CODE, sizeof(BINARY_CODE) - 1)) { 20 | printf("uc_mem_write(…) failed\n"); 21 | return 1; 22 | } 23 | printf("uc_emu_start(…)\n"); 24 | uc_emu_start(uc, MEMORY_STARTING_ADDRESS, MEMORY_STARTING_ADDRESS + sizeof(BINARY_CODE) - 1, 0, 20); 25 | printf("done\n"); 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /tests/regress/invalid_write_in_cpu_tb_exec_x86_64.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /* 4 | * Disassembly according to capstone: 5 | * mulx rsp, rsp, rdx 6 | */ 7 | #define BINARY "\xc4\xe2\xdb\xf6\xe2" 8 | #define MEMORY_SIZE 2 * 1024 * 1024 9 | #define STARTING_ADDRESS 0x1000000 10 | 11 | int main(int argc, char **argv, char **envp) { 12 | uc_engine *uc; 13 | if (uc_open(UC_ARCH_X86, UC_MODE_64, &uc)) { 14 | printf("uc_open(…) failed\n"); 15 | return 1; 16 | } 17 | uc_mem_map(uc, STARTING_ADDRESS, MEMORY_SIZE, UC_PROT_ALL); 18 | if (uc_mem_write(uc, STARTING_ADDRESS, BINARY, sizeof(BINARY) - 1)) { 19 | printf("uc_mem_write(…) failed\n"); 20 | return 1; 21 | } 22 | printf("uc_emu_start(…)\n"); 23 | uc_emu_start(uc, STARTING_ADDRESS, STARTING_ADDRESS + sizeof(BINARY) - 1, 0, 20); 24 | printf("done\n"); 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /tests/regress/map_crash.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #define UC_BUG_WRITE_SIZE 13000 7 | #define UC_BUG_WRITE_ADDR 0x1000 8 | 9 | int main() 10 | { 11 | int size; 12 | uint8_t *buf; 13 | uc_engine *uc; 14 | uc_err err = uc_open (UC_ARCH_X86, UC_MODE_64, &uc); 15 | if (err) { 16 | fprintf (stderr, "Cannot initialize unicorn\n"); 17 | return 1; 18 | } 19 | size = UC_BUG_WRITE_SIZE; 20 | buf = malloc (size); 21 | if (!buf) { 22 | fprintf (stderr, "Cannot allocate\n"); 23 | return 1; 24 | } 25 | memset (buf, 0, size); 26 | if (!uc_mem_map (uc, UC_BUG_WRITE_ADDR, size, UC_PROT_ALL)) { 27 | uc_mem_write (uc, UC_BUG_WRITE_ADDR, buf, size); 28 | } 29 | uc_close(uc); 30 | free(buf); 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /tests/regress/map_write.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define ADDR 0x00400000 6 | #define SIZE 1024*64 7 | #define OVERFLOW 1 8 | 9 | int main() 10 | { 11 | uc_engine *uc = NULL; 12 | uint8_t *buf = NULL, *buf2 = NULL; 13 | int i; 14 | uc_err err; 15 | 16 | err = uc_open (UC_ARCH_X86, UC_MODE_64, &uc); 17 | if (err) { 18 | printf ("uc_open %d\n", err); 19 | goto exit; 20 | } 21 | err = uc_mem_map (uc, ADDR, SIZE, UC_PROT_ALL); 22 | if (err) { 23 | printf ("uc_mem_map %d\n", err); 24 | goto exit; 25 | } 26 | buf = calloc (SIZE*2, 1); 27 | buf2 = calloc (SIZE, 1); 28 | for (i=0;i 2 | 3 | static void hook_code(uc_engine *uc, uint64_t address, uint32_t size, void *user_data) { 4 | printf("tracing\n"); 5 | } 6 | 7 | #define HARDWARE_ARCHITECTURE UC_ARCH_MIPS 8 | #define HARDWARE_MODE UC_MODE_MIPS32 9 | 10 | #define MEMORY_STARTING_ADDRESS 0x1000000 11 | #define MEMORY_SIZE 2 * 1024 * 1024 12 | #define MEMORY_PERMISSIONS UC_PROT_ALL 13 | 14 | #define BINARY_CODE "00000000000000000000000000AA" 15 | 16 | int main(int argc, char **argv, char **envp) { 17 | uc_engine *uc; 18 | if (uc_open(HARDWARE_ARCHITECTURE, HARDWARE_MODE, &uc)) { 19 | printf("uc_open(…) failed\n"); 20 | return 1; 21 | } 22 | uc_mem_map(uc, MEMORY_STARTING_ADDRESS, MEMORY_SIZE, MEMORY_PERMISSIONS); 23 | if (uc_mem_write(uc, MEMORY_STARTING_ADDRESS, BINARY_CODE, sizeof(BINARY_CODE) - 1)) { 24 | printf("uc_mem_write(…) failed\n"); 25 | return 1; 26 | } 27 | uc_hook trace; 28 | uc_hook_add(uc, &trace, UC_HOOK_CODE, hook_code, NULL, MEMORY_STARTING_ADDRESS, MEMORY_STARTING_ADDRESS + 1); 29 | printf("uc_emu_start(…)\n"); 30 | uc_emu_start(uc, MEMORY_STARTING_ADDRESS, MEMORY_STARTING_ADDRESS + sizeof(BINARY_CODE) - 1, 0, 0); 31 | printf("done\n"); 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /tests/regress/mips_kernel_mmu.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | from unicorn import * 4 | from unicorn.mips_const import * 5 | 6 | import regress 7 | 8 | class MipsSyscall(regress.RegressTest): 9 | def test(self): 10 | addr = 0x80000000 11 | code = '34213456'.decode('hex') # ori $at, $at, 0x3456 12 | 13 | uc = Uc(UC_ARCH_MIPS, UC_MODE_MIPS32 + UC_MODE_BIG_ENDIAN) 14 | uc.mem_map(addr, 0x1000) 15 | uc.mem_write(addr, code) 16 | uc.reg_write(UC_MIPS_REG_AT, 0) 17 | 18 | uc.emu_start(addr, addr + len(code)) 19 | 20 | self.assertEqual(uc.reg_read(UC_MIPS_REG_AT), 0x3456) 21 | 22 | 23 | if __name__ == '__main__': 24 | regress.main() 25 | -------------------------------------------------------------------------------- /tests/regress/mips_syscall_pc.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | from unicorn import * 4 | from unicorn.mips_const import * 5 | 6 | import regress 7 | 8 | def intr_hook(uc, intno, data): 9 | print 'interrupt=%d, v0=%d, pc=0x%08x' % (intno, uc.reg_read(UC_MIPS_REG_V0), uc.reg_read(UC_MIPS_REG_PC)) 10 | 11 | class MipsSyscall(regress.RegressTest): 12 | def test(self): 13 | addr = 0x40000 14 | code = '0c000000'.decode('hex') # syscall 15 | 16 | uc = Uc(UC_ARCH_MIPS, UC_MODE_MIPS32 + UC_MODE_LITTLE_ENDIAN) 17 | uc.mem_map(addr, 0x1000) 18 | uc.mem_write(addr, code) 19 | uc.reg_write(UC_MIPS_REG_V0, 100) 20 | uc.hook_add(UC_HOOK_INTR, intr_hook) 21 | 22 | uc.emu_start(addr, addr+len(code)) 23 | self.assertEqual(0x40004, uc.reg_read(UC_MIPS_REG_PC)) 24 | 25 | 26 | if __name__ == '__main__': 27 | regress.main() 28 | -------------------------------------------------------------------------------- /tests/regress/mov_gs_eax.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | from unicorn import * 4 | from unicorn.x86_const import * 5 | 6 | import regress 7 | 8 | class VldrPcInsn(regress.RegressTest): 9 | 10 | def runTest(self): 11 | uc = Uc(UC_ARCH_X86, UC_MODE_32) 12 | uc.mem_map(0x1000, 0x1000) 13 | # mov gs, eax; mov eax, 1 14 | code = '8ee8b801000000'.decode('hex') 15 | uc.mem_write(0x1000, code) 16 | uc.reg_write(UC_X86_REG_EAX, 0xFFFFFFFF) 17 | 18 | with self.assertRaises(UcError) as ex_ctx: 19 | uc.emu_start(0x1000, 0x1000 + len(code)) 20 | 21 | self.assertEquals(ex_ctx.exception.errno, UC_ERR_EXCEPTION) 22 | 23 | if __name__ == '__main__': 24 | regress.main() 25 | -------------------------------------------------------------------------------- /tests/regress/movsd.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # By Ryan Hileman, issue #3 3 | 4 | from capstone import * 5 | from unicorn import * 6 | from unicorn.x86_const import * 7 | 8 | import regress 9 | code = 'f20f1005aa120000'.decode('hex') 10 | 11 | def dis(mem, addr): 12 | md = Cs(CS_ARCH_X86, CS_MODE_64) 13 | return '\n'.join([ 14 | '%s %s' % (i.mnemonic, i.op_str) 15 | for i in md.disasm(str(mem), addr) 16 | ]) 17 | 18 | def hook_code(uc, addr, size, user_data): 19 | mem = uc.mem_read(addr, size) 20 | print 'instruction size:', size 21 | print 'instruction:', str(mem).encode('hex'), dis(mem, addr) 22 | print 'reference: ', code.encode('hex'), dis(code, addr) 23 | 24 | class Movsd(regress.RegressTest): 25 | 26 | def runTest(self): 27 | addr = 0x400000 28 | mu = Uc(UC_ARCH_X86, UC_MODE_64) 29 | mu.hook_add(UC_HOOK_CODE, hook_code) 30 | mu.mem_map(addr, 8 * 1024 * 1024) 31 | mu.mem_write(addr, code) 32 | mu.emu_start(addr, addr + len(code)) 33 | 34 | if __name__ == '__main__': 35 | regress.main() 36 | -------------------------------------------------------------------------------- /tests/regress/osx_qemu_thread_create_crash.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import platform 4 | import resource 5 | 6 | from unicorn import * 7 | 8 | import regress 9 | 10 | # OS X: OK with 2047 iterations. 11 | # OS X: Crashes at 2048:th iteration ("qemu: qemu_thread_create: Resource temporarily unavailable"). 12 | # Linux: No crashes observed. 13 | class ThreadCreateCrash(regress.RegressTest): 14 | def test(self): 15 | for i in xrange(2048): 16 | Uc(UC_ARCH_X86, UC_MODE_64) 17 | self.assertTrue(True, "If not reached, then we have a crashing bug.") 18 | 19 | if __name__ == '__main__': 20 | regress.main() 21 | -------------------------------------------------------------------------------- /tests/regress/potential_memory_leak.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import platform 4 | import resource 5 | 6 | from unicorn import * 7 | 8 | import regress 9 | 10 | class MemoryLeak(regress.RegressTest): 11 | def test(self): 12 | if platform.system() == "Darwin": 13 | rusage_multiplier = 1 14 | elif platform.system() == "Linux": 15 | rusage_multiplier = 1024 16 | else: 17 | # resource.getrusage(...) is platform dependent. Only tested under OS X and Linux. 18 | return 19 | max_rss_before = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss * rusage_multiplier 20 | for i in xrange(10000): 21 | mu = Uc(UC_ARCH_X86, UC_MODE_64) 22 | mu.mem_map(0, 4096) 23 | mu.emu_start(0, 0) 24 | max_rss_after = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss * rusage_multiplier 25 | rss_increase_per_iteration = (max_rss_after - max_rss_before) / i 26 | self.assertLess(rss_increase_per_iteration, 8000) 27 | 28 | if __name__ == '__main__': 29 | regress.main() 30 | -------------------------------------------------------------------------------- /tests/regress/pshufb.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # By Ryan Hileman, issue #91 3 | 4 | # Invalid instruction = test failed 5 | 6 | from unicorn import * 7 | from unicorn.x86_const import * 8 | 9 | import regress 10 | 11 | class Pshufb(regress.RegressTest): 12 | 13 | def runTest(self): 14 | uc = Uc(UC_ARCH_X86, UC_MODE_64) 15 | uc.mem_map(0x2000, 0x1000) 16 | # pshufb xmm0, xmm1 17 | uc.mem_write(0x2000, '660f3800c1'.decode('hex')) 18 | uc.emu_start(0x2000, 0x2005) 19 | 20 | if __name__ == '__main__': 21 | regress.main() 22 | -------------------------------------------------------------------------------- /tests/regress/reg_write_sign_extension.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """See https://github.com/unicorn-engine/unicorn/issues/98""" 4 | 5 | import unicorn 6 | import regress 7 | 8 | ADDR = 0xffaabbcc 9 | 10 | def hook_mem_invalid(mu, access, address, size, value, user_data): 11 | print ">>> Access type: %u, expected value: 0x%x, actual value: 0x%x" % (access, ADDR, address) 12 | assert(address == ADDR) 13 | mu.mem_map(address & 0xfffff000, 4 * 1024) 14 | mu.mem_write(address, b'\xcc') 15 | return True 16 | 17 | class RegWriteSignExt(regress.RegressTest): 18 | 19 | def runTest(self): 20 | mu = unicorn.Uc(unicorn.UC_ARCH_X86, unicorn.UC_MODE_32) 21 | mu.reg_write(unicorn.x86_const.UC_X86_REG_EBX, ADDR) 22 | 23 | mu.mem_map(0x10000000, 1024 * 4) 24 | # jmp ebx 25 | mu.mem_write(0x10000000, b'\xff\xe3') 26 | 27 | mu.hook_add(unicorn.UC_HOOK_MEM_FETCH_UNMAPPED | unicorn.UC_HOOK_MEM_FETCH_PROT, hook_mem_invalid) 28 | mu.emu_start(0x10000000, 0x10000000 + 2, count=1) 29 | 30 | if __name__ == '__main__': 31 | regress.main() 32 | -------------------------------------------------------------------------------- /tests/regress/regress.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import unittest 4 | 5 | from os.path import dirname, basename, isfile 6 | import glob 7 | 8 | # Find all unittest type in this directory and run it. 9 | 10 | class RegressTest(unittest.TestCase): 11 | pass 12 | 13 | def main(): 14 | unittest.main() 15 | 16 | if __name__ == '__main__': 17 | directory = dirname(__file__) 18 | if directory == '': 19 | directory = '.' 20 | modules = glob.glob(directory+"/*.py") 21 | __all__ = [ basename(f)[:-3] for f in modules if isfile(f)] 22 | suite = unittest.TestSuite() 23 | 24 | for module in __all__: 25 | m = __import__(module) 26 | for cl in dir(m): 27 | try: 28 | realcl = getattr(m,cl) 29 | if issubclass(realcl, unittest.TestCase): 30 | suite.addTest(realcl()) 31 | except Exception as e: 32 | pass 33 | 34 | unittest.TextTestRunner().run(suite) 35 | -------------------------------------------------------------------------------- /tests/regress/regress.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | 4 | ./map_crash 5 | ./map_write 6 | ./sigill 7 | ./sigill2 8 | ./block_test 9 | ./ro_mem_test 10 | ./nr_mem_test 11 | ./timeout_segfault 12 | ./rep_movsb 13 | ./mem_unmap 14 | ./mem_protect 15 | ./mem_exec 16 | ./mem_map_large 17 | ./00opcode_uc_crash 18 | ./eflags_noset 19 | ./eflags_nosync 20 | ./mips_kseg0_1 21 | ./mem_double_unmap 22 | 23 | -------------------------------------------------------------------------------- /tests/regress/rep_hook.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | from unicorn import * 3 | from unicorn.x86_const import * 4 | import regress 5 | 6 | PAGE_SIZE = 4 * 1024 7 | 8 | CODE = b'\xf3\xaa' # rep stosb 9 | 10 | 11 | def hook_code(uc, addr, size, user_data): 12 | print("hook called at %x" %addr) 13 | 14 | class REP(regress.RegressTest): 15 | 16 | def test_rep(self): 17 | mu = Uc(UC_ARCH_X86, UC_MODE_32) 18 | 19 | mu.mem_map(0, PAGE_SIZE) 20 | mu.mem_write(0, CODE) 21 | mu.reg_write(UC_X86_REG_ECX, 3) 22 | mu.reg_write(UC_X86_REG_EDI, 0x100) 23 | mu.hook_add(UC_HOOK_CODE, hook_code) 24 | 25 | mu.emu_start(0, len(CODE)) 26 | self.assertEqual(0, mu.reg_read(UC_X86_REG_ECX)) 27 | 28 | 29 | if __name__ == '__main__': 30 | regress.main() 31 | -------------------------------------------------------------------------------- /tests/regress/segfault_on_stop.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import regress 4 | import unicorn 5 | 6 | 7 | class SegfaultOnStop(regress.RegressTest): 8 | def test(self): 9 | unicorn.Uc(unicorn.UC_ARCH_X86, unicorn.UC_MODE_64).emu_stop() 10 | self.assertTrue(True, "If not reached, then we have a crashing bug.") 11 | 12 | if __name__ == '__main__': 13 | regress.main() 14 | -------------------------------------------------------------------------------- /tests/regress/sigill.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #define UC_BUG_WRITE_SIZE 128 7 | #define UC_BUG_WRITE_ADDR 0x1000 // fix this by change this to 0x2000 8 | 9 | int got_sigill = 0; 10 | 11 | void _interrupt(uc_engine *uc, uint32_t intno, void *user_data) 12 | { 13 | if (intno == 6) { 14 | uc_emu_stop(uc); 15 | got_sigill = 1; 16 | } 17 | } 18 | 19 | int main() 20 | { 21 | int size; 22 | uint8_t *buf; 23 | uc_engine *uc; 24 | uc_hook uh_trap; 25 | uc_err err = uc_open (UC_ARCH_X86, UC_MODE_64, &uc); 26 | if (err) { 27 | fprintf (stderr, "Cannot initialize unicorn\n"); 28 | return 1; 29 | } 30 | size = UC_BUG_WRITE_SIZE; 31 | buf = malloc (size); 32 | if (!buf) { 33 | fprintf (stderr, "Cannot allocate\n"); 34 | return 1; 35 | } 36 | memset (buf, 0, size); 37 | if (!uc_mem_map(uc, UC_BUG_WRITE_ADDR, size, UC_PROT_ALL)) { 38 | uc_mem_write(uc, UC_BUG_WRITE_ADDR, 39 | (const uint8_t*)"\xff\xff\xff\xff\xff\xff\xff\xff", 8); 40 | } 41 | uc_hook_add(uc, &uh_trap, UC_HOOK_INTR, _interrupt, NULL, 1, 0); 42 | uc_emu_start(uc, UC_BUG_WRITE_ADDR, UC_BUG_WRITE_ADDR+8, 0, 1); 43 | uc_close(uc); 44 | free(buf); 45 | printf ("Correct: %s\n", got_sigill? "YES": "NO"); 46 | return got_sigill? 0: 1; 47 | } 48 | -------------------------------------------------------------------------------- /tests/regress/sigill2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #define UC_BUG_WRITE_SIZE 128 7 | #define UC_BUG_WRITE_ADDR 0x2000 8 | 9 | int main() 10 | { 11 | int size; 12 | uc_engine *uc; 13 | 14 | uc_err err = uc_open (UC_ARCH_X86, UC_MODE_64, &uc); 15 | if (err) { 16 | fprintf (stderr, "Cannot initialize unicorn\n"); 17 | return 1; 18 | } 19 | size = UC_BUG_WRITE_SIZE; 20 | if (!uc_mem_map (uc, UC_BUG_WRITE_ADDR, size, UC_PROT_ALL)) { 21 | uc_mem_write (uc, UC_BUG_WRITE_ADDR, 22 | (const uint8_t*)"\xff\xff\xff\xff\xff\xff\xff\xff", 8); 23 | } 24 | err = uc_emu_start(uc, UC_BUG_WRITE_ADDR, UC_BUG_WRITE_ADDR+8, 0, 1); 25 | uc_close(uc); 26 | printf ("Error = %u (%s)\n", err, uc_strerror(err)); 27 | return err? -1: 0; 28 | } 29 | -------------------------------------------------------------------------------- /tests/regress/sparc64.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | from unicorn import * 4 | from unicorn.sparc_const import * 5 | 6 | PAGE_SIZE = 1 * 1024 * 1024 7 | 8 | uc = Uc(UC_ARCH_SPARC, UC_MODE_SPARC64|UC_MODE_BIG_ENDIAN) 9 | uc.reg_write(UC_SPARC_REG_SP, 100) 10 | print 'writing sp = 100' 11 | 12 | # 0: b0 06 20 01 inc %i0 13 | # 4: b2 06 60 01 inc %i1 14 | 15 | CODE = "\xb0\x06\x20\x01" \ 16 | "\xb2\x06\x60\x01" 17 | 18 | uc.mem_map(0, PAGE_SIZE) 19 | uc.mem_write(0, CODE) 20 | uc.emu_start(0, len(CODE), 0, 2) 21 | 22 | print 'sp =', uc.reg_read(UC_SPARC_REG_SP) 23 | print 'i0 =', uc.reg_read(UC_SPARC_REG_I0) 24 | print 'i1 =', uc.reg_read(UC_SPARC_REG_I1) 25 | -------------------------------------------------------------------------------- /tests/regress/sparc_jump_to_zero.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define HARDWARE_ARCHITECTURE UC_ARCH_SPARC 4 | #define HARDWARE_MODE UC_MODE_SPARC32|UC_MODE_BIG_ENDIAN 5 | 6 | #define MEMORY_STARTING_ADDRESS 0x1000000 7 | #define MEMORY_SIZE 2 * 1024 * 1024 8 | #define MEMORY_PERMISSIONS UC_PROT_ALL 9 | 10 | #define BINARY_CODE "\x02\xbc\x00\x00" 11 | 12 | int main(int argc, char **argv, char **envp) { 13 | uc_engine *uc; 14 | if (uc_open(HARDWARE_ARCHITECTURE, HARDWARE_MODE, &uc)) { 15 | printf("uc_open(…) failed\n"); 16 | return 1; 17 | } 18 | uc_mem_map(uc, MEMORY_STARTING_ADDRESS, MEMORY_SIZE, MEMORY_PERMISSIONS); 19 | if (uc_mem_write(uc, MEMORY_STARTING_ADDRESS, BINARY_CODE, sizeof(BINARY_CODE) - 1)) { 20 | printf("uc_mem_write(…) failed\n"); 21 | return 1; 22 | } 23 | printf("uc_emu_start(…)\n"); 24 | uc_emu_start(uc, MEMORY_STARTING_ADDRESS, MEMORY_STARTING_ADDRESS + sizeof(BINARY_CODE) - 1, 0, 20); 25 | printf("done\n"); 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /tests/regress/write_before_map.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from __future__ import print_function 4 | from unicorn import * 5 | from unicorn.x86_const import * 6 | 7 | import regress 8 | 9 | X86_CODE64 = "\x90" # NOP 10 | 11 | 12 | class WriteBeforeMap(regress.RegressTest): 13 | def runTest(self): 14 | # Initialize emulator in X86-32bit mode 15 | mu = Uc(UC_ARCH_X86, UC_MODE_64) 16 | 17 | # memory address where emulation starts 18 | ADDRESS = 0x1000000 19 | 20 | # write machine code to be emulated to memory 21 | mu.mem_write(ADDRESS, X86_CODE64) 22 | 23 | 24 | if __name__ == '__main__': 25 | regress.main() 26 | -------------------------------------------------------------------------------- /tests/regress/wrong_rip_arm.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | from unicorn import * 4 | from unicorn.x86_const import * 5 | from unicorn.arm_const import * 6 | 7 | import regress 8 | 9 | # adds r1, #0x48 10 | # ldrsb r7, [r7, r7] 11 | # ldrsh r7, [r2, r1] 12 | # ldr r0, [pc, #0x168] 13 | # cmp r7, #0xbf 14 | # str r7, [r5, #0x20] 15 | # ldr r1, [r5, #0x64] 16 | # strb r7, [r5, #0xc] 17 | # ldr r0, [pc, #0x1a0] 18 | binary1 = b'\x48\x31\xff\x57\x57\x5e\x5a\x48\xbf\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xef\x08\x57\x54\x5f\x6a\x3b\x58\x0f\x05' 19 | # binary1 = b'\x48\x31\xff\x57' 20 | #adds r1, #0x48 21 | #ldrsb r7, [r7, r7] 22 | 23 | class WrongRIPArm(regress.RegressTest): 24 | 25 | def runTest(self): 26 | mu = Uc(UC_ARCH_ARM, UC_MODE_THUMB) 27 | mu.mem_map(0, 2 * 1024 * 1024) 28 | # write machine code to be emulated to memory 29 | mu.mem_write(0, binary1) 30 | mu.reg_write(UC_ARM_REG_R13, 1 * 1024 * 1024) 31 | # emu for maximum 1 instruction. 32 | mu.emu_start(0, len(binary1), 0, 1) 33 | self.assertEqual(0x48, mu.reg_read(UC_ARM_REG_R1)) 34 | pos = mu.reg_read(UC_ARM_REG_R15) 35 | self.assertEqual(0x2, pos) 36 | 37 | if __name__ == '__main__': 38 | regress.main() 39 | -------------------------------------------------------------------------------- /tests/regress/wrong_sp_arm.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # By Ryan Hileman, issue #16 3 | 4 | from unicorn import * 5 | from unicorn.arm_const import * 6 | from unicorn.arm64_const import * 7 | 8 | import regress 9 | 10 | class WrongSPArm(regress.RegressTest): 11 | 12 | def test_32(self): 13 | with self.assertRaises(UcError): 14 | uc = Uc(UC_ARCH_ARM, UC_MODE_32) 15 | uc.reg_write(UC_ARM_REG_SP, 4) 16 | 17 | def test_64(self): 18 | uc = Uc(UC_ARCH_ARM64, UC_MODE_ARM) 19 | uc.reg_write(UC_ARM64_REG_SP, 4) 20 | self.assertEqual(0x4, uc.reg_read(UC_ARM64_REG_SP)) 21 | 22 | def test_arm(self): 23 | uc = Uc(UC_ARCH_ARM, UC_MODE_ARM) 24 | uc.reg_write(UC_ARM_REG_SP, 4) 25 | self.assertEqual(0x4, uc.reg_read(UC_ARM_REG_SP)) 26 | 27 | if __name__ == '__main__': 28 | regress.main() 29 | -------------------------------------------------------------------------------- /tests/regress/x86_16_segfault.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define BINARY "\x90" 4 | #define MEMORY_SIZE 4 * 1024 5 | #define STARTING_ADDRESS 100 * 1024 6 | 7 | int main(int argc, char **argv, char **envp) { 8 | uc_engine *uc; 9 | if (uc_open(UC_ARCH_X86, UC_MODE_16, &uc)) { 10 | printf("uc_open(…) failed\n"); 11 | return 1; 12 | } 13 | uc_mem_map(uc, STARTING_ADDRESS, MEMORY_SIZE, UC_PROT_ALL); 14 | if (uc_mem_write(uc, STARTING_ADDRESS, BINARY, sizeof(BINARY) - 1)) { 15 | printf("uc_mem_write(…) failed\n"); 16 | return 1; 17 | } 18 | printf("uc_emu_start(…)\n"); 19 | uc_emu_start(uc, STARTING_ADDRESS, STARTING_ADDRESS + sizeof(BINARY) - 1, 0, 20); 20 | printf("done\n"); 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /tests/regress/x86_64_eflags.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import regress 3 | import unicorn as U 4 | 5 | class WrongEFLAGS(regress.RegressTest): 6 | def test_eflags(self): 7 | # xor r14,r14 8 | CODE = 'M1\xf6' 9 | 10 | uc = U.Uc(U.UC_ARCH_X86, U.UC_MODE_64) 11 | uc.reg_write(U.x86_const.UC_X86_REG_RIP, 0x6000b0) 12 | uc.reg_write(U.x86_const.UC_X86_REG_EFLAGS, 0x200) 13 | 14 | uc.mem_map(0x600000, 0x1000) 15 | uc.mem_write(0x6000b0, CODE) 16 | uc.emu_start(0x6000b0, 0, count=1) 17 | 18 | 19 | # Here's the original execution trace for this on actual hardware. 20 | # 21 | # (gdb) x/i $pc 22 | # => 0x6000b0: xor %r14,%r14 23 | # (gdb) p/x $eflags 24 | # $1 = 0x200 25 | # (gdb) p $eflags 26 | # $2 = [ IF ] 27 | # (gdb) si 28 | # 0x00000000006000b3 in ?? () 29 | # (gdb) p/x $eflags 30 | # $3 = 0x246 31 | # (gdb) p $eflags 32 | # $4 = [ PF ZF IF ] 33 | 34 | self.assertEqual(0x6000b3, uc.reg_read(U.x86_const.UC_X86_REG_RIP)) 35 | self.assertEqual(0x246, uc.reg_read(U.x86_const.UC_X86_REG_EFLAGS)) 36 | 37 | if __name__ == '__main__': 38 | regress.main() 39 | -------------------------------------------------------------------------------- /tests/regress/x86_eflags.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import regress 3 | import unicorn as U 4 | 5 | class WrongEFLAGS2(regress.RegressTest): 6 | def test_eflags(self): 7 | # imul eax, ebx 8 | CODE = '\x0f\xaf\xc3' 9 | 10 | uc = U.Uc(U.UC_ARCH_X86, U.UC_MODE_32) 11 | uc.reg_write(U.x86_const.UC_X86_REG_EAX, 16) 12 | uc.reg_write(U.x86_const.UC_X86_REG_EBX, 1) 13 | uc.reg_write(U.x86_const.UC_X86_REG_EFLAGS, 0x292) 14 | 15 | uc.mem_map(0x600000, 0x1000) 16 | uc.mem_write(0x6000b0, CODE) 17 | uc.emu_start(0x6000b0, 0, count=1) 18 | 19 | 20 | # Here's the original execution trace for this on actual hardware. 21 | # 22 | # (gdb) x/i $eip 23 | # => 0x804aae5: imul eax,DWORD PTR [ebp-0x8] 24 | # (gdb) p/x $eax 25 | # $2 = 0x10 26 | # (gdb) x/wx $ebp-8 27 | # 0xbaaaad4c: 0x00000001 28 | # (gdb) p/x $eflags 29 | # $3 = 0x292 30 | # (gdb) si 31 | # 0x0804aae9 in ?? () 32 | # (gdb) p/x $eflags 33 | # $4 = 0x202 34 | 35 | self.assertEqual(0x202, uc.reg_read(U.x86_const.UC_X86_REG_EFLAGS)) 36 | 37 | if __name__ == '__main__': 38 | regress.main() 39 | -------------------------------------------------------------------------------- /tests/regress/x86_fldt_fsqrt.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from unicorn import * 3 | from unicorn.x86_const import * 4 | from struct import pack 5 | 6 | import regress 7 | 8 | CODE_ADDR = 0x1000000 9 | CODE = ( 10 | '\xb8\x00\x00\x00\x02' # mov eax, 0x2000000 11 | '\xdb\x28' # fldt [eax] 12 | '\xd9\xfa' # fsqrt 13 | ) 14 | 15 | DATA_ADDR = 0x2000000 16 | DATA = '\0\0\0\0\0\0\0\0\0\1' 17 | 18 | class FldtFsqrt(regress.RegressTest): 19 | def test_fldt_fsqrt(self): 20 | uc = Uc(UC_ARCH_X86, UC_MODE_32) 21 | 22 | uc.mem_map(CODE_ADDR, 0x1000) 23 | uc.mem_write(CODE_ADDR, CODE) 24 | 25 | uc.mem_map(DATA_ADDR, 0x1000) 26 | uc.mem_write(DATA_ADDR, DATA) 27 | 28 | uc.emu_start(CODE_ADDR, CODE_ADDR + len(CODE), 10000, 10) 29 | 30 | if __name__ == '__main__': 31 | regress.main() 32 | -------------------------------------------------------------------------------- /tests/regress/x86_self_modifying.elf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/unicorn-for-efi/40a8d07ba3cef067d9a6455c163dbed8d94f8e38/tests/regress/x86_self_modifying.elf -------------------------------------------------------------------------------- /tests/regress/x86_self_modifying.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from unicorn import * 3 | from unicorn.x86_const import * 4 | from struct import pack 5 | 6 | import os 7 | import regress 8 | 9 | # The file we're loading is a full assembled ELF. 10 | # Source for it, along with assembly instructions, are in x86_self_modifying.s 11 | 12 | CODE_ADDR = 0x08048000 13 | STACK_ADDR = 0x2000000 14 | CODE = open(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'x86_self_modifying.elf')).read() 15 | CODE_SIZE = len(CODE) + (0x1000 - len(CODE)%0x1000) 16 | STACK_SIZE = 0x8000 17 | 18 | ENTRY_POINT = 0x8048074 19 | 20 | def hook_intr(uc, intno, data): 21 | uc.emu_stop() 22 | 23 | class SelfModifying(regress.RegressTest): 24 | def test_self_modifying(self): 25 | uc = Uc(UC_ARCH_X86, UC_MODE_32) 26 | 27 | uc.mem_map(CODE_ADDR, CODE_SIZE, 5) 28 | uc.mem_map(STACK_ADDR, STACK_SIZE, 7) 29 | uc.mem_write(CODE_ADDR, CODE) 30 | uc.reg_write(UC_X86_REG_ESP, STACK_ADDR + STACK_SIZE) 31 | 32 | uc.hook_add(UC_HOOK_INTR, hook_intr) 33 | 34 | uc.emu_start(ENTRY_POINT, -1) 35 | 36 | retcode = uc.reg_read(UC_X86_REG_EBX) 37 | self.assertEqual(retcode, 65) 38 | 39 | if __name__ == '__main__': 40 | regress.main() 41 | -------------------------------------------------------------------------------- /tests/regress/x86_set_ip.py: -------------------------------------------------------------------------------- 1 | from unicorn import * 2 | from unicorn.x86_const import * 3 | 4 | count = 0 5 | 6 | def cb(uc, addr, sz, data): 7 | global count 8 | count += 1 9 | print(f"addr: {hex(addr)} count: {count}") 10 | if count == 5: 11 | uc.emu_stop() 12 | else: 13 | uc.reg_write(UC_X86_REG_RIP, 0x2000) 14 | 15 | mu = Uc(UC_ARCH_X86, UC_MODE_64) 16 | 17 | mu.mem_map(0x1000, 0x4000) 18 | mu.mem_write(0x1000, b"\x90" * 5) 19 | mu.mem_write(0x2000, b"\x90" * 5) 20 | mu.hook_add(UC_HOOK_CODE, cb) 21 | mu.emu_start(0x1000, 0x2000+1, 0, 0) 22 | -------------------------------------------------------------------------------- /tests/unit/test_m68k.c: -------------------------------------------------------------------------------- 1 | #include "unicorn_test.h" 2 | 3 | const uint64_t code_start = 0x1000; 4 | const uint64_t code_len = 0x4000; 5 | 6 | static void uc_common_setup(uc_engine **uc, uc_arch arch, uc_mode mode, 7 | const char *code, uint64_t size, 8 | uc_cpu_m68k cpu_model) 9 | { 10 | OK(uc_open(arch, mode, uc)); 11 | OK(uc_ctl_set_cpu_model(*uc, cpu_model)); 12 | OK(uc_mem_map(*uc, code_start, code_len, UC_PROT_ALL)); 13 | OK(uc_mem_write(*uc, code_start, code, size)); 14 | } 15 | 16 | static void test_move_to_sr(void) 17 | { 18 | 19 | uc_engine *uc; 20 | char code[] = "\x46\xfc\x27\x00"; // move #$2700,sr 21 | int r_sr; 22 | 23 | uc_common_setup(&uc, UC_ARCH_M68K, UC_MODE_BIG_ENDIAN, code, 24 | sizeof(code) - 1, UC_CPU_M68K_M68000); 25 | OK(uc_reg_read(uc, UC_M68K_REG_SR, &r_sr)); 26 | 27 | r_sr = r_sr | 0x2000; 28 | 29 | OK(uc_reg_write(uc, UC_M68K_REG_SR, &r_sr)); 30 | 31 | OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0)); 32 | 33 | OK(uc_close(uc)); 34 | } 35 | 36 | TEST_LIST = {{"test_move_to_sr", test_move_to_sr}, {NULL, NULL}}; -------------------------------------------------------------------------------- /tests/unit/test_s390x.c: -------------------------------------------------------------------------------- 1 | #include "unicorn_test.h" 2 | 3 | const uint64_t code_start = 0x1000; 4 | const uint64_t code_len = 0x4000; 5 | 6 | static void uc_common_setup(uc_engine **uc, uc_arch arch, uc_mode mode, 7 | const char *code, uint64_t size) 8 | { 9 | OK(uc_open(arch, mode, uc)); 10 | OK(uc_mem_map(*uc, code_start, code_len, UC_PROT_ALL)); 11 | OK(uc_mem_write(*uc, code_start, code, size)); 12 | } 13 | 14 | static void test_s390x_lr(void) 15 | { 16 | char code[] = "\x18\x23"; // lr %r2, %r3 17 | uint64_t r_pc, r_r2, r_r3 = 0x114514; 18 | uc_engine *uc; 19 | 20 | uc_common_setup(&uc, UC_ARCH_S390X, UC_MODE_BIG_ENDIAN, code, 21 | sizeof(code) - 1); 22 | 23 | OK(uc_reg_write(uc, UC_S390X_REG_R3, &r_r3)); 24 | 25 | OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0)); 26 | 27 | OK(uc_reg_read(uc, UC_S390X_REG_R2, &r_r2)); 28 | OK(uc_reg_read(uc, UC_S390X_REG_PC, &r_pc)); 29 | 30 | TEST_CHECK(r_r2 == 0x114514); 31 | TEST_CHECK(r_pc == code_start + sizeof(code) - 1); 32 | 33 | OK(uc_close(uc)); 34 | } 35 | 36 | TEST_LIST = {{"test_s390x_lr", test_s390x_lr}, {NULL, NULL}}; 37 | -------------------------------------------------------------------------------- /tests/unit/test_sparc.c: -------------------------------------------------------------------------------- 1 | #include "unicorn_test.h" 2 | 3 | const uint64_t code_start = 0x1000; 4 | const uint64_t code_len = 0x4000; 5 | 6 | TEST_LIST = {{NULL, NULL}}; -------------------------------------------------------------------------------- /tests/unit/test_tricore.c: -------------------------------------------------------------------------------- 1 | #include "unicorn_test.h" 2 | 3 | const uint64_t code_start = 0x1000; 4 | const uint64_t code_len = 0x4000; 5 | 6 | TEST_LIST = {{NULL, NULL}}; 7 | --------------------------------------------------------------------------------