(process, pattern, minAddr = None,
                                         maxAddr = None,
                                         bufferPages = None,
                                         overlapping = False)
Search for the given pattern within the process memory.

        @type  process: L{Process}
        @param process: Process to search.

        @type  pattern: L{Pattern}
        @param pattern: Pattern to search for.
            It must be an instance of a subclass of L{Pattern}.

            The following L{Pattern} subclasses are provided by WinAppDbg:
             - L{BytePattern}
             - L{TextPattern}
             - L{RegExpPattern}
             - L{HexPattern}

            You can also write your own subclass of L{Pattern} for customized
            searches.

        @type  minAddr: int
        @param minAddr: (Optional) Start the search at this memory address.

        @type  maxAddr: int
        @param maxAddr: (Optional) Stop the search at this memory address.

        @type  bufferPages: int
        @param bufferPages: (Optional) Number of memory pages to buffer when
            performing the search. Valid values are:
             - C{0} or C{None}:
               Automatically determine the required buffer size. May not give
               complete results for regular expressions that match variable
               sized strings.
             - C{> 0}: Set the buffer size, in memory pages.
             - C{< 0}: Disable buffering entirely. This may give you a little
               speed gain at the cost of an increased memory usage. If the
               target process has very large contiguous memory regions it may
               actually be slower or even fail. It's also the only way to
               guarantee complete results for regular expressions that match
               variable sized strings.

        @type  overlapping: bool
        @param overlapping: C{True} to allow overlapping results, C{False}
            otherwise.

            Overlapping results yield the maximum possible number of results.

            For example, if searching for "AAAA" within "AAAAAAAA" at address
            C{0x10000}, when overlapping is turned off the following matches
            are yielded::
                (0x10000, 4, "AAAA")
                (0x10004, 4, "AAAA")

            If overlapping is turned on, the following matches are yielded::
                (0x10000, 4, "AAAA")
                (0x10001, 4, "AAAA")
                (0x10002, 4, "AAAA")
                (0x10003, 4, "AAAA")
                (0x10004, 4, "AAAA")

            As you can see, the middle results are overlapping the last two.

        @rtype:  iterator of tuple( int, int, str )
        @return: An iterator of tuples. Each tuple contains the following:
             - The memory address where the pattern was found.
             - The size of the data that matches the pattern.
             - The data that matches the pattern.

        @raise WindowsError: An error occurred when querying or reading the
            process memory.
