bool RoseBin_DataFlowAnalysis::exceptionCall(SgAsmX86Instruction* call) { // this function returns true, if the function that is being called is the _malloc function // this is good to know, so that the malloc analysis can be performed even if there is no ret // (tps - 05/23/08): Since the new disassembler does not know function names, this analysis // does not work. // todo : as long as there are no function names -- the malloc analysis will not work. bool exception=false; if (call==NULL) return exception; if (call->get_kind() != x86_call) return exception; SgAsmOperandList* opList = call->get_operandList(); ROSE_ASSERT(opList); SgAsmExpressionPtrList ptrList = opList->get_operands(); // get the first (and only) element string comment = call->get_comment(); if (ptrList.size()!=0) { SgAsmExpression* expr = *(ptrList.begin()); string replace = expr->get_replacement(); if (replace=="_malloc" || replace=="malloc@plt" || comment=="malloc") exception=true; } // cerr << "Found call --- comment = " << comment << " exception = " << exception << endl; return exception; }
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; } };
/** Add edges to graph from functions that call system calls to system calls. * * The first 1000 vertexes (0 to 999) in the graph is reserved for system calls, which is many more than the actual system * calls in linux. */ void add_syscall_edges(DirectedGraph* G, std::vector<SgAsmFunction*>& all_functions) { // Detect all system calls and add an edge from the function to the function to the system call for (unsigned int caller_id = 0; caller_id < all_functions.size(); ++caller_id) { SgAsmFunction *func = all_functions[caller_id]; std::vector<SgAsmInstruction*> insns = SageInterface::querySubTree<SgAsmInstruction>(func); for (std::vector<SgAsmInstruction*>::iterator inst_it = insns.begin(); inst_it != insns.end(); ++inst_it) { SgAsmX86Instruction *insn = isSgAsmX86Instruction(*inst_it); if (insn == NULL) continue; SgAsmBlock *block = SageInterface::getEnclosingNode<SgAsmBlock>(insn); // On linux system calls are always interrups and all interrupts are system calls if (insn && block && insn->get_kind()==x86_int) { const SgAsmExpressionPtrList &opand_list = insn->get_operandList()->get_operands(); SgAsmExpression *expr = opand_list.size()==1 ? opand_list[0] : NULL; //semantically execute the basic block to find out which sytem call was called if (expr && expr->variantT()==V_SgAsmIntegerValueExpression && 0x80==isSgAsmIntegerValueExpression(expr)->get_value()) { const SgAsmStatementPtrList &stmts = block->get_statementList(); size_t int_n; for (int_n=0; int_n<stmts.size(); int_n++) { if (isSgAsmInstruction(stmts[int_n])==insn) break; } typedef PartialSymbolicSemantics::Policy<PartialSymbolicSemantics::State, PartialSymbolicSemantics::ValueType> Policy; typedef X86InstructionSemantics<Policy, PartialSymbolicSemantics::ValueType> Semantics; Policy policy; Semantics semantics(policy); try { semantics.processBlock(stmts, 0, int_n); if (policy.readRegister<32>("eax").is_known()) { int nr = policy.readRegister<32>("eax").known_value(); boost::add_edge(caller_id, nr, *G); } } catch (const Semantics::Exception&) { } catch (const Policy::Exception&) { } } } } } }
/**************************************************** * process operand tuples. * Handles all expressions to be added to the instructions. ****************************************************/ void RoseBin_DB_IDAPRO::process_operand_tuples_query(MYSQL* conn, MYSQL_RES* res_set) { // get the functions rememberOperandStrings.clear(); // Not needed right now char* q = (char*)"SELECT * FROM operand_tuples_1 order by operand_id desc"; if (RoseBin_support::DEBUG_MODE()) cout << "\n>> QUERY:: " << q << "\n" << endl; res_set = process_query(conn,q); if (res_set == NULL) { print_problemWithResults(conn); } else { map < int, vector < SgAsmExpression* > > tmp_instruction_map; // tmp_instruction_map.clear(); MYSQL_ROW row; long address=0; int operand_id=-1; int position =-1; while ((row = mysql_fetch_row(res_set))!=NULL) { for (unsigned int i=0; i<mysql_num_fields(res_set);i++) { char* ret=(char*)""; if (row[i] ==NULL) { ret = (char*)"<NULL>"; if (i==0) address = -1; if (i==1) operand_id = -1; if (i==2) position = -1; } else { ret= row[i]; if (i==0) address = atoi(ret); if (i==1) operand_id = atoi(ret); if (i==2) position = atoi(ret); } } //cerr << " >>>>>>>>>> position : " << position; // if this would have to be saved in a map, it would need to be a multimap!! //if (RoseBin_support::DEBUG_MODE()) { ostringstream addrhex; addrhex << hex << setw(8) << address ; //cout<< "\n\n----------------------------------------------------------------" << endl; if (operand_id % 5000 == 0) { cout << ">> creating operand_tuple : address: " << addrhex.str() << " " << address << " - operand_id: " << operand_id << " - position:" << position << endl; } //} // get the expr_id for the operand_id SgAsmExpression* binExp=NULL; //string operand_str=(char*)""; if (operand_id>=0) { // operand_str = rememberOperandStrings.find(operand_id) != rememberOperandStrings.end() ? rememberOperandStrings[operand_id] : ""; //if (RoseBin_support::DEBUG_MODE()) //cout << ">>>> operand_str: " << operand_str << endl; ROSE_ASSERT (operand_id < (int)rememberExpressionTree_ROOT.size()); int expr_id_root = rememberExpressionTree_ROOT[operand_id]; ROSE_ASSERT (operand_id < (int)rememberExpressionTree_ParentChild.size()); map <int, vector<int> > subTree = rememberExpressionTree_ParentChild[operand_id]; rememberExpressionTree_ROOT.resize(operand_id + 1); rememberExpressionTree_ParentChild.resize(operand_id + 1); ROSE_ASSERT (expr_id_root < (int)rememberExpressionTree.size()); exprTreeType exprTree = rememberExpressionTree[expr_id_root]; string typeOfOperand = resolveType(&exprTree); #if 0 // print multimapsolveRe if (RoseBin_support::DEBUG_MODE()) { multimap<int,int>::iterator it = subTree.begin(); for (; it!=subTree.end();++it) { int f=it->first; int s=it->second; cout << " mm : " << f << "," << s << endl; } } #endif binExp = buildROSE->resolveRecursivelyExpression(address,expr_id_root, subTree, typeOfOperand, &rememberExpressionTree, operand_id, &rememberSubstitution, &rememberComments); } // if operand // should save for each instruction, a list of operands and their position // and add the operand later on to the instruction // map < address, map < pos, binExp > > vector<SgAsmExpression*>& currentOperands = tmp_instruction_map[address]; if (position >= (int)currentOperands.size()) currentOperands.resize(position + 1); currentOperands[position] = binExp; #if 0 map <int, map <int, SgAsmExpression*> >::iterator tmpIt = tmp_instruction_map.find(address); bool found=false; if (tmpIt!=tmp_instruction_map.end()) found=true; if (found) { //cerr << " found position: " << position << endl; // I do not want to add an address into tmp if not in (side effect!) map <int, SgAsmExpression*> tmp_map = tmp_instruction_map[address]; tmp_map[position] = binExp; tmp_instruction_map[address] = tmp_map; } else { // first time visit //cerr << " notfound position: " << position << endl; map <int, SgAsmExpression*> tmp_map; tmp_map[position] = binExp; tmp_instruction_map[address] = tmp_map; } #endif } // while // get basic_block and append this instruction if (RoseBin_support::DEBUG_MODE()) cout << "\n\n> appending operandList to instruction. " << endl; rose_hash::unordered_map <uint64_t, SgAsmInstruction* >::iterator blockIt; int count = 0; cerr << "Instruction count: " << rememberInstructions.size() << endl; for (blockIt=rememberInstructions.begin();blockIt!=rememberInstructions.end();++blockIt) { ++count; if (count % 1000 == 0) cout << "Adding operands to instruction " << count << endl; int inst_address = blockIt->first; SgAsmInstruction* remInstr = blockIt->second; map<int, vector< SgAsmExpression*> >::iterator it = tmp_instruction_map.find(inst_address); if (it != tmp_instruction_map.end()) { // Skip for instructions without operands vector < SgAsmExpression*>& exprList_forInst = it->second; int sizeList = exprList_forInst.size(); // find each element separately for (int i=0; i<sizeList; i++) { SgAsmExpression* binExp = exprList_forInst[i]; #if 0 map <int, SgAsmExpression*>::iterator it = exprList_forInst.find(i); // get the elements in order!! this is important. SgAsmExpression* binExp = it->second; #endif remInstr->get_operandList()->append_operand(binExp); binExp->set_parent(remInstr->get_operandList()); exprTreeType exprTree = buildROSE->getDebugHelp(binExp); if (RoseBin_support::DEBUG_MODE()) cout << ">> append operand (to instruction): binExp: " <<binExp << " - sym: " <<exprTree.symbol << " - immedi: " << exprTree.immediate << endl; } tmp_instruction_map.erase(it); } } } // if (res_set==NULL) checkError(conn,res_set); }
/* 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; }
/* 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; }
/**************************************************** * 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 ***********************************************************/ int64_t RoseBin_DataFlowAbstract::check_isRegister(SgGraphNode* node, SgAsmx86Instruction* inst, std::pair<X86RegisterClass, int> codeSearch, bool rightSide, vector<std::pair<X86RegisterClass, int> >& regsOfInterest, bool& cantTrack ) { // 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 int64_t res = 0xFFFFFFFF; SgAsmOperandList* opList = inst->get_operandList(); ROSE_ASSERT(opList); SgAsmx86RegisterReferenceExpression* refExpr =NULL; std::pair<X86RegisterClass, int> code ; //SgAsmx86RegisterReferenceExpression::x86_position_in_register_enum pos ; //SgAsmMemoryReferenceExpression* memRef = NULL; int counter=0; if (rightSide) counter =-1; else counter = 2; string operands=""; bool foundECX = false; int64_t newVal = 0xFFFFFFFF; // 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); if (rightSide) counter++; else counter--; if (counter==0) { // left hand side if rightSide=true ************************************************************* // right hand side if rightSide=false ************************************************************* SgAsmValueExpression* valExp = isSgAsmValueExpression(expr); refExpr = isSgAsmx86RegisterReferenceExpression(expr); // ****** 1. valueExpression if (valExp) { // value expr newVal = getValueInExpression(valExp); operands += " <<left :: value " +RoseBin_support::HexToString(newVal)+">>"; } // ****** 2. referenceExpression else if (refExpr) { // ****** 2. referenceExpression // the right hand side is also a register or memory location code = std::make_pair((X86RegisterClass)refExpr->get_descriptor().get_major(), refExpr->get_descriptor().get_minor()); operands += " << left :: refExpr >> "; // we need to track the value of the register in order to find out its value vector<std::pair<X86RegisterClass, int> >::iterator it = regsOfInterest.begin(); for (;it!=regsOfInterest.end();++it) { std::pair<X86RegisterClass, int> codeI = *it; if (codeI==codeSearch) { newVal = trackValueForRegister(node, codeSearch, cantTrack, refExpr); break; } } } else { cerr << " unhandled case in checkVariables " << expr->class_name() << endl; exit(0); } } else { // right hand side if rightSide=true ************************************************************ // left hand side if rightSide=false ************************************************************ SgAsmx86RegisterReferenceExpression* refExprR = isSgAsmx86RegisterReferenceExpression(expr); if (refExprR) { code = std::make_pair((X86RegisterClass)refExprR->get_descriptor().get_major(), refExprR->get_descriptor().get_minor()); operands += " <<right :: refExpr>> "; if (code==codeSearch) foundECX=true; } } } if (foundECX) res = newVal; /* if (RoseBin_support::DEBUG_MODE()) cout << " >> checkRegister : " << RoseBin_support::HexToString(res) << " -- " << operands << " foundReg: " << RoseBin_support::resBool(foundECX) << endl; */ return res; }