Exemple #1
0
void TwoBit::after_predict(unsigned long ip, unsigned long nextIP, bool success)
{
	Disassembler disAssem;
	unsigned int type = disAssem.typeOfInst(ip, pid);

	branchTargetBuffer[TWO_BIT_getBTBOffset(ip)] = nextIP;

	if(InstType(type) == CND_JMP)
	{
		if(success)
		{
			if(state[TWO_BIT_getBTBOffset(ip)] == TT)
				state[TWO_BIT_getBTBOffset(ip)] = TT;
			else if(state[TWO_BIT_getBTBOffset(ip)] == T)
				state[TWO_BIT_getBTBOffset(ip)] = TT;
			else if(state[TWO_BIT_getBTBOffset(ip)] == N)
				state[TWO_BIT_getBTBOffset(ip)] = T;
			else if(state[TWO_BIT_getBTBOffset(ip)] == NN)
				state[TWO_BIT_getBTBOffset(ip)] = N;
		}
		else
		{
			if(state[TWO_BIT_getBTBOffset(ip)] == TT)
				state[TWO_BIT_getBTBOffset(ip)] = T;
			else if(state[TWO_BIT_getBTBOffset(ip)] == T)
				state[TWO_BIT_getBTBOffset(ip)] = N;
			else if(state[TWO_BIT_getBTBOffset(ip)] == N)
				state[TWO_BIT_getBTBOffset(ip)] = NN;
			else if(state[TWO_BIT_getBTBOffset(ip)] == NN)
				state[TWO_BIT_getBTBOffset(ip)] = NN;
		}
	}
}
Exemple #2
0
int
main(int argc, char *argv[])
{
    // Parse command-line
    int argno=1;
    for (/*void*/; argno<argc && '-'==argv[argno][0]; ++argno) {
        if (!strcmp(argv[argno], "--")) {
            ++argno;
            break;
        } else {
            std::cerr <<argv[0] <<": unrecognized switch: " <<argv[argno] <<"\n";
            exit(1);
        }
    }
    if (argno+1!=argc) {
        std::cerr <<"usage: " <<argv[0] <<" [SWITCHES] [--] SPECIMEN\n";
        exit(1);
    }
    std::string specimen_name = argv[argno++];

    // Open the file
    rose_addr_t start_va = 0;
    MemoryMap map;
    size_t file_size = map.insertFile(specimen_name, start_va);
    map.at(start_va).limit(file_size).changeAccess(MemoryMap::EXECUTABLE, 0);

    // Try to disassemble every byte, and print the CALL/FARCALL targets
    InstructionMap insns;
    size_t nerrors=0;
    Disassembler *disassembler = new DisassemblerX86(4);
    for (rose_addr_t offset=0; offset<file_size; ++offset) {
        try {
            rose_addr_t insn_va = start_va + offset;
            if (SgAsmX86Instruction *insn = isSgAsmX86Instruction(disassembler->disassembleOne(&map, insn_va)))
                insns[insn_va] = insn;
        } catch (const Disassembler::Exception &e) {
            ++nerrors;
        }
    }

    // Partition those instructions into basic blocks and functions
    Partitioner partitioner;
    SgAsmBlock *gblock = partitioner.partition(NULL, insns, &map);

    // Print addresses of functions
    struct T1: AstSimpleProcessing {
        void visit(SgNode *node) {
            if (SgAsmFunction *func = isSgAsmFunction(node))
                std::cout <<StringUtility::addrToString(func->get_entry_va()) <<"\n";
        }
    };
    T1().traverse(gblock, preorder);

    std::cerr <<specimen_name <<": " <<insns.size() <<" instructions; " <<nerrors <<" errors\n";
    return 0;
}
int main(int argc, const char* argv[])
{
    if (argc != 3)
    {
        std::cerr << "Wrong number of parameters. Should be 2." << std::endl;
        return 0;
    }

    Disassembler disassembler;
    if (disassembler.LoadAssembly(argv[2]))
        disassembler.Disassemble(std::cout);

    return 0;
}
Exemple #4
0
int
main(int argc, char *argv[])
{
    // Parse command-line
    int argno=1;
    for (/*void*/; argno<argc && '-'==argv[argno][0]; ++argno) {
        if (!strcmp(argv[argno], "--")) {
            ++argno;
            break;
        } else {
            std::cerr <<argv[0] <<": unrecognized switch: " <<argv[argno] <<"\n";
            exit(1);
        }
    }
    if (argno+1!=argc) {
        std::cerr <<"usage: " <<argv[0] <<" [SWITCHES] [--] SPECIMEN\n";
        exit(1);
    }
    std::string specimen_name = argv[argno++];
            
    // Open the file
    rose_addr_t start_va = 0;
    MemoryMap map;
    size_t file_size = map.insertFile(specimen_name, start_va);
    map.at(start_va).limit(file_size).changeAccess(MemoryMap::EXECUTABLE, 0);

    // Try to disassemble every byte, and print the CALL/FARCALL targets
    size_t ninsns=0, nerrors=0;
    Disassembler *disassembler = new DisassemblerX86(4);
    for (rose_addr_t offset=0; offset<file_size; ++offset) {
        try {
            rose_addr_t insn_va = start_va + offset;
            SgAsmX86Instruction *insn = isSgAsmX86Instruction(disassembler->disassembleOne(&map, insn_va));
            if (insn && (x86_call==insn->get_kind() || x86_farcall==insn->get_kind())) {
                ++ninsns;
                rose_addr_t target_va;
                if (insn->getBranchTarget(&target_va))
                    std::cout <<StringUtility::addrToString(insn_va) <<": " <<StringUtility::addrToString(target_va) <<"\n";
            }
        } catch (const Disassembler::Exception &e) {
            ++nerrors;
        }
    }

    std::cerr <<specimen_name <<": " <<ninsns <<" instructions; " <<nerrors <<" errors\n";
    return 0;
}
int
main(int argc, char *argv[]) {
    ROSE_INITIALIZE;
    Diagnostics::initAndRegister(&::mlog, "tool");

    // Parse command-line
    P2::Engine engine;
    Settings settings;
    std::vector<std::string> specimen = parseCommandLine(argc, argv, engine, settings);
    if (specimen.empty()) {
        ::mlog[FATAL] <<"no specimen supplied on command-line; see --help\n";
        exit(1);
    }

    // Load specimen into ROSE's simulated memory
    if (!engine.parseContainers(specimen.front())) {
        ::mlog[FATAL] <<"cannot parse specimen binary container\n";
        exit(1);
    }
    Disassembler *disassembler = engine.obtainDisassembler();
    if (!disassembler) {
        ::mlog[FATAL] <<"no disassembler for this architecture\n";
        exit(1);
    }
    const RegisterDescriptor REG_IP = disassembler->instructionPointerRegister();
    ASSERT_require2(REG_IP.is_valid(), "simulation must know what register serves as the instruction pointer");

    // Single-step the specimen natively in a debugger and show each instruction.
    BinaryDebugger debugger(specimen);
    while (!debugger.isTerminated()) {
        uint64_t ip = debugger.readRegister(REG_IP).toInteger();
        uint8_t buf[16];                                // 16 should be large enough for any instruction
        size_t nBytes = debugger.readMemory(ip, sizeof buf, buf);
        if (0 == nBytes) {
            ::mlog[ERROR] <<"cannot read memory at " <<StringUtility::addrToString(ip) <<"\n";
        } else if (SgAsmInstruction *insn = disassembler->disassembleOne(buf, ip, nBytes, ip)) {
            std::cout <<unparseInstructionWithAddress(insn) <<"\n";
        } else {
            ::mlog[ERROR] <<"cannot disassemble instruction at " <<StringUtility::addrToString(ip) <<"\n";
        }
        debugger.singleStep();
    }
    std::cout <<debugger.howTerminated();
}
Exemple #6
0
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();
}
Exemple #7
0
void armv_end(void* codestart, u32 cycl)
{
	//Normal block end
	//cycle counter rv

	//pop registers & return
	assembler->Subs(w27, w27, cycl);
	ptrdiff_t offset = reinterpret_cast<uintptr_t>(arm_exit) - assembler->GetBuffer()->GetStartAddress<uintptr_t>();
	Label arm_exit_label;
	assembler->BindToOffset(&arm_exit_label, offset);
	assembler->B(&arm_exit_label, mi);	//statically predicted as not taken

	offset = reinterpret_cast<uintptr_t>(arm_dispatch) - assembler->GetBuffer()->GetStartAddress<uintptr_t>();
	Label arm_dispatch_label;
	assembler->BindToOffset(&arm_dispatch_label, offset);
	assembler->B(&arm_dispatch_label);

	assembler->FinalizeCode();
	verify(assembler->GetBuffer()->GetCursorOffset() <= assembler->GetBuffer()->GetCapacity());
	vmem_platform_flush_cache(
		codestart, assembler->GetBuffer()->GetEndAddress<void*>(),
		codestart, assembler->GetBuffer()->GetEndAddress<void*>());
	icPtr += assembler->GetBuffer()->GetSizeInBytes();

#if 0
	Instruction* instr_start = (Instruction *)codestart;
	Instruction* instr_end = assembler->GetBuffer()->GetEndAddress<Instruction*>();
	Decoder decoder;
	Disassembler disasm;
	decoder.AppendVisitor(&disasm);
	Instruction* instr;
	for (instr = instr_start; instr < instr_end; instr += kInstructionSize) {
		decoder.Decode(instr);
		printf("arm64 arec\t %p:\t%s\n",
				   reinterpret_cast<void*>(instr),
				   disasm.GetOutput());
	}
#endif
	delete assembler;
	assembler = NULL;
}
Exemple #8
0
void TwoBit::do_predict(unsigned long ip, BranchResult& result)
{
	Disassembler disAssem;
	unsigned int type = disAssem.typeOfInst(ip, pid);

	if(InstType(type) == CALL || InstType(type) == RETURN || InstType(type) == JMP)
	{
		result.setTorF(true);
		result.setJmpAddress(branchTargetBuffer[TWO_BIT_getBTBOffset(ip)]);
	}
	else
	{
		if(state[TWO_BIT_getBTBOffset(ip)] == TT || state[TWO_BIT_getBTBOffset(ip)] == T)
		{
			result.setTorF(true);
			result.setJmpAddress(branchTargetBuffer[TWO_BIT_getBTBOffset(ip)]);
		}
		else
		{
			result.setTorF(false);
		}
	}
}
Exemple #9
0
static void test_instr(Disassembler &disassembler, const char *inBuf, size_t len, const std::string &expectedOpCode, TestHarness &harness) {
  std::ostringstream out;
  std::istringstream in(std::string(inBuf, len));

  try {
    disassembler.disassemble(&in, &out);
  } catch (...) {
    harness.assertAlways(expectedOpCode);
    return;
  }

  std::string outString = out.str();

  trim_left(outString);
  trim_right(outString);
  harness.assertTrue(outString == expectedOpCode, expectedOpCode);
}
Exemple #10
0
int main(int argc, char *argv[]) {
    std::ios_base::sync_with_stdio(true);
    std::string hostname = "localhost";
    short port = 32002;

    /* Process command-line arguments. ROSE will do most of the work, but we need to look for the --debugger switch. */
    for (int argno=1; argno<argc; argno++) {
        if (!strncmp(argv[argno], "--debugger=", 11)) {
            char *colon = strchr(argv[argno]+11, ':');
            if (colon) {
                hostname = std::string(argv[argno]+11, colon-(argv[argno]+11));
                char *rest;
                port = strtol(colon+1, &rest, 0);
                if (rest && *rest) {
                    fprintf(stderr, "invalid argument for --debugger=HOST:PORT switch\n");
                    exit(1);
                }
            } else {
                hostname = argv[argno]+11;
            }
            memmove(argv+argno, argv+argno+1, (argc-(argno+1))*sizeof(*argv));
            --argc;
            break;
        }
    }
    fprintf(stderr, "Parsing and disassembling executable...\n");
    SgProject *project = frontend(argc, argv);

    /* Connect to debugger */
    fprintf(stderr, "Connecting to debugger at %s:%d\n", hostname.c_str(), port);
    Debugger dbg(hostname, port);

    /* Choose an interpretation */
    SgAsmInterpretation *interp = isSgAsmInterpretation(NodeQuery::querySubTree(project, V_SgAsmInterpretation).back());
    assert(interp);
    Disassembler *disassembler = Disassembler::lookup(interp)->clone();
    assert(disassembler!=NULL);

    fprintf(stderr, "Setting break points...\n");
    int status __attribute__((unused)) = dbg.setbp(0, 0xffffffff);
    assert(status>=0);

    fprintf(stderr, "Starting executable...\n");
    uint64_t nprocessed = 0;

    dbg.cont(); /* Advance to the first breakpoint. */
    while (1) {
        nprocessed++;
        unsigned char insn_buf[15];
        size_t nread = dbg.memory(dbg.rip(), sizeof insn_buf, insn_buf);
        SgAsmInstruction *insn = NULL;
        try {
            insn = disassembler->disassembleOne(insn_buf, dbg.rip(), nread, dbg.rip(), NULL);
        } catch(const Disassembler::Exception &e) {
            std::cerr <<"disassembler exception: " <<e <<"\n";
        }
        if (!insn) {
            dbg.cont();
            continue;
        }
        /* Trace instructions */
        fprintf(stderr, "[%07"PRIu64"] 0x%08"PRIx64": %s\n", nprocessed, insn->get_address(), unparseInstruction(insn).c_str());

        /* Single step to cause the instruction to be executed remotely. Then compare our state with the remote state. */
        dbg.step();
    }


    exit(1); /*FIXME*/
}
Exemple #11
0
int main(int argc, char** argv) {
	try {
		std::map<std::string, std::string> engines;
		ObjectFactory<std::string, Engine> engineFactory;

		ENGINE("groovie", "Groovie", Groovie::GroovieEngine);
		ENGINE("kyra2", "Legend of Kyrandia: Hand of Fate", Kyra::Kyra2Engine);
		ENGINE("scummv6", "SCUMM v6", Scumm::v6::Scummv6Engine);

		po::options_description visible("Options");
		visible.add_options()
			("help,h", "Produce this help message.")
			("engine,e", po::value<std::string>(), "Engine the script originates from.")
			("list,l", "List the supported engines.")
			("dump-disassembly,d", po::value<std::string>()->implicit_value(""), "Dump the disassembly to a file. Leave out filename to output to stdout.")
			("dump-graph,g", po::value<std::string>()->implicit_value(""), "Output the control flow graph in dot format to a file. Leave out filename to output to stdout.")
			("only-disassembly,D", "Stops after disassembly. Implies -d.")
			("only-graph,G", "Stops after control flow graph has been generated. Implies -g.")
			("show-unreachable,u", "Show the address and contents of unreachable groups in the script.")
			("variant,v", po::value<std::string>()->default_value(""), "Tell the engine that the script is from a specific variant. To see a list of variants supported by a specific engine, use the -h option and the -e option together.")
			("no-stack-effect,s", "Leave out the stack effect when printing raw instructions.");

		po::options_description args("");
		args.add(visible).add_options()
			("input-file", po::value<std::string>(), "Input file");

		po::positional_options_description fileArg;
		fileArg.add("input-file", -1);

		po::variables_map vm;
		try {
			// FIXME: If specified as the last parameter before the input file name, -d currently requires a filename to specified. -d must be specified earlier than that if outputting to stdout.
			po::store(po::command_line_parser(argc, argv).options(args).positional(fileArg).run(), vm);
			po::notify(vm);
		} catch (std::exception& e) {
			std::cout << e.what() << std::endl;
		}

		if (vm.count("list")) {
			std::cout << "Available engines:" << "\n";

			std::map<std::string, std::string>::iterator it;
			for (it = engines.begin(); it != engines.end(); it++)
				std::cout << (*it).first << " " << (*it).second << "\n";

			return 0;
		}

		if (vm.count("help") || !vm.count("input-file")) {
			std::cout << "Usage: " << argv[0] << " [option...] file" << "\n";
			std::cout << visible << "\n";
			if (vm.count("engine") && engines.find(vm["engine"].as<std::string>()) != engines.end()) {
				Engine *engine = engineFactory.create(vm["engine"].as<std::string>());
				std::vector<std::string> variants;
				engine->getVariants(variants);
				if (variants.empty()) {
					std::cout << engines[vm["engine"].as<std::string>()] << " does not use variants.\n";
				} else {
					std::cout << "Supported variants for " << engines[vm["engine"].as<std::string>()] << ":\n";
					for (std::vector<std::string>::iterator i = variants.begin(); i != variants.end(); ++i) {
						std::cout << "  " << *i << "\n";
					}
				}
				delete engine;
				std::cout << "\n";
			}
			std::cout << "Note: If outputting to stdout, -d or -g must NOT be specified immediately before the input file.\n";
			return 1;
		}

		if (!vm.count("engine")) {
			std::cout << "Engine must be specified.\n";
			return 2;
		} else if (engines.find(vm["engine"].as<std::string>()) == engines.end()) {
			std::cout << "Unknown engine.\n";
			return 2;
		}

		if (vm.count("no-stack-effect")) {
			setOutputStackEffect(false);
		}

		Engine *engine = engineFactory.create(vm["engine"].as<std::string>());
		engine->_variant = vm["variant"].as<std::string>();
		std::string inputFile = vm["input-file"].as<std::string>();

		// Disassembly
		InstVec insts;
		Disassembler *disassembler = engine->getDisassembler(insts);
		disassembler->open(inputFile.c_str());

		disassembler->disassemble();
		if (vm.count("dump-disassembly")) {
			std::streambuf *buf;
			std::ofstream of;

			if (vm["dump-disassembly"].as<std::string>() != "") {
				of.open(vm["dump-disassembly"].as<std::string>().c_str());
				buf = of.rdbuf();
			} else {
				buf = std::cout.rdbuf();
			}
			std::ostream out(buf);
			disassembler->dumpDisassembly(out);
		}

		if (!engine->supportsCodeFlow() || vm.count("only-disassembly") || insts.empty()) {
			if (!vm.count("dump-disassembly")) {
				disassembler->dumpDisassembly(std::cout);
			}
			delete disassembler;
			delete engine;
			return 0;
		}

		delete disassembler;

		// Control flow analysis
		ControlFlow *cf = new ControlFlow(insts, engine);
		cf->createGroups();
		Graph g = cf->analyze();

		if (vm.count("dump-graph")) {
			std::streambuf *buf;
			std::ofstream of;

			if (vm["dump-graph"].as<std::string>() != "") {
				of.open(vm["dump-graph"].as<std::string>().c_str());
				buf = of.rdbuf();
			} else {
				buf = std::cout.rdbuf();
			}
			std::ostream out(buf);
			boost::write_graphviz(out, g, boost::make_label_writer(get(boost::vertex_name, g)), boost::makeArrowheadWriter(get(boost::edge_attribute, g)), GraphProperties(engine, g));
		}

		if (!engine->supportsCodeGen() || vm.count("only-graph")) {
			if (!vm.count("dump-graph")) {
				boost::write_graphviz(std::cout, g, boost::make_label_writer(get(boost::vertex_name, g)), boost::makeArrowheadWriter(get(boost::edge_attribute, g)), GraphProperties(engine, g));
			}
			delete cf;
			delete engine;
			return 0;
		}

		// Post-processing of CFG
		engine->postCFG(insts, g);

		// Code generation
		CodeGenerator *cg = engine->getCodeGenerator(std::cout);
		cg->generate(g);

		if (vm.count("show-unreachable")) {
			std::vector<GroupPtr> unreachable;
			VertexRange vr = boost::vertices(g);
			for (VertexIterator v = vr.first; v != vr.second; ++v)
			{
				GroupPtr gr = boost::get(boost::vertex_name, g, *v);
				if (gr->_stackLevel == -1)
					unreachable.push_back(gr);
			}
			if (!unreachable.empty()) {
				for (size_t i = 0; i < unreachable.size(); i++) {
					if (i == 0) {
						if (unreachable.size() == 1)
							std::cout << boost::format("\n%d unreachable group detected.\n") % unreachable.size();
						else
							std::cout << boost::format("\n%d unreachable groups detected.\n") % unreachable.size();
					}
					std::cout << "Group " << (i + 1) << ":\n";
					ConstInstIterator inst = unreachable[i]->_start;
					do {
						std::cout << *inst;
					} while (inst++ != unreachable[i]->_end);
					std::cout << "----------\n";
				}
			}
		}

		// Free memory
		delete cf;
		delete cg;
		delete engine;
	} catch (UnknownOpcodeException &e) {
		std::cerr << "ERROR: " << e.what() << "\n";
		return 3;
	} catch (std::exception &e) {
		std::cerr << "ERROR: " << e.what() << "\n";
		return 4;
	}

	return 0;
}
Error
ClangExpressionParser::DisassembleFunction (Stream &stream, ExecutionContext &exe_ctx, RecordingMemoryManager *jit_memory_manager)
{
    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
    
    const char *name = m_expr.FunctionName();
    
    Error ret;
    
    ret.Clear();
    
    lldb::addr_t func_local_addr = LLDB_INVALID_ADDRESS;
    lldb::addr_t func_remote_addr = LLDB_INVALID_ADDRESS;
    
    std::vector<JittedFunction>::iterator pos, end = m_jitted_functions.end();
    
    for (pos = m_jitted_functions.begin(); pos < end; pos++)
    {
        if (strstr(pos->m_name.c_str(), name))
        {
            func_local_addr = pos->m_local_addr;
            func_remote_addr = pos->m_remote_addr;
        }
    }
    
    if (func_local_addr == LLDB_INVALID_ADDRESS)
    {
        ret.SetErrorToGenericError();
        ret.SetErrorStringWithFormat("Couldn't find function %s for disassembly", name);
        return ret;
    }
    
    if(log)
        log->Printf("Found function, has local address 0x%llx and remote address 0x%llx", (uint64_t)func_local_addr, (uint64_t)func_remote_addr);
    
    std::pair <lldb::addr_t, lldb::addr_t> func_range;
    
    func_range = jit_memory_manager->GetRemoteRangeForLocal(func_local_addr);
    
    if (func_range.first == 0 && func_range.second == 0)
    {
        ret.SetErrorToGenericError();
        ret.SetErrorStringWithFormat("Couldn't find code range for function %s", name);
        return ret;
    }
    
    if(log)
        log->Printf("Function's code range is [0x%llx-0x%llx]", func_range.first, func_range.second);
    
    if (!exe_ctx.target)
    {
        ret.SetErrorToGenericError();
        ret.SetErrorString("Couldn't find the target");
    }
    
    lldb::DataBufferSP buffer_sp(new DataBufferHeap(func_range.second - func_remote_addr, 0));
    
    Error err;
    exe_ctx.process->ReadMemory(func_remote_addr, buffer_sp->GetBytes(), buffer_sp->GetByteSize(), err);
    
    if (!err.Success())
    {
        ret.SetErrorToGenericError();
        ret.SetErrorStringWithFormat("Couldn't read from process: %s", err.AsCString("unknown error"));
        return ret;
    }
    
    ArchSpec arch(exe_ctx.target->GetArchitecture());
    
    Disassembler *disassembler = Disassembler::FindPlugin(arch);
    
    if (disassembler == NULL)
    {
        ret.SetErrorToGenericError();
        ret.SetErrorStringWithFormat("Unable to find disassembler plug-in for %s architecture.", arch.GetArchitectureName());
        return ret;
    }
    
    if (!exe_ctx.process)
    {
        ret.SetErrorToGenericError();
        ret.SetErrorString("Couldn't find the process");
        return ret;
    }
    
    DataExtractor extractor(buffer_sp, 
                            exe_ctx.process->GetByteOrder(),
                            exe_ctx.target->GetArchitecture().GetAddressByteSize());
    
    if (log)
    {
        log->Printf("Function data has contents:");
        extractor.PutToLog (log.get(),
                            0,
                            extractor.GetByteSize(),
                            func_remote_addr,
                            16,
                            DataExtractor::TypeUInt8);
    }
    
    disassembler->DecodeInstructions (Address (NULL, func_remote_addr), extractor, 0, UINT32_MAX);
    
    InstructionList &instruction_list = disassembler->GetInstructionList();
    
    uint32_t bytes_offset = 0;
    
    for (uint32_t instruction_index = 0, num_instructions = instruction_list.GetSize(); 
         instruction_index < num_instructions; 
         ++instruction_index)
    {
        Instruction *instruction = instruction_list.GetInstructionAtIndex(instruction_index).get();
        instruction->Dump (&stream,
                           true,
                           &extractor, 
                           bytes_offset, 
                           &exe_ctx, 
                           true);
        stream.PutChar('\n');
        bytes_offset += instruction->GetByteSize();
    }
    
    return ret;
}
Exemple #13
0
int main (int argc, char *argv[]) 
{
	unsigned long ip;	

	Disassembler* disAssem = new Disassembler;
	InfoRegs infoRegs;

	struct timeval startTime;
	struct timeval endTime;

	int opt;
	unsigned long numOfLimitInst = 0;
	unsigned long numOfBranchInst = 0;
	bool limitInst = false;
	char** temp = NULL;

	bool debugOn = false;

	bool rawOn = false;
	
	bool loadOn = false;

	/*
	 ** This program is started with the PID of the target process.
	 */

	while((opt = getopt(argc, argv, ":i:drl:")) != -1)
	{
		switch(opt) {
			case 'i':
				numOfLimitInst = strtoul(optarg, temp, 0);
				limitInst = true;
				break;
			case 'd':
				debugOn = true;
				break;
			case 'r':
				rawOn = true;
				break;
			case 'l':
				loadOn = true;
				workLoadParsing(argv[optind - 1]);
				for(int k = 0; ; k++)
				{
					if(workLoad[k] == NULL)
						break;
					else
						printf("%s\n", workLoad[k]);
				}
				break;				
		}
	}

	try {
		if(!loadOn)
			throw 1;
	}
	catch (int ex) {
		errExit("Not WorkLoad");
	}

	struct sigaction act;
	act.sa_handler = int_handler;
	sigemptyset(&act.sa_mask);
	act.sa_flags = 0;
	sigaction(SIGINT, &act, NULL);

	// select profiled program
	Tracer tracer(workLoad[0], &workLoad[0]);

	try {
		tracer.traceStart();
	}
	catch(int exept) {
		errExit("trace start");
	}
	
	// set Simulator
	Simul bSim(tracer.getChildPid(), disAssem, &workLoad[0]);
	pbSim = &bSim;

	// set predictor
	bSim.setPredictor(new NotTaken());
	bSim.setPredictor(new TwoBit());
	bSim.setPredictor(new Correlate());
	bSim.setPredictor(new GShare());
	bSim.setPredictor(new GShareRet());

	gettimeofday(&startTime, NULL);
	/*
	 ** Loop now, tracing the child
	 */
	while (1) {
		/*
		 ** Ok, now we will continue the child, but set the single step bit in
		 ** the psw. This will cause the child to exeute just one instruction and
		 ** trap us again. The wait(2) catches the trap.
		 */ 		
		try {
			tracer.traceSingleStep(infoRegs);
			ip = infoRegs.getRIP();
		}
		catch(int except) {
			if(errno == ESRCH) {
				cout << "Target Process is terminated...." << endl;
				break;
			}
			errMsg("Single step");
			break;
		}
		
		try {
			bSim.runSimulation(ip);
		}
		catch(int execpt) {
			errMsg("runSimulation\n");
		}

		if(debugOn)
		{
			try {
				disAssem->showInst(ip, tracer.getChildPid());
			}
			catch(int ex) {
				errMsg("showInst");
			}
		}

		if(limitInst)
		{
			if(disAssem->typeOfInst(ip, tracer.getChildPid()))
			{
				numOfBranchInst++;

				if(numOfBranchInst >= numOfLimitInst)
					break;
			}
		}
	}
	gettimeofday(&endTime, NULL);
	long endSec = (long)endTime.tv_sec * 1000000 + endTime.tv_usec;
	long startSec = (long)startTime.tv_sec * 1000000 + startTime.tv_usec;
	bSim.setTime(endSec - startSec);

	bSim.printResult(rawOn);
	return 0;
}
Exemple #14
0
bool
Disassembler::Disassemble
(
    Debugger &debugger,
    const ArchSpec &arch,
    const ExecutionContext &exe_ctx,
    const AddressRange &disasm_range,
    uint32_t num_mixed_context_lines,
    bool show_bytes,
    Stream &strm
)
{
    if (disasm_range.GetByteSize())
    {
        Disassembler *disassembler = Disassembler::FindPlugin(arch);

        if (disassembler)
        {
            AddressRange range(disasm_range);
            
            Process *process = exe_ctx.process;

            // If we weren't passed in a section offset address range,
            // try and resolve it to something
            if (range.GetBaseAddress().IsSectionOffset() == false)
            {
                if (process && process->IsAlive())
                {
                    process->ResolveLoadAddress (range.GetBaseAddress().GetOffset(), range.GetBaseAddress());
                }
                else if (exe_ctx.target)
                {
                    exe_ctx.target->GetImages().ResolveFileAddress (range.GetBaseAddress().GetOffset(), range.GetBaseAddress());
                }
            }


            DataExtractor data;
            size_t bytes_disassembled = disassembler->ParseInstructions (&exe_ctx, range, data);
            if (bytes_disassembled == 0)
            {
                return false;
            }
            else
            {
                // We got some things disassembled...
                size_t num_instructions = disassembler->GetInstructionList().GetSize();
                uint32_t offset = 0;
                SymbolContext sc;
                SymbolContext prev_sc;
                AddressRange sc_range;
                if (num_mixed_context_lines)
                    strm.IndentMore ();


                Address addr(range.GetBaseAddress());
    
                // We extract the section to make sure we don't transition out
                // of the current section when disassembling
                const Section *addr_section = addr.GetSection();
                Module *range_module = range.GetBaseAddress().GetModule();

                for (size_t i=0; i<num_instructions; ++i)
                {
                    Disassembler::Instruction *inst = disassembler->GetInstructionList().GetInstructionAtIndex (i);
                    if (inst)
                    {
                        addr_t file_addr = addr.GetFileAddress();
                        if (addr_section == NULL || addr_section->ContainsFileAddress (file_addr) == false)
                        {
                            if (range_module)
                                range_module->ResolveFileAddress (file_addr, addr);
                            else if (exe_ctx.target)
                                exe_ctx.target->GetImages().ResolveFileAddress (file_addr, addr);
                                
                            addr_section = addr.GetSection();
                        }

                        prev_sc = sc;

                        if (addr_section)
                        {
                            Module *module = addr_section->GetModule();
                            uint32_t resolved_mask = module->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
                            if (resolved_mask)
                            {
                                if (prev_sc.function != sc.function || prev_sc.symbol != sc.symbol)
                                {
                                    if (prev_sc.function || prev_sc.symbol)
                                        strm.EOL();

                                    strm << sc.module_sp->GetFileSpec().GetFilename();
                                    
                                    if (sc.function)
                                        strm << '`' << sc.function->GetMangled().GetName();
                                    else if (sc.symbol)
                                        strm << '`' << sc.symbol->GetMangled().GetName();
                                    strm << ":\n";
                                }

                                if (num_mixed_context_lines && !sc_range.ContainsFileAddress (addr))
                                {
                                    sc.GetAddressRange (eSymbolContextEverything, sc_range);
                                        
                                    if (sc != prev_sc)
                                    {
                                        if (offset != 0)
                                            strm.EOL();

                                        sc.DumpStopContext(&strm, process, addr);

                                        if (sc.comp_unit && sc.line_entry.IsValid())
                                        {
                                            debugger.GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.line_entry.file,
                                                                                                           sc.line_entry.line,
                                                                                                           num_mixed_context_lines,
                                                                                                           num_mixed_context_lines,
                                                                                                           num_mixed_context_lines ? "->" : "",
                                                                                                           &strm);
                                        }
                                    }
                                }
                            }
                            else
                            {
                                sc.Clear();
                            }
                        }
                        if (num_mixed_context_lines)
                            strm.IndentMore ();
                        strm.Indent();
                        size_t inst_byte_size = inst->GetByteSize();
                        inst->Dump(&strm, &addr, show_bytes ? &data : NULL, offset, exe_ctx, show_bytes);
                        strm.EOL();
                        offset += inst_byte_size;
                        
                        addr.SetOffset (addr.GetOffset() + inst_byte_size);

                        if (num_mixed_context_lines)
                            strm.IndentLess ();
                    }
                    else
                    {
                        break;
                    }
                }
                if (num_mixed_context_lines)
                    strm.IndentLess ();

            }
        }
        return true;
    }
    return false;
}
Exemple #15
0
int main(int argc, char** argv)
{
    if (argc != 2 ) {
        fprintf(stderr, "Invalid input to [MIPSsim]\n");
        printf("Usage: MIPSsim [input file name]\n");
        return 1;
    }
    
//	FILE *fp = fopen(INPUTFILE, "r");
    FILE *fp =fopen(argv[1], "r");
    
	if(!fp){
        fprintf(stderr, "Can't open input file");
        return 1;
	}
    
    FILE *out_dis = fopen(OUTPUT_DIS, "w");
    
	char line[INSTRUCTION_LENGTH + 1];
	bool is_instruction = true;
	int address = INITIAL_COM_ADDR;
    char out[100];
	Disassembler disassembler;
    map<MEMORY,int> inital_mem;
    MEMORY data_addr_start = -1;
    MEMORY data_addr_end;
	
    
	while(fscanf(fp,"%s\n",&line) != -1){
        
		assert(strlen(line) == INSTRUCTION_LENGTH);
        
		if(is_instruction){
			char head[3] = {line[0],line[1]};
            
			if(strcmp(head, "01") == 0){
                disassembler.disassemble(1, address, line, out);

                fprintf(out_dis, "%s\n",out);
                //printf("%s\n", out);
				if(strcmp(line, BREAK_CODE) == 0)
					is_instruction = false;
			}
			else if (strcmp(head, "11") == 0)
            {
				disassembler.disassemble(2, address, line, out);
                //printf("%s\n", out);
                fprintf(out_dis, "%s\n",out);
            }
		}
		else {
            //printf("%s\t%d\t%d\n",line,address,disassembler.ImmediateTransform(line,INSTRUCTION_LENGTH));
            int num = disassembler.SignedImmediateTransform(line,INSTRUCTION_LENGTH);
			fprintf(out_dis,"%s\t%d\t%d\n",line,address, num);
            inital_mem[address] = num;
            
            if (data_addr_start == -1) {
                data_addr_start = address;
            }
		}
        
		address += 4;
	}
    
    data_addr_end = address - 4;

    
//    for (map<MEMORY, char*>::iterator it = disassembler.result.begin(); it != disassembler.result.end(); it++) {
//        printf("%d:%s\n", it->first, it->second);
//    }
    
	fclose(fp);
    fclose(out_dis);
    
    //simulation
    Console console(INITIAL_COM_ADDR, data_addr_start/4,data_addr_end/4, OUTPUT_SIM);
    
    map<MEMORY, int>::iterator it;
    for (it = inital_mem.begin(); it != inital_mem.end(); it++) {
        console.memory_set(it->first/4, it->second);
    }
    
    while (console.PC != FLAG_COM_ADDR) {
        console.execute(disassembler.result[console.PC]);
//        printf("%d\n", console.PC);
    }
}
		virtual bool PostInit() override
		{
			auto func_base = (uintptr_t)this->GetFuncAddr();
			
			auto l_is_call_to_addr = [](const auto& insn, void *addr){
				if (insn.ID() != X86_INS_CALL) return false;
				
				auto operands = insn.Operands();
				if (operands.size() != 1) return false;
				
				auto op0 = operands[0];
				if (op0.Type() != X86_OP_IMM || op0.Imm_U32() != (uintptr_t)addr) return false;
				
				return true;
			};
			
			auto l_is_push_imm32_arg = [](const auto& insn, uint32_t esp_off, uint32_t imm_val){
				if (insn.ID() != X86_INS_MOV) return false;
				
				auto operands = insn.Operands();
				if (operands.size() != 2) return false;
				
				auto op0 = operands[0];
				if (op0.Type() != X86_OP_MEM || op0.Size() != 4 || op0.Mem_Seg() != X86_REG_INVALID ||
					op0.Mem_Base() != X86_REG_ESP || op0.Mem_Index() != X86_REG_INVALID || op0.Mem_Disp() != esp_off) return false;
				
				auto op1 = operands[1];
				if (op1.Type() != X86_OP_IMM || op1.Size() != 4 || op1.Imm_U32() != imm_val) return false;
				
				return true;
			};
			
			auto l_is_test_al = [](const auto& insn){
				if (insn.ID() != X86_INS_TEST) return false;
				
				auto operands = insn.Operands();
				if (operands.size() != 2) return false;
				
				auto op0 = operands[0];
				if (op0.Type() != X86_OP_REG || op0.Reg() != X86_REG_AL) return false;
				
				auto op1 = operands[1];
				if (op1.Type() != X86_OP_REG || op1.Reg() != X86_REG_AL) return false;
				
				return true;
			};
			
			auto l_is_jcc_imm = [](const auto& insn){
				switch (insn.ID()) {
				case X86_INS_JAE:
				case X86_INS_JA:
				case X86_INS_JBE:
				case X86_INS_JB:
				case X86_INS_JE:
				case X86_INS_JGE:
				case X86_INS_JG:
				case X86_INS_JLE:
				case X86_INS_JL:
				case X86_INS_JNE:
				case X86_INS_JNO:
				case X86_INS_JNP:
				case X86_INS_JNS:
				case X86_INS_JO:
				case X86_INS_JP:
				case X86_INS_JS:
					break;
				default:
					return false;
				}
				
				auto operands = insn.Operands();
				if (operands.size() != 1) return false;
				
				auto op0 = operands[0];
				if (op0.Type() != X86_OP_IMM) return false;
				
				return true;
			};
			
			void *call_target = AddrManager::GetAddr("CTFPlayer::IsPlayerClass");
			if (call_target == nullptr) return false;
			
			Disassembler<true> disasm;
			auto result = disasm.Disassemble(func_base, s_DisasmLimit);
			
			auto it_arg4 = result.end();
			auto it_call = result.end();
			auto it_test = result.end();
			auto it_jcc  = result.end();
			
			for (auto i = result.begin(); i != result.end(); ++i) {
			//	auto insn = *i;
			//	uintptr_t off = insn.Addr() - func_base;
				
			//	if (off >= 0x5e2 && off < 0x600) {
			//		DevMsg("\n+0x%03x: %s %s\n", off, insn.MnemonicStr(), insn.OperandStr());
			//		
			//		DevMsg("Bytes:");
			//		for (auto byte : insn.Bytes()) {
			//			DevMsg(" %02X", byte);
			//		}
			//		DevMsg("\n");
			//	}
				
				/* find the call to CTFPlayer::IsPlayerClass */
				if (l_is_call_to_addr(*i, call_target)) {
					it_call = i;
					DevMsg("Found call @ +0x%03x\n", (*it_call).Addr() - func_base);
					
					for (auto j = i - 1; j >= i - 4 && j != result.begin(); --j) {
						if (it_arg4 == result.end() && l_is_push_imm32_arg(*j, 0x4, TF_CLASS_ENGINEER)) {
							it_arg4 = j;
							DevMsg("Found arg4 @ +0x%03x\n", (*it_arg4).Addr() - func_base);
						}
					}
					
					for (auto j = i + 1; j <= i + 1 && j != result.end(); ++j) {
						if (it_test == result.end() && l_is_test_al(*j)) {
							it_test = j;
							DevMsg("Found test @ +0x%03x\n", (*it_test).Addr() - func_base);
						}
					}
					
					for (auto j = i + 2; j <= i + 2 && j != result.end(); ++j) {
						if (it_jcc == result.end() && l_is_jcc_imm(*j)) {
							it_jcc = j;
							DevMsg("Found jcc @ +0x%03x\n", (*it_jcc).Addr() - func_base);
						}
					}
				}
			}
			
		#if 0
			bool result = disasm.IterateRange(this->GetFuncAddr(), s_DisasmLimit, [=](const InstructionDetailed& insn){
				uint32_t off = insn.Addr() - (uintptr_t)this->GetFuncAddr();
				if (off >= 0x5e2 && off < 0x600) {
					DevMsg("\n+0x%03x: %s %s\n", off, insn.MnemonicStr(), insn.OperandStr());
					
					DevMsg("Bytes:");
					for (auto byte : insn.Bytes()) {
						DevMsg(" %02X", byte);
					}
					DevMsg("\n");
					
					
				}
				
				/*
				DevMsg("Insn @ %s+0x%03x: mnemonic '%s' opcode '%s'\n",
					this->GetFuncName(), (insn.Addr() - (uintptr_t)this->GetFuncAddr()),
					insn.MnemonicStr(), insn.OperandStr());
				
				if (insn.ID() != X86_INS_CALL) return true;
				
				DevMsg("Call @ %s+0x%03x: mnemonic '%s' opcode '%s'\n",
					this->GetFuncName(), (insn.Addr() - (uintptr_t)this->GetFuncAddr()),
					insn.MnemonicStr(), insn.OperandStr());
				DevMsg("Bytes:");
				for (auto byte : insn.Bytes()) {
					DevMsg(" %02X", byte);
				}
				DevMsg("\n");*/
				
				return true;
				
				// TODO: return false if we find what we're looking for
				// also set m_bFound
				// also set m_FuncOff
				// also set up m_Buf and m_Mask
			});
			
			DevMsg("PostInit: result is %d, error is '%s'\n", result, disasm.ErrorString());
		#endif
			
			// TODO: return false upon failure
			return true;
		}
