Beispiel #1
0
    def AddInstruction(self,inst):
        self.freezeProc()
        instToks = tokenizeInst(inst)
        instToksMinusLocals = ()

        for tok in instToks:
            if tok[0] == STRING:
                # Create an inlined string
                inlineName = "inline_pyasm_string%i" % self.inlineStringNo
                escapedString = tok[1].decode("string_escape")
                self.ADStr(inlineName,escapedString)
                instToksMinusLocals += ((SYMBOL,inlineName),)
                self.inlineStringNo += 1                
            elif tok[0] != SYMBOL: # do nothing
                instToksMinusLocals += ( tok,)
            elif self.Constants.has_key(tok[1]): #replace constant
                instToksMinusLocals += (self.Constants[tok[1]],)
            elif self.CurrentProcedure:
                #look for local match
                local = self.CurrentProcedure.LookupVar(tok[1])
                if local: #found match
                    instToksMinusLocals += local
                else: # defer resolution to second pass
                    instToksMinusLocals += (tok,)
            else: # stick with local
                instToksMinusLocals = instToks
            
        self.Instructions.append(instToksMinusLocals)
Beispiel #2
0
    def LoadConcreteValues(self, toks):
        if type(toks) == type(""):
            toks = tokenizeInst(toks)
        logging.info("%s => %s" % (self.Instruction.InstructionString, toks))
        tmpModRM = ModRM()
        firstDef, restDef = (self.Instruction.InstructionDef[0],
                             self.Instruction.InstructionDef[1:])
        firstTok, restTok = toks[0], toks[1:]
        while 1:
            logging.info("TOK COMPARES: %s => %s" % (firstDef, firstTok))
            if firstDef[0] in (OPCODE, COMMA, REGISTER):
                #TODO: Can we handle this special case better?
                #      The special case is a m8/16/32 value that is constant
                #      and doesn't have an RM.
                if firstDef[0] == REGISTER and firstDef[1][0] == '[' and \
                   firstTok[0] == LBRACKET:
                    firstTok, restTok = restTok[0], restTok[1:]
                    if firstTok[1] == firstDef[1][1:-1]:
                        firstTok, restTok = restTok[0], restTok[1:]
                    else:
                        raise x86instError("TOKEN MISMATCH '%s' '%s'" % \
                                           (firstDef,firstTok))
                elif firstDef[0] != firstTok[0]:
                    raise x86instError("These should be equal '%s' '%s'" % \
                                       (firstDef, firstTok))
            elif firstDef[0] == NUMBER:
                if firstTok[0] != NUMBER or firstTok[1] != firstDef[1]:
                    raise x86instError("INVALID NUMBER '%s'" % repr(firstTok))
            elif firstDef[0] == OPERAND:
                if firstDef[1] in ('r/m32', 'r/m16', 'r/m8'):
                    #figure out r/m val
                    if firstTok[0] == REGISTER:
                        #figure out r val
                        registerName = firstTok[1]
                        registerType = firstDef[1][0] + firstDef[1][3:]
                        registerVal = regOpcode[registerType].index(
                            registerName)
                        if registerVal < 0:
                            raise x86instError(
                                "Couldn't resolve register '%s'" %
                                registerName)
                        else:
                            tmpModRM.Mode = 3
                            tmpModRM.RM = registerVal
                    elif firstTok[0] == LBRACKET:
                        firstTok, restTok = restTok[0], restTok[1:]
                        if firstTok[0] in (NUMBER, SYMBOL):
                            tmpModRM.Mode = 0
                            tmpModRM.RM = 6
                            if firstTok[0] == NUMBER:
                                self.Displacement = eval(firstTok[1])
                            else:
                                self.Displacement = 0x0
                                self.DisplacementSymbol = firstTok[1]
                            firstTok, restTok = restTok[0], restTok[1:]
                        elif firstTok[0] == REGISTER:
                            regTok = firstTok
                            firstTok, restTok = restTok[0], restTok[1:]
                            if firstTok[0] in (NUMBER, SYMBOL):  #displacement
                                if firstTok[0] == NUMBER:
                                    num = eval(firstTok[1])
                                    if num >= -127 and num <= 128:
                                        tmpModRM.Mode = 1
                                    else:
                                        tmpModRM.Mode = 2
                                else:
                                    tmpModRM.Mode = 2
                                tmpModRM.RM = [
                                    'EAX', 'ECX', 'EDX', 'EBX', '[--][--]',
                                    'EBP', 'ESI', 'EDI'
                                ].index(regTok[1])
                                if firstTok[0] == NUMBER:
                                    self.Displacement = eval(firstTok[1])
                                else:
                                    self.Displacement = 0x0
                                    self.DisplacementSymbol = firstTok[1]
                                firstTok, restTok = restTok[0], restTok[1:]
                            else:  # no displacement
                                tmpModRM.Mode = 0
                                tmpModRM.RM = [
                                    'EAX', 'ECX', 'EDX', 'EBX', '[--][--]',
                                    'disp32', 'ESI', 'EDI'
                                ].index(regTok[1])

                    else:
                        raise x86instError("Invalid r/m token '%s'" %
                                           firstTok[0])

                elif firstDef[1] in ('r32', 'r16', 'r8'):
                    #figure out r val
                    registerName = firstTok[1]
                    registerVal = regOpcode[firstDef[1]].index(registerName)
                    if registerVal < 0:
                        raise x86instError("Couldn't resolve register '%s'" %
                                           registerName)
                    else:
                        tmpModRM.RegOp = registerVal
                elif firstDef[1] in ('imm32', 'imm16', 'imm8'):
                    if firstTok[0] == NUMBER:
                        self.Immediate = eval(firstTok[1])
                    else:
                        self.Immediate = 0x0
                        self.ImmediateSymbol = firstTok[1]
                elif firstDef[1] in ('rel32', 'rel16', 'rel8'):
                    # Do we need to do the math here (convert absolute val to relative?)
                    if firstTok[0] == NUMBER:
                        self.Displacement = eval(firstTok[1])
                    else:
                        self.Displacement = 0x0
                        self.DisplacementSymbol = firstTok[1]
                else:
                    #there will really be more cases here.
                    raise x86instError("Invalid Operand type '%s'" %
                                       firstDef[1])
            else:
                raise x86instError("Invalid token", firstDef)

            if not restDef:
                break
            firstDef, restDef = restDef[0], restDef[1:]
            firstTok, restTok = restTok[0], restTok[1:]

        for flag in self.Instruction.OpcodeFlags:
            if flag in ['/0', '/1', '/2', '/3', '/4', '/5', '/6', '/7']:
                tmpModRM.RegOp = eval(flag[1])
        self.ModRM = tmpModRM
