 |
Cheat Engine The Official Site of Cheat Engine
|
| View previous topic :: View next topic |
| Author |
Message |
Poent Cheater
Reputation: 0
Joined: 24 Apr 2007 Posts: 32
|
Posted: Mon Mar 24, 2008 2:23 am Post subject: [C++] Hooking the PeekMessage Loop? |
|
|
As you may or may not know, the vast majority of DirectX games out there utilize the PeekMessage function to handle almost all of their function calls once the game has loaded. If the Peek message loop doesn;t ring any bells then some of you, rather, may be familiar with the GetMessage() loop. This Message Handle is perfectly logical for Window programming, because generally speaking Windows applications, Word for example, tend to sit and do nothing until you make a move.
This doesn't work well however for game programming . While all this waiting is going on,the game needs to be creating thirty to sixty fully-rendered 3D images per second and putting them on the screen without any delay at all. And so we are presented with a rather interesting problem, because Windows, if it sends any messages, will most definitely not be sending thirty of them per second.
This is where PeekMessage comes in. It doesn't wait for anything. PeekMessage() just looks into the message queue and checks to see if any messages are waiting. If not, the program will continue on, allowing us to do what we need.
In light of that little bit of knowledge (which may or may not be exactly accurate) it should quickly became obvious that hooking and monitoring calls that pass threw the message queue would allow anyone to actively and accurately respond to events that happened in-game, whether that response is directed towards hacking or towards simply making a kind of AI.
More specifically (leaving it at a simplistic level for ease of understanding the concept...) lets say that in a game -- a player pings the mini map. The program (or hack, or bot.. etc), which would be monitoring all calls that are passed to the message handle, recognizes this function and then moves the users screen to that ping location based off the calls that pass threw this loop.
The concept is simple enough, especially if you know exactly when and where to look in a game for this loop. However, I would like to be able to actively monitor a real time game that I DO NOT have to source code to.
This is where I would like some help...
How can I go about locating where this PeekMessage function is loaded into the memory, and how can i actively return and monitor the data that is passed threw this function?
On a side note, getting ahead of myself here and looking a the nitty gritty, I can see where dll injection would be a solution to almost my entire conundrum. With that in mind... and also knowing that I have never attempted dll injection, AND knowing that in order to inject the dll i would still need to know the location of the PeekMessage Function one way or another... I do not necessarily want to modify any in game memory. I simply want to have a program respond to what it sees. outside of the program its monitoring. are there stills ways to indirectly monitor those calls?
Any and all help would be very much appreciated and I thank you all for the read. If needed, I will be more than happy to supply simple programs that demo the PeekMessage function and windows message calls in case any of you would like something simplistic and static to work with if you choose to help me out with this.
Once again, thanks ahead of time for the help. any and all comments are much appreciated.
_________________
There Are No Stupid Questions, But There Are A Lot Of Inquisitive Idiots. |
|
| Back to top |
|
 |
Symbol I'm a spammer
Reputation: 0
Joined: 18 Apr 2007 Posts: 5094 Location: Israel.
|
Posted: Mon Mar 24, 2008 3:22 am Post subject: |
|
|
| If you don't want to change the game's memory then you can probably debug the game, set a breakpoint at peekmessage address, get all the information you need and run the game.
|
|
| Back to top |
|
 |
