brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.5 KiB · 985deb8 Raw
299 lines · python
1#!/usr/bin/env python2 3# ----------------------------------------------------------------------4# Be sure to add the python path that points to the LLDB shared library.5#6# # To use this in the embedded python interpreter using "lldb" just7# import it with the full path using the "command script import"8# command9#   (lldb) command script import /path/to/cmdtemplate.py10# ----------------------------------------------------------------------11 12import platform13import os14import re15import sys16import subprocess17 18try:19    # Just try for LLDB in case PYTHONPATH is already correctly setup20    import lldb21except ImportError:22    lldb_python_dirs = list()23    # lldb is not in the PYTHONPATH, try some defaults for the current platform24    platform_system = platform.system()25    if platform_system == "Darwin":26        # On Darwin, try the currently selected Xcode directory27        xcode_dir = subprocess.check_output("xcode-select --print-path", shell=True)28        if xcode_dir:29            lldb_python_dirs.append(30                os.path.realpath(31                    xcode_dir + "/../SharedFrameworks/LLDB.framework/Resources/Python"32                )33            )34            lldb_python_dirs.append(35                xcode_dir + "/Library/PrivateFrameworks/LLDB.framework/Resources/Python"36            )37        lldb_python_dirs.append(38            "/System/Library/PrivateFrameworks/LLDB.framework/Resources/Python"39        )40    success = False41    for lldb_python_dir in lldb_python_dirs:42        if os.path.exists(lldb_python_dir):43            if not (sys.path.__contains__(lldb_python_dir)):44                sys.path.append(lldb_python_dir)45                try:46                    import lldb47                except ImportError:48                    pass49                else:50                    print('imported lldb from: "%s"' % (lldb_python_dir))51                    success = True52                    break53    if not success:54        print(55            "error: couldn't locate the 'lldb' module, please set PYTHONPATH correctly"56        )57        sys.exit(1)58 59import optparse60import shlex61import string62import struct63import time64 65 66def append_data_callback(option, opt_str, value, parser):67    if opt_str == "--uint8":68        int8 = int(value, 0)69        parser.values.data += struct.pack("1B", int8)70    if opt_str == "--uint16":71        int16 = int(value, 0)72        parser.values.data += struct.pack("1H", int16)73    if opt_str == "--uint32":74        int32 = int(value, 0)75        parser.values.data += struct.pack("1I", int32)76    if opt_str == "--uint64":77        int64 = int(value, 0)78        parser.values.data += struct.pack("1Q", int64)79    if opt_str == "--int8":80        int8 = int(value, 0)81        parser.values.data += struct.pack("1b", int8)82    if opt_str == "--int16":83        int16 = int(value, 0)84        parser.values.data += struct.pack("1h", int16)85    if opt_str == "--int32":86        int32 = int(value, 0)87        parser.values.data += struct.pack("1i", int32)88    if opt_str == "--int64":89        int64 = int(value, 0)90        parser.values.data += struct.pack("1q", int64)91 92 93def create_memfind_options():94    usage = "usage: %prog [options] STARTADDR [ENDADDR]"95    description = """This command can find data in a specified address range.96Options are used to specify the data that is to be looked for and the options97can be specified multiple times to look for longer streams of data.98"""99    parser = optparse.OptionParser(description=description, prog="memfind", usage=usage)100    parser.add_option(101        "-s",102        "--size",103        type="int",104        metavar="BYTESIZE",105        dest="size",106        help="Specify the byte size to search.",107        default=0,108    )109    parser.add_option(110        "--int8",111        action="callback",112        callback=append_data_callback,113        type="string",114        metavar="INT",115        dest="data",116        help="Specify a 8 bit signed integer value to search for in memory.",117        default="",118    )119    parser.add_option(120        "--int16",121        action="callback",122        callback=append_data_callback,123        type="string",124        metavar="INT",125        dest="data",126        help="Specify a 16 bit signed integer value to search for in memory.",127        default="",128    )129    parser.add_option(130        "--int32",131        action="callback",132        callback=append_data_callback,133        type="string",134        metavar="INT",135        dest="data",136        help="Specify a 32 bit signed integer value to search for in memory.",137        default="",138    )139    parser.add_option(140        "--int64",141        action="callback",142        callback=append_data_callback,143        type="string",144        metavar="INT",145        dest="data",146        help="Specify a 64 bit signed integer value to search for in memory.",147        default="",148    )149    parser.add_option(150        "--uint8",151        action="callback",152        callback=append_data_callback,153        type="string",154        metavar="INT",155        dest="data",156        help="Specify a 8 bit unsigned integer value to search for in memory.",157        default="",158    )159    parser.add_option(160        "--uint16",161        action="callback",162        callback=append_data_callback,163        type="string",164        metavar="INT",165        dest="data",166        help="Specify a 16 bit unsigned integer value to search for in memory.",167        default="",168    )169    parser.add_option(170        "--uint32",171        action="callback",172        callback=append_data_callback,173        type="string",174        metavar="INT",175        dest="data",176        help="Specify a 32 bit unsigned integer value to search for in memory.",177        default="",178    )179    parser.add_option(180        "--uint64",181        action="callback",182        callback=append_data_callback,183        type="string",184        metavar="INT",185        dest="data",186        help="Specify a 64 bit unsigned integer value to search for in memory.",187        default="",188    )189    return parser190 191 192def memfind_command(debugger, command, result, dict):193    # Use the Shell Lexer to properly parse up command options just like a194    # shell would195    command_args = shlex.split(command)196    parser = create_memfind_options()197    (options, args) = parser.parse_args(command_args)198    # try:199    #     (options, args) = parser.parse_args(command_args)200    # except:201    #     # if you don't handle exceptions, passing an incorrect argument to the OptionParser will cause LLDB to exit202    #     # (courtesy of OptParse dealing with argument errors by throwing SystemExit)203    #     result.SetStatus (lldb.eReturnStatusFailed)204    #     print >>result, "error: option parsing failed" # returning a string is the same as returning an error whose description is the string205    #     return206    memfind(debugger.GetSelectedTarget(), options, args, result)207 208 209def print_error(str, show_usage, result):210    print(str, file=result)211    if show_usage:212        print(create_memfind_options().format_help(), file=result)213 214 215def memfind(target, options, args, result):216    num_args = len(args)217    start_addr = 0218    if num_args == 1:219        if options.size > 0:220            print_error(221                "error: --size must be specified if there is no ENDADDR argument",222                True,223                result,224            )225            return226        start_addr = int(args[0], 0)227    elif num_args == 2:228        if options.size != 0:229            print_error(230                "error: --size can't be specified with an ENDADDR argument",231                True,232                result,233            )234            return235        start_addr = int(args[0], 0)236        end_addr = int(args[1], 0)237        if start_addr >= end_addr:238            print_error(239                "error: inavlid memory range [%#x - %#x)" % (start_addr, end_addr),240                True,241                result,242            )243            return244        options.size = end_addr - start_addr245    else:246        print_error("error: memfind takes 1 or 2 arguments", True, result)247        return248 249    if not options.data:250        print("error: no data specified to search for", file=result)251        return252 253    if not target:254        print("error: invalid target", file=result)255        return256    process = target.process257    if not process:258        print("error: invalid process", file=result)259        return260 261    error = lldb.SBError()262    bytes = process.ReadMemory(start_addr, options.size, error)263    if error.Success():264        num_matches = 0265        print(266            "Searching memory range [%#x - %#x) for" % (start_addr, end_addr),267            end=" ",268            file=result,269        )270        for byte in options.data:271            print("%2.2x" % ord(byte), end=" ", file=result)272        print(file=result)273 274        match_index = string.find(bytes, options.data)275        while match_index != -1:276            num_matches = num_matches + 1277            print(278                "%#x: %#x + %u" % (start_addr + match_index, start_addr, match_index),279                file=result,280            )281            match_index = string.find(bytes, options.data, match_index + 1)282 283        if num_matches == 0:284            print("error: no matches found", file=result)285    else:286        print("error: %s" % (error.GetCString()), file=result)287 288 289if __name__ == "__main__":290    print(291        "error: this script is designed to be used within the embedded script interpreter in LLDB"292    )293 294 295def __lldb_init_module(debugger, internal_dict):296    memfind_command.__doc__ = create_memfind_options().format_help()297    debugger.HandleCommand("command script add -o -f memory.memfind_command memfind")298    print('"memfind" command installed, use the "--help" option for detailed help')299