angr / pyvex

Python bindings for Valgrind's VEX IR.
BSD 2-Clause "Simplified" License
339 stars 115 forks source link

problem with block.extend since last commit #142

Closed canpadawan closed 6 years ago

canpadawan commented 6 years ago

since commit 30009df4dcdd46331ceb891be5619679a8f0a919

I get issues with block extensions.

    150             to_replace = { }
    151             for expr in stmt.expressions:
--> 152                 replacement = convert_expr(expr)
    153                 if replacement is not expr:
    154                     to_replace[expr] = replacement

angr/pyvex/pyvex/block.pyc in convert_expr(expr)
    128             """
    129             if type(expr) is RdTmp:
--> 130                 return RdTmp.get_instance(convert_tmp(expr.tmp))
    131             return expr
    132 

angr/pyvex/pyvex/block.pyc in convert_tmp(tmp)
    116             """
    117             if tmp not in conversion_dict:
--> 118                 tmp_type = extendwith.tyenv.lookup(tmp)
    119                 conversion_dict[tmp] = self.tyenv.add(tmp_type)
    120             return conversion_dict[tmp]

angr/pyvex/pyvex/block.pyc in lookup(self, tmp)
    479             l.debug("Invalid temporary number %d", tmp)
    480             raise IndexError(tmp)
--> 481         return self.types[tmp]
    482 
    483     def sizeof(self, tmp):

IndexError: list index out of range

I can't reproduce the problem using shellcode... I can send file and extra_lifter to investigate further.

ltfish commented 6 years ago

It'll be great if you can send us the binary that triggers this issue. I'm confident that this is a bug, but I cannot debug or fix it without being able to reproduce it :(

canpadawan commented 6 years ago
from archinfo import Endness
from pyvex.lifting.util import *
from pyvex.lifting import register
import angr

class Instruction_MSR_W(Instruction):
    bin_format = '11110011100rnnnn'
    name = 'msr.w'

    def parse(self, bitstrm):
        super(Instruction_MSR_W, self).parse(bitstrm)
        endness = 'uintle:16' if Endness.LE==self.arch.instruction_endness else 'uintbe:16'
        bitstrm.read(endness)
        self.bitwidth += 16

    def compute_result(self):
        pass

class LifterThumb(GymratLifter):
    instrs = [Instruction_MSR_W]

register(LifterThumb, 'ARMEL')

angr.Project('./testfile.zip').factory.block(0xc0125479, num_inst=4).pp()

also the guard condition on IRTypeEnv.lookup() should be

if not 0 <= tmp < self.types_used:                                     
    l.debug("Invalid temporary number %d", tmp)                          
    raise IndexError(tmp)   

instead of if tmp < 0 or tmp > self.types_used

the file is an elf but renamed for github testfile.zip

The issue looks really similar to #143 viel spaß :-)

ltfish commented 6 years ago

I reproduced it! Now I can debug and see what's going on. Thanks!

canpadawan commented 6 years ago

thanks!