Archive for the ‘HotKey’ Tag
Vb Net Article – Medal of Honour Allied Assault Basic Hacks
Medal of Honour Allied Assault Basic Hacks.
I got bored a while back and made some basic hacks for MoHAA.
I made a class (Well a few classes) that I used to read the console, send text to the console, and a few memory hacks.
I then stuck this into a global key hook and set up the hotkeys.
The classes are all contained inside Public Class MoHFunctions
Public Class WindowFunctions
<DllImport(“user32.dll”, SetLastError:=True, CharSet:=CharSet.Auto)> Private Shared Function ShowWindow(ByVal hwnd As IntPtr, ByVal nCmdShow As Int32) As Boolean
End Function
Private Enum WindowShowStyle As UInteger
Hide = 0
ShowMinimized = 2
Minimize = 6
ShowMinNoActivate = 7
ForceMinimized = 11
End Enum
Private Declare Auto Function FindWindow Lib “user32″ (ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
Public Shared Sub MinimiseWindow()
Dim MoHWnd As IntPtr = FindWindow(0, “Medal of Honor Allied Assult”)
ShowWindow(MoHWnd, WindowShowStyle.Minimize)
End Sub
End Class
That class is basically for minimising the MoHAA Window, I never got round to adding anything else to it. Maybe one day…
Now for a long class, the console stuff.
Public Class Console
<DllImport(“User32.dll”)> Private Shared Function EnumChildWindows(ByVal WindowHandle As IntPtr, ByVal Callback As EnumWindowProcess, ByVal lParam As IntPtr) As Boolean
End Function
<DllImport(“user32.dll”, CharSet:=CharSet.Auto)> Private Shared Sub GetClassName(ByVal hWnd As System.IntPtr, ByVal lpClassName As System.Text.StringBuilder, ByVal nMaxCount As Integer)
End Sub
Private Shared Function GetChildWindows(ByVal ParentHandle As IntPtr) As IntPtr()
Dim ChildrenList As New List(Of IntPtr)
Dim ListHandle As GCHandle = GCHandle.Alloc(ChildrenList)
Try
EnumChildWindows(ParentHandle, AddressOf EnumWindow, GCHandle.ToIntPtr(ListHandle))
Finally
If ListHandle.IsAllocated Then ListHandle.Free()
End Try
Return ChildrenList.ToArray
End Function
Private Shared Function EnumWindow(ByVal Handle As IntPtr, ByVal Parameter As IntPtr) As Boolean
Dim ChildrenList As List(Of IntPtr) = GCHandle.FromIntPtr(Parameter).Target
If ChildrenList Is Nothing Then Throw New Exception(“GCHandle Target could not be cast as List(Of IntPtr)”)
ChildrenList.Add(Handle)
Return True
End Function
Private Declare Auto Function SendMessage Lib “user32″ (ByVal hwnd As IntPtr, ByVal wMsg As Integer, ByVal wparam As Integer, ByVal lparam As System.Text.StringBuilder) As IntPtr
Private Declare Auto Function SendMessage Lib “user32″ (ByVal hWnd As IntPtr, ByVal msg As Integer, ByVal wParam As IntPtr, ByVal lParam As String) As IntPtr
Private Declare Auto Function FindWindow Lib “user32″ (ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
Private Delegate Function EnumWindowProcess(ByVal Handle As IntPtr, ByVal Parameter As IntPtr) As Boolean
Private Const WM_GETTEXT = &HD
Private Const WM_GETTEXTLENGTH As Integer = &HE
Private Const WM_SETTEXT = &HC
Private Const WM_CHAR = &H102
These functions are to get a list of the windows inside of the MoHAA console, and to get the text from it.
Private Shared Function FindMoH() As IntPtr
FindMoH = FindWindow(“mohaa winconsole”, vbNullString)
End Function
This function gets the window handle for the MoHAA console, which is then used to get the consoles edit controls handle.
Now, for the sending to the console:
Public Shared Function SendText(ByVal Text As String) As Boolean
Dim handle As IntPtr = FindMoH()
If handle = 0 Then
MessageBox.Show(“Medal of Honor Allied Assult Console not found.”, “Error:”, MessageBoxButtons.OK, MessageBoxIcon.Error)
Return “Error;”
Exit Function
End If
For Each child As IntPtr In GetChildWindows(handle)
Dim sClassName As New System.Text.StringBuilder(“”, 256)
Call GetClassName(child, sClassName, 256)
If sClassName.ToString = “Edit” Then
Dim sb As New System.Text.StringBuilder(Text)
SendMessage(child, WM_SETTEXT, 0, sb)
SendMessage(child, WM_CHAR, 13, 1)
Return True
End If
Next
End Function
This finds the Edit control by looping through the handles until if finds one with the class name “Edit”. It then uses SendMessage to set the text in the window, and then sends the Return character to the window to set it
(child, WM_CHAR, 13, 1)
Reading text from the console isnt much different:
Public Shared Function ReadText() As String
ReadText = “”
Dim handle As IntPtr = FindMoH()
If handle = 0 Then
MessageBox.Show(“Medal of Honor Allied Assult Console not found.”, “Error:”, MessageBoxButtons.OK, MessageBoxIcon.Error)
Return “Error;”
Exit Function
End If
For Each child As IntPtr In GetChildWindows(handle)
Dim sClassName As New System.Text.StringBuilder(“”, 256)
Call GetClassName(child, sClassName, 256)
If sClassName.ToString = “Edit” Then
Dim conLength As IntPtr
conLength = SendMessage(child, WM_GETTEXTLENGTH, IntPtr.Zero, IntPtr.Zero)
Dim sbText As New System.Text.StringBuilder(conLength.ToInt32 + 1)
Dim ptrRet As IntPtr
ptrRet = SendMessage(child, WM_GETTEXT, conLength.ToInt32 + 1, sbText)
If Not sbText.ToString = “” Then
Return sbText.ToString
End If
End If
Next
End Function
This again loops through the handles, until it finds the edit control.
It then sends the GETTEXTLENGTH in order to get the length of the text in the console and then sends GETTEXT to the window to the length that was previously returned.
It then builds the string; if it’s not blank then it returns the value.
Now what can we actually do with these functions? Well to be honest, I didn’t use the ReadText function because I figured the only way to use it would be to check it on a loop, then if a specific string came up you could then do whatever, but I couldn’t be bothered with that…
Public Shared Sub SilentShot()
SendText(“echo Silent Shot”)
SendText(“+attackprimary; weapdrop”)
End Sub
Public Shared Sub Time()
SendText(“echo “ & Now.Hour & “:” & Now.Minute & “:” & Now.Second)
SendText(“locationprint 6 29 “ & Now.Hour & “:” & Now.Minute & “:” & Now.Second)
End Sub
Public Shared Sub Connect(ByVal Ip As String)
SendText(“connect “ & Ip)
End Sub
Public Shared Sub Specator()
SendText(“echo Gone Spectator”)
SendText(“spectator”)
End Sub
Public Shared Sub Reconnect()
SendText(“reconnect”)
End Sub
Now, that’s just some basic stuff, but you could create some more advanced scripts such as:
SendText(“+forward”)
System.Threading.Thread.Sleep(50)
SendText(“-forward”)
SendText(“+moveup”)
System.Threading.Thread.Sleep(400)
SendText(“-moveup”)
System.Threading.Thread.Sleep(10)
SendText(“+forward”)
System.Threading.Thread.Sleep(20)
SendText(“+moveup”)
System.Threading.Thread.Sleep(200)
SendText(“-moveup”)
SendText(“+forward”)
System.Threading.Thread.Sleep(200)
SendText(“+moveup”)
System.Threading.Thread.Sleep(100)
SendText(“-moveup”)
System.Threading.Thread.Sleep(20)
SendText(“+moveleft”)
SendText(“-forward”)
SendText(“-moveleft”)
Now I just came up with that and gave it a quick test, so I can’t guarantee that it works every time (It was just a bind that I made and converted, and it was made quickly so there ARE errors)
bind 9 “+forward;wait 50;-forward;+moveup;say jumped;wait 400;-moveup;wait 10;+forward;say forward;wait 20;+moveup;say jumped;+wait 200; -moveup;+forward;wait 200; say jumped;+moveup; wait 100; -moveup;wait 20;+moveleft;-forward;-moveleft;-moveup”
For example, one noticeable error: say jumped;+wait 200;
Now, off of the console stuff, and onto some fun stuff, memory editing!
Public Class Memory
<DllImport(“kernel32.dll”)> Private Shared Function WriteProcessMemory(ByVal hProcess As IntPtr, ByVal lpBaseAddress As IntPtr, ByVal lpBuffer As Byte(), ByVal nSize As UIntPtr, <Runtime.InteropServices.Out()> ByRef lpNumberOfBytesWritten As IntPtr) As Boolean
End Function
My favourite APIJ, well not really but what you gonna do?
So, anyway, in the main part of the program we have a variable named MoHProchWnd, that’s where I store MoHAA’s PiD using the sub below
Public Shared Sub onLoad()
Try
Dim Processes() As System.Diagnostics.Process
Processes = System.Diagnostics.Process.GetProcessesByName(“MOHAA”)
Main.MoHProchWnd = Processes(0).Handle
Catch ex As Exception
Main.MoHProchWnd = 0
End Try
End Sub
So, anyway below is a basic function for enabling cheats in MoHAA (“Cvars”)
Public Shared Sub EnableCheats()
If Main.MoHProchWnd = 0 Then
onLoad()
End If
Dim bytes As Byte() = New Byte(0) {&H86}
WriteProcessMemory(Main.MoHProchWnd, New IntPtr(&H44F999), bytes, New UIntPtr(CType(bytes.Length, UInt32)), New IntPtr(0))
KeyHook.Cheats = True
End Sub
And then to disable them
Public Shared Sub DisableCheats()
If Main.MoHProchWnd = 0 Then
onLoad()
End If
Dim bytes As Byte() = New Byte(0) {&H85}
WriteProcessMemory(Main.MoHProchWnd, New IntPtr(&H44F999), bytes, New UIntPtr(CType(bytes.Length, UInt32)), New IntPtr(0))
KeyHook.Cheats = False
End Sub
And a quick example of what else can be done:
Public Shared Sub EnableThirdPerson()
If Main.MoHProchWnd = 0 Then
onLoad()
End If
Dim bytes As Byte() = New Byte(0) {&H1}
WriteProcessMemory(Main.MoHProchWnd, New IntPtr(&HECCAF0), bytes, New UIntPtr(CType(bytes.Length, UInt32)), New IntPtr(0))
KeyHook.ThirdPerson = True
Console.SendText(“cg_cameraverticaldisplacement -18″)
Console.SendText(“echo 3rd Person Camera Position Fixed”)
End Sub
Public Shared Sub DisableThirdPerson()
If Main.MoHProchWnd = 0 Then
onLoad()
End If
Dim bytes As Byte() = New Byte(0) {&H0}
WriteProcessMemory(Main.MoHProchWnd, New IntPtr(&HECCAF0), bytes, New UIntPtr(CType(bytes.Length, UInt32)), New IntPtr(0))
KeyHook.ThirdPerson = False
Console.SendText(“cg_cameraverticaldisplacement -2″)
Console.SendText(“echo 1st Person Camera Position Fixed”)
End Sub
That uses the console class to correct the camera position, and edits the programs memory to enable the third person – Note, that since it directly pokes an address, cheats do not need to be enabled to toggle 3rd person.
Now, onto the usage of these classes further. As I previously stated, I set this up on a global key hook. Below is the sub that I use to carry out the above functions.
Private Shared Sub KeyCheck()
If n0Down = True Then
If Cheats = True Then
Cheats = False
Memory.DisableCheats()
Else
Cheats = True
Memory.EnableCheats()
End If
ElseIf n1Down = True Then
If ThirdPerson = True Then
ThirdPerson = False
Memory.DisableThirdPerson()
Else
ThirdPerson = True
Memory.EnableThirdPerson()
End If
ElseIf n2Down = True Then
Console.SilentShot()
ElseIf n3Down = True Then
Console.Specator()
ElseIf n4Down = True Then
Console.Time()
ElseIf n5Down = True Then
Console.Reconnect()
ElseIf n6Down = True Then
Console.Connect(“213.251.176.208:28305″)
Console.SendText(“Echo Connecting to LCA V2 Sniper only”)
Console.SendText(“Echo IP: 213.251.176.208:28305″)
Exit Sub
ElseIf n7Down = True Then
Console.Connect(“213.251.176.208:12000″)
Console.SendText(“Echo Connecting to LCA Stalingrad Sniper only”)
Console.SendText(“Echo IP: 213.251.176.208:12000″)
ElseIf n8Down = True Then
Console.Connect(“217.79.181.142:27001″)
Console.SendText(“Echo Connecting to [NAG] Stalingrad Sniper only 1″)
Console.SendText(“Echo IP: 217.79.181.142:27001″)
ElseIf n9Down = True Then
Console.Connect(“213.133.101.46:27001″)
Console.SendText(“Echo Connecting to [NAG] Stalingrad Sniper only 2″)
Console.SendText(“Echo IP: 213.133.101.46:27001″)
ElseIf minusDown = True Then
WindowFunctions.MinimiseWindow()
End If
End Sub
As you can see, it just checks what key is down, and then if the specified one is, it carries out the function. n0 and n1 toggle the two memory functions by checking a Boolean to see if the function is enabled or not.
I was playing again earlier and thought about making a more accurate sniper rifle.
I tried to just make a bind:
bind MOUSE1 “+attacksecondary; +attackprimary; -attacksecondary”
However, due to the way that MoHAA works, this would not carry out the zoom out function. So, I looked through the cmdlist, and found the zoomoff function, and made a new bind:
bind MOUSE1 “+attacksecondary; +attackprimary; zoomoff”
Whilst this worked when playing on a local server, I tried it on another server and it did not work.
So now, I have not actually done this, but I would also hook the mouse, then if the mouse is clicked I would send these messages to console, after unbinding Mouse1 in game:
Console.SendText(“+attacksecondary”)
Console.SendText(“+attackprimary”)
Console.SendText(“-attacksecondary”)
But that however would do that for every single gun in the game, so I looked further for a console command that would give me the name of the gun currently in use. I searched both the cmdlist and the cvarslist, to no avail.
I then went searching in the memory, and found a number of helpful addresses:
010EEEF0 – Text[22] – The name of the gun as a string
010EEF40 – 4 Bytes – The gun as an integer
I decided that the best way to do it would be using the integer, and then a list of values to see what gun is currently in use. I tested all the weapons and created this list
Value/Weapon
1 – Papers
2 – Colt 45
3 – Walther P38
4 – Hi Standard Silenced
5 – M1 Garand
6 – Mauser KAR 98K
7 – KAR98 – Sniper
8 – Springfield
9 – Thompson
10 – MP40
11 – BAR
12 – StG 44
13 – Frag Grenade
14 – Stielhandgranate
15 – Bazooka
16 – Panzerschreck
Now, I can read the memory at that address, and if the current weapon is either 7 or 8, it will send the zoom in, shoot, zoom out function for a 100% accurate shot.
VB Net – Mouse Macro Basics
Got bored so I’ve decided that I’m going to make a little macro program, and ill post the updates here.
Currently, I’ve got the basic structure and events working and I’ve tested it on a reactions tester to see how efficient it was.
Currently, it’s started using a HotKey, and detects the message and starts a background worker.
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
MyBase.WndProc(m)
If m.Msg = WM_HOTKEY Then
If BackgroundWorker1.IsBusy = False Then
BackgroundWorker1.RunWorkerAsync()
stops = False
Else
stops = True
End If
ElseIf m.Msg = WM_QUERYENDSESSION Then
stops = True
Application.Exit()
End If
End Sub
The stops is a global Boolean and is in there as a separate way to end the macro’s loop, in case something has gone wrong. The first press of the HotKey starts the macro, the second ends it.
ElseIf m.Msg = WM_QUERYENDSESSION Then
Is just in there if the message detected is the Windows Shutdown message, the application closes and ends the loop
Now, we have to look at how exactly we are going to create our mouse functions. Firstly, let’s look at the basic mouse click:
I’m carrying out this function using the mouse_event library:
Private Declare Sub mouse_event Lib “user32″ (ByVal dwFlags As Long, ByVal dx As Long, ByVal dy As Long, ByVal cButtons As Long, ByVal dwExtraInfo As Long)
This is used with the below mouse event constants:
Const MOUSEEVENTF_MOVE As Int32 = &H1
Const MOUSEEVENTF_LEFTDOWN As Int32 = &H2
Const MOUSEEVENTF_LEFTUP As Int32 = &H4
Const MOUSEEVENTF_RIGHTDOWN As Int32 = &H8
Const MOUSEEVENTF_RIGHTUP As Int32 = &H10
Const MOUSEEVENTF_MIDDLEDOWN As Int32 = &H20
Const MOUSEEVENTF_MIDDLEUP As Int32 = &H40
Const MOUSEEVENTF_ABSOLUTE As Int32 = &H8000
Const MOUSEEVENTF_WHEEL As Int32 = &H800
For the sake of ease, we will only be using the dwFlags option of the mouse_events library, in order to peform a mouse click.
For a left mouse click:
mouse_event(MOUSEEVENTF_LEFTDOWN + MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)
This will click the mouse at the cursors current location.
Next, we will look at moving the mouse to specified coordinates.
This isn’t hard, you can either move the mouse using the mouse_event library or you can set the cursor location like this:
Windows.Forms.Cursor.Position = New Point(700, 600)
This will move the mouse location to the specified point on the screen.
Next what we will look at is Pixel colour detection. This is done using the GetPixel and CreateDC API:
<Runtime.InteropServices.DllImport(“gdi32.dll”)> Private Shared Function GetPixel(ByVal hdc As IntPtr, ByVal nXPos As Integer, ByVal nYPos As Integer) As Integer
End Function
<Runtime.InteropServices.DllImport(“gdi32.dll”)> Private Shared Function CreateDC(ByVal lpszDriver As String, ByVal lpszDevice As String, ByVal lpszOutput As String, ByVal lpInitData As IntPtr) As IntPtr
End Function
<Runtime.InteropServices.DllImport(“gdi32.dll”)> Private Shared Function DeleteDC(ByVal hdc As IntPtr) As Boolean
End Function
We create a function in order to easily provide us with information on the pixel colour:
Private Function GetPixelColor(ByVal x As Integer, ByVal y As Integer) As Color
”This gets the pixel colour from the specified x/y coordinates
Dim Scrn_hdc As IntPtr = CreateDC(“Display”, Nothing, Nothing, IntPtr.Zero)
”Display being the name of the driver (Aka the screen display)
Dim Colour As Integer = GetPixel(Scrn_hdc, x, y)
”Gets pixel information from this hdc
DeleteDC(Scrn_hdc)
Return Color.FromArgb(Colour And &HFF, (Colour And &HFF00) >> 8, (Colour And &HFF0000) >> 16)
”Returns the colour value
End Function
We now have everything we need to create a basic pixel checker.
Now, back to the Background Worker. This is where we will do the pixel checking, on a loop
Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Dim count As Integer = 0
Do
If GetPixelColor(530, 540) <> Color.FromArgb(255, 255, 0, 0) Then
”Waits for the colour at that point to change from Red
Windows.Forms.Cursor.Position = New Point(530, 540)
”Moves the mouse cursor
mouse_event(MOUSEEVENTF_LEFTDOWN + MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)
‘ mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)
”Clicks the mouse
count += 1
”Adds one to count
Windows.Forms.Cursor.Position = New Point(700, 600)
”Moves the mouse cursor out of the way
System.Threading.Thread.Sleep(50)
”Sleeps the thread
If count = 5 Then
”If its done 5 clicks, it sets stops to true
stops = True
End If
End If
System.Threading.Thread.Sleep(1)
”Pause the loop
Loop Until stops = True ‘
‘Loop until stops is true, either set when count = 5 or externally
End Sub
This is just a basic example. It checks the pixel colour at 530,540 and if it is not Red it moves the mouse to that location and clicks. It then moves the mouse off of that location and adds one to the loop.
If the loop has been carried out 5 times, it then sets stops to true and the macro is stopped.
VB Net – Global Hotkey
Private Declare Function RegisterHotKey Lib “user32″ (ByVal hwnd As IntPtr, ByVal id As Integer, ByVal fsModifiers As Integer, ByVal vk As Integer) As Integer
Private Declare Function UnregisterHotKey Lib “user32″ (ByVal hwnd As IntPtr, ByVal id As Integer) As Integer
Private Declare Function GlobalAddAtom Lib “kernel32″ Alias “GlobalAddAtomA” (ByVal lpString As String) As Short
Private Declare Function GlobalDeleteAtom Lib “kernel32″ (ByVal nAtom As Short) As Short
Private Const MOD_ALT As Integer = 1
Private Const MOD_CONTROL As Integer = 2
Private Const MOD_SHIFT As Integer = 4
Private Const MOD_WIN As Integer = 8
Private Const MOD_NONE As Integer = 0
Private Const WM_HOTKEY As Integer = &H312
Dim hotkeyID As Short
Sub RegisterGHK(ByVal hotkey As Keys, ByVal modifiers As Integer)
Try
Dim atomName As String = Process.GetCurrentProcess.Id.ToString(“X8″) & Me.Name
hotkeyID = GlobalAddAtom(atomName)
If hotkeyID = 0 Then
Throw New Exception(“Unable to generate unique hotkey ID. Error code: ” & System.Runtime.InteropServices.Marshal.GetLastWin32Error().ToString)
End If
If RegisterHotKey(Me.Handle, hotkeyID, modifiers, CInt(hotkey)) = 0 Then
Throw New Exception(“Unable to register hotkey. Error code: ” & System.Runtime.InteropServices.Marshal.GetLastWin32Error.ToString)
End If
Catch ex As Exception
UnregisterGHK()
End Try
End Sub
Sub UnregisterGHK()
If Me.hotkeyID <> 0 Then
UnregisterHotKey(Me.Handle, hotkeyID)
GlobalDeleteAtom(hotkeyID)
hotkeyID = 0
End If
End Sub
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
MyBase.WndProc(m)
If m.Msg = WM_HOTKEY Then
Me.Activate()
MessageBox.Show(“Hotkey has been pressed”)
End If
Leave a Comment
Comments (1)
Leave a Comment