Poent Cheater
Reputation: 0
Joined: 24 Apr 2007 Posts: 32
|
Posted: Mon Mar 24, 2008 11:00 am Post subject: |
|
|
how do I go about finding the address in the first place? I've tried using Ollydbg to search for basic functions but I dont know quite enough to be able to find it exactly.
EDIT:
After looking a little more closely at the peekmessage function it seems that while all of the program must pass over this loop every cycle, it does not have to pass independent functions threw it. for example only windows specific messages are dispatched threw this loop. While the Game_run() and Render_frame() type functions are simply called and updated after it passes the windows call check.
This leaves me in a little bit more complicated situation than i had originally intended or thought it to be. Rather than monitoring the peek message loop a need to monitor independant calls. While in some games such as 2d RPGS and rts's lots of things would normally pass threw that function, in newer games.. they dont..
So, allow me to update my question.. How would I go about finding a specifically called function in a game that will occur intermittently and how would I go about forwarding that message to an application in order to form a response to it?
P.S.
For those of you trying to follow along, here is some demo code I wrote up using the peekmessage loop and how a game would generally look.
| Code: | // include the basic windows header file
#include <windows.h>
#include <windowsx.h>
#define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEY_UP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)
// the WindowProc function prototype
LRESULT CALLBACK WindowProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam);
void run_game();
void renderframe();
void blah();
//our main function
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
HWND hWnd; //handle to the window
WNDCLASSEX wc; //creates the windows class struct
ZeroMemory(&wc, sizeof(WNDCLASSEX)); // clear out the window class for use
// fill in the struct with the needed information
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)WindowProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
wc.lpszClassName = "WindowClass1";
// register the window class
RegisterClassEx(&wc);
// create the window and use the result as the handle
hWnd = CreateWindowEx(NULL,"WindowClass1","test debug program",
WS_OVERLAPPEDWINDOW,300,300,500,400,NULL,
NULL,hInstance,NULL);
// display the window on the screen
ShowWindow(hWnd, nCmdShow);
// this struct holds Windows event messages
MSG msg;
// Enter the infinite message loop.
/*This is where we will start to pass over PeekMessage to see if there is anything in the queue for windows to handle.*/
while(TRUE)
{
// Check to see if any messages are waiting in the queue
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
// If the message is WM_QUIT, exit the while loop
if (msg.message == WM_QUIT)
break;
//Test if a key has been pressed. If so dispatch it and display it for us. then wait for our input.
else if (msg.message == WM_KEYFIRST){
MessageBox(0, "Test Call to peek message", 0, MB_OK);
}
// translate keystroke messages into the right format
TranslateMessage(&msg);
// send the message to the WindowProc function
DispatchMessage(&msg);
}
run_game(); //this is where the function calls i'm interested in will be (generally)
renderframe(); //possibly be able to monitor directX render calls with this.
blah();
//this is just the escape sequence... press esc
if(KEY_DOWN(VK_ESCAPE)){
PostMessage(hWnd, WM_DESTROY, 0, 0);
}
}
// return this part of the WM_QUIT message to Windows
return msg.wParam;
}
// this is the main message handler for the program
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
// sort through and find what code to run for the message given
switch(message)
{
// this message is read when the window is closed
case WM_DESTROY:
{
// close the application entirely
PostQuitMessage(0);
return 0;
} break;
}
// Handle any messages the switch statement didn't
return DefWindowProc (hWnd, message, wParam, lParam);
}
void run_game(){
//game variable update's here
}
void renderframe(){
//show those updated variables here
}
void blah(){
//whatever else is needed here
} |
_________________
There Are No Stupid Questions, But There Are A Lot Of Inquisitive Idiots. |
|
| Back to top |
|
 |
Symbol I'm a spammer
Reputation: 0
Joined: 18 Apr 2007 Posts: 5094 Location: Israel.
|
Posted: Mon Mar 24, 2008 11:47 am Post subject: |
|
|
You can create a little hook, for example:
| Code: | DWORD PeekMessageAddress = GetProcAddress(GetModuleHandle("User32.dll"), "PeekMessageA");
*(char*)PeekMessageAddress = 0xE9; //JMP
*(DWORD*)(PeekMessageAddress+1) = (int)&Hook - PostMessageAddress - 5;
...
...
...
....... hook(LPMSG lpMsg, HWND hWnd, UINT FilterMin, UINT FilterMax, UINT wRemoveMsg)
{
/*
Do something
*/
_asm
{
ret 14
}
} |
or something like that...
I gotta go now, but I don't really understand what you want to do... control the game's messages?
|
|
| Back to top |
|
 |
Poent Cheater
Reputation: 0
Joined: 24 Apr 2007 Posts: 32
|
Posted: Mon Mar 24, 2008 1:14 pm Post subject: |
|
|
I dont want to comtrol anything really, not at this point at any rate. i simply want to respond to the game when a specific function is called.
EG:
lets say that i hold down alt and press "G". In warcraft 3, this triggers a function that, when the mouse is left click, it generates a 'ping' at a location.
I want to be able to either record this ping with an external program, or generate some kind of macro to respond to it with...
Or in another sudo example, i want to be able to see that a ping was made, then have an external program automatically move the screen to that pings location.
-----------
Granted, i want this to not be specific to just pings of course, in other games where there may be some kind of trigger event or message event I could use this to respond actively to what its doing.
Also as mentioned above, when i was researching a bit more about the PeekMessage function i found that it really isn;t the part of the program that i want to monitor, i want to monitor custom function calls.
_________________
There Are No Stupid Questions, But There Are A Lot Of Inquisitive Idiots. |
|
| Back to top |
|
 |
