python-3.xx86-64reverse-engineeringelfangr

How to run program using angr after loading with the elfcore backend?


I am attempting to write a python script using the angr binary analysis library (http://angr.io/). I have written code that successfully loads a core dump of the process I want to play with by using the ElfCore back end (http://angr.io/api-doc/cle.html#cle.backends.elf.elfcore.ELFCore) passed to the project constructor, doing something like the following:

ap = angr.Project("corefile", main_opts={'backend': 'elfcore'})

What I am wondering is, how do I now "run" the program forward from the state (registers and memory) which was defined by the core dump? For example, when I attempted to create a SimState using the above project:

ss = angr.sim_state.SimState(project=ap)
ss.regs.rip

I got back that rip was uninitialized (which it was certainly initialized in the core dump/at the point when the core dump was generated).

Thanks in advance for any help!


Solution

  • Alright! I figured this out. Being a total angr n00b® this may not be the best way of doing this, but since nobody offered a better way this is what I came up with.

    First...

    ap = angr.Project("corefile", main_opts={'backend': 'elfcore'}, rebase_granularity=0x1000)
    ss = angr.factory.AngrObjectFactory(ap).blank_state()
    

    the rebase_granularity was needed because my core file had the stack mapped high in the address range and angr refuses to map things above your main binary (my core file in this case).

    From inspecting the angr source (and playing at a Python terminal) I found out that at this point, the above state will have memory all mapped out the way the core file defined it to be, but the registers are not defined appropriately yet. Therefore I needed to proceed to:

    # Get the elfcore_object
    elfcore_object = None
    for o in ap.loader.all_objects:
        if type(o) == cle.backends.elf.elfcore.ELFCore:
            elfcore_object = o
            break
    if elfcore_object is None:
        error
    
    # Set the reg values from the elfcore_object to the sim state, realizing that not all
    # of the registers will be supported (particularly some segment registers)
    for regval in elfcore_object.initial_register_values():
        try:
            setattr(ss.regs, regval[0], regval[1])
        except Exception:
            warn
    
    # get a simgr
    simgr = ap.factory.simgr(ss)
    

    Now, I was able to run forward from here using the state defined by the core dump as my starting point...

    for ins in ap.factory.block(simgr.active[0].addr).capstone.insns:
        print(ins)
    
    simgr.step()
    
    ...repeat