Author Topic: VB trainer code  (Read 723 times)

0 Members and 1 Guest are viewing this topic.

CodeFuzion

  • Poptart
  • *
  • Posts: 2
    • View Profile
VB trainer code
« on: July 28, 2004, 04:34:36 am »
Unlike C, VB doesn't include declarations of the common API functions so we must add them to our project. There are 6 main functions
                     used in almost every trainer, and those will be discussed here.

                        1.FindWindow(ClassName, WindowTitle) - FindWindow returns a handle to a window that has the class name and window title we
                          specify. For our purposes we can leave ClassName Null and just give the WindowTitle of the game were interested in. It can be
                          declared as follows:   Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName
                          As String) As Long
                        2.GetWindowThreadProcessId(WindowHandle, ProcessId) - Here we pass the handle from FindWindow and get back a ProcessId,
                          which is needed to get a handle to the process. It's declaration is:   Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd
                          As Long, lpdwProcessId As Long) As Long
                        3.OpenProcess(DesiredAccess, Inherit, ProcessId) - This function will return a handle to our target process. This handle can then be
                          used to read and write to our target. DesiredAccess determines the access rights the handle will have to the target; for now just use
                          PROCESS_ALL_ACCESS. Inherit should always be False. ProcessId is gotten from the GetWindowThreadProcessId function.
                             Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long)
                          As Long
                        4.CloseHandle(ProcessHandle) - Every handle you open should be closed with a call to CloseHandle.   Declare Function CloseHandle
                          Lib "kernel32" (ByVal hObject As Long) As Long
                        5.WriteProcessMemory(ProcessHandle, Address, Value, SizeofValue, BytesWritten) - This is one of the two functions that does the
                          actual work. It writes Value to the target address specified by Address. You can declare it like this:  Declare Function
                          WriteProcessMemory Lib "kernel32" (ByVal hProcess As Long, ByVal lpBaseAddress As Any, ByVal lpBuffer As Any, ByVal nSize As Long,
                          lpNumberOfBytesWritten As Long) As Long
                        6.ReadProcessMemory(ProcessHandle, Address, Value, SizeofValue, BytesWritten) - This is the other work function. It places into
                          Value the value from the target's address specified by Address. Declare it:  Declare Function WriteProcessMemory Lib "kernel32" (ByVal
                          hProcess As Long, ByVal lpBaseAddress As Any, ByVal lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long

                     There is a lot to know about the Windows API functions. You should make it a point to study the more common ones by looking it up in
                     your programming help files. The help files will also give much more valuable information on the above functions, such as return values and
                     error handling.

                     A Simple Trainer

                     So how do these functions work together so we can make trainers? As an example here's how to code a simple "trainer" for the windows
                     calculator application. The trainer will read the value displayed in the calculator window, and will write our name there if we click a button.

                     First we need to find the address of the calculator display window. This is not a tutorial on Memory searching in games so I'm only giving
                     very general instructions.

                          Enter 123456 into the calculator display
                          Open your favorite memory search program and search for the string 123456
                          Repeat with a different value until only 1 address is found

                     That's the only address we need to know to make our trainer. The address for the display in my calculator application is 40B181 hex,
                     4239745 dec. When I refer to this address in the code listings just replace it with whatever value you found.

                     Now lets go ahead and design the trainer interface.

                          Start a new project in VB and then add 1 Textbox, 1 button and a timer. The textbox will be used to display the string we retrieve
                          from the calculator window and the button will be used to send our name to the display window.
                          Set the form Caption to Calculator Trainer
                          Rename the textbox to txtDisplay and clear the Text property
                          Change the timer name to ReadTimer and the interval to 500
                          Change the button Caption to "Display Name" and the button Name to btnPasteName


                     For this trainer we will need all 6 of our common functions, ReadProcessMemory, WriteProcessMemory, OpenProcess,
                     GetWindowThreadProcessId ,FindWindow and CloseHandle. Insert a new module into the project and add the following lines. Several of
                     the lines are wrapped here but they must be on one line in your module (or you can use the continuation character _ )

                     Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
                     Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
                     Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
                     Declare Function WriteProcessMemory Lib "kernel32" (ByVal hProcess As Long, ByVal lpBaseAddress As Any, ByVal lpBuffer As Any, ByVal nSize As
                     Long, lpNumberOfBytesWritten As Long) As Long
                     Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, ByVal lpBaseAddress As Any, ByVal lpBuffer As Any, ByVal nSize As
                     Long, lpNumberOfBytesWritten As Long) As Long
                     Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long


                     So let's write the code we need to display our name to the calculator window. First we need to get a handle to our target window with the
                     FindWindow function. We'll need to save this handle in a variable and check it for errors to make sure the calculator program is actually
                     running. (FindWindow returns 0 on error)
                        Dim hwnd As Long
                        hwnd = FindWindow(vbNullString, "Calculator")
                        If (hwnd = 0) Then
                           MsgBox "Window not found!"
                           Exit Sub
                        End If
                     Notice we passed a Null String to FindWindow in place of the ClassName, so any window named "Calculator" should be found. If you
                     know the ClassName you can use it but its not necessary.

                     Now lets use our window handle and get a ProcessId. Notice pid is passed as an argument and not assigned the return value.
                        Dim pid As Long
                        GetWindowThreadProcessId hwnd, pid

                     We can now use our pid (ProcessId) to get a Process Handle to the calculator program. The return value here can again be checked for a
                     valid handle and if not then exit the sub.
                        Dim pHandle As Long
                        pHandle = OpenProcess(PROCESS_ALL_ACCESS, False, pid)
                        If (pHandle = 0) Then
                           MsgBox "Couldn't get a process handle!"
                           Exit Sub
                        End If

                     The WriteProcessMemory function is the most important one to our trainer and is the one most likely to fail. So lets take a closer look at
                     the parameters it wants.
                        WriteProcessMemory (ByVal hProcess As Long, ByVal lpBaseAddress As Any, ByVal lpBuffer As Any, ByVal nSize As Long,
                     lpNumberOfBytesWritten As Long)
                     Lets break it down so we know what each function argument does.
                         hProcess is the handle of the process were writing to. We receive this handle from the OpenProcess function above.
                        lpBaseAddress - This is the address we want to write to in the Calculator's virtual memory space, which we found with our memory
                     search program. (The address for my calculator program was &H40B181)
                        lpBuffer is the data I want to write to the above address, . It can be a value, array, string or any other data type.
                         nSize is the number of bytes we want to write to lpBaseAddress. This field should match your data type: if your writing a long then this
                     value should be 4. If your writing a string it should be the length of the string.
                        lpNumberOfBytesWritten will hold the actual number of bytes written to the target address when WriteProcessMemory returns. It can
                     be checked to make sure the call actually worked.

                     Putting our values into this function we get WriteProcessMemory pHandle, &H40B181, "Beans", 5, 0&. I'm passing 0 to
                     lpNumberOfBytesWritten because I'm not going to double check the number of bytes written.

                     Finally we need to close the handle opened by OpenProcess by passing our Process Handle to CloseHandle().
                        CloseHandle hProcess

                     Now to add all the code to our trainer. Double Click on the button to display its code window. The code were adding will go under the
                     Click event for the button (btnPasteName), so make sure that's where your at, then add the following lines. (You don't need to add the
                     comments).

                     Private Sub btnPasteName_Click()
                        ' Declare some variables we need
                        Dim hwnd As Long        ' Holds the handle returned by FindWindow
                        Dim pid As Long         ' Used to hold the Process Id
                        Dim pHandle As Long     ' Holds the Process Handle
                       
                        ' First get a handle to the "game" window
                        hwnd = FindWindow(vbNullString, "Calculator")
                        If (hwnd = 0) Then
                           MsgBox "Window not found!"
                           Exit Sub
                        End If
                       
                        ' We can now get the pid
                        GetWindowThreadProcessId hwnd, pid
                       
                        ' Use the pid to get a Process Handle
                        pHandle = OpenProcess(PROCESS_ALL_ACCESS, False, pid)
                        If (pHandle = 0) Then
                           MsgBox "Couldn't get a process handle!"
                           Exit Sub
                        End If
                         
                        ' Now we can write to our address in memory
                        WriteProcessMemory pHandle, &H40B181, "Beans", 5, 0&
                       
                        ' Close the Process Handle
                        CloseHandle hProcess
                     End Sub

                     And that's it! Clicking the button will cause the calculator window text to be reset to the name we entered. (You may have to minimize and
                     restore the calculator app before it will update its display.


                     Lets add one more feature to our trainer. We'll monitor the display window of the calculator program and show the text in our trainer
                     window. Double Click on the timer to display its code window. Then add the following lines.

                     Private Sub ReadTimer_Timer()
                        ' Declare some variables we need
                        Dim hwnd As Long        ' Holds the handle returned by FindWindow
                        Dim pid As Long         ' Used to hold the Process Id
                        Dim pHandle As Long     ' Holds the Process Handle
                        Dim str As String * 20  ' String to hold display text
                       
                        ' First get a handle to the "game" window
                        hwnd = FindWindow(vbNullString, "Calculator")
                        If (hwnd = 0) Then Exit Sub
                           
                        ' We can now get the pid
                        GetWindowThreadProcessId hwnd, pid
                       
                        ' Use the pid to get a Process Handle
                        pHandle = OpenProcess(PROCESS_ALL_ACCESS, False, pid)
                        If (pHandle = 0) Then Exit Sub
                         
                        ' Now we can read from memory
                        ReadProcessMemory pHandle, &H40B181, str, 20, 0&
                       
                        ' And display the string in our textbox
                        txtDisplay = str
                       
                        ' Close the Process Handle
                        CloseHandle hProcess
                     End Sub

                     The only new thing here is the ReadProcessMemory function. The value read from &H40B181 is placed into str. This string is then
                     displayed in our Textbox - txtDisplay.

                     There are a few other things I wanted to cover in this tutorial that I never got to, but this should give you enough to go on for now. The
                     main thing is to keep working at it and don't be afraid to experiment. Look up other API functions and use them in a trainer. The more you
                     practice, the easier it will be.