/* See related method above */ rose_addr_t SgAsmGenericSection::write(std::ostream &f, rose_addr_t offset, const SgUnsignedCharList &buf) const { if (0==buf.size()) return 0; return write(f, offset, buf.size(), (void*)&(buf[0])); }
/* String output with old-style arguments. */ std::string SgAsmExecutableFileFormat::hexdump(rose_addr_t base_addr, const std::string &prefix, const SgUnsignedCharList &data, bool multiline) { if (data.empty()) return ""; HexdumpFormat fmt; fmt.multiline = multiline; fmt.prefix = prefix.c_str(); return hexdump(base_addr, &(data[0]), data.size(), fmt); }
/* Stream output for old-style arguments. */ void SgAsmExecutableFileFormat::hexdump(std::ostream &f, rose_addr_t base_addr, const std::string &prefix, const SgUnsignedCharList &data, bool multiline) { if (!data.empty()) { HexdumpFormat fmt; fmt.multiline = multiline; fmt.prefix = prefix.c_str(); hexdump(f, base_addr, &(data[0]), data.size(), fmt); } }
/** Reads content of a section and returns it as a container. The returned container will always have exactly @p size byte. * If @p size bytes are not available in this section at the specified offset then the container will be zero padded. */ SgUnsignedCharList SgAsmGenericSection::read_content_local_ucl(rose_addr_t rel_offset, rose_addr_t size) { SgUnsignedCharList retval; unsigned char *buf = new unsigned char[size]; read_content_local(rel_offset, buf, size, false); /*zero pads; never throws*/ for (size_t i=0; i<size; i++) retval.push_back(buf[i]); delete[] buf; return retval; }
SgUnsignedCharList Assembler::assembleBlock(const std::vector<SgAsmInstruction*> &insns, rose_addr_t va) { SgUnsignedCharList retval; for (std::vector<SgAsmInstruction*>::const_iterator ii=insns.begin(); ii!=insns.end(); ++ii) { SgAsmInstruction *insn = *ii; insn->set_address(va); SgUnsignedCharList ucl = assembleOne(insn); retval.insert(retval.end(), ucl.begin(), ucl.end()); va += ucl.size(); } return retval; }
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; }
int main(int argc, char *argv[]) { std::ios::sync_with_stdio(); argv0 = argv[0]; { size_t slash = argv0.rfind('/'); argv0 = slash==std::string::npos ? argv0 : argv0.substr(slash+1); if (0==argv0.substr(0, 3).compare("lt-")) argv0 = argv0.substr(3); } int argno = 1; for (/*void*/; argno<argc && '-'==argv[argno][0]; ++argno) { std::cout << argv[argno] << std::endl; if (!strcmp(argv[argno], "--")) { ++argno; break; } else if (!strcmp(argv[argno], "--help") || !strcmp(argv[argno], "-h")) { ::usage(0); } else { std::cerr <<argv0 <<": unrecognized switch: " <<argv[argno] <<"\n" <<"see \"" <<argv0 <<" --help\" for usage info.\n"; exit(1); } } if (argno+1!=argc) ::usage(1); std::string specimen_name = StringUtility::getAbsolutePathFromRelativePath(argv[argno++], true); std::string specimen_path = StringUtility::getPathFromFileName(specimen_name); std::cout << "Specimen name is: " << specimen_name << std::endl; SgAsmInterpretation *interp = CloneDetection::open_specimen(specimen_name, argv0, false); SgBinaryComposite *binfile = SageInterface::getEnclosingNode<SgBinaryComposite>(interp); assert(interp!=NULL && binfile!=NULL); // Figure out what functions we need to generate files from. std::vector<SgAsmFunction*> all_functions = SageInterface::querySubTree<SgAsmFunction>(interp); std::cerr <<argv0 <<": " <<all_functions.size() <<" function" <<(1==all_functions.size()?"":"s") <<" found\n"; for (std::vector<SgAsmFunction*>::iterator fi=all_functions.begin(); fi!=all_functions.end(); ++fi) { // Save function SgAsmFunction *func = *fi; std::vector<SgAsmInstruction*> insns = SageInterface::querySubTree<SgAsmInstruction>(func); std::string function_name = func->get_name(); if( function_name.size() == 0 || insns.size() < 100 || function_name.find("@plt") != std::string::npos ) { continue; } std::cout << "function name is: " << function_name << std::endl; { //std::string file_name = specimen_name+"_"+func->get_name()+"_"+boost::lexical_cast<std::string>(func->get_entry_va()); std::string file_name = specimen_path + "/" + function_name; std::cout << "generating " << file_name << " from " << specimen_name << std::endl; std::ofstream func_file; func_file.open(file_name.c_str()); // Save instructions for (std::vector<SgAsmInstruction*>::iterator it = insns.begin(); it != insns.end(); ++it) { SgUnsignedCharList array = (*it)->get_raw_bytes(); std::string str = ""; for(size_t i=0; i < array.size(); ++i) { unsigned char c = array[i]; str+= c; } func_file << str; } func_file.close(); } } return 0; }