brintos

brintos / llvm-project-archived public Read only

0
0
Text · 1.4 KiB · c18cffb Raw
55 lines · python
1#!/usr/bin/env python2 3"""A tool for looking for indirect jumps and calls in x86 binaries.4 5   Helpful to verify whether or not retpoline mitigations are catching6   all of the indirect branches in a binary and telling you which7   functions the remaining ones are in (assembly, etc).8 9   Depends on llvm-objdump being in your path and is tied to the10   dump format.11"""12 13from __future__ import print_function14 15import os16import sys17import re18import subprocess19import optparse20 21# Look for indirect calls/jmps in a binary. re: (call|jmp).*\*22def look_for_indirect(file):23    args = ["llvm-objdump"]24    args.extend(["-d"])25    args.extend([file])26 27    p = subprocess.Popen(28        args=args, stdin=None, stderr=subprocess.PIPE, stdout=subprocess.PIPE29    )30    (stdout, stderr) = p.communicate()31 32    function = ""33    for line in stdout.splitlines():34        if not line.startswith(" "):35            function = line36        result = re.search("(call|jmp).*\*", line)37        if result is not None:38            # TODO: Perhaps use cxxfilt to demangle functions?39            print(function)40            print(line)41    return42 43 44def main(args):45    # No options currently other than the binary.46    parser = optparse.OptionParser("%prog [options] <binary>")47    (opts, args) = parser.parse_args(args)48    if len(args) != 2:49        parser.error("invalid number of arguments: %s" % len(args))50    look_for_indirect(args[1])51 52 53if __name__ == "__main__":54    main(sys.argv)55