 |
Cheat Engine The Official Site of Cheat Engine
|
| View previous topic :: View next topic |
| Author |
Message |
Mal1t1a Cheater
Reputation: 0
Joined: 03 Jan 2010 Posts: 40
|
Posted: Tue Jun 03, 2014 7:25 pm Post subject: Reliably hook a game's engine |
|
|
Before you read
I want to make this as clear as day: NOTHING THAT I AM DOING INVOLVES WRITING TO THE ACTUAL PROCESS. I AM NOT MANIPULATING MEMORY AND THE ENTIRE GAME IS SERVER-SIDE.
Introduction
Okay, it's been awhile since I last posted about hooking into a game's memory to inject a .dll, that I never did get to finish. Harddrive failure, and there was no chance at recovering the lost data (tried with spinrite and alternatives). So I gave up on it, so I thought. I've come back to the hacking scene as my programming skills need to be sharpened. I've been thinking about this for awhile, and a .dll injection seems like the only way to go, because a timer just doesn't do it. I need to know exactly when something changes exactly AFTER it changes and exactly BEFORE it changes again.
Background experience
I'm experienced at reverse engineering games and applications, but I'm by no means a pro. I can navigate pretty fluidly around the basics like the back of my hand. What I mean by this is identifying the memory type, and finding it. Sometimes this is very tricky, what with pointers and memory types that should be one thing but turn out to be another. Various game events, one of which I want to hook is object specific updates.
My goal
My goal is to create a basic A.I., which I have been working on in VB.NET using a timer that updates every milisecond, recording the execution time of the A.I. and adjusts itself to the computation speed so it doesn't create lag, and providing an accurate "Thought rate" or "Processing rate". This process get's very cpu intensive due to the extent of the amount of "ReadProcessMemory" calls being made to get a fresh "game state". Sometimes it takes anywhere from 1 - 5 SECONDS. To play this game you need to have a reaction time less than 1000ms (more like 100ms ~ 250ms) and even then it doesn't mean you'll win. I want to battle it against the A.I. that is already implemented inside of the game. All of this to watch my own A.I. grow and become better and better.
Code history and snippets
My current code is heavily based in VB.NET because that's what I grew up learning, it's the easiest to understand, and it's pretty fast to code in. I HAVE to use structured send and post messages in order to do a simple tasks like mouse operation (move and click), and keyboard operation (hold key, release key, press key, and use modifiers). I've already put in a ton of hours of work to try to get a small library of functions and methods to simulate "gameplay".
Something as simple as sending a "Mouse Move and Click" seems to be very bloated:
| Code: |
Public Sub SendMouseMoveClick(ByVal ProcessName As String, ByVal Spot As Point, ByVal mkButton As IntPtr)
Dim hWnd As IntPtr = GetProcessWindowHandle(ProcessName)
If mkButton = MK_LBUTTON Then
SendMessage(hWnd, WM_MOUSEACTIVATE, hWnd, MakeLParam(1, WM_LBUTTONDOWN))
SendMessage(hWnd, WM_SETCURSOR, WM_MOUSEMOVE, MakeLParam(1, WM_MOUSEMOVE))
SendMessage(hWnd, WM_MOUSEMOVE, WM_MOUSEMOVE, MakeLParam(Spot.X, Spot.Y))
SendMessage(hWnd, WM_SETCURSOR, WM_LBUTTONDOWN, MakeLParam(1, WM_LBUTTONDOWN))
SendMessage(hWnd, WM_LBUTTONDOWN, mkButton, MakeLParam(Spot.X, Spot.Y))
SendMessage(hWnd, WM_SETCURSOR, WM_MOUSEMOVE, MakeLParam(1, WM_MOUSEMOVE))
SendMessage(hWnd, WM_MOUSEMOVE, WM_MOUSEMOVE, MakeLParam(Spot.X, Spot.Y))
SendMessage(hWnd, WM_SETCURSOR, WM_LBUTTONUP, MakeLParam(1, WM_LBUTTONUP))
SendMessage(hWnd, WM_LBUTTONUP, 0, MakeLParam(Spot.X, Spot.Y))
ElseIf mkButton = MK_RBUTTON Then
SendMessage(hWnd, WM_MOUSEACTIVATE, hWnd, MakeLParam(1, WM_RBUTTONDOWN))
SendMessage(hWnd, WM_SETCURSOR, WM_MOUSEMOVE, MakeLParam(1, WM_MOUSEMOVE))
SendMessage(hWnd, WM_MOUSEMOVE, WM_MOUSEMOVE, MakeLParam(Spot.X, Spot.Y))
SendMessage(hWnd, WM_SETCURSOR, WM_RBUTTONDOWN, MakeLParam(1, WM_RBUTTONDOWN))
SendMessage(hWnd, WM_RBUTTONDOWN, mkButton, MakeLParam(Spot.X, Spot.Y))
SendMessage(hWnd, WM_SETCURSOR, WM_MOUSEMOVE, MakeLParam(1, WM_MOUSEMOVE))
SendMessage(hWnd, WM_MOUSEMOVE, WM_MOUSEMOVE, MakeLParam(Spot.X, Spot.Y))
SendMessage(hWnd, WM_SETCURSOR, WM_RBUTTONUP, MakeLParam(1, WM_RBUTTONUP))
SendMessage(hWnd, WM_RBUTTONUP, 0, MakeLParam(Spot.X, Spot.Y))
End If
End Sub
|
As you can see, it's alot of messages being sent for something that should just be a WM_MOUSEMOVE, WM_(L|R)BUTTONDOWN, and WM_(L|R)BUTTONUP. I used spy++ to intercept these messages and I tried many MANY different variants; all of which failed. The game only in-takes specific messages in a specific order as a specific type. For example, I can't POST any of these messages or the game will not understand. Maybe I approached this wrong but this method does in-fact, work.
Same goes with the keyboards messages. The game only in-takes a "Send" message, in this order and with the bits of the message changed accordingly:
WM_KEYDOWN
WM_CHAR
WM_KEYUP
so I created these methods to emulate:
| Code: |
Public Sub SendHoldKey(ByVal hWnd As IntPtr, ByVal vKey As Integer, Optional ByVal scanCodeValue As Integer = &H1C, Optional ByVal repeatCount As Integer = 0)
Dim scanCode As Integer = scanCodeValue << 16 'shift 16 bits
Dim extended As Integer = 0 << 24 'shift 16 + 8 bits
Dim reserved As Integer = 0 'Not to be used so no need to shift all zeroes.
Dim contextCode As Integer = 0 << 29 'shift 16 + 8 + 1 + 4
Dim previousState As Integer = 0 << 30 'shift 16 + 8 + 1 + 4 + 1
Dim transitionState As Integer = 0 << 31 'shift 16 + 8 + 1 + 4 + 1 + 1
Dim lParam As Integer = repeatCount + _
scanCode + _
extended + _
reserved + _
contextCode + _
previousState + _
transitionState
SendMessage(hWnd, WM_KEYDOWN, vKey, lParam)
End Sub
Public Sub SendCharKey(ByVal hWnd As IntPtr, ByVal vKey As Integer, Optional ByVal scanCodeValue As Integer = &H1C, Optional ByVal repeatCount As Integer = 0)
Dim scanCode As Integer = scanCodeValue << 16 'shift 16 bits
Dim extended As Integer = 0 << 24 'shift 16 + 8 bits
Dim reserved As Integer = 0 'Not to be used so no need to shift all zeroes.
Dim contextCode As Integer = 0 << 29 'shift 16 + 8 + 1 + 4
Dim previousState As Integer = 0 << 30 'shift 16 + 8 + 1 + 4 + 1
Dim transitionState As Integer = 0 << 31 'shift 16 + 8 + 1 + 4 + 1 + 1
Dim lParam As Integer = repeatCount + _
scanCode + _
extended + _
reserved + _
contextCode + _
previousState + _
transitionState
SendMessage(hWnd, WM_CHAR, vKey, lParam)
End Sub
Public Sub SendReleaseKey(ByVal hWnd As IntPtr, ByVal vKey As Integer, Optional ByVal scanCodeValue As Integer = &H1C, Optional ByVal repeatCount As Integer = 0)
Dim scanCode As Integer = scanCodeValue << 16 'shift 16 bits
Dim extended As Integer = 0 << 24 'shift 16 + 8 bits
Dim reserved As Integer = 0 'Not to be used so no need to shift all zeroes.
Dim contextCode As Integer = 0 << 29 'shift 16 + 8 + 1 + 4
Dim previousState As Integer = 1 << 30 'shift 16 + 8 + 1 + 4 + 1
Dim transitionState As Integer = 1 << 31 'shift 16 + 8 + 1 + 4 + 1 + 1
Dim lParam As Integer = repeatCount + _
scanCode + _
extended + _
reserved + _
contextCode + _
previousState + _
transitionState
PostMessage(hWnd, WM_KEYUP, vKey, lParam)
End Sub
|
The keyboard code snippets appear to work flawlessly, where-as the mouse code snippets work "PROPERLY" only when my cursor is over the game's window. It still "mostly" works when it's not. It's been awhile since I fiddled with that bit of code and used spy++, but I remember trying to use WM_SETFOCUS and WM_ACTIVATE as per what spy++ reported. I think my tests were unsuccessful. I'll have to revisit them again sometime soon.
What I'm asking for
How can I inject a .DLL file to read memory changes, and change the variables in the .DLL's memory accordingly so.
Knowledge of whether or not my approach to this is proper.
A coding partner (if you want to join in on this project, but I don't expect anyone to want to join).
what I'm NOT asking for
Hacks.
Cheats.
Memory manipulation.
Anything that deals with Writing routines.
Last edited by Mal1t1a on Tue Jun 03, 2014 9:36 pm; edited 4 times in total |
|
| Back to top |
|
 |
atom0s Moderator
Reputation: 205
Joined: 25 Jan 2006 Posts: 8587 Location: 127.0.0.1
|
Posted: Tue Jun 03, 2014 7:29 pm Post subject: |
|
|
We do not discuss multiplayer cheating / hacking on this site.
http://forum.cheatengine.org/faq.php#0
Regardless of your intent, you named the game and the intent involves things that break the ToS of the game which break the rules here as well. So we do not allow discussion of things like this here.
_________________
- Retired. |
|
| Back to top |
|
 |
Mal1t1a Cheater
Reputation: 0
Joined: 03 Jan 2010 Posts: 40
|
Posted: Tue Jun 03, 2014 9:37 pm Post subject: |
|
|
| atom0s wrote: | We do not discuss multiplayer cheating / hacking on this site.
http://forum.cheatengine.org/faq.php#0
Regardless of your intent, you named the game and the intent involves things that break the ToS of the game which break the rules here as well. So we do not allow discussion of things like this here. |
Okay, I stripped the direct relations, how about now? Also I'm not playing Multiplayer.
|
|
| Back to top |
|
 |
zm0d Master Cheater
Reputation: 7
Joined: 06 Nov 2013 Posts: 423
|
Posted: Wed Jun 04, 2014 4:43 am Post subject: |
|
|
When you inject a DLL into a process, you are modifying the processes memory. Also you write the DLL to the target process.
| Mal1t1a wrote: | what I'm NOT asking for
Hacks.
Cheats.
Memory manipulation.
Anything that deals with Writing routines. |
|
|
| Back to top |
|
 |
atom0s Moderator
Reputation: 205
Joined: 25 Jan 2006 Posts: 8587 Location: 127.0.0.1
|
Posted: Wed Jun 04, 2014 11:58 am Post subject: |
|
|
Given your goal some things I would really point out to you for speed:
1. Injection is better than stand-alone.
If the game has no anti-cheat to worry about I would inject into the game for direct memory access. You will have much faster reads since you can directly read the memory instead of using an API call.
Along with this, you can directly inject input into the game while you are injected into it. And with that, you can have the game minimized entirely and use a form of IPC to send input from an external program as well.
2. Fixing Slow ReadProcessMemory Calls
An ideal way to read memory is in chunks instead of single calls. If you read a chunk in, you can cast it to a structure which is a ton faster than reading certain values 1 by 1. If you are reading 1 by 1 you are creating a lot of overhead and unneeded calls, which in turn slows down the process of getting all the data you need.
Being injected also makes this easy since you can cast the memory directly to a structure removing all the middle-man API calls and such too.
3. Ditch Vb.NET
Simply put, get rid of it. It is a horrible language that is barely holding on.
If you want to stay in the realm of .NET, I would recommend C#
If you want to start getting more in depth with game hacking with hooking, injection, and so on, I would recommend C/C++ then. You can do injection with .NET languages as well but its a lot more work.
Any language that can access the system API can be used for game hacking though, so the choice is yours, that is just my opinion.
| Quote: | | How can I inject a .DLL file to read memory changes, and change the variables in the .DLL's memory accordingly so. |
Going along with what I just said, I do not recommend trying to learn how to do DLL injection in .NET languages. It is a hefty amount of work that gets overall annoying and just not really worth it. I would recommend moving into a language where injection is much more common, such as:
- C / C++
- ASM
- Delphi
- etc.
Once you understand and are comfortable with one of these languages, there are several methods you can use to do DLL injection.
- CreateRemoteThread
- Manual Mapping
- SetWindowsHookEx
- IAT injection to force your library to load.
- Code injection to overwrite the OEP of the process to jump to a cave to load your DLL.
- System wide registry entry which forces your DLL to load into every process.
And so on. There are a lot of ways to get a DLL into a process.
_________________
- Retired. |
|
| Back to top |
|
 |
zm0d Master Cheater
Reputation: 7
Joined: 06 Nov 2013 Posts: 423
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You can download files in this forum
|
|