Example #1
0
def main():


    pid = int(sys.argv[1])
    proc = Process(pid)


    #= info

    print "pid;", proc.get_pid()
    print "is_alive;", proc.is_alive()
    print "is_debugged;", proc.is_debugged()
    print "is_wow;", proc.is_wow64()
    print "arch;", proc.get_arch()
    print "bits;", proc.get_bits()
    print "filename:", proc.get_filename()
    print "exit_time;", proc.get_exit_time()
    print "running_time;", proc.get_running_time()
    print "service;", proc.get_services()
    print "policy;", proc.get_dep_policy()
    print "peb;", proc.get_peb()
    print "main_module;", proc.get_main_module()
    print "peb_address", proc.get_peb_address()
    print "entry_point;", proc.get_entry_point()

    print "image_base;", proc.get_image_base()
    print "image_name;", proc.get_image_name()
    print "command_line;", proc.get_command_line()
    print "environment;", proc.get_environment()
    print "handle;", proc.get_handle()

    print "resume;",proc.resume()
Example #2
0
class Main(object):
    def __init__(self, argv):
        self.argv = argv

    def parse_cmdline(self):

        # An empty command line causes the help message to be shown
        if len(self.argv) == 1:
            self.argv = self.argv + ['-h']

        # Usage string
        usage = "%prog [options] <target process IDs or names...>"
        self.parser = optparse.OptionParser(usage=usage)

        # Options to set the search method
        search = optparse.OptionGroup(
            self.parser, "What to search",
            "(at least one of these switches must be used)")
        search.add_option("-s",
                          "--string",
                          action="append",
                          metavar="VALUE",
                          help="where VALUE is case sensitive text")
        search.add_option("-i",
                          "--istring",
                          action="append",
                          metavar="VALUE",
                          help="where VALUE is case insensitive text")
        search.add_option("-x",
                          "--hexa",
                          action="append",
                          metavar="VALUE",
                          help="where VALUE is hexadecimal data")
        search.add_option("-p",
                          "--pattern",
                          action="append",
                          metavar="VALUE",
                          help="where VALUE is an hexadecimal pattern")
        self.parser.add_option_group(search)

        # Options to control the search internals
        engine = optparse.OptionGroup(self.parser, "How to search")
        engine.add_option("-m", "--memory-pages",
                          action="store", type="int", metavar="NUMBER",
                          help="maximum number of consecutive memory pages" \
                               " to read (matches larger than this won't"   \
                               " be found)         "   \
                               "[default: 2, use 0 for no limit]")
        self.parser.add_option_group(engine)

        # Options to set the output type
        output = optparse.OptionGroup(self.parser, "What to show")
        output.add_option("-v",
                          "--verbose",
                          action="store_true",
                          dest="verbose",
                          help="verbose output")
        output.add_option("-q",
                          "--quiet",
                          action="store_false",
                          dest="verbose",
                          help="brief output [default]")
        self.parser.add_option_group(output)

        # Default values
        self.parser.set_defaults(
            string=[],
            istring=[],
            hexa=[],
            pattern=[],
            regexp=[],
            memory_pages=2,
            verbose=False,
        )

        # Parse the command line and check for validity
        (self.options, self.targets) = self.parser.parse_args(self.argv)

        # Our script's filename is not a target, skip it
        self.targets = self.targets[1:]

        # Fail if no search query was entered
        if not self.options.string  and \
           not self.options.istring and \
           not self.options.hexa    and \
           not self.options.pattern:
            self.parser.error("at least one search switch must be used")

    def prepare_input(self):

        # Build the lists of search objects
        self.build_searchers_list(StringSearch)
        self.build_searchers_list(TextSearch)
        self.build_searchers_list(HexSearch)
        self.build_searchers_list(PatternSearch)

        # Build the list of target pids
        self.build_targets_list()

    def build_searchers_list(self, cls):
        searchers = getattr(self.options, cls.name)
        for index in range(len(searchers)):
            try:
                searchers[index] = cls(searchers[index], index)
            except Exception as e:
                msg = cls.init_error_msg(index, searchers[index], e)
                self.parser.error(msg)

    def build_targets_list(self):

        # Take a process snapshot
        self.system = System()
        self.system.request_debug_privileges()
        self.system.scan_processes()

        # If no targets were given, search on all processes
        if not self.targets:
            self.targets = self.system.get_process_ids()

        # If targets were given, search only on those processes
        else:
            expanded_targets = set()
            for token in self.targets:
                try:
                    pid = HexInput.integer(token)
                    if not self.system.has_process(pid):
                        self.parser.error("process not found: %s" % token)
                    expanded_targets.add(pid)
                except ValueError:
                    found = self.system.find_processes_by_filename(token)
                    pidlist = [process.get_pid() for (process, _) in found]
                    if not pidlist:
                        self.parser.error("process not found: %s" % token)
                    expanded_targets.update(pidlist)
            self.targets = list(expanded_targets)

        # Sort the targets list
        self.targets.sort()

    def do_search(self):

        # For each target process...
        for self.pid in self.targets:

            # Try to open the process, skip on error
            try:
                self.process = Process(self.pid)
                self.process.get_handle()
            except WindowsError:
                print("Can't open process %d, skipping" % self.pid)
                if self.options.verbose:
                    print
                continue

            # Get a list of allocated memory regions
            memory = list()
            for mbi in self.process.get_memory_map():
                if mbi.State == win32.MEM_COMMIT and \
                                            not mbi.Protect & win32.PAGE_GUARD:
                    memory.append((mbi.BaseAddress, mbi.RegionSize))

            # If no allocation limit is set,
            # read entire regions and search on them
            if self.options.memory_pages <= 0:
                for (address, size) in memory:
                    try:
                        data = self.process.read(address, size)
                    except WindowsError as e:
                        begin = HexDump.address(address)
                        end = HexDump.address(address + size)
                        msg = "Error reading %s-%s: %s"
                        msg = msg % (begin, end, str(e))
                        print(msg)
                        if self.options.verbose:
                            print
                        continue
                    self.search_block(data, address, 0)

            # If an allocation limit is set,
            # read blocks within regions to search
            else:
                step = self.system.pageSize
                size = step * self.options.memory_pages
                for (address, total_size) in memory:
                    try:
                        end = address + total_size
                        shift = 0
                        buffer = self.process.read(address,
                                                   min(size, total_size))
                        while 1:
                            self.search_block(buffer, address, shift)
                            shift = step
                            address = address + step
                            if address >= end:
                                break
                            buffer = buffer[step:]
                            buffer = buffer + self.process.read(address, step)
                    except WindowsError as e:
                        begin = HexDump.address(address)
                        end = HexDump.address(address + total_size)
                        msg = "Error reading %s-%s: %s"
                        msg = msg % (begin, end, str(e))
                        print(msg)
                        if self.options.verbose:
                            print

    def search_block(self, data, address, shift):
        self.search_block_with(self.options.string, data, address, shift)
        self.search_block_with(self.options.istring, data, address, shift)
        self.search_block_with(self.options.hexa, data, address, shift)
        self.search_block_with(self.options.pattern, data, address, shift)

    def search_block_with(self, searchers_list, data, address, shift):
        for searcher in searchers_list:
            if shift == 0:
                searcher.restart()
            else:
                searcher.shift(shift)
            while 1:
                searcher.search(data)
                if not searcher.found():
                    break
                if self.options.verbose:
                    print(searcher.message(self.pid, address - shift, data))
                    print
                else:
                    print(searcher.message(self.pid, address - shift))

    def run(self):

        # Banner
        print("Process memory finder")
        print("by Mario Vilas (mvilas at gmail.com)")
        print

        # Parse the command line
        self.parse_cmdline()

        # Prepare the input
        self.prepare_input()

        # Perform the search on the selected targets
        self.do_search()