Reading a structure using a pointer

new_learner0

Member
Joined
May 3, 2011
Messages
7
Programming Experience
Beginner
Hey All,
I am trying to use VirtualQueryEx to read the memory of a process (first instance of notepad in this case). This function returns a pointer to the MEMORY_BASIC_INFORMATION structure. I am trying to read this structure. But everytime I try to access a member of the structure, I get a zero, which indicates I am messing something up. I am copying my code here.

Any help will be greatly appreciated.

-Coder_in_distress

VB.NET:
Imports System.Runtime.InteropServices

Module Module1

    Declare Auto Sub GetSystemInfo Lib "kernel32.dll" (ByRef Info As SYSTEM_INFO)
    Public Declare Function VirtualQueryEx Lib "kernel32" Alias "VirtualQueryEx" (ByVal hProcess As IntPtr, ByVal lpAddress As IntPtr, <Out()> ByVal lpBuffer As MEMORY_BASIC_INFORMATION, ByVal dwLength As Long) As Long
    End Function

    Structure SYSTEM_INFO
        Dim ProcessorArchitecture As Int16
        Dim Reserved As Int16
        Dim PageSize As Int32
        Dim MinAppAddress As Int32
        Dim MaxAppAddress As Int32
        Dim ActiveProcMask As Int32
        Dim NumberOfProcessors As Int32
        Dim ProcessorType As Int32
        Dim AllocGranularity As Int32
        Dim ProcessorLevel As Int32
        Dim ProcessorRevision As Int32
    End Structure
    Public Structure MEMORY_BASIC_INFORMATION
        Dim BaseAddress As IntPtr
        Dim AllocationBase As IntPtr
        Dim AllocationProtect As UInt32
        Dim RegionSize As IntPtr
        Dim State As UInt32
        Dim Protect As UInt32
        Dim lType As UInt32
    End Structure

    Sub Main()
        Dim ProcessToReadFrom As Process = Process.GetProcessesByName("notepad")(0)
        Dim prHandle = ProcessToReadFrom.Handle

        PrintDLLs(prHandle)

    End Sub
  


    Function PrintDLLs(ByVal handle As IntPtr)
        Dim Address As Integer
        Dim Sysinfo As SYSTEM_INFO
        Dim MemInfo As MEMORY_BASIC_INFORMATION


        GetSystemInfo(Sysinfo)

        For Address = Sysinfo.MinAppAddress To Sysinfo.MaxAppAddress
            Try
                
                If VirtualQueryEx(handle, Address, MemInfo, Marshal.SizeOf(MemInfo)) = 0 Then

                End If
                Console.WriteLine(MemInfo.lType)

                Address = Address + Sysinfo.PageSize
            Catch ex As Exception

            End Try
            
        Next


    End Function

End Module
 
You use Marshal.PtrToStructure to get a managed structure from an unmanaged pointer.


I made the following change -

VB.NET:
VirtualQueryEx(handle, Address, Marshal.PtrToStructure(MemInfo, GetType(MEMORY_BASIC_INFORMATION)), Marshal.SizeOf(MemInfo)) = 0
and I get the error -
Value of type 'ConsoleApplication1.Module1.MEMORY_BASIC_INFORMATION' cannot be converted to 'System.IntPtr'.

I understand that there is some type mismatch and that maybe I am not using Marshal.ptrtostructure correctly but am stuck at that.

Any feedback will be greatly appreciated.
 
Unmanaged functions deal with pointers, which you declare as IntPtr in your VB code. If a function returns a pointer to a structure, you declare it as returning an IntPtr in your VB code and then you call Marshal.PtrToStructure and pass the function result to get the actual structure instance. Likewise, if a function has a structure pointer as a parameter, you call Marshal.StructureToPtr to get an IntPtr to pass to the function. Only pointers, i.e. IntPtrs, go in and out of the unmanaged functions.
 
Thank you for your reply. I have made some changes and it still does not work. Here is what I have -

VB.NET:
Imports System.Runtime.InteropServices

Module Module1

    Declare Auto Sub GetSystemInfo Lib "kernel32.dll" (ByRef Info As SYSTEM_INFO)
    Public Declare Function VirtualQueryEx Lib "kernel32" Alias "VirtualQueryEx" (ByVal hProcess As IntPtr, ByVal lpAddress As IntPtr, <Out()> ByVal lpBuffer As MEMORY_BASIC_INFORMATION, ByVal dwLength As Long) As Long

  <StructLayout(LayoutKind.Sequential)> _
    Structure SYSTEM_INFO
        Dim ProcessorArchitecture As Int16
        Dim Reserved As Int16
        Dim PageSize As Int32
        Dim MinAppAddress As Int32
        Dim MaxAppAddress As Int32
        Dim ActiveProcMask As Int32
        Dim NumberOfProcessors As Int32
        Dim ProcessorType As Int32
        Dim AllocGranularity As Int32
        Dim ProcessorLevel As Int32
        Dim ProcessorRevision As Int32
    End Structure
  <StructLayout(LayoutKind.Sequential)> _
    Public Structure MEMORY_BASIC_INFORMATION
        Dim BaseAddress As IntPtr
        Dim AllocationBase As IntPtr
        Dim AllocationProtect As UInt32
        Dim RegionSize As IntPtr
        Dim State As UInt32
        Dim Protect As UInt32
        Dim lType As UInt32
    End Structure

    Sub Main()
        Dim ProcessToReadFrom As Process = Process.GetProcessesByName("notepad")(0)
        Dim prHandle = ProcessToReadFrom.Handle

        PrintDLLs(prHandle)

    End Sub
  


    Function PrintDLLs(ByVal handle As IntPtr)
        Dim Address As Integer
        Dim Sysinfo As SYSTEM_INFO
        Dim MemInfo As MEMORY_BASIC_INFORMATION
        Dim myptr As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(MemInfo))

        GetSystemInfo(Sysinfo)

         For Address = Sysinfo.MinAppAddress To Sysinfo.MaxAppAddress
            Try
 
                Marshal.StructureToPtr(MemInfo, myptr, False)
                If VirtualQueryEx(handle, Address, Marshal.PtrToStructure(myptr, MemInfo.GetType()), Marshal.SizeOf(MemInfo)) = 0 Then

                End If
                                       
                Console.WriteLine(MemInfo.lType)

                Address = Address + Sysinfo.PageSize
            Catch ex As Exception

            End Try
            
        Next


    End Function

End Module
And MemInfo.lType still gives me a 0.

Any feedback will be appreciated.
 
Back
Top