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; } };
/**************************************************** * 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); }
/**************************************************** * 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; }