├── .appveyor.yml ├── .codespell_ignore ├── .github ├── actions │ └── install │ │ ├── action.yml │ │ └── install.sh └── workflows │ └── tests.yml ├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── Dockerfile ├── LICENSE ├── README.md ├── doc ├── README.md ├── cheatsheets │ ├── reminder_disassembler.drawio │ ├── reminder_disassembler.pdf │ ├── reminder_sandbox.drawio │ └── reminder_sandbox.pdf ├── expression │ └── expression.ipynb ├── ir │ └── lift.ipynb ├── jitter │ └── jitter.ipynb ├── locationdb │ └── locationdb.ipynb └── logo_miasm.png ├── example ├── asm │ ├── shellcode.py │ └── simple.py ├── disasm │ ├── callback.py │ ├── dis_binary.py │ ├── dis_binary_lift.py │ ├── dis_binary_lift_model_call.py │ ├── dis_x86_string.py │ ├── full.py │ └── single_instr.py ├── expression │ ├── access_c.py │ ├── asm_to_ir.py │ ├── basic_op.py │ ├── basic_simplification.py │ ├── constant_propagation.py │ ├── export_llvm.py │ ├── expr_c.py │ ├── expr_grapher.py │ ├── expr_random.py │ ├── expr_reduce.py │ ├── expr_translate.py │ ├── get_read_write.py │ ├── graph_dataflow.py │ ├── interfer.py │ ├── simplification_add.py │ ├── simplification_tools.py │ └── solve_condition_stp.py ├── ida │ ├── ctype_propagation.py │ ├── depgraph.py │ ├── graph_ir.py │ ├── menu.py │ ├── rpyc_ida.py │ ├── symbol_exec.py │ └── utils.py ├── jitter │ ├── arm.py │ ├── arm_sc.py │ ├── example_types.py │ ├── memory_breakpoint.py │ ├── mips32.py │ ├── msp430.py │ ├── run_with_linuxenv.py │ ├── sandbox_call.py │ ├── sandbox_elf_aarch64l.py │ ├── sandbox_elf_ppc32.py │ ├── sandbox_pe_x86_32.py │ ├── sandbox_pe_x86_64.py │ ├── test_x86_32_seh.py │ ├── trace.py │ ├── unpack_generic.py │ ├── unpack_upx.py │ ├── x86_32.py │ └── x86_64.py ├── loader │ ├── build_pe.py │ ├── get_exports.py │ ├── minidump_to_pe.py │ └── sc2pe.py ├── samples │ ├── aarch64_simple.S │ ├── arm_sc.S │ ├── arm_simple.S │ ├── armt.S │ ├── box_upx.exe │ ├── dse_crackme │ ├── dse_crackme.c │ ├── human.S │ ├── md5_aarch64l │ ├── md5_arm │ ├── md5_ppc32b │ ├── mips32.S │ ├── msp430.S │ ├── simple_test.bin │ ├── simple_test.c │ ├── test_x86_32_dis.S │ ├── x86_32_automod.S │ ├── x86_32_automod_2.S │ ├── x86_32_dead.S │ ├── x86_32_enc.S │ ├── x86_32_if_reg.S │ ├── x86_32_manip_ptr.S │ ├── x86_32_mod.S │ ├── x86_32_mod_self.S │ ├── x86_32_pop_esp.S │ ├── x86_32_repmod.S │ ├── x86_32_sc.bin │ ├── x86_32_seh.S │ ├── x86_32_simple.S │ └── x86_64.S └── symbol_exec │ ├── depgraph.py │ ├── dse_crackme.py │ ├── dse_strategies.py │ ├── single_instr.py │ └── symbol_exec.py ├── miasm ├── __init__.py ├── analysis │ ├── __init__.py │ ├── binary.py │ ├── cst_propag.py │ ├── data_analysis.py │ ├── data_flow.py │ ├── debugging.py │ ├── depgraph.py │ ├── disasm_cb.py │ ├── dse.py │ ├── expression_range.py │ ├── gdbserver.py │ ├── machine.py │ ├── modularintervals.py │ ├── outofssa.py │ ├── sandbox.py │ ├── simplifier.py │ └── ssa.py ├── arch │ ├── __init__.py │ ├── aarch64 │ │ ├── __init__.py │ │ ├── arch.py │ │ ├── disasm.py │ │ ├── jit.py │ │ ├── lifter_model_call.py │ │ ├── regs.py │ │ └── sem.py │ ├── arm │ │ ├── __init__.py │ │ ├── arch.py │ │ ├── disasm.py │ │ ├── jit.py │ │ ├── lifter_model_call.py │ │ ├── regs.py │ │ └── sem.py │ ├── mep │ │ ├── __init__.py │ │ ├── arch.py │ │ ├── disasm.py │ │ ├── jit.py │ │ ├── lifter_model_call.py │ │ ├── regs.py │ │ └── sem.py │ ├── mips32 │ │ ├── __init__.py │ │ ├── arch.py │ │ ├── disasm.py │ │ ├── jit.py │ │ ├── lifter_model_call.py │ │ ├── regs.py │ │ └── sem.py │ ├── msp430 │ │ ├── __init__.py │ │ ├── arch.py │ │ ├── ctype.py │ │ ├── disasm.py │ │ ├── jit.py │ │ ├── lifter_model_call.py │ │ ├── regs.py │ │ └── sem.py │ ├── ppc │ │ ├── __init__.py │ │ ├── arch.py │ │ ├── disasm.py │ │ ├── jit.py │ │ ├── lifter_model_call.py │ │ ├── regs.py │ │ └── sem.py │ ├── sh4 │ │ ├── __init__.py │ │ ├── arch.py │ │ └── regs.py │ └── x86 │ │ ├── __init__.py │ │ ├── arch.py │ │ ├── ctype.py │ │ ├── disasm.py │ │ ├── jit.py │ │ ├── lifter_model_call.py │ │ ├── regs.py │ │ └── sem.py ├── core │ ├── __init__.py │ ├── asm_ast.py │ ├── asmblock.py │ ├── bin_stream.py │ ├── bin_stream_ida.py │ ├── cpu.py │ ├── ctypesmngr.py │ ├── graph.py │ ├── interval.py │ ├── locationdb.py │ ├── modint.py │ ├── objc.py │ ├── parse_asm.py │ ├── sembuilder.py │ ├── types.py │ └── utils.py ├── expression │ ├── __init__.py │ ├── expression.py │ ├── expression_helper.py │ ├── expression_reduce.py │ ├── parser.py │ ├── simplifications.py │ ├── simplifications_common.py │ ├── simplifications_cond.py │ ├── simplifications_explicit.py │ └── smt2_helper.py ├── ir │ ├── __init__.py │ ├── analysis.py │ ├── ir.py │ ├── symbexec.py │ ├── symbexec_top.py │ ├── symbexec_types.py │ └── translators │ │ ├── C.py │ │ ├── __init__.py │ │ ├── miasm_ir.py │ │ ├── python.py │ │ ├── smt2.py │ │ ├── translator.py │ │ └── z3_ir.py ├── jitter │ ├── JitCore.c │ ├── JitCore.h │ ├── Jitgcc.c │ ├── Jitllvm.c │ ├── __init__.py │ ├── arch │ │ ├── JitCore_aarch64.c │ │ ├── JitCore_aarch64.h │ │ ├── JitCore_arm.c │ │ ├── JitCore_arm.h │ │ ├── JitCore_m68k.c │ │ ├── JitCore_m68k.h │ │ ├── JitCore_mep.c │ │ ├── JitCore_mep.h │ │ ├── JitCore_mips32.c │ │ ├── JitCore_mips32.h │ │ ├── JitCore_msp430.c │ │ ├── JitCore_msp430.h │ │ ├── JitCore_ppc32.c │ │ ├── JitCore_ppc32.h │ │ ├── JitCore_ppc32_regs.h │ │ ├── JitCore_x86.c │ │ ├── JitCore_x86.h │ │ └── __init__.py │ ├── bn.c │ ├── bn.h │ ├── codegen.py │ ├── compat_py23.h │ ├── csts.py │ ├── emulatedsymbexec.py │ ├── jitcore.py │ ├── jitcore_cc_base.py │ ├── jitcore_gcc.py │ ├── jitcore_llvm.py │ ├── jitcore_python.py │ ├── jitload.py │ ├── llvmconvert.py │ ├── loader │ │ ├── __init__.py │ │ ├── elf.py │ │ ├── pe.py │ │ └── utils.py │ ├── op_semantics.c │ ├── op_semantics.h │ ├── queue.h │ ├── vm_mngr.c │ ├── vm_mngr.h │ ├── vm_mngr_py.c │ └── vm_mngr_py.h ├── loader │ ├── __init__.py │ ├── cstruct.py │ ├── elf.py │ ├── elf_init.py │ ├── minidump.py │ ├── minidump_init.py │ ├── new_cstruct.py │ ├── pe.py │ ├── pe_init.py │ └── strpatchwork.py ├── os_dep │ ├── __init__.py │ ├── common.py │ ├── linux │ │ ├── __init__.py │ │ ├── environment.py │ │ └── syscall.py │ ├── linux_stdlib.py │ ├── win_32_structs.py │ ├── win_api_x86_32.py │ └── win_api_x86_32_seh.py └── runtime │ ├── divti3.c │ ├── export.h │ ├── int_endianness.h │ ├── int_lib.h │ ├── int_types.h │ ├── int_util.h │ ├── udivmodti4.c │ └── udivti3.c ├── optional_requirements.txt ├── requirements.txt ├── setup.py └── test ├── analysis ├── data_flow.py ├── depgraph.py ├── dg_check.py ├── dg_test_00_expected.json ├── dg_test_00_implicit_expected.json ├── dg_test_01_expected.json ├── dg_test_01_implicit_expected.json ├── dg_test_02_expected.json ├── dg_test_02_implicit_expected.json ├── dg_test_03_expected.json ├── dg_test_03_implicit_expected.json ├── dg_test_04_expected.json ├── dg_test_04_implicit_expected.json ├── dg_test_05_expected.json ├── dg_test_05_implicit_expected.json ├── dg_test_06_expected.json ├── dg_test_06_implicit_expected.json ├── dg_test_07_expected.json ├── dg_test_07_implicit_expected.json ├── dg_test_08_expected.json ├── dg_test_08_implicit_expected.json ├── dg_test_09_expected.json ├── dg_test_09_implicit_expected.json ├── dg_test_10_expected.json ├── dg_test_10_implicit_expected.json ├── dg_test_11_expected.json ├── dg_test_11_implicit_expected.json ├── dse.py ├── modularintervals.py ├── range.py └── unssa.py ├── arch ├── aarch64 │ ├── arch.py │ └── unit │ │ ├── asm_test.py │ │ └── mn_ubfm.py ├── arm │ ├── arch.py │ └── sem.py ├── mep │ ├── asm │ │ ├── launch.py │ │ ├── test_asm.py │ │ ├── test_major_opcode_0.py │ │ ├── test_major_opcode_1.py │ │ ├── test_major_opcode_10.py │ │ ├── test_major_opcode_11.py │ │ ├── test_major_opcode_12.py │ │ ├── test_major_opcode_13.py │ │ ├── test_major_opcode_14.py │ │ ├── test_major_opcode_15.py │ │ ├── test_major_opcode_2.py │ │ ├── test_major_opcode_3.py │ │ ├── test_major_opcode_4.py │ │ ├── test_major_opcode_5.py │ │ ├── test_major_opcode_6.py │ │ ├── test_major_opcode_7.py │ │ ├── test_major_opcode_8.py │ │ ├── test_major_opcode_9.py │ │ └── ut_helpers_asm.py │ ├── ir │ │ ├── launch.py │ │ ├── test_arithmetic.py │ │ ├── test_bitmanipulation.py │ │ ├── test_branchjump.py │ │ ├── test_control.py │ │ ├── test_coprocessor.py │ │ ├── test_datacache.py │ │ ├── test_debug.py │ │ ├── test_divide.py │ │ ├── test_extension.py │ │ ├── test_ir.py │ │ ├── test_ldz.py │ │ ├── test_loadstore.py │ │ ├── test_logical.py │ │ ├── test_move.py │ │ ├── test_multiply.py │ │ ├── test_repeat.py │ │ ├── test_shift.py │ │ └── ut_helpers_ir.py │ └── jit │ │ ├── launch.py │ │ ├── test_jit_branchjump.py │ │ ├── test_jit_repeat.py │ │ └── ut_helpers_jit.py ├── mips32 │ ├── arch.py │ └── unit │ │ ├── asm_test.py │ │ └── mn_bcc.py ├── msp430 │ ├── arch.py │ └── sem.py ├── ppc32 │ ├── arch.py │ └── sem.py ├── sh4 │ └── arch.py └── x86 │ ├── arch.py │ ├── qemu │ ├── expected │ │ ├── test_adc.exp │ │ ├── test_add.exp │ │ ├── test_and.exp │ │ ├── test_bcd.exp │ │ ├── test_bsx.exp │ │ ├── test_bt.exp │ │ ├── test_btc.exp │ │ ├── test_btr.exp │ │ ├── test_bts.exp │ │ ├── test_cmp.exp │ │ ├── test_code16.exp │ │ ├── test_conv.exp │ │ ├── test_dec.exp │ │ ├── test_exceptions.exp │ │ ├── test_floats.exp │ │ ├── test_inc.exp │ │ ├── test_jcc.exp │ │ ├── test_lea.exp │ │ ├── test_loop.exp │ │ ├── test_misc.exp │ │ ├── test_mul.exp │ │ ├── test_neg.exp │ │ ├── test_not.exp │ │ ├── test_or.exp │ │ ├── test_rcl.exp │ │ ├── test_rcr.exp │ │ ├── test_rol.exp │ │ ├── test_ror.exp │ │ ├── test_sar.exp │ │ ├── test_sbb.exp │ │ ├── test_segs.exp │ │ ├── test_self_modifying_code.exp │ │ ├── test_shl.exp │ │ ├── test_shld.exp │ │ ├── test_shr.exp │ │ ├── test_shrd.exp │ │ ├── test_single_step.exp │ │ ├── test_sse.exp │ │ ├── test_string.exp │ │ ├── test_sub.exp │ │ ├── test_xchg.exp │ │ └── test_xor.exp │ ├── expected_x86_64 │ │ ├── test_adc.exp │ │ ├── test_add.exp │ │ ├── test_and.exp │ │ ├── test_bt.exp │ │ ├── test_btc.exp │ │ ├── test_btr.exp │ │ ├── test_bts.exp │ │ ├── test_cmp.exp │ │ ├── test_conv.exp │ │ ├── test_dec.exp │ │ ├── test_floats.exp │ │ ├── test_fxsave.exp │ │ ├── test_inc.exp │ │ ├── test_jcc.exp │ │ ├── test_lea.exp │ │ ├── test_loop.exp │ │ ├── test_misc.exp │ │ ├── test_mul.exp │ │ ├── test_neg.exp │ │ ├── test_not.exp │ │ ├── test_or.exp │ │ ├── test_rcl.exp │ │ ├── test_rcr.exp │ │ ├── test_rol.exp │ │ ├── test_ror.exp │ │ ├── test_sar.exp │ │ ├── test_sbb.exp │ │ ├── test_shl.exp │ │ ├── test_shld.exp │ │ ├── test_shr.exp │ │ ├── test_shrd.exp │ │ ├── test_sse.exp │ │ ├── test_string.exp │ │ ├── test_sub.exp │ │ ├── test_xchg.exp │ │ └── test_xor.exp │ ├── test-i386 │ ├── test-x86_64 │ ├── testqemu.py │ └── testqemu64.py │ ├── sem.py │ └── unit │ ├── access_xmm.py │ ├── asm_test.py │ ├── mn_cdq.py │ ├── mn_cmov.py │ ├── mn_cpuid.py │ ├── mn_daa.py │ ├── mn_das.py │ ├── mn_div.py │ ├── mn_float.py │ ├── mn_getset128.py │ ├── mn_int.py │ ├── mn_pcmpeq.py │ ├── mn_pextr.py │ ├── mn_pinsr.py │ ├── mn_pmaxu.py │ ├── mn_pminu.py │ ├── mn_pmovmskb.py │ ├── mn_pshufb.py │ ├── mn_psrl_psll.py │ ├── mn_punpck.py │ ├── mn_pushpop.py │ ├── mn_rotsh.py │ ├── mn_seh.py │ ├── mn_stack.py │ ├── mn_strings.py │ └── test_asm_x86_64.py ├── core ├── asmblock.py ├── graph.py ├── interval.py ├── locationdb.py ├── modint.py ├── parse_asm.py ├── sembuilder.py ├── test_types.py └── utils.py ├── expr_type └── test_chandler.py ├── expression ├── expr_cmp.py ├── expr_pickle.py ├── expression.py ├── expression_helper.py ├── parser.py ├── simplifications.py ├── stp.py └── z3_div.py ├── ir ├── ir.py ├── ir2C.py ├── reduce_graph.py ├── symbexec.py └── translators │ ├── smt2.py │ └── z3_ir.py ├── jitter ├── bad_block.py ├── jit_options.py ├── jitcore.py ├── jitload.py ├── jmp_out_mem.py ├── mem_breakpoint.py ├── test_post_instr.py └── vm_mngr.py ├── os_dep ├── common.py ├── linux │ ├── stdlib.py │ ├── test_env.aarch64l │ ├── test_env.arml │ ├── test_env.c │ ├── test_env.py │ ├── test_env.x86_32 │ └── test_env.x86_64 └── win_api_x86_32.py ├── samples ├── x86_32 │ ├── bsr_bsf.S │ ├── cst_propag │ │ ├── x86_32_sc_1.S │ │ ├── x86_32_sc_10.S │ │ ├── x86_32_sc_11.S │ │ ├── x86_32_sc_12.S │ │ ├── x86_32_sc_13.S │ │ ├── x86_32_sc_14.S │ │ ├── x86_32_sc_15.S │ │ ├── x86_32_sc_16.S │ │ ├── x86_32_sc_17.S │ │ ├── x86_32_sc_18.S │ │ ├── x86_32_sc_19.S │ │ ├── x86_32_sc_2.S │ │ ├── x86_32_sc_20.S │ │ ├── x86_32_sc_3.S │ │ ├── x86_32_sc_4.S │ │ ├── x86_32_sc_5.S │ │ ├── x86_32_sc_6.S │ │ ├── x86_32_sc_7.S │ │ ├── x86_32_sc_8.S │ │ └── x86_32_sc_9.S │ ├── dg_test_00.S │ ├── dg_test_01.S │ ├── dg_test_02.S │ ├── dg_test_03.S │ ├── dg_test_04.S │ ├── dg_test_05.S │ ├── dg_test_06.S │ ├── dg_test_07.S │ ├── dg_test_08.S │ ├── dg_test_09.S │ ├── dg_test_10.S │ └── dg_test_11.S └── x86_64 │ └── mul_div.S ├── test_all.py └── utils ├── __init__.py ├── cosmetics.py ├── multithread.py ├── test.py └── testset.py /.appveyor.yml: -------------------------------------------------------------------------------- 1 | image: Visual Studio 2022 2 | 3 | configuration: 4 | - Release 5 | 6 | clone_folder: c:\projects\miasm 7 | 8 | environment: 9 | matrix: 10 | - PYTHON: "C:\\Python312-x64" 11 | PYTHON_VERSION: "3.12.x" 12 | PYTHON_ARCH: "64" 13 | 14 | init: 15 | - "ECHO %PYTHON% %PYTHON_VERSION% %PYTHON_ARCH%" 16 | - "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%" 17 | 18 | install: 19 | - cmd: cd c:\projects\miasm 20 | - cmd: "python.exe -m pip install -r requirements.txt" 21 | - cmd: "python.exe -m pip install -r optional_requirements.txt" 22 | 23 | build_script: 24 | - "%PYTHON%\\python.exe setup.py build" 25 | - "%PYTHON%\\python.exe setup.py install" 26 | 27 | test_script: 28 | - cmd: cd c:\projects\miasm\test 29 | - "%PYTHON%\\python.exe -W error test_all.py -t gcc" 30 | 31 | after_test: 32 | - cmd: chdir 33 | - cmd: if "%platform%"=="Win32" 7z a -t7z ..\miasm.x86.release.7z c:\projects\miasm\build\*lib* 34 | - cmd: if "%platform%"=="X64" 7z a -t7z ..\miasm.x64.release.7z c:\projects\miasm\build\*lib* 35 | 36 | artifacts: 37 | - path: miasm.*.7z 38 | -------------------------------------------------------------------------------- /.codespell_ignore: -------------------------------------------------------------------------------- 1 | ba 2 | dum 3 | dont 4 | uint 5 | mye 6 | iff 7 | nto 8 | rela 9 | daa 10 | od 11 | blocs 12 | fpr 13 | seh 14 | -------------------------------------------------------------------------------- /.github/actions/install/action.yml: -------------------------------------------------------------------------------- 1 | 2 | runs: 3 | using: "composite" 4 | steps: 5 | - run: ${{ github.action_path }}/install.sh 6 | shell: bash 7 | -------------------------------------------------------------------------------- /.github/actions/install/install.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | 4 | # codespell 5 | pip install codespell 6 | # install 7 | python setup.py build build_ext 8 | python setup.py install 9 | # extended tests 10 | git clone https://github.com/cea-sec/miasm-extended-tests 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Build directory 2 | /build/* 3 | dist/ 4 | sdists/ 5 | # Emacs files 6 | *~ 7 | # Compiled python files 8 | __pycache__/ 9 | *.py[cod] 10 | # Generated files 11 | *.egg* 12 | **.dot 13 | **.so 14 | VERSION 15 | # Virtual environments 16 | venv*/ 17 | .env/ 18 | .venv*/ -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: python 3 | python: 4 | - 2.7 5 | - 3.6 6 | addons: 7 | apt: 8 | sources: ['llvm-toolchain-xenial-6.0', 'ubuntu-toolchain-r-test'] 9 | packages: 10 | - llvm-6.0 11 | - llvm-6.0-dev 12 | - g++-5 13 | env: 14 | global: CXX=g++-5 LLVM_CONFIG=llvm-config-6.0 15 | matrix: 16 | - MIASM_TEST_EXTRA_ARG="-o regression -t long,python,llvm,gcc,z3,qemu,cparser" 17 | - MIASM_TEST_EXTRA_ARG="-o example -t long,python,llvm,gcc,z3,qemu,cparser" 18 | - MIASM_TEST_EXTRA_ARG="-o long" 19 | - MIASM_TEST_EXTRA_ARG="-o qemu -t llvm,gcc" 20 | - MIASM_TEST_EXTRA_ARG="-o qemu -t python,gcc" 21 | - MIASM_TEST_EXTRA_ARG="-o qemu -t python,llvm" 22 | - MIASM_TEST_EXTRA_ARG="-o llvm -t qemu,long" 23 | - MIASM_TEST_EXTRA_ARG="-o gcc -t qemu,long" 24 | - MIASM_TEST_EXTRA_ARG="-o python -t qemu,long" 25 | - MIASM_TEST_EXTRA_ARG="-o z3" 26 | - MIASM_TEST_EXTRA_ARG="-o cparser" 27 | - MIASM_EXTENTED_TESTS_LS_X64="ls_x64" 28 | - MIASM_EXTENTED_TESTS_LOADER="loader" 29 | - MIASM_EXTENTED_TESTS_IR="ir_tests" 30 | before_script: 31 | - pip install -r optional_requirements.txt 32 | # codespell 33 | - "pip install codespell && git ls-files | xargs codespell --ignore-words=.codespell_ignore 2>/dev/null" 34 | # install 35 | - python setup.py build build_ext 36 | - python setup.py install 37 | # extended tests 38 | - git clone https://github.com/cea-sec/miasm-extended-tests 39 | script: 40 | - test -z "$MIASM_TEST_EXTRA_ARG" || (cd test && flags=""; python --version |& grep -q "Python 3" || flags="-W error"; python $flags test_all.py $MIASM_TEST_EXTRA_ARG && git ls-files -o --exclude-standard) 41 | - test -z "$MIASM_EXTENTED_TESTS_LS_x64" || (cd "miasm-extended-tests/$MIASM_EXTENTED_TESTS_LS_X64" && ./run.sh "$TRAVIS_BUILD_DIR") 42 | - test -z "$MIASM_EXTENTED_TESTS_LOADER" || (cd "miasm-extended-tests/$MIASM_EXTENTED_TESTS_LOADER" && ./test_dll.py) 43 | - test -z "$MIASM_EXTENTED_TESTS_IR" || (cd "miasm-extended-tests/$MIASM_EXTENTED_TESTS_IR" && ./run.sh) 44 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # This file is part of Miasm-Docker. 2 | # Copyright 2019 Camille Mougey 3 | # 4 | # Miasm-Docker is free software: you can redistribute it and/or modify it 5 | # under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # Miasm-Docker is distributed in the hope that it will be useful, but WITHOUT 10 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 11 | # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 12 | # License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with Miasm-Docker. If not, see . 16 | 17 | FROM debian:buster 18 | LABEL maintainer="Camille Mougey " 19 | 20 | # Download needed packages 21 | RUN apt-get update && apt-get install -y --no-install-recommends \ 22 | gcc \ 23 | g++ \ 24 | python3 \ 25 | python3-dev \ 26 | python3-pip \ 27 | python3-setuptools \ 28 | python3-wheel \ 29 | && apt-get clean \ 30 | && rm -rf /var/lib/apt/lists/* /root/.cache 31 | 32 | WORKDIR /opt/miasm 33 | 34 | # Install Requirements 35 | COPY requirements.txt /opt/miasm/requirements.txt 36 | RUN pip3 install -r requirements.txt 37 | COPY optional_requirements.txt /opt/miasm/optional_requirements.txt 38 | RUN pip3 install -r optional_requirements.txt 39 | 40 | # Install miasm 41 | COPY README.md /opt/miasm/README.md 42 | COPY setup.py /opt/miasm/setup.py 43 | COPY miasm /opt/miasm/miasm 44 | RUN pip3 install . 45 | 46 | # Get everything else 47 | COPY . /opt/miasm 48 | 49 | # Set user 50 | RUN useradd miasm && \ 51 | chown -Rh miasm /opt/miasm 52 | USER miasm 53 | 54 | # Default cmd 55 | WORKDIR /opt/miasm/test 56 | CMD ["/bin/bash", "-c", "/usr/bin/python3 test_all.py -m"] 57 | -------------------------------------------------------------------------------- /doc/README.md: -------------------------------------------------------------------------------- 1 | # Documentation 2 | 3 | Miasm documentation is organized around the following elements: 4 | 5 | - code comments, as: 6 | ```python 7 | >>> from miasm.core.locationdb import LocationDB 8 | >>> help(LocationDB) 9 | 10 | class LocationDB(builtins.object) 11 | | LocationDB is a "database" of information associated to location. 12 | | 13 | | An entry in a LocationDB is uniquely identified with a LocKey. 14 | | Additional information which can be associated with a LocKey are: 15 | | - an offset (uniq per LocationDB) 16 | | - several names (each are uniqs per LocationDB) 17 | | 18 | | As a schema: 19 | | loc_key 1 <-> 0..1 offset 20 | | 1 <-> 0..n name 21 | | 22 | | >>> loc_db = LocationDB() 23 | | # Add a location with no additional information 24 | | >>> loc_key1 = loc_db.add_location() 25 | | # Add a location with an offset 26 | | >>> loc_key2 = loc_db.add_location(offset=0x1234) 27 | | # Add a location with several names 28 | | >>> loc_key3 = loc_db.add_location(name="first_name") 29 | | >>> loc_db.add_location_name(loc_key3, "second_name") 30 | | # Associate an offset to an existing location 31 | | >>> loc_db.set_location_offset(loc_key3, 0x5678) 32 | | # Remove a name from an existing location 33 | | >>> loc_db.remove_location_name(loc_key3, "second_name") 34 | ... 35 | ``` 36 | 37 | - examples for the main features (see `/example`) 38 | - interactive tutorials (IPython Notebooks) on the following topics: 39 | - Emulation API: [notebook](jitter/jitter.ipynb) 40 | - Miasm's IR bricks known as `Expr`: [notebook](expression/expression.ipynb) 41 | - Lifting from assembly to IR: [notebook](ir/lift.ipynb) 42 | - `LocationDB` usage, the database for locations: [notebook](locationdb/locationdb.ipynb) 43 | - more complex examples through blog posts on [miasm.re](https://miasm.re) 44 | - cheatsheets: 45 | - `Sandbox` and associated emulation options: [cheatsheet](cheatsheets/reminder_sandbox.pdf) 46 | - Disassembler, lifter and associated structures: [cheatsheet](cheatsheets/reminder_disassembler.pdf) 47 | -------------------------------------------------------------------------------- /doc/cheatsheets/reminder_disassembler.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cea-sec/miasm/2a15c60712b326b541d42ac48f372f97023547e7/doc/cheatsheets/reminder_disassembler.pdf -------------------------------------------------------------------------------- /doc/cheatsheets/reminder_sandbox.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cea-sec/miasm/2a15c60712b326b541d42ac48f372f97023547e7/doc/cheatsheets/reminder_sandbox.pdf -------------------------------------------------------------------------------- /doc/logo_miasm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cea-sec/miasm/2a15c60712b326b541d42ac48f372f97023547e7/doc/logo_miasm.png -------------------------------------------------------------------------------- /example/asm/simple.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | from pdb import pm 3 | from pprint import pprint 4 | 5 | from miasm.arch.x86.arch import mn_x86 6 | from miasm.core import parse_asm, asmblock 7 | from miasm.core.locationdb import LocationDB 8 | 9 | # Assemble code 10 | loc_db = LocationDB() 11 | asmcfg = parse_asm.parse_txt( 12 | mn_x86, 32, ''' 13 | main: 14 | MOV EAX, 1 15 | MOV EBX, 2 16 | MOV ECX, 2 17 | MOV DX, 2 18 | 19 | loop: 20 | INC EBX 21 | CMOVZ EAX, EBX 22 | ADD EAX, ECX 23 | JZ loop 24 | RET 25 | ''', 26 | loc_db 27 | ) 28 | 29 | # Set 'main' loc_key's offset 30 | loc_db.set_location_offset(loc_db.get_name_location("main"), 0x0) 31 | 32 | # Spread information and resolve instructions offset 33 | patches = asmblock.asm_resolve_final(mn_x86, asmcfg) 34 | 35 | # Show resolved asmcfg 36 | for block in asmcfg.blocks: 37 | print(block) 38 | 39 | # Print offset -> bytes 40 | pprint(patches) 41 | -------------------------------------------------------------------------------- /example/disasm/dis_binary.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import sys 3 | from miasm.analysis.binary import Container 4 | from miasm.analysis.machine import Machine 5 | from miasm.core.locationdb import LocationDB 6 | 7 | fdesc = open(sys.argv[1], 'rb') 8 | loc_db = LocationDB() 9 | 10 | # The Container will provide a *bin_stream*, bytes source for the disasm engine 11 | # It will provide a view from a PE or an ELF. 12 | cont = Container.from_stream(fdesc, loc_db) 13 | 14 | # The Machine, instantiated with the detected architecture, will provide tools 15 | # (disassembler, etc.) to work with this architecture 16 | machine = Machine(cont.arch) 17 | 18 | # Instantiate a disassembler engine, using the previous bin_stream and its 19 | # associated location DB. The assembly listing will use the binary symbols 20 | mdis = machine.dis_engine(cont.bin_stream, loc_db=cont.loc_db) 21 | 22 | # Run a recursive traversal disassembling from the entry point 23 | # (do not follow sub functions by default) 24 | addr = cont.entry_point 25 | asmcfg = mdis.dis_multiblock(addr) 26 | 27 | # Display each basic blocks 28 | for block in asmcfg.blocks: 29 | print(block) 30 | 31 | # Output control flow graph in a dot file 32 | open('bin_cfg.dot', 'w').write(asmcfg.dot()) 33 | -------------------------------------------------------------------------------- /example/disasm/dis_binary_lift.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import sys 3 | from future.utils import viewvalues 4 | from miasm.analysis.binary import Container 5 | from miasm.analysis.machine import Machine 6 | from miasm.core.locationdb import LocationDB 7 | 8 | ##################################### 9 | # Common section from dis_binary.py # 10 | ##################################### 11 | 12 | fdesc = open(sys.argv[1], 'rb') 13 | loc_db = LocationDB() 14 | 15 | cont = Container.from_stream(fdesc, loc_db) 16 | 17 | machine = Machine(cont.arch) 18 | 19 | mdis = machine.dis_engine(cont.bin_stream, loc_db=cont.loc_db) 20 | 21 | addr = cont.entry_point 22 | asmcfg = mdis.dis_multiblock(addr) 23 | 24 | ##################################### 25 | # End common section # 26 | ##################################### 27 | 28 | # Get a Lifter 29 | lifter = machine.lifter(mdis.loc_db) 30 | 31 | # Get the IR of the asmcfg 32 | ircfg = lifter.new_ircfg_from_asmcfg(asmcfg) 33 | 34 | # Display each IR basic blocks 35 | for irblock in viewvalues(ircfg.blocks): 36 | print(irblock) 37 | 38 | # Output ir control flow graph in a dot file 39 | open('bin_ir_cfg.dot', 'w').write(ircfg.dot()) 40 | -------------------------------------------------------------------------------- /example/disasm/dis_binary_lift_model_call.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import sys 3 | 4 | from future.utils import viewvalues 5 | from miasm.analysis.binary import Container 6 | from miasm.analysis.machine import Machine 7 | from miasm.core.locationdb import LocationDB 8 | 9 | ##################################### 10 | # Common section from dis_binary.py # 11 | ##################################### 12 | 13 | fdesc = open(sys.argv[1], 'rb') 14 | loc_db = LocationDB() 15 | 16 | cont = Container.from_stream(fdesc, loc_db) 17 | 18 | machine = Machine(cont.arch) 19 | 20 | mdis = machine.dis_engine(cont.bin_stream, loc_db=cont.loc_db) 21 | 22 | addr = cont.entry_point 23 | asmcfg = mdis.dis_multiblock(addr) 24 | 25 | ##################################### 26 | # End common section # 27 | ##################################### 28 | 29 | # Get an IRA converter 30 | # The sub call are modelised by default operators 31 | # call_func_ret and call_func_stack 32 | lifter = machine.lifter_model_call(mdis.loc_db) 33 | 34 | # Get the IR of the asmcfg 35 | ircfg = lifter.new_ircfg_from_asmcfg(asmcfg) 36 | 37 | # Display each IR basic blocks 38 | for irblock in viewvalues(ircfg.blocks): 39 | print(irblock) 40 | 41 | # Output ir control flow graph in a dot file 42 | open('bin_lifter_model_call_cfg.dot', 'w').write(ircfg.dot()) 43 | -------------------------------------------------------------------------------- /example/disasm/dis_x86_string.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | from miasm.analysis.binary import Container 3 | from miasm.analysis.machine import Machine 4 | from miasm.core.locationdb import LocationDB 5 | 6 | # The Container will provide a *bin_stream*, bytes source for the disasm engine 7 | loc_db = LocationDB() 8 | cont = Container.from_string( 9 | b"\x83\xf8\x10\x74\x07\x89\xc6\x0f\x47\xc3\xeb\x08\x89\xc8\xe8\x31\x33\x22\x11\x40\xc3", 10 | loc_db 11 | ) 12 | 13 | # Instantiate a x86 32 bit architecture 14 | machine = Machine("x86_32") 15 | 16 | # Instantiate a disassembler engine, using the previous bin_stream and its 17 | # associated location DB. 18 | mdis = machine.dis_engine(cont.bin_stream, loc_db=loc_db) 19 | 20 | # Run a recursive traversal disassembling from address 0 21 | asmcfg = mdis.dis_multiblock(0) 22 | 23 | # Display each basic blocks 24 | for block in asmcfg.blocks: 25 | print(block) 26 | 27 | # Output control flow graph in a dot file 28 | open('str_cfg.dot', 'w').write(asmcfg.dot()) 29 | -------------------------------------------------------------------------------- /example/disasm/single_instr.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | from miasm.arch.x86.arch import mn_x86 3 | from miasm.arch.x86.regs import EDX 4 | from miasm.core.locationdb import LocationDB 5 | 6 | loc_db = LocationDB() 7 | l = mn_x86.fromstring('MOV EAX, EBX', loc_db, 32) 8 | print("instruction:", l) 9 | print("arg:", l.args[0]) 10 | x = mn_x86.asm(l) 11 | print(x) 12 | l.args[0] = EDX 13 | y = mn_x86.asm(l) 14 | print(y) 15 | print(mn_x86.dis(y[0], 32)) 16 | -------------------------------------------------------------------------------- /example/expression/asm_to_ir.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | from pdb import pm 3 | 4 | from future.utils import viewitems 5 | 6 | from miasm.arch.x86.arch import mn_x86 7 | from miasm.core import parse_asm 8 | from miasm.expression.expression import * 9 | from miasm.core import asmblock 10 | from miasm.arch.x86.lifter_model_call import LifterModelCall_x86_32 11 | from miasm.analysis.data_flow import DeadRemoval 12 | from miasm.core.locationdb import LocationDB 13 | 14 | 15 | # First, asm code 16 | loc_db = LocationDB() 17 | asmcfg = parse_asm.parse_txt( 18 | mn_x86, 32, ''' 19 | main: 20 | MOV EAX, 1 21 | MOV EBX, 2 22 | MOV ECX, 2 23 | MOV DX, 2 24 | 25 | loop: 26 | INC EBX 27 | CMOVZ EAX, EBX 28 | ADD EAX, ECX 29 | JZ loop 30 | RET 31 | ''', 32 | loc_db 33 | ) 34 | 35 | 36 | loc_db.set_location_offset(loc_db.get_name_location("main"), 0x0) 37 | for block in asmcfg.blocks: 38 | print(block) 39 | 40 | 41 | print("symbols:") 42 | print(loc_db) 43 | patches = asmblock.asm_resolve_final(mn_x86, asmcfg) 44 | 45 | # Translate to IR 46 | lifter = LifterModelCall_x86_32(loc_db) 47 | ircfg = lifter.new_ircfg_from_asmcfg(asmcfg) 48 | deadrm = DeadRemoval(lifter) 49 | 50 | 51 | # Display IR 52 | for lbl, irblock in viewitems(ircfg.blocks): 53 | print(irblock) 54 | 55 | # Dead propagation 56 | open('graph.dot', 'w').write(ircfg.dot()) 57 | print('*' * 80) 58 | deadrm(ircfg) 59 | open('graph2.dot', 'w').write(ircfg.dot()) 60 | 61 | # Display new IR 62 | print('new ir blocks') 63 | for lbl, irblock in viewitems(ircfg.blocks): 64 | print(irblock) 65 | -------------------------------------------------------------------------------- /example/expression/basic_op.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | from miasm.expression.expression import * 3 | 4 | print(""" 5 | Simple expression manipulation demo 6 | """) 7 | 8 | # define 2 ID 9 | a = ExprId('eax', 32) 10 | b = ExprId('ebx', 32) 11 | print(a, b) 12 | # eax ebx 13 | 14 | # add those ID 15 | c = ExprOp('+', a, b) 16 | print(c) 17 | # (eax + ebx) 18 | 19 | # + automatically generates ExprOp('+', a, b) 20 | c = a + b 21 | print(c) 22 | # (eax + ebx) 23 | 24 | # ax is a slice of eax 25 | ax = a[:16] 26 | print(ax) 27 | # eax[0:16] 28 | 29 | # memory deref 30 | d = ExprMem(c, 32) 31 | print(d) 32 | # @32[(eax + ebx)] 33 | -------------------------------------------------------------------------------- /example/expression/basic_simplification.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | from miasm.expression.expression import * 3 | from miasm.expression.simplifications import expr_simp 4 | 5 | print(""" 6 | Simple expression simplification demo 7 | """) 8 | 9 | 10 | a = ExprId('eax', 32) 11 | b = ExprId('ebx', 32) 12 | 13 | exprs = [a + b - a, 14 | ExprInt(0x12, 32) + ExprInt(0x30, 32) - a, 15 | ExprCompose(a[:8], a[8:16])] 16 | 17 | for e in exprs: 18 | print('*' * 40) 19 | print('original expression:', e) 20 | print("simplified:", expr_simp(e)) 21 | -------------------------------------------------------------------------------- /example/expression/constant_propagation.py: -------------------------------------------------------------------------------- 1 | """ 2 | Example of "constant expression" propagation. 3 | A "constant expression" is an expression based on constants or init regs. 4 | 5 | """ 6 | 7 | from argparse import ArgumentParser 8 | 9 | from miasm.analysis.machine import Machine 10 | from miasm.analysis.binary import Container 11 | from miasm.analysis.cst_propag import propagate_cst_expr 12 | from miasm.analysis.data_flow import DeadRemoval, \ 13 | merge_blocks, remove_empty_assignblks 14 | from miasm.expression.simplifications import expr_simp 15 | from miasm.core.locationdb import LocationDB 16 | 17 | 18 | 19 | parser = ArgumentParser(description="Constant expression propagation") 20 | parser.add_argument('filename', help="File to analyze") 21 | parser.add_argument('address', help="Starting address for disassembly engine") 22 | parser.add_argument('-s', "--simplify", action="store_true", 23 | help="Apply simplifications rules (liveness, graph simplification, ...)") 24 | 25 | args = parser.parse_args() 26 | 27 | 28 | machine = Machine("x86_32") 29 | 30 | loc_db = LocationDB() 31 | cont = Container.from_stream(open(args.filename, 'rb'), loc_db) 32 | mdis = machine.dis_engine(cont.bin_stream, loc_db=loc_db) 33 | lifter = machine.lifter_model_call(mdis.loc_db) 34 | addr = int(args.address, 0) 35 | deadrm = DeadRemoval(lifter) 36 | 37 | asmcfg = mdis.dis_multiblock(addr) 38 | ircfg = lifter.new_ircfg_from_asmcfg(asmcfg) 39 | entry_points = set([mdis.loc_db.get_offset_location(addr)]) 40 | 41 | init_infos = lifter.arch.regs.regs_init 42 | cst_propag_link = propagate_cst_expr(lifter, ircfg, addr, init_infos) 43 | 44 | if args.simplify: 45 | ircfg.simplify(expr_simp) 46 | modified = True 47 | while modified: 48 | modified = False 49 | modified |= deadrm(ircfg) 50 | modified |= remove_empty_assignblks(ircfg) 51 | modified |= merge_blocks(ircfg, entry_points) 52 | 53 | 54 | open("%s.propag.dot" % args.filename, 'w').write(ircfg.dot()) 55 | -------------------------------------------------------------------------------- /example/expression/expr_c.py: -------------------------------------------------------------------------------- 1 | """ 2 | Parse C expression to access variables and retrieve information: 3 | * Miasm expression to access this variable 4 | * variable type 5 | """ 6 | from __future__ import print_function 7 | 8 | from miasm.core.ctypesmngr import CTypeStruct, CAstTypes, CTypePtr 9 | from miasm.arch.x86.ctype import CTypeAMD64_unk 10 | from miasm.core.objc import CTypesManagerNotPacked, CHandler 11 | from miasm.expression.expression import ExprId 12 | 13 | 14 | """ 15 | C manipulation example 16 | """ 17 | 18 | # Digest C information 19 | text = """ 20 | struct line { 21 | char color[20]; 22 | int size; 23 | }; 24 | 25 | struct rectangle { 26 | unsigned int width; 27 | unsigned int length; 28 | struct line* line; 29 | }; 30 | """ 31 | 32 | # Type manager for x86 64: structures not packed 33 | base_types = CTypeAMD64_unk() 34 | types_ast = CAstTypes() 35 | 36 | # Add C types definition 37 | types_ast.add_c_decl(text) 38 | 39 | types_mngr = CTypesManagerNotPacked(types_ast, base_types) 40 | 41 | # Create the ptr variable with type "struct rectangle*" 42 | ptr_rectangle = types_mngr.get_objc(CTypePtr(CTypeStruct('rectangle'))) 43 | 44 | ptr = ExprId('ptr', 64) 45 | c_context = {ptr.name: ptr_rectangle} 46 | mychandler = CHandler(types_mngr, C_types=c_context) 47 | 48 | # Parse some C accesses 49 | c_acceses = ["ptr->width", 50 | "ptr->length", 51 | "ptr->line", 52 | "ptr->line->color", 53 | "ptr->line->color[3]", 54 | "ptr->line->size" 55 | ] 56 | 57 | for c_str in c_acceses: 58 | expr = mychandler.c_to_expr(c_str) 59 | c_type = mychandler.c_to_type(c_str) 60 | print('C access:', c_str) 61 | print('\tExpr:', expr) 62 | print('\tType:', c_type) 63 | -------------------------------------------------------------------------------- /example/expression/expr_grapher.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | from miasm.expression.expression import * 4 | 5 | print("Simple Expression grapher demo") 6 | 7 | a = ExprId("A", 32) 8 | b = ExprId("B", 32) 9 | c = ExprId("C", 32) 10 | d = ExprId("D", 32) 11 | m = ExprMem(a + b + c + a, 32) 12 | 13 | e1 = ExprCompose(a + b - ((c * a) // m) | b, a + m) 14 | e2 = ExprInt(15, 64) 15 | e = ExprCond(d, e1, e2)[0:32] 16 | 17 | print("[+] Expression:") 18 | print(e) 19 | 20 | g = e.graph() 21 | print("[+] Graph:") 22 | print(g.dot()) 23 | -------------------------------------------------------------------------------- /example/expression/expr_random.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | from builtins import range 3 | import string 4 | import random 5 | 6 | from miasm.expression.expression_helper import ExprRandom 7 | 8 | print("Simple expression generator\n") 9 | 10 | depth = 8 11 | seed = 0 12 | random.seed(seed) 13 | 14 | print("- An ID:") 15 | print(ExprRandom.identifier()) 16 | print("- A number:") 17 | print(ExprRandom.number()) 18 | 19 | print("- 3 expressions (without cleaning expression cache):") 20 | for i in range(3): 21 | print("\t%s\n" % ExprRandom.get(depth=depth, clean=False)) 22 | 23 | class ExprRandom_NoPerfect_NoReuse_UppercaseIdent(ExprRandom): 24 | """ExprRandom extension with: 25 | - perfect tree disabled 26 | - element reuse disabled 27 | - identifiers uppercased 28 | """ 29 | 30 | perfect_tree = False 31 | reuse_element = False 32 | identifier_charset = string.ascii_uppercase 33 | 34 | print("- 3 expressions with a custom generator:") 35 | for i in range(3): 36 | print("\t%s\n" % ExprRandom_NoPerfect_NoReuse_UppercaseIdent.get(depth=depth)) 37 | -------------------------------------------------------------------------------- /example/expression/expr_translate.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import random 3 | 4 | from future.utils import viewitems 5 | 6 | from miasm.expression.expression import * 7 | from miasm.expression.expression_helper import ExprRandom 8 | from miasm.ir.translators import Translator 9 | 10 | random.seed(0) 11 | 12 | class ExprRandom_OpSubRange(ExprRandom): 13 | operations_by_args_number = {1: ["-"], 14 | 2: ["<<", ">>",], 15 | "2+": ["+", "*", "&", "|", "^"], 16 | } 17 | 18 | 19 | print("[+] Compute a random expression:") 20 | expr = ExprRandom_OpSubRange.get(depth=8) 21 | print("-> %s" % expr) 22 | print() 23 | 24 | target_exprs = {lang:Translator.to_language(lang).from_expr(expr) 25 | for lang in Translator.available_languages()} 26 | for target_lang, target_expr in viewitems(target_exprs): 27 | print("[+] Translate in %s:" % target_lang) 28 | print(target_expr) 29 | print() 30 | 31 | print("[+] Eval in Python:") 32 | def memory(addr, size): 33 | ret = random.randint(0, (1 << size) - 1) 34 | print("Memory access: @0x%x -> 0x%x" % (addr, ret)) 35 | return ret 36 | 37 | for expr_id in expr.get_r(mem_read=True): 38 | if isinstance(expr_id, ExprId): 39 | value = random.randint(0, (1 << expr_id.size) - 1) 40 | print("Declare var: %s = 0x%x" % (expr_id.name, value)) 41 | globals()[expr_id.name] = value 42 | 43 | print("-> 0x%x" % eval(target_exprs["Python"])) 44 | 45 | print("[+] Validate the Miasm syntax rebuilding") 46 | exprRebuild = eval(target_exprs["Miasm"]) 47 | assert(expr == exprRebuild) 48 | 49 | 50 | a = ExprId("a", 32) 51 | b = ExprId("b", 32) 52 | cst1 = ExprInt(1, 32) 53 | eq_test = ExprOp("==", a, b + cst1) 54 | 55 | for lang in Translator.available_languages(): 56 | translator = Translator.to_language(lang) 57 | print("Translate to %s:" % lang) 58 | print(translator.from_expr(eq_test)) 59 | -------------------------------------------------------------------------------- /example/expression/get_read_write.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | from future.utils import viewitems 4 | 5 | from miasm.arch.x86.arch import mn_x86 6 | from miasm.expression.expression import get_rw 7 | from miasm.arch.x86.lifter_model_call import LifterModelCall_x86_32 8 | from miasm.core.locationdb import LocationDB 9 | 10 | loc_db = LocationDB() 11 | 12 | 13 | print(""" 14 | Simple expression manipulation demo. 15 | Get read/written registers for a given instruction 16 | """) 17 | 18 | arch = mn_x86 19 | lifter = LifterModelCall_x86_32(loc_db) 20 | ircfg = lifter.new_ircfg() 21 | instr = arch.fromstring('LODSB', loc_db, 32) 22 | instr.offset, instr.l = 0, 15 23 | lifter.add_instr_to_ircfg(instr, ircfg) 24 | 25 | print('*' * 80) 26 | for lbl, irblock in viewitems(ircfg.blocks): 27 | print(irblock) 28 | for assignblk in irblock: 29 | rw = assignblk.get_rw() 30 | for dst, reads in viewitems(rw): 31 | print('read: ', [str(x) for x in reads]) 32 | print('written:', dst) 33 | print() 34 | 35 | open('graph_instr.dot', 'w').write(ircfg.dot()) 36 | -------------------------------------------------------------------------------- /example/expression/simplification_add.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | import miasm.expression.expression as m2_expr 4 | from miasm.expression.simplifications import ExpressionSimplifier 5 | 6 | # Creates an expression simplifier that (by default) applies no simplifications. 7 | # Other instances with simplifications enabled by default can be found in `expressions/simplifications.py`. 8 | simp = ExpressionSimplifier() 9 | 10 | print(""" 11 | Expression simplification demo: Adding a simplification: 12 | a + a + a == a * 3 13 | 14 | More detailed examples can be found in miasm/expression/simplification*. 15 | """) 16 | 17 | 18 | # Define the simplification method 19 | ## @expr_simp is the current expression simplifier instance 20 | ## (for recursive simplifications) 21 | ## @expr is the expression to (perhaps) simplify 22 | def simp_add_mul(expr_simp, expr): 23 | "Naive Simplification: a + a + a == a * 3" 24 | 25 | # Match the expected form 26 | ## isinstance(expr, m2_expr.ExprOp) is not needed: simplifications are 27 | ## attached to expression types 28 | if expr.op == "+" and \ 29 | len(expr.args) == 3 and \ 30 | expr.args.count(expr.args[0]) == len(expr.args): 31 | 32 | # Effective simplification 33 | return m2_expr.ExprOp("*", expr.args[0], 34 | m2_expr.ExprInt(3, expr.args[0].size)) 35 | else: 36 | # Do not simplify 37 | return expr 38 | 39 | 40 | a = m2_expr.ExprId('a', 32) 41 | base_expr = a + a + a 42 | print("Without adding the simplification:") 43 | print("\t%s = %s" % (base_expr, simp(base_expr))) 44 | 45 | # Enable pass 46 | simp.enable_passes({m2_expr.ExprOp: [simp_add_mul]}) 47 | 48 | print("After adding the simplification:") 49 | print("\t%s = %s" % (base_expr, simp(base_expr))) 50 | 51 | assert simp(base_expr) == m2_expr.ExprOp("*", a, 52 | m2_expr.ExprInt(3, a.size)) 53 | -------------------------------------------------------------------------------- /example/expression/simplification_tools.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | from miasm.expression.expression import * 3 | from pdb import pm 4 | 5 | print(""" 6 | Expression simplification demo. 7 | (and regression test) 8 | """) 9 | 10 | 11 | a = ExprId('a', 32) 12 | b = ExprId('b', 32) 13 | c = ExprId('c', 32) 14 | d = ExprId('d', 32) 15 | e = ExprId('e', 32) 16 | 17 | m = ExprMem(a, 32) 18 | s = a[:8] 19 | 20 | i1 = ExprInt(0x1, 32) 21 | i2 = ExprInt(0x2, 32) 22 | cc = ExprCond(a, b, c) 23 | 24 | o = ExprCompose(a[8:16], a[:8]) 25 | 26 | o2 = ExprCompose(a[8:16], a[:8]) 27 | 28 | l = [a[:8], b[:8], c[:8], m[:8], s, i1[:8], i2[:8], o[:8]] 29 | l2 = l[::-1] 30 | 31 | 32 | x = ExprMem(a + b + ExprInt(0x42, 32), 32) 33 | 34 | 35 | def replace_expr(e): 36 | dct = {c + ExprInt(0x42, 32): d, 37 | a + b: c, } 38 | if e in dct: 39 | return dct[e] 40 | return e 41 | 42 | 43 | print(x) 44 | y = x.visit(replace_expr) 45 | print(y) 46 | print(x.copy()) 47 | print(y.copy()) 48 | print(y == y.copy()) 49 | print(repr(y), repr(y.copy())) 50 | 51 | 52 | z = ExprCompose(a[5:5 + 8], b[:16], x[:8]) 53 | print(z) 54 | print(z.copy()) 55 | print(z[:31].copy().visit(replace_expr)) 56 | 57 | print('replace') 58 | print(x.replace_expr({c + ExprInt(0x42, 32): d, 59 | a + b: c, })) 60 | print(z.replace_expr({c + ExprInt(0x42, 32): d, 61 | a + b: c, })) 62 | 63 | 64 | u = z.copy() 65 | print(u) 66 | -------------------------------------------------------------------------------- /example/ida/rpyc_ida.py: -------------------------------------------------------------------------------- 1 | """rpyc IDA server""" 2 | from __future__ import print_function 3 | 4 | from rpyc.utils.server import OneShotServer 5 | from rpyc.core import SlaveService 6 | 7 | 8 | 9 | def serve_threaded(hostname="localhost", port=4455): 10 | """This will run a rpyc server in IDA, so a custom script client will be 11 | able to access IDA api. 12 | WARNING: IDA will be locked until the client script terminates. 13 | """ 14 | 15 | print('Running server') 16 | server = OneShotServer(SlaveService, hostname=hostname, 17 | port=port, reuse_addr=True, ipv6=False, 18 | authenticator=None, 19 | auto_register=False) 20 | server.logger.quiet = False 21 | 22 | return server.start() 23 | 24 | 25 | if __name__ == "__main__": 26 | serve_threaded() 27 | -------------------------------------------------------------------------------- /example/jitter/arm.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python2 2 | #-*- coding:utf-8 -*- 3 | from __future__ import print_function 4 | import logging 5 | from pdb import pm 6 | 7 | from miasm.analysis.sandbox import Sandbox_Linux_arml 8 | from miasm.core.locationdb import LocationDB 9 | 10 | # Get arguments 11 | parser = Sandbox_Linux_arml.parser(description="""Sandbox an elf binary with arm 12 | engine (ex: jit_arm.py samples/md5_arm -a A684)""") 13 | parser.add_argument("filename", help="ELF Filename") 14 | parser.add_argument('-v', "--verbose", help="verbose mode", action="store_true") 15 | options = parser.parse_args() 16 | 17 | # Prepare the sandbox 18 | loc_db = LocationDB() 19 | sb = Sandbox_Linux_arml(loc_db, options.filename, options, globals()) 20 | 21 | # Handle 'verbose' option 22 | if options.verbose is True: 23 | logging.basicConfig(level=logging.INFO) 24 | else: 25 | logging.basicConfig(level=logging.WARNING) 26 | 27 | if options.verbose is True: 28 | print(sb.jitter.vm) 29 | 30 | # Run the code 31 | sb.run() 32 | -------------------------------------------------------------------------------- /example/jitter/arm_sc.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python2 2 | #-*- coding:utf-8 -*- 3 | from miasm.core.utils import int_to_byte 4 | from miasm.analysis.sandbox import Sandbox_Linux_armb_str 5 | from miasm.analysis.sandbox import Sandbox_Linux_arml_str 6 | from miasm.loader.strpatchwork import StrPatchwork 7 | from miasm.core.locationdb import LocationDB 8 | 9 | from pdb import pm 10 | 11 | parser = Sandbox_Linux_arml_str.parser(description="""Sandbox an elf binary with arm engine 12 | (ex: jit_arm_sc.py example/demo_arm_l.bin)""") 13 | parser.add_argument("filename", help="string Filename") 14 | parser.add_argument("endianness", help="endianness [b/l]") 15 | parser.add_argument('-v', "--verbose", 16 | help="verbose mode", action="store_true") 17 | 18 | options = parser.parse_args() 19 | 20 | if options.endianness == 'b': 21 | sandbox = Sandbox_Linux_armb_str 22 | elif options.endianness == 'l': 23 | sandbox = Sandbox_Linux_arml_str 24 | else: 25 | raise ValueError("Bad endianness!") 26 | 27 | loc_db = LocationDB() 28 | sb = sandbox(loc_db, options.filename, options, globals()) 29 | 30 | if options.address is None: 31 | raise ValueError('invalid address') 32 | 33 | sb.run() 34 | 35 | # test correct de xor 36 | start = sb.jitter.cpu.R0 37 | stop = sb.jitter.cpu.R1 38 | s = sb.jitter.vm.get_mem(start, stop-start) 39 | s = StrPatchwork(s) 40 | for i, c in enumerate(s): 41 | s[i] = int_to_byte(ord(c)^0x11) 42 | s = bytes(s) 43 | assert(s == b"test string\x00") 44 | 45 | 46 | -------------------------------------------------------------------------------- /example/jitter/sandbox_call.py: -------------------------------------------------------------------------------- 1 | """This example illustrate the Sandbox.call API, for direct call of a given 2 | function""" 3 | 4 | from miasm.analysis.sandbox import Sandbox_Linux_arml 5 | from miasm.analysis.binary import Container 6 | from miasm.os_dep.linux_stdlib import linobjs 7 | from miasm.core.utils import hexdump 8 | from miasm.core.locationdb import LocationDB 9 | 10 | # Parse arguments 11 | parser = Sandbox_Linux_arml.parser(description="ELF sandboxer") 12 | parser.add_argument("filename", help="ELF Filename") 13 | options = parser.parse_args() 14 | 15 | loc_db = LocationDB() 16 | sb = Sandbox_Linux_arml(loc_db, options.filename, options, globals()) 17 | 18 | with open(options.filename, "rb") as fdesc: 19 | cont = Container.from_stream(fdesc, loc_db) 20 | loc_key = cont.loc_db.get_name_location("md5_starts") 21 | addr_to_call = cont.loc_db.get_location_offset(loc_key) 22 | 23 | # Calling md5_starts(malloc(0x64)) 24 | addr = linobjs.heap.alloc(sb.jitter, 0x64) 25 | sb.call(addr_to_call, addr) 26 | hexdump(sb.jitter.vm.get_mem(addr, 0x64)) 27 | -------------------------------------------------------------------------------- /example/jitter/sandbox_elf_aarch64l.py: -------------------------------------------------------------------------------- 1 | import logging 2 | from pdb import pm 3 | from miasm.analysis.sandbox import Sandbox_Linux_aarch64l 4 | from miasm.core.locationdb import LocationDB 5 | from miasm.jitter.jitload import log_func 6 | 7 | # Insert here user defined methods 8 | 9 | # Parse arguments 10 | parser = Sandbox_Linux_aarch64l.parser(description="ELF sandboxer") 11 | parser.add_argument("filename", help="ELF Filename") 12 | options = parser.parse_args() 13 | 14 | # Create sandbox 15 | loc_db = LocationDB() 16 | sb = Sandbox_Linux_aarch64l(loc_db, options.filename, options, globals()) 17 | 18 | log_func.setLevel(logging.ERROR) 19 | 20 | # Run 21 | sb.run() 22 | 23 | assert(sb.jitter.running is False) 24 | -------------------------------------------------------------------------------- /example/jitter/sandbox_elf_ppc32.py: -------------------------------------------------------------------------------- 1 | import os 2 | from pdb import pm 3 | from miasm.analysis.sandbox import Sandbox_Linux_ppc32b 4 | from miasm.core.locationdb import LocationDB 5 | from miasm.jitter.csts import * 6 | from miasm.jitter.jitload import log_func 7 | import logging 8 | 9 | # Insert here user defined methods 10 | 11 | # Parse arguments 12 | parser = Sandbox_Linux_ppc32b.parser(description="ELF sandboxer") 13 | parser.add_argument("filename", help="ELF Filename") 14 | options = parser.parse_args() 15 | 16 | # Create sandbox 17 | loc_db = LocationDB() 18 | sb = Sandbox_Linux_ppc32b(loc_db, options.filename, options, globals()) 19 | log_func.setLevel(logging.ERROR) 20 | 21 | sb.run() 22 | -------------------------------------------------------------------------------- /example/jitter/sandbox_pe_x86_32.py: -------------------------------------------------------------------------------- 1 | from pdb import pm 2 | from miasm.analysis.sandbox import Sandbox_Win_x86_32 3 | from miasm.core.locationdb import LocationDB 4 | # Insert here user defined methods 5 | 6 | # Parse arguments 7 | parser = Sandbox_Win_x86_32.parser(description="PE sandboxer") 8 | parser.add_argument("filename", help="PE Filename") 9 | options = parser.parse_args() 10 | 11 | # Create sandbox 12 | loc_db = LocationDB() 13 | sb = Sandbox_Win_x86_32(loc_db, options.filename, options, globals()) 14 | 15 | # Run 16 | sb.run() 17 | 18 | assert(sb.jitter.running is False) 19 | -------------------------------------------------------------------------------- /example/jitter/sandbox_pe_x86_64.py: -------------------------------------------------------------------------------- 1 | from pdb import pm 2 | from miasm.analysis.sandbox import Sandbox_Win_x86_64 3 | from miasm.core.locationdb import LocationDB 4 | 5 | # Insert here user defined methods 6 | 7 | # Parse arguments 8 | parser = Sandbox_Win_x86_64.parser(description="PE sandboxer") 9 | parser.add_argument("filename", help="PE Filename") 10 | options = parser.parse_args() 11 | 12 | # Create sandbox 13 | loc_db = LocationDB() 14 | sb = Sandbox_Win_x86_64(loc_db, options.filename, options, globals()) 15 | 16 | # Run 17 | sb.run() 18 | 19 | assert(sb.jitter.running is False) 20 | -------------------------------------------------------------------------------- /example/jitter/trace.py: -------------------------------------------------------------------------------- 1 | """ 2 | This example demonstrates two instrumentation possibility: 3 | - instrumentation executed at each instruction 4 | - instrumentation on jitter behavior (here, memory tracking) 5 | 6 | Note: for better performance, one can also extend Codegen to produce 7 | instrumentation at the C / LLVM level 8 | """ 9 | from __future__ import print_function 10 | 11 | import os 12 | import time 13 | from pdb import pm 14 | from miasm.analysis.sandbox import Sandbox_Linux_arml 15 | from miasm.jitter.emulatedsymbexec import EmulatedSymbExec 16 | from miasm.jitter.jitcore_python import JitCore_Python 17 | from miasm.core.locationdb import LocationDB 18 | 19 | # Function called at each instruction 20 | instr_count = 0 21 | def instr_hook(jitter): 22 | global instr_count 23 | instr_count += 1 24 | return True 25 | 26 | # Extension of the Python jitter to track memory accesses 27 | class ESETrackMemory(EmulatedSymbExec): 28 | """Emulated symb exec with memory access tracking""" 29 | 30 | def mem_read(self, expr_mem): 31 | value = super(ESETrackMemory, self).mem_read(expr_mem) 32 | print("Read %s: %s" % (expr_mem, value)) 33 | return value 34 | 35 | def mem_write(self, dest, data): 36 | print("Write %s: %s" % (dest, data)) 37 | return super(ESETrackMemory, self).mem_write(dest, data) 38 | 39 | # Parse arguments 40 | parser = Sandbox_Linux_arml.parser(description="Tracer") 41 | parser.add_argument("filename", help="ELF Filename") 42 | options = parser.parse_args() 43 | 44 | # Use our memory tracker 45 | JitCore_Python.SymbExecClass = ESETrackMemory 46 | 47 | # Create sandbox, forcing Python jitter 48 | options.jitter = "python" 49 | loc_db = LocationDB() 50 | sb = Sandbox_Linux_arml(loc_db, options.filename, options, globals()) 51 | 52 | # Force jit one instr per call, and register our callback 53 | sb.jitter.jit.set_options(jit_maxline=1, max_exec_per_call=1) 54 | sb.jitter.exec_cb = instr_hook 55 | 56 | # Run 57 | start_time = time.time() 58 | sb.run() 59 | stop_time = time.time() 60 | 61 | assert sb.jitter.running is False 62 | print("Instr speed: %02.f / sec" % (instr_count / (stop_time - start_time))) 63 | -------------------------------------------------------------------------------- /example/jitter/unpack_generic.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import os 3 | import logging 4 | from miasm.analysis.sandbox import Sandbox_Win_x86_32 5 | from miasm.jitter.loader.pe import vm2pe, ImpRecStrategy 6 | from miasm.core.locationdb import LocationDB 7 | from miasm.jitter.jitload import JitterException 8 | 9 | parser = Sandbox_Win_x86_32.parser(description="Generic & dummy unpacker") 10 | parser.add_argument("filename", help="PE Filename") 11 | parser.add_argument("--oep", help="Stop and dump if this address is reached") 12 | parser.add_argument('-v', "--verbose", 13 | help="verbose mode", action="store_true") 14 | options = parser.parse_args() 15 | 16 | loc_db = LocationDB() 17 | sb = Sandbox_Win_x86_32( 18 | loc_db, options.filename, options, globals(), 19 | parse_reloc=False 20 | ) 21 | 22 | if options.verbose is True: 23 | logging.basicConfig(level=logging.INFO) 24 | else: 25 | logging.basicConfig(level=logging.WARNING) 26 | 27 | if options.verbose is True: 28 | print(sb.jitter.vm) 29 | 30 | def stop(jitter): 31 | logging.info('User provided OEP reached') 32 | # Stop execution 33 | return False 34 | 35 | if options.oep: 36 | # Set callbacks 37 | sb.jitter.add_breakpoint(int(options.oep, 0), stop) 38 | 39 | # Run until an error is encountered - IT IS UNLIKELY THE ORIGINAL ENTRY POINT 40 | try: 41 | sb.run() 42 | except (JitterException, ValueError) as e: 43 | logging.exception(e) 44 | 45 | out_fname = "%s.dump" % (options.filename) 46 | 47 | # Try a generic approach to rebuild the Import Table 48 | imprec = ImpRecStrategy(sb.jitter, sb.libs, 32) 49 | imprec.recover_import() 50 | 51 | # Rebuild the PE and dump it 52 | print("Dump to %s" % out_fname) 53 | vm2pe(sb.jitter, out_fname, libs=sb.libs, e_orig=sb.pe) 54 | -------------------------------------------------------------------------------- /example/jitter/x86_32.py: -------------------------------------------------------------------------------- 1 | from argparse import ArgumentParser 2 | from miasm.jitter.csts import PAGE_READ, PAGE_WRITE 3 | from miasm.analysis.machine import Machine 4 | from miasm.core.locationdb import LocationDB 5 | 6 | from pdb import pm 7 | 8 | parser = ArgumentParser(description="x86 32 basic Jitter") 9 | parser.add_argument("filename", help="x86 32 shellcode filename") 10 | parser.add_argument("-j", "--jitter", 11 | help="Jitter engine (default is 'gcc')", 12 | default="gcc") 13 | args = parser.parse_args() 14 | 15 | def code_sentinelle(jitter): 16 | jitter.running = False 17 | jitter.pc = 0 18 | return True 19 | 20 | loc_db = LocationDB() 21 | 22 | myjit = Machine("x86_32").jitter(loc_db, args.jitter) 23 | myjit.init_stack() 24 | 25 | data = open(args.filename, 'rb').read() 26 | run_addr = 0x40000000 27 | myjit.vm.add_memory_page(run_addr, PAGE_READ | PAGE_WRITE, data) 28 | 29 | myjit.set_trace_log() 30 | myjit.push_uint32_t(0x1337beef) 31 | 32 | myjit.add_breakpoint(0x1337beef, code_sentinelle) 33 | 34 | myjit.run(run_addr) 35 | -------------------------------------------------------------------------------- /example/loader/build_pe.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | from miasm.loader.pe_init import PE 4 | 5 | # Build an empty PE object 6 | pe_object = PE() 7 | 8 | # Add a section with a just a "RET" 9 | payload = b"\xc3" 10 | s_text = pe_object.SHList.add_section( 11 | name="text", addr=0x1000, rawsize=0x1000, data=payload 12 | ) 13 | 14 | # Set the entry point on this instruction 15 | pe_object.Opthdr.AddressOfEntryPoint = s_text.addr 16 | 17 | # Add some imports 18 | new_dll = [ 19 | ({"name": "kernel32.dll", 20 | "firstthunk": s_text.addr + 0x100}, 21 | ["CreateFileA", "SetFilePointer", "WriteFile", "CloseHandle"] 22 | ), 23 | ({"name": "USER32.dll", 24 | "firstthunk": None}, 25 | ["SetDlgItemInt", "GetMenu", "HideCaret"] 26 | ) 27 | ] 28 | pe_object.DirImport.add_dlldesc(new_dll) 29 | s_myimp = pe_object.SHList.add_section(name="myimp", rawsize=0x1000) 30 | pe_object.DirImport.set_rva(s_myimp.addr) 31 | 32 | # Rebuild the PE and dump it to a file 33 | open('fresh_pe.exe', 'wb').write(bytes(pe_object)) 34 | -------------------------------------------------------------------------------- /example/loader/get_exports.py: -------------------------------------------------------------------------------- 1 | from argparse import ArgumentParser 2 | from miasm.analysis.binary import Container 3 | from miasm.core.locationdb import LocationDB 4 | from miasm.jitter.loader.pe import get_export_name_addr_list 5 | 6 | 7 | parser = ArgumentParser(description="Retrieve exported functions of a DLL") 8 | parser.add_argument("filename", 9 | help="DLL filename") 10 | args = parser.parse_args() 11 | 12 | 13 | fdesc = open(args.filename, 'rb') 14 | loc_db = LocationDB() 15 | cont = Container.from_stream(fdesc, loc_db) 16 | 17 | exported_funcs = get_export_name_addr_list(cont.executable) 18 | 19 | for name_or_ordinal, address in exported_funcs: 20 | print(name_or_ordinal, hex(address)) 21 | -------------------------------------------------------------------------------- /example/loader/minidump_to_pe.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | """Minidump to PE example""" 3 | 4 | import sys 5 | 6 | from future.utils import viewvalues 7 | 8 | from miasm.loader.minidump_init import Minidump 9 | from miasm.loader.pe_init import PE 10 | 11 | minidump = Minidump(open(sys.argv[1], 'rb').read()) 12 | 13 | pe = PE() 14 | for i, memory in enumerate(sorted(viewvalues(minidump.memory), 15 | key=lambda x:x.address)): 16 | # Get section name 17 | name = str(memory.name) 18 | if not name: 19 | name = "s_%02d" % i 20 | else: 21 | name = name.split('\\')[-1] 22 | 23 | # Get section protection 24 | protect = memory.pretty_protect 25 | protect_mask = 0x20 26 | if protect == "UNKNOWN": 27 | protect_mask |= 0xe0000000 28 | else: 29 | if "EXECUTE" in protect: 30 | protect_mask |= 1 << 29 31 | if "READ" in protect: 32 | protect_mask |= 1 << 30 33 | if "WRITE" in protect: 34 | protect_mask |= 1 << 31 35 | 36 | # Add the section 37 | pe.SHList.add_section(name=name, addr=memory.address, rawsize=memory.size, 38 | data=memory.content, flags=protect_mask) 39 | 40 | # Find entry point 41 | try: 42 | entry_point = minidump.threads.Threads[0].ThreadContext.Eip[0] 43 | except AttributeError: 44 | entry_point = minidump.threads.Threads[0].ThreadContext.Rip[0] 45 | 46 | pe.Opthdr.AddressOfEntryPoint = entry_point 47 | 48 | open("out_pe.bin", "wb").write(bytes(pe)) 49 | -------------------------------------------------------------------------------- /example/loader/sc2pe.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from argparse import ArgumentParser 4 | from miasm.loader import pe_init 5 | 6 | 7 | parser = ArgumentParser(description="Create a PE from a shellcode") 8 | parser.add_argument("filename", 9 | help="x86 shellcode filename") 10 | parser.add_argument("-p", "--pename", 11 | help="new PE filename (default is 'sc_pe.exe')", 12 | default="sc_pe.exe") 13 | parser.add_argument("-w", "--word-size", 14 | help="word size (default is 32 bits)", 15 | choices=[32, 64], 16 | type=int, 17 | default=32) 18 | args = parser.parse_args() 19 | 20 | 21 | data = open(args.filename, 'rb').read() 22 | pe = pe_init.PE(wsize=args.word_size) 23 | s_text = pe.SHList.add_section(name="text", addr=0x1000, data=data) 24 | pe.Opthdr.AddressOfEntryPoint = s_text.addr 25 | open(args.pename, 'wb').write(bytes(pe)) 26 | -------------------------------------------------------------------------------- /example/samples/aarch64_simple.S: -------------------------------------------------------------------------------- 1 | main: 2 | SUB SP, SP, 0x10 3 | STRB W0, [SP,0xF] 4 | LDRB W0, [SP,0xF] 5 | CMP W0, 0x1F 6 | B.LS is_print 7 | LDRB W0, [SP,0xF] 8 | CMP W0, 0x7E 9 | B.HI is_print 10 | MOVZ W0, 1 11 | B ret_ 12 | is_print: 13 | MOVZ W0, 0 14 | 15 | ret_: 16 | ADD SP, SP, 0x10 17 | RET LR -------------------------------------------------------------------------------- /example/samples/arm_sc.S: -------------------------------------------------------------------------------- 1 | main: 2 | MOV R1, R0 3 | MOV R2, 0x100 4 | LDR R3, [PC, mykey1-$] 5 | loop: 6 | ADD R2, R1, R2 7 | ADD R1, R1, 1 8 | LDR R3, [PC, mykey2-$] 9 | CMP R1, R3 10 | BEQ loop 11 | 12 | ADD R0, R1, R2 13 | BX LR 14 | mykey1: 15 | .long 0x1 16 | mykey2: 17 | .long 0x2 18 | -------------------------------------------------------------------------------- /example/samples/arm_simple.S: -------------------------------------------------------------------------------- 1 | main: 2 | STMFD SP!, {R4, R5, LR} 3 | MOV R0, mystr & 0xffff 4 | ORR R0, R0, mystr & 0xffff0000 5 | MOV R4, R0 6 | MOV R1, mystrend & 0xffff 7 | ORR R1, R1, mystrend & 0xffff0000 8 | xxx: 9 | LDRB R2, [PC, key-$] 10 | loop: 11 | LDRB R3, [R0] 12 | EOR R3, R3, R2 13 | STRB R3, [R0], 1 14 | CMP R0, R1 15 | BNE loop 16 | end: 17 | MOV R0, R4 18 | LDMFD SP!, {R4, R5, PC} 19 | key: 20 | .byte 0x11 21 | mystr: 22 | .string "test string" 23 | mystrend: 24 | .long 0 25 | -------------------------------------------------------------------------------- /example/samples/armt.S: -------------------------------------------------------------------------------- 1 | memcpy: 2 | PUSH {R0-R3, LR} 3 | B test_end 4 | loop: 5 | LDRB R3, [R1] 6 | STRB R3, [R0] 7 | ADDS R0, R0, 1 8 | ADDS R1, R1, 1 9 | SUBS R2, R2, 1 10 | test_end: 11 | CMP R2, 0 12 | BNE loop 13 | POP {R0-R3, PC} 14 | main: 15 | PUSH {LR} 16 | SUB SP, 0x100 17 | MOV R0, SP 18 | ADD R1, PC, mystr-$ 19 | MOV R0, R0 20 | EORS R2, R2 21 | ADDS R2, R2, 0x4 22 | BL memcpy 23 | ADD SP, 0x100 24 | POP {PC} 25 | 26 | mystr: 27 | .string "toto" 28 | -------------------------------------------------------------------------------- /example/samples/box_upx.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cea-sec/miasm/2a15c60712b326b541d42ac48f372f97023547e7/example/samples/box_upx.exe -------------------------------------------------------------------------------- /example/samples/dse_crackme: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cea-sec/miasm/2a15c60712b326b541d42ac48f372f97023547e7/example/samples/dse_crackme -------------------------------------------------------------------------------- /example/samples/human.S: -------------------------------------------------------------------------------- 1 | ;; Walk a human link list and print its information 2 | main: 3 | TEST RDI, RDI 4 | JZ next 5 | 6 | PUSH RBX 7 | MOV RBX, RDI 8 | loop_arg: 9 | LEA RSI, QWORD PTR [RBX+0x10] 10 | LEA RDI, QWORD PTR [name-_+RIP] 11 | XOR EAX, EAX 12 | CALL printf 13 | 14 | MOVZX ESI, WORD PTR [RBX+0x8] 15 | LEA RDI, QWORD PTR [age-_+RIP] 16 | XOR EAX, EAX 17 | CALL printf 18 | 19 | MOV ESI, DWORD PTR [RBX+0xC] 20 | XOR EAX, EAX 21 | LEA RDI, QWORD PTR [height-_+RIP] 22 | CALL printf 23 | 24 | MOV RBX, QWORD PTR [RBX] 25 | TEST RBX, RBX 26 | JNZ loop_arg 27 | 28 | POP RBX 29 | next: 30 | 31 | 32 | LEA RBX, QWORD PTR [struct_human_ptr-_+RIP] 33 | loop_global: 34 | CMP RBX, 0 35 | JZ end 36 | 37 | LEA RSI, QWORD PTR [RBX+0x10] 38 | LEA RDI, QWORD PTR [name-_+RIP] 39 | XOR EAX, EAX 40 | CALL printf 41 | MOV RBX, QWORD PTR [RBX] 42 | JMP loop_global 43 | end: 44 | RET 45 | 46 | printf: 47 | ;; Dummy printf 48 | RET 49 | 50 | age: 51 | .string "Age: %d\n" 52 | height: 53 | .string "Height: %d\n" 54 | name: 55 | .string "Name: %s\n" 56 | struct_human_ptr: 57 | .dword 0xdead, 0xcafe 58 | -------------------------------------------------------------------------------- /example/samples/md5_aarch64l: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cea-sec/miasm/2a15c60712b326b541d42ac48f372f97023547e7/example/samples/md5_aarch64l -------------------------------------------------------------------------------- /example/samples/md5_arm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cea-sec/miasm/2a15c60712b326b541d42ac48f372f97023547e7/example/samples/md5_arm -------------------------------------------------------------------------------- /example/samples/md5_ppc32b: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cea-sec/miasm/2a15c60712b326b541d42ac48f372f97023547e7/example/samples/md5_ppc32b -------------------------------------------------------------------------------- /example/samples/mips32.S: -------------------------------------------------------------------------------- 1 | main: 2 | ADDIU A0, ZERO, 0x10 3 | ADDIU A1, ZERO, 0 4 | loop: 5 | ADDIU A1, A1, 0x1 6 | BNE A0, ZERO, loop 7 | ADDIU A0, A0, 0xFFFFFFFF 8 | 9 | ADDIU A2, A2, 0x1 10 | MOVN A1, ZERO, ZERO 11 | JR RA 12 | ADDIU A2, A2, 0x1 13 | -------------------------------------------------------------------------------- /example/samples/msp430.S: -------------------------------------------------------------------------------- 1 | main: 2 | mov.w 0x10, R10 3 | mov.w 0x0, R11 4 | call func 5 | loop: 6 | add.w 1, R11 7 | sub.w 1, R10 8 | jnz loop 9 | mov.w @SP+, PC 10 | 11 | func: 12 | add.w 1, R9 13 | mov.w @SP+, PC 14 | -------------------------------------------------------------------------------- /example/samples/simple_test.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cea-sec/miasm/2a15c60712b326b541d42ac48f372f97023547e7/example/samples/simple_test.bin -------------------------------------------------------------------------------- /example/samples/simple_test.c: -------------------------------------------------------------------------------- 1 | int test(unsigned int argc, char** argv) 2 | { 3 | unsigned int ret; 4 | if (argc == 0) 5 | ret = 0x1001; 6 | else if (argc < 2) 7 | ret = 0x1002; 8 | else if (argc <= 5) 9 | ret = 0x1003; 10 | else if (argc != 7 && argc*2 == 14) 11 | ret = 0x1004; 12 | else if (argc*2 == 14) 13 | ret = 0x1005; 14 | else if (argc & 0x30) 15 | ret = 0x1006; 16 | else if (argc + 3 == 0x45) 17 | ret = 0x1007; 18 | else 19 | ret = 0x1008; 20 | return ret; 21 | } 22 | 23 | int main(int argc, char** argv) 24 | { 25 | return test(argc, argv); 26 | } 27 | -------------------------------------------------------------------------------- /example/samples/test_x86_32_dis.S: -------------------------------------------------------------------------------- 1 | main: 2 | CMP EAX, 0x10 3 | JZ lbl2 4 | MOV ESI, EAX 5 | CMOVA EAX, EBX 6 | JMP end 7 | lbl2: 8 | MOV EAX, ECX 9 | CALL 0x11223344 10 | INC EAX 11 | end: 12 | RET 13 | -------------------------------------------------------------------------------- /example/samples/x86_32_automod.S: -------------------------------------------------------------------------------- 1 | main: 2 | XOR EDX, EDX 3 | JZ lbl_start 4 | 5 | lbl_start: 6 | INC EDX 7 | INC EDX 8 | INC EDX 9 | JZ dum 10 | 11 | INC EDX 12 | INC EDX 13 | INC EDX 14 | JZ dum 15 | 16 | INC EDX 17 | INC EDX 18 | INC EDX 19 | JZ dum 20 | 21 | lbl_stop: 22 | 23 | MOV ESI, exit_code 24 | MOV EDI, lbl_start 25 | MOV AL, 0x90 26 | MOV ECX, 24 27 | REPE MOVSB 28 | JMP lbl_start 29 | 30 | exit_code: 31 | MOV EAX, 0x11223344 32 | MOV EAX, 0x11223344 33 | MOV EAX, 0x11223344 34 | CMP EDX, 0x12 35 | JZ dum 36 | RET 37 | 38 | dum: 39 | INT 0x3 40 | RET 41 | -------------------------------------------------------------------------------- /example/samples/x86_32_automod_2.S: -------------------------------------------------------------------------------- 1 | main: 2 | MOV EAX, 0 3 | MOV ECX, 0x3 4 | block1: 5 | DEC ECX 6 | block2: 7 | INC EAX 8 | tmp: 9 | DEC ECX 10 | JNZ block2 11 | ; Modify block1 12 | MOV BYTE PTR [block1], 0x90 13 | ; Modify block2 14 | MOV BYTE PTR [block2], 0x90 15 | MOV BYTE PTR [tmp], 0x90 16 | MOV ECX, 4 17 | MOV EBX, EAX 18 | XOR EAX, EAX 19 | CMP EBX, 2 20 | JZ block2 21 | CMP EBX, 0 22 | JZ ok 23 | INT 0x3 24 | ok: 25 | RET 26 | -------------------------------------------------------------------------------- /example/samples/x86_32_dead.S: -------------------------------------------------------------------------------- 1 | main: 2 | MOV ECX, ECX 3 | INC ECX 4 | CMP ECX, 0 5 | JZ lbl0 6 | INC EAX 7 | lbl0: 8 | DEC EAX 9 | JMP lbl1 10 | lbl1: 11 | MOV EAX, 3 12 | JMP lbl2 13 | lbl2: 14 | MOV EAX, 4 15 | RET 16 | -------------------------------------------------------------------------------- /example/samples/x86_32_enc.S: -------------------------------------------------------------------------------- 1 | main: 2 | CALL cipher_code 3 | CALL msgbox_encrypted_start 4 | CALL cipher_code 5 | RET 6 | 7 | cipher_code: 8 | PUSH EBP 9 | MOV EBP, ESP 10 | 11 | LEA ESI, DWORD PTR [msgbox_encrypted_start] 12 | LEA EDI, DWORD PTR [msgbox_encrypted_stop] 13 | 14 | loop: 15 | XOR BYTE PTR [ESI], 0x42 16 | INC ESI 17 | CMP ESI, EDI 18 | JBE loop 19 | 20 | MOV ESP, EBP 21 | POP EBP 22 | RET 23 | 24 | msgbox_encrypted_start: 25 | PUSH 0 26 | PUSH title 27 | PUSH msg 28 | PUSH 0 29 | CALL DWORD PTR [ MessageBoxA ] 30 | RET 31 | .dontsplit 32 | msgbox_encrypted_stop: 33 | .long 0 34 | 35 | title: 36 | .string "Hello!" 37 | msg: 38 | .string "World!" 39 | -------------------------------------------------------------------------------- /example/samples/x86_32_if_reg.S: -------------------------------------------------------------------------------- 1 | main: 2 | MOV EAX, 0x0 3 | CMP EBX, 0 4 | JZ skip1 5 | OR EAX, 0x11220000 6 | skip1: 7 | CMP EBX, 0 8 | JZ skip2 9 | OR EAX, 0x3344 10 | skip2: 11 | RET 12 | -------------------------------------------------------------------------------- /example/samples/x86_32_manip_ptr.S: -------------------------------------------------------------------------------- 1 | main: 2 | PUSH EBP 3 | MOV EBP, ESP 4 | SUB ESP, 0x100 5 | MOV EAX, 0x1337 6 | ; test ptr manip 7 | LEA ESI, DWORD PTR [mystr^toto] 8 | CALL toto 9 | mystr: 10 | .string "test string" 11 | toto: 12 | POP EDI 13 | 14 | PUSH EDI 15 | ; test scasb 16 | XOR EAX, EAX 17 | XOR ECX, ECX 18 | DEC ECX 19 | REPNE SCASB 20 | NOT ECX 21 | DEC ECX 22 | 23 | ; test movsb 24 | POP ESI 25 | LEA EDI, DWORD PTR [EBP-0x100] 26 | REPE MOVSB 27 | 28 | ; test float 29 | PUSH 0 30 | FLD1 31 | FLD1 32 | FADD ST, ST(1) 33 | FIST DWORD PTR [ESP] 34 | POP EAX 35 | 36 | ; test cond mnemo 37 | NOP 38 | NOP 39 | CMOVZ EAX, EBX 40 | ; test shr 41 | NOP 42 | SHR EAX, 1 43 | NOP 44 | NOP 45 | SHR EAX, CL 46 | NOP 47 | 48 | MOV ESP, EBP 49 | POP EBP 50 | RET 51 | -------------------------------------------------------------------------------- /example/samples/x86_32_mod.S: -------------------------------------------------------------------------------- 1 | main: 2 | CALL test_automod 3 | CALL test_automod 4 | RET 5 | 6 | test_automod: 7 | PUSH EBP 8 | MOV EBP, ESP 9 | 10 | loop: 11 | MOV EAX, 0 12 | CMP EAX, 0 13 | JMP mod_addr 14 | mod_addr: 15 | JNZ end 16 | 17 | PUSH 0 18 | PUSH title 19 | PUSH msg 20 | PUSH 0 21 | CALL DWORD PTR [ MessageBoxA ] 22 | 23 | ; automodif code 24 | MOV BYTE PTR [mod_addr], 0xEB 25 | JMP loop 26 | end: 27 | MOV BYTE PTR [mod_addr], 0x75 28 | MOV ESP, EBP 29 | POP EBP 30 | RET 31 | 32 | title: 33 | .string "Hello!" 34 | msg: 35 | .string "World!" 36 | -------------------------------------------------------------------------------- /example/samples/x86_32_mod_self.S: -------------------------------------------------------------------------------- 1 | main: 2 | PUSH EBP 3 | MOV EBP, ESP 4 | MOV BYTE PTR [myint], 0x90 5 | myint: 6 | INT 0x3 7 | 8 | PUSH 0 9 | PUSH title 10 | PUSH msg 11 | PUSH 0 12 | CALL DWORD PTR [ MessageBoxA ] 13 | MOV ESP, EBP 14 | POP EBP 15 | RET 16 | 17 | title: 18 | .string "Hello!" 19 | msg: 20 | .string "World!" 21 | -------------------------------------------------------------------------------- /example/samples/x86_32_pop_esp.S: -------------------------------------------------------------------------------- 1 | main: 2 | MOV EAX, ESP 3 | CALL test 4 | MOV ESP, EAX 5 | PUSH 0 6 | PUSH title 7 | PUSH msg 8 | PUSH 0 9 | CALL DWORD PTR [ MessageBoxA ] 10 | RET 11 | 12 | test: 13 | POP ESP 14 | JMP ESP 15 | title: 16 | .string "Hello!" 17 | msg: 18 | .string "World!" 19 | -------------------------------------------------------------------------------- /example/samples/x86_32_repmod.S: -------------------------------------------------------------------------------- 1 | main: 2 | CALL test_automod 3 | RET 4 | 5 | lbl_good: 6 | NOP 7 | NOP 8 | NOP 9 | NOP 10 | NOP 11 | NOP 12 | NOP 13 | NOP 14 | NOP 15 | 16 | test_automod: 17 | PUSH EBP 18 | MOV EBP, ESP 19 | 20 | LEA EDI, DWORD PTR [lbl_mod] 21 | LEA ESI, DWORD PTR [lbl_good] 22 | 23 | MOV ECX, 0x8 24 | REPE MOVSB 25 | lbl_mod: 26 | XOR EAX, EAX 27 | MOV DWORD PTR [EAX], 0xDEADC0DE 28 | 29 | NOP 30 | NOP 31 | NOP 32 | 33 | PUSH 0 34 | PUSH title 35 | PUSH msg 36 | PUSH 0 37 | CALL DWORD PTR [ MessageBoxA ] 38 | 39 | MOV ESP, EBP 40 | POP EBP 41 | RET 42 | 43 | title: 44 | .string "Hello!" 45 | msg: 46 | .string "World!" 47 | -------------------------------------------------------------------------------- /example/samples/x86_32_sc.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cea-sec/miasm/2a15c60712b326b541d42ac48f372f97023547e7/example/samples/x86_32_sc.bin -------------------------------------------------------------------------------- /example/samples/x86_32_seh.S: -------------------------------------------------------------------------------- 1 | 2 | main: 3 | PUSH error 4 | PUSH DWORD PTR FS:[0x0] 5 | MOV DWORD PTR FS:[0x0], ESP 6 | XOR EAX, EAX 7 | 8 | ;; Access violation 9 | lbl_err_0: 10 | MOV DWORD PTR [EAX], 0x0 11 | lbl_err_end0: 12 | NOP 13 | 14 | 15 | ;; Breakpoint 16 | lbl_err_1: 17 | INT 0x3 18 | lbl_err_end1: 19 | NOP 20 | 21 | ;; Divide by 0 22 | XOR EAX, EAX 23 | lbl_err_2: 24 | DIV EAX 25 | lbl_err_end2: 26 | NOP 27 | 28 | ;; Privileged instruction 29 | lbl_err_3: 30 | STI 31 | lbl_err_end3: 32 | NOP 33 | 34 | ;; Unknown instruction (Bad LEA encoding) 35 | lbl_err_4: 36 | .byte 0x8D, 0xC0 37 | lbl_err_end4: 38 | NOP 39 | 40 | POP DWORD PTR FS:[0x0] 41 | ADD ESP, 4 42 | RET 43 | 44 | ;; Single step 45 | lbl_err_5: 46 | INT 0x1 47 | lbl_err_end5: 48 | NOP 49 | 50 | error: 51 | MOV ECX, DWORD PTR [ESP+0xC] 52 | MOV EAX, DWORD PTR [ECX+0xB8] 53 | MOV EBX, DWORD PTR [err_num] 54 | CMP EAX, DWORD PTR [labels_err + 4*EBX] 55 | JZ error_address_ok 56 | INT 0x3 57 | error_address_ok: 58 | INC DWORD PTR [err_num] 59 | MOV EAX, DWORD PTR [labels_err_end + 4*EBX] 60 | MOV DWORD PTR [ECX+0xB8], EAX 61 | XOR EAX, EAX 62 | RET 63 | 64 | 65 | 66 | err_num: 67 | .dword 0 68 | 69 | labels_err: 70 | .dword lbl_err_0 71 | .dword lbl_err_end1 72 | .dword lbl_err_2 73 | .dword lbl_err_3 74 | .dword lbl_err_4 75 | .dword lbl_err_5 76 | 77 | 78 | labels_err_end: 79 | .dword lbl_err_end0 80 | .dword lbl_err_end1 81 | .dword lbl_err_end2 82 | .dword lbl_err_end3 83 | .dword lbl_err_end4 84 | .dword lbl_err_end5 85 | -------------------------------------------------------------------------------- /example/samples/x86_32_simple.S: -------------------------------------------------------------------------------- 1 | main: 2 | PUSH 0 3 | PUSH title 4 | PUSH msg 5 | PUSH 0 6 | CALL DWORD PTR [ MessageBoxA ] 7 | RET 8 | 9 | title: 10 | .string "Hello!" 11 | msg: 12 | .string "World!" 13 | -------------------------------------------------------------------------------- /example/samples/x86_64.S: -------------------------------------------------------------------------------- 1 | main: 2 | MOV R9, 0x0 3 | LEA R8, QWORD PTR [title] 4 | LEA RDX, QWORD PTR [msg] 5 | MOV RCX, 0x0 6 | CALL QWORD PTR [ MessageBoxA ] 7 | RET 8 | 9 | title: 10 | .string "Hello!" 11 | msg: 12 | .string "World!" 13 | -------------------------------------------------------------------------------- /example/symbol_exec/single_instr.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | # Minimalist Symbol Exec example 3 | from miasm.analysis.binary import Container 4 | from miasm.analysis.machine import Machine 5 | from miasm.ir.symbexec import SymbolicExecutionEngine 6 | from miasm.core.locationdb import LocationDB 7 | 8 | START_ADDR = 0 9 | machine = Machine("x86_32") 10 | loc_db = LocationDB() 11 | 12 | # Assemble and disassemble a MOV 13 | ## Ensure that attributes 'offset' and 'l' are set 14 | line = machine.mn.fromstring("MOV EAX, EBX", loc_db, 32) 15 | asm = machine.mn.asm(line)[0] 16 | 17 | # Get back block 18 | cont = Container.from_string(asm, loc_db = loc_db) 19 | mdis = machine.dis_engine(cont.bin_stream, loc_db=loc_db) 20 | mdis.lines_wd = 1 21 | asm_block = mdis.dis_block(START_ADDR) 22 | 23 | # Translate ASM -> IR 24 | lifter_model_call = machine.lifter_model_call(mdis.loc_db) 25 | ircfg = lifter_model_call.new_ircfg() 26 | lifter_model_call.add_asmblock_to_ircfg(asm_block, ircfg) 27 | 28 | # Instantiate a Symbolic Execution engine with default value for registers 29 | symb = SymbolicExecutionEngine(lifter_model_call) 30 | 31 | # Emulate one IR basic block 32 | ## Emulation of several basic blocks can be done through .emul_ir_blocks 33 | cur_addr = symb.run_at(ircfg, START_ADDR) 34 | 35 | # Modified elements 36 | print('Modified registers:') 37 | symb.dump(mems=False) 38 | print('Modified memory (should be empty):') 39 | symb.dump(ids=False) 40 | 41 | # Check final status 42 | eax, ebx = lifter_model_call.arch.regs.EAX, lifter_model_call.arch.regs.EBX 43 | assert symb.symbols[eax] == ebx 44 | assert eax in symb.symbols 45 | -------------------------------------------------------------------------------- /example/symbol_exec/symbol_exec.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | from argparse import ArgumentParser 3 | 4 | from future.utils import viewvalues 5 | from miasm.analysis.binary import Container 6 | from miasm.analysis.machine import Machine 7 | from miasm.core.locationdb import LocationDB 8 | from miasm.ir.symbexec import SymbolicExecutionEngine 9 | 10 | parser = ArgumentParser("Simple SymbolicExecution demonstrator") 11 | parser.add_argument("target_binary", help="Target binary path") 12 | parser.add_argument("--address", help="Starting address for emulation. If not set, use the entrypoint") 13 | parser.add_argument("--steps", help="Log emulation state after each instruction", action="store_true") 14 | options = parser.parse_args() 15 | 16 | ################################################################### 17 | # Common section from example/disam/dis_binary_lift_model_call.py # 18 | ################################################################### 19 | 20 | fdesc = open(options.target_binary, 'rb') 21 | loc_db = LocationDB() 22 | 23 | cont = Container.from_stream(fdesc, loc_db) 24 | 25 | machine = Machine(cont.arch) 26 | 27 | mdis = machine.dis_engine(cont.bin_stream, loc_db=cont.loc_db) 28 | 29 | # no address -> entry point 30 | # 0xXXXXXX -> use this address 31 | # symbol -> resolve then use 32 | if options.address is None: 33 | addr = cont.entry_point 34 | else: 35 | try: 36 | addr = int(options.address, 0) 37 | except ValueError: 38 | addr = loc_db.get_name_offset(options.address) 39 | asmcfg = mdis.dis_multiblock(addr) 40 | 41 | lifter = machine.lifter_model_call(mdis.loc_db) 42 | ircfg = lifter.new_ircfg_from_asmcfg(asmcfg) 43 | 44 | ##################################### 45 | # End common section # 46 | ##################################### 47 | 48 | # Instantiate a Symbolic Execution engine with default value for registers 49 | symb = SymbolicExecutionEngine(lifter) 50 | 51 | # Emulate until the next address cannot be resolved (`ret`, unresolved condition, etc.) 52 | cur_addr = symb.run_at(ircfg, addr, step=options.steps) 53 | 54 | # Modified elements 55 | print('Modified registers:') 56 | symb.dump(mems=False) 57 | print('Modified memory:') 58 | symb.dump(ids=False) 59 | -------------------------------------------------------------------------------- /miasm/analysis/__init__.py: -------------------------------------------------------------------------------- 1 | "High-level tools for binary analysis" 2 | -------------------------------------------------------------------------------- /miasm/arch/__init__.py: -------------------------------------------------------------------------------- 1 | "Architecture implementations" 2 | -------------------------------------------------------------------------------- /miasm/arch/aarch64/__init__.py: -------------------------------------------------------------------------------- 1 | __all__ = ["arch", "disasm", "regs", "sem"] 2 | -------------------------------------------------------------------------------- /miasm/arch/aarch64/disasm.py: -------------------------------------------------------------------------------- 1 | from miasm.core.asmblock import disasmEngine 2 | from miasm.arch.aarch64.arch import mn_aarch64 3 | 4 | cb_aarch64_funcs = [] 5 | 6 | 7 | def cb_aarch64_disasm(*args, **kwargs): 8 | for func in cb_aarch64_funcs: 9 | func(*args, **kwargs) 10 | 11 | 12 | class dis_aarch64b(disasmEngine): 13 | attrib = "b" 14 | def __init__(self, bs=None, **kwargs): 15 | super(dis_aarch64b, self).__init__( 16 | mn_aarch64, self.attrib, bs, 17 | dis_block_callback = cb_aarch64_disasm, 18 | **kwargs) 19 | 20 | 21 | class dis_aarch64l(disasmEngine): 22 | attrib = "l" 23 | def __init__(self, bs=None, **kwargs): 24 | super(dis_aarch64l, self).__init__( 25 | mn_aarch64, self.attrib, bs, 26 | dis_block_callback = cb_aarch64_disasm, 27 | **kwargs) 28 | -------------------------------------------------------------------------------- /miasm/arch/aarch64/lifter_model_call.py: -------------------------------------------------------------------------------- 1 | #-*- coding:utf-8 -*- 2 | 3 | from miasm.ir.analysis import LifterModelCall 4 | from miasm.arch.aarch64.sem import Lifter_Aarch64l, Lifter_Aarch64b 5 | 6 | 7 | class LifterModelCallAarch64lBase(Lifter_Aarch64l, LifterModelCall): 8 | 9 | def __init__(self, loc_db): 10 | Lifter_Aarch64l.__init__(self, loc_db) 11 | self.ret_reg = self.arch.regs.X0 12 | 13 | 14 | class LifterModelCallAarch64bBase(Lifter_Aarch64b, LifterModelCall): 15 | 16 | def __init__(self, loc_db): 17 | Lifter_Aarch64b.__init__(self, loc_db) 18 | self.ret_reg = self.arch.regs.X0 19 | 20 | 21 | class LifterModelCallAarch64l(LifterModelCallAarch64lBase): 22 | 23 | def __init__(self, loc_db): 24 | LifterModelCallAarch64lBase.__init__(self, loc_db) 25 | self.ret_reg = self.arch.regs.X0 26 | 27 | def get_out_regs(self, _): 28 | return set([self.ret_reg, self.sp]) 29 | 30 | def sizeof_char(self): 31 | return 8 32 | 33 | def sizeof_short(self): 34 | return 16 35 | 36 | def sizeof_int(self): 37 | return 32 38 | 39 | def sizeof_long(self): 40 | return 32 41 | 42 | def sizeof_pointer(self): 43 | return 32 44 | 45 | 46 | class LifterModelCallAarch64b(LifterModelCallAarch64bBase, LifterModelCallAarch64l): 47 | 48 | def __init__(self, loc_db): 49 | LifterModelCallAarch64bBase.__init__(self, loc_db) 50 | self.ret_reg = self.arch.regs.X0 51 | -------------------------------------------------------------------------------- /miasm/arch/arm/__init__.py: -------------------------------------------------------------------------------- 1 | __all__ = ["arch", "disasm", "regs", "sem"] 2 | -------------------------------------------------------------------------------- /miasm/arch/arm/disasm.py: -------------------------------------------------------------------------------- 1 | from future.utils import viewvalues 2 | 3 | from miasm.core.asmblock import AsmConstraint, disasmEngine 4 | from miasm.arch.arm.arch import mn_arm, mn_armt 5 | 6 | 7 | def cb_arm_fix_call(mdis, cur_block, offsets_to_dis): 8 | """ 9 | for arm: 10 | MOV LR, PC 11 | LDR PC, [R5, 0x14] 12 | * is a subcall * 13 | 14 | """ 15 | if len(cur_block.lines) < 2: 16 | return 17 | l1 = cur_block.lines[-1] 18 | l2 = cur_block.lines[-2] 19 | if l1.name != "LDR": 20 | return 21 | if l2.name != "MOV": 22 | return 23 | 24 | values = viewvalues(mdis.arch.pc) 25 | if not l1.args[0] in values: 26 | return 27 | if not l2.args[1] in values: 28 | return 29 | loc_key_cst = mdis.loc_db.get_or_create_offset_location(l1.offset + 4) 30 | cur_block.add_cst(loc_key_cst, AsmConstraint.c_next) 31 | offsets_to_dis.add(l1.offset + 4) 32 | 33 | cb_arm_funcs = [cb_arm_fix_call] 34 | 35 | 36 | def cb_arm_disasm(*args, **kwargs): 37 | for func in cb_arm_funcs: 38 | func(*args, **kwargs) 39 | 40 | 41 | class dis_armb(disasmEngine): 42 | attrib = 'b' 43 | def __init__(self, bs=None, **kwargs): 44 | super(dis_armb, self).__init__(mn_arm, self.attrib, bs, **kwargs) 45 | self.dis_block_callback = cb_arm_disasm 46 | 47 | class dis_arml(disasmEngine): 48 | attrib = 'l' 49 | def __init__(self, bs=None, **kwargs): 50 | super(dis_arml, self).__init__(mn_arm, self.attrib, bs, **kwargs) 51 | self.dis_block_callback = cb_arm_disasm 52 | 53 | class dis_armtb(disasmEngine): 54 | attrib = 'b' 55 | def __init__(self, bs=None, **kwargs): 56 | super(dis_armtb, self).__init__(mn_armt, self.attrib, bs, **kwargs) 57 | 58 | class dis_armtl(disasmEngine): 59 | attrib = 'l' 60 | def __init__(self, bs=None, **kwargs): 61 | super(dis_armtl, self).__init__(mn_armt, self.attrib, bs, **kwargs) 62 | -------------------------------------------------------------------------------- /miasm/arch/mep/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cea-sec/miasm/2a15c60712b326b541d42ac48f372f97023547e7/miasm/arch/mep/__init__.py -------------------------------------------------------------------------------- /miasm/arch/mep/disasm.py: -------------------------------------------------------------------------------- 1 | # Toshiba MeP-c4 - miasm disassembly engine 2 | # Guillaume Valadon 3 | 4 | from miasm.core.asmblock import disasmEngine 5 | from miasm.arch.mep.arch import mn_mep 6 | 7 | 8 | class dis_mepb(disasmEngine): 9 | """MeP miasm disassembly engine - Big Endian 10 | 11 | Notes: 12 | - its is mandatory to call the miasm Machine 13 | """ 14 | 15 | attrib = "b" 16 | 17 | def __init__(self, bs=None, **kwargs): 18 | super(dis_mepb, self).__init__(mn_mep, self.attrib, bs, **kwargs) 19 | 20 | 21 | class dis_mepl(dis_mepb): 22 | """MeP miasm disassembly engine - Little Endian""" 23 | attrib = "l" 24 | -------------------------------------------------------------------------------- /miasm/arch/mep/lifter_model_call.py: -------------------------------------------------------------------------------- 1 | # Toshiba MeP-c4 - miasm IR analysis 2 | # Guillaume Valadon 3 | 4 | from miasm.arch.mep.sem import Lifter_MEPb, Lifter_MEPl 5 | from miasm.ir.analysis import LifterModelCall 6 | 7 | 8 | class LifterModelCallMepb(Lifter_MEPb, LifterModelCall): 9 | """MeP high level IR manipulations - Big Endian 10 | 11 | Notes: 12 | - it is mandatory for symbolic execution. 13 | """ 14 | 15 | def __init__(self, loc_db): 16 | Lifter_MEPb.__init__(self, loc_db) 17 | self.ret_reg = self.arch.regs.R0 18 | 19 | # Note: the following are abstract method and must be implemented 20 | def sizeof_char(self): 21 | "Return the size of a char in bits" 22 | return 8 23 | 24 | def sizeof_short(self): 25 | "Return the size of a short in bits" 26 | return 16 27 | 28 | def sizeof_int(self): 29 | "Return the size of an int in bits" 30 | return 32 31 | 32 | def sizeof_long(self): 33 | "Return the size of a long in bits" 34 | return 32 35 | 36 | def sizeof_pointer(self): 37 | "Return the size of a void* in bits" 38 | return 32 39 | 40 | 41 | class LifterModelCallMepl(Lifter_MEPl, LifterModelCallMepb): 42 | """MeP high level IR manipulations - Little Endian""" 43 | 44 | def __init__(self, loc_db): 45 | LifterModelCallMepb.__init__(self, loc_db) 46 | -------------------------------------------------------------------------------- /miasm/arch/mips32/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cea-sec/miasm/2a15c60712b326b541d42ac48f372f97023547e7/miasm/arch/mips32/__init__.py -------------------------------------------------------------------------------- /miasm/arch/mips32/disasm.py: -------------------------------------------------------------------------------- 1 | from miasm.core.asmblock import disasmEngine 2 | from miasm.arch.mips32.arch import mn_mips32 3 | 4 | 5 | 6 | class dis_mips32b(disasmEngine): 7 | attrib = 'b' 8 | def __init__(self, bs=None, **kwargs): 9 | super(dis_mips32b, self).__init__(mn_mips32, self.attrib, bs, **kwargs) 10 | 11 | 12 | class dis_mips32l(disasmEngine): 13 | attrib = "l" 14 | def __init__(self, bs=None, **kwargs): 15 | super(dis_mips32l, self).__init__(mn_mips32, self.attrib, bs, **kwargs) 16 | 17 | -------------------------------------------------------------------------------- /miasm/arch/msp430/__init__.py: -------------------------------------------------------------------------------- 1 | __all__ = ["arch", "disasm", "regs", "sem"] 2 | -------------------------------------------------------------------------------- /miasm/arch/msp430/disasm.py: -------------------------------------------------------------------------------- 1 | from miasm.core.asmblock import disasmEngine 2 | from miasm.arch.msp430.arch import mn_msp430 3 | 4 | 5 | class dis_msp430(disasmEngine): 6 | 7 | def __init__(self, bs=None, **kwargs): 8 | super(dis_msp430, self).__init__(mn_msp430, None, bs, **kwargs) 9 | -------------------------------------------------------------------------------- /miasm/arch/msp430/jit.py: -------------------------------------------------------------------------------- 1 | from miasm.jitter.jitload import Jitter 2 | from miasm.core.locationdb import LocationDB 3 | from miasm.core.utils import pck16, upck16 4 | from miasm.arch.msp430.sem import Lifter_MSP430 5 | 6 | import logging 7 | 8 | log = logging.getLogger('jit_msp430') 9 | hnd = logging.StreamHandler() 10 | hnd.setFormatter(logging.Formatter("[%(levelname)-8s]: %(message)s")) 11 | log.addHandler(hnd) 12 | log.setLevel(logging.CRITICAL) 13 | 14 | class jitter_msp430(Jitter): 15 | 16 | def __init__(self, loc_db, *args, **kwargs): 17 | Jitter.__init__(self, Lifter_MSP430(loc_db), *args, **kwargs) 18 | self.vm.set_little_endian() 19 | 20 | def push_uint16_t(self, value): 21 | regs = self.cpu.get_gpreg() 22 | regs['SP'] -= 2 23 | self.cpu.set_gpreg(regs) 24 | self.vm.set_mem(regs['SP'], pck16(value)) 25 | 26 | def pop_uint16_t(self): 27 | regs = self.cpu.get_gpreg() 28 | value = self.vm.get_u16(regs['SP']) 29 | regs['SP'] += 2 30 | self.cpu.set_gpreg(regs) 31 | return value 32 | 33 | def get_stack_arg(self, index): 34 | regs = self.cpu.get_gpreg() 35 | value = self.vm.get_u16(regs['SP'] + 2 * index) 36 | return value 37 | 38 | def init_run(self, *args, **kwargs): 39 | Jitter.init_run(self, *args, **kwargs) 40 | self.cpu.PC = self.pc 41 | 42 | -------------------------------------------------------------------------------- /miasm/arch/msp430/lifter_model_call.py: -------------------------------------------------------------------------------- 1 | #-*- coding:utf-8 -*- 2 | 3 | from miasm.ir.analysis import LifterModelCall 4 | from miasm.arch.msp430.sem import Lifter_MSP430 5 | from miasm.ir.ir import AssignBlock 6 | from miasm.expression.expression import * 7 | 8 | class LifterModelCallMsp430Base(Lifter_MSP430, LifterModelCall): 9 | 10 | def __init__(self, loc_db): 11 | Lifter_MSP430.__init__(self, loc_db) 12 | self.ret_reg = self.arch.regs.R15 13 | 14 | def call_effects(self, addr, instr): 15 | call_assignblk = AssignBlock( 16 | [ 17 | ExprAssign(self.ret_reg, ExprOp('call_func_ret', addr, self.sp, self.arch.regs.R15)), 18 | ExprAssign(self.sp, ExprOp('call_func_stack', addr, self.sp)) 19 | ], 20 | instr 21 | ) 22 | return [call_assignblk], [] 23 | 24 | class LifterModelCallMsp430(LifterModelCallMsp430Base): 25 | 26 | def __init__(self, loc_db): 27 | LifterModelCallMsp430Base.__init__(self, loc_db) 28 | 29 | def get_out_regs(self, _): 30 | return set([self.ret_reg, self.sp]) 31 | 32 | -------------------------------------------------------------------------------- /miasm/arch/ppc/__init__.py: -------------------------------------------------------------------------------- 1 | __all__ = ["arch", "disasm", "regs", "sem"] 2 | -------------------------------------------------------------------------------- /miasm/arch/ppc/disasm.py: -------------------------------------------------------------------------------- 1 | from miasm.arch.ppc.arch import mn_ppc 2 | from miasm.core.asmblock import disasmEngine 3 | 4 | class dis_ppc32b(disasmEngine): 5 | def __init__(self, bs=None, **kwargs): 6 | super(dis_ppc32b, self).__init__(mn_ppc, None, bs, **kwargs) 7 | self.attrib = 'b' 8 | -------------------------------------------------------------------------------- /miasm/arch/sh4/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cea-sec/miasm/2a15c60712b326b541d42ac48f372f97023547e7/miasm/arch/sh4/__init__.py -------------------------------------------------------------------------------- /miasm/arch/x86/__init__.py: -------------------------------------------------------------------------------- 1 | __all__ = ["arch", "disasm", "regs", "sem"] 2 | -------------------------------------------------------------------------------- /miasm/arch/x86/disasm.py: -------------------------------------------------------------------------------- 1 | from miasm.core.asmblock import disasmEngine 2 | from miasm.arch.x86.arch import mn_x86 3 | 4 | 5 | cb_x86_funcs = [] 6 | 7 | 8 | def cb_x86_disasm(mdis, cur_block, offset_to_dis): 9 | for func in cb_x86_funcs: 10 | func(mdis, cur_block, offset_to_dis) 11 | 12 | 13 | class dis_x86(disasmEngine): 14 | attrib = None 15 | 16 | def __init__(self, bs=None, **kwargs): 17 | super(dis_x86, self).__init__(mn_x86, self.attrib, bs, **kwargs) 18 | self.dis_block_callback = cb_x86_disasm 19 | 20 | 21 | class dis_x86_16(dis_x86): 22 | attrib = 16 23 | 24 | 25 | class dis_x86_32(dis_x86): 26 | attrib = 32 27 | 28 | 29 | class dis_x86_64(dis_x86): 30 | attrib = 64 31 | -------------------------------------------------------------------------------- /miasm/core/__init__.py: -------------------------------------------------------------------------------- 1 | "Core components" 2 | -------------------------------------------------------------------------------- /miasm/core/bin_stream_ida.py: -------------------------------------------------------------------------------- 1 | from builtins import range 2 | from idc import get_wide_byte, get_segm_end 3 | from idautils import Segments 4 | from idaapi import is_mapped 5 | 6 | from miasm.core.utils import int_to_byte 7 | from miasm.core.bin_stream import bin_stream_str 8 | 9 | 10 | class bin_stream_ida(bin_stream_str): 11 | """ 12 | bin_stream implementation for IDA 13 | 14 | Don't generate xrange using address computation: 15 | It can raise error on overflow 7FFFFFFF with 32 bit python 16 | """ 17 | def _getbytes(self, start, l=1): 18 | out = [] 19 | for ad in range(l): 20 | offset = ad + start + self.base_address 21 | if not is_mapped(offset): 22 | raise IOError(f"not enough bytes @ offset {offset:x}") 23 | out.append(int_to_byte(get_wide_byte(offset))) 24 | return b''.join(out) 25 | 26 | def readbs(self, l=1): 27 | if self.offset + l > self.l: 28 | raise IOError("not enough bytes") 29 | content = self.getbytes(self.offset) 30 | self.offset += l 31 | return content 32 | 33 | def __str__(self): 34 | raise NotImplementedError('Not fully functional') 35 | 36 | def setoffset(self, val): 37 | self.offset = val 38 | 39 | def getlen(self): 40 | # Lazy version 41 | if hasattr(self, "_getlen"): 42 | return self._getlen 43 | max_addr = get_segm_end(list(Segments())[-1] - (self.offset - self.base_address)) 44 | self._getlen = max_addr 45 | return max_addr 46 | -------------------------------------------------------------------------------- /miasm/expression/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2011 EADS France, Fabrice Desclaux 3 | # 4 | # This program is free software; you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation; either version 2 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program 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 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License along 15 | # with this program; if not, write to the Free Software Foundation, Inc., 16 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | # 18 | "Intermediate language implementation" 19 | -------------------------------------------------------------------------------- /miasm/ir/__init__.py: -------------------------------------------------------------------------------- 1 | "Intermediate representation methods" 2 | -------------------------------------------------------------------------------- /miasm/ir/translators/__init__.py: -------------------------------------------------------------------------------- 1 | """IR Translators""" 2 | from miasm.ir.translators.translator import Translator 3 | import miasm.ir.translators.C 4 | import miasm.ir.translators.python 5 | import miasm.ir.translators.miasm_ir 6 | import miasm.ir.translators.smt2 7 | try: 8 | import miasm.ir.translators.z3_ir 9 | except ImportError: 10 | # Nothing to do, z3 not available 11 | pass 12 | 13 | __all__ = ["Translator"] 14 | -------------------------------------------------------------------------------- /miasm/ir/translators/miasm_ir.py: -------------------------------------------------------------------------------- 1 | from builtins import map 2 | from miasm.ir.translators.translator import Translator 3 | 4 | 5 | class TranslatorMiasm(Translator): 6 | "Translate a Miasm expression to its Python building form" 7 | 8 | __LANG__ = "Miasm" 9 | 10 | def from_ExprId(self, expr): 11 | return "ExprId(%s, size=%d)" % (repr(expr.name), expr.size) 12 | 13 | def from_ExprInt(self, expr): 14 | return "ExprInt(0x%x, %d)" % (int(expr), expr.size) 15 | 16 | def from_ExprCond(self, expr): 17 | return "ExprCond(%s, %s, %s)" % (self.from_expr(expr.cond), 18 | self.from_expr(expr.src1), 19 | self.from_expr(expr.src2)) 20 | 21 | def from_ExprSlice(self, expr): 22 | return "ExprSlice(%s, %d, %d)" % (self.from_expr(expr.arg), 23 | expr.start, 24 | expr.stop) 25 | 26 | def from_ExprOp(self, expr): 27 | return "ExprOp(%s, %s)" % ( 28 | repr(expr.op), 29 | ", ".join(map(self.from_expr, expr.args)) 30 | ) 31 | 32 | def from_ExprCompose(self, expr): 33 | args = ["%s" % self.from_expr(arg) for arg in expr.args] 34 | return "ExprCompose(%s)" % ", ".join(args) 35 | 36 | def from_ExprAssign(self, expr): 37 | return "ExprAssign(%s, %s)" % (self.from_expr(expr.dst), 38 | self.from_expr(expr.src)) 39 | 40 | def from_ExprMem(self, expr): 41 | return "ExprMem(%s, size=%d)" % (self.from_expr(expr.ptr), expr.size) 42 | 43 | 44 | # Register the class 45 | Translator.register(TranslatorMiasm) 46 | -------------------------------------------------------------------------------- /miasm/jitter/__init__.py: -------------------------------------------------------------------------------- 1 | "JustInTime compilation feature" 2 | -------------------------------------------------------------------------------- /miasm/jitter/arch/JitCore_aarch64.h: -------------------------------------------------------------------------------- 1 | 2 | struct vm_cpu { 3 | uint32_t exception_flags; 4 | uint32_t interrupt_num; 5 | 6 | /* gpregs */ 7 | 8 | uint64_t X0; 9 | uint64_t X1; 10 | uint64_t X2; 11 | uint64_t X3; 12 | uint64_t X4; 13 | uint64_t X5; 14 | uint64_t X6; 15 | uint64_t X7; 16 | uint64_t X8; 17 | uint64_t X9; 18 | uint64_t X10; 19 | uint64_t X11; 20 | uint64_t X12; 21 | uint64_t X13; 22 | uint64_t X14; 23 | uint64_t X15; 24 | uint64_t X16; 25 | uint64_t X17; 26 | uint64_t X18; 27 | uint64_t X19; 28 | uint64_t X20; 29 | uint64_t X21; 30 | uint64_t X22; 31 | uint64_t X23; 32 | uint64_t X24; 33 | uint64_t X25; 34 | uint64_t X26; 35 | uint64_t X27; 36 | uint64_t X28; 37 | uint64_t X29; 38 | uint64_t LR; 39 | uint64_t SP; 40 | 41 | uint64_t PC; 42 | 43 | /* eflag */ 44 | uint32_t zf; 45 | uint32_t nf; 46 | uint32_t of; 47 | uint32_t cf; 48 | }; 49 | 50 | _MIASM_EXPORT void dump_gpregs(struct vm_cpu* vmcpu); 51 | 52 | _MIASM_EXPORT void MEM_WRITE_08(JitCpu* jitcpu, uint64_t addr, uint8_t src); 53 | _MIASM_EXPORT void MEM_WRITE_16(JitCpu* jitcpu, uint64_t addr, uint16_t src); 54 | _MIASM_EXPORT void MEM_WRITE_32(JitCpu* jitcpu, uint64_t addr, uint32_t src); 55 | _MIASM_EXPORT void MEM_WRITE_64(JitCpu* jitcpu, uint64_t addr, uint64_t src); 56 | 57 | #define RETURN_PC return BlockDst; 58 | -------------------------------------------------------------------------------- /miasm/jitter/arch/JitCore_arm.h: -------------------------------------------------------------------------------- 1 | 2 | struct vm_cpu { 3 | uint32_t exception_flags; 4 | uint32_t interrupt_num; 5 | 6 | /* gpregs */ 7 | uint32_t R0; 8 | uint32_t R1; 9 | uint32_t R2; 10 | uint32_t R3; 11 | uint32_t R4; 12 | uint32_t R5; 13 | uint32_t R6; 14 | uint32_t R7; 15 | uint32_t R8; 16 | uint32_t R9; 17 | uint32_t R10; 18 | uint32_t R11; 19 | uint32_t R12; 20 | uint32_t SP; 21 | uint32_t LR; 22 | uint32_t PC; 23 | 24 | /* eflag */ 25 | uint32_t zf; 26 | uint32_t nf; 27 | uint32_t of; 28 | uint32_t cf; 29 | 30 | /* ge */ 31 | uint32_t ge0; 32 | uint32_t ge1; 33 | uint32_t ge2; 34 | uint32_t ge3; 35 | 36 | uint32_t bp_num; 37 | }; 38 | 39 | 40 | _MIASM_EXPORT void dump_gpregs(struct vm_cpu* vmcpu); 41 | 42 | _MIASM_EXPORT void MEM_WRITE_08(JitCpu* jitcpu, uint64_t addr, uint8_t src); 43 | _MIASM_EXPORT void MEM_WRITE_16(JitCpu* jitcpu, uint64_t addr, uint16_t src); 44 | _MIASM_EXPORT void MEM_WRITE_32(JitCpu* jitcpu, uint64_t addr, uint32_t src); 45 | _MIASM_EXPORT void MEM_WRITE_64(JitCpu* jitcpu, uint64_t addr, uint64_t src); 46 | 47 | #define RETURN_PC return BlockDst; 48 | -------------------------------------------------------------------------------- /miasm/jitter/arch/JitCore_m68k.h: -------------------------------------------------------------------------------- 1 | 2 | struct vm_cpu { 3 | uint32_t exception_flags; 4 | uint32_t interrupt_num; 5 | 6 | /* gpregs */ 7 | uint32_t A0; 8 | uint32_t A1; 9 | uint32_t A2; 10 | uint32_t A3; 11 | uint32_t A4; 12 | uint32_t A5; 13 | uint32_t A6; 14 | uint32_t SP; 15 | 16 | uint32_t D0; 17 | uint32_t D1; 18 | uint32_t D2; 19 | uint32_t D3; 20 | uint32_t D4; 21 | uint32_t D5; 22 | uint32_t D6; 23 | uint32_t D7; 24 | 25 | 26 | uint32_t PC; 27 | 28 | /* eflag */ 29 | uint32_t zf; 30 | uint32_t nf; 31 | uint32_t vf; 32 | uint32_t cf; 33 | uint32_t xf; 34 | 35 | uint64_t float_st0; 36 | uint64_t float_st1; 37 | uint64_t float_st2; 38 | uint64_t float_st3; 39 | uint64_t float_st4; 40 | uint64_t float_st5; 41 | uint64_t float_st6; 42 | uint64_t float_st7; 43 | 44 | uint32_t bp_num; 45 | }; 46 | 47 | 48 | _MIASM_EXPORT void dump_gpregs(struct vm_cpu* vmcpu); 49 | 50 | _MIASM_EXPORT void MEM_WRITE_08(JitCpu* jitcpu, uint64_t addr, uint8_t src); 51 | _MIASM_EXPORT void MEM_WRITE_16(JitCpu* jitcpu, uint64_t addr, uint16_t src); 52 | _MIASM_EXPORT void MEM_WRITE_32(JitCpu* jitcpu, uint64_t addr, uint32_t src); 53 | _MIASM_EXPORT void MEM_WRITE_64(JitCpu* jitcpu, uint64_t addr, uint64_t src); 54 | 55 | #define RETURN_PC return BlockDst; 56 | -------------------------------------------------------------------------------- /miasm/jitter/arch/JitCore_mep.h: -------------------------------------------------------------------------------- 1 | // Inspired from JitCore_msp430.h 2 | 3 | struct vm_cpu { 4 | /* miasm flags */ 5 | uint32_t exception_flags; 6 | 7 | /* gpregs */ 8 | uint32_t R0; 9 | uint32_t R1; 10 | uint32_t R2; 11 | uint32_t R3; 12 | uint32_t R4; 13 | uint32_t R5; 14 | uint32_t R6; 15 | uint32_t R7; 16 | uint32_t R8; 17 | uint32_t R9; 18 | uint32_t R10; 19 | uint32_t R11; 20 | uint32_t R12; 21 | uint32_t TP; 22 | uint32_t GP; 23 | uint32_t SP; 24 | 25 | /* csregs */ 26 | uint32_t PC; 27 | uint32_t LP; 28 | uint32_t SAR; 29 | uint32_t S3; 30 | uint32_t RPB; 31 | uint32_t RPE; 32 | uint32_t RPC; 33 | uint32_t HI; 34 | uint32_t LO; 35 | uint32_t S9; 36 | uint32_t S10; 37 | uint32_t S11; 38 | uint32_t MB0; 39 | uint32_t ME0; 40 | uint32_t MB1; 41 | uint32_t ME1; 42 | uint32_t PSW; 43 | uint32_t ID; 44 | uint32_t TMP; 45 | uint32_t EPC; 46 | uint32_t EXC; 47 | uint32_t CFG; 48 | uint32_t S22; 49 | uint32_t NPC; 50 | uint32_t DBG; 51 | uint32_t DEPC; 52 | uint32_t OPT; 53 | uint32_t RCFG; 54 | uint32_t CCFG; 55 | uint32_t S29; 56 | uint32_t S30; 57 | uint32_t S31; 58 | uint32_t S32; 59 | 60 | /* miasm specific regs */ 61 | uint32_t PC_end; 62 | uint32_t RPE_instr_count; 63 | uint32_t RPC_current; 64 | 65 | 66 | uint32_t take_jmp; 67 | uint32_t last_addr; 68 | uint32_t is_repeat_end; 69 | uint32_t in_erepeat; 70 | 71 | /* flags */ 72 | 73 | }; 74 | 75 | _MIASM_EXPORT void dump_gpregs(struct vm_cpu* vmcpu); 76 | 77 | _MIASM_EXPORT void MEM_WRITE_08(JitCpu* jitcpu, uint64_t addr, uint8_t src); 78 | _MIASM_EXPORT void MEM_WRITE_16(JitCpu* jitcpu, uint64_t addr, uint16_t src); 79 | _MIASM_EXPORT void MEM_WRITE_32(JitCpu* jitcpu, uint64_t addr, uint32_t src); 80 | _MIASM_EXPORT void MEM_WRITE_64(JitCpu* jitcpu, uint64_t addr, uint64_t src); 81 | 82 | #define RETURN_PC return BlockDst; 83 | -------------------------------------------------------------------------------- /miasm/jitter/arch/JitCore_msp430.h: -------------------------------------------------------------------------------- 1 | 2 | struct vm_cpu { 3 | uint32_t exception_flags; 4 | 5 | /* gpregs */ 6 | uint32_t PC; 7 | uint32_t SP; 8 | uint32_t R3; 9 | uint32_t R4; 10 | uint32_t R5; 11 | uint32_t R6; 12 | uint32_t R7; 13 | uint32_t R8; 14 | uint32_t R9; 15 | uint32_t R10; 16 | uint32_t R11; 17 | uint32_t R12; 18 | uint32_t R13; 19 | uint32_t R14; 20 | uint32_t R15; 21 | 22 | /* eflag */ 23 | uint32_t zf; 24 | uint32_t nf; 25 | uint32_t of; 26 | uint32_t cf; 27 | 28 | uint32_t cpuoff; 29 | uint32_t gie; 30 | uint32_t osc; 31 | uint32_t scg0; 32 | uint32_t scg1; 33 | uint32_t res; 34 | 35 | }; 36 | 37 | #define RETURN_PC return BlockDst; 38 | 39 | _MIASM_EXPORT void dump_gpregs(struct vm_cpu* vmcpu); 40 | 41 | _MIASM_EXPORT void MEM_WRITE_08(JitCpu* jitcpu, uint64_t addr, uint8_t src); 42 | _MIASM_EXPORT void MEM_WRITE_16(JitCpu* jitcpu, uint64_t addr, uint16_t src); 43 | _MIASM_EXPORT void MEM_WRITE_32(JitCpu* jitcpu, uint64_t addr, uint32_t src); 44 | _MIASM_EXPORT void MEM_WRITE_64(JitCpu* jitcpu, uint64_t addr, uint64_t src); 45 | -------------------------------------------------------------------------------- /miasm/jitter/arch/JitCore_ppc32.h: -------------------------------------------------------------------------------- 1 | /* 2 | * _size can't be used yet because all register accesses are homogeneously 3 | * 32-bit 4 | */ 5 | struct vm_cpu { 6 | #define JITCORE_PPC_REG_EXPAND(_name, _size) \ 7 | uint32_t _name; 8 | #include "JitCore_ppc32_regs.h" 9 | #undef JITCORE_PPC_REG_EXPAND 10 | 11 | uint64_t exception_flags; 12 | uint32_t spr_access; 13 | uint32_t reserve; 14 | uint32_t reserve_address; 15 | }; 16 | 17 | _MIASM_EXPORT void dump_gpregs(struct vm_cpu *); 18 | 19 | _MIASM_EXPORT void MEM_WRITE_08(JitCpu* jitcpu, uint64_t addr, uint8_t src); 20 | _MIASM_EXPORT void MEM_WRITE_16(JitCpu* jitcpu, uint64_t addr, uint16_t src); 21 | _MIASM_EXPORT void MEM_WRITE_32(JitCpu* jitcpu, uint64_t addr, uint32_t src); 22 | _MIASM_EXPORT void MEM_WRITE_64(JitCpu* jitcpu, uint64_t addr, uint64_t src); 23 | -------------------------------------------------------------------------------- /miasm/jitter/arch/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cea-sec/miasm/2a15c60712b326b541d42ac48f372f97023547e7/miasm/jitter/arch/__init__.py -------------------------------------------------------------------------------- /miasm/jitter/csts.py: -------------------------------------------------------------------------------- 1 | #-*- coding:utf-8 -*- 2 | 3 | 4 | # VM Mngr Exceptions 5 | EXCEPT_DO_NOT_UPDATE_PC = 1 << 25 6 | EXCEPT_NUM_UPDT_EIP = (1<<11) 7 | 8 | EXCEPT_CODE_AUTOMOD = (1 << 0) 9 | EXCEPT_SOFT_BP = (1 << 1) 10 | EXCEPT_INT_XX = (1 << 2) 11 | EXCEPT_SPR_ACCESS = (1 << 3) 12 | EXCEPT_SYSCALL = (1 << 4) 13 | EXCEPT_BREAKPOINT_MEMORY = (1 << 10) 14 | # Deprecated 15 | EXCEPT_BREAKPOINT_INTERN = EXCEPT_BREAKPOINT_MEMORY 16 | 17 | EXCEPT_ACCESS_VIOL = ((1 << 14) | EXCEPT_DO_NOT_UPDATE_PC) 18 | EXCEPT_DIV_BY_ZERO = ((1 << 16) | EXCEPT_DO_NOT_UPDATE_PC) 19 | EXCEPT_PRIV_INSN = ((1 << 17) | EXCEPT_DO_NOT_UPDATE_PC) 20 | EXCEPT_ILLEGAL_INSN = ((1 << 18) | EXCEPT_DO_NOT_UPDATE_PC) 21 | EXCEPT_UNK_MNEMO = ((1 << 19) | EXCEPT_DO_NOT_UPDATE_PC) 22 | EXCEPT_INT_1 = ((1 << 20) | EXCEPT_DO_NOT_UPDATE_PC) 23 | 24 | JitterExceptions = { 25 | "DO_NOT_UPDATE_PC": EXCEPT_DO_NOT_UPDATE_PC, 26 | "NUM_UPDT_EIP": EXCEPT_NUM_UPDT_EIP, 27 | "CODE_AUTOMOD": EXCEPT_CODE_AUTOMOD, 28 | "SOFT_BP": EXCEPT_SOFT_BP, 29 | "INT_XX": EXCEPT_INT_XX, 30 | "SPR_ACCESS": EXCEPT_SPR_ACCESS, 31 | "SYSCALL": EXCEPT_SYSCALL, 32 | "BREAKPOINT_MEMORY": EXCEPT_BREAKPOINT_MEMORY, 33 | "BREAKPOINT_INTERN": EXCEPT_BREAKPOINT_INTERN, 34 | "ACCESS_VIOL": EXCEPT_ACCESS_VIOL, 35 | "DIV_BY_ZERO": EXCEPT_DIV_BY_ZERO, 36 | "PRIV_INSN": EXCEPT_PRIV_INSN, 37 | "ILLEGAL_INSN": EXCEPT_ILLEGAL_INSN, 38 | "UNK_MNEMO": EXCEPT_UNK_MNEMO, 39 | "INT_1": EXCEPT_INT_1, 40 | } 41 | 42 | # VM Mngr constants 43 | 44 | PAGE_READ = 1 45 | PAGE_WRITE = 2 46 | PAGE_EXEC = 4 47 | 48 | BREAKPOINT_READ = 1 49 | BREAKPOINT_WRITE = 2 50 | 51 | -------------------------------------------------------------------------------- /miasm/jitter/loader/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cea-sec/miasm/2a15c60712b326b541d42ac48f372f97023547e7/miasm/jitter/loader/__init__.py -------------------------------------------------------------------------------- /miasm/jitter/vm_mngr_py.h: -------------------------------------------------------------------------------- 1 | #ifndef VM_MNGR_PY_H 2 | #define VM_MNGR_PY_H 3 | 4 | #ifdef _WIN32 5 | #define SIGALRM 0 6 | #endif 7 | 8 | typedef struct { 9 | PyObject_HEAD 10 | PyObject *vmmngr; 11 | vm_mngr_t vm_mngr; 12 | } VmMngr; 13 | 14 | #endif// VM_MNGR_PY_H 15 | 16 | bn_t PyLong_to_bn(PyObject* py_long); 17 | PyObject* bn_to_PyLong(bn_t bn); 18 | -------------------------------------------------------------------------------- /miasm/loader/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | __all__ = ['pe_init', 'elf_init', 'strpatchwork'] 4 | -------------------------------------------------------------------------------- /miasm/os_dep/__init__.py: -------------------------------------------------------------------------------- 1 | "Operating System specific methods" 2 | -------------------------------------------------------------------------------- /miasm/os_dep/linux/__init__.py: -------------------------------------------------------------------------------- 1 | # Linux emulation 2 | -------------------------------------------------------------------------------- /miasm/runtime/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 | #if __x86_64 16 | 17 | #include "int_lib.h" 18 | #include "export.h" 19 | 20 | tu_int __udivmodti4(tu_int a, tu_int b, tu_int* rem); 21 | 22 | /* Returns: a / b */ 23 | 24 | ti_int 25 | __divti3(ti_int a, ti_int b) 26 | { 27 | const int bits_in_tword_m1 = (int)(sizeof(ti_int) * CHAR_BIT) - 1; 28 | ti_int s_a = a >> bits_in_tword_m1; /* s_a = a < 0 ? -1 : 0 */ 29 | ti_int s_b = b >> bits_in_tword_m1; /* s_b = b < 0 ? -1 : 0 */ 30 | a = (a ^ s_a) - s_a; /* negate if s_a == -1 */ 31 | b = (b ^ s_b) - s_b; /* negate if s_b == -1 */ 32 | s_a ^= s_b; /* sign of quotient */ 33 | return (__udivmodti4(a, b, (tu_int*)0) ^ s_a) - s_a; /* negate if s_a == -1 */ 34 | } 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /miasm/runtime/export.h: -------------------------------------------------------------------------------- 1 | #ifndef MIASM_RT_EXPORT_H 2 | #define MIASM_RT_EXPORT_H 3 | 4 | #ifdef _WIN32 5 | #define _MIASM_EXPORT __declspec(dllexport) 6 | #else 7 | #define _MIASM_EXPORT __attribute__((visibility("default"))) 8 | #endif 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /miasm/runtime/int_util.h: -------------------------------------------------------------------------------- 1 | //===-- int_util.h - internal utility functions ---------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file is not part of the interface of this library. 10 | // 11 | // This file defines non-inline utilities which are available for use in the 12 | // library. The function definitions themselves are all contained in int_util.c 13 | // which will always be compiled into any compiler-rt library. 14 | // 15 | //===----------------------------------------------------------------------===// 16 | 17 | #ifndef INT_UTIL_H 18 | #define INT_UTIL_H 19 | 20 | /// \brief Trigger a program abort (or panic for kernel code). 21 | #define compilerrt_abort() __compilerrt_abort_impl(__FILE__, __LINE__, __func__) 22 | 23 | NORETURN void __compilerrt_abort_impl(const char *file, int line, 24 | const char *function); 25 | 26 | #define COMPILE_TIME_ASSERT(expr) COMPILE_TIME_ASSERT1(expr, __COUNTER__) 27 | #define COMPILE_TIME_ASSERT1(expr, cnt) COMPILE_TIME_ASSERT2(expr, cnt) 28 | #define COMPILE_TIME_ASSERT2(expr, cnt) \ 29 | typedef char ct_assert_##cnt[(expr) ? 1 : -1] UNUSED 30 | 31 | #endif // INT_UTIL_H 32 | -------------------------------------------------------------------------------- /miasm/runtime/udivti3.c: -------------------------------------------------------------------------------- 1 | //===-- udivti3.c - Implement __udivti3 -----------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file implements __udivti3 for the compiler_rt library. 10 | // 11 | //===----------------------------------------------------------------------===// 12 | 13 | #include "int_lib.h" 14 | #include "export.h" 15 | 16 | #ifdef CRT_HAS_128BIT 17 | 18 | // Returns: a / b 19 | 20 | _MIASM_EXPORT tu_int __udivti3(tu_int a, tu_int b) { 21 | return __udivmodti4(a, b, 0); 22 | } 23 | 24 | #endif // CRT_HAS_128BIT 25 | -------------------------------------------------------------------------------- /optional_requirements.txt: -------------------------------------------------------------------------------- 1 | pycparser 2 | z3-solver==4.8.7.0 3 | llvmlite==0.44.0 4 | parameterized~=0.8.1 5 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | setuptools 2 | pyparsing>=2.4.1 3 | future 4 | -------------------------------------------------------------------------------- /test/analysis/dg_check.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | from pdb import pm 3 | import sys 4 | import subprocess 5 | import json 6 | 7 | 8 | expected_file = sys.argv[1] 9 | dg = subprocess.Popen([sys.executable] + sys.argv[2:], stdout=subprocess.PIPE) 10 | 11 | stdout, _ = dg.communicate() 12 | expected = json.load(open(expected_file)) 13 | result = json.loads(stdout.decode()) 14 | 15 | 16 | assert len(expected) == len(result) 17 | 18 | assert all(r in result for r in expected) 19 | assert all(r in expected for r in result) 20 | -------------------------------------------------------------------------------- /test/analysis/dg_test_00_expected.json: -------------------------------------------------------------------------------- 1 | [{"EAX": "0x1", "has_loop": false}] 2 | -------------------------------------------------------------------------------- /test/analysis/dg_test_00_implicit_expected.json: -------------------------------------------------------------------------------- 1 | [{"has_loop": false, "EAX": "0x1", "satisfiability": true, "constraints": {}}] 2 | -------------------------------------------------------------------------------- /test/analysis/dg_test_01_expected.json: -------------------------------------------------------------------------------- 1 | [{"EAX": "0x3", "has_loop": false}] 2 | -------------------------------------------------------------------------------- /test/analysis/dg_test_01_implicit_expected.json: -------------------------------------------------------------------------------- 1 | [{"has_loop": false, "EAX": "0x3", "satisfiability": true, "constraints": {}}] 2 | -------------------------------------------------------------------------------- /test/analysis/dg_test_02_expected.json: -------------------------------------------------------------------------------- 1 | [{"EAX": "0x3", "has_loop": false}, {"EAX": "0x4", "has_loop": false}] 2 | -------------------------------------------------------------------------------- /test/analysis/dg_test_02_implicit_expected.json: -------------------------------------------------------------------------------- 1 | [{"has_loop": false, "EAX": "0x4", "satisfiability": true, "constraints": {"zf": "0x1"}}, {"has_loop": false, "EAX": "0x3", "satisfiability": true, "constraints": {"zf": "0x0"}}] 2 | -------------------------------------------------------------------------------- /test/analysis/dg_test_03_expected.json: -------------------------------------------------------------------------------- 1 | [{"EAX": "0x3", "has_loop": false}, {"EAX": "0x5", "has_loop": true}] 2 | -------------------------------------------------------------------------------- /test/analysis/dg_test_03_implicit_expected.json: -------------------------------------------------------------------------------- 1 | [{"has_loop": false, "EAX": "0x3", "satisfiability": false, "constraints": {}}, {"has_loop": true, "EAX": "0x5", "satisfiability": false, "constraints": {}}] 2 | -------------------------------------------------------------------------------- /test/analysis/dg_test_04_expected.json: -------------------------------------------------------------------------------- 1 | [{"EAX": "EBX", "has_loop": false}] 2 | -------------------------------------------------------------------------------- /test/analysis/dg_test_04_implicit_expected.json: -------------------------------------------------------------------------------- 1 | [{"has_loop": false, "EAX": "EBX", "satisfiability": true, "constraints": {}}, {"has_loop": true, "EAX": "EBX", "satisfiability": false, "constraints": {}}] 2 | -------------------------------------------------------------------------------- /test/analysis/dg_test_05_expected.json: -------------------------------------------------------------------------------- 1 | [{"EAX": "0x3", "has_loop": false}] 2 | -------------------------------------------------------------------------------- /test/analysis/dg_test_05_implicit_expected.json: -------------------------------------------------------------------------------- 1 | [{"has_loop": false, "EAX": "0x3", "satisfiability": true, "constraints": {}}, {"has_loop": true, "EAX": "0x3", "satisfiability": false, "constraints": {}}] 2 | -------------------------------------------------------------------------------- /test/analysis/dg_test_06_expected.json: -------------------------------------------------------------------------------- 1 | [{"EAX": "0x1", "has_loop": false}, {"EAX": "0x2", "has_loop": false}] 2 | -------------------------------------------------------------------------------- /test/analysis/dg_test_06_implicit_expected.json: -------------------------------------------------------------------------------- 1 | [{"has_loop": false, "EAX": "0x1", "satisfiability": true, "constraints": {"EAX": "0xffffffff"}}, {"has_loop": false, "EAX": "0x2", "satisfiability": false, "constraints": {}}] 2 | -------------------------------------------------------------------------------- /test/analysis/dg_test_07_expected.json: -------------------------------------------------------------------------------- 1 | [{"EAX": "0x1", "ECX": "0x2", "has_loop": false}] 2 | -------------------------------------------------------------------------------- /test/analysis/dg_test_07_implicit_expected.json: -------------------------------------------------------------------------------- 1 | [{"has_loop": false, "EAX": "0x1", "constraints": {}, "satisfiability": true, "ECX": "0x2"}] 2 | -------------------------------------------------------------------------------- /test/analysis/dg_test_08_expected.json: -------------------------------------------------------------------------------- 1 | [{"ECX": "0x2", "has_loop": false}] 2 | -------------------------------------------------------------------------------- /test/analysis/dg_test_08_implicit_expected.json: -------------------------------------------------------------------------------- 1 | [{"has_loop": false, "constraints": {}, "satisfiability": true, "ECX": "0x2"}] 2 | -------------------------------------------------------------------------------- /test/analysis/dg_test_09_expected.json: -------------------------------------------------------------------------------- 1 | [{"EAX": "0x1", "EBX": "0x2", "has_loop": false}, 2 | {"EAX": "0x3", "EBX": "0x4", "has_loop": false}] 3 | -------------------------------------------------------------------------------- /test/analysis/dg_test_09_implicit_expected.json: -------------------------------------------------------------------------------- 1 | [{"has_loop": false, "EAX": "0x1", "EBX": "0x2", "satisfiability": true, "constraints": {}}, {"has_loop": false, "EAX": "0x3", "EBX": "0x4", "satisfiability": true, "constraints": {}}] 2 | -------------------------------------------------------------------------------- /test/analysis/dg_test_10_expected.json: -------------------------------------------------------------------------------- 1 | [{"EAX": "0x1", "EBX": "0x3", "has_loop": false}, {"EAX": "0x1", "EBX": "0x4", "has_loop": false}, {"EAX": "0x2", "EBX": "0x4", "has_loop": false}, {"EAX": "0x2", "EBX": "0x3", "has_loop": false}] 2 | -------------------------------------------------------------------------------- /test/analysis/dg_test_10_implicit_expected.json: -------------------------------------------------------------------------------- 1 | [{"has_loop": false, "EAX": "0x1", "EBX": "0x3", "satisfiability": true, "constraints": {"zf": "0x0"}}, {"has_loop": false, "EAX": "0x2", "EBX": "0x3", "satisfiability": false, "constraints": {}}, {"has_loop": false, "EAX": "0x1", "EBX": "0x4", "satisfiability": false, "constraints": {}}, {"has_loop": false, "EAX": "0x2", "EBX": "0x4", "satisfiability": true, "constraints": {"zf": "0x1"}}] 2 | -------------------------------------------------------------------------------- /test/analysis/dg_test_11_expected.json: -------------------------------------------------------------------------------- 1 | [{"has_loop": false, "EBX": "0x1"}, {"has_loop": false, "EBX": "0x3"}, {"has_loop": true, "EBX": "0x5"}] 2 | -------------------------------------------------------------------------------- /test/analysis/dg_test_11_implicit_expected.json: -------------------------------------------------------------------------------- 1 | [{"has_loop": false, "EBX": "0x1", "satisfiability": true, "constraints": {}}, {"has_loop": false, "EBX": "0x3", "satisfiability": true, "constraints": {}}, {"has_loop": true, "EBX": "0x5", "satisfiability": true, "constraints": {}}] 2 | -------------------------------------------------------------------------------- /test/arch/aarch64/unit/asm_test.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | 4 | from future.utils import viewitems 5 | 6 | from miasm.arch.aarch64.arch import mn_aarch64, base_expr, variable 7 | from miasm.core import parse_asm 8 | from miasm.expression.expression import * 9 | from miasm.core import asmblock 10 | from miasm.loader.strpatchwork import StrPatchwork 11 | from miasm.analysis.machine import Machine 12 | from miasm.jitter.csts import * 13 | from miasm.core.locationdb import LocationDB 14 | 15 | reg_and_id = dict(mn_aarch64.regs.all_regs_ids_byname) 16 | 17 | class Asm_Test(object): 18 | def __init__(self, jitter): 19 | self.loc_db = LocationDB() 20 | self.myjit = Machine("aarch64l").jitter(self.loc_db, jitter) 21 | self.myjit.init_stack() 22 | 23 | def __call__(self): 24 | self.asm() 25 | self.run() 26 | self.check() 27 | 28 | def asm(self): 29 | asmcfg = parse_asm.parse_txt(mn_aarch64, 'l', self.TXT, self.loc_db) 30 | # fix shellcode addr 31 | self.loc_db.set_location_offset(self.loc_db.get_name_location("main"), 0x0) 32 | s = StrPatchwork() 33 | patches = asmblock.asm_resolve_final(mn_aarch64, asmcfg) 34 | for offset, raw in viewitems(patches): 35 | s[offset] = raw 36 | 37 | self.assembly = bytes(s) 38 | 39 | def run(self): 40 | run_addr = 0 41 | self.myjit.vm.add_memory_page(run_addr, PAGE_READ | PAGE_WRITE, self.assembly) 42 | 43 | self.myjit.cpu.LR = 0x1337beef 44 | 45 | self.myjit.add_breakpoint(0x1337beef, lambda x:False) 46 | 47 | self.myjit.init_run(run_addr) 48 | self.myjit.continue_run() 49 | 50 | assert(self.myjit.pc == 0x1337beef) 51 | 52 | def check(self): 53 | raise NotImplementedError('abstract method') 54 | -------------------------------------------------------------------------------- /test/arch/aarch64/unit/mn_ubfm.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python2 2 | 3 | import sys 4 | 5 | from asm_test import Asm_Test 6 | from pdb import pm 7 | 8 | 9 | class Test_UBFM1(Asm_Test): 10 | TXT = ''' 11 | main: 12 | MOVZ X0, 0x5600 13 | UBFM X0, X0, 8, 15 14 | RET LR 15 | ''' 16 | def check(self): 17 | assert(self.myjit.cpu.X0 == 0x56) 18 | pass 19 | 20 | class Test_UBFM2(Asm_Test): 21 | TXT = ''' 22 | main: 23 | MOVZ X0, 0x56 24 | UBFM X0, X0, 4, 55 25 | RET LR 26 | ''' 27 | def check(self): 28 | assert(self.myjit.cpu.X0 == 0x5) 29 | pass 30 | 31 | 32 | if __name__ == "__main__": 33 | [test(*sys.argv[1:])() for test in [Test_UBFM1, Test_UBFM2 ]] 34 | -------------------------------------------------------------------------------- /test/arch/mep/asm/launch.py: -------------------------------------------------------------------------------- 1 | # Toshiba MeP-c4 - pytest unit tests wrapper 2 | # Guillaume Valadon 3 | 4 | from ut_helpers_asm import launch_tests 5 | 6 | from test_major_opcode_0 import TestMajor0; launch_tests(TestMajor0()) 7 | from test_major_opcode_1 import TestMajor1; launch_tests(TestMajor1()) 8 | from test_major_opcode_2 import TestMajor2; launch_tests(TestMajor2()) 9 | from test_major_opcode_3 import TestMajor3; launch_tests(TestMajor3()) 10 | from test_major_opcode_4 import TestMajor4; launch_tests(TestMajor4()) 11 | from test_major_opcode_5 import TestMajor5; launch_tests(TestMajor5()) 12 | from test_major_opcode_6 import TestMajor6; launch_tests(TestMajor6()) 13 | from test_major_opcode_7 import TestMajor7; launch_tests(TestMajor7()) 14 | from test_major_opcode_8 import TestMajor8; launch_tests(TestMajor8()) 15 | from test_major_opcode_9 import TestMajor9; launch_tests(TestMajor9()) 16 | from test_major_opcode_10 import TestMajor10; launch_tests(TestMajor10()) 17 | from test_major_opcode_11 import TestMajor11; launch_tests(TestMajor11()) 18 | from test_major_opcode_12 import TestMajor12; launch_tests(TestMajor12()) 19 | from test_major_opcode_13 import TestMajor13; launch_tests(TestMajor13()) 20 | from test_major_opcode_14 import TestMajor14; launch_tests(TestMajor14()) 21 | from test_major_opcode_15 import TestMajor15; launch_tests(TestMajor15()) 22 | from test_asm import TestMisc; launch_tests(TestMisc()) 23 | -------------------------------------------------------------------------------- /test/arch/mep/asm/test_asm.py: -------------------------------------------------------------------------------- 1 | # Toshiba MeP-c4 - Misc unit tests 2 | # Guillaume Valadon 3 | 4 | from __future__ import print_function 5 | from miasm.core.utils import decode_hex, encode_hex 6 | from miasm.arch.mep.arch import mn_mep 7 | 8 | class TestMisc(object): 9 | 10 | def test(self): 11 | 12 | # Disassemble & assemble unit tests 13 | unit_tests = [("ADD R1, 2", "6108")] 14 | unit_tests += [("JMP 0xC3FA38", "d9c8c3fa")] 15 | unit_tests += [("SLT3 R0, R8, R10", "08a2")] 16 | unit_tests += [("SB R9, (R4)", "0948")] 17 | unit_tests += [("SSARB 3(GP)", "13ec")] 18 | unit_tests += [("SWCPI C13, (R2+)", "3d20")] 19 | unit_tests += [("ADD3 R2, SP, 0x1C", "421c")] 20 | unit_tests += [("SW R7, 0x50(SP)", "4752")] 21 | 22 | for mn_str, mn_hex in unit_tests: 23 | print("-" * 49) # Tests separation 24 | 25 | # Disassemble 26 | mn_bin = decode_hex(mn_hex) 27 | mn = mn_mep.dis(mn_bin, "b") 28 | 29 | print("dis: %s -> %s" % (mn_hex.rjust(20), str(mn).rjust(20))) 30 | assert(str(mn) == mn_str) # disassemble assertion 31 | 32 | # Assemble and return all possible candidates 33 | instr = mn_mep.fromstring(str(mn), "b") 34 | instr.mode = "b" 35 | asm_list = [encode_hex(i).decode() for i in mn_mep.asm(instr)] 36 | 37 | # Print the results 38 | print("asm: %s -> %s" % ( 39 | mn_str.rjust(20), 40 | ", ".join(asm_list).rjust(20)) 41 | ) 42 | assert(mn_hex in asm_list) # assemble assertion 43 | -------------------------------------------------------------------------------- /test/arch/mep/asm/test_major_opcode_10.py: -------------------------------------------------------------------------------- 1 | # Toshiba MeP-c4 - Major Opcode #10 unit tests 2 | # Guillaume Valadon 3 | 4 | from ut_helpers_asm import check_instruction 5 | 6 | 7 | class TestMajor10(object): 8 | 9 | def test_BEQZ(self): 10 | """Test the BEQZ instruction""" 11 | 12 | # Top instructions 13 | check_instruction("BEQZ $11, 0xFFFFFF8C", "ab8c") 14 | check_instruction("BEQZ $4, 0x6", "a406") 15 | check_instruction("BEQZ $TP, 0x4", "ad04") 16 | check_instruction("BEQZ $11, 0x4", "ab04") 17 | check_instruction("BEQZ $12, 0xA", "ac0a") 18 | 19 | # Randomly chosen instructions 20 | check_instruction("BEQZ $0, 0x42", "a042") 21 | check_instruction("BEQZ $10, 0x6", "aa06") 22 | check_instruction("BEQZ $0, 0x8", "a008") 23 | check_instruction("BEQZ $12, 0x4", "ac04") 24 | check_instruction("BEQZ $1, 0x70", "a170") 25 | 26 | def test_BNEZ(self): 27 | """Test the BNEZ instruction""" 28 | 29 | # Top instructions 30 | check_instruction("BNEZ $7, 0x46", "a747") 31 | check_instruction("BNEZ $0, 0x40", "a041") 32 | check_instruction("BNEZ $9, 0x1C", "a91d") 33 | check_instruction("BNEZ $0, 0xFFFFFFF6", "a0f7") 34 | check_instruction("BNEZ $4, 0xA", "a40b") 35 | 36 | # Randomly chosen instructions 37 | check_instruction("BNEZ $7, 0xE", "a70f") 38 | check_instruction("BNEZ $11, 0xE", "ab0f") 39 | check_instruction("BNEZ $10, 0x28", "aa29") 40 | check_instruction("BNEZ $9, 0xFFFFFFAE", "a9af") 41 | check_instruction("BNEZ $9, 0xE", "a90f") 42 | -------------------------------------------------------------------------------- /test/arch/mep/asm/test_major_opcode_11.py: -------------------------------------------------------------------------------- 1 | # Toshiba MeP-c4 - Major Opcode #11 unit tests 2 | # Guillaume Valadon 3 | 4 | from ut_helpers_asm import check_instruction 5 | 6 | 7 | class TestMajor11(object): 8 | 9 | def test_BRA(self): 10 | """Test the BRA instruction""" 11 | 12 | # Top instructions 13 | check_instruction("BRA 0xFFFFF9B4", "b9b4") 14 | check_instruction("BRA 0x34", "b034") 15 | check_instruction("BRA 0x16", "b016") 16 | check_instruction("BRA 0x46", "b046") 17 | check_instruction("BRA 0xFFFFFF98", "bf98") 18 | 19 | # Randomly chosen instructions 20 | check_instruction("BRA 0x2AA", "b2aa") 21 | check_instruction("BRA 0x22", "b022") 22 | check_instruction("BRA 0x12", "b012") 23 | check_instruction("BRA 0x7FE", "b7fe") 24 | check_instruction("BRA 0x34", "b034") 25 | 26 | def test_BSR(self): 27 | """Test the BSR instruction""" 28 | 29 | # Top instructions 30 | check_instruction("BSR 0xFFFFFF22", "bf23", multi=2) 31 | check_instruction("BSR 0x716", "b717", multi=2) 32 | check_instruction("BSR 0xFFFFFE36", "be37", multi=2) 33 | check_instruction("BSR 0xFFFFFBB2", "bbb3", multi=2) 34 | check_instruction("BSR 0xFFFFFCCE", "bccf", multi=2) 35 | 36 | # Randomly chosen instructions 37 | check_instruction("BSR 0xFFFFFED4", "bed5", multi=2) 38 | check_instruction("BSR 0xFFFFFF62", "bf63", multi=2) 39 | check_instruction("BSR 0xFFFFFF36", "bf37", multi=2) 40 | check_instruction("BSR 0xFFFFFBD0", "bbd1", multi=2) 41 | check_instruction("BSR 0x5AA", "b5ab", multi=2) 42 | 43 | # Manually crafted 44 | check_instruction("BSR 0xC67BFA", "bfa3", offset=0xc67c58) 45 | -------------------------------------------------------------------------------- /test/arch/mep/asm/test_major_opcode_5.py: -------------------------------------------------------------------------------- 1 | # Toshiba MeP-c4 - Major Opcode #5 unit tests 2 | # Guillaume Valadon 3 | 4 | from ut_helpers_asm import check_instruction 5 | 6 | 7 | class TestMajor5(object): 8 | 9 | def test_MOV(self): 10 | """Test the MOV instruction""" 11 | 12 | # Top instructions 13 | check_instruction("MOV $2, 0", "5200", multi=2) 14 | check_instruction("MOV $12, 0", "5c00", multi=2) 15 | check_instruction("MOV $4, 0", "5400", multi=2) 16 | check_instruction("MOV $0, 0", "5000", multi=2) 17 | check_instruction("MOV $0, 3", "5003", multi=2) 18 | 19 | # Randomly chosen instructions 20 | check_instruction("MOV $8, 84", "5854", multi=2) 21 | check_instruction("MOV $SP, 108", "5f6c", multi=2) 22 | check_instruction("MOV $12, 80", "5c50", multi=2) 23 | check_instruction("MOV $TP, 59", "5d3b", multi=2) 24 | check_instruction("MOV $9, 89", "5959", multi=2) 25 | -------------------------------------------------------------------------------- /test/arch/mep/asm/test_major_opcode_9.py: -------------------------------------------------------------------------------- 1 | # Toshiba MeP-c4 - Major Opcode #9 unit tests 2 | # Guillaume Valadon 3 | 4 | from ut_helpers_asm import check_instruction 5 | 6 | 7 | class TestMajor9(object): 8 | 9 | def test_ADD3(self): 10 | """Test the ADD3 instruction""" 11 | 12 | # Top instructions 13 | check_instruction("ADD3 $10, $4, $0", "940a") 14 | check_instruction("ADD3 $3, $0, $0", "9003") 15 | check_instruction("ADD3 $12, $4, $0", "940c") 16 | check_instruction("ADD3 $7, $12, $0", "9c07") 17 | check_instruction("ADD3 $TP, $4, $0", "940d") 18 | 19 | # Randomly chosen instructions 20 | check_instruction("ADD3 $4, $1, $9", "9194") 21 | check_instruction("ADD3 $7, $12, $9", "9c97") 22 | check_instruction("ADD3 $12, $9, $SP", "99fc") 23 | check_instruction("ADD3 $12, $TP, $7", "9d7c") 24 | check_instruction("ADD3 $4, $8, $SP", "98f4") 25 | -------------------------------------------------------------------------------- /test/arch/mep/ir/launch.py: -------------------------------------------------------------------------------- 1 | # Toshiba MeP-c4 - pytest unit tests wrapper 2 | # Guillaume Valadon 3 | 4 | from ut_helpers_ir import launch_tests 5 | 6 | from test_arithmetic import TestArithmetic; launch_tests(TestArithmetic()) 7 | from test_bitmanipulation import TestBitManipulation; launch_tests(TestBitManipulation()) 8 | from test_branchjump import TestBranchJump; launch_tests(TestBranchJump()) 9 | from test_control import TestControl; launch_tests(TestControl()) 10 | from test_coprocessor import TestCoprocessor; launch_tests(TestCoprocessor()) 11 | from test_datacache import TestDataCache; launch_tests(TestDataCache()) 12 | from test_debug import TestDebug; launch_tests(TestDebug()) 13 | from test_divide import TestDivide; launch_tests(TestDivide()) 14 | from test_extension import TestExtension; launch_tests(TestExtension()) 15 | from test_ldz import TestLdz; launch_tests(TestLdz()) 16 | from test_loadstore import TestLoadStore; launch_tests(TestLoadStore()) 17 | from test_logical import TestLogical; launch_tests(TestLogical()) 18 | from test_move import TestMove; launch_tests(TestMove()) 19 | from test_multiply import TestMultiply; launch_tests(TestMultiply()) 20 | from test_repeat import TestRepeat; launch_tests(TestRepeat()) 21 | from test_shift import TestShift; launch_tests(TestShift()) 22 | from test_ir import TestMisc; launch_tests(TestMisc()) 23 | -------------------------------------------------------------------------------- /test/arch/mep/ir/test_datacache.py: -------------------------------------------------------------------------------- 1 | # Toshiba MeP-c4 - Data cache instructions unit tests 2 | # Guillaume Valadon 3 | 4 | from ut_helpers_ir import exec_instruction 5 | 6 | 7 | class TestDataCache(object): 8 | 9 | def test_cache(self): 10 | """Test CACHE execution""" 11 | 12 | # CACHE imm4, (Rm) 13 | exec_instruction("CACHE 0x0, (R0)", [], []) 14 | -------------------------------------------------------------------------------- /test/arch/mep/ir/test_debug.py: -------------------------------------------------------------------------------- 1 | # Toshiba MeP-c4 - Debug instructions unit tests 2 | # Guillaume Valadon 3 | 4 | from ut_helpers_ir import exec_instruction 5 | 6 | from miasm.expression.expression import ExprId, ExprInt, ExprCond, ExprOp 7 | 8 | 9 | class TestDebug(object): 10 | 11 | def test_dret(self): 12 | """Test DRET execution""" 13 | 14 | # DRET 15 | exec_instruction("DRET", 16 | [(ExprId("DEPC", 32), ExprInt(2, 32)), 17 | (ExprId("DBG", 32), ExprInt(0xFFFFFFFF, 32))], 18 | [(ExprId("PC", 32), ExprInt(2, 32)), 19 | (ExprId("DBG", 32), ExprInt(0xFFFFBFFF, 32))]) 20 | 21 | exec_instruction("DRET", 22 | [(ExprId("DEPC", 32), ExprInt(2, 32)), 23 | (ExprId("DBG", 32), ExprInt(2**15, 32))], 24 | [(ExprId("PC", 32), ExprInt(2, 32)), 25 | (ExprId("DBG", 32), ExprInt(2**15, 32))]) 26 | 27 | def test_dbreak(self): 28 | """Test DBREAK execution""" 29 | 30 | # DBREAK 31 | exec_instruction("DBREAK", 32 | [(ExprId("DBG", 32), ExprInt(0, 32))], 33 | [(ExprId("DBG", 32), ExprInt(0b10, 32))]) 34 | -------------------------------------------------------------------------------- /test/arch/mep/ir/test_extension.py: -------------------------------------------------------------------------------- 1 | # Toshiba MeP-c4 - Byte/Halfword extension instructions unit tests 2 | # Guillaume Valadon 3 | 4 | from ut_helpers_ir import exec_instruction 5 | 6 | from miasm.expression.expression import ExprId, ExprMem, ExprInt 7 | 8 | 9 | class TestExtension(object): 10 | 11 | def test_extb(self): 12 | """Test EXTB execution""" 13 | 14 | # EXTB Rn 15 | exec_instruction("EXTB R1", 16 | [(ExprId("R1", 32), ExprInt(0xFE, 32))], 17 | [(ExprId("R1", 32), ExprInt(0xFFFFFFFE, 32))]) 18 | 19 | exec_instruction("EXTB R2", 20 | [(ExprId("R2", 32), ExprInt(0x80, 32))], 21 | [(ExprId("R2", 32), ExprInt(0xFFFFFF80, 32))]) 22 | 23 | def test_exth(self): 24 | """Test EXTH execution""" 25 | 26 | # EXTH Rn 27 | exec_instruction("EXTH R1", 28 | [(ExprId("R1", 32), ExprInt(0xFFFE, 32))], 29 | [(ExprId("R1", 32), ExprInt(0xFFFFFFFE, 32))]) 30 | 31 | exec_instruction("EXTH R2", 32 | [(ExprId("R2", 32), ExprInt(0x8000, 32))], 33 | [(ExprId("R2", 32), ExprInt(0xFFFF8000, 32))]) 34 | 35 | def test_extub(self): 36 | """Test EXTUB execution""" 37 | 38 | # EXTUB Rn 39 | exec_instruction("EXTUB R1", 40 | [(ExprId("R1", 32), ExprInt(0xFFFFFFFE, 32))], 41 | [(ExprId("R1", 32), ExprInt(0xFE, 32))]) 42 | 43 | exec_instruction("EXTUB R2", 44 | [(ExprId("R2", 32), ExprInt(0xFFFFFF80, 32))], 45 | [(ExprId("R2", 32), ExprInt(0x80, 32))]) 46 | 47 | def test_extuh(self): 48 | """Test EXTUH execution""" 49 | 50 | # EXTUH Rn 51 | exec_instruction("EXTUH R1", 52 | [(ExprId("R1", 32), ExprInt(0xFFFFFFFE, 32))], 53 | [(ExprId("R1", 32), ExprInt(0xFFFE, 32))]) 54 | 55 | exec_instruction("EXTUH R2", 56 | [(ExprId("R2", 32), ExprInt(0xFFFF8000, 32))], 57 | [(ExprId("R2", 32), ExprInt(0x8000, 32))]) 58 | -------------------------------------------------------------------------------- /test/arch/mep/ir/test_ldz.py: -------------------------------------------------------------------------------- 1 | # Toshiba MeP-c4 - Leading zero instructions unit tests 2 | # Guillaume Valadon 3 | 4 | from ut_helpers_ir import exec_instruction 5 | 6 | from miasm.expression.expression import ExprId, ExprInt, ExprCond, ExprOp 7 | 8 | 9 | class TestLdz(object): 10 | 11 | def test_ldz(self): 12 | """Test LDZ execution""" 13 | 14 | # LDZ Rn,Rm 15 | exec_instruction("LDZ R0, R1", 16 | [(ExprId("R1", 32), ExprInt(0x80000000, 32))], 17 | [(ExprId("R0", 32), ExprInt(0, 32))]) 18 | 19 | exec_instruction("LDZ R0, R1", 20 | [(ExprId("R1", 32), ExprInt(0x40000000, 32))], 21 | [(ExprId("R0", 32), ExprInt(1, 32))]) 22 | 23 | exec_instruction("LDZ R0, R1", 24 | [(ExprId("R1", 32), ExprInt(0b1111, 32))], 25 | [(ExprId("R0", 32), ExprInt(28, 32))]) 26 | 27 | exec_instruction("LDZ R0, R1", 28 | [(ExprId("R1", 32), ExprInt(0b0100, 32))], 29 | [(ExprId("R0", 32), ExprInt(29, 32))]) 30 | 31 | exec_instruction("LDZ R0, R1", 32 | [(ExprId("R1", 32), ExprInt(0b0010, 32))], 33 | [(ExprId("R0", 32), ExprInt(30, 32))]) 34 | 35 | exec_instruction("LDZ R0, R1", 36 | [(ExprId("R1", 32), ExprInt(0b0001, 32))], 37 | [(ExprId("R0", 32), ExprInt(31, 32))]) 38 | 39 | exec_instruction("LDZ R0, R1", 40 | [(ExprId("R1", 32), ExprInt(0b0000, 32))], 41 | [(ExprId("R0", 32), ExprInt(32, 32))]) 42 | -------------------------------------------------------------------------------- /test/arch/mep/ir/test_move.py: -------------------------------------------------------------------------------- 1 | # Toshiba MeP-c4 - Move instructions unit tests 2 | # Guillaume Valadon 3 | 4 | from ut_helpers_ir import exec_instruction 5 | 6 | from miasm.expression.expression import ExprId, ExprMem, ExprInt 7 | 8 | 9 | class TestMove(object): 10 | 11 | def test_mov(self): 12 | """Test MOV execution""" 13 | 14 | # MOV Rn,Rm 15 | exec_instruction("MOV R1, R2", 16 | [(ExprId("R2", 32), ExprInt(0x2807, 32))], 17 | [(ExprId("R1", 32), ExprInt(0x2807, 32))]) 18 | 19 | # MOV Rn,imm8 20 | exec_instruction("MOV R1, 0x28", 21 | [], 22 | [(ExprId("R1", 32), ExprInt(0x28, 32))]) 23 | 24 | exec_instruction("MOV R1, 0x80", 25 | [], 26 | [(ExprId("R1", 32), ExprInt(0xFFFFFF80, 32))]) 27 | 28 | # MOV Rn,imm16 29 | exec_instruction("MOV R1, 0x2807", 30 | [], 31 | [(ExprId("R1", 32), ExprInt(0x2807, 32))], 32 | index=1) 33 | 34 | def test_movu(self): 35 | """Test MOVU execution""" 36 | 37 | # MOVU Rn[0-7],imm24 38 | exec_instruction("MOVU R1, 0xFF2807", 39 | [], 40 | [(ExprId("R1", 32), ExprInt(0xFF2807, 32))], 41 | index=1) 42 | 43 | # MOVU Rn,imm16 44 | exec_instruction("MOVU R10, 0x2807", 45 | [], 46 | [(ExprId("R10", 32), ExprInt(0x2807, 32))]) 47 | 48 | def test_movh(self): 49 | """Test MOVH execution""" 50 | 51 | # MOVH Rn,imm16 52 | exec_instruction("MOVH R1, 1", 53 | [], 54 | [(ExprId("R1", 32), ExprInt(0x10000, 32))]) 55 | 56 | exec_instruction("MOVH R1, 0xFFFF", 57 | [], 58 | [(ExprId("R1", 32), ExprInt(0xFFFF0000, 32))]) 59 | -------------------------------------------------------------------------------- /test/arch/mep/ir/test_repeat.py: -------------------------------------------------------------------------------- 1 | # Toshiba MeP-c4 - Repeat instructions unit tests 2 | # Guillaume Valadon 3 | 4 | from ut_helpers_ir import exec_instruction 5 | 6 | from miasm.expression.expression import ExprId, ExprInt, ExprCond, ExprOp 7 | 8 | 9 | class TestRepeat(object): 10 | 11 | def test_repeat(self): 12 | """Test REPEAT execution""" 13 | 14 | # REPEAT Rn, disp17.align2 15 | exec_instruction("REPEAT R0, 0x42", 16 | [(ExprId("PC", 32), ExprInt(2, 32)), 17 | (ExprId("R0", 32), ExprInt(0x28, 32))], 18 | [(ExprId("RPB", 32), ExprInt(6, 32)), 19 | (ExprId("RPE", 32), ExprInt(0x44, 32)), 20 | (ExprId("RPC", 32), ExprInt(0x28, 32))]) 21 | 22 | def test_erepeat(self): 23 | """Test EREPEAT execution""" 24 | 25 | # EREPEAT disp17.align2 26 | exec_instruction("EREPEAT 0x42", 27 | [(ExprId("PC", 32), ExprInt(0, 32))], 28 | [(ExprId("RPB", 32), ExprInt(4, 32)), 29 | (ExprId("RPE", 32), ExprInt(0x43, 32))]) 30 | -------------------------------------------------------------------------------- /test/arch/mep/jit/launch.py: -------------------------------------------------------------------------------- 1 | # Toshiba MeP-c4 - pytest unit tests wrapper 2 | # Guillaume Valadon 3 | 4 | from ut_helpers_jit import launch_tests 5 | 6 | from test_jit_branchjump import TestBranchJump; launch_tests(TestBranchJump()) 7 | from test_jit_repeat import TestRepeat; launch_tests(TestRepeat()) 8 | -------------------------------------------------------------------------------- /test/arch/mep/jit/test_jit_branchjump.py: -------------------------------------------------------------------------------- 1 | # Toshiba MeP-c4 - Branch/Jump instructions JIT unit tests 2 | # Guillaume Valadon 3 | 4 | from ut_helpers_jit import jit_instructions 5 | 6 | 7 | class TestBranchJump(object): 8 | 9 | def test_blti(self): 10 | """Test BLTI jit""" 11 | 12 | # Instructions that will be jitted 13 | instructions = "MOV R0, 1\n" 14 | instructions += "BLTI R0, 0x2, 0x6\n" 15 | instructions += "MOV R0, 0\n" 16 | instructions += "MOV R1, 1" 17 | 18 | # Jit 19 | jitter = jit_instructions(instructions) 20 | 21 | # Check expected results 22 | assert(jitter.cpu.R0 == 1) 23 | assert(jitter.cpu.R1 == 1) 24 | -------------------------------------------------------------------------------- /test/arch/mep/jit/ut_helpers_jit.py: -------------------------------------------------------------------------------- 1 | # Toshiba MeP-c4 - unit tests helpers 2 | # Guillaume Valadon 3 | 4 | from __future__ import print_function 5 | 6 | from miasm.analysis.machine import Machine 7 | from miasm.jitter.csts import PAGE_READ, PAGE_WRITE 8 | from miasm.core.locationdb import LocationDB 9 | 10 | 11 | def jit_instructions(mn_str): 12 | """JIT instructions and return the jitter object.""" 13 | 14 | # Get the miasm Machine 15 | machine = Machine("mepb") 16 | mn_mep = machine.mn() 17 | loc_db = LocationDB() 18 | 19 | # Assemble the instructions 20 | asm = b"" 21 | for instr_str in mn_str.split("\n"): 22 | instr = mn_mep.fromstring(instr_str, "b") 23 | instr.mode = "b" 24 | asm += mn_mep.asm(instr)[0] 25 | 26 | # Init the jitter and add the assembled instructions to memory 27 | jitter = machine.jitter(loc_db, jit_type="gcc") 28 | jitter.vm.add_memory_page(0, PAGE_READ | PAGE_WRITE, asm) 29 | 30 | # Set the breakpoint 31 | jitter.add_breakpoint(len(asm), lambda x: False) 32 | 33 | # Jit the instructions 34 | #jitter.init_stack() 35 | jitter.init_run(0) 36 | jitter.continue_run() 37 | 38 | return jitter 39 | 40 | 41 | def launch_tests(obj): 42 | """Call test methods by name""" 43 | 44 | test_methods = [name for name in dir(obj) if name.startswith("test")] 45 | 46 | for method in test_methods: 47 | print(method) 48 | try: 49 | getattr(obj, method)() 50 | except AttributeError as e: 51 | print("Method not found: %s" % method) 52 | assert(False) 53 | print('-' * 42) 54 | -------------------------------------------------------------------------------- /test/arch/mips32/unit/asm_test.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | 4 | from future.utils import viewitems 5 | 6 | from miasm.arch.mips32.arch import mn_mips32 7 | from miasm.core import parse_asm 8 | from miasm.expression.expression import * 9 | from miasm.core import asmblock 10 | from miasm.loader.strpatchwork import StrPatchwork 11 | from miasm.analysis.machine import Machine 12 | from miasm.jitter.csts import * 13 | from miasm.core.locationdb import LocationDB 14 | 15 | 16 | reg_and_id = dict(mn_mips32.regs.all_regs_ids_byname) 17 | 18 | class Asm_Test(object): 19 | 20 | def __init__(self, jitter): 21 | self.loc_db = LocationDB() 22 | self.myjit = Machine("mips32l").jitter(self.loc_db, jitter) 23 | self.myjit.init_stack() 24 | 25 | def __call__(self): 26 | self.asm() 27 | self.run() 28 | self.check() 29 | 30 | def asm(self): 31 | asmcfg = parse_asm.parse_txt(mn_mips32, 'l', self.TXT, self.loc_db) 32 | # fix shellcode addr 33 | self.loc_db.set_location_offset(self.loc_db.get_name_location("main"), 0x0) 34 | s = StrPatchwork() 35 | patches = asmblock.asm_resolve_final(mn_mips32, asmcfg) 36 | for offset, raw in viewitems(patches): 37 | s[offset] = raw 38 | 39 | s = bytes(s) 40 | self.assembly = s 41 | 42 | def run(self): 43 | run_addr = 0 44 | self.myjit.vm.add_memory_page( 45 | run_addr, PAGE_READ | PAGE_WRITE, self.assembly) 46 | 47 | self.myjit.cpu.RA = 0x1337beef 48 | 49 | self.myjit.add_breakpoint(0x1337beef, lambda x: False) 50 | 51 | self.myjit.init_run(run_addr) 52 | self.myjit.continue_run() 53 | 54 | assert(self.myjit.pc == 0x1337beef) 55 | 56 | def check(self): 57 | raise NotImplementedError('abstract method') 58 | -------------------------------------------------------------------------------- /test/arch/mips32/unit/mn_bcc.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python2 2 | 3 | import sys 4 | 5 | from asm_test import Asm_Test 6 | 7 | 8 | class Test_BCC(Asm_Test): 9 | MYSTRING = "test string" 10 | TXT = ''' 11 | main: 12 | ADDIU A0, V0, mystr 13 | strlen: 14 | LBU V0, 0(A0) 15 | BEQ V0, ZERO, SKIP 16 | ADDU V1, ZERO, ZERO 17 | loop: 18 | ADDIU A0, A0, 1 19 | LBU V0, 0(A0) 20 | BNE V0, ZERO, loop 21 | ADDIU V1, V1, 1 22 | SKIP: 23 | JR RA 24 | ADDU V0, V1, ZERO 25 | 26 | mystr: 27 | .string "%s" 28 | ''' % MYSTRING 29 | 30 | def check(self): 31 | assert(self.myjit.cpu.V0 == len(self.MYSTRING)) 32 | 33 | 34 | if __name__ == "__main__": 35 | [test(*sys.argv[1:])() for test in [Test_BCC]] 36 | -------------------------------------------------------------------------------- /test/arch/x86/qemu/expected/test_bsx.exp: -------------------------------------------------------------------------------- 1 | bsrw A=00000000 R=12345678 1 2 | bsrw A=12340128 R=12340008 0 3 | bsfw A=00000000 R=12345678 1 4 | bsfw A=12340128 R=12340003 0 5 | bsrl A=00000000 R=12345678 1 6 | bsrl A=00340128 R=00000015 0 7 | bsfl A=00000000 R=12345678 1 8 | bsfl A=00340128 R=00000003 0 9 | -------------------------------------------------------------------------------- /test/arch/x86/qemu/expected/test_code16.exp: -------------------------------------------------------------------------------- 1 | func1() = 0x00000001 2 | func2() = 0x00005678 spdec=2 3 | func3() = 0x00000025 4 | -------------------------------------------------------------------------------- /test/arch/x86/qemu/expected/test_conv.exp: -------------------------------------------------------------------------------- 1 | cbw A=8234a6f8 R=8234fff8 2 | cwde A=8234a6f8 R=ffffa6f8 3 | cwd A=8234a6f8 R=8234a6f8:8345ffff 4 | cdq A=8234a6f8 R=8234a6f8:ffffffff 5 | bswapl : A=12345678 R=78563412 6 | -------------------------------------------------------------------------------- /test/arch/x86/qemu/expected/test_lea.exp: -------------------------------------------------------------------------------- 1 | lea 0x4000 = 00004000 2 | lea (%%eax) = 00000001 3 | lea (%%ebx) = 00000002 4 | lea (%%ecx) = 00000004 5 | lea (%%edx) = 00000008 6 | lea (%%esi) = 00000010 7 | lea (%%edi) = 00000020 8 | lea 0x40(%%eax) = 00000041 9 | lea 0x40(%%ebx) = 00000042 10 | lea 0x40(%%ecx) = 00000044 11 | lea 0x40(%%edx) = 00000048 12 | lea 0x40(%%esi) = 00000050 13 | lea 0x40(%%edi) = 00000060 14 | lea 0x4000(%%eax) = 00004001 15 | lea 0x4000(%%ebx) = 00004002 16 | lea 0x4000(%%ecx) = 00004004 17 | lea 0x4000(%%edx) = 00004008 18 | lea 0x4000(%%esi) = 00004010 19 | lea 0x4000(%%edi) = 00004020 20 | lea (%%eax, %%ecx) = 00000005 21 | lea (%%ebx, %%edx) = 0000000a 22 | lea (%%ecx, %%ecx) = 00000008 23 | lea (%%edx, %%ecx) = 0000000c 24 | lea (%%esi, %%ecx) = 00000014 25 | lea (%%edi, %%ecx) = 00000024 26 | lea 0x40(%%eax, %%ecx) = 00000045 27 | lea 0x4000(%%ebx, %%edx) = 0000400a 28 | lea (%%ecx, %%ecx, 2) = 0000000c 29 | lea (%%edx, %%ecx, 4) = 00000018 30 | lea (%%esi, %%ecx, 8) = 00000030 31 | lea (,%%eax, 2) = 00000002 32 | lea (,%%ebx, 4) = 00000008 33 | lea (,%%ecx, 8) = 00000020 34 | lea 0x40(,%%eax, 2) = 00000042 35 | lea 0x40(,%%ebx, 4) = 00000048 36 | lea 0x40(,%%ecx, 8) = 00000060 37 | lea -10(%%ecx, %%ecx, 2) = 00000002 38 | lea -10(%%edx, %%ecx, 4) = 0000000e 39 | lea -10(%%esi, %%ecx, 8) = 00000026 40 | lea 0x4000(%%ecx, %%ecx, 2) = 0000400c 41 | lea 0x4000(%%edx, %%ecx, 4) = 00004018 42 | lea 0x4000(%%esi, %%ecx, 8) = 00004030 43 | lea 0x4000 = 00004000 44 | lea (%%bx) = 00000002 45 | lea (%%si) = 00000010 46 | lea (%%di) = 00000020 47 | lea 0x40(%%bx) = 00000042 48 | lea 0x40(%%si) = 00000050 49 | lea 0x40(%%di) = 00000060 50 | lea 0x4000(%%bx) = 00004002 51 | lea 0x4000(%%si) = 00004010 52 | lea (%%bx,%%si) = 00000012 53 | lea (%%bx,%%di) = 00000022 54 | lea 0x40(%%bx,%%si) = 00000052 55 | lea 0x40(%%bx,%%di) = 00000062 56 | lea 0x4000(%%bx,%%si) = 00004012 57 | lea 0x4000(%%bx,%%di) = 00004022 58 | -------------------------------------------------------------------------------- /test/arch/x86/qemu/expected/test_misc.exp: -------------------------------------------------------------------------------- 1 | xlat: EAX=12345688 2 | func_lret=87654321 3 | func_iret=abcd4321 4 | popl esp=09abcdef 5 | popw esp=00bc6058 6 | -------------------------------------------------------------------------------- /test/arch/x86/qemu/expected/test_segs.exp: -------------------------------------------------------------------------------- 1 | FS[1] = aa 2 | GS[1] = 55 3 | DS[1] = aa 4 | SS[tmp] = a5 5 | FS:reg = 0017:abcdef12 6 | larw: Z=1 1234f200 7 | larl: Z=1 00c0f200 8 | lslw: Z=1 12341fff 9 | lsll: Z=1 00001fff 10 | larw: Z=0 12345678 11 | larl: Z=0 12345678 12 | lslw: Z=0 12345678 13 | lsll: Z=0 12345678 14 | arplw A=1234567b B=0762123d R=1234567b z=0 15 | arplw A=12345679 B=0762123f R=1234567b z=1 16 | arplw A=12345679 B=0762123d R=12345679 z=0 17 | -------------------------------------------------------------------------------- /test/arch/x86/qemu/expected/test_self_modifying_code.exp: -------------------------------------------------------------------------------- 1 | self modifying code: 2 | func1 = 0x1 3 | func2 = 0x2 4 | func3 = 0x3 5 | func4 = 0x4 6 | smc_code2(2) = 2 7 | smc_code2(3) = 3 8 | smc_code2(4) = 4 9 | -------------------------------------------------------------------------------- /test/arch/x86/qemu/expected/test_single_step.exp: -------------------------------------------------------------------------------- 1 | EIP=08051baf 2 | EIP=08051bb4 3 | EIP=08051bb9 4 | EIP=08051bba 5 | EIP=08051bb4 6 | EIP=08051bb9 7 | EIP=08051bba 8 | EIP=08051bb4 9 | EIP=08051bb9 10 | EIP=08051bba 11 | EIP=08051bbc 12 | EIP=08051bc1 13 | EIP=08051bc6 14 | EIP=08051bcb 15 | EIP=08051bcd 16 | EIP=08051bd2 17 | EIP=08051bd2 18 | EIP=08051bd2 19 | EIP=08051bd4 20 | EIP=08051bd9 21 | EIP=08051bdb 22 | EIP=08051be0 23 | EIP=08051be5 24 | EIP=08051bea 25 | EIP=08051bec 26 | EIP=08051bf1 27 | EIP=08051bf1 28 | EIP=08051bf1 29 | EIP=08051bf1 30 | EIP=08051bf3 31 | EIP=08051bf8 32 | EIP=08051bff 33 | EIP=08051c01 34 | EIP=08051c08 35 | EIP=08051c0d 36 | EIP=08051c16 37 | EIP=08051c1b 38 | EIP=08051c1c 39 | EIP=08051c22 40 | EIP=08051c27 41 | EIP=08051c28 42 | EIP=08051c2f 43 | EIP=08051c30 44 | val=43986 45 | sstep_buf2[0] = 1 46 | sstep_buf2[1] = 2 47 | sstep_buf2[2] = 3 48 | sstep_buf2[3] = 4 49 | -------------------------------------------------------------------------------- /test/arch/x86/qemu/expected/test_xchg.exp: -------------------------------------------------------------------------------- 1 | xchgl A=fbca7654 B=12345678 2 | xchgw A=12347654 B=fbca5678 3 | xchgb A=12345654 B=fbca7678 4 | xchgl A=fbca7654 B=12345678 5 | xchgw A=12347654 B=fbca5678 6 | xchgb A=12345654 B=fbca7678 7 | xaddl A=fbca7654 B=0dfecccc 8 | xaddw A=12347654 B=fbcacccc 9 | xaddb A=12345654 B=fbca76cc 10 | xaddl same res=2468acf0 11 | xaddl A=fbca7654 B=0dfecccc 12 | xaddw A=12347654 B=fbcacccc 13 | xaddb A=12345654 B=fbca76cc 14 | cmpxchgl EAX=fbca7654 A=12345678 C=12345678 15 | cmpxchgw EAX=fbca7654 A=12345678 C=fbca5678 16 | cmpxchgb EAX=fbca7654 A=12345678 C=fbca7678 17 | cmpxchgl EAX=fffefdfc A=12345678 C=fbca7654 18 | cmpxchgw EAX=fffefdfc A=12345678 C=fbca7654 19 | cmpxchgb EAX=fffefdfc A=12345678 C=fbca7654 20 | cmpxchgl EAX=fbca7654 A=12345678 C=12345678 21 | cmpxchgw EAX=fbca7654 A=12345678 C=fbca5678 22 | cmpxchgb EAX=fbca7654 A=12345678 C=fbca7678 23 | cmpxchgl EAX=fffefdfc A=12345678 C=fbca7654 24 | cmpxchgw EAX=fffefdfc A=12345678 C=fbca7654 25 | cmpxchgb EAX=fffefdfc A=12345678 C=fbca7654 26 | cmpxchg8b: eax=65423456 edx=000fbca7 op1=000fbca765423456 CC=00 27 | cmpxchg8b: eax=6789abcd edx=00012345 op1=0006532432432434 CC=40 28 | -------------------------------------------------------------------------------- /test/arch/x86/qemu/expected_x86_64/test_conv.exp: -------------------------------------------------------------------------------- 1 | cbw A=82340d358234a6f8 R=82340d358234fff8 2 | cwde A=82340d358234a6f8 R=00000000ffffa6f8 3 | cdqe A=82340d358234a6f8 R=ffffffff8234a6f8 4 | cwd A=82340d358234a6f8 R=82340d358234a6f8:83450a3f8345ffff 5 | cdq A=82340d358234a6f8 R=82340d358234a6f8:00000000ffffffff 6 | cqo A=82340d358234a6f8 R=82340d358234a6f8:ffffffffffffffff 7 | bswapl : A=1234fdb512345678 R=0000000078563412 8 | bswapq : A=1234fdb512345678 R=78563412b5fd3412 9 | -------------------------------------------------------------------------------- /test/arch/x86/qemu/expected_x86_64/test_fxsave.exp: -------------------------------------------------------------------------------- 1 | fpuc=037f 2 | fpus=2800 3 | fptag=00e0 4 | ST0: b17217f7d1cf79ac 3ffe 5 | ST1: c90fdaa22168c235 4000 6 | ST2: 8000000000000000 3fff 7 | mxcsr=00001f80 8 | xmm0: 456723c698694873dc515cff944a58ec 9 | xmm1: 25252525252525252525252525252525 10 | xmm2: 00000002fffffffaffff15a000000064 11 | xmm3: 00000000000000000000000000000000 12 | xmm4: 000000ffffffff000000000000000000 13 | xmm5: c0180000000000004000000000000000 14 | xmm6: 4004ccccc0c00000c00b333333333333 15 | xmm7: 1f297ccd58bad7ab41f21efba9e3e146 16 | xmm8: 00000000000000000000000000000000 17 | xmm9: 00000000000000000000000000000000 18 | xmm10: ffffff00000000000000000000000000 19 | xmm11: 000000000000000000000000000000ff 20 | xmm12: 00000000000000000000000000000000 21 | xmm13: 3ff66666666666660000000000000000 22 | xmm14: 3c3a1edf000000000000000000000000 23 | xmm15: 456723c698694873dc515cff944a58ec 24 | -------------------------------------------------------------------------------- /test/arch/x86/qemu/expected_x86_64/test_loop.exp: -------------------------------------------------------------------------------- 1 | jecxz ECX=0000000000000000 ZF=0 r=1 2 | jecxz ECX=0000000000000000 ZF=1 r=1 3 | jecxz ECX=0000000000000001 ZF=0 r=0 4 | jecxz ECX=0000000000000001 ZF=1 r=0 5 | jecxz ECX=0000000000010000 ZF=0 r=0 6 | jecxz ECX=0000000000010000 ZF=1 r=0 7 | jecxz ECX=0000000000010001 ZF=0 r=0 8 | jecxz ECX=0000000000010001 ZF=1 r=0 9 | jecxz ECX=0000000100000000 ZF=0 r=1 10 | jecxz ECX=0000000100000000 ZF=1 r=1 11 | jecxz ECX=0000000100000001 ZF=0 r=0 12 | jecxz ECX=0000000100000001 ZF=1 r=0 13 | loopl ECX=00000000ffffffff ZF=0 r=1 14 | loopl ECX=00000000ffffffff ZF=1 r=1 15 | loopl ECX=0000000000000000 ZF=0 r=0 16 | loopl ECX=0000000000000000 ZF=1 r=0 17 | loopl ECX=000000000000ffff ZF=0 r=1 18 | loopl ECX=000000000000ffff ZF=1 r=1 19 | loopl ECX=0000000000010000 ZF=0 r=1 20 | loopl ECX=0000000000010000 ZF=1 r=1 21 | loopl ECX=00000000ffffffff ZF=0 r=1 22 | loopl ECX=00000000ffffffff ZF=1 r=1 23 | loopl ECX=0000000000000000 ZF=0 r=0 24 | loopl ECX=0000000000000000 ZF=1 r=0 25 | loopzl ECX=00000000ffffffff ZF=0 r=0 26 | loopzl ECX=00000000ffffffff ZF=1 r=1 27 | loopzl ECX=0000000000000000 ZF=0 r=0 28 | loopzl ECX=0000000000000000 ZF=1 r=0 29 | loopzl ECX=000000000000ffff ZF=0 r=0 30 | loopzl ECX=000000000000ffff ZF=1 r=1 31 | loopzl ECX=0000000000010000 ZF=0 r=0 32 | loopzl ECX=0000000000010000 ZF=1 r=1 33 | loopzl ECX=00000000ffffffff ZF=0 r=0 34 | loopzl ECX=00000000ffffffff ZF=1 r=1 35 | loopzl ECX=0000000000000000 ZF=0 r=0 36 | loopzl ECX=0000000000000000 ZF=1 r=0 37 | loopnzl ECX=00000000ffffffff ZF=0 r=1 38 | loopnzl ECX=00000000ffffffff ZF=1 r=0 39 | loopnzl ECX=0000000000000000 ZF=0 r=0 40 | loopnzl ECX=0000000000000000 ZF=1 r=0 41 | loopnzl ECX=000000000000ffff ZF=0 r=1 42 | loopnzl ECX=000000000000ffff ZF=1 r=0 43 | loopnzl ECX=0000000000010000 ZF=0 r=1 44 | loopnzl ECX=0000000000010000 ZF=1 r=0 45 | loopnzl ECX=00000000ffffffff ZF=0 r=1 46 | loopnzl ECX=00000000ffffffff ZF=1 r=0 47 | loopnzl ECX=0000000000000000 ZF=0 r=0 48 | loopnzl ECX=0000000000000000 ZF=1 r=0 49 | -------------------------------------------------------------------------------- /test/arch/x86/qemu/expected_x86_64/test_misc.exp: -------------------------------------------------------------------------------- 1 | xlat: EAX=0000000012345688 2 | popl esp=0000000009abcdef 3 | -------------------------------------------------------------------------------- /test/arch/x86/qemu/test-i386: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cea-sec/miasm/2a15c60712b326b541d42ac48f372f97023547e7/test/arch/x86/qemu/test-i386 -------------------------------------------------------------------------------- /test/arch/x86/qemu/test-x86_64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cea-sec/miasm/2a15c60712b326b541d42ac48f372f97023547e7/test/arch/x86/qemu/test-x86_64 -------------------------------------------------------------------------------- /test/arch/x86/unit/access_xmm.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python2 2 | """Test getter and setter for XMM registers (128 bits)""" 3 | 4 | from miasm.analysis.machine import Machine 5 | from miasm.core.locationdb import LocationDB 6 | 7 | # Jitter engine doesn't matter, use the always available 'python' one 8 | loc_db = LocationDB() 9 | myjit = Machine("x86_32").jitter(loc_db, "python") 10 | 11 | # Test basic access (get) 12 | assert myjit.cpu.XMM0 == 0 13 | 14 | # Test set 15 | myjit.cpu.XMM1 = 0x00112233445566778899aabbccddeeff 16 | 17 | # Ensure set has been correctly handled 18 | assert myjit.cpu.XMM1 == 0x00112233445566778899aabbccddeeff 19 | -------------------------------------------------------------------------------- /test/arch/x86/unit/mn_cmov.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from asm_test import Asm_Test_64 3 | 4 | class Test_CMOVZ_OK(Asm_Test_64): 5 | TXT = ''' 6 | main: 7 | MOV RAX, 0x8877665544332211 8 | MOV RBX, RAX 9 | MOV RAX, 0xAABBCCDDEEFF0011 10 | XOR RCX, RCX 11 | CMOVZ RAX, RBX 12 | RET 13 | ''' 14 | def check(self): 15 | assert self.myjit.cpu.RAX == 0x8877665544332211 16 | 17 | 18 | class Test_CMOVZ_KO(Asm_Test_64): 19 | TXT = ''' 20 | main: 21 | MOV RAX, 0x8877665544332211 22 | MOV RBX, RAX 23 | MOV RAX, 0xAABBCCDDEEFF0011 24 | XOR RCX, RCX 25 | INC RCX 26 | CMOVZ RAX, RBX 27 | RET 28 | ''' 29 | def check(self): 30 | assert self.myjit.cpu.RAX == 0xAABBCCDDEEFF0011 31 | 32 | 33 | class Test_CMOVZ_OK_64_32(Asm_Test_64): 34 | TXT = ''' 35 | main: 36 | MOV RAX, 0x8877665544332211 37 | MOV RBX, RAX 38 | MOV RAX, 0xAABBCCDDEEFF0011 39 | XOR RCX, RCX 40 | CMOVZ EAX, EBX 41 | RET 42 | ''' 43 | def check(self): 44 | assert self.myjit.cpu.RAX == 0x44332211 45 | 46 | 47 | class Test_CMOVZ_KO_64_32(Asm_Test_64): 48 | TXT = ''' 49 | main: 50 | MOV RAX, 0x8877665544332211 51 | MOV RBX, RAX 52 | MOV RAX, 0xAABBCCDDEEFF0011 53 | XOR RCX, RCX 54 | INC RCX 55 | CMOVZ EAX, EBX 56 | RET 57 | ''' 58 | def check(self): 59 | assert self.myjit.cpu.RAX == 0xEEFF0011 60 | 61 | 62 | 63 | if __name__ == "__main__": 64 | [ 65 | test(*sys.argv[1:])() for test in [ 66 | Test_CMOVZ_OK, 67 | Test_CMOVZ_KO, 68 | Test_CMOVZ_OK_64_32, 69 | Test_CMOVZ_KO_64_32, 70 | ] 71 | ] 72 | 73 | -------------------------------------------------------------------------------- /test/arch/x86/unit/mn_cpuid.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python2 2 | 3 | import sys 4 | 5 | from asm_test import Asm_Test_32 6 | 7 | class Test_CPUID(Asm_Test_32): 8 | """Check for cpuid support (and not for arbitrary returned values)""" 9 | TXT = ''' 10 | main: 11 | XOR EAX, EAX 12 | CPUID 13 | RET 14 | ''' 15 | 16 | def check(self): 17 | assert self.myjit.cpu.EAX == 0xa 18 | 19 | 20 | if __name__ == "__main__": 21 | [test(*sys.argv[1:])() for test in [Test_CPUID]] 22 | -------------------------------------------------------------------------------- /test/arch/x86/unit/mn_daa.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python2 2 | import sys 3 | 4 | from asm_test import Asm_Test_32 5 | 6 | 7 | class Test_DAA(Asm_Test_32): 8 | TXT = ''' 9 | main: 10 | MOV EBP, ESP 11 | LEA ESI, DWORD PTR [array_al] 12 | loop: 13 | 14 | ; load original cf 15 | LODSB 16 | MOV BL, AL 17 | ; load original af 18 | LODSB 19 | SHL AL, 4 20 | OR AL, BL 21 | MOV AH, AL 22 | SAHF 23 | ; load original al 24 | LODSB 25 | 26 | DAA 27 | MOV BL, AL 28 | 29 | LAHF 30 | MOV CL, AH 31 | 32 | ; test cf 33 | LODSB 34 | MOV DL, CL 35 | AND DL, 1 36 | CMP DL, AL 37 | JNZ BAD 38 | 39 | MOV DL, CL 40 | SHR DL, 4 41 | AND DL, 1 42 | ; test af 43 | LODSB 44 | CMP DL, AL 45 | JNZ BAD 46 | 47 | ; test value 48 | LODSB 49 | CMP AL, BL 50 | JNZ BAD 51 | 52 | CMP ESI, array_al_end 53 | JB loop 54 | 55 | 56 | end: 57 | RET 58 | 59 | BAD: 60 | INT 0x3 61 | RET 62 | 63 | array_al: 64 | .byte 0, 1, 0x08, 0, 1, 0x0E 65 | .byte 0, 1, 0x09, 0, 1, 0x0F 66 | .byte 0, 1, 0x0A, 0, 1, 0x10 67 | .byte 0, 1, 0x98, 0, 1, 0x9E 68 | .byte 0, 1, 0x99, 0, 1, 0x9F 69 | .byte 0, 1, 0x9A, 1, 1, 0x00 70 | array_al_end: 71 | .long 0 72 | ''' 73 | def check(self): 74 | pass 75 | 76 | 77 | if __name__ == "__main__": 78 | [test(*sys.argv[1:])() for test in [Test_DAA]] 79 | -------------------------------------------------------------------------------- /test/arch/x86/unit/mn_div.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from asm_test import Asm_Test_64 3 | 4 | class Test_DIV(Asm_Test_64): 5 | TXT = ''' 6 | main: 7 | MOV RAX, 0x8877665544332211 8 | MOV RBX, 0x11223344556677 9 | DIV RBX 10 | RET 11 | ''' 12 | def check(self): 13 | assert self.myjit.cpu.RAX == 0x7F7 14 | assert self.myjit.cpu.RDX == 0x440 15 | 16 | if __name__ == "__main__": 17 | [test(*sys.argv[1:])() for test in [Test_DIV]] 18 | -------------------------------------------------------------------------------- /test/arch/x86/unit/mn_float.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python2 2 | import sys 3 | 4 | from asm_test import Asm_Test_32 5 | 6 | 7 | class Test_FADD(Asm_Test_32): 8 | TXT = ''' 9 | main: 10 | ; test float 11 | PUSH 0 12 | FLD1 13 | FLD1 14 | FADD ST, ST(1) 15 | FIST DWORD PTR [ESP] 16 | POP EAX 17 | RET 18 | ''' 19 | def check(self): 20 | assert(self.myjit.cpu.EAX == 2) 21 | 22 | 23 | if __name__ == "__main__": 24 | [test(*sys.argv[1:])() for test in [Test_FADD]] 25 | -------------------------------------------------------------------------------- /test/arch/x86/unit/mn_getset128.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python2 2 | 3 | import sys 4 | 5 | from asm_test import Asm_Test_32 6 | 7 | 8 | class Test_get_set_128(Asm_Test_32): 9 | TXT = ''' 10 | main: 11 | MOVD XMM0, ESI 12 | MOVD XMM1, EDI 13 | PCMPEQQ XMM0, XMM1 14 | JZ ret 15 | MOV EAX, 1 16 | 17 | PUSH 0x11112222 18 | PUSH 0x33334444 19 | PUSH 0x55556666 20 | PUSH 0x77778888 21 | MOVAPS XMM2, XMMWORD PTR [ESP] 22 | ADD ESP, 0x10 23 | ret: 24 | RET 25 | ''' 26 | 27 | def prepare(self): 28 | val = 1 29 | self.myjit.cpu.ESI = 0x11223344 30 | self.myjit.cpu.EDI = 0x11223345 31 | self.myjit.cpu.XMM0 = val 32 | 33 | # Check 128 get / set 34 | assert self.myjit.cpu.XMM0 == val 35 | assert self.myjit.cpu.get_gpreg()['XMM0'] == val 36 | 37 | def check(self): 38 | assert self.myjit.cpu.XMM0 == 0xffffffffffffffff0000000000000000 39 | assert self.myjit.cpu.XMM1 == 0x11223345 40 | 41 | # Check 128 get / set 42 | assert self.myjit.cpu.get_gpreg()['XMM0'] == 0xffffffffffffffff0000000000000000 43 | assert self.myjit.cpu.get_gpreg()['XMM1'] == 0x11223345 44 | 45 | assert self.myjit.cpu.get_gpreg()['XMM2'] == 0x11112222333344445555666677778888 46 | assert self.myjit.cpu.get_gpreg()['XMM2'] == 0x11112222333344445555666677778888 47 | 48 | 49 | if __name__ == "__main__": 50 | [test(*sys.argv[1:])() for test in [ 51 | Test_get_set_128, 52 | ]] 53 | -------------------------------------------------------------------------------- /test/arch/x86/unit/mn_int.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python2 2 | import sys 3 | 4 | from miasm.jitter.csts import EXCEPT_INT_XX 5 | from asm_test import Asm_Test_32 6 | 7 | 8 | class Test_INT(Asm_Test_32): 9 | TXT = ''' 10 | main: 11 | MOV ECX, 0x10 12 | loop: 13 | INT 0x42 14 | DEC ECX 15 | JNZ loop 16 | ret: 17 | RET 18 | ''' 19 | 20 | def set_int_num(self, jitter): 21 | assert jitter.cpu.get_interrupt_num() == 0x42 22 | self.int_num += 1 23 | jitter.cpu.set_exception(0) 24 | return True 25 | 26 | def __init__(self, jitter): 27 | super(Test_INT, self).__init__(jitter) 28 | self.int_num = 0 29 | self.myjit.add_exception_handler(EXCEPT_INT_XX, 30 | self.set_int_num) 31 | 32 | def check(self): 33 | assert self.int_num == 0x10 34 | self.myjit.cpu.set_interrupt_num(14) 35 | assert self.myjit.cpu.get_interrupt_num() == 14 36 | 37 | 38 | if __name__ == "__main__": 39 | [test(*sys.argv[1:])() for test in [Test_INT]] 40 | -------------------------------------------------------------------------------- /test/arch/x86/unit/mn_pextr.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python2 2 | 3 | import sys 4 | 5 | from asm_test import Asm_Test_32 6 | 7 | class Test_PEXTRB(Asm_Test_32): 8 | TXT = ''' 9 | main: 10 | CALL next 11 | .byte 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 12 | .byte 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 13 | next: 14 | POP EBP 15 | MOV EAX, 0xFFFFFFFF 16 | MOVQ MM0, QWORD PTR [EBP] 17 | PEXTRW EAX, MM0, 2 18 | RET 19 | ''' 20 | 21 | def check(self): 22 | assert self.myjit.cpu.MM0 == 0x1122334455667788 23 | assert self.myjit.cpu.EAX == 0x3344 24 | 25 | 26 | if __name__ == "__main__": 27 | [test(*sys.argv[1:])() for test in [Test_PEXTRB]] 28 | -------------------------------------------------------------------------------- /test/arch/x86/unit/mn_pinsr.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python2 2 | 3 | import sys 4 | 5 | from asm_test import Asm_Test_32 6 | 7 | class Test_PINSRB(Asm_Test_32): 8 | TXT = ''' 9 | main: 10 | CALL next 11 | .byte 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 12 | .byte 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 13 | next: 14 | POP EBP 15 | MOVQ MM0, QWORD PTR [EBP] 16 | MOVQ MM1, MM0 17 | PINSRW MM1, QWORD PTR [EBP+0x8], 2 18 | RET 19 | ''' 20 | 21 | def check(self): 22 | assert self.myjit.cpu.MM0 == 0x1122334455667788 23 | assert self.myjit.cpu.MM1 == 0x1122070855667788 24 | 25 | 26 | if __name__ == "__main__": 27 | [test(*sys.argv[1:])() for test in [Test_PINSRB]] 28 | -------------------------------------------------------------------------------- /test/arch/x86/unit/mn_pmaxu.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python2 2 | import sys 3 | 4 | from asm_test import Asm_Test_32 5 | 6 | class Test_PMAXU(Asm_Test_32): 7 | TXT = ''' 8 | main: 9 | CALL next 10 | .byte 0x88, 0x76, 0x66, 0x54, 0x44, 0x32, 0x00, 0x10 11 | .byte 0x87, 0x77, 0x66, 0x55, 0x40, 0x33, 0x22, 0x11 12 | next: 13 | POP EBP 14 | MOVQ MM0, QWORD PTR [EBP] 15 | MOVQ MM1, MM0 16 | PMAXUB MM1, QWORD PTR [EBP+0x8] 17 | RET 18 | ''' 19 | 20 | def check(self): 21 | assert self.myjit.cpu.MM0 == 0x1000324454667688 22 | assert self.myjit.cpu.MM1 == 0x1122334455667788 23 | 24 | 25 | if __name__ == "__main__": 26 | [test(*sys.argv[1:])() for test in [Test_PMAXU]] 27 | -------------------------------------------------------------------------------- /test/arch/x86/unit/mn_pminu.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python2 2 | import sys 3 | 4 | from asm_test import Asm_Test_32 5 | 6 | class Test_PMINU(Asm_Test_32): 7 | TXT = ''' 8 | main: 9 | CALL next 10 | .byte 0x88, 0x78, 0x66, 0x56, 0x44, 0x3F, 0xFF, 0x1F 11 | .byte 0x89, 0x77, 0x66, 0x55, 0xF9, 0x33, 0x22, 0x11 12 | next: 13 | POP EBP 14 | MOVQ MM0, QWORD PTR [EBP] 15 | MOVQ MM1, MM0 16 | PMINUB MM1, QWORD PTR [EBP+0x8] 17 | RET 18 | ''' 19 | 20 | def check(self): 21 | assert self.myjit.cpu.MM0 == 0x1FFF3F4456667888 22 | assert self.myjit.cpu.MM1 == 0x1122334455667788 23 | 24 | 25 | if __name__ == "__main__": 26 | [test(*sys.argv[1:])() for test in [Test_PMINU]] 27 | -------------------------------------------------------------------------------- /test/arch/x86/unit/mn_pmovmskb.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python2 2 | 3 | import sys 4 | 5 | from asm_test import Asm_Test_32 6 | 7 | class Test_PMOVMSKB(Asm_Test_32): 8 | TXT = ''' 9 | main: 10 | CALL next 11 | .byte 0x88, 0x77, 0xE6, 0x55, 0xC4, 0x33, 0x22, 0x11 12 | .byte 0x01, 0x02, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA 13 | next: 14 | POP EBP 15 | MOV EAX, 0xFFFFFFFF 16 | MOVQ MM0, QWORD PTR [EBP] 17 | MOVQ MM1, MM0 18 | PMOVMSKB EAX, MM1 19 | RET 20 | ''' 21 | 22 | def check(self): 23 | assert self.myjit.cpu.MM0 == 0x112233C455E67788 24 | assert self.myjit.cpu.MM1 == 0x112233C455E67788 25 | assert self.myjit.cpu.EAX == 0x00000015 26 | 27 | if __name__ == "__main__": 28 | [test(*sys.argv[1:])() for test in [Test_PMOVMSKB,]] 29 | -------------------------------------------------------------------------------- /test/arch/x86/unit/mn_pshufb.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python2 2 | import sys 3 | 4 | from asm_test import Asm_Test_32 5 | 6 | class Test_PSHUFB(Asm_Test_32): 7 | TXT = ''' 8 | main: 9 | CALL next 10 | .byte 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 11 | .byte 0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1, 0x0 12 | next: 13 | POP EBP 14 | MOVQ MM0, QWORD PTR [EBP] 15 | MOVQ MM1, MM0 16 | PSHUFB MM1, QWORD PTR [EBP+0x8] 17 | RET 18 | ''' 19 | 20 | def check(self): 21 | assert self.myjit.cpu.MM0 == 0x1122334455667788 22 | assert self.myjit.cpu.MM1 == 0x8877665544332211 23 | 24 | 25 | if __name__ == "__main__": 26 | [test(*sys.argv[1:])() for test in [Test_PSHUFB]] 27 | -------------------------------------------------------------------------------- /test/arch/x86/unit/mn_psrl_psll.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python2 2 | import sys 3 | 4 | from asm_test import Asm_Test_32 5 | 6 | class Test_PSRL(Asm_Test_32): 7 | TXT = ''' 8 | main: 9 | CALL next 10 | .byte 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 11 | .byte 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 12 | next: 13 | POP EBP 14 | MOVQ MM0, QWORD PTR [EBP] 15 | MOVQ MM1, MM0 16 | MOVQ MM2, MM0 17 | MOVQ MM3, MM0 18 | PSRLW MM1, QWORD PTR [EBP+0x8] 19 | PSRLD MM2, QWORD PTR [EBP+0x8] 20 | PSRLQ MM3, QWORD PTR [EBP+0x8] 21 | RET 22 | ''' 23 | 24 | def check(self): 25 | assert self.myjit.cpu.MM0 == 0x1122334455667788 26 | assert self.myjit.cpu.MM1 == 0x0112033405560778 27 | assert self.myjit.cpu.MM2 == 0x0112233405566778 28 | assert self.myjit.cpu.MM3 == 0x0112233445566778 29 | 30 | class Test_PSLL(Asm_Test_32): 31 | TXT = ''' 32 | main: 33 | CALL next 34 | .byte 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 35 | .byte 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 36 | next: 37 | POP EBP 38 | MOVQ MM0, QWORD PTR [EBP] 39 | MOVQ MM1, MM0 40 | MOVQ MM2, MM0 41 | MOVQ MM3, MM0 42 | PSLLW MM1, QWORD PTR [EBP+0x8] 43 | PSLLD MM2, QWORD PTR [EBP+0x8] 44 | PSLLQ MM3, QWORD PTR [EBP+0x8] 45 | RET 46 | ''' 47 | 48 | def check(self): 49 | assert self.myjit.cpu.MM0 == 0x1122334455667788 50 | assert self.myjit.cpu.MM1 == 0x1220344056607880 51 | assert self.myjit.cpu.MM2 == 0x1223344056677880 52 | assert self.myjit.cpu.MM3 == 0x1223344556677880 53 | 54 | 55 | if __name__ == "__main__": 56 | [test(*sys.argv[1:])() for test in [Test_PSRL, Test_PSLL]] 57 | -------------------------------------------------------------------------------- /test/arch/x86/unit/mn_stack.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python2 2 | 3 | import sys 4 | 5 | from asm_test import Asm_Test_32 6 | 7 | 8 | class Test_PUSHPOP(Asm_Test_32): 9 | TXT = ''' 10 | main: 11 | MOV EBP, ESP 12 | PUSH 0x11223344 13 | POP EAX 14 | CMP EBP, ESP 15 | JNZ BAD 16 | 17 | PUSHW 0x1122 18 | POPW AX 19 | CMP EBP, ESP 20 | JNZ BAD 21 | 22 | PUSH SS 23 | POP EAX 24 | CMP EBP, ESP 25 | JNZ BAD 26 | 27 | PUSHW SS 28 | POPW AX 29 | CMP EBP, ESP 30 | JNZ BAD 31 | 32 | PUSHFD 33 | POP EAX 34 | CMP EBP, ESP 35 | JNZ BAD 36 | 37 | PUSHFW 38 | POPW AX 39 | CMP EBP, ESP 40 | JNZ BAD 41 | 42 | PUSH EAX 43 | POPFD 44 | CMP EBP, ESP 45 | JNZ BAD 46 | 47 | PUSHW AX 48 | POPFW 49 | CMP EBP, ESP 50 | JNZ BAD 51 | 52 | RET 53 | 54 | BAD: 55 | INT 0x3 56 | RET 57 | ''' 58 | def check(self): 59 | assert(self.myjit.cpu.ESP-4 == self.myjit.cpu.EBP) 60 | 61 | 62 | if __name__ == "__main__": 63 | [test(*sys.argv[1:])() for test in [Test_PUSHPOP]] 64 | -------------------------------------------------------------------------------- /test/arch/x86/unit/mn_strings.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python2 2 | import sys 3 | 4 | from asm_test import Asm_Test_32 5 | 6 | class Test_SCAS(Asm_Test_32): 7 | MYSTRING = "test string" 8 | TXT = ''' 9 | main: 10 | LEA EDI, DWORD PTR [mystr] 11 | XOR ECX, ECX 12 | DEC ECX 13 | REPNE SCASB 14 | NOT ECX 15 | DEC ECX 16 | RET 17 | 18 | mystr: 19 | .string "%s" 20 | ''' % MYSTRING 21 | 22 | def check(self): 23 | assert(self.myjit.cpu.ECX == len(self.MYSTRING)) 24 | mystr = self.myjit.lifter.loc_db.get_name_location('mystr') 25 | assert(self.myjit.cpu.EDI == self.myjit.lifter.loc_db.get_location_offset(mystr) + len(self.MYSTRING)+1) 26 | 27 | 28 | class Test_MOVS(Asm_Test_32): 29 | MYSTRING = "test string" 30 | TXT = ''' 31 | main: 32 | LEA ESI, DWORD PTR [mystr] 33 | LEA EDI, DWORD PTR [buffer] 34 | MOV ECX, %d 35 | REPE MOVSB 36 | RET 37 | 38 | mystr: 39 | .string "%s" 40 | buffer: 41 | .string "%s" 42 | ''' % (len(MYSTRING), MYSTRING, " "*len(MYSTRING)) 43 | 44 | def check(self): 45 | assert(self.myjit.cpu.ECX == 0) 46 | buffer = self.myjit.lifter.loc_db.get_name_location('buffer') 47 | assert(self.myjit.cpu.EDI == self.myjit.lifter.loc_db.get_location_offset(buffer) + len(self.MYSTRING)) 48 | mystr = self.myjit.lifter.loc_db.get_name_location('mystr') 49 | assert(self.myjit.cpu.ESI == self.myjit.lifter.loc_db.get_location_offset(mystr) + len(self.MYSTRING)) 50 | 51 | 52 | if __name__ == "__main__": 53 | [test(*sys.argv[1:])() for test in [Test_SCAS, Test_MOVS]] 54 | -------------------------------------------------------------------------------- /test/arch/x86/unit/test_asm_x86_64.py: -------------------------------------------------------------------------------- 1 | from miasm.core import asmblock 2 | from miasm.arch.x86 import arch 3 | from miasm.core import parse_asm 4 | from miasm.core.interval import interval 5 | from miasm.core.locationdb import LocationDB 6 | 7 | my_mn = arch.mn_x86 8 | loc_db = LocationDB() 9 | 10 | asmcfg = parse_asm.parse_txt( 11 | my_mn, 64, r''' 12 | main: 13 | PUSH RBP 14 | MOV RBP, RSP 15 | loop_dec: 16 | CMP RCX, RDX 17 | JB loop_dec 18 | end: 19 | MOV RSP, RBP 20 | POP RBP 21 | RET 22 | 23 | ''', 24 | loc_db 25 | ) 26 | 27 | loc_db.set_location_offset(loc_db.get_name_location("main"), 0x100001000) 28 | dst_interval = interval([(0x100001000, 0x100002000)]) 29 | patches = asmblock.asm_resolve_final( 30 | my_mn, 31 | asmcfg, 32 | dst_interval 33 | ) 34 | -------------------------------------------------------------------------------- /test/core/modint.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | from miasm.core.modint import * 4 | 5 | a = uint8(0x42) 6 | b = uint8(0xFF) 7 | c = uint8(0x4) 8 | 9 | d = uint1(0) 10 | e = uint1(1) 11 | 12 | f = uint8(0x1) 13 | g = int8(-3) 14 | 15 | print(a, b, c) 16 | print(a + b, a + c, b + c) 17 | print(a == a, a == b, a == 0x42, a == 0x78) 18 | print(a != b, a != a) 19 | print(d, e) 20 | print(d + e, d + d, e + e, e + e + e, e + 0x11) 21 | 22 | assert(f == 1) 23 | assert(f + 1 == 2) 24 | assert(2 == f + 1) 25 | assert(f + 0xff == 0) 26 | assert(f & 0 == 0) 27 | assert(f & 0xff == f) 28 | assert(0xff & f == f) 29 | assert(f // 1 == f) 30 | assert(1 // f == f) 31 | assert(int(f) == 1) 32 | assert(int(f) == 1) 33 | assert(~f == 0xfe) 34 | assert(f << 1 == 2) 35 | assert(f << 8 == 0) 36 | assert(1 << f == 2) 37 | assert(0x80 << f == 0) 38 | assert(f % 2 == f) 39 | assert(f % 1 == 0) 40 | assert(2 % f == 0) 41 | assert(f * 2 == 2) 42 | assert(2 * f == 2) 43 | assert(f * f == 1) 44 | assert(f * uint8(0x80) == 0x80) 45 | assert(-f == 0xff) 46 | assert(f | f == f) 47 | assert(f | 0 == f) 48 | assert(2 | f == 3) 49 | assert(f >> 0 == f) 50 | assert(f >> 1 == 0) 51 | assert(0x10 >> f == 0x8) 52 | assert(0x100 >> f == 0x80) # XXXX 53 | assert(0x1000 >> f == 0x0) # XXXX 54 | assert(f ^ f == 0) 55 | assert(f ^ 0 == f) 56 | assert(0 ^ f == f) 57 | assert(1 ^ f == 0) 58 | assert(c // g == -1) 59 | assert(c // -3 == -1) 60 | assert(c % g == 1) 61 | assert(c % -3 == 1) 62 | 63 | print(e + c, c + e, c - e, e - c) 64 | print(1000 * a) 65 | print(hex(a)) 66 | 67 | define_int(128) 68 | define_uint(128) 69 | h = uint128(0x11223344556677889900AABBCCDDEEFF) 70 | i = int128(-0x9900AABBCCDDEEFF1122334455667788) 71 | 72 | assert(i //h == 6) 73 | assert(i % h == 0x3221aa32bb43cd58d9cc54dd65ee7e) 74 | 75 | -------------------------------------------------------------------------------- /test/core/sembuilder.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import inspect 3 | from pdb import pm 4 | 5 | from miasm.core.sembuilder import SemBuilder 6 | from miasm.core.locationdb import LocationDB 7 | import miasm.expression.expression as m2_expr 8 | 9 | 10 | 11 | # Test classes 12 | class IR(object): 13 | def __init__(self, loc_db): 14 | self.loc_db = loc_db 15 | 16 | IRDst = m2_expr.ExprId("IRDst", 32) 17 | 18 | def get_next_instr(self, _): 19 | return m2_expr.LocKey(0) 20 | 21 | def get_next_loc_key(self, _): 22 | return m2_expr.LocKey(0) 23 | 24 | class Instr(object): 25 | mode = 32 26 | 27 | # Test 28 | sb = SemBuilder(m2_expr.__dict__) 29 | 30 | @sb.parse 31 | def test(Arg1, Arg2, Arg3): 32 | "Test docstring" 33 | Arg1 = Arg2 34 | value1 = Arg2 35 | value2 = Arg3 + i32(4) - ExprMem(Arg1, 32) 36 | Arg3 = Arg3 if Arg2 + value1 else i32(0) + value2 37 | tmpvar = 'myop'(i32(2)) 38 | Arg2 = ('myopsize%d' % Arg1.size)(tmpvar, Arg1) 39 | alias = Arg1[:24] 40 | 41 | if not Arg1: 42 | Arg2 = Arg3 43 | else: 44 | alias = {i16(4), i8(5)} 45 | 46 | a = m2_expr.ExprId('A', 32) 47 | b = m2_expr.ExprId('B', 32) 48 | c = m2_expr.ExprId('C', 32) 49 | loc_db = LocationDB() 50 | ir = IR(loc_db) 51 | instr = Instr() 52 | res = test(ir, instr, a, b, c) 53 | 54 | print("[+] Returned:") 55 | print(res) 56 | print("[+] DocString:", test.__doc__) 57 | 58 | print("[+] Cur instr:") 59 | for statement in res[0]: 60 | print(statement) 61 | 62 | print("[+] Blocks:") 63 | for irb in res[1]: 64 | print(irb.loc_key) 65 | for assignblk in irb: 66 | for expr in assignblk: 67 | print(expr) 68 | print() 69 | -------------------------------------------------------------------------------- /test/core/utils.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python2 2 | 3 | #-*- coding:utf-8 -*- 4 | 5 | from __future__ import print_function 6 | from builtins import range 7 | import unittest 8 | 9 | 10 | class TestUtils(unittest.TestCase): 11 | 12 | def test_boundedDict(self): 13 | from miasm.core.utils import BoundedDict 14 | 15 | # Use a callback 16 | def logger(key): 17 | print("DELETE", key) 18 | 19 | # Create a 5/2 dictionary 20 | bd = BoundedDict(5, 2, initialdata={"element": "value"}, 21 | delete_cb=logger) 22 | bd["element2"] = "value2" 23 | assert("element" in bd) 24 | assert("element2" in bd) 25 | self.assertEqual(bd["element"], "value") 26 | self.assertEqual(bd["element2"], "value2") 27 | 28 | # Increase 'element2' use 29 | _ = bd["element2"] 30 | 31 | for i in range(6): 32 | bd[i] = i 33 | print("Insert %d -> %s" % (i, bd)) 34 | 35 | assert(len(bd) == 2) 36 | 37 | assert("element2" in bd) 38 | self.assertEqual(bd["element2"], "value2") 39 | 40 | 41 | if __name__ == '__main__': 42 | testsuite = unittest.TestLoader().loadTestsFromTestCase(TestUtils) 43 | report = unittest.TextTestRunner(verbosity=2).run(testsuite) 44 | exit(len(report.errors + report.failures)) 45 | -------------------------------------------------------------------------------- /test/expression/expr_pickle.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import pickle 3 | from miasm.expression.expression import ExprInt, ExprAssign, ExprId, \ 4 | Expr, ExprCompose, ExprMem 5 | 6 | 7 | a = ExprId("test", 8) 8 | b = ExprInt(1338, 8) 9 | c = a + b 10 | d = ExprCompose(a, b) 11 | e = ExprMem(a, 32) 12 | f = a[:8] 13 | aff = ExprAssign(a, b) 14 | 15 | 16 | print('Pickling') 17 | out = pickle.dumps((a, b, c, d, e, f, aff)) 18 | print('Unpickling') 19 | new_a, new_b, new_c, new_d, new_e, new_f, new_aff = pickle.loads(out) 20 | print('Result') 21 | print(a, b, c, aff) 22 | print(id(a), id(b), id(c), id(d), id(e), id(f), id(aff)) 23 | print(new_a, new_b, new_c, new_d, new_e, new_f, new_aff) 24 | print(id(new_a), id(new_b), id(new_c), id(new_d), id(new_e), id(new_f), id(new_aff)) 25 | 26 | assert a == new_a 27 | assert b == new_b 28 | assert c == new_c 29 | assert d == new_d 30 | assert e == new_e 31 | assert f == new_f 32 | assert aff == new_aff 33 | assert new_a + new_b == a + b 34 | 35 | 36 | assert a is new_a 37 | assert b is new_b 38 | assert c is new_c 39 | assert d is new_d 40 | assert e is new_e 41 | assert f is new_f 42 | assert aff is new_aff 43 | assert new_a + new_b is a + b 44 | 45 | Expr.use_singleton = False 46 | 47 | new_a, new_b, new_c, new_d, new_e, new_f, new_aff = pickle.loads(out) 48 | 49 | 50 | assert a is not new_a 51 | assert b is not new_b 52 | assert c is not new_c 53 | assert d is not new_d 54 | assert e is not new_e 55 | assert f is not new_f 56 | assert aff is not new_aff 57 | assert new_a + new_b is not a + b 58 | 59 | 60 | assert a == new_a 61 | assert b == new_b 62 | assert c == new_c 63 | assert d == new_d 64 | assert e == new_e 65 | assert f == new_f 66 | assert aff == new_aff 67 | assert new_a + new_b == a + b 68 | -------------------------------------------------------------------------------- /test/expression/parser.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | from miasm.expression.parser import str_to_expr 3 | from miasm.expression.expression import ExprInt, ExprId, ExprSlice, ExprMem, \ 4 | ExprCond, ExprCompose, ExprOp, ExprAssign, ExprLoc, LocKey 5 | 6 | for expr_test in [ExprInt(0x12, 32), 7 | ExprId('test', 32), 8 | ExprLoc(LocKey(12), 32), 9 | ExprSlice(ExprInt(0x10, 32), 0, 8), 10 | ExprMem(ExprInt(0x10, 32), 32), 11 | ExprCond(ExprInt(0x10, 32), ExprInt(0x11, 32), ExprInt(0x12, 32)), 12 | ExprCompose(ExprInt(0x10, 16), ExprInt(0x11, 8), ExprInt(0x12, 8)), 13 | ExprInt(0x11, 8) + ExprInt(0x12, 8), 14 | ExprAssign(ExprId('EAX', 32), ExprInt(0x12, 32)), 15 | ]: 16 | 17 | print('Test: %s' % expr_test) 18 | assert str_to_expr(repr(expr_test)) == expr_test 19 | -------------------------------------------------------------------------------- /test/expression/stp.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python2 2 | #-*- coding:utf-8 -*- 3 | 4 | from builtins import range 5 | import unittest 6 | 7 | 8 | class TestIrIr2STP(unittest.TestCase): 9 | 10 | def test_ExprOp_strcst(self): 11 | from miasm.expression.expression import ExprInt, ExprOp 12 | from miasm.ir.translators.translator import Translator 13 | translator_smt2 = Translator.to_language("smt2") 14 | 15 | args = [ExprInt(i, 32) for i in range(9)] 16 | 17 | self.assertEqual( 18 | translator_smt2.from_expr(ExprOp('|', *args[:2])), r'(bvor (_ bv0 32) (_ bv1 32))') 19 | self.assertEqual( 20 | translator_smt2.from_expr(ExprOp('-', *args[:2])), r'(bvsub (_ bv0 32) (_ bv1 32))') 21 | self.assertEqual( 22 | translator_smt2.from_expr(ExprOp('+', *args[:3])), r'(bvadd (bvadd (_ bv0 32) (_ bv1 32)) (_ bv2 32))') 23 | self.assertRaises(NotImplementedError, translator_smt2.from_expr, ExprOp('X', *args[:1])) 24 | 25 | def test_ExprSlice_strcst(self): 26 | from miasm.expression.expression import ExprInt, ExprOp 27 | from miasm.ir.translators.translator import Translator 28 | translator_smt2 = Translator.to_language("smt2") 29 | 30 | args = [ExprInt(i, 32) for i in range(9)] 31 | 32 | self.assertEqual( 33 | translator_smt2.from_expr(args[0][1:2]), r'((_ extract 1 1) (_ bv0 32))') 34 | self.assertRaises(ValueError, args[0].__getitem__, slice(1,7,2)) 35 | 36 | if __name__ == '__main__': 37 | testsuite = unittest.TestLoader().loadTestsFromTestCase(TestIrIr2STP) 38 | report = unittest.TextTestRunner(verbosity=2).run(testsuite) 39 | exit(len(report.errors + report.failures)) 40 | 41 | -------------------------------------------------------------------------------- /test/expression/z3_div.py: -------------------------------------------------------------------------------- 1 | import z3 2 | from miasm.ir.translators import Translator 3 | from miasm.expression.expression import * 4 | 5 | translator = Translator.to_language("z3") 6 | 7 | values = [ 8 | (42, 10, 4, 2), 9 | (-42, 10, -4, -2), 10 | (42, -10, -4, 2), 11 | (-42, -10, 4, -2) 12 | ] 13 | 14 | for a, b, c, d in values: 15 | cst_a = ExprInt(a, 8) 16 | cst_b = ExprInt(b, 8) 17 | 18 | div_result = ExprInt(c, 8) 19 | div = ExprOp("sdiv", cst_a, cst_b) 20 | print("%d / %d == %d" % (a, b, div_result)) 21 | solver = z3.Solver() 22 | print("%s == %s" %(div, div_result)) 23 | eq1 = translator.from_expr(div) != translator.from_expr(div_result) 24 | solver.add(eq1) 25 | result = solver.check() 26 | assert result == z3.unsat 27 | 28 | mod_result = ExprInt(d, 8) 29 | print("%d %% %d == %d" % (a, b, mod_result)) 30 | res2 = ExprOp("smod", cst_a, cst_b) 31 | solver = z3.Solver() 32 | print("%s == %s" %(res2, mod_result)) 33 | eq2 = translator.from_expr(res2) != translator.from_expr(mod_result) 34 | solver.add(eq2) 35 | result = solver.check() 36 | assert result == z3.unsat 37 | 38 | -------------------------------------------------------------------------------- /test/ir/ir.py: -------------------------------------------------------------------------------- 1 | from future.utils import viewitems 2 | 3 | from miasm.expression.expression import * 4 | from miasm.ir.ir import AssignBlock 5 | from miasm.expression.simplifications import expr_simp 6 | 7 | id_a = ExprId("a", 32) 8 | id_b = ExprId("b", 32) 9 | int0 = ExprInt(0, id_a.size) 10 | 11 | # Test AssignBlock 12 | ## Constructors 13 | assignblk1 = AssignBlock([ExprAssign(id_a, id_b)]) 14 | assignblk2 = AssignBlock({id_a: id_b}) 15 | 16 | ## Equality 17 | assignblk1_bis = AssignBlock([ExprAssign(id_a, id_b)]) 18 | assert assignblk1 == assignblk1_bis 19 | assert assignblk1 == assignblk2 20 | 21 | ## Immutability 22 | try: 23 | assignblk1[id_a] = id_a 24 | except RuntimeError: 25 | pass 26 | else: 27 | raise RuntimeError("An error was expected") 28 | try: 29 | del assignblk1[id_a] 30 | except RuntimeError: 31 | pass 32 | else: 33 | raise RuntimeError("An error was expected") 34 | 35 | ## Basic APIs 36 | assert assignblk1.get_r() == set([id_b]) 37 | assert assignblk1.get_w() == set([id_a]) 38 | assert assignblk1.get_rw() == {id_a: set([id_b])} 39 | assert list(assignblk1) == [id_a] 40 | assert dict(assignblk1) == {id_a: id_b} 41 | assert assignblk1[id_a] == id_b 42 | assert list(viewitems(assignblk1)) == list(viewitems(assignblk1)) 43 | assert set(assignblk1.iteritems()) == set(assignblk1.items()) 44 | 45 | ## Simplify 46 | assignblk3 = AssignBlock({id_a: id_b - id_b}) 47 | assert assignblk3[id_a] != int0 48 | assignblk4 = assignblk3.simplify(expr_simp) 49 | assert assignblk3[id_a] != int0 50 | assert assignblk4[id_a] == int0 51 | -------------------------------------------------------------------------------- /test/ir/translators/smt2.py: -------------------------------------------------------------------------------- 1 | from z3 import Solver, unsat, parse_smt2_string 2 | from miasm.expression.expression import * 3 | from miasm.ir.translators.smt2 import TranslatorSMT2 4 | from miasm.ir.translators.z3_ir import TranslatorZ3 5 | 6 | # create nested expression 7 | a = ExprId("a", 64) 8 | b = ExprId('b', 32) 9 | c = ExprId('c', 16) 10 | d = ExprId('d', 8) 11 | e = ExprId('e', 1) 12 | 13 | left = ExprCond( 14 | e + ExprOp('parity', a), 15 | ExprMem(a * a, 64), 16 | ExprMem(a, 64) 17 | ) 18 | 19 | cond = ( 20 | ExprSlice( 21 | ExprSlice( 22 | ExprSlice(a, 0, 32) + b, 0, 16 23 | ) * c, 24 | 0, 25 | 8 26 | ) << ExprOp('>>>', d, ExprInt(0x5, 8)) 27 | ) 28 | right = ExprCond( 29 | cond, 30 | a + ExprInt(0x64, 64), 31 | ExprInt(0x16, 64) 32 | ) 33 | 34 | e = ExprAssign(left, right) 35 | 36 | # initialise translators 37 | t_z3 = TranslatorZ3() 38 | t_smt2 = TranslatorSMT2() 39 | 40 | # translate to z3 41 | e_z3 = t_z3.from_expr(e) 42 | # translate to smt2 43 | smt2 = t_smt2.to_smt2([t_smt2.from_expr(e)]) 44 | 45 | # parse smt2 string with z3 46 | result = parse_smt2_string(smt2) 47 | smt2_z3 = result[0] 48 | # initialise SMT solver 49 | s = Solver() 50 | 51 | # prove equivalence of z3 and smt2 translation 52 | s.add(e_z3 != smt2_z3) 53 | assert (s.check() == unsat) 54 | -------------------------------------------------------------------------------- /test/jitter/bad_block.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from miasm.core.utils import decode_hex 3 | from miasm.jitter.csts import PAGE_READ, PAGE_WRITE, EXCEPT_UNK_MNEMO 4 | from miasm.analysis.machine import Machine 5 | from miasm.core.locationdb import LocationDB 6 | 7 | def code_sentinelle(jitter): 8 | jitter.running = False 9 | jitter.pc = 0 10 | return True 11 | 12 | machine = Machine("x86_32") 13 | loc_db = LocationDB() 14 | jitter = machine.jitter(loc_db, sys.argv[1]) 15 | 16 | jitter.init_stack() 17 | 18 | # nop 19 | # mov eax, 0x42 20 | # XX 21 | data = decode_hex("90b842000000ffff90909090") 22 | 23 | # Will raise memory error at 0x40000006 24 | 25 | error_raised = False 26 | def raise_me(jitter): 27 | global error_raised 28 | error_raised = True 29 | assert jitter.pc == 0x40000006 30 | return False 31 | 32 | jitter.add_exception_handler(EXCEPT_UNK_MNEMO, raise_me) 33 | 34 | run_addr = 0x40000000 35 | 36 | jitter.vm.add_memory_page(run_addr, PAGE_READ | PAGE_WRITE, data) 37 | 38 | jitter.set_trace_log() 39 | jitter.push_uint32_t(0x1337beef) 40 | 41 | jitter.add_breakpoint(0x1337beef, code_sentinelle) 42 | 43 | jitter.init_run(run_addr) 44 | jitter.continue_run() 45 | 46 | assert error_raised is True 47 | -------------------------------------------------------------------------------- /test/jitter/jitcore.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from miasm.core.locationdb import LocationDB 3 | 4 | from miasm.analysis.machine import Machine 5 | machine = Machine("x86_64") 6 | loc_db = LocationDB() 7 | jitter = machine.jitter(loc_db, sys.argv[1]) 8 | 9 | jitter.cpu.RAX = 16565615892967251934 10 | assert jitter.cpu.RAX == 16565615892967251934 11 | 12 | jitter.cpu.RAX = -1 & 0xffffffffffffffff 13 | assert jitter.cpu.RAX == 0xffffffffffffffff 14 | 15 | jitter.cpu.RAX = -2 & 0xffffffffffffffff 16 | assert jitter.cpu.RAX == 0xfffffffffffffffe 17 | 18 | jitter.cpu.EAX = -2 & 0xffffffff 19 | assert jitter.cpu.EAX == 0xfffffffe 20 | 21 | jitter.cpu.RAX = -0xffffffffffffffff & 0xffffffffffffffff 22 | assert jitter.cpu.RAX == 1 23 | 24 | try: 25 | jitter.cpu.RAX = 0x1ffffffffffffffff 26 | except TypeError: 27 | pass 28 | else: 29 | raise Exception("Should see that 0x1ffffffffffffffff is too big for RAX") 30 | 31 | try: 32 | jitter.cpu.RAX = 0x10000000000000000 33 | except TypeError: 34 | pass 35 | else: 36 | raise Exception("Should see that 0x10000000000000000 is too big for RAX") 37 | 38 | jitter.cpu.EAX = -0xefffffff & 0xffffffff 39 | assert jitter.cpu.EAX == 0x10000001 40 | 41 | jitter.cpu.EAX = -0xFFFFFFFF & 0xffffffff 42 | assert jitter.cpu.EAX == 1 43 | 44 | try: 45 | jitter.cpu.EAX = -0x1ffffffff 46 | except TypeError: 47 | pass 48 | else: 49 | raise Exception("Should see that -0x1ffffffff is too big for EAX") 50 | -------------------------------------------------------------------------------- /test/jitter/jitload.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from pdb import pm 3 | 4 | from miasm.core.utils import decode_hex, encode_hex 5 | from miasm.jitter.csts import PAGE_READ, PAGE_WRITE 6 | from miasm.analysis.machine import Machine 7 | from miasm.expression.expression import ExprId, ExprAssign, ExprInt, ExprMem 8 | from miasm.core.locationdb import LocationDB 9 | 10 | 11 | # Initial data: from 'example/samples/x86_32_sc.bin' 12 | data = decode_hex("8d49048d5b0180f90174058d5bffeb038d5b0189d8c3") 13 | loc_db = LocationDB() 14 | 15 | # Init jitter 16 | myjit = Machine("x86_32").jitter(loc_db, sys.argv[1]) 17 | myjit.init_stack() 18 | 19 | run_addr = 0x40000000 20 | myjit.vm.add_memory_page(run_addr, PAGE_READ | PAGE_WRITE, data) 21 | 22 | # Sentinelle called on terminate 23 | def code_sentinelle(jitter): 24 | jitter.running = False 25 | jitter.pc = 0 26 | return True 27 | 28 | myjit.push_uint32_t(0x1337beef) 29 | myjit.add_breakpoint(0x1337beef, code_sentinelle) 30 | 31 | # Run 32 | myjit.init_run(run_addr) 33 | myjit.continue_run() 34 | 35 | # Check end 36 | assert myjit.running is False 37 | 38 | # Check resulting state / accessors 39 | assert myjit.cpu.EAX == 0 40 | assert myjit.cpu.ECX == 4 41 | 42 | # Check eval_expr 43 | eax = ExprId("RAX", 64)[:32] 44 | imm0, imm4, imm4_64 = ExprInt(0, 32), ExprInt(4, 32), ExprInt(4, 64) 45 | memdata = ExprMem(ExprInt(run_addr, 32), len(data) * 8) 46 | assert myjit.eval_expr(eax) == imm0 47 | ## Due to ExprAssign construction, imm4 is "promoted" to imm4_64 48 | assert myjit.eval_expr(ExprAssign(eax, imm4)) == imm4_64 49 | assert myjit.eval_expr(eax) == imm4 50 | ## Changes must be passed on myjit.cpu instance 51 | assert myjit.cpu.EAX == 4 52 | ## Memory 53 | assert int(myjit.eval_expr(memdata)) == int(encode_hex(data[::-1]), 16) 54 | -------------------------------------------------------------------------------- /test/jitter/jmp_out_mem.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from miasm.core.utils import decode_hex 3 | from miasm.jitter.csts import PAGE_READ, PAGE_WRITE, EXCEPT_ACCESS_VIOL 4 | from miasm.analysis.machine import Machine 5 | from miasm.core.locationdb import LocationDB 6 | 7 | 8 | def code_sentinelle(jitter): 9 | jitter.running = False 10 | jitter.pc = 0 11 | return True 12 | 13 | 14 | machine = Machine("x86_32") 15 | loc_db = LocationDB() 16 | jitter = machine.jitter(loc_db, sys.argv[1]) 17 | 18 | jitter.init_stack() 19 | 20 | # nop 21 | # mov eax, 0x42 22 | # jmp 0x20 23 | 24 | data = decode_hex("90b842000000eb20") 25 | 26 | # Will raise memory error at 0x40000028 27 | 28 | error_raised = False 29 | def raise_me(jitter): 30 | global error_raised 31 | error_raised = True 32 | assert jitter.pc == 0x40000028 33 | return False 34 | 35 | jitter.add_exception_handler(EXCEPT_ACCESS_VIOL, raise_me) 36 | 37 | 38 | run_addr = 0x40000000 39 | 40 | jitter.vm.add_memory_page(run_addr, PAGE_READ | PAGE_WRITE, data) 41 | 42 | jitter.set_trace_log() 43 | jitter.push_uint32_t(0x1337beef) 44 | 45 | jitter.add_breakpoint(0x1337beef, code_sentinelle) 46 | 47 | jitter.init_run(run_addr) 48 | jitter.continue_run() 49 | 50 | assert error_raised is True 51 | -------------------------------------------------------------------------------- /test/jitter/test_post_instr.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import sys 3 | 4 | from miasm.core.utils import decode_hex 5 | from miasm.analysis.machine import Machine 6 | from miasm.jitter.csts import PAGE_READ, PAGE_WRITE, \ 7 | EXCEPT_BREAKPOINT_MEMORY, EXCEPT_ACCESS_VIOL 8 | from miasm.core.locationdb import LocationDB 9 | from miasm.jitter.jitload import JitterException 10 | 11 | machine = Machine("x86_32") 12 | loc_db = LocationDB() 13 | jitter = machine.jitter(loc_db, sys.argv[1]) 14 | 15 | # Prepare stack and reset memory accesses to avoid an exception 16 | jitter.vm.add_memory_page(0x10000, PAGE_READ|PAGE_WRITE, b"\x00"*0x1000, "stack") 17 | print(jitter.vm) 18 | 19 | jitter.cpu.ESP = 0x10000 + 0x1000 20 | jitter.push_uint32_t(0x0) 21 | jitter.push_uint32_t(0x1337beef) 22 | 23 | jitter.vm.reset_memory_access() 24 | print(hex(jitter.vm.get_exception())) 25 | 26 | # Add code, and keep memory write pending 27 | jitter.vm.add_memory_page(0x1000, PAGE_READ|PAGE_WRITE, b"\x00"*0x1000, "code page") 28 | 29 | # MOV EAX, 0x11223344 30 | # RET 31 | jitter.vm.set_mem(0x1000, decode_hex("B844332211C3")) 32 | 33 | 34 | jitter.set_trace_log() 35 | 36 | def do_not_raise_me(jitter): 37 | raise ValueError("Should not be here") 38 | 39 | jitter.add_exception_handler(EXCEPT_BREAKPOINT_MEMORY, do_not_raise_me) 40 | jitter.vm.add_memory_breakpoint(0x11000-4, 4, PAGE_READ | PAGE_WRITE) 41 | 42 | # The memory write pending will raise automod exception 43 | # The RET should not re evaluate PC @ [ESP+4] 44 | jitter.init_run(0x1000) 45 | try: 46 | jitter.continue_run() 47 | except JitterException: 48 | assert jitter.vm.get_exception() == EXCEPT_ACCESS_VIOL 49 | -------------------------------------------------------------------------------- /test/jitter/vm_mngr.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from miasm.jitter.csts import PAGE_READ, PAGE_WRITE 3 | from miasm.analysis.machine import Machine 4 | from miasm.core.locationdb import LocationDB 5 | 6 | loc_db = LocationDB() 7 | myjit = Machine("x86_32").jitter(loc_db, sys.argv[1]) 8 | 9 | base_addr = 0x13371337 10 | page_size = 0x1000 11 | data = b"\x00" * page_size 12 | rights = [0, PAGE_READ, PAGE_WRITE, PAGE_READ|PAGE_WRITE] 13 | shuffled_rights = [PAGE_READ, 0, PAGE_READ|PAGE_WRITE, PAGE_WRITE] 14 | 15 | # Add pages 16 | for i, access_right in enumerate(rights): 17 | myjit.vm.add_memory_page(base_addr + i * page_size, access_right, data) 18 | 19 | # Check rights 20 | for i, access_right in enumerate(rights): 21 | assert myjit.vm.get_mem_access(base_addr + i * page_size) == access_right 22 | 23 | # Modify rights 24 | for i, access_right in enumerate(shuffled_rights): 25 | myjit.vm.set_mem_access(base_addr + i * page_size, access_right) 26 | 27 | # Check for modification 28 | for i, access_right in enumerate(shuffled_rights): 29 | assert myjit.vm.get_mem_access(base_addr + i * page_size) == access_right 30 | 31 | # Remove pages 32 | for i in range(len(rights)): 33 | myjit.vm.remove_memory_page(base_addr + i * page_size) 34 | 35 | # Add pages again 36 | for i, access_right in enumerate(rights): 37 | myjit.vm.add_memory_page(base_addr + i * page_size, access_right, data) 38 | -------------------------------------------------------------------------------- /test/os_dep/common.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python2 2 | #-*- coding:utf-8 -*- 3 | 4 | from builtins import range 5 | import unittest 6 | import logging 7 | from miasm.analysis.machine import Machine 8 | import miasm.os_dep.common as commonapi 9 | from miasm.core.utils import pck32 10 | from miasm.jitter.csts import PAGE_READ, PAGE_WRITE 11 | from miasm.core.locationdb import LocationDB 12 | 13 | machine = Machine("x86_32") 14 | 15 | loc_db = LocationDB() 16 | jit = machine.jitter(loc_db) 17 | jit.init_stack() 18 | 19 | class TestCommonAPI(unittest.TestCase): 20 | 21 | def test_get_size(self): 22 | heap = commonapi.heap() 23 | with self.assertRaises(AssertionError): 24 | heap.get_size(jit.vm, 0) 25 | heap.alloc(jit, 20) 26 | heap.alloc(jit, 40) 27 | heap.alloc(jit, 50) 28 | heap.alloc(jit, 60) 29 | ptr = heap.alloc(jit, 10) 30 | heap.alloc(jit, 80) 31 | for i in range(10): 32 | self.assertEqual(heap.get_size(jit.vm, ptr+i), 10) 33 | 34 | if __name__ == '__main__': 35 | testsuite = unittest.TestLoader().loadTestsFromTestCase(TestCommonAPI) 36 | report = unittest.TextTestRunner(verbosity=2).run(testsuite) 37 | exit(len(report.errors + report.failures)) 38 | 39 | -------------------------------------------------------------------------------- /test/os_dep/linux/stdlib.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python2 2 | #-*- coding:utf-8 -*- 3 | 4 | import unittest 5 | import logging 6 | from miasm.analysis.machine import Machine 7 | import miasm.os_dep.linux_stdlib as stdlib 8 | from miasm.core.utils import pck32 9 | from miasm.jitter.csts import PAGE_READ, PAGE_WRITE 10 | from miasm.core.locationdb import LocationDB 11 | 12 | machine = Machine("x86_32") 13 | 14 | loc_db = LocationDB() 15 | jit = machine.jitter(loc_db) 16 | jit.init_stack() 17 | 18 | heap = stdlib.linobjs.heap 19 | 20 | class TestLinuxStdlib(unittest.TestCase): 21 | 22 | def test_xxx_sprintf(self): 23 | def alloc_str(s): 24 | s += b"\x00" 25 | ptr = heap.alloc(jit, len(s)) 26 | jit.vm.set_mem(ptr, s) 27 | return ptr 28 | fmt = alloc_str(b"'%s' %d") 29 | str_ = alloc_str(b"coucou") 30 | buf = heap.alloc(jit,1024) 31 | 32 | jit.push_uint32_t(1111) 33 | jit.push_uint32_t(str_) 34 | jit.push_uint32_t(fmt) 35 | jit.push_uint32_t(buf) 36 | jit.push_uint32_t(0) # ret_ad 37 | stdlib.xxx_sprintf(jit) 38 | ret = jit.get_c_str(buf) 39 | self.assertEqual(ret, "'coucou' 1111") 40 | 41 | 42 | if __name__ == '__main__': 43 | testsuite = unittest.TestLoader().loadTestsFromTestCase(TestLinuxStdlib) 44 | report = unittest.TextTestRunner(verbosity=2).run(testsuite) 45 | exit(len(report.errors + report.failures)) 46 | -------------------------------------------------------------------------------- /test/os_dep/linux/test_env.aarch64l: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cea-sec/miasm/2a15c60712b326b541d42ac48f372f97023547e7/test/os_dep/linux/test_env.aarch64l -------------------------------------------------------------------------------- /test/os_dep/linux/test_env.arml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cea-sec/miasm/2a15c60712b326b541d42ac48f372f97023547e7/test/os_dep/linux/test_env.arml -------------------------------------------------------------------------------- /test/os_dep/linux/test_env.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char** argv, char** envp) 5 | { 6 | printf("argc %d\n", argc); 7 | printf("argv[0] %s\n", argv[0]); 8 | printf("argv[1] %s\n", argv[1]); 9 | printf("envp[0] %s\n", envp[0]); 10 | } 11 | -------------------------------------------------------------------------------- /test/os_dep/linux/test_env.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import os 3 | import sys 4 | from pdb import pm 5 | from miasm.analysis.binary import Container 6 | from miasm.analysis.sandbox import Sandbox_Linux_x86_32, Sandbox_Linux_x86_64,\ 7 | Sandbox_Linux_arml, Sandbox_Linux_aarch64l 8 | from miasm.core.locationdb import LocationDB 9 | 10 | if len(sys.argv) < 2: 11 | print("Usage: %s ..." % sys.argv[0]) 12 | exit(0) 13 | 14 | arch = sys.argv[1] 15 | 16 | if arch == "x86_32": 17 | sandbox = Sandbox_Linux_x86_32 18 | elif arch == "x86_64": 19 | sandbox = Sandbox_Linux_x86_64 20 | elif arch == "arml": 21 | sandbox = Sandbox_Linux_arml 22 | elif arch == "aarch64l": 23 | sandbox = Sandbox_Linux_aarch64l 24 | else: 25 | raise ValueError("Unsupported arch: %s" % arch) 26 | 27 | # Parse arguments 28 | parser = sandbox.parser(description="ELF sandboxer") 29 | parser.add_argument("filename", help="ELF Filename") 30 | options = parser.parse_args(sys.argv[2:]) 31 | 32 | # Create sandbox 33 | loc_db = LocationDB() 34 | sb = sandbox(loc_db, options.filename, options, globals()) 35 | 36 | # Run 37 | sb.run() 38 | 39 | assert(sb.jitter.running is False) 40 | -------------------------------------------------------------------------------- /test/os_dep/linux/test_env.x86_32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cea-sec/miasm/2a15c60712b326b541d42ac48f372f97023547e7/test/os_dep/linux/test_env.x86_32 -------------------------------------------------------------------------------- /test/os_dep/linux/test_env.x86_64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cea-sec/miasm/2a15c60712b326b541d42ac48f372f97023547e7/test/os_dep/linux/test_env.x86_64 -------------------------------------------------------------------------------- /test/samples/x86_32/bsr_bsf.S: -------------------------------------------------------------------------------- 1 | main: 2 | ;; BSF 3 | ;; standard case 4 | MOV ECX, 0xF0000004 5 | MOV EAX, 0x0 6 | BSF EAX, ECX 7 | JZ bad 8 | CMP EAX, 2 9 | JNZ bad 10 | 11 | 12 | ;; case undef 13 | MOV ECX, 0x0 14 | MOV EAX, 0x1337beef 15 | BSF EAX, ECX 16 | JNZ bad 17 | CMP EAX, 0x1337beef 18 | JNZ bad 19 | 20 | ;; BSR 21 | ;; standard case 22 | MOV ECX, 0x4000000F 23 | MOV EAX, 0x0 24 | BSR EAX, ECX 25 | JZ bad 26 | CMP EAX, 30 27 | JNZ bad 28 | 29 | 30 | ;; case undef 31 | MOV ECX, 0x0 32 | MOV EAX, 0x1337beef 33 | BSR EAX, ECX 34 | JNZ bad 35 | CMP EAX, 0x1337beef 36 | JNZ bad 37 | 38 | RET 39 | 40 | bad: 41 | INT 0x3 42 | RET 43 | -------------------------------------------------------------------------------- /test/samples/x86_32/cst_propag/x86_32_sc_1.S: -------------------------------------------------------------------------------- 1 | main: 2 | PUSH EBP 3 | MOV EBP, ESP 4 | MOV ECX, 1 5 | MOV EDX, 2 6 | LEA ECX, DWORD PTR [ECX+0x4] 7 | LEA EBX, DWORD PTR [ECX+0x1] 8 | CMP CL, 0x1 9 | JZ test1 10 | LEA EBX, DWORD PTR [EBX-1] 11 | JMP end 12 | test1: 13 | LEA EBX, DWORD PTR [EBX-1] 14 | end: 15 | MOV EAX, EBX 16 | LEA EAX, DWORD PTR [EAX + EDX] 17 | MOV EDX, DWORD PTR [EBP+0xC] 18 | LEA EAX, DWORD PTR [EAX + EDX] 19 | MOV ESP, EBP 20 | POP EBP 21 | RET 22 | -------------------------------------------------------------------------------- /test/samples/x86_32/cst_propag/x86_32_sc_10.S: -------------------------------------------------------------------------------- 1 | main: 2 | PUSH EBP 3 | MOV EBP, ESP 4 | MOV ECX, DWORD PTR [ESP+0x8] 5 | INC EBX 6 | CMP CL, 0x1 7 | JZ test1 8 | MOV EAX, 8 9 | JMP end 10 | test1: 11 | MOV EAX, 4 12 | end: 13 | LEA EBX, DWORD PTR [EAX+EBX] 14 | MOV EAX, EBX 15 | MOV ESP, EBP 16 | POP EBP 17 | RET 18 | -------------------------------------------------------------------------------- /test/samples/x86_32/cst_propag/x86_32_sc_11.S: -------------------------------------------------------------------------------- 1 | main: 2 | MOV ECX, 10 3 | loop1: 4 | DEC ECX 5 | JNZ less 6 | JMP goon 7 | less: 8 | DEC ECX 9 | goon: 10 | JNZ loop1 11 | RET 12 | -------------------------------------------------------------------------------- /test/samples/x86_32/cst_propag/x86_32_sc_12.S: -------------------------------------------------------------------------------- 1 | main: 2 | MOV EBX, 1 3 | MOV ECX, 2 4 | CMP EDX, 3 5 | JNZ test1 6 | ADD EBX, 1 7 | JMP goon 8 | test1: 9 | ADD ECX, 1 10 | goon: 11 | LEA EAX, DWORD PTR [EBX+ECX] 12 | RET 13 | -------------------------------------------------------------------------------- /test/samples/x86_32/cst_propag/x86_32_sc_13.S: -------------------------------------------------------------------------------- 1 | main: 2 | MOV ECX, 10 3 | loop: 4 | DEC ECX 5 | JNZ loop 6 | MOV EAX, ECX 7 | RET 8 | -------------------------------------------------------------------------------- /test/samples/x86_32/cst_propag/x86_32_sc_14.S: -------------------------------------------------------------------------------- 1 | main: 2 | MOV ECX, 10 3 | MOV EDX, 10 4 | loop: 5 | INC EDX 6 | DEC EDX 7 | DEC ECX 8 | JNZ loop 9 | MOV EAX, EDX 10 | RET 11 | -------------------------------------------------------------------------------- /test/samples/x86_32/cst_propag/x86_32_sc_15.S: -------------------------------------------------------------------------------- 1 | main: 2 | ADD EDI, 1 3 | MOV ECX, 10 4 | loop1: 5 | MOV EDX, 10 6 | INC EDI 7 | loop2: 8 | ADD EDI, 2 9 | SUB EDI, 2 10 | SUB EDX, 1 11 | JNZ loop2 12 | DEC EDI 13 | SUB ECX, 1 14 | JNZ loop1 15 | MOV EAX, EDI 16 | RET 17 | -------------------------------------------------------------------------------- /test/samples/x86_32/cst_propag/x86_32_sc_16.S: -------------------------------------------------------------------------------- 1 | main: 2 | MOV EBX, 1 3 | ADD EDI, 1 4 | MOV ECX, 10 5 | loop1: 6 | MOV EDX, 10 7 | INC EDI 8 | loop2: 9 | LEA EDI, DWORD PTR [EDI+EBX] 10 | LEA EDI, DWORD PTR [EDI-1] 11 | SUB EDX, 1 12 | JNZ loop2 13 | DEC EDI 14 | SUB ECX, 1 15 | JNZ loop1 16 | MOV EAX, EDI 17 | RET 18 | -------------------------------------------------------------------------------- /test/samples/x86_32/cst_propag/x86_32_sc_17.S: -------------------------------------------------------------------------------- 1 | main: 2 | MOV EBX, 1 3 | ADD EDI, 1 4 | SUB EBX, EDI 5 | SUB EDI, 1 6 | ADD EBX, EDI 7 | MOV EAX, EBX 8 | RET 9 | -------------------------------------------------------------------------------- /test/samples/x86_32/cst_propag/x86_32_sc_18.S: -------------------------------------------------------------------------------- 1 | main: 2 | PUSH EBP 3 | MOV EBP, ESP 4 | MOV EAX, DWORD PTR [EBP+0x8] 5 | MOV EBX, DWORD PTR [EBP+0xC] 6 | ADD EAX, EBX 7 | TEST EAX, EAX 8 | JNZ test 9 | PUSH 1 10 | PUSH 2 11 | PUSH DWORD PTR [EBP+0x10] 12 | CALL func1 13 | ADD ESP, 0xC 14 | JMP goon 15 | test: 16 | MOV ECX, 10 17 | loop: 18 | PUSH 1 19 | PUSH 2 20 | CALL func2 21 | ADD ESP, 0x8 22 | DEC ECX 23 | JNZ loop 24 | goon: 25 | MOV ESP, EBP 26 | POP EBP 27 | RET 28 | 29 | 30 | func1: 31 | RET 32 | func2: 33 | RET 34 | -------------------------------------------------------------------------------- /test/samples/x86_32/cst_propag/x86_32_sc_19.S: -------------------------------------------------------------------------------- 1 | main: 2 | 3 | MOV EBX, 1 4 | MOV ECX, 1 5 | CMP EDX, 10 6 | JZ test1 7 | ADD EBX, 1 8 | ADD ECX, 1 9 | JMP gogon 10 | test1: 11 | ADD EBX, 2 12 | ADD ECX, 2 13 | gogon: 14 | ADD EAX, EBX 15 | ADD EAX, ECX 16 | RET 17 | -------------------------------------------------------------------------------- /test/samples/x86_32/cst_propag/x86_32_sc_2.S: -------------------------------------------------------------------------------- 1 | main: 2 | PUSH EBP 3 | MOV EBP, ESP 4 | MOV ECX, DWORD PTR [ESP+0x8] 5 | MOV EDX, DWORD PTR [EBP+0xC] 6 | LEA ECX, DWORD PTR [ECX+0x4] 7 | LEA EBX, DWORD PTR [EBX+0x1] 8 | CMP CL, 0x1 9 | JZ test1 10 | LEA EBX, DWORD PTR [EBX-1] 11 | JMP end 12 | test1: 13 | LEA EBX, DWORD PTR [EBX+0x1] 14 | end: 15 | MOV EAX, EBX 16 | LEA EAX, DWORD PTR [EAX + EDX] 17 | MOV EDX, DWORD PTR [EBP+0xC] 18 | LEA EAX, DWORD PTR [EAX + EDX] 19 | MOV ESP, EBP 20 | POP EBP 21 | RET 22 | -------------------------------------------------------------------------------- /test/samples/x86_32/cst_propag/x86_32_sc_20.S: -------------------------------------------------------------------------------- 1 | main: 2 | MOV EBX, 0 3 | MOV ECX, 0 4 | 5 | CMP EDX, 0 6 | JNZ test1 7 | JMP goon 8 | test1: 9 | MOV EDX, 1 10 | LEA EDX, DWORD PTR [EDX+0xF] 11 | LEA EBX, DWORD PTR [EBX+EDX] 12 | MOV EDX, 2 13 | LEA EDX, DWORD PTR [EDX+0xE] 14 | MOV ECX, EDX 15 | LEA EBX, DWORD PTR [EBX+ECX] 16 | JNZ test1 17 | goon: 18 | MOV EAX, EBX 19 | RET 20 | -------------------------------------------------------------------------------- /test/samples/x86_32/cst_propag/x86_32_sc_3.S: -------------------------------------------------------------------------------- 1 | main: 2 | PUSH EBP 3 | MOV EBP, ESP 4 | MOV ECX, DWORD PTR [EBP+0x8] 5 | loop: 6 | SUB ECX, 1 7 | JZ end 8 | PUSH EDX 9 | POP ESI 10 | JMP loop 11 | end: 12 | MOV EAX, DWORD PTR [ESP+0xC] 13 | MOV ESP, EBP 14 | POP EBP 15 | RET 16 | -------------------------------------------------------------------------------- /test/samples/x86_32/cst_propag/x86_32_sc_4.S: -------------------------------------------------------------------------------- 1 | main: 2 | PUSH EBP 3 | MOV EBP, ESP 4 | MOV ECX, DWORD PTR [EBP+0x8] 5 | loop: 6 | PUSH EDX 7 | POP ESI 8 | SUB ECX, 1 9 | JZ end 10 | JMP loop 11 | end: 12 | MOV EAX, DWORD PTR [ESP+0xC] 13 | MOV ESP, EBP 14 | POP EBP 15 | RET 16 | -------------------------------------------------------------------------------- /test/samples/x86_32/cst_propag/x86_32_sc_5.S: -------------------------------------------------------------------------------- 1 | main: 2 | PUSH EBP 3 | MOV EBP, ESP 4 | MOV ECX, DWORD PTR [EBP+0x8] 5 | 6 | SUB ECX, 1 7 | JZ test1 8 | SUB ECX, 1 9 | JZ test2 10 | SUB ECX, 1 11 | JZ test3 12 | 13 | JMP end 14 | test1: 15 | INC EAX 16 | test2: 17 | INC EAX 18 | test3: 19 | INC EAX 20 | end: 21 | INC EAX 22 | MOV ESP, EBP 23 | POP EBP 24 | RET 25 | -------------------------------------------------------------------------------- /test/samples/x86_32/cst_propag/x86_32_sc_6.S: -------------------------------------------------------------------------------- 1 | main: 2 | PUSH EBP 3 | MOV EBP, ESP 4 | MOV ECX, DWORD PTR [EBP+0x8] 5 | 6 | INC EAX 7 | SUB ECX, 1 8 | JZ test1 9 | ADD EAX, 1 10 | JMP go1 11 | test1: 12 | ADD EAX, 2 13 | go1: 14 | 15 | 16 | INC EAX 17 | SUB ECX, 1 18 | JZ test2 19 | ADD EAX, 0x10 20 | JMP go2 21 | test2: 22 | ADD EAX, 0x20 23 | go2: 24 | 25 | INC EAX 26 | SUB ECX, 1 27 | JZ test3 28 | ADD EAX, 0x30 29 | JMP go3 30 | test3: 31 | ADD EAX, 0x40 32 | go3: 33 | 34 | INC EAX 35 | MOV ESP, EBP 36 | POP EBP 37 | RET 38 | -------------------------------------------------------------------------------- /test/samples/x86_32/cst_propag/x86_32_sc_7.S: -------------------------------------------------------------------------------- 1 | main: 2 | PUSH EBP 3 | MOV EBP, ESP 4 | MOV ECX, DWORD PTR [EBP+0x8] 5 | INC EAX 6 | 7 | loop: 8 | INC EAX 9 | DEC EAX 10 | SUB ECX, 1 11 | JZ loop 12 | 13 | INC EAX 14 | MOV ESP, EBP 15 | POP EBP 16 | RET 17 | -------------------------------------------------------------------------------- /test/samples/x86_32/cst_propag/x86_32_sc_8.S: -------------------------------------------------------------------------------- 1 | main: 2 | PUSH EBP 3 | MOV EBP, ESP 4 | MOV ECX, DWORD PTR [EBP+0x8] 5 | INC EAX 6 | 7 | loop: 8 | MOV EDX, 1 9 | MOV ESI, 1 10 | ADD EAX, EDX 11 | SUB EAX, ESI 12 | SUB ECX, 1 13 | JZ loop 14 | 15 | INC EAX 16 | MOV ESP, EBP 17 | POP EBP 18 | RET 19 | -------------------------------------------------------------------------------- /test/samples/x86_32/cst_propag/x86_32_sc_9.S: -------------------------------------------------------------------------------- 1 | main: 2 | PUSH EBP 3 | MOV EBP, ESP 4 | MOV ECX, 10 ; DWORD PTR [EBP+0x8] 5 | 6 | MOV EBX, 0x1000 ; 7 | INC EBX ; EBX = 0x1001 8 | MOV EAX, EBX ; EAX = 0x1001 9 | MOV EBX, 0x10001 ; EBX = 0x10001 10 | DEC EBX ; EBX = 0x10000 11 | MOV ESI, EBX ; ESI = 0x10000 12 | ; 13 | ADD EDI, EAX ; EDI += 0x1001 14 | ADD EDI, ESI ; EDI += 0x10000 15 | ;; EDI = EDI + 0x11001 16 | 17 | loop: 18 | MOV EBX, 0x1000 ; 19 | MOV EAX, EBX ; 20 | MOV EBX, 0x100001 ; 21 | MOV ESI, EBX ; 22 | MUL ESI ; EAX = 0x1000 23 | MOV EBX, 0x1 ; 24 | ADD EDI, EBX ; EDI += 1 25 | MOV EBX, 0x1000 ; 26 | ADD EDI, EBX ; EDI += 0x1000 27 | SUB EDI, EAX ; EDI -= 0x1000 28 | DEC EDI ; EDI -= 1 29 | SUB ECX, 1 30 | JNZ loop 31 | 32 | INC EDI 33 | MOV EAX, EDI 34 | MOV ESP, EBP 35 | POP EBP 36 | RET 37 | -------------------------------------------------------------------------------- /test/samples/x86_32/dg_test_00.S: -------------------------------------------------------------------------------- 1 | main: 2 | MOV ECX, 0x1 3 | JMP lbl1 4 | lbl1: 5 | MOV EBX, ECX 6 | JMP lbl2 7 | lbl2: 8 | MOV EAX, EBX 9 | RET 10 | -------------------------------------------------------------------------------- /test/samples/x86_32/dg_test_01.S: -------------------------------------------------------------------------------- 1 | main: 2 | MOV ECX, 0x1 3 | JMP lbl1 4 | lbl1: 5 | MOV EBX, 0x2 6 | JMP lbl2 7 | lbl2: 8 | LEA EAX, DWORD PTR [EBX + ECX] 9 | RET 10 | -------------------------------------------------------------------------------- /test/samples/x86_32/dg_test_02.S: -------------------------------------------------------------------------------- 1 | main: 2 | MOV ECX, 0x1 3 | JZ lbl2 4 | lbl1: 5 | MOV EBX, 0x2 6 | JMP end 7 | lbl2: 8 | MOV EBX, 0x3 9 | JMP end 10 | end: 11 | LEA EAX, DWORD PTR [EBX + ECX] 12 | RET 13 | -------------------------------------------------------------------------------- /test/samples/x86_32/dg_test_03.S: -------------------------------------------------------------------------------- 1 | main: 2 | MOV EBX, 0x1 3 | JMP lbl1 4 | lbl1: 5 | ADD EBX, 0x2 6 | CMP EBX, 0x0 7 | JNZ lbl1 8 | end: 9 | MOV EAX, EBX 10 | RET 11 | -------------------------------------------------------------------------------- /test/samples/x86_32/dg_test_04.S: -------------------------------------------------------------------------------- 1 | main: 2 | MOV ECX, 0x1 3 | JMP lbl1 4 | lbl1: 5 | ADD ECX, 0x2 6 | CMP ECX, 0x0 7 | JZ lbl1 8 | end: 9 | MOV EAX, EBX 10 | RET 11 | -------------------------------------------------------------------------------- /test/samples/x86_32/dg_test_05.S: -------------------------------------------------------------------------------- 1 | main: 2 | MOV ECX, 0x1 3 | MOV EBX, 0x3 4 | JMP lbl1 5 | lbl1: 6 | ADD ECX, 0x2 7 | CMP ECX, 0x0 8 | JZ lbl1 9 | end: 10 | MOV EAX, EBX 11 | RET 12 | -------------------------------------------------------------------------------- /test/samples/x86_32/dg_test_06.S: -------------------------------------------------------------------------------- 1 | main: 2 | MOV ECX, 0x1 3 | MOV EDX, 0x2 4 | JMP lbl1 5 | lbl1: 6 | MOV EBX, ECX 7 | MOV ECX, EDX 8 | CMP EAX, 0x0 9 | JZ lbl1 10 | end: 11 | MOV EAX, EBX 12 | RET 13 | -------------------------------------------------------------------------------- /test/samples/x86_32/dg_test_07.S: -------------------------------------------------------------------------------- 1 | main: 2 | MOV ECX, 0x1 3 | MOV EBX, 0x2 4 | JMP lbl1 5 | lbl1: 6 | XCHG EBX, ECX 7 | JMP end 8 | end: 9 | MOV EAX, EBX 10 | RET 11 | -------------------------------------------------------------------------------- /test/samples/x86_32/dg_test_08.S: -------------------------------------------------------------------------------- 1 | main: 2 | MOV ECX, 0x1 3 | MOV EBX, 0x2 4 | JMP lbl1 5 | lbl1: 6 | XCHG EBX, ECX 7 | JMP end 8 | end: 9 | MOV EAX, EBX 10 | RET 11 | -------------------------------------------------------------------------------- /test/samples/x86_32/dg_test_09.S: -------------------------------------------------------------------------------- 1 | main: 2 | MOV ECX, 0x8 3 | JZ lbl2 4 | lbl1: 5 | MOV EAX, 0x1 6 | MOV EBX, 0x2 7 | JMP end 8 | lbl2: 9 | MOV EAX, 0x3 10 | MOV EBX, 0x4 11 | JMP end 12 | end: 13 | RET 14 | -------------------------------------------------------------------------------- /test/samples/x86_32/dg_test_10.S: -------------------------------------------------------------------------------- 1 | main: 2 | MOV ECX, 0x8 3 | JZ lbl2 4 | lbl1: 5 | MOV EAX, 0x1 6 | JMP end1 7 | lbl2: 8 | MOV EAX, 0x2 9 | JMP end1 10 | end1: 11 | JZ lbl4 12 | lbl3: 13 | MOV EBX, 0x3 14 | JMP end 15 | lbl4: 16 | MOV EBX, 0x4 17 | JMP end 18 | 19 | end: 20 | RET 21 | -------------------------------------------------------------------------------- /test/samples/x86_32/dg_test_11.S: -------------------------------------------------------------------------------- 1 | main: 2 | MOV EBX, 0x1 3 | JMP lbl1 4 | lbl1: 5 | ADD EBX, 0x2 6 | CMP EBX, 0x0 7 | JNZ lbl1 8 | end: 9 | MOV EAX, EBX 10 | RET 11 | -------------------------------------------------------------------------------- /test/samples/x86_64/mul_div.S: -------------------------------------------------------------------------------- 1 | main: 2 | ;; MUL 3 | MOV RCX, 0x20000002 4 | MOV RAX, 0x1122334455667788 5 | MOV RDX, RAX 6 | MOV RAX, 0x1122334400000020 7 | MUL ECX 8 | CMP RAX, 0x40 9 | JNZ bad 10 | CMP RDX, 0x4 11 | JNZ bad 12 | 13 | ;; IMUL 14 | MOV RCX, 0xFFFFFFF2 15 | MOV RAX, 0x1122334455667788 16 | MOV RDX, RAX 17 | MOV RAX, 0x1122334400000020 18 | IMUL ECX 19 | MOV ESI, 0xFFFFFE40 20 | CMP RAX, RSI 21 | JNZ bad 22 | MOV ESI 0xFFFFFFFF 23 | CMP RDX, RSI 24 | JNZ bad 25 | 26 | ;; DIV 27 | MOV RAX, 0x1122334400000002 28 | MOV RCX, RAX 29 | MOV RAX, 0x1122334400000000 30 | MOV RDX, RAX 31 | MOV RAX, 0x1122334440000003 32 | DIV ECX 33 | CMP RAX, 0x20000001 34 | JNZ bad 35 | CMP RDX, 0x1 36 | JNZ bad 37 | 38 | ;; IDIV 39 | MOV RAX, 0x11223344FFFFFFF2 40 | MOV RCX, RAX 41 | MOV RAX, 0x11223344FFFFFFFF 42 | MOV RDX, RAX 43 | MOV RAX, 0x11223344FFFFFFF2 44 | IDIV ECX 45 | CMP RAX, 0x1 46 | JNZ bad 47 | CMP RDX, 0x0 48 | JNZ bad 49 | 50 | 51 | RET 52 | 53 | bad: 54 | INT 0x3 55 | 56 | -------------------------------------------------------------------------------- /test/utils/__init__.py: -------------------------------------------------------------------------------- 1 | __all__ = ["test", "testset", "cosmetics"] 2 | -------------------------------------------------------------------------------- /test/utils/cosmetics.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import os 3 | import platform 4 | 5 | is_win = platform.system() == "Windows" 6 | 7 | def getTerminalSize(): 8 | "Return the size of the terminal : COLUMNS, LINES" 9 | 10 | env = os.environ 11 | 12 | def ioctl_GWINSZ(fd): 13 | try: 14 | import fcntl 15 | import termios 16 | import struct 17 | import os 18 | cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ, 19 | '1234')) 20 | except: 21 | return 22 | return cr 23 | cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2) 24 | if not cr: 25 | try: 26 | fd = os.open(os.ctermid(), os.O_RDONLY) 27 | cr = ioctl_GWINSZ(fd) 28 | os.close(fd) 29 | except: 30 | pass 31 | if not cr: 32 | cr = (env.get('LINES', 25), env.get('COLUMNS', 80)) 33 | return int(cr[1]), int(cr[0]) 34 | 35 | 36 | WIDTH = getTerminalSize()[0] 37 | colors = { 38 | "red": "\033[91;1m", 39 | "end": "\033[0m", 40 | "green": "\033[92;1m", 41 | "lightcyan": "\033[96m", 42 | "blue": "\033[94;1m" 43 | } 44 | 45 | if is_win: 46 | colors = { 47 | "red": "", 48 | "end": "", 49 | "green": "", 50 | "lightcyan": "", 51 | "blue": "" 52 | } 53 | 54 | def write_colored(text, color, already_printed=0): 55 | text_colored = colors[color] + text + colors["end"] 56 | print(" " * (WIDTH - already_printed - len(text)) + text_colored) 57 | 58 | 59 | def write_underline(text): 60 | print("\033[4m" + text + colors["end"]) 61 | -------------------------------------------------------------------------------- /test/utils/multithread.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import sys 3 | from . import cosmetics 4 | import time 5 | 6 | 7 | def task_done(test, error, test_ok, test_ko): 8 | command_line = " ".join(test.command_line) 9 | if error is not None: 10 | print(cosmetics.colors["red"] + 'ERROR', end=' ') 11 | print(cosmetics.colors["lightcyan"] + command_line + cosmetics.colors["end"]) 12 | print(error) 13 | test_ko.append((test, error)) 14 | else: 15 | print(cosmetics.colors["green"] + 'DONE', end=' ') 16 | print(cosmetics.colors["lightcyan"] + command_line + cosmetics.colors["end"], end=' ') 17 | print("%ds" % (time.time() - test.start_time)) 18 | test_ok.append((test, error)) 19 | 20 | 21 | def task_new(test): 22 | command_line = " ".join(test.command_line) 23 | print(cosmetics.colors["lightcyan"], end=' ') 24 | print(test.base_dir.upper(), command_line, end=' ') 25 | print(cosmetics.colors["end"]) 26 | -------------------------------------------------------------------------------- /test/utils/test.py: -------------------------------------------------------------------------------- 1 | class Test(object): 2 | "Stand for a test to run" 3 | 4 | def __init__(self, command_line, base_dir="", depends=None, 5 | products=None, tags=None, executable=None): 6 | """Create a Test instance. 7 | @command_line: list of string standing for arguments to launch 8 | @base_dir: base directory for launch 9 | @depends: list of Test instance indicating dependencies 10 | @products: elements produced to remove after tests 11 | @tags: list of str indicating current test categories 12 | @executable: if set, use this binary instead of Python 13 | """ 14 | self.command_line = command_line 15 | self.base_dir = base_dir 16 | self.depends = depends if depends else [] 17 | self.products = products if products else [] 18 | self.tags = tags if tags else [] 19 | self.executable = executable 20 | 21 | def __repr__(self): 22 | displayed = ["command_line", "base_dir", "depends", "products", "tags"] 23 | displayed.append("python" if not self.executable else self.executable) 24 | return "" 26 | 27 | def __eq__(self, test): 28 | if not isinstance(test, Test): 29 | return False 30 | 31 | return all([self.command_line == test.command_line, 32 | self.base_dir == test.base_dir, 33 | self.depends == test.depends, 34 | self.products == test.products, 35 | self.tags == test.tags, 36 | self.executable == test.executable, 37 | ]) 38 | --------------------------------------------------------------------------------