Imports System.Text
Imports System.Runtime.InteropServices

Public Class Memory

#Region "Instance Fields"
    Private mAddress As Integer
    Private mProcess As Process
#End Region

#Region "Initialize"
    Public Sub New(ByVal [process] As Process, ByVal address As Integer)
        Me.mProcess = [process]
        Me.mAddress = address
    End Sub

    Public Sub New(ByVal ProcessName As String)
        Me.mProcess = findProcess(ProcessName)
    End Sub

    Public Sub New()
    End Sub
#End Region

#Region "Functions"
    Public Shared Function findProcess(ByVal pName As String) As Process
        Dim p As Process() = Process.GetProcessesByName(pName)
        If p.length > 0 Then
            Return p(0)
        Else
            Return Nothing
        End If
    End Function

    Public Shared Function GetModule(ByVal [module] As String, ByVal process As Process) As ProcessModule
        Dim module2 As ProcessModule
        Try
            Dim module1 As ProcessModule
            For Each module1 In process.Modules
                If (module1.ModuleName.ToLower = [module].ToLower) Then
                    Return module1
                End If
            Next
            module2 = Nothing
        Catch obj1 As Exception
            module2 = Nothing
        End Try
        Return module2
    End Function

    Public Shared Function GetModuleEndAddress(ByVal [module] As String, ByVal process As Process) As Integer
        Dim num1 As Integer
        Try
            Dim module1 As ProcessModule
            For Each module1 In process.Modules
                If (module1.ModuleName.ToLower = [module].ToLower) Then
                    Return (module1.ModuleMemorySize + module1.BaseAddress.ToInt32)
                End If
            Next
            num1 = -1
        Catch obj1 As Exception
            num1 = -1
        End Try
        Return num1
    End Function


    Private Sub getBaseAddress(ByVal p As Process, ByVal m As String)
        Dim pm As ProcessModuleCollection = p.Modules
        For Each mo As ProcessModule In pm
            If mo.FileName = m Then
                Me.mAddress = mo.BaseAddress
            End If
        Next
    End Sub

    Public Function GetOpcode(ByVal intLength As Integer) As String
        Dim buffer1 As Byte() = Me.GetByteArray(intLength)
        Return BitConverter.ToString(buffer1)
    End Function

    Public Function GetByte() As Byte
        Dim data As Byte() = New Byte(1 - 1) {}
        WindowsAPI.Peek(Me.mProcess, Me.mAddress, data)
        Return data(0)
    End Function

    Public Function GetByteArray(ByVal num As Integer) As Byte()
        Dim data As Byte() = New Byte(num - 1) {}
        WindowsAPI.Peek(Me.mProcess, Me.mAddress, data)
        Return data
    End Function

    Public Function GetDouble() As Double
        Dim value As Byte() = New Byte(8 - 1) {}
        WindowsAPI.Peek(Me.mProcess, Me.mAddress, value)
        Return BitConverter.ToDouble(value, 0)
    End Function

    Public Function GetFloat() As Single
        Dim value As Byte() = New Byte(4 - 1) {}
        WindowsAPI.Peek(Me.mProcess, Me.mAddress, value)
        Return BitConverter.ToSingle(value, 0)
    End Function

    Public Function GetInt16() As Integer
        Dim value As Byte() = New Byte(2 - 1) {}
        WindowsAPI.Peek(Me.mProcess, Me.mAddress, value)
        Return BitConverter.ToInt16(value, 0)
    End Function

    Public Function GetInt32() As Integer
        Dim value As Byte() = New Byte(4 - 1) {}
        WindowsAPI.Peek(Me.mProcess, Me.mAddress, value)
        Return BitConverter.ToInt32(value, 0)
    End Function

    Public Function GetInt64() As Long
        Dim value As Byte() = New Byte(8 - 1) {}
        WindowsAPI.Peek(Me.mProcess, Me.mAddress, value)
        Return BitConverter.ToInt64(value, 0)
    End Function

    Public Function GetName() As String
        Dim bytes As Byte() = New Byte(18 - 1) {}
        WindowsAPI.Peek(Me.mProcess, Me.mAddress, bytes)
        Return Encoding.ASCII.GetString(bytes)
    End Function

    Public Function GetProgram() As Integer
        Dim value As Byte() = New Byte(30 - 1) {}
        WindowsAPI.Peek(Me.mProcess, Me.mAddress, value)
        Return BitConverter.ToInt32(value, 0)
    End Function

    Public Function GetStringFromByteArray(ByVal bytes As Byte()) As String
        Dim u8 As New UTF8Encoding
        Dim text1 As String = u8.GetString(bytes)
        Dim startIndex As Integer = text1.IndexOf(ChrW(0))
        If (Not startIndex = -1) Then
            text1 = text1.Remove(startIndex, (text1.Length - startIndex))
        End If
        Return text1
    End Function

    Public Function GetUInt32() As UInt32
        Dim value As Byte() = New Byte(4 - 1) {}
        WindowsAPI.Peek(Me.mProcess, Me.mAddress, value)
        Return BitConverter.ToUInt32(value, 0)
    End Function

    Public Function GetUInt16() As UInt16
        Dim value As Byte() = New Byte(4 - 1) {}
        WindowsAPI.Peek(Me.mProcess, Me.mAddress, value)
        Return BitConverter.ToUInt16(value, 0)
    End Function

    Public Function GetMobStructure() As Mob.MobInfo
        Dim mob As Mob.MobInfo
        Dim lpBytesWritten As Integer = 0
        Dim buffer As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(GetType(Mob.MobInfo)))
        Dim pol As IntPtr = WindowsAPI.OpenProcess(WindowsAPI.PROCESS_ALL_ACCESS, False, Me.mProcess.Id)
        WindowsAPI.ReadProcessMemory(pol, New IntPtr(Me.mAddress), buffer, Marshal.SizeOf(GetType(Mob.MobInfo)), lpBytesWritten)
        mob = CType(Marshal.PtrToStructure(buffer, GetType(Mob.MobInfo)), Mob.MobInfo)
        WindowsAPI.CloseHandle(pol)
        Return mob
    End Function

    Public Sub Reset(ByVal val As Integer)
        Dim data As Byte() = BitConverter.GetBytes(val)
        WindowsAPI.Poke(Me.mProcess, Me.mAddress, data)
    End Sub

    Public Sub SetByte(ByVal val As Byte)
        Dim data As Byte() = BitConverter.GetBytes(val)
        WindowsAPI.Poke(Me.mProcess, Me.mAddress, data)
    End Sub

    Public Sub SetByteArray(ByVal val As Byte())
        WindowsAPI.Poke(Me.mProcess, Me.mAddress, val)
    End Sub

    Public Sub SetDouble(ByVal val As Double)
        Dim data As Byte() = BitConverter.GetBytes(val)
        WindowsAPI.Poke(Me.mProcess, Me.mAddress, data)
    End Sub

    Public Sub SetFloat(ByVal val As Single)
        Dim data As Byte() = BitConverter.GetBytes(val)
        WindowsAPI.Poke(Me.mProcess, Me.mAddress, data)
    End Sub

    Public Sub SetInt32(ByVal val As Integer)
        Dim data As Byte() = BitConverter.GetBytes(val)
        WindowsAPI.Poke(Me.mProcess, Me.mAddress, data)
    End Sub

    Public Sub SetInt64(ByVal val As Long)
        Dim data As Byte() = BitConverter.GetBytes(val)
        WindowsAPI.Poke(Me.mProcess, Me.mAddress, data)
    End Sub

    Public Sub SetUInt16(ByVal val As UInt16)
        Dim data As Byte() = BitConverter.GetBytes(val)
        WindowsAPI.Poke(Me.mProcess, Me.mAddress, data)
    End Sub

    Public Sub SetUInt32(ByVal val As UInt32)
        Dim data As Byte() = BitConverter.GetBytes(val)
        WindowsAPI.Poke(Me.mProcess, Me.Address, data)
    End Sub
#End Region

#Region "Properties"

    Public Property Address() As Integer
        Get
            Return Me.mAddress
        End Get
        Set(ByVal value As Integer)
            Me.mAddress = value
        End Set
    End Property

#End Region

End Class