Symbol I'm a spammer
Reputation: 0
Joined: 18 Apr 2007 Posts: 5094 Location: Israel.
|
Posted: Mon Mar 24, 2008 2:03 pm Post subject: |
|
|
| Poent wrote: | I dont want to comtrol anything really, not at this point at any rate. i simply want to respond to the game when a specific function is called.
EG:
lets say that i hold down alt and press "G". In warcraft 3, this triggers a function that, when the mouse is left click, it generates a 'ping' at a location.
I want to be able to either record this ping with an external program, or generate some kind of macro to respond to it with... |
Then its probably the best to make a DLL that does that hook, for example, leys say you want to make some file with everything you did in game, some sort of "history" of things you've done.
You see "WM_HOTKEY message with wParam XXX and ID YYY is waiting, time to attack" then add "Attacked with skill X at something" if thats what you mean...
| Poent wrote: | | in other games where there may be some kind of trigger event or message event I could use this to respond actively to what its doing. |
For example, "attacked now, lets check HP and MP and if needed use a postion"?
| Poent wrote: | | Also as mentioned above, when i was researching a bit more about the PeekMessage function i found that it really isn't the part of the program that i want to monitor, i want to monitor custom function calls. |
Good luck finding every call and finding what it does...
Try finding the message loop? (or peekmessage loop, is it?)
Best thing you can do is hook it with a DLL or something...
|
|
| Back to top |
|
 |
