コード例 #1
0
    def extract(self, binary, logfile):
        protos = dict()
        with open(binary, 'rb') as f:
            e = ELFFile(f)
            symtable = e.get_section_by_name(".symtab")
            if not symtable:
                Log.stderr("symbole table not found")
                return protos
            for entry in symtable.iter_symbols():
                if "FUNC" in entry['st_info'].type:
                    name = entry.name
                    addr = entry["st_value"]
                    ret = entry["st_value"]
                    protos[addr] = (name, addr, ret)
            dynsym = e.get_section_by_name(".dynsym")
            reloc = e.get_section_by_name(".rela.plt")
            plt_base = e.get_section_by_name(".plt")['sh_addr']
            # Additionally add plt entries
            for idx, entry in enumerate(reloc.iter_relocations()):
                name = dynsym.get_symbol(entry['r_info_sym']).name + "@plt"
                addr = plt_base + 16 * (idx + 1)
                protos[addr] = (name, addr, addr)

        with open(logfile, "w") as f:
            for (name, entry, ret) in protos.values():
                f.write("{}:{}:{}\n".format(name, entry, ret))
コード例 #2
0
ファイル: launch.py プロジェクト: Frky/iCi
def launch_analysis(args, analysis=None):
    if analysis is None:
        analysis = args.analysis

    # Read configuration file
    tpl = Confiture("config/template.yaml")
    config = tpl.check_and_get("config/config.yaml")

    # Check if temporary repo exists
    if not os.path.exists("tmp"):
        os.makedirs("tmp")

    # Extract dwarf info
    SymExtractor().extract(args.pgm, "tmp/dwarf.txt")

    # Create Pintool object
    pintool = Pintool(
        config["pin"]["path"],
        config["pin"]["bin"],
        config["pin"]["compile-flags"],
        config["pintool"]["src"],
        config["pintool"]["obj"],
    )

    # Log file
    if args.log:
        logidir = args.log
    else:
        logdir = default_log_dir(args.pgm)

    # Compile pintool
    Log.stdout("compiling pintool")
    if not pintool.compile(analysis if analysis else args.analysis):
        Log.stdout("compilation exited with non-zero status")
        exit()
    if "oracle" in analysis:
        infile = "tmp/dwarf.txt"
    else:
        infile = None
    # Launch pintool
    Log.stdout("launching analysis on {}".format(args.pgm))
    pintool.launch(args.pgm, args.args, infile, logdir,
                   "-l true" if not args.ignore_libs else None)

    # Get results
    for an in analysis:
        Log.stdout("extracting results")
        res = Result(default_log_path(logdir, args.pgm, an))
        # Print the results
        Log.stdout("results of inference:")
        res.display()
コード例 #3
0
ファイル: res.py プロジェクト: Frky/iCi
 def __init__(self, path, name=""):
     self.__fn = dict()
     self.__name = name
     last_fn = None
     with open(path, "r") as f:
         # First line is elapsed time
         self.__time = f.readline()[:-1]
         for line in f.readlines():
             typ = line.split(":")[0]
             if typ == 'F':
                 fn = Function(*line[:-1].split(":")[1:])
                 self.__fn.setdefault(fn.iname, list())
                 self.__fn[fn.iname].append(fn)
                 last_fn = fn
             elif typ == 'I':
                 ins = Instruction(line[:-1].split(":")[1:])
                 if last_fn is not None:
                     last_fn.add_ins(ins)
             else:
                 Log.stderr("unrecognized format: {}".format(line))
コード例 #4
0
ファイル: pintool.py プロジェクト: Frky/iCi
def pintool_analysis(analysis, args):
    # Read configuration file
    tpl = Confiture("config/template.yaml")
    config = tpl.check_and_get("config/config.yaml")

    # Check if temporary repo exists
    if not os.path.exists("tmp"):
        os.makedirs("tmp")

    # Create Pintool object
    call = Pintool(
        config["pin"]["path"],
        config["pin"]["bin"],
        config["pin"]["compile-flags"],
        config["analysis"][analysis]["src"],
        config["analysis"][analysis]["obj"],
    )

    # Log file
    if args.log:
        log = args.log
    else:
        log = default_log_path(args.pgm, analysis)

    # Compile pintool
    Log.stdout("compiling pintool")
    if not call.compile():
        Log.stdout("compilation exited with non-zero status")
        exit()
    # Launch pintool
    Log.stdout("launching analysis on {}".format(args.pgm))
    call.launch(args.pgm, args.args, None, log)

    # Get results
    Log.stdout("extracting results")
    res = Result(log, analysis)
    # Print the results
    Log.stdout("results of inference:")
    res.display()
コード例 #5
0
ファイル: res.py プロジェクト: Frky/iCi
 def print_ins(self, ref, prefix="", ignore_ld=False):
     uniq = 0
     for ins in self.__ins:
         if "ld-linux" in ins.img and ignore_ld:
             continue
         # Look for the reference instruction (if exists)
         refi = None
         if ref:
             for r in ref:
                 if r.addr == ins.addr:
                     refi = r
                     break
         if refi:
             nb_catch = refi.nb_hit
         else:
             nb_catch = 0
         if nb_catch != ins.nb_hit:
             Log.stdout("{}{} [seen {}]".format(prefix, ins, nb_catch),
                        prefix="",
                        lvl=3)
             uniq += 1
     return uniq