Beispiel #3
0
def findBestMatch(s):
    toks = tokenizeInst(s)
    try:
        return findBestMatchTokens(toks)
    except x86asmError:
        raise x86asmError("Unable to find match for '%s'" % s)
Beispiel #4
0
    def LoadConcreteValues(self, toks):
        if type(toks) == type(""):
            toks = tokenizeInst(toks)
        logging.info("%s => %s" % (self.Instruction.InstructionString, toks))
        tmpModRM = ModRM()
        firstDef, restDef = (self.Instruction.InstructionDef[0],self.Instruction.InstructionDef[1:])
        firstTok, restTok = toks[0],toks[1:]
        while 1:
            logging.info("TOK COMPARES: %s => %s" % (firstDef, firstTok))
            if firstDef[0] in (OPCODE, COMMA, REGISTER):
                #TODO: Can we handle this special case better?
                #      The special case is a m8/16/32 value that is constant
                #      and doesn't have an RM.
                if firstDef[0] == REGISTER and firstDef[1][0] == '[' and \
                   firstTok[0] == LBRACKET:
                    firstTok, restTok = restTok[0],restTok[1:]
                    if firstTok[1] == firstDef[1][1:-1]:
                        firstTok, restTok = restTok[0],restTok[1:]
                    else:
                        raise x86instError("TOKEN MISMATCH '%s' '%s'" % \
                                           (firstDef,firstTok))
                elif firstDef[0] != firstTok[0]:
                    raise x86instError("These should be equal '%s' '%s'" % \
                                       (firstDef, firstTok))
            elif firstDef[0] == NUMBER:
                if firstTok[0] != NUMBER or firstTok[1] != firstDef[1]:
                    raise x86instError("INVALID NUMBER '%s'" % repr(firstTok))
            elif firstDef[0] == OPERAND:
                if firstDef[1] in ('r/m32','r/m16','r/m8'):
                    #figure out r/m val
                    if firstTok[0] == REGISTER:
                        #figure out r val
                        registerName = firstTok[1]
                        registerType = firstDef[1][0] + firstDef[1][3:]
                        registerVal = regOpcode[registerType].index(registerName)
                        if registerVal < 0:
                            raise x86instError("Couldn't resolve register '%s'" % registerName)
                        else:
                            tmpModRM.Mode = 3
                            tmpModRM.RM = registerVal
                    elif firstTok[0] == LBRACKET:
                        firstTok, restTok = restTok[0],restTok[1:]
                        if firstTok[0] in (NUMBER,SYMBOL):
                            tmpModRM.Mode = 0
                            tmpModRM.RM = 6
                            if firstTok[0] == NUMBER:
                                self.Displacement = eval(firstTok[1])
                            else:
                                self.Displacement = 0x0
                                self.DisplacementSymbol = firstTok[1]
                            firstTok, restTok = restTok[0],restTok[1:]
                        elif firstTok[0] == REGISTER:
                            regTok = firstTok
                            firstTok, restTok = restTok[0],restTok[1:]
                            if firstTok[0] in (NUMBER,SYMBOL): #displacement
                                if firstTok[0] == NUMBER:
                                    num = eval(firstTok[1])
                                    if num >= -127 and num <= 128:
                                        tmpModRM.Mode = 1
                                    else:
                                        tmpModRM.Mode = 2
                                else:
                                    tmpModRM.Mode = 2
                                tmpModRM.RM = ['EAX','ECX','EDX','EBX',
                                               '[--][--]','EBP','ESI',
                                               'EDI'].index(regTok[1])
                                if firstTok[0] == NUMBER:
                                    self.Displacement = eval(firstTok[1])
                                else:
                                    self.Displacement = 0x0
                                    self.DisplacementSymbol = firstTok[1]
                                firstTok, restTok = restTok[0],restTok[1:]
                            else: # no displacement
                                tmpModRM.Mode = 0
                                tmpModRM.RM = ['EAX','ECX','EDX','EBX',
                                                '[--][--]','disp32','ESI',
                                               'EDI'].index(regTok[1])
                            
                    else:
                        raise x86instError("Invalid r/m token '%s'" % firstTok[0])
                            
                elif firstDef[1] in ('r32','r16','r8'):
                    #figure out r val
                    registerName = firstTok[1]
                    registerVal = regOpcode[firstDef[1]].index(registerName)
                    if registerVal < 0:
                        raise x86instError("Couldn't resolve register '%s'" % registerName)
                    else:
                        tmpModRM.RegOp = registerVal
                elif firstDef[1] in ('imm32','imm16','imm8'):
                    if firstTok[0] == NUMBER:
                        self.Immediate = eval(firstTok[1])
                    else:
                        self.Immediate = 0x0
                        self.ImmediateSymbol = firstTok[1]
                elif firstDef[1] in ('rel32','rel16','rel8'):
                    # Do we need to do the math here (convert absolute val to relative?)
                    if firstTok[0] == NUMBER:
                        self.Displacement = eval(firstTok[1])
                    else:
                        self.Displacement = 0x0
                        self.DisplacementSymbol = firstTok[1]
                else:
                    #there will really be more cases here.
                    raise x86instError("Invalid Operand type '%s'" % firstDef[1])
            else:
                raise x86instError("Invalid token" , firstDef)
                                       
            if not restDef:
                break
            firstDef, restDef = restDef[0],restDef[1:]
            firstTok, restTok = restTok[0],restTok[1:]

        for flag in self.Instruction.OpcodeFlags:
            if flag in ['/0','/1','/2','/3','/4','/5','/6','/7']:
                tmpModRM.RegOp = eval(flag[1])
        self.ModRM = tmpModRM