Search for the given pattern within the process memory.
Search for the given pattern within the process memory .
def search_process(process, pattern, minAddr = None,
                                         maxAddr = None,
                                         bufferPages = None,
                                         overlapping = False):
        """
        Search for the given pattern within the process memory.

        @type  process: L{Process}
        @param process: Process to search.

        @type  pattern: L{Pattern}
        @param pattern: Pattern to search for.
            It must be an instance of a subclass of L{Pattern}.

            The following L{Pattern} subclasses are provided by WinAppDbg:
             - L{BytePattern}
             - L{TextPattern}
             - L{RegExpPattern}
             - L{HexPattern}

            You can also write your own subclass of L{Pattern} for customized
            searches.

        @type  minAddr: int
        @param minAddr: (Optional) Start the search at this memory address.

        @type  maxAddr: int
        @param maxAddr: (Optional) Stop the search at this memory address.

        @type  bufferPages: int
        @param bufferPages: (Optional) Number of memory pages to buffer when
            performing the search. Valid values are:
             - C{0} or C{None}:
               Automatically determine the required buffer size. May not give
               complete results for regular expressions that match variable
               sized strings.
             - C{> 0}: Set the buffer size, in memory pages.
             - C{< 0}: Disable buffering entirely. This may give you a little
               speed gain at the cost of an increased memory usage. If the
               target process has very large contiguous memory regions it may
               actually be slower or even fail. It's also the only way to
               guarantee complete results for regular expressions that match
               variable sized strings.

        @type  overlapping: bool
        @param overlapping: C{True} to allow overlapping results, C{False}
            otherwise.

            Overlapping results yield the maximum possible number of results.

            For example, if searching for "AAAA" within "AAAAAAAA" at address
            C{0x10000}, when overlapping is turned off the following matches
            are yielded::
                (0x10000, 4, "AAAA")
                (0x10004, 4, "AAAA")

            If overlapping is turned on, the following matches are yielded::
                (0x10000, 4, "AAAA")
                (0x10001, 4, "AAAA")
                (0x10002, 4, "AAAA")
                (0x10003, 4, "AAAA")
                (0x10004, 4, "AAAA")

            As you can see, the middle results are overlapping the last two.

        @rtype:  iterator of tuple( int, int, str )
        @return: An iterator of tuples. Each tuple contains the following:
             - The memory address where the pattern was found.
             - The size of the data that matches the pattern.
             - The data that matches the pattern.

        @raise WindowsError: An error occurred when querying or reading the
            process memory.
        """

        # Do some namespace lookups of symbols we'll be using frequently.
        MEM_COMMIT = win32.MEM_COMMIT
        PAGE_GUARD = win32.PAGE_GUARD
        page = MemoryAddresses.pageSize
        read = pattern.read
        find = pattern.find

        # Calculate the address range.
        if minAddr is None:
            minAddr = 0
        if maxAddr is None:
            maxAddr = win32.LPVOID(-1).value  # XXX HACK

        # Calculate the buffer size from the number of pages.
        if bufferPages is None:
            try:
                size = MemoryAddresses.\
                            align_address_to_page_end(len(pattern)) + page
            except NotImplementedError:
                size = None
        elif bufferPages > 0:
                size = page * (bufferPages + 1)
        else:
                size = None

        # Get the memory map of the process.
        memory_map = process.iter_memory_map(minAddr, maxAddr)

        # Perform search with buffering enabled.
        if size:

            # Loop through all memory blocks containing data.
            buffer     = "" # buffer to hold the memory data
            prev_addr  = 0  # previous memory block address
            last       = 0  # position of the last match
            delta      = 0  # delta of last read address and start of buffer
            for mbi in memory_map:

                # Skip blocks with no data to search on.
                if not mbi.has_content():
                    continue

                # Get the address and size of this block.
                address    = mbi.BaseAddress    # current address to search on
                block_size = mbi.RegionSize     # total size of the block
                if address >= maxAddr:
                    break
                end = address + block_size      # end address of the block

                # If the block is contiguous to the previous block,
                # coalesce the new data in the buffer.
                if delta and address == prev_addr:
                    buffer += read(process, address, page)

                # If not, clear the buffer and read new data.
                else:
                    buffer = read(process, address, min(size, block_size))
                    last   = 0
                    delta  = 0

                # Search for the pattern in this block.
                while 1:

                    # Yield each match of the pattern in the buffer.
                    pos, length = find(buffer, last)
                    while pos >= last:
                        match_addr = address + pos - delta
                        if minAddr <= match_addr < maxAddr:
                            result = pattern.found(
                                            match_addr, length,
                                            buffer [ pos : pos + length ] )
                            if result is not None:
                                yield result
                        if overlapping:
                            last = pos + 1
                        else:
                            last = pos + length
                        pos, length = find(buffer, last)

                    # Advance to the next page.
                    address    = address + page
                    block_size = block_size - page
                    prev_addr  = address

                    # Fix the position of the last match.
                    last = last - page
                    if last < 0:
                        last = 0

                    # Remove the first page in the buffer.
                    buffer = buffer[ page : ]
                    delta  = page

                    # If we haven't reached the end of the block yet,
                    # read the next page in the block and keep seaching.
                    if address < end:
                        buffer = buffer + read(process, address, page)

                    # Otherwise, we're done searching this block.
                    else:
                        break

        # Perform search with buffering disabled.
        else:

            # Loop through all memory blocks containing data.
            for mbi in memory_map:

                # Skip blocks with no data to search on.
                if not mbi.has_content():
                    continue

                # Get the address and size of this block.
                address    = mbi.BaseAddress
                block_size = mbi.RegionSize
                if address >= maxAddr:
                    break;

                # Read the whole memory region.
                buffer = process.read(address, block_size)

                # Search for the pattern in this region.
                pos, length = find(buffer)
                last = 0
                while pos >= last:
                    match_addr = address + pos
                    if minAddr <= match_addr < maxAddr:
                        result = pattern.found(
                                        match_addr, length,
                                        buffer [ pos : pos + length ] )
                        if result is not None:
                            yield result
                    if overlapping:
                        last = pos + 1
                    else:
                        last = pos + length
                    pos, length = find(buffer, last)
