int main(int argc, char *argv[]) { Diagnostics::initialize(); mlog = Sawyer::Message::Facility("tool", Diagnostics::destination); Diagnostics::mfacilities.insertAndAdjust(mlog); // Parse command line Settings settings; std::vector<std::string> args = parseCommandLine(argc, argv, settings).unreachedArgs(); if (args.size()!=2) throw std::runtime_error("invalid usage; see --help"); // Load the CSV files FunctionByAddress code1, data1, code2, data2; readCsvFile(args[0], code1 /*out*/, data1 /*out*/); readCsvFile(args[1], code2 /*out*/, data2 /*out*/); showStats(FileSystem::Path(args[0]).filename().string(), code1, data1, FileSystem::Path(args[1]).filename().string(), code2, data2); std::cout <<"\n"; // Parse the specimen if (!settings.specimenName.empty()) { P2::Engine engine; MemoryMap map = engine.load(settings.specimenName); InstructionProvider::Ptr insns = InstructionProvider::instance(engine.obtainDisassembler(), map); map.dump(std::cout); listInstructions(insns, map, code1, code2); } }
int main(int argc, char *argv[]) { Diagnostics::initialize(); ::mlog = Diagnostics::Facility("tool", Diagnostics::destination); Diagnostics::mfacilities.insertAndAdjust(::mlog); // Parse the command-line Partitioner2::Engine engine; std::vector<std::string> specimenNames = parseCommandLine(argc, argv, engine); if (specimenNames.empty()) throw std::runtime_error("no specimen specified; see --help"); // Load specimen into memory MemoryMap map = engine.loadSpecimens(specimenNames); // Configure instruction semantics Partitioner2::Partitioner partitioner = engine.createPartitioner(); Disassembler *disassembler = engine.obtainDisassembler(); const RegisterDictionary *regdict = disassembler->get_registers(); if (disassembler->dispatcher() == NULL) throw std::runtime_error("no instruction semantics for this architecture"); BaseSemantics::RiscOperatorsPtr ops = InstructionSemantics2::ConcreteSemantics::RiscOperators::instance(regdict); BaseSemantics::DispatcherPtr cpu = disassembler->dispatcher()->create(ops); ConcreteSemantics::MemoryState::promote(ops->currentState()->memoryState())->memoryMap(map); // Find starting address rose_addr_t va = 0; if (settings.startVa) { va = *settings.startVa; } else if (engine.isaName() == "coldfire") { // Use the interrupt vector to initialize the stack pointer and instruction pointer. uint32_t sp, ip; if (4 != map.at(0).limit(4).read((uint8_t*)&sp).size()) throw std::runtime_error("cannot read stack pointer at address 0x00000000"); ops->writeRegister(disassembler->stackPointerRegister(), ops->number_(32, ByteOrder::be_to_host(sp))); if (4 != map.at(4).limit(4).read((uint8_t*)&ip).size()) throw std::runtime_error("cannot read instruction pointer at address 0x00000004"); va = ByteOrder::be_to_host(ip); } else if (!map.atOrAfter(0).require(MemoryMap::EXECUTABLE).next().assignTo(va)) { throw std::runtime_error("no starting address specified and none marked executable"); } ops->writeRegister(disassembler->instructionPointerRegister(), ops->number_(32, va)); // Execute map.dump(::mlog[INFO]); while (1) { va = ops->readRegister(disassembler->instructionPointerRegister())->get_number(); SgAsmInstruction *insn = partitioner.instructionProvider()[va]; SAWYER_MESG(::mlog[TRACE]) <<unparseInstructionWithAddress(insn, NULL, regdict) <<"\n"; try { cpu->processInstruction(insn); } catch (const BaseSemantics::Exception &e) { ::mlog[WARN] <<e <<"\n"; } } // std::cout <<"Final state:\n"; // std::cout <<*ops->currentState(); }
// Get all the functions defined for this process image. We do this by disassembling the entire process executable memory // and using CFG analysis to figure out where the functions are located. Functions find_functions(RTS_Message *m, RSIM_Process *proc) { m->mesg("%s triggered; disassembling entire specimen image...\n", name); MemoryMap *map = disassembly_map(proc); std::ostringstream ss; map->dump(ss, " "); m->mesg("%s: using this memory map for disassembly:\n%s", name, ss.str().c_str()); SgAsmBlock *gblk = proc->disassemble(false/*take no shortcuts*/, map); delete map; map=NULL; std::vector<SgAsmFunction*> functions = SageInterface::querySubTree<SgAsmFunction>(gblk); #if 0 /*DEBUGGING [Robb P. Matzke 2013-02-12]*/ // Prune the function list to contain only what we want. for (std::vector<SgAsmFunction*>::iterator fi=functions.begin(); fi!=functions.end(); ++fi) { if ((*fi)->get_name().compare("_Z1fRi")!=0) *fi = NULL; } functions.erase(std::remove(functions.begin(), functions.end(), (SgAsmFunction*)NULL), functions.end()); #endif return Functions(functions.begin(), functions.end()); }
int main(int argc, char *argv[]) { ROSE_INITIALIZE; Diagnostics::initAndRegister(mlog, "tool"); Sawyer::ProgressBarSettings::minimumUpdateInterval(0.2); // more fluid spinner // Parse command-line P2::Engine engine; Settings settings; std::vector<std::string> args = parseCommandLine(argc, argv, engine, settings); ASSERT_always_require2(args.size() >= 2, "incorrect usage; see --help"); // Parse file containing instruction addresses std::string addrFileName = args[0]; std::set<rose_addr_t> knownVas = parseAddressFile(addrFileName); mlog[INFO] <<"parsed " <<plural(knownVas.size(), "unique addresses") <<"\n"; // Load specimen natively and attach debugger std::vector<std::string> specimen_cmd(args.begin()+1, args.end()); BinaryDebugger debugger(specimen_cmd); debugger.setBreakpoint(AddressInterval::whole()); ASSERT_always_require(debugger.isAttached()); ASSERT_always_forbid(debugger.isTerminated()); pid_t pid = debugger.isAttached(); mlog[INFO] <<"child PID " <<pid <<"\n"; // Get memory map. MemoryMap map; if (MAP_ROSE==settings.mapSource) { map = engine.loadSpecimens(specimen_cmd[0]); } else { map.insertProcess(":noattach:" + numberToString(pid)); } map.dump(mlog[INFO]); // The addresses specified in the instruction address file must all be in memory that is mapped. BOOST_FOREACH (rose_addr_t va, knownVas) { ASSERT_always_require2(map.at(va).require(MemoryMap::EXECUTABLE).exists(), "given address " + addrToString(va) + " is not mapped or lacks execute permission"); }
int main(int argc, char *argv[]) { Diagnostics::initialize(); BinaryAnalysis::Partitioner2::Engine engine; Settings settings; std::vector<std::string> specimenNames = parseCommandLine(argc, argv, engine, settings /*in,out*/); BinaryAnalysis::MagicNumber analyzer; analyzer.maxBytesToCheck(settings.maxBytes); MemoryMap map = engine.loadSpecimens(specimenNames); map.dump(mlog[INFO]); size_t step = std::max(size_t(1), settings.step); AddressInterval limits = settings.limits.isEmpty() ? map.hull() : (settings.limits & map.hull()); Sawyer::Container::IntervalSet<AddressInterval> addresses(map); addresses.intersect(limits); size_t nPositions = addresses.size() / step; mlog[INFO] <<"approximately " <<StringUtility::plural(nPositions, "positions") <<" to check\n"; { Sawyer::ProgressBar<size_t> progress(nPositions, mlog[INFO], "positions"); for (rose_addr_t va=limits.least(); va<=limits.greatest() && map.atOrAfter(va).next().assignTo(va); va+=step, ++progress) { std::string magicString = analyzer.identify(map, va); if (magicString!="data") { // runs home to Momma when it gets confused uint8_t buf[8]; size_t nBytes = map.at(va).limit(sizeof buf).read(buf).size(); std::cout <<StringUtility::addrToString(va) <<" |" <<leadingBytes(buf, nBytes) <<" | " <<magicString <<"\n"; } if (va==limits.greatest()) break; // prevent overflow at top of address space } } }