コード例 #6
0
def diff_analysis(args):
    #     if args.file1:
    #         if not args.file2:
    #             Log.stderr("you must specify two files")
    #             exit()
    #         oracle = Result(args.file1)
    #         other = Result(args.file2)
    if not args.analysis or len(args.analysis) < 2:
        Log.stderr("you must specify at least two analysis")
        exit()
    if not args.pgm:
        Log.stderr("you must specify a program to analyze")
        exit()
    if args.run:
        lvl = Log.get_verbose()
        Log.set_verbose(0)
        launch_analysis(args)
        Log.set_verbose(lvl)
    logdir = default_log_dir(args.pgm)
    path = default_log_path(logdir, args.pgm, args.analysis[0])
    oracle = Result(path, args.analysis[0])
    for an in args.analysis[1:]:
        path = default_log_path(logdir, args.pgm, an)
        other = Result(path, an)
        if Log.get_verbose() < 3:
            Log.stdout("pgm={}".format(os.path.basename(args.pgm)),
                       lvl=1,
                       prefix="")
            Log.stdout("args={}".format(args.args), lvl=1, prefix="")
            Log.stdout("analysis1={}".format(oracle.name), lvl=1, prefix="")
            Log.stdout("time1={}".format(oracle.time), lvl=1, prefix="")
            Log.stdout("analysis2={}".format(other.name), lvl=1, prefix="")
            Log.stdout("time2={}".format(other.time), lvl=1, prefix="")
        other.diff(oracle, ignore_ld=args.ignore_ld)
コード例 #7
0
ファイル: res.py プロジェクト: Frky/iCi
 def diff(self, oracle, ignore_ld=False, no_ins=False):
     # Total number of errors
     misses = 0
     extra = 0
     # number of unique instructions causing errors
     u_misses, u_extra = 0, 0
     tot = 0
     for img, fn in oracle.fn.items():
         if "ld-linux" in img and ignore_ld:
             continue
         self.__fn.setdefault(img, list())
         Log.stdout(" | {}".format(img), prefix="", lvl=3)
         Log.stdout(" |", prefix="", lvl=3)
         for f in fn:
             g = None
             for gg in self.__fn[img]:
                 if gg.offset == f.offset:
                     g = gg
                     break
             if g is None:
                 ncalls = 0
             else:
                 ncalls = g.calls
             if ncalls < f.calls:
                 misses += (f.calls - ncalls)
                 Log.stdout(" |   (@{:012x}) {} - {} calls missed".format(
                     f.offset, f.name, f.calls - ncalls),
                            prefix="",
                            lvl=3)
                 u_misses += f.print_ins(g.ins if g else None, " |      ",
                                         ignore_ld)
             elif f.calls < ncalls:
                 extra += (ncalls - f.calls)
                 Log.stdout(" |   (@{:012x}) {} - {} extra calls".format(
                     f.offset, f.name, -f.calls + ncalls),
                            prefix="",
                            lvl=3)
                 u_extra += f.print_ins(g.ins if g else None, " |      ",
                                        ignore_ld)
             tot += f.calls
         for g in self.__fn[img]:
             f = None
             for ff in fn:
                 if ff.offset == g.offset:
                     f = ff
                     break
             if f is None:
                 extra += g.calls
                 Log.stdout(" |   (@{:012x}) {} - {} extra calls".format(
                     g.offset, g.name, g.calls),
                            prefix="",
                            lvl=3)
                 u_extra += g.print_ins(None, " |      ", ignore_ld)
         Log.stdout(" |", prefix="", lvl=3)
     Log.stdout(" | TOTAL CALLS (ORACLE): {}".format(tot), prefix="", lvl=3)
     Log.stdout(" | TOTAL MISSES: {} ({} unique instructions)".format(
         misses, u_misses),
                prefix="",
                lvl=3)
     Log.stdout(" | TOTAL EXTRA: {} ({} unique instructions)".format(
         extra, u_extra),
                prefix="",
                lvl=3)
     if Log.get_verbose() < 3:
         Log.stdout("calls={}".format(tot), prefix="", lvl=1)
         Log.stdout("misses={}".format(misses), prefix="", lvl=1)
         Log.stdout("u_misses={}".format(u_misses), prefix="", lvl=1)
         Log.stdout("extra={}".format(extra), prefix="", lvl=1)
         Log.stdout("u_extra={}".format(u_extra), prefix="", lvl=1)
コード例 #8
0
ファイル: res.py プロジェクト: Frky/iCi
 def display(self):
     tot_calls = 0
     for img, fn in self.__fn.items():
         Log.stdout(" | # {}".format(img), lvl=3, prefix="")
         for f in sorted(fn, key=lambda a: -a.calls):
             if f.calls == 0:
                 break
             Log.stdout(" | \t{}".format(f), lvl=3, prefix="")
             tot_calls += f.calls
     Log.stdout(" | ", prefix="", lvl=3)
     Log.stdout(" | TOTAL: {} calls".format(tot_calls), lvl=3, prefix="")
     # If verbose was lower than the lvl of previous messages
     if Log.get_verbose() < 3:
         # Log time
         Log.stdout("time={}".format(self.__time), lvl=1, prefix="")
         # Log summary
         Log.stdout("calls={}".format(tot_calls), lvl=1, prefix="")
コード例 #9
0
parser.add_argument('-v',
                    action="store_const",
                    const=True,
                    help="output detailed results")
parser.add_argument('-q',
                    action="store_const",
                    const=True,
                    help="quiet mode -- only output the minimum result info")
parser.add_argument('--run',
                    action="store_const",
                    const=True,
                    metavar="RUN",
                    help="Re-run instrumentations before diff")
args = parser.parse_args()

if args.v:
    Log.set_verbose(3)
if args.q:
    Log.set_verbose(1)
if args.res:
    Log.set_output(args.res)

if args.cmd[0] == "launch":
    launch_analysis(args)
elif args.cmd[0] == "diff":
    diff_analysis(args)
else:
    Log.stderr("unknown analysis: {}".format(args.analysis[0]))

Log.close()