void ThreadPlanAssemblyTracer::Log() {
  Stream *stream = GetLogStream();

  if (!stream)
    return;

  RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();

  lldb::addr_t pc = reg_ctx->GetPC();
  ProcessSP process_sp(m_thread.GetProcess());
  Address pc_addr;
  bool addr_valid = false;
  uint8_t buffer[16] = {0}; // Must be big enough for any single instruction
  addr_valid = process_sp->GetTarget().GetSectionLoadList().ResolveLoadAddress(
      pc, pc_addr);

  pc_addr.Dump(stream, &m_thread, Address::DumpStyleResolvedDescription,
               Address::DumpStyleModuleWithFileAddress);
  stream->PutCString(" ");

  Disassembler *disassembler = GetDisassembler();
  if (disassembler) {
    Status err;
    process_sp->ReadMemory(pc, buffer, sizeof(buffer), err);

    if (err.Success()) {
      DataExtractor extractor(buffer, sizeof(buffer),
                              process_sp->GetByteOrder(),
                              process_sp->GetAddressByteSize());

      bool data_from_file = false;
      if (addr_valid)
        disassembler->DecodeInstructions(pc_addr, extractor, 0, 1, false,
                                         data_from_file);
      else
        disassembler->DecodeInstructions(Address(pc), extractor, 0, 1, false,
                                         data_from_file);

      InstructionList &instruction_list = disassembler->GetInstructionList();
      const uint32_t max_opcode_byte_size =
          instruction_list.GetMaxOpcocdeByteSize();

      if (instruction_list.GetSize()) {
        const bool show_bytes = true;
        const bool show_address = true;
        Instruction *instruction =
            instruction_list.GetInstructionAtIndex(0).get();
        const FormatEntity::Entry *disassemble_format =
            m_thread.GetProcess()
                ->GetTarget()
                .GetDebugger()
                .GetDisassemblyFormat();
        instruction->Dump(stream, max_opcode_byte_size, show_address,
                          show_bytes, nullptr, nullptr, nullptr,
                          disassemble_format, 0);
      }
    }
  }

  const ABI *abi = process_sp->GetABI().get();
  TypeFromUser intptr_type = GetIntPointerType();

  if (abi && intptr_type.IsValid()) {
    ValueList value_list;
    const int num_args = 1;

    for (int arg_index = 0; arg_index < num_args; ++arg_index) {
      Value value;
      value.SetValueType(Value::eValueTypeScalar);
      //            value.SetContext (Value::eContextTypeClangType,
      //            intptr_type.GetOpaqueQualType());
      value.SetCompilerType(intptr_type);
      value_list.PushValue(value);
    }

    if (abi->GetArgumentValues(m_thread, value_list)) {
      for (int arg_index = 0; arg_index < num_args; ++arg_index) {
        stream->Printf(
            "\n\targ[%d]=%llx", arg_index,
            value_list.GetValueAtIndex(arg_index)->GetScalar().ULongLong());

        if (arg_index + 1 < num_args)
          stream->PutCString(", ");
      }
    }
  }

  RegisterValue reg_value;
  for (uint32_t reg_num = 0, num_registers = reg_ctx->GetRegisterCount();
       reg_num < num_registers; ++reg_num) {
    const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_num);
    if (reg_ctx->ReadRegister(reg_info, reg_value)) {
      assert(reg_num < m_register_values.size());
      if (m_register_values[reg_num].GetType() == RegisterValue::eTypeInvalid ||
          reg_value != m_register_values[reg_num]) {
        if (reg_value.GetType() != RegisterValue::eTypeInvalid) {
          stream->PutCString("\n\t");
          reg_value.Dump(stream, reg_info, true, false, eFormatDefault);
        }
      }
      m_register_values[reg_num] = reg_value;
    }
  }
  stream->EOL();
  stream->Flush();
}
Exemple #18
0
ISADisassembler::ISADisassembler(Disassembler& _disassembler, cxuint outBufSize)
        : disassembler(_disassembler), startOffset(0), labelStartOffset(0),
          dontPrintLabelsAfterCode(false), output(outBufSize, _disassembler.getOutput())
{ }