Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    X3eRo0
    @X3eRo0
    The problem is between 2 basic blocks that contains the call afl_maybe_log we may have a basic block that doesn't have a call afl_maybe_log
    So to connect them together we have to follow through the middle basic block
    If miasm does not split at call instruction then this middle basic block goes away
    serpilliere
    @serpilliere
    maybe you will have to 'order' the basic blocks from the head: maybe a kind of 'dominator tree' ?
    X3eRo0
    @X3eRo0
    How can I do that? Any examples?
    X3eRo0
    @X3eRo0
    @serpilliere turns out that for some reason miasm was treating argument to call as normal integer argument and not a correct address
    as you know call's arguments are relative to rip, so our weird numbers were just relative offset to "__afl_maybe_log" and i fixed it with a simple hack
    to calculate the absolute address and fix the arguments of call instruction. Any idea which part of code would be responible for handeling the argument of call correctly when removed from the break_flow()?
    serpilliere
    @serpilliere
    you mean the call to afl were stuffs like call [RIP + XXX] right ?
    X3eRo0
    @X3eRo0
    No call instruction itself stores the destination relative to rip
    For example 1: call 5
    Will call to address 6
    serpilliere
    @serpilliere
    yes, but with the origin miasm calln it's fix and transformed to call ExprLoc(XXX), correct ?
    -mrh-
    @-mrh-:matrix.org
    [m]
    MIASM IS THE FUCKING BEST RER FRAMEWORK !
    sar5430
    @sar5430
    can confirm
    serpilliere
    @serpilliere
    lol
    Khangaroo
    @khang06
    what's the easiest way to get all possible destinations of a basic block? i was thinking that i could use symbolic execution on the block and then shove irdst into z3 and make it generate all possible solutions, but i was wondering if that was overcomplicating things and that there's a better way
    Khangaroo
    @khang06
    ended up just going with z3 anyways, but now there's the issue of it spitting out a bunch of garbage answers because of the lack of memory concretization since this relies on jump tables
    Andrix44
    @Andrix44
    How can I make the symbolic execution jump into a function? I want it to have the same effect as being inlined. call_func_ret(0x40120D, call_func_stack(0x401236, ESP + 0xFFFFFFDC) + 0xFFFFFFFC)[0:8]?(0x4013CA,0x401412)
    xikhud
    @acquykhud

    Hi everyone, I have a piece of asm code like this

    .text:00007A3B 89 4C 24 04                             mov     [esp+4], ecx
    .text:00007A3F 89 04 24                                mov     [esp], eax
    .text:00007A42 C7 44 24 08 00 00 00 00                 mov     dword ptr [esp+8], 0
    .text:00007A4A E8 51 15 00 00                          call    alloc_string
    .text:00007A4F 89 C6                                   mov     esi, eax

    alloc_string is an external function (it's not a glibc function) so when I run it in sandbox (attached by a DSEEngine), I want to skip 5 bytes at 0x7A4A, what I did is

    def hook_alloc_string_dse(dse: DSEEngine):
        jitter = dse.jitter # type: jitter_x86_32
        regs = dse.lifter.arch.regs
        input_addr = 0x3000000
        jitter.cpu.EIP += 5
        jitter.cpu.EAX = input_addr
        jitter.vm.add_memory_page(input_addr, 3, b'AAAAAAAAAAAAAAAAAAAAA')
        dse.update_state(
            {
                regs.EIP: ExprInt(jitter.cpu.EIP, 32),
                regs.EAX: ExprInt(input_addr, 32)
            }
        )
    
    dse = DSEEngine(sb.machine, loc_db=loc_db)
    dse.attach(sb.jitter)
    dse.update_state_from_concrete()
    dse.add_handler(0x7A4A, hook_alloc_string_dse)
    
    sb.run(0x7A20) # run from start of function

    But when I ran, it threw an exception:

    Traceback (most recent call last):
      File "h.py", line 103, in <module>
        sb.run(0x7A20)
      File "/ctf/ctf/miasm/build/lib.linux-x86_64-3.8/miasm/analysis/sandbox.py", line 624, in run
        super(Sandbox_Linux_x86_32, self).run(addr)
      File "/ctf/ctf/miasm/build/lib.linux-x86_64-3.8/miasm/analysis/sandbox.py", line 136, in run
        self.jitter.continue_run()
      File "/ctf/ctf/miasm/build/lib.linux-x86_64-3.8/miasm/jitter/jitload.py", line 436, in continue_run
        return next(self.run_iterator)
      File "/ctf/ctf/miasm/build/lib.linux-x86_64-3.8/miasm/jitter/jitload.py", line 369, in runiter_once
        res = self.exec_cb(self)
      File "/ctf/ctf/miasm/build/lib.linux-x86_64-3.8/miasm/analysis/dse.py", line 320, in callback
        self._check_state()
      File "/ctf/ctf/miasm/build/lib.linux-x86_64-3.8/miasm/analysis/dse.py", line 315, in _check_state
        raise DriftException(errors)
    miasm.analysis.dse.DriftException: Drift of:
            @32[0x13FFB2]: 0x32e50 instead of 0x7a4f
            ESP: 0x13ffb2 instead of 0x13ffae

    How should I fix this? Thanks in advance

    I think at this situation, the jitter had already jumped into the call,it pushed the return address onto the stack, so the jitter and the DSE were not synchronized anymore, but I don't know how to fix it
    -mrh-
    @-mrh-:matrix.org
    [m]
    you have to fix the stack manually since on 32bits the args are pushed into it . so skipping the call in that way won't work .
    serpilliere
    @serpilliere
    Sorry for the non answer, I was in hollydays :)
    @khang06 It's not an easy problem. Maybe during your analyse, you can 'concretize' values which are from readonly memory . For example for jump tables, addresses may be in the text region, so when you have an ExprMem, you could read the pointer and see if it's this region to read it from the binary
    @Andrix44 first, you have to use the lifter that does not do function function call modeling. If your call are modeled using a real call instruction, the symb exec will go into the sub function
    serpilliere
    @serpilliere
    @acquykhud : @-mrh-:matrix.org gave you the correct solution!
    SioYooo
    @SioYooo
    Hi there, I am a newbie to this tool, When I am using IDA pro to launch the tool, it says "TypeError: disasmEngine.init() missing 1 required positional argument: 'loc_db'"
    IridiumXOR
    @IridiumXOR
    @serpilliere FYI I have published a research paper on ACM Transaction on Privacy and Security (https://dl.acm.org/doi/abs/10.1145/3528102) which uses MIASM to perform value recovery for MMU registers (here the paper https://www.s3.eurecom.fr/docs/tops22_oliveri.pdf ). Thanks for the support provides me during the extension on MIASM to support MMU features
    SioYooo
    @SioYooo
    Can anyone tell how to fix this problem?
    it seems the error happend at here:
    File "C:\Python310\lib\site-packages\miasm\arch\x86\disasm.py", line 17, in init
    super(dis_x86, self).init(mn_x86, self.attrib, bs, **kwargs)
    mrh
    @-mrh-:matrix.org
    [m]
    @SioYooo: loc_db.get_location_offset(...) hence you need an entry in a LocationDB wish is identified by a LocKey
    SioYooo
    @SioYooo

    @SioYooo: loc_db.get_location_offset(...) hence you need an entry in a LocationDB wish is identified by a LocKey

    Since I am really new to this area, could you more specific where I should add these into? thanks a lot

    mrh
    @-mrh-:matrix.org
    [m]
    1 reply
    serpilliere
    @serpilliere
    @SioYooo : You have use cases of the API in miasm sources.
    They are in the "example" directory.
    They are sorted by category.
    For example, it seems that here you have a disasm api problem, so let's look at the example in : miasm/example/disasm/dis_binary.py
    Everything is commented to explain the API:
    from __future__ import print_function
    import sys
    from miasm.analysis.binary import Container
    from miasm.analysis.machine import Machine
    from miasm.core.locationdb import LocationDB
    
    fdesc = open(sys.argv[1], 'rb')
    loc_db = LocationDB()
    
    # The Container will provide a *bin_stream*, bytes source for the disasm engine
    # It will prodive a view from a PE or an ELF.
    cont = Container.from_stream(fdesc, loc_db)
    
    # The Machine, instantiated with the detected architecture, will provide tools
    # (disassembler, etc.) to work with this architecture
    machine = Machine(cont.arch)
    
    # Instantiate a disassembler engine, using the previous bin_stream and its
    # associated location DB. The assembly listing will use the binary symbols
    mdis = machine.dis_engine(cont.bin_stream, loc_db=cont.loc_db)
    
    # Run a recursive traversal disassembling from the entry point
    # (do not follow sub functions by default)
    addr = cont.entry_point
    asmcfg = mdis.dis_multiblock(addr)
    
    # Display each basic blocks
    for block in asmcfg.blocks:
        print(block)
    
    # Output control flow graph in a dot file
    open('bin_cfg.dot', 'w').write(asmcfg.dot())
    @IridiumXOR hey! nice to hear that!
    I am adding the paper to my todo list :)
    SioYooo
    @SioYooo
    @serpilliere Thanks a lot, I will try this later today.
    serpilliere
    @serpilliere
    noproblemo
    Adrien Guinet
    @aguinet
    is there an example of doing DSE with a symbolic memory? Basically I have a function taking a pointer to a fixed-size buffer as argument, compute stuff with that data and sotres it back to that buffer
    I would like to get the equations of what's written :)
    (I can already execute it with a miasm sandbox)
    dse.symbolize_memory seems the way to go :)
    coffeebag
    @coffeebag
    Hi, do you think it's theorically possible to do an SSA simplification then create a cleaned version of the function (without recompilation, and just by cleaning original code based on the final SSA form) ?
    I think it will require to manually whitelist out_regs like ESP
    BTW i can't XDOT anymore the .dot generated by MIASM (i'm upstream)
    Syntax error : non-based string used after </TABLE> in line 1
    serpilliere
    @serpilliere
    Hi @coffeebag !
    You mean regenerating asm output?
    @coffeebag : have you got a minimal dot that you can share which generates the error?
    coffeebag
    @coffeebag
    @serpilliere yep, i was thinking about comibining SSA form + def-use in order to known which instuctions keep on the original function
    serpilliere
    @serpilliere
    @coffeebag : IR can have complex expressions, and the code must bind variables to register. The task of regenerating asm is complicated: it's the work of a compilator.
    I will have a look for the graph
    Khangaroo
    @khang06
    wouldn't it be possible to do miasm ir -> llvm ir -> machine code?
    serpilliere
    @serpilliere
    yes, but the IR represents the side effects on registers, which , in IR will be variables.
    So the generated code in llvm is more or less like the code of an emulator of x86.
    It may be optimised, but you also need ABI to recover a decent result.