Poent Cheater
Reputation: 0
Joined: 24 Apr 2007 Posts: 32
|
Posted: Mon Mar 24, 2008 2:42 pm Post subject: |
|
|
So i've pretty much hit the point when I agree.. i think i need to hook it with a Dll. but i'm still not exactly sure how this will all work out.
| Quote: |
Then its probably the best to make a DLL that does that hook, for example, leys say you want to make some file with everything you did in game, some sort of "history" of things you've done.
You see "WM_HOTKEY message with wParam XXX and ID YYY is waiting, time to attack" then add "Attacked with skill X at something" if thats what you mean...
For example, "attacked now, lets check HP and MP and if needed use a position"? |
exactly, so assuming that i can get a dll injected and hooked onto the process (I'll worry about that later) how would I be able to see the function i need? I don't necessarily want locate and find out what every call does.. just a few very specific ones.
With my burning desire to learn more about this, i went ahead and created a small application that kindof does what a game should do (WAY SIMPLISTIC) and created a custom function that would be called when i hit the down arrow key. here is the code:
| Code: | #include <iostream>
#include <windows.h>
#define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEY_UP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)
void HERE_IT_IS(int& X);
using namespace std;
int main(){
int x = 0;
cout<<"My functions"<<endl;
while(TRUE){
if(KEY_DOWN(VK_ESCAPE)){
break;
}
else if(KEY_DOWN(VK_DOWN)){
HERE_IT_IS(x);
}
Sleep(50);
}
}
void HERE_IT_IS(int& x){
x++;
cout<<"function has passed "<< x <<" times."<<endl;
}
|
Lets say i want to create a program to see when the 'HERE_IT_IS' function is called. This is almost exactly the scenario I'm looking at except for the part that... I wouldn't have the source to this. only the program.
How would I go about finding that function and watching for it actively?
i pretty much just want to be able to do something along the lines of
| Code: | if(HERE_IT_IS == called){
do something();
} |
_________________
There Are No Stupid Questions, But There Are A Lot Of Inquisitive Idiots. |
|
| Back to top |
|
 |
Symbol I'm a spammer
Reputation: 0
Joined: 18 Apr 2007 Posts: 5094 Location: Israel.
|
Posted: Mon Mar 24, 2008 3:04 pm Post subject: |
|
|
| Poent wrote: | assuming that i can get a dll injected and hooked onto the process (I'll worry about that later) how would I be able to see the function i need? I don't necessarily want locate and find out what every call does.. just a few very specific ones.
With my burning desire to learn more about this, i went ahead and created a small application that kindof does what a game should do (WAY SIMPLISTIC) and created a custom function that would be called when i hit the down arrow key.
Lets say i want to create a program to see when the 'HERE_IT_IS' function is called. This is almost exactly the scenario I'm looking at except for the part that... I wouldn't have the source to this. only the program.
How would I go about finding that function and watching for it actively?
i pretty much just want to be able to do something along the lines of
| Code: | if(HERE_IT_IS == called){
do something();
} |
|
It doesn't really matters if you hook PeekMessage, because the message loop (PeekMessage loop?) is only to see which messages are waiting and translating them (for example, "TextBoxX is focused, the key 0x30 (0) was pressed, lets draw some pixels") but the window procedure (WNDCLASSEX.lpfnWndProc :O ) is checking which message was sent and tells the program what to do.
Simply find out where the window procedure is located at and you'll see a really long switch with lots of calls.
Thats what you'll need.
|
|
| Back to top |
|
 |
Poent Cheater
Reputation: 0
Joined: 24 Apr 2007 Posts: 32
|
Posted: Mon Mar 24, 2008 5:55 pm Post subject: |
|
|
Being mostly new to olly, how do I go about finding where the windows procedure is?
also, when dissassebling the test function program above... I found that my function was NEVER listed in the machine language as HERE_IT_IS as labeled. instead there were simply pointers. The function itself came out to be:
| Code: | 00401432 /$ 55 PUSH EBP
00401433 |. 89E5 MOV EBP,ESP
00401435 |. 83EC 08 SUB ESP,8
00401438 |. 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8]
0040143B |. FF00 INC DWORD PTR DS:[EAX]
0040143D |. C74424 04 0D0>MOV DWORD PTR SS:[ESP+4],0044000D ; ASCII "function has passed "
00401445 |. C70424 C03344>MOV DWORD PTR SS:[ESP],004433C0
0040144C |. E8 A7AC0300 CALL 0043C0F8
00401451 |. 89C2 MOV EDX,EAX
00401453 |. 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8]
00401456 |. 8B00 MOV EAX,DWORD PTR DS:[EAX]
00401458 |. 894424 04 MOV DWORD PTR SS:[ESP+4],EAX
0040145C |. 891424 MOV DWORD PTR SS:[ESP],EDX
0040145F |. E8 2C9A0200 CALL 0042AE90
00401464 |. C74424 04 220>MOV DWORD PTR SS:[ESP+4],00440022 ; ASCII " times."
0040146C |. 890424 MOV DWORD PTR SS:[ESP],EAX
0040146F |. E8 84AC0300 CALL 0043C0F8
00401474 |. C74424 04 C8A>MOV DWORD PTR SS:[ESP+4],0043AEC8
0040147C |. 890424 MOV DWORD PTR SS:[ESP],EAX
0040147F |. E8 CC8B0200 CALL 0042A050
00401484 |. C9 LEAVE
00401485 \. C3 RET
|
as you can see nothing in there is descriptive and the only way i was able to find that ping was by whacking my threw the top part of the code and noP'ing out the check if the key is down so it forced to run the function.
On a full game this seems like it would be pretty much impossible, even assuming that they used recognizable functions like GetAsyncKeyState and assuming that I knew machine level code pretty well.
Will these functions be seen where the windows procedure is? if not how will I go about finding them?
update:
In my programming course today during our lab time I actually got a chance to butt heads with something other than a wall, and it was brought to my attention that the problem i was having was that i couldn't think of a value that would be changed as a result of this function passing, which.. globally speaking, is true. however, for the second or two that I can see a ping on the map, there HAS to be somewhere in the memory that has changed. With cheat engine, i was actually able to find 7 addresses that changed only when this function was called. Will I actually be able to trace these addresses to a call and use that call in this monitoring program?
When I ended up finding several calls to GameMain with ce. Will these be anywhere close to what I need to locate the function every time its loaded into the memory?
at address 0B400CB0 - 00 00 00 00 - mov [esi],00000000
_________________
There Are No Stupid Questions, But There Are A Lot Of Inquisitive Idiots. |
|
| Back to top |
|
 |
rapion124 Grandmaster Cheater Supreme
Reputation: 0
Joined: 25 Mar 2007 Posts: 1095
|
Posted: Wed Mar 26, 2008 4:08 pm Post subject: |
|
|
WinProc will probably have the syntax of a while loop with Peek/GetMessage and a bunch of switches. It is quite easy to find. Use OllyDBG and when the game starts, trace from the entry point until the window gets created. Then, let the program run and click "pause." On Olly, change thread and try to step each thread until the window responds. There is your WinProc thread. Monitor it and you will step into the WinProc procedure.
Also, what you write into the compiler isn't what is actually going to be in your executable. The variables in your function are actually in the stack. That's what the [ebp] are for. The compiler uses the function names to keep track of each function during compile time only.
|
|
| 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
|
|