def search_process ( process , pattern , minAddr = None , maxAddr = None , bufferPages = None , overlapping = False ) : # Do some namespace lookups of symbols we'll be using frequently. MEM_COMMIT = win32 . MEM_COMMIT PAGE_GUARD = win32 . PAGE_GUARD page = MemoryAddresses . pageSize read = pattern . read find = pattern . find # Calculate the address range. if minAddr is None : minAddr = 0 if maxAddr is None : maxAddr = win32 . LPVOID ( - 1 ) . value # XXX HACK # Calculate the buffer size from the number of pages. if bufferPages is None : try : size = MemoryAddresses . align_address_to_page_end ( len ( pattern ) ) + page except NotImplementedError : size = None elif bufferPages > 0 : size = page * ( bufferPages + 1 ) else : size = None # Get the memory map of the process. memory_map = process . iter_memory_map ( minAddr , maxAddr ) # Perform search with buffering enabled. if size : # Loop through all memory blocks containing data. buffer = "" # buffer to hold the memory data prev_addr = 0 # previous memory block address last = 0 # position of the last match delta = 0 # delta of last read address and start of buffer for mbi in memory_map : # Skip blocks with no data to search on. if not mbi . has_content ( ) : continue # Get the address and size of this block. address = mbi . BaseAddress # current address to search on block_size = mbi . RegionSize # total size of the block if address >= maxAddr : break end = address + block_size # end address of the block # If the block is contiguous to the previous block, # coalesce the new data in the buffer. if delta and address == prev_addr : buffer += read ( process , address , page ) # If not, clear the buffer and read new data. else : buffer = read ( process , address , min ( size , block_size ) ) last = 0 delta = 0 # Search for the pattern in this block. while 1 : # Yield each match of the pattern in the buffer. pos , length = find ( buffer , last ) while pos >= last : match_addr = address + pos - delta if minAddr <= match_addr < maxAddr : result = pattern . found ( match_addr , length , buffer [ pos : pos + length ] ) if result is not None : yield result if overlapping : last = pos + 1 else : last = pos + length pos , length = find ( buffer , last ) # Advance to the next page. address = address + page block_size = block_size - page prev_addr = address # Fix the position of the last match. last = last - page if last < 0 : last = 0 # Remove the first page in the buffer. buffer = buffer [ page : ] delta = page # If we haven't reached the end of the block yet, # read the next page in the block and keep seaching. if address < end : buffer = buffer + read ( process , address , page ) # Otherwise, we're done searching this block. else : break # Perform search with buffering disabled. else : # Loop through all memory blocks containing data. for mbi in memory_map : # Skip blocks with no data to search on. if not mbi . has_content ( ) : continue # Get the address and size of this block. address = mbi . BaseAddress block_size = mbi . RegionSize if address >= maxAddr : break # Read the whole memory region. buffer = process . read ( address , block_size ) # Search for the pattern in this region. pos , length = find ( buffer ) last = 0 while pos >= last : match_addr = address + pos if minAddr <= match_addr < maxAddr : result = pattern . found ( match_addr , length , buffer [ pos : pos + length ] ) if result is not None : yield result if overlapping : last = pos + 1 else : last = pos + length pos , length = find ( buffer , last )