parameters: (process, pattern, minAddr = None,
                                           maxAddr = None,
                                           bufferPages = None,
                                           overlapping = False)
docstring: 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.
docstring_summary: Search for the given pattern within the process memory.
docstring_tokens: Search for the given pattern within the process memory .
function: 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)
function_tokens: 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 )