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)
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
def findBestMatch(s): toks = tokenizeInst(s) try: return findBestMatchTokens(toks) except x86asmError: raise x86asmError("Unable to find match for '%s'" % s)
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