コード例 #1
0
ファイル: runRandom.C プロジェクト: Federico2014/edg4x-rose
// Run natively and return number of instructions executed and reason for termination.
static std::pair<size_t, std::string>
runNatively(const Settings &settings, const std::string &specimenName, Sawyer::Optional<rose_addr_t> initVa,
            const P2::Partitioner &partitioner, rose_addr_t randomAddress) {
    Stream debug(mlog[DEBUG]);

    BinaryDebugger debugger(specimenName);
    if (debugger.isTerminated()) {
        mlog[FATAL] <<"child " <<debugger.isAttached() <<" " <<debugger.howTerminated() <<" before we could gain control\n";
        exit(1);
    }

    // Allow child to run until we hit the desired address.
    if (initVa) {
        debugger.setBreakpoint(*initVa);
        debugger.runToBreakpoint();
        debugger.clearBreakpoint(*initVa);
        if (debugger.isTerminated()) {
            mlog[FATAL] <<"child " <<debugger.isAttached() <<" " <<debugger.howTerminated()
                        <<" without reaching " <<addrToString(*initVa) <<"\n";
            exit(1);
        }
    }
    
    // Show specimen address map so we can verify that the Linux loader used the same addresses we used.
    // We could have shown it earlier, but then we wouldn't have seen the results of dynamic linking.
    if (settings.showMaps) {
        std::cout <<"Linux loader specimen memory map:\n";
        system(("cat /proc/" + numberToString(debugger.isAttached()) + "/maps").c_str());
    }

    // Branch to the starting address
    debug <<"branching to " <<addrToString(randomAddress) <<"\n";
    debugger.executionAddress(randomAddress);

    std::string terminationReason;
    size_t nExecuted = 0;                               // number of instructions executed
    while (1) {
        // Check for and avoid system calls if necessary
        if (!settings.allowSyscalls) {
            rose_addr_t eip = debugger.executionAddress();
            SgAsmX86Instruction *insn = isSgAsmX86Instruction(partitioner.instructionProvider()[eip]);
            if (!insn || insn->isUnknown()) {
                if (settings.showInsnTrace)
                    std::cout <<"at " <<addrToString(eip) <<": " <<(insn?"no":"unknown") <<" instruction\n";
                terminationReason = "executed at " + addrToString(eip) +" which we don't know about";
                break;
            }
            if (settings.showInsnTrace)
                std::cout <<"at " <<unparseInstructionWithAddress(insn) <<"\n";
            if (insn->get_kind() == x86_int || insn->get_kind() == x86_sysenter) {
                terminationReason = "tried to execute a system call";
                break;
            }
        }

        // Single-step
        if (debug)
            debug <<"single stepping at " <<addrToString(debugger.executionAddress()) <<"\n";
        debugger.singleStep();
        if (debugger.isTerminated()) {
            terminationReason = debugger.howTerminated();
            break;
        }
        ++nExecuted;
        if (settings.maxInsns!=0 && nExecuted>=settings.maxInsns) {
            terminationReason = "reached instruction limit";
            break;
        }
    }
    debugger.terminate();
    return std::make_pair(nExecuted, terminationReason);
}