コード例 #1
0
ファイル: 115-syscall-usage.C プロジェクト: 8l/rose
/** Add edges to graph from functions that call system calls to system calls.
 *
 *  The first 1000 vertexes (0 to 999) in the graph is reserved for system calls, which is many more than the actual system
 *  calls in linux.  */
void
add_syscall_edges(DirectedGraph* G, std::vector<SgAsmFunction*>& all_functions)
{
    // Detect all system calls and add an edge from the function to the function to the system call
    for (unsigned int caller_id = 0; caller_id < all_functions.size(); ++caller_id) {
        SgAsmFunction *func = all_functions[caller_id];

        std::vector<SgAsmInstruction*> insns = SageInterface::querySubTree<SgAsmInstruction>(func);

        for (std::vector<SgAsmInstruction*>::iterator inst_it = insns.begin(); inst_it != insns.end(); ++inst_it) {
            SgAsmX86Instruction *insn = isSgAsmX86Instruction(*inst_it);
            if (insn == NULL)
                continue;

            SgAsmBlock *block = SageInterface::getEnclosingNode<SgAsmBlock>(insn);

            // On linux system calls are always interrups and all interrupts are system calls
            if (insn && block && insn->get_kind()==x86_int) {

                const SgAsmExpressionPtrList &opand_list = insn->get_operandList()->get_operands();
                SgAsmExpression *expr = opand_list.size()==1 ? opand_list[0] : NULL;

                //semantically execute the basic block to find out which sytem call was called
                if (expr && expr->variantT()==V_SgAsmIntegerValueExpression &&
                    0x80==isSgAsmIntegerValueExpression(expr)->get_value()) {

                    const SgAsmStatementPtrList &stmts = block->get_statementList();
                    size_t int_n;
                    for (int_n=0; int_n<stmts.size(); int_n++) {
                        if (isSgAsmInstruction(stmts[int_n])==insn)
                            break;
                    }

                    typedef PartialSymbolicSemantics::Policy<PartialSymbolicSemantics::State,
                                                             PartialSymbolicSemantics::ValueType> Policy;
                    typedef X86InstructionSemantics<Policy, PartialSymbolicSemantics::ValueType> Semantics;
                    Policy policy;
                    Semantics semantics(policy);

                    try {
                        semantics.processBlock(stmts, 0, int_n);
                        if (policy.readRegister<32>("eax").is_known()) {
                            int nr = policy.readRegister<32>("eax").known_value();
                            boost::add_edge(caller_id, nr, *G);
                        }
                    } catch (const Semantics::Exception&) {
                    } catch (const Policy::Exception&) {
                    }
                }
            }
        }
    }
}