void normalizeInstructionInSubTree(SgNode* topNode ){ vector<SgAsmx86Instruction*> insns; FindInstructionsVisitor vis; AstQueryNamespace::querySubTree(topNode, std::bind2nd( vis, &insns )); for(std::vector<SgAsmx86Instruction*>::iterator iItr = insns.begin(); iItr != insns.end(); ++iItr) { SgAsmx86Instruction* insn = *iItr; SgAsmExpressionPtrList& operands = getOperands(insn); // Add to total for this variant // Add to total for each kind of operand size_t operandCount = operands.size(); for (size_t i = 0; i < operandCount; ++i) { SgAsmExpression* operand = operands[i]; SgAsmExpression* newOperand; if( isSgAsmMemoryReferenceExpression(operand) ) { SgAsmMemoryReferenceExpression* memRefExp = new SgAsmMemoryReferenceExpression; SgAsmWordValueExpression* wordVal = new SgAsmWordValueExpression; wordVal->set_value(0); memRefExp->set_segment(wordVal); memRefExp->set_address(wordVal); memRefExp->set_type(new SgAsmTypeWord); newOperand = memRefExp; }else if(isSgAsmRegisterReferenceExpression(operand) ){ SgAsmx86RegisterReferenceExpression* regRef = new SgAsmx86RegisterReferenceExpression; regRef->get_descriptor().set_major(x86_regclass_mm); regRef->get_descriptor().set_minor(0); newOperand = regRef; }else{ SgAsmWordValueExpression* wordVal = new SgAsmWordValueExpression; wordVal->set_value(0); newOperand = wordVal; } newOperand->set_parent(operand->get_parent()); DeleteSgTree(operands[i]); operands[i]=newOperand; } //std::cout << "Unparsed: " <<unparseX86Instruction(insn)<< std::endl; } };
/**************************************************** * traverse the binary AST to test if all nodes are there ****************************************************/ void RoseFile::visit(SgNode* node) { SgAsmFunction* funcDecl= isSgAsmFunction(node); SgAsmInstruction* instr= isSgAsmInstruction(node); //SgAsmBlock* block= isSgAsmBlock(node); nodes++; //cerr << " traversing node " << binNode << endl; if (funcDecl) { trav_funcs++; // should have a parent SgAsmBlock* glob = isSgAsmBlock(funcDecl->get_parent()); if (glob==NULL) { int address = funcDecl->get_address(); ostringstream addrhex; addrhex << hex << setw(8) << address ; //cerr << " func with no global :: " << addrhex.str() << " " << address << endl; } // ROSE_ASSERT(glob); } /* if (block) { trav_blocks++; SgAsmFunction* func = isSgAsmFunction(block->get_parent()); int address = block->get_address(); ostringstream addrhex; addrhex << hex << setw(8) << address ; //if (func==NULL) { //cerr << trav_blocks << " block with no function :: " << addrhex.str() << " " << address << endl; //} else //cerr << trav_blocks << " block with no function :: " << addrhex.str() << " " << address << endl; //ROSE_ASSERT(func); } */ if (isSgAsmMemoryReferenceExpression(node)) { SgAsmMemoryReferenceExpression* n = isSgAsmMemoryReferenceExpression(node); // cerr << "Found a SgAsmMemoryReferenceExpression" << endl; ROSE_ASSERT(n->get_type()); } if (instr) { trav_inst++; SgAsmFunction* ins = isSgAsmFunction(instr->get_parent()); if (ins==NULL) { int address = ins->get_address(); ostringstream addrhex; addrhex << hex << setw(8) << address ; cerr << " ERROR :: instr with no parent function :: " << addrhex.str() << " " << address << endl; } //ROSE_ASSERT(ins); } SgAsmNode* asmNode = isSgAsmNode(node); if (asmNode) if (asmNode->get_parent()==NULL) { if (!isSgAsmBlock(asmNode)) { cerr << " PARENT == NULL :: " << asmNode->class_name() << endl; ROSE_ASSERT(asmNode->get_parent()); } } }
SgAsmMemoryReferenceExpression* makeMemoryReference(SgAsmExpression* addr, SgAsmExpression* segment, SgAsmType* t) { SgAsmMemoryReferenceExpression* r = new SgAsmMemoryReferenceExpression(addr); addr->set_parent(r); if (segment) { r->set_segment(segment); segment->set_parent(r); } if (t) r->set_type(t); return r; }
/* Helper function for unparseArmExpression(SgAsmExpression*) * * If this function is called for an EXPR node that cannot appear at the top of an ARM instruction operand tree then the node * might create two strings: the primary expression return value and an additional string returned through the SUFFIX * argument. What to do with the additional string depends on layers higher up in the call stack. * * The sign will be prepended to the result if EXPR is a value expression of some sort. */ static std::string unparseArmExpression(SgAsmExpression* expr, const AsmUnparser::LabelMap *labels, ArmSignForExpressionUnparsing sign, std::string *suffix=NULL) { std::string result, extra; if (!isSgAsmValueExpression(expr)) { result += unparseArmSign(sign); } switch (expr->variantT()) { case V_SgAsmBinaryMultiply: ROSE_ASSERT (isSgAsmByteValueExpression(isSgAsmBinaryExpression(expr)->get_rhs())); result = unparseArmExpression(isSgAsmBinaryExpression(expr)->get_lhs(), labels, arm_sign_none) + "*" + StringUtility::numberToString(isSgAsmByteValueExpression(isSgAsmBinaryExpression(expr)->get_rhs())); break; case V_SgAsmBinaryLsl: result = unparseArmExpression(isSgAsmBinaryExpression(expr)->get_lhs(), labels, arm_sign_none) + ", lsl " + unparseArmExpression(isSgAsmBinaryExpression(expr)->get_rhs(), labels, arm_sign_none); break; case V_SgAsmBinaryLsr: result = unparseArmExpression(isSgAsmBinaryExpression(expr)->get_lhs(), labels, arm_sign_none) + ", lsr " + unparseArmExpression(isSgAsmBinaryExpression(expr)->get_rhs(), labels, arm_sign_none); break; case V_SgAsmBinaryAsr: result = unparseArmExpression(isSgAsmBinaryExpression(expr)->get_lhs(), labels, arm_sign_none) + ", asr " + unparseArmExpression(isSgAsmBinaryExpression(expr)->get_rhs(), labels, arm_sign_none); break; case V_SgAsmBinaryRor: result = unparseArmExpression(isSgAsmBinaryExpression(expr)->get_lhs(), labels, arm_sign_none) + ", ror " + unparseArmExpression(isSgAsmBinaryExpression(expr)->get_rhs(), labels, arm_sign_none); break; case V_SgAsmUnaryRrx: result = unparseArmExpression(isSgAsmUnaryExpression(expr)->get_operand(), labels, arm_sign_none) + ", rrx"; break; case V_SgAsmUnaryArmSpecialRegisterList: result += unparseArmExpression(isSgAsmUnaryExpression(expr)->get_operand(), labels, arm_sign_none) + "^"; break; case V_SgAsmExprListExp: { SgAsmExprListExp* el = isSgAsmExprListExp(expr); const std::vector<SgAsmExpression*>& exprs = el->get_expressions(); result += "{"; for (size_t i = 0; i < exprs.size(); ++i) { if (i != 0) result += ", "; result += unparseArmExpression(exprs[i], labels, arm_sign_none); } result += "}"; break; } case V_SgAsmBinaryAdd: { /* This node cannot appear at the top of an ARM instruction operand tree */ SgAsmBinaryExpression *e = isSgAsmBinaryExpression(expr); result += unparseArmExpression(e->get_lhs(), labels, arm_sign_none) + ", " + unparseArmExpression(e->get_rhs(), labels, arm_sign_plus); break; } case V_SgAsmBinarySubtract: { /* This node cannot appear at the top of an ARM instruction operand tree */ SgAsmBinaryExpression *e = isSgAsmBinaryExpression(expr); result += unparseArmExpression(e->get_lhs(), labels, arm_sign_none) + ", " + unparseArmExpression(e->get_rhs(), labels, arm_sign_minus); break; } case V_SgAsmBinaryAddPreupdate: { /* This node cannot appear at the top of an ARM instruction operand tree */ SgAsmBinaryExpression *e = isSgAsmBinaryExpression(expr); result += unparseArmExpression(e->get_lhs(), labels, arm_sign_none) + ", " + unparseArmExpression(e->get_rhs(), labels, arm_sign_plus); extra = "!"; break; } case V_SgAsmBinarySubtractPreupdate: { /* This node cannot appear at the top of an ARM instruction operand tree */ SgAsmBinaryExpression *e = isSgAsmBinaryExpression(expr); result += unparseArmExpression(e->get_lhs(), labels, arm_sign_none) + ", " + unparseArmExpression(e->get_rhs(), labels, arm_sign_minus); extra = "!"; break; } case V_SgAsmBinaryAddPostupdate: { /* Two styles of syntax depending on whether this is at top-level or inside a memory reference expression. */ SgAsmBinaryExpression *e = isSgAsmBinaryExpression(expr); if (suffix) { result += unparseArmExpression(e->get_lhs(), labels, arm_sign_none); extra = ", " + unparseArmExpression(e->get_rhs(), labels, arm_sign_plus); } else { /* Used by LDM* and STM* instructions outside memory reference expressions. RHS is unused. */ result = unparseArmExpression(e->get_lhs(), labels, arm_sign_none) + "!"; } break; } case V_SgAsmBinarySubtractPostupdate: { /* Two styles of syntax depending on whether this is at top-level or inside a memory reference expression. */ SgAsmBinaryExpression *e = isSgAsmBinaryExpression(expr); if (suffix) { result += unparseArmExpression(e->get_lhs(), labels, arm_sign_none); extra = ", " + unparseArmExpression(e->get_rhs(), labels, arm_sign_minus); } else { /* Used by LDM* and STM* instructions outside memory reference expressions. RHS is unused. */ result += unparseArmExpression(e->get_lhs(), labels, arm_sign_none) + "!"; } break; } case V_SgAsmMemoryReferenceExpression: { SgAsmMemoryReferenceExpression* mr = isSgAsmMemoryReferenceExpression(expr); SgAsmExpression* addr = mr->get_address(); switch (addr->variantT()) { case V_SgAsmRegisterReferenceExpression: case V_SgAsmBinaryAdd: case V_SgAsmBinarySubtract: case V_SgAsmBinaryAddPreupdate: case V_SgAsmBinarySubtractPreupdate: case V_SgAsmBinaryAddPostupdate: case V_SgAsmBinarySubtractPostupdate: break; default: ROSE_ASSERT (!"Bad addressing mode"); } std::string suffix; result += "[" + unparseArmExpression(addr, labels, arm_sign_none, &suffix) + "]"; result += suffix; break; } case V_SgAsmArmRegisterReferenceExpression: result += unparseArmRegister(isSgAsmArmRegisterReferenceExpression(expr)); break; case V_SgAsmByteValueExpression: case V_SgAsmWordValueExpression: case V_SgAsmDoubleWordValueExpression: { SgAsmValueExpression *ve = isSgAsmValueExpression(expr); assert(ve!=NULL); uint64_t v = SageInterface::getAsmConstant(ve); result += "#" + unparseArmSign(sign) + StringUtility::numberToString(v); if (labels && v!=0) { AsmUnparser::LabelMap::const_iterator li=labels->find(v); if (li!=labels->end()) result += "<" + li->second + ">"; } break; } default: { std::cerr << "Unhandled expression kind " << expr->class_name() << std::endl; ROSE_ASSERT (false); } } /* The extra data should be passed back up the call stack so it can be inserted into the ultimate return string. We can't * insert it here because the string can't be generated strictly left-to-right. If "suffix" is the null pointer then the * caller isn't expecting a suffix and we'll have to just do our best -- the result will not be valid ARM assembly. */ if (extra.size()>0 && !suffix) result = "\"" + result + "\" and \"" + extra + "\""; if (suffix) *suffix = extra; if (expr->get_replacement() != "") { result += " <" + expr->get_replacement() + ">"; } return result; }
std::string unparseX86Expression(SgAsmExpression *expr, const AsmUnparser::LabelMap *labels, bool leaMode) { std::string result = ""; if (expr == NULL) return "BOGUS:NULL"; switch (expr->variantT()) { case V_SgAsmBinaryAdd: result = unparseX86Expression(isSgAsmBinaryExpression(expr)->get_lhs(), labels, false) + " + " + unparseX86Expression(isSgAsmBinaryExpression(expr)->get_rhs(), labels, false); break; case V_SgAsmBinarySubtract: result = unparseX86Expression(isSgAsmBinaryExpression(expr)->get_lhs(), labels, false) + " - " + unparseX86Expression(isSgAsmBinaryExpression(expr)->get_rhs(), labels, false); break; case V_SgAsmBinaryMultiply: result = unparseX86Expression(isSgAsmBinaryExpression(expr)->get_lhs(), labels, false) + "*" + unparseX86Expression(isSgAsmBinaryExpression(expr)->get_rhs(), labels, false); break; case V_SgAsmMemoryReferenceExpression: { SgAsmMemoryReferenceExpression* mr = isSgAsmMemoryReferenceExpression(expr); if (!leaMode) { result += x86TypeToPtrName(mr->get_type()) + " PTR " + (mr->get_segment() ? unparseX86Expression(mr->get_segment(), labels, false) + ":" : ""); } result += "[" + unparseX86Expression(mr->get_address(), labels, false) + "]"; break; } case V_SgAsmx86RegisterReferenceExpression: { SgAsmx86RegisterReferenceExpression* rr = isSgAsmx86RegisterReferenceExpression(expr); result = unparseX86Register(rr->get_descriptor()); break; } case V_SgAsmByteValueExpression: case V_SgAsmWordValueExpression: case V_SgAsmDoubleWordValueExpression: case V_SgAsmQuadWordValueExpression: case V_SgAsmIntegerValueExpression: { SgAsmIntegerValueExpression *ival = isSgAsmIntegerValueExpression(expr); assert(ival!=NULL); uint64_t value = ival->get_absolute_value(); // not sign extended result = StringUtility::addrToString(value, ival->get_significant_bits(), true/*signed*/); // Optional label. Prefer a label supplied by the caller's LabelMap, but not for single-byte constants. If // there's no caller-supplied label, then consider whether the value expression is relative to some other IR node. std::string label; if (ival->get_significant_bits()>8) label =x86ValToLabel(value, labels); if (label.empty()) label = ival->get_label(); if (!label.empty()) result += "<" + label + ">"; break; } default: { std::cerr << "Unhandled expression kind " << expr->class_name() << std::endl; ROSE_ASSERT (false); } } if (expr->get_replacement() != "") { result += " <" + expr->get_replacement() + ">"; } #if 0 if (expr->get_bit_size()>0) { result += " <@" + StringUtility::numberToString(expr->get_bit_offset()) + "+" + StringUtility::numberToString(expr->get_bit_size()) + ">"; } #endif return result; }
/* Helper for unparsePowerpcExpression(SgAsmExpression*) */ static std::string unparsePowerpcExpression(SgAsmExpression* expr, const AsmUnparser::LabelMap *labels, const RegisterDictionary *registers, bool useHex) { std::string result = ""; if (expr == NULL) return "BOGUS:NULL"; switch (expr->variantT()) { case V_SgAsmBinaryAdd: result = unparsePowerpcExpression(isSgAsmBinaryExpression(expr)->get_lhs(), labels, registers, false) + " + " + unparsePowerpcExpression(isSgAsmBinaryExpression(expr)->get_rhs(), labels, registers, false); break; case V_SgAsmMemoryReferenceExpression: { SgAsmMemoryReferenceExpression* mr = isSgAsmMemoryReferenceExpression(expr); SgAsmExpression* addr = mr->get_address(); switch (addr->variantT()) { case V_SgAsmBinaryAdd: { SgAsmBinaryAdd* a = isSgAsmBinaryAdd(addr); std::string lhs = unparsePowerpcExpression(a->get_lhs(), labels, registers, false); if (isSgAsmValueExpression(a->get_rhs())) { // Sign-extend from 16 bits SgAsmValueExpression *ve = isSgAsmValueExpression(a->get_rhs()); ASSERT_not_null(ve); result = boost::lexical_cast<std::string>( (int64_t)IntegerOps::signExtend<16, 64>(SageInterface::getAsmConstant(ve))); result += "(" + lhs + ")"; } else { result = lhs + ", " + unparsePowerpcExpression(a->get_rhs(), labels, registers, false); } break; } default: result = "(" + unparsePowerpcExpression(addr, labels, registers, false) + ")"; break; } break; } case V_SgAsmDirectRegisterExpression: { SgAsmInstruction *insn = SageInterface::getEnclosingNode<SgAsmInstruction>(expr); SgAsmDirectRegisterExpression* rr = isSgAsmDirectRegisterExpression(expr); result = unparsePowerpcRegister(insn, rr->get_descriptor(), registers); break; } case V_SgAsmIntegerValueExpression: { uint64_t v = isSgAsmIntegerValueExpression(expr)->get_absoluteValue(); if (useHex) { result = StringUtility::intToHex(v); } else { result = StringUtility::numberToString(v); } if (expr->get_comment().empty() && labels) { AsmUnparser::LabelMap::const_iterator li = labels->find(v); if (li!=labels->end()) result = StringUtility::appendAsmComment(result, li->second); } break; } default: { ASSERT_not_reachable("invalid PowerPC expression: " + expr->class_name()); } } result = StringUtility::appendAsmComment(result, expr->get_replacement()); result = StringUtility::appendAsmComment(result, expr->get_comment()); return result; }
std::string unparseX86Expression(SgAsmExpression *expr, const AsmUnparser::LabelMap *labels, const RegisterDictionary *registers, bool leaMode) { std::string result = ""; if (expr == NULL) return "BOGUS:NULL"; switch (expr->variantT()) { case V_SgAsmBinaryAdd: result = unparseX86Expression(isSgAsmBinaryExpression(expr)->get_lhs(), labels, registers, false) + " + " + unparseX86Expression(isSgAsmBinaryExpression(expr)->get_rhs(), labels, registers, false); break; case V_SgAsmBinarySubtract: result = unparseX86Expression(isSgAsmBinaryExpression(expr)->get_lhs(), labels, registers, false) + " - " + unparseX86Expression(isSgAsmBinaryExpression(expr)->get_rhs(), labels, registers, false); break; case V_SgAsmBinaryMultiply: result = unparseX86Expression(isSgAsmBinaryExpression(expr)->get_lhs(), labels, registers, false) + "*" + unparseX86Expression(isSgAsmBinaryExpression(expr)->get_rhs(), labels, registers, false); break; case V_SgAsmMemoryReferenceExpression: { SgAsmMemoryReferenceExpression* mr = isSgAsmMemoryReferenceExpression(expr); if (!leaMode) { result += x86TypeToPtrName(mr->get_type()) + " " + (mr->get_segment() ? unparseX86Expression(mr->get_segment(), labels, registers, false) + ":" : ""); } result += "[" + unparseX86Expression(mr->get_address(), labels, registers, false) + "]"; break; } case V_SgAsmDirectRegisterExpression: { SgAsmInstruction *insn = SageInterface::getEnclosingNode<SgAsmInstruction>(expr); SgAsmDirectRegisterExpression* rr = isSgAsmDirectRegisterExpression(expr); result = unparseX86Register(insn, rr->get_descriptor(), registers); break; } case V_SgAsmIndirectRegisterExpression: { SgAsmInstruction *insn = SageInterface::getEnclosingNode<SgAsmInstruction>(expr); SgAsmIndirectRegisterExpression* rr = isSgAsmIndirectRegisterExpression(expr); result = unparseX86Register(insn, rr->get_descriptor(), registers); if (!result.empty() && '0'==result[result.size()-1]) result = result.substr(0, result.size()-1); result += "(" + StringUtility::numberToString(rr->get_index()) + ")"; break; } case V_SgAsmIntegerValueExpression: { SgAsmIntegerValueExpression *ival = isSgAsmIntegerValueExpression(expr); ASSERT_not_null(ival); uint64_t value = ival->get_absoluteValue(); // not sign extended // If the value looks like it might be an address, then don't bother showing the decimal form. if ((32==ival->get_significantBits() || 64==ival->get_significantBits()) && value > 0x0000ffff && value < 0xffff0000) { result = StringUtility::addrToString(value, ival->get_significantBits()); } else { result = StringUtility::signedToHex2(value, ival->get_significantBits()); } // Optional label. Prefer a label supplied by the caller's LabelMap, but not for single-byte constants. If // there's no caller-supplied label, then consider whether the value expression is relative to some other IR node. if (expr->get_comment().empty()) { std::string label; if (label.empty() && ival->get_significantBits()>8) label =x86ValToLabel(value, labels); if (label.empty()) label = ival->get_label(); result = StringUtility::appendAsmComment(result, label); } break; } default: { ASSERT_not_reachable("invalid x86 expression: " + expr->class_name()); } } result = StringUtility::appendAsmComment(result, expr->get_replacement()); result = StringUtility::appendAsmComment(result, expr->get_comment()); return result; }
// Constructor DataMemberInitializationAttribute::DataMemberInitializationAttribute ( SgAsmInstruction* instruction, SgProject* p ) { ROSE_ASSERT(instruction != NULL); printf ("Building a DataMemberInitializationAttribute object for instruction = %s \n",unparseInstructionWithAddress(instruction).c_str()); // Identify the offset and if this is a stack reference or a global reference. SgAsmMemoryReferenceExpression* memoryReferenceExpression = isSgAsmMemoryReferenceExpression(instruction->get_operandList()->get_operands()[0]); ROSE_ASSERT(memoryReferenceExpression != NULL); SgAsmRegisterReferenceExpression* segmentRegister = isSgAsmRegisterReferenceExpression(memoryReferenceExpression->get_segment()); ROSE_ASSERT(segmentRegister != NULL); #ifdef USE_NEW_ISA_INDEPENDENT_REGISTER_HANDLING // This is a data member isStackVariable = (segmentRegister->get_register_number() == SgAsmRegisterReferenceExpression::e_ss); // This is to test if there is another register being referenced. bool isGlobalVariable = (segmentRegister->get_register_number() == SgAsmRegisterReferenceExpression::e_ds); // This should be either a stack or global variable (no other allowed). ROSE_ASSERT(isStackVariable == true || isGlobalVariable == true); ROSE_ASSERT(isStackVariable == false || isGlobalVariable == false); SgAsmBinaryAdd* binaryAdd = isSgAsmBinaryAdd(memoryReferenceExpression->get_address()); if (binaryAdd != NULL) { // Case of a non-zero offset into the global scope or the stack frame. ROSE_ASSERT(binaryAdd->get_rhs() != NULL); SgAsmValueExpression* offsetExpression = isSgAsmValueExpression(binaryAdd->get_rhs()); ROSE_ASSERT(offsetExpression != NULL); offset = get_value(offsetExpression); } else { // Case of zero offset from stack frame (first variable in the stack) // or a global variable with immediate address. offset = 0; if (isGlobalVariable == true) { // Handle the case of a global variable. ROSE_ASSERT(memoryReferenceExpression != NULL); SgAsmValueExpression* offsetExpression = isSgAsmValueExpression(memoryReferenceExpression->get_address()); if (offsetExpression != NULL) { offset = get_value(offsetExpression); } #if 0 // ... finish me ... printf ("... finish me ... offset = %p \n",(void*)offset); ROSE_ASSERT(false); #else printf ("isGlobalVariable == true: offset = %p \n",(void*)offset); #endif } } SgAsmValueExpression* valueExpression = isSgAsmValueExpression(instruction->get_operandList()->get_operands()[1]); ROSE_ASSERT(valueExpression != NULL); value = get_value(valueExpression); type = valueExpression->get_type(); ROSE_ASSERT(type != NULL); printf (" isStackVariable = %s \n",isStackVariable ? "true" : "false"); printf (" isGlobalVariable = %s \n",isGlobalVariable ? "true" : "false"); printf (" offset = %zu \n",offset); printf (" value = %zu = %p \n",value,(void*)value); printf (" type = %p = %s \n",type,type->class_name().c_str()); #else // DQ (9/2/2013): This allows us to get the existing code compiled and then move to update the code seperately. printf ("This code needs to be updated to handle the new register handling (ISA independence) \n"); ROSE_ASSERT(false); #endif #if 0 printf ("Exiting as a test... \n"); ROSE_ASSERT(false); #endif }
/**************************************************** * create a BinaryNode ****************************************************/ SgAsmExpression* RoseBin_IDAPRO_buildTree::convertBinaryNode(exprTreeType* expt, list<SgAsmExpression*> *children, const string& typeOfOperandIn) { string typeOfOperand = typeOfOperandIn; SgAsmExpression* binNode=NULL; int sizeOfList = children->size(); bool isLeaf = false; if (sizeOfList==0) isLeaf = true; if (RoseBin_support::DEBUG_MODE()) { ostringstream addrhex; addrhex << hex << setw(8) << expt->immediate ; cout << "\n>> convert binNode: expr_id: " << expt->id << endl; cout << " isLeaf: " << RoseBin_support::resBool(isLeaf) << " symbol: " << expt->symbol << " immedi: " << expt->immediate << " hex: " << addrhex.str() << endl; } if (expt->expr_type==4) { // this is a operator if (RoseBin_support::DEBUG_MODE()) cout << " its a operator ... " << expt->symbol << endl; string symbol = RoseBin_support::str_to_upper(expt->symbol); if (symbol=="CS" || symbol=="DS" || symbol=="SS" || symbol=="ES" || symbol == "FS" || symbol=="GS") { // we need the child information to build this if (sizeOfList!=1) { //cerr << " a reference expression can only take one child! " <<endl; list<SgAsmExpression*>::iterator childList = children->begin(); for (; childList!=children->end();++childList) { SgAsmExpression* child = *childList; exprTreeType exprTree = debugHelpMap[child]; //cout << " children are : " << child << " -- " << exprTree.symbol << endl; } abort(); } SgAsmExpression* child = *(children->begin()); ROSE_ASSERT(RoseAssemblyLanguage==x86); RegisterDescriptor regDesc; resolveRegisterX86(symbol, ®Desc); if (isSgAsmMemoryReferenceExpression(child)) { binNode = new SgAsmx86RegisterReferenceExpression(regDesc); isSgAsmx86RegisterReferenceExpression(binNode)->set_type(getRegisterType(regDesc)); isSgAsmMemoryReferenceExpression(child)->set_segment(binNode); binNode->set_parent(child); binNode=child; } else { binNode = child; // do nothing // if we have a jump case, we have a value only and no RegRef } #if 0 // resolve the register information if (RoseAssemblyLanguage==x86) { SgAsmRegisterReferenceExpression::x86_register_enum registerSg = SgAsmRegisterReferenceExpression::undefined_general_register; SgAsmRegisterReferenceExpression::x86_position_in_register_enum regSize = SgAsmRegisterReferenceExpression::undefined_position_in_register; resolveRegisterX86(symbol, ®isterSg, ®Size); // binNode = new SgAsmRegisterReferenceExpression(registerSg, regSize); binNode = new SgAsmRegisterReferenceExpression(); (isSgAsmRegisterReferenceExpression(binNode))->set_x86_register_code(registerSg); (isSgAsmRegisterReferenceExpression(binNode))->set_x86_position_in_register_code(regSize); } else if (RoseAssemblyLanguage==arm) { SgAsmRegisterReferenceExpression::arm_register_enum registerSg = SgAsmRegisterReferenceExpression::undefined_arm_register; SgAsmRegisterReferenceExpression::arm_position_in_register_enum regSize = SgAsmRegisterReferenceExpression::undefined_arm_position_in_register; resolveRegisterX86(symbol, ®isterSg, ®Size); // binNode = new SgAsmRegisterReferenceExpression(registerSg, regSize); binNode = new SgAsmRegisterReferenceExpression(); (isSgAsmRegisterReferenceExpression(binNode))->set_arm_register_code(registerSg); (isSgAsmRegisterReferenceExpression(binNode))->set_arm_position_in_register_code(regSize); } // the child could be the expression to an address, e.g. ss:[ebp] // todo : dont know how to change this right now. Affected by AST structure change //isSgAsmRegisterReferenceExpression(binNode)->set_segment(child); rememberOffset = isSgAsmRegisterReferenceExpression(binNode); if (child==NULL) { cerr << "adding no child to RegisterReference " << endl; } child->set_parent(binNode); #endif } else if (expt->symbol=="+") { list<SgAsmExpression*>::iterator childList = children->begin(); int count=0; if (children->size()==1) { // the add has only one child SgAsmExpression* child = *(children->begin()); if (child) { binNode = child; // child->set_parent(previousExp); // if (isSgAsmMemoryReferenceExpression(previousExp)) // isSgAsmMemoryReferenceExpression(previousExp)->set_address(child); // changed on 16Jan08 //if (isSgAsmRegisterReferenceExpression(previousExp)) // isSgAsmRegisterReferenceExpression(previousExp)->set_offset(child); } } else { binNode = new SgAsmBinaryAdd(); for (; childList!=children->end();++childList) { SgAsmExpression* child = *childList; if (child) { if (count==0) isSgAsmBinaryAdd(binNode)->set_lhs(child); else isSgAsmBinaryAdd(binNode)->set_rhs(child); child->set_parent(binNode); } count++; } } } else if (expt->symbol=="-") { binNode = new SgAsmBinarySubtract(); list<SgAsmExpression*>::iterator childList = children->begin(); int count=0; for (; childList!=children->end();++childList) { SgAsmExpression* child = *childList; if (count==0) isSgAsmBinarySubtract(binNode)->set_lhs(child); else isSgAsmBinarySubtract(binNode)->set_rhs(child); count++; child->set_parent(binNode); } } else if (expt->symbol=="*") { binNode = new SgAsmBinaryMultiply(); list<SgAsmExpression*>::iterator childList = children->begin(); int count=0; for (; childList!=children->end();++childList) { SgAsmExpression* child = *childList; if (count==0) isSgAsmBinaryMultiply(binNode)->set_lhs(child); else isSgAsmBinaryMultiply(binNode)->set_rhs(child); count++; child->set_parent(binNode); } } else if (expt->symbol=="/") { binNode = new SgAsmBinaryDivide(); list<SgAsmExpression*>::iterator childList = children->begin(); int count=0; for (; childList!=children->end();++childList) { SgAsmExpression* child = *childList; if (count==0) isSgAsmBinaryDivide(binNode)->set_lhs(child); else isSgAsmBinaryDivide(binNode)->set_rhs(child); count++; child->set_parent(binNode); } } else if (expt->symbol=="[") { // the child is the expression that constitutes the address , e.g. [ebp] SgAsmExpression* child = *(children->begin()); // the child is another expression, like +, - , ... ROSE_ASSERT(child); binNode = new SgAsmMemoryReferenceExpression(); isSgAsmMemoryReferenceExpression(binNode)->set_type(SgAsmTypeQuadWord::createType()); ROSE_ASSERT (binNode->get_type()); isSgAsmMemoryReferenceExpression(binNode)->set_address(child); child->set_parent(binNode); // isSgAsmMemoryReferenceExpression(binNode)->set_offset(rememberOffset); //rememberOffset->set_parent(binNode); //rememberOffset=NULL; } else if (expt->symbol=="b4" || expt->symbol=="b2" || expt->symbol=="b1" || expt->symbol=="b6" || expt->symbol=="b8") { // since b4, b2, b1 are types and no nodes, // we return the binNode of the child binNode = *(children->begin()); if (isSgAsmMemoryReferenceExpression(binNode)) { SgAsmMemoryReferenceExpression* memRefT = isSgAsmMemoryReferenceExpression(binNode); if (expt->symbol=="b1") memRefT->set_type(SgAsmTypeByte::createType()); else if (expt->symbol=="b2") memRefT->set_type(SgAsmTypeWord::createType()); else if (expt->symbol=="b4") memRefT->set_type(SgAsmTypeDoubleWord::createType()); else if (expt->symbol=="b6") memRefT->set_type(SgAsmTypeByte::createType()); // FIXME else if (expt->symbol=="b8") memRefT->set_type(SgAsmTypeQuadWord::createType()); ROSE_ASSERT (memRefT->get_type()); } } else { cerr << "ERROR:: FIXME:: symbol not resolved " << expt->symbol << endl; // temp solution for arm. tps (09/17/07) binNode = new SgAsmIntegerValueExpression('5', 8); // ascii for 5 // exit(0); } } else if (expt->expr_type==2) { // its a value if (RoseBin_support::DEBUG_MODE()) cout << " its a value... resolving type: --- " << typeOfOperand << " --- " ; // fixme .. temporary fix for DB issue if (typeOfOperand=="BYTE") typeOfOperand="WORD"; if (typeOfOperand=="WORD") typeOfOperand="DWORD"; if (typeOfOperand=="BYTE") { binNode = SageBuilderAsm::makeByteValue(expt->immediate); } else if (typeOfOperand=="WORD") { binNode = SageBuilderAsm::makeWordValue(expt->immediate); } else if (typeOfOperand=="DWORD") { binNode = SageBuilderAsm::makeDWordValue(expt->immediate); } else if (typeOfOperand=="QWORD") { binNode = SageBuilderAsm::makeQWordValue(expt->immediate); } else if (typeOfOperand=="SFLOAT") { binNode = new SgAsmSingleFloatValueExpression(); isSgAsmSingleFloatValueExpression(binNode)->set_value(expt->immediate); } else if (typeOfOperand=="DFLOAT") { binNode = SageBuilderAsm::makeQWordValue(expt->immediate); } else { cerr << "ERROR :: unhandled type of value: " << typeOfOperand << " val: " << RoseBin_support::ToString(expt->immediate) << endl; // exit(0); // creating defualt for now binNode = SageBuilderAsm::makeDWordValue(expt->immediate); } if (RoseBin_support::DEBUG_MODE()) cout << typeOfOperand << endl; //printExprNode(*expt); } else if (expt->expr_type==1) { // register if (RoseBin_support::DEBUG_MODE()) cout << " its a register .... " << endl; if (RoseAssemblyLanguage==x86) { RegisterDescriptor regDesc; string symbol = RoseBin_support::str_to_upper(expt->symbol); resolveRegisterX86(symbol, ®Desc); //binNode = new SgAsmRegisterReferenceExpression(registerSg, regSize); binNode = new SgAsmx86RegisterReferenceExpression(regDesc); isSgAsmx86RegisterReferenceExpression(binNode)->set_type(getRegisterType(regDesc)); } else if (RoseAssemblyLanguage==arm) { RegisterDescriptor regDesc; string symbol = RoseBin_support::str_to_upper(expt->symbol); resolveRegisterX86(symbol, ®Desc); // binNode = new SgAsmRegisterReferenceExpression(registerSg, regSize); binNode = new SgAsmArmRegisterReferenceExpression(regDesc); // todo : find out types for ARM } } else { cerr << " ERROR ... buildTree ... wrong type " << endl; RoseBin_support::printExprNode(*expt); exit(0); } return binNode; }
/************************************************************ * checks if an instruction has a RegisterReference on the * right (bool) or left side. * Return value is meaningless if registerReference return value is false. ***********************************************************/ std::pair<X86RegisterClass, int> RoseBin_DataFlowAbstract::check_isRegister(SgGraphNode* node, SgAsmx86Instruction* inst, bool rightSide, bool& memoryReference, bool& registerReference ) { // bool rightSide specifies // true = checking the right side (of instruction operands) for a registerReference // false = checking the left side (of instruction operands) for a registerReference registerReference = false; SgAsmOperandList* opList = inst->get_operandList(); ROSE_ASSERT(opList); SgAsmx86RegisterReferenceExpression* refExpr =NULL; std::pair<X86RegisterClass, int> code = std::make_pair(x86_regclass_gpr, 0); // meaningless int counter=0; int endCounter=0; if (rightSide) endCounter=1; string operands=""; // iterate through the operands (for x86 = 2 operands) SgAsmExpressionPtrList ptrList = opList->get_operands(); for (SgAsmExpressionPtrList::iterator it=ptrList.begin(); it!=ptrList.end(); ++it) { SgAsmExpression* expr = *it; ROSE_ASSERT(expr); // skip the iteration if we do not evaluate the correct side // counter ==0 (left side) counter==1 (right side) if (counter!=endCounter) { counter++; continue; } else counter++; SgAsmMemoryReferenceExpression* mem = isSgAsmMemoryReferenceExpression(expr); if (mem) { memoryReference = true; SgAsmExpression* memOff = mem->get_address(); if (isSgAsmx86RegisterReferenceExpression(memOff)) { SgAsmx86RegisterReferenceExpression* memRegRef = isSgAsmx86RegisterReferenceExpression(memOff); code = std::make_pair((X86RegisterClass)memRegRef->get_descriptor().get_major(), memRegRef->get_descriptor().get_minor()); registerReference = true; } } refExpr = isSgAsmx86RegisterReferenceExpression(expr); if (refExpr) { code = std::make_pair((X86RegisterClass)refExpr->get_descriptor().get_major(), refExpr->get_descriptor().get_minor()); registerReference = true; } } #if 0 refExpr = isSgAsmx86RegisterReferenceExpression(expr); if (refExpr) { // check if it could be a memory reference // changed by tps on 16Jan08 SgAsmExpression* offset = refExpr->get_offset(); if (isSgAsmMemoryReferenceExpression(offset)) { // is a memory reference memoryReference = true; SgAsmMemoryReferenceExpression* mem = isSgAsmMemoryReferenceExpression(offset); SgAsmExpression* memOff = mem->get_address(); if (isSgAsmx86RegisterReferenceExpression(memOff)) { SgAsmx86RegisterReferenceExpression* memRegRef = isSgAsmx86RegisterReferenceExpression(memOff); code = memRegRef->get_identifier(); registerReference = true; } } else { // is a register reference code = refExpr->get_identifier(); registerReference = true; // } } } #endif return code; }
bool RoseBin_Emulate::evaluateInstruction( SgAsmx86Instruction* binInst, string& operands) { SgAsmOperandList* opList = binInst->get_operandList(); ROSE_ASSERT(opList); //string operands = ""; bool success = true; // *************************************************************** // handle special cases // handle function calls to cpuid and int if (binInst->get_kind() == x86_cpuid) { operands += " :: specialOp cpuid"; //clearRegisters(); rbx = getRandomValue(100); // example return value rcx = getRandomValue(100); // example return value rdx = getRandomValue(100); // example return value return success; } else if (binInst->get_kind() == x86_int) { operands += " :: specialOp Int"; //clearRegisters(); getRegister_val(std::make_pair(x86_regclass_gpr, x86_gpr_ax), RoseBin_support::x86_regpos_qword, rax); // should get the values from memory! string values = ""; rose_hash::unordered_map <uint64_t, uint64_t>::iterator it = memory.begin(); for (;it!=memory.end();++it) { uint64_t loc = it->first; uint64_t val = it->second; string loc_s = RoseBin_support::HexToString(loc); string val_s = RoseBin_support::HexToString(val); values+= "("+loc_s+":"+val_s+")-"; } //uint64_t rbx_v = getMemory(0x1c); //uint64_t rcx_v = getMemory(0x20); //uint64_t rdx_v = getMemory(0x24); if (rax==4) { // sys_write //string values = "" + RoseBin_support::HexToString(rbx_v); //values += "-" + RoseBin_support::HexToString(rcx_v); //values += "-" + RoseBin_support::HexToString(rdx_v); operands += " :: syswrite : "+values; } else { success = false; } return success; } // handle call to rdtsc else if (binInst->get_kind() == x86_rdtsc) { // simulate timer function operands += " :: specialOp rdtsc"; rdx = 0x0ULL; rax = getRandomValue(10); return success; } // ************************************************************** int counter=0; SgAsmx86RegisterReferenceExpression* refExpr =NULL; std::pair<X86RegisterClass, int> code ; RoseBin_support::X86PositionInRegister pos ; // iterate through the operands (for x86 = 2 operands) SgAsmExpressionPtrList ptrList = opList->get_operands(); SgAsmMemoryReferenceExpression* memRef = NULL; for (SgAsmExpressionPtrList::iterator it=ptrList.begin(); it!=ptrList.end(); ++it) { SgAsmExpression* expr = *it; ROSE_ASSERT(expr); //string type = "DWORD"; //string result = unparser->resolveOperand(expr,&type); if (counter==0) { // left hand side ************************************************************* refExpr = isSgAsmx86RegisterReferenceExpression(expr); // check what it could be // ******** 1. its a RegisterReferenceExpression on the left side if (refExpr) { code = std::make_pair((X86RegisterClass)refExpr->get_descriptor().get_major(), refExpr->get_descriptor().get_minor()); pos = get_position_in_register(refExpr->get_descriptor()); operands = "\\nleft :: refExpr "; //SgAsmExpression* expression = refExpr->get_offset(); //memRef = isSgAsmMemoryReferenceExpression(expression); //if (memRef) // operands += " :: memoryRefExp "; operands += "\\n"; } // ******** 2. Its a BitAndByteInstruction else { switch (binInst->get_kind()) { case x86_sete: { // if the instruction is a sete, then we want to check ZF and set the // proper register to 1 if (ZF) { uint64_t qw_val=1; assignRegister(code, qw_val); ZF=false; } break; } case x86_dec: { uint64_t left = getRegister(code); assignRegister(code, --left); break; } default: { success = false; } } } } else { // right hand side ************************************************************ SgAsmValueExpression* valExp = isSgAsmValueExpression(expr); SgAsmx86RegisterReferenceExpression* refExprR = isSgAsmx86RegisterReferenceExpression(expr); uint8_t b_val=0xF; uint16_t w_val=0xFF; uint32_t dw_val=0xFFFF; uint64_t qw_val=0xFFFFFFFF; // check what it could be // ****** 1. valueExpression if (valExp) { // value expr operands += "right :: valExp "; RoseBin_support::resolveValue(valExp, false, b_val, w_val, dw_val, qw_val); uint64_t val = 0xFFFFFFFF; if (b_val!=0xF) val = uint64_t(b_val); else if (w_val!=0xFF) val = uint64_t(w_val); else if (dw_val!=0xFFFF) val = uint64_t(dw_val); else if (qw_val!=0xFFFFFFFF) val = uint64_t(qw_val); if (refExpr) { switch (binInst->get_kind()) { // mov instruction case x86_mov: { operands += " :: DataTrans :: Mov "; assignRegister(code, pos, b_val, w_val, dw_val, qw_val); uint64_t addr_value=0; getRegister_val(code, RoseBin_support::x86_regpos_qword, addr_value); //string str=""; //string var = createVariable(addr_value, str, type, description, length); //string varHex = RoseBin_support::HexToString(addr_value) ; //operands += "\\nVariable : " + var + "("+varHex+")"; break; } case x86_and: { operands += " :: Logical :: And"; uint64_t reg = getRegister(code); operands+=printRegister("reg",reg); operands+=printRegister("val",val); reg &= val; assignRegister(code, reg); if (reg==0) ZF = true; else ZF=false; break; } case x86_add: { operands += " :: Arithm :: Add"; uint64_t left = getRegister(code); uint64_t sum = left+val; assignRegister(code, sum); break; } default: success = false; } } // refExp else { success = false;} } // valExp else if (refExprR) { // ****** 2. referenceExpression // the right hand side is also a register or memory location std::pair<X86RegisterClass, int> codeR ; RoseBin_support::X86PositionInRegister posR ; codeR = std::make_pair((X86RegisterClass)refExprR->get_descriptor().get_major(), refExprR->get_descriptor().get_minor()); posR = get_position_in_register(refExprR->get_descriptor()); operands += "right :: refExpr "; switch (binInst->get_kind()) { case x86_mov: { operands += " :: DataTrans :: Mov"; if (memRef) { operands += " :: MemRef "; SgAsmExpression* mem_loc = memRef->get_address(); string res = unparseExpression(mem_loc); uint64_t pos = 0; RoseBin_support::from_string<uint64_t>(pos, res, std::hex); uint64_t value = getRegister(codeR); assignMemory(pos, value); operands += "["+res+"] "+" ("+RoseBin_support::HexToString(pos)+":"+RoseBin_support::HexToString(value)+")"; } else { operands += " :: RegRef "; // copy value in right register to left register getRegister_val(codeR, posR, b_val, w_val, dw_val, qw_val); assignRegister(code, pos, b_val, w_val, dw_val, qw_val); } break; } //mov instruction case x86_cmp: { operands += " :: Arith :: Cmp"; uint64_t left = getRegister(code); uint64_t right = getRegister(codeR); if (left==right) ZF=true; break; } default: { success =false; } } } //refExprR else { success =false;} } counter++; } operands += "\\n"; return success; }