Page 1 of 1

[Windows] Scan-Memory

Posted: Tue Nov 01, 2022 1:31 pm
by Mijikai
Scan memory (checks access rights and combines regions).

Code & Example (PB 6.0):

Code: Select all

EnableExplicit

Import "kernel32.lib"
  GetModuleInformation_.i(hProcess.i,hModule.i,*lpmodinfo,cb.i) As "GetModuleInformation"
EndImport

Structure MEMORY_REGION_STRUCT
  *address
  size.i
EndStructure

Procedure.i ScanMemory(Handle.i,*Buffer,BufferSize.i,*Data,DataSize.i)
  Protected mi.MODULEINFO
  Protected mbi.MEMORY_BASIC_INFORMATION
  Protected *address
  Protected *limit
  Protected flags.i
  Protected skip.i
  Protected NewList region.MEMORY_REGION_STRUCT()
  If *Buffer = #Null Or BufferSize = #Null
    If Handle = #Null
      Handle = GetModuleHandle_(#Null)
    EndIf
    If GetModuleInformation_(GetCurrentProcess_(),Handle,@mi,SizeOf(MODULEINFO)) = #Null
      ProcedureReturn #Null
    EndIf
    If *Buffer = #Null
      *Buffer = mi\lpBaseOfDll
    EndIf
    If BufferSize = #Null
      BufferSize = mi\SizeOfImage
    EndIf
  EndIf
  If DataSize <= BufferSize
    *address = *Buffer
    *limit = *Buffer + BufferSize - DataSize
    flags = #PAGE_READONLY|#PAGE_READWRITE|#PAGE_WRITECOPY|#PAGE_EXECUTE|#PAGE_EXECUTE_READ|#PAGE_EXECUTE_READWRITE|#PAGE_EXECUTE_WRITECOPY
    While VirtualQuery_(*address,@mbi,SizeOf(MEMORY_BASIC_INFORMATION))
      If mbi\State = #MEM_COMMIT And mbi\Protect & flags And Not mbi\Protect & #PAGE_GUARD
        If skip
          If AddElement(region())
            region()\address = *address
            region()\size = mbi\RegionSize
            skip = #False
          EndIf
        Else
          If ListSize(region())
            region()\size + mbi\RegionSize
          Else
            If AddElement(region())
              region()\address = *address
              region()\size = mbi\RegionSize
            EndIf
          EndIf
        EndIf
      Else
        skip = #True
      EndIf
      *address + mbi\RegionSize
      If *address > *limit
        Break
      EndIf
    Wend
    ForEach region()
      *Buffer = region()\address
      BufferSize = region()\size - DataSize
      If BufferSize > 0
        BufferSize + *Buffer
        Repeat
          If CompareMemory(*Buffer,*Data,DataSize)
            ProcedureReturn *Buffer  
          EndIf
          *Buffer + 1
        Until *Buffer > BufferSize
      EndIf
    Next
  EndIf
  ProcedureReturn #Null
EndProcedure

Procedure.i Main()
  Protected text.s
  Protected *ascii
  text = "Hello World!"
  *ascii = Ascii("Beep")
  ShowMemoryViewer(ScanMemory(#Null,@text,24,@"World",10),10)
  If *ascii
    ;ShowMemoryViewer(ScanMemory(GetModuleHandle_("kernel32.dll"),#Null,#Null,*ascii,4),4)
    FreeMemory(*ascii)  
  EndIf
  ProcedureReturn #Null
EndProcedure 

Main()

End

Re: [Windows] Scan-Memory

Posted: Wed Nov 02, 2022 8:38 pm
by Olli
Hello Mijikai,

this code feels good ! I do not have the use now, but sure it's good. And also good the "[windows]" mention : if you want to remove this mention, you could be interested by this Linux aspect.

Anyway, I appreciate your back work defining a "scan" not only as data seeker, but also as data careful seeker.

Re: [Windows] Scan-Memory

Posted: Wed Nov 02, 2022 10:18 pm
by BarryG
Thanks for the code! I'm sure I can find a use for it.