SgAsmX86Instruction* buildX86MultibyteNopInstruction(size_t nBytes) { ASSERT_require(nBytes > 0); ASSERT_require(nBytes <= 9); SgAsmX86Instruction *instruction = new SgAsmX86Instruction(0, "nop", x86_nop, x86_insnsize_32, x86_insnsize_32, x86_insnsize_32); // Build a simple version of multi-byte nop using repeated prefixes. SgUnsignedCharList insnbuf; for (size_t i = 1; i < nBytes; i++) insnbuf.push_back(0x66); insnbuf.push_back(0x90); instruction->set_raw_bytes(insnbuf); instruction->set_lockPrefix(false); instruction->set_repeatPrefix(x86_repeat_none); SgAsmOperandList *operands = new SgAsmOperandList(); instruction->set_operandList(operands); operands->set_parent(instruction); return instruction; }
SgAsmInstruction* SageBuilderAsm::buildMultibyteNopInstruction(int n) { // DQ (5/1/2010): Support for building multi-byte NOP instructions. // this is x86 specific which is OK for now. // SgAsmInstruction* instruction = NULL; ROSE_ASSERT(n > 0); ROSE_ASSERT(n <= 9); uint64_t ip = 0; /* Virtual address for start of instruction */ std::string mnemonic = "nop"; X86InstructionKind kind = x86_nop; X86InstructionSize insnSize = x86_insnsize_32; /* Default size of instructions, based on architecture; see init() */ X86InstructionSize effectiveOperandSize = x86_insnsize_32; X86InstructionSize effectiveAddressSize = x86_insnsize_32; bool lock = false; X86RepeatPrefix repeatPrefix = x86_repeat_none; bool branchPredictionEnabled = false; X86BranchPrediction branchPrediction = x86_branch_prediction_none; // SgUnsignedCharList insnbuf(0x90); SgUnsignedCharList insnbuf; size_t insnbufat = size_t(n); /* Index of next byte to be read from or write to insnbuf */ SgAsmx86Instruction *instruction = NULL; instruction = new SgAsmx86Instruction(ip, mnemonic, kind, insnSize, effectiveOperandSize, effectiveAddressSize); ROSE_ASSERT(instruction != NULL); // Here we are building a simpler version of multi-byte nop using repeated prefixes. for (int i = 1; i < n; i++) { insnbuf.push_back(0x66); } insnbuf.push_back(0x90); #if 0 // This switch will implement proper multi-byte NOPs (not implemented yet). switch(n) { case 1: { // instruction->set_raw_bytes(SgUnsignedCharList(&(insnbuf[0]), &(insnbuf[0])+insnbufat)); insnbuf.push_front(0x66); break; } // case 2: instruction = makeInstruction(x86_nop, "nop", modrm); break; default: { printf ("Error: SageBuilderAsm::buildMultibyteNopInstruction(n=%d) not supported \n",n); ROSE_ASSERT(false); } } #endif instruction->set_raw_bytes(SgUnsignedCharList(&(insnbuf[0]), &(insnbuf[0])+insnbufat)); ROSE_ASSERT(instruction != NULL); instruction->set_lockPrefix(lock); instruction->set_repeatPrefix(repeatPrefix); if (branchPredictionEnabled) instruction->set_branchPrediction(branchPrediction); SgAsmOperandList *operands = new SgAsmOperandList(); instruction->set_operandList(operands); operands->set_parent(instruction); return instruction; }
/**************************************************** * process all instructions in the DB * add the instructions to the blocks ****************************************************/ void RoseBin_DB_IDAPRO::process_instruction_query(MYSQL* conn, MYSQL_RES* res_set) { rememberInstructions.clear(); // get the functions // char* q = (char*)"SELECT * FROM instructions_1"; char *q = (char*)"select *, (select parent_function from basic_blocks_1 where id = i.basic_block_id and (i.address - parent_function) >= 0 and (i.address - parent_function) = (select min(i.address - parent_function) from basic_blocks_1 where id = i.basic_block_id and (i.address - parent_function) >= 0) ) as i_f from instructions_1 i order by i.address"; 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 { MYSQL_ROW row; string mnemonic=(char*)""; uint64_t address=0; int basic_block=-1; int sequence =-1; string data=(char*)""; int i_func; 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) basic_block = -1; if (i==2) mnemonic = ret; if (i==3) sequence = -1; if (i==4) data=ret; if (i==5) i_func= -1; } else { ret= row[i]; if (i==0) address = atoi(ret); if (i==1) basic_block = atoi(ret); if (i==2) mnemonic = ret; if (i==3) sequence = atoi(ret); if (i==4) data=ret; if (i==5) i_func = atoi(ret); } } // patched to adjust to objdump , Apr 26 2007 if (mnemonic ==(char*)"retn") mnemonic = (char*)"ret"; if (RoseBin_support::DEBUG_MODE()) { ostringstream addrhex; addrhex << hex << setw(8) << address ; cout << ">> creating instruction : " << addrhex.str() << " " << address << " - " << basic_block << " - " << mnemonic << " - " << sequence << endl; } // check if it is an instruction or if it appears in the callgraph, // if it is in the callgraph, one wants to create a BinaryCall instead // append the instruction to its function rose_hash::unordered_map <int, SgAsmFunction* >::iterator func_it = rememberFunctions.find(i_func); SgAsmFunction* func = NULL; // for (func_it; func_it!=rememberFunctions.end(); ++func_it) { if (func_it != rememberFunctions.end()) { func = func_it->second; } else { if (i_func!=-1) cerr << " ERROR : cant find the function i_func : " << i_func << " in rememberFunctions for instruction : " << mnemonic << endl; } SgAsmInstruction* instruction = NULL; instruction = createInstruction(address, func, mnemonic); // instruction = new SgAsmInstruction(address,bb,mnemonic,""); // Sep 29, tps : commented the following line out, since the function was removed. //instruction->set_raw_bytes(data); ROSE_ASSERT(instruction); SgAsmOperandList* operandList = new SgAsmOperandList(); instruction->set_operandList(operandList); operandList->set_parent(instruction); ostringstream hexaddr; hexaddr << hex << setw(8) << address ; if (RoseBin_support::DEBUG_MODE()) cout << " .rememberInstruction " << instruction->class_name() << " at : " << address << " hex: " << hexaddr.str() << endl; rememberInstructions[address]= instruction ; if (func) { // get the block in the func and append to it to conform to jeremiah func->append_statement(instruction); instruction->set_parent(func); //vector <SgNode*> blockVec =func->get_traversalSuccessorContainer(); //SgAsmBlock* block = isSgAsmBlock(blockVec[0]); //ROSE_ASSERT(block); //block->append_statement(instruction); //instruction->set_parent(block); ROSE_ASSERT(instruction->get_parent()); //SgAsmNode* nInst = (SgAsmNode*) instruction; //nInst->set_parent(func); ostringstream addrhex; addrhex << hex << setw(8) << i_func ; if (RoseBin_support::DEBUG_MODE()) cout << ">> appended instruction to function: " << func->get_name() << " addr " << addrhex.str() << " " << address << endl; } else { if (i_func!=-1) { cerr << " ERROR :: could not append instruction to function : " << endl; //exit(0); } } } // while } // if (res_set==NULL) checkError(conn,res_set); }