Array of bytes

    Publicités

Users Who Are Viewing This Thread (Total: 0, Members: 0, Guests: 0)

[WonderFul

Membre
Dec 10, 2014
58
0
66
Bonjour, j'aurais une question, comment on fait pour lire l'adress ou la valeurs d'une Array of bytes (aob) et comment en écrie dessu, (genre comme cheat engine) en vb.net

Esque le fichier class ReadWirteMemory.vb le permet ?
 

TheHardButcher

Programmeur C/C++
V
Dec 14, 2009
1,461
58
964
France
Théoriquement, un array of byte, c'est plein d'octet (byte = octet) donc si tu adresse est 0x00FF00 et que ton arrya a une taille 5, tu devrai écrire 5 octets après 0x00FF00 de façon a écrire dans ton array of byte !
 

Astropilot

The Lord
V.I.P
V
Jan 6, 2011
9,285
18
1,254
France
Voila un code que je viens de faire (j'ai repris la fonction connue en c++ et je l'ai retranscrite en vb.net)

Code:
    Public Function Compare(ByVal Process As String, ByVal Address As Long, ByVal Pattern As Byte(), ByVal Mask As String) As Boolean
        Dim pTemp As Byte = Nothing
        For i As Integer = 0 To Mask.Length - 1 Step 1
            pTemp = ReadByte(Process, (Address + i), 4)
            If pTemp = Nothing Then
                Return False
            End If
            If Mask(i) = "x" And pTemp <> Pattern(i) Then
                Return False
            End If
        Next
        Return True
    End Function

    Public Function FindPattern(ByVal Process As String, ByVal Pattern As Byte(), ByVal Mask As String) As Long
        For dwCurrentAddress As Long = &H0400000 To &H7FFFFFF Step &H1
            If Compare(Process, dwCurrentAddress, Pattern, Mask) Then
                Return dwCurrentAddress
            End If
        Next
        Return -1
    End Function

Il te faut aussi ajouter cette fonction dans ton ReadWritingMemory.vb:

Code:
Private Declare Function ReadProcessMemory4 Lib "kernel32" Alias "ReadProcessMemory" (ByVal hProcess As Integer, ByVal lpBaseAddress As Integer, ByRef lpBuffer As Byte, ByVal nSize As Integer, ByRef lpNumberOfBytesWritten As Integer) As Byte

Public Function ReadByte(ByVal ProcessName As String, ByVal Address As Integer, Optional ByVal nsize As Integer = 4) As Byte
        Dim MyP As Process() = Process.GetProcessesByName(ProcessName)
        Dim hProcess As IntPtr = OpenProcess(&H10, 0, MyP(0).Id)

        Dim hAddress As Integer
        Dim vBuffer As Byte = Nothing

        hAddress = Address
        ReadProcessMemory4(hProcess, hAddress, vBuffer, nsize, 0)
        CloseHandle(hProcess)
        Return vBuffer
    End Function

Ensuite tu call la fonction FindPattern genre comme ca par exemple:

Code:
Dim Pattern As Byte() = Array.ConvertAll("MonTextAChercher".ToCharArray(), Function(c) CType(Asc(c), Byte))
Dim MonAddress As Long = FindPattern("S4League", Pattern, "xxxxxx????xxxxxx")

/!\ La fonction est ultra lente, donc je recommande de bien cibler l'intervalle de recherche et aussi d'améliorer la fonction ^^/!\
 
Last edited:

[WonderFul

Membre
Dec 10, 2014
58
0
66
Ya un problème avec le code, il est pas que longtemps enfaite il est infinie il ouvre la memoire puis il stagne
 

[WonderFul

Membre
Dec 10, 2014
58
0
66
Mon but principal est d'arriver a trouver une adress de cette façon
D9 45 FC 8B E5 5D C3 CC CC CC CC CC CC CC CC CC CC CC CC CC 55 8B EC 51 89 4D FC 8D 45 08 50
6st6woG.png

-------------------
Mais pour le moment je me contente d'une adresse ciblé:
8B 55 E8 3B 55 08 7E 0B 8B 45
Qui n'à qu'une seul adresse.

Sauf j'ai déjà des problème dans le code base,

Donc j'ai modifier un peux ton code (celui a mettre dans readwirtememory.vb)

Code:
 Public Function ReadByte(ByVal ProcessName As String, ByVal Address As Integer, Optional ByVal nsize As Integer = 4) As Byte
        If ProcessName.EndsWith(".exe") Then
            ProcessName = ProcessName.Replace(".exe", "")
        End If
        Dim MyP As Process() = Process.GetProcessesByName(ProcessName)
        If MyP.Length = 0 Then
            MessageBox.Show(ProcessName & " isn't open!")
            Exit Function
        End If
        Dim hProcess As IntPtr = OpenProcess(&H10, 0, MyP(0).Id)
        If hProcess = IntPtr.Zero Then
            MessageBox.Show("Failed to open " & ProcessName & "!")
            Exit Function
        End If
        Dim hAddress As Integer
        Dim vBuffer As Byte = Nothing

        hAddress = Address
        ReadProcessMemory4(hProcess, hAddress, vBuffer, nsize, 0)

        Return vBuffer
    End Function

Ainsi que le FindPatern pour suivre son avancement:

Code:
    Public Function FindPattern(ByVal Process As String, ByVal Pattern As Byte(), ByVal Mask As String) As Long
        For dwCurrentAddress As Long = &H400000 To &H7FFFFFF Step &H1
            ProgressBar1.Maximum = &H7FFFFFF
            ProgressBar1.Value = dwCurrentAddress
            If Compare(Process, dwCurrentAddress, Pattern, Mask) Then
                ProgressBar1.Value = ProgressBar1.Maximum
                Return dwCurrentAddress
            End If
        Next
        Return -1
    End Function

Je n'est pas toucher au Compare:

Code:
    Public Function Compare(ByVal Process As String, ByVal Address As Long, ByVal Pattern As Byte(), ByVal Mask As String) As Boolean
        Dim pTemp As Byte = Nothing
        For i As Integer = 0 To Mask.Length - 1 Step 1
            pTemp = ReadByte(Process, (Address + i), 4)
            If pTemp = Nothing Then
                Return False
            End If
            If Mask(i) = "x" And pTemp <> Pattern(i) Then
                Return False
            End If
        Next
        Return True
    End Function

Donc ma fonction a était faite comme sa:

Code:
    Dim Threadz As Threading.Thread

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Threadz = New System.Threading.Thread(Sub()
                                                  Dim Pattern As Byte() = Array.ConvertAll("8B 55 E8 3B 55 08 7E 0B 8B 45".ToCharArray(), Function(c) CType(Asc(c), Byte))
                                                  Dim MonAddress As Long = FindPattern("S4Client.exe", Pattern, "xxxxxx????xxxxxx")
                                                  TextBox3.Text = MonAddress
                                              End Sub)
        Threadz.Start()

    End Sub

Donc sa fonctionne je n'est auccune erreur sauf un chargement de l'infini ma pogressbar n'avance environ que de 1mm et se stope litéralement pendant 35mins
 

ragnarock

Membre actif
Mar 22, 2010
194
0
917
Salut,

Je te conseille de repartir d'une base saine, et donc de ne pas prendre le code de la première page, il est affreusement pas opti. Mais surtout il te faut de la lecture, Ce lien n'est pas visible, veuillez vous connecter pour l'afficher. Je m'inscris! par exemple. Une fois que t'auras compris à peu près comment marche la mémoire, tu pourras répondre toi-même à tes questions.

sinon quelques pistes :
- ReadProcessMemory est une fonction assez lente, vaut mieux lire un gros bloc de mémoire et rechercher dedans que de lire la mémoire tous les 4 bytes
- Cheat Engine est open-source
- Ce lien n'est pas visible, veuillez vous connecter pour l'afficher. Je m'inscris!
- Il y a un debugger dans VS, quand tu ne sais pas ce que fais ton programme, tu mets un breakpoint et tu debug
 

[WonderFul

Membre
Dec 10, 2014
58
0
66
EDITE --

Probleme resolue, j'ai oublier de moficer le mask... Autant pour moi.

J'aurais juste besoin d'une presition a quoi sert-il, voilà merci sinona #Resolu

Ps: Merci Astro, Ragnarock, et la commun
 

Astropilot

The Lord
V.I.P
V
Jan 6, 2011
9,285
18
1,254
France
EDITE --

Probleme resolue, j'ai oublier de moficer le mask... Autant pour moi.

J'aurais juste besoin d'une presition a quoi sert-il, voilà merci sinona #Resolu

Ps: Merci Astro, Ragnarock, et la commun

Le masque te permet de dire à la fonction les bytes obligatoires et ceux a ignorer.
Exemple avec un aob random: 4D 6F 6E 54 65 78 74
Imaginons que 6E 54 65 peuvent changer, on connais alors 4D 6F ?? ?? ?? 78 74
Du coup on va dire au programme de ne pas verifier ces bytes, ce qui donne le mask suivant: xx???xx

@ragnarock
J'ai bien précisé que mon code était très lent et avais besoin d'être retravaillé, si j'ai le temps je verrais si je peux l'optimiser.
 

ragnarock

Membre actif
Mar 22, 2010
194
0
917
ouais j'ai bien vu, c'est dur de rater le gros pavé rouge dans ton post^^
je voulais quand même le répéter, parce qu'il l'a quand même utilisé.

Si tu veux quelques conseils pour opti ça, dis-moi.
 

Astropilot

The Lord
V.I.P
V
Jan 6, 2011
9,285
18
1,254
France
Déjà ça d'optimisation et ça va déjà beauuuuuuucoup plus vite :D
(Thanks Rag pour l'idée des block de mémoire :p)

Code:
Public Function Compare(ByVal dwBuffer() As Byte, ByVal Pattern As Byte(), ByVal Mask As String, ByVal Index As Integer) As Boolean
        Dim pTemp As Byte = Nothing
        For i As Integer = 0 To Mask.Length - 1 Step 1
            pTemp = dwBuffer(i + Index)
            If pTemp = Nothing Then
                Return False
            End If
            If Mask(i) = "x" And pTemp <> Pattern(i) Then
                Return False
            End If
        Next
        Return True
    End Function

    Public Function FindPattern(ByVal Process As String, ByVal StartAddress As Long, ByVal StopAddress As Long, ByVal Pattern As Byte(), ByVal Mask As String) As Long
        Dim dwAddress As Long = StartAddress
        While dwAddress < StopAddress
            Dim dwBuffer As Byte() = ReadMultiByte(Process, dwAddress, 4096)
            For i As Integer = 0 To 1024 Step 1
                If Compare(dwBuffer, Pattern, Mask, i) = True Then
                    Return dwAddress + i
                End If
            Next
            dwAddress += 4096
        End While
        Return -1
    End Function

Du coup j'ai aussi modifier la fonction de lecture pour lire plusieurs bytes et pas qu'un seul:

Code:
Private Declare Function ReadProcessMemory5 Lib "kernel32" Alias "ReadProcessMemory" (ByVal hProcess As Integer, ByVal lpBaseAddress As Integer, ByVal lpBuffer() As Byte, ByVal nSize As Integer, ByRef lpNumberOfBytesWritten As Integer) As Boolean
Public Function ReadMultiByte(ByVal ProcessName As String, ByVal Address As Integer, Optional ByVal nsize As Integer = 4) As Byte()
        Dim MyP As Process() = Process.GetProcessesByName(ProcessName)
        Dim hProcess As IntPtr = OpenProcess(PROCESS_ALL_ACCESS, 0, MyP(0).Id)

        Dim hAddress As Integer
        Dim vBuffer(nsize - 1) As Byte

        hAddress = Address
        ReadProcessMemory5(hProcess, hAddress, vBuffer, nsize, 0)
        CloseHandle(hProcess)
        Return vBuffer
    End Function

Et voila comment l'use:

Code:
Dim Pattern As Byte() = Array.ConvertAll("MonTextAChercher".ToCharArray(), Function(c) CType(Asc(c), Byte))
FindPattern("MonProcess", &H200000, &H7FFFFF, Pattern, "xxxxxxxxxxxxxxxx")
 

ragnarock

Membre actif
Mar 22, 2010
194
0
917
Je suis pas le seul à me faire chier un lundi soir x)
J'ai pas fait l'historie des blocs, j'ai juste opti un peu et clean le code.

Bon ce qu'on fait là c'est pas vraiment OOP du tout.

Code:
    Private Declare Function CloseHandle Lib "kernel32" (tHandle As IntPtr)

    Private Declare Function OpenProcess Lib "kernel32" (dwDesiredAccess As Integer, bInheritHandle As Boolean, dwProcessId As Integer) As IntPtr

    Private Declare Function ReadProcessMemory Lib "kernel32" Alias "ReadProcessMemory" (hProcess As IntPtr, lpBaseAddress As Integer, <Out> lpBuffer As Byte(), nSize As Integer, ByRef lpNumberOfBytesWritten As Integer) As Byte

    Private Const PROCESS_VM_READ = &H10

    Public Function ReadByte(hProcess As IntPtr, Address As Integer, Optional ByVal nsize As Integer = 4) As Byte()
        Dim vBuffer(nsize - 1) As Byte
        Dim lpNumberOfBytesWritten As Integer

        ReadProcessMemory(hProcess, Address, vBuffer, nsize, lpNumberOfBytesWritten)

        Return vBuffer
    End Function

    Public Function Compare(hProcess As IntPtr, Address As Long, Pattern As Byte(), Mask As String) As Boolean
        Dim pTemp As Byte

        For i = 0 To Mask.Length - 1 Step 1

            If Mask(i) = "?" Then
                Continue For
            End If

            pTemp = ReadByte(hProcess, (Address + i), 1)(0)

            If pTemp = Nothing Then
                Return False
            End If

            If pTemp <> Pattern(i) Then
                Return False
            End If
        Next

        Return True
    End Function

    Public Function FindPattern(AProcess As String, Pattern As Byte(), Mask As String) As Long

        Dim proc = Process.GetProcessesByName(AProcess).FirstOrDefault()
        If proc Is Nothing Then
            Return -1
        End If

        Dim hProc = OpenProcess(PROCESS_VM_READ, False, proc.Id)
        If hProc = IntPtr.Zero Then
            Return -1
        End If

        Try
            For dwCurrentAddress As Long = &H400000 To &H7FFFFFF Step 1
                If Compare(hProc, dwCurrentAddress, Pattern, Mask) Then
                    Return dwCurrentAddress
                End If
            Next
        
            Return -1
        Finally
            CloseHandle(hProc)
        End Try
    End Function
 

Astropilot

The Lord
V.I.P
V
Jan 6, 2011
9,285
18
1,254
France
En partant de mon dernier code & en ajoutant tes optimisations, mon code est capable de trouver un array se trouvant a l'adresse 0x02D5A290 en deux secondes en commençant a l'adresse 0x0000000
Je vais rendre ca plus beau et en faire une classe que je partagerais quand j'aurais finit :)

Edit:
J'fais un petit prog en même temps pour ceux qui voudrais tester :)
BwyxDuu.png
 
Last edited: