Vb.net Multi Pointer auslesen

Discussion in 'Fragen & Antworten' started by xCyancali, Feb 28, 2014.

Thread Status:
Not open for further replies.
  1. xCyancali

    xCyancali Guest

    Hallo,

    Ich versuche mich wieder an ein Programm in Vb.net mit dem ich die Akutellen Leben in den Spiel 4Story auslesen kann.

    Das Prinzip wie ein Pointer aufgebaut ist, und wie man den richtigen in CE sucht habe ich mittlerweile verstanden.
    Das Problem liegt aber darin, den Pointer in Vb.net richtig zu implementieren.

    Mein Pointer für die Leben:
    [​IMG]

    Ich habe folgendes Memory Mudule:
    Zu lang, deswegen hier:
    http://pastebin.com/mdvhUzi2

    Und mein Versuch ist folgt aufgebaut:

    Code:
    Imports System.Runtime.InteropServices
    Imports System.Text
    
    Public Class Form1
        Dim SpielName = "TClient"      'ohne --> .exe <--
        Dim ModuleName = "TClient.exe" 'mit  --> .exe <-- || oder dll je nachdem
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    
            Dim offsets As String() = {&H1BC, &H658, &HC4}
    
        End Sub
    
    End Class
    

    Grundkenntnisse in Vb habe ich.
    Ich befasse mich aber eher mit Bots für Browsergames (Packets Bots).

    Aber hier verstehe ich nun nicht, wie ich die Baseadresse auslese und wie ich die folgenden Befehle aufbauen muss, bzw. wie diese überhaupt heißen.


    Bei Hilfe bin ich sehr dankbar :)

    Lg,
    xCyancali
     
  2. hoschi111

    hoschi111 Administrator Staff Member Administrator

    Joined:
    Dec 19, 2017
    Messages:
    1,147
    Likes Received:
    2
    Das MemoryModul kommt mir bekannt vor.
    Du musst das Projekt als x86 kompilieren, dann sollte "FindAddress" funktionieren.

    Aber zum eigentlichen Problem:

    Deine Grundkenntnisse haben aber noch große Lücken. Dein erster Lösungsansatz deklariert Variablen, die du niemals brauchst, bzw. verwendest.

    Lies am Besten die Offsets "von Hand" aus.
    Schrittweise ReadMemory der vorher ausgelesenen ReadMemory(of Integer).

    Wenn das Problem nicht bis Mittwoch behoben ist, kann ich dir helfen (bin im Urlaub).
     
  3. xCyancali

    xCyancali Guest

    Hallo,

    Ich verstehe das nicht :/
    Mein Projekt führt das Programm als x86 aus.

    Ich verstehe nicht ganz wie ich weiter machen muss.
    Für den, der mir das erklärt, den überweise ich 5 € Via Paypal.

    Lg,
    xCyancali
     
  4. krusty

    krusty Addicted Member Inventar

    Joined:
    Sep 8, 2012
    Messages:
    175
    Likes Received:
    0
    also, das fertige resultat sollte in etwa so aussehen:

    Code:
    dim base as IntPrt = GetBaseAddress("TClient.exe")
    dim staticOffset as IntPrt = &H000d9134
    dim offsets() as IntPtr = {&H1BC, &H658, &HC4}
    dim endAddress = FindAddress(base, staticOffset, offsets)
    
    (per hand geschrieben)
    Die Funktion GetBaseAddress musste selber schreiben, ist aber recht einfach.
    .Net bietet eine Process Klasse:
    Code:
    dim p as Process = Process....irgendwas("TClient.exe")(0)
    dim base as IntPtr = p....irgendwasBaseaddress()
    irgendwie sowas.

    Darf ich erfahren, wie du darauf kommst die Offets als String Array zu deklarieren ?
     
  5. Skyfail

    Skyfail Administrator Staff Member Administrator Inventar

    Joined:
    Mar 21, 2013
    Messages:
    792
    Likes Received:
    0
    @krusty: Da frag mal lieber hoschi, der hat die Funktion erstellt :D
     
  6. krusty

    krusty Addicted Member Inventar

    Joined:
    Sep 8, 2012
    Messages:
    175
    Likes Received:
    0
    was soll ich da fragen ?
    Ich kenne und verstehe das Modul.
    Die Prozessklasse ist .Net intern und die hab ich gerad nich im Kopf.
     
  7. xCyancali

    xCyancali Guest

    Danke, aber ich verstehe nicht, welchen Namen die Baseadress Funktion trägt.

    [​IMG]
    :/
     
  8. Skyfail

    Skyfail Administrator Staff Member Administrator Inventar

    Joined:
    Mar 21, 2013
    Messages:
    792
    Likes Received:
    0
    Code:
    Function GetBaseAdress(Byval Process As String) As IntPtr
    Dim p() as Process = Process.GetProcessesByName(Process)
    If p.Count = 0 Then
    Return 0
    End If
    Return p(0).BaseAddress
    End Function

    Nicht 100% richtig

    Und bei staticOffset das new weg
     
  9. xCyancali

    xCyancali Guest


    Ich habs jetzt so gemacht, da es sonnst Fehlermeldungen gab:

    Code:
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    
            '   Dim offsets As String() = {&H1BC, &H658, &HC4}
    
            Dim base As IntPtr = GetBaseAdress()
            Dim staticOffset As IntPtr = &HD9134
            Dim offsets() As IntPtr = {&H1BC, &H658, &HC4}
            Dim endAddress = FindAddress(base, staticOffset, offsets)
            [color=#FF0000]Dim value As Integer = ReadMemory(endAddress)[/color]
        End Sub
        Function GetBaseAdress() As IntPtr
            Dim p() As Process = Process.GetProcessesByName("TClient.exe")
            If p.Count = 0 Then
                Return 0
            End If
            Return p(0).ToString
        End Function
    Problem:
    Dim value As Integer = ReadMemory(endAddress)
    Habe keine Ahnung, wie es weiter geht :/
     
  10. Skyfail

    Skyfail Administrator Staff Member Administrator Inventar

    Joined:
    Mar 21, 2013
    Messages:
    792
    Likes Received:
    0
    Code:
    ​    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Dim SpielName = "TClient"      'ohne --> .exe <--
            Dim ModuleName = "TClient.exe" 'mit  --> .exe <-- || oder dll je nachdem
    
            SetProcessname("TClient")
            Dim Offsets As String() = {&HC4, &H658, &H1BC}
            Dim Address As Integer = FindMyAddress(ModuleName, &HD9134, Offsets)
        End Sub
    Memory Modul:
    http://pastebin.com/XjQLk2yf​

    Der Grund, warum die Offsets als String Array deklariert sind ist glaube ich der, dass hoschi überprüft, ob sich "none" darin befindet, falls man keine weiteren Offsets braucht.
     
  11. krusty

    krusty Addicted Member Inventar

    Joined:
    Sep 8, 2012
    Messages:
    175
    Likes Received:
    0
    Scheinbar sind keinerlei Programmierkenntnise vorhanden,
    wtf soll das ?
    Code:
    Return p(0).ToString
    das ist totaler quatsch,

    sorry aber in sonem frühen Stadium kann man dir einfach nicht ordentlich helfen,
    stell dir vor, du sollst nen Aufsatz über die französische Revolution auf französisch schreiben und kennst nur die Wörter "voulez vous coucher avec moi", das geht einfach nicht !
    So, bin raus, bye
     
  12. xCyancali

    xCyancali Guest

    Programmier Kenntnisse sind vorhanden!
    Ich befasse mich verstärkt mit Packet Bots für Browsergames, da brauche ich keine Memory Module, wo ich nicht ganz durchblicke!


    Return p(0).BaseAddress
    Damit klappts aber nicht.
     
  13. Skyfail

    Skyfail Administrator Staff Member Administrator Inventar

    Joined:
    Mar 21, 2013
    Messages:
    792
    Likes Received:
    0
    p(0).ToString() wird noch weniger klappen. Die Baseaddress, die zurückgegeben wird müsste stimmen, aber das sollte doch eh die FindMyAddress Funktion machen
     
  14. krusty

    krusty Addicted Member Inventar

    Joined:
    Sep 8, 2012
    Messages:
    175
    Likes Received:
    0
    Code:
    Return p(0).BaseAddress
     Damit klappts aber nicht. 
    Wir haben doch gesagt, dass wirs frei ausm Kopf geschrieben haben,
    es heißt
    p(0).MainModile.BaseAddress
    Nachzulesen hier:
    http://msdn.microsoft.com/de-de/library/system.diagnostics.process(v=vs.110).aspx
    bzw hier
    http://msdn.microsoft.com/de-de/library/system.diagnostics.processmodule(v=vs.110).aspx
    oder hier
    http://msdn.microsoft.com/de-de/library/system.diagnostics.processmodule.baseaddress(v=vs.110).aspx

    Stichwort generische Methoden, einen Blick ins Memorymodul werfen und man weiß, wies geht:
    Dim bla as Integer = ReadMemory(Of integer)(what ever)
     
  15. xCyancali

    xCyancali Guest

    Danke, jetzt kommen keine Fehlermeldungen mehr :)

    Allerdings bekomme ich als Rückgabe wert, wenn ich FindmyAdress und Readmemory zurückgebe, jeweils eine 0 :/

    Code:
     Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Dim SpielName = "TClient"      'ohne --> .exe <--
            Dim ModuleName = "TClient.exe" 'mit  --> .exe <-- || oder dll je nachdem
            SetProcessname("TClient")
            Dim Offsets As String() = {&HC4, &H658, &H1BC}
            Dim Address As Integer = FindMyAddress(ModuleName, &HD9134, Offsets)
            MsgBox(Address)
            Dim Read As Integer = ReadMemory(Of Integer)(Address)
    
            MsgBox(Read)
        End Sub
    
        Function GetBaseAdress() As IntPtr
            Dim p() As Process = Process.GetProcessesByName("TClient.exe")
            If p.Count = 0 Then
                Return 0
            End If
            Return p(0).MainModule.BaseAddress()
        End Function
    Und was ist das für Wert, also woher kommt der Wert?
     
  16. Skyfail

    Skyfail Administrator Staff Member Administrator Inventar

    Joined:
    Mar 21, 2013
    Messages:
    792
    Likes Received:
    0
  17. xCyancali

    xCyancali Guest


    Danke :)

    Jetzt kommen keine Fehler mehr.
    Allerdings bekomme ich den Rückgabewert "0":

    [​IMG]

    Code:
    Code:
    Imports System.Runtime.InteropServices
    Imports System.Text
    Imports System.Diagnostics.Process
    Public Class Form1
    
       
    
        Private Sub _life()
            Dim SpielName = "TClient"      'ohne --> .exe <--
            Dim ModuleName = "TClient.exe" 'mit  --> .exe <-- || oder dll je nachdem
            SetProcessname("TClient")
            Dim Offsets As String() = {&H1BC, &H658, &HC4}
            Dim Address As Integer = FindMyAddress(ModuleName, &HD9134, Offsets)
       
            Dim Read As Integer = ReadMemory(Of Integer)(Address)
    
            Leben.Text = CStr(Read)
    
        End Sub
        Function GetBaseAdress() As IntPtr
            Dim p() As Process = Process.GetProcessesByName("TClient.exe")
            If p.Count = 0 Then
                Return 0
            End If
            Return p(0).MainModule.BaseAddress()
        End Function
    
        Private Sub Timer1_Tick(sender As System.Object, e As System.EventArgs) Handles Timer1.Tick
            '100 MS Frequenz
            _life()
        End Sub
    End Class​

    Was mich wundert:
    Die Funktion "GetBaseAdress" ist nicht eingebaut.

    Wenn ich bei
    Code:
    Dim Address As Integer = FindMyAddress(ModuleName, &HD9134, Offsets)
    , die Funktioniert "GetBaseAdress()" einbaue, also so:
    Code:
    ​Dim Address As Integer = FindMyAddress(cint(GetBaseAdress()), &HD9134, Offsets)
    , dann ändert dies auch nichts :/

    Kann man jemand bitte die Lösung geben?

    Den überweise ich via Paypal 10€.
    Auch gerne per Spende, sodass ich keinen Anspruch auf Käuferschutz habe, um das Geld wieder zu holen.
     
  18. Helios

    Helios Moderator Staff Member Inventar

    Joined:
    Mar 5, 2013
    Messages:
    138
    Likes Received:
    0
    Versuch mal dieses Memory Modul:

    Code:
    Option Strict On
    
    Imports System.Runtime.InteropServices
    Imports System.Text
    
    Module MemoryModule
    
    #Region "DLL Imports"
    
        <DllImport("kernel32.dll")> _
        Private Function OpenProcess(ByVal dwDesiredAccess As UInteger, <MarshalAs(UnmanagedType.Bool)> ByVal bInheritHandle As Boolean, ByVal dwProcessId As Integer) As IntPtr
        End Function
    
        <DllImport("kernel32.dll", SetLastError:=True)> _
        Private Function WriteProcessMemory(ByVal hProcess As IntPtr, ByVal lpBaseAddress As IntPtr, ByVal lpBuffer As Byte(), ByVal nSize As IntPtr, <Out()> ByRef lpNumberOfBytesWritten As IntPtr) As Boolean
        End Function
    
        <DllImport("kernel32.dll", SetLastError:=True)> _
        Private Function ReadProcessMemory(ByVal hProcess As IntPtr, ByVal lpBaseAddress As IntPtr, <Out()> ByVal lpBuffer() As Byte, ByVal dwSize As IntPtr, ByRef lpNumberOfBytesRead As IntPtr) As Boolean
        End Function
    
        <DllImport("kernel32.dll", SetLastError:=True)>
        Private Function CloseHandle(ByVal hObject As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
        End Function
    
    #End Region
    
    #Region "Declare Variables"
    
        Private Const PROCESS_VM_WRITE As UInteger = &H20
        Private Const PROCESS_VM_READ As UInteger = &H10
        Private Const PROCESS_VM_OPERATION As UInteger = &H8
        Private TargetProcess As String = "OrcsMustDie2"
        Private ProcessHandle As IntPtr = IntPtr.Zero
        Private LastKnownPID As Integer = -1
    
    #End Region
    
    #Region "Read- & WriteMemory Functions"
    
        Private Function ProcessIDExists(ByVal pID As Integer) As Boolean
            For Each p As Process In Process.GetProcessesByName(TargetProcess)
                If p.ID = pID Then Return True
            Next
            Return False
        End Function
    
        Public Sub SetProcessName(ByVal processName As String)
            TargetProcess = processName
            If ProcessHandle <> IntPtr.Zero Then CloseHandle(ProcessHandle)
            LastKnownPID = -1
            ProcessHandle = IntPtr.Zero
        End Sub
    
        Public Function GetCurrentProcessName() As String
            Return TargetProcess
        End Function
    
        Public Function UpdateProcessHandle() As Boolean
            If LastKnownPID = -1 OrElse Not ProcessIDExists(LastKnownPID) Then
                If ProcessHandle <> IntPtr.Zero Then CloseHandle(ProcessHandle)
                Dim p() As Process = Process.GetProcessesByName(TargetProcess)
                If p.Length = 0 Then Return False
                LastKnownPID = p(0).Id
                ProcessHandle = OpenProcess(PROCESS_VM_READ Or PROCESS_VM_WRITE Or PROCESS_VM_OPERATION, False, p(0).Id)
                If ProcessHandle = IntPtr.Zero Then Return False
            End If
            Return True
        End Function
    
        Public Function ReadMemory(Of T)(ByVal address As Object) As T
            Return ReadMemory(Of T)(CLng(address))
        End Function
    
        Public Function ReadMemory(Of T)(ByVal address As Integer) As T
            Return ReadMemory(Of T)(New IntPtr(address), 0, False)
        End Function
    
        Public Function ReadMemory(Of T)(ByVal address As Long) As T
            Return ReadMemory(Of T)(New IntPtr(address), 0, False)
        End Function
    
        Public Function ReadMemory(Of T)(ByVal address As IntPtr) As T
            Return ReadMemory(Of T)(address, 0, False)
        End Function
    
        Public Function ReadMemory(ByVal address As IntPtr, ByVal length As Integer) As Byte()
            Return ReadMemory(Of Byte())(address, length, False)
        End Function
    
        Public Function ReadMemory(ByVal address As Integer, ByVal length As Integer) As Byte()
            Return ReadMemory(Of Byte())(New IntPtr(address), length, False)
        End Function
    
        Public Function ReadMemory(ByVal address As Long, ByVal length As Integer) As Byte()
            Return ReadMemory(Of Byte())(New IntPtr(address), length, False)
        End Function
    
        Public Function ReadMemory(Of T)(ByVal address As IntPtr, ByVal length As Integer, ByVal unicodeString As Boolean) As T
            Dim buffer() As Byte
            If GetType(T) Is GetType(String) Then
                If unicodeString Then buffer = New Byte(length * 2 - 1) {} Else buffer = New Byte(length - 1) {}
            ElseIf GetType(T) Is GetType(Byte()) Then
                buffer = New Byte(length - 1) {}
            Else
                buffer = New Byte(Marshal.SizeOf(GetType(T)) - 1) {}
            End If
            If Not UpdateProcessHandle() Then Return Nothing
            Dim success As Boolean = ReadProcessMemory(ProcessHandle, address, buffer, New IntPtr(buffer.Length), IntPtr.Zero)
            If Not success Then Return Nothing
            If GetType(T) Is GetType(Byte()) Then Return CType(CType(buffer, Object), T)
            If GetType(T) Is GetType(String) Then
                If unicodeString Then Return CType(CType(Encoding.Unicode.GetString(buffer), Object), T)
                Return CType(CType(Encoding.ASCII.GetString(buffer), Object), T)
            End If
            Dim gcHandle As GCHandle = gcHandle.Alloc(buffer, GCHandleType.Pinned)
            Dim returnObject As T = CType(Marshal.PtrToStructure(gcHandle.AddrOfPinnedObject, GetType(T)), T)
            gcHandle.Free()
            Return returnObject
        End Function
    
        Private Function GetObjectBytes(ByVal value As Object) As Byte()
            If value.GetType() Is GetType(Byte()) Then Return CType(value, Byte())
            Dim buffer(Marshal.SizeOf(value) - 1) As Byte
            Dim ptr As IntPtr = Marshal.AllocHGlobal(buffer.Length)
            Marshal.StructureToPtr(value, ptr, True)
            Marshal.Copy(ptr, buffer, 0, buffer.Length)
            Marshal.FreeHGlobal(ptr)
            Return buffer
        End Function
    
        Public Function WriteMemory(Of T)(ByVal address As Object, ByVal value As T) As Boolean
            Return WriteMemory(CLng(address), value)
        End Function
    
        Public Function WriteMemory(Of T)(ByVal address As Object, ByVal value As Object) As Boolean
            Return WriteMemory(CLng(address), CType(value, T))
        End Function
    
        Public Function WriteMemory(Of T)(ByVal address As Integer, ByVal value As T) As Boolean
            Return WriteMemory(New IntPtr(address), value)
        End Function
    
        Public Function WriteMemory(Of T)(ByVal address As Integer, ByVal value As Object) As Boolean
            Return WriteMemory(address, CType(value, T))
        End Function
    
        Public Function WriteMemory(Of T)(ByVal address As Long, ByVal value As T) As Boolean
            Return WriteMemory(New IntPtr(address), value)
        End Function
    
        Public Function WriteMemory(Of T)(ByVal address As Long, ByVal value As Object) As Boolean
            Return WriteMemory(address, CType(value, T))
        End Function
    
        Public Function WriteMemory(Of T)(ByVal address As IntPtr, ByVal value As T) As Boolean
            Return WriteMemory(address, value, False)
        End Function
    
        Public Function WriteMemory(Of T)(ByVal address As IntPtr, ByVal value As Object) As Boolean
            Return WriteMemory(address, CType(value, T), False)
        End Function
    
        Public Function WriteMemory(Of T)(ByVal address As Object, ByVal value As T, ByVal unicode As Boolean) As Boolean
            Return WriteMemory(CLng(address), value, unicode)
        End Function
    
        Public Function WriteMemory(Of T)(ByVal address As Integer, ByVal value As T, ByVal unicode As Boolean) As Boolean
            Return WriteMemory(New IntPtr(address), value, unicode)
        End Function
    
        Public Function WriteMemory(Of T)(ByVal address As Long, ByVal value As T, ByVal unicode As Boolean) As Boolean
            Return WriteMemory(New IntPtr(address), value, unicode)
        End Function
    
        Public Function WriteMemory(Of T)(ByVal address As IntPtr, ByVal value As T, ByVal unicode As Boolean) As Boolean
            If Not UpdateProcessHandle() Then Return False
            Dim buffer() As Byte
            If TypeOf value Is String Then
                If unicode Then buffer = Encoding.Unicode.GetBytes(value.ToString()) Else buffer = Encoding.ASCII.GetBytes(value.ToString())
            Else
                buffer = GetObjectBytes(value)
            End If
            Dim result As Boolean = WriteProcessMemory(ProcessHandle, address, buffer, New IntPtr(buffer.Length), IntPtr.Zero)
            Return result
        End Function
    
        Public Function GetProcessID(ByVal hProcess As String, ByVal MachineName As String) As String
            Try
                Dim ps As Diagnostics.Process() = Diagnostics.Process.GetProcessesByName(hProcess, MachineName)
                For Each Item As Diagnostics.Process In ps
                    Return Item.Id.ToString()
                    'Return Item.MainWindowHandle.ToString()
                Next
            Catch ex As Exception
                MessageBox.Show(ex.Message.ToString(), "Info")
            End Try
            Return String.Empty
        End Function
    
    #End Region
    End Module
    


    Und meine GetPointer Funktion:

    Code:
    Public Function GetBaseAddress(ByVal prozess As String) As Integer
            Dim p As Process() = Process.GetProcessesByName(prozess)
            'Dim pID As IntPtr = p(0).Handle
            If Not p.Count < 1 Then
                Dim base As IntPtr = p(0).MainModule.BaseAddress
                Return CInt(base)
            Else
                Return 0
            End If
        End Function
    
        Public Function GetPointer(ByVal pModule As String, ByVal Offsets As Integer()) As Integer
            Dim BaseAddress As Integer = GetBaseAddress(pModule)
            BaseAddress = BaseAddress + Offsets(0)
            Dim RealAddress As Integer = ReadMemory(Of Integer)(BaseAddress)
            RealAddress = RealAddress + Offsets(1)
            Dim i As Integer = Offsets.GetUpperBound(0)
            For index As Integer = 2 To Offsets.GetUpperBound(0)
                RealAddress = ReadMemory(Of Integer)(RealAddress) + Offsets(index)
            Next
            Return RealAddress
        End Function
    ​

    Du schreibst dann in deinem Fall folgendes:

    Code:
    ​
    Dim offsets() as integer = {&HC4, &H658, &H1bc}
    Dim pModule as string = "TClient"
    Adresse = Getpointer(pmodule,offsets)
    
     
  19. xCyancali

    xCyancali Guest

    Danke für die hilfe, allerdings bekomme ich wieder den "Zugriff Verweigert" Fehler. :/
    [​IMG]

    Ein User, der mich in Skype deswegen angeschrieben hat, hatte sich das mit Teamviewer angeschaut.

    Er meinte, dass ich die WinApi Funktion benutzen müsste, da 4Story das blocken würde.
     
  20. krusty

    krusty Addicted Member Inventar

    Joined:
    Sep 8, 2012
    Messages:
    175
    Likes Received:
    0
    Als admin gestartet ?
    Ist 4Story ein 32 oder 63 Bit Prozess ?
    Wenn es ein 32 Bit Prozess ist, musst du dein Programm auch als 32 Bit kompilieren
    ebenso bei 64 Bit,
    Das "prozessübergreifende" auslesen von Modulen bei unterschiedlichem Prozess geht nicht.
     
Thread Status:
Not open for further replies.
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.