Jump to content

  • Log In with Google      Sign In   
  • Create Account


--Game Hooking revisited--


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
3 replies to this topic

#1 Ketzer2002   Members   -  Reputation: 100

Like
0Likes
Like

Posted 23 March 2012 - 09:55 AM

Hi Guys,

first of all I would say, that I'm a new member in this forum, but I'm reading many articles and posts here quite a while just for my personal interest.

I'm a student of business informatics at a university of applied sciences in germany (ohhh my god, not a pure informatician ^^).

So what do informatics students do in there sparetime? right, they are playing some computer games and programming things... :-)

It's now a whole bunch of time, since I read many articles about Game Hooking, API Hooking and Hijaking and so on. I wonder why there are no actuall tutorials for some general approach to hook a game.

With actuall I mean newer than out of the year <= 2007... ;-), and why there is no usefull and also good documented codeline to use a generic hook for a managed code program, that is written in C#.

My approach is to set up a nice looking tutorial, that mainly doesn't go to deep in the system mechanics like: "you have to set up some 'asm' with NOP NOP NOP NOP..." because this tutorial isn't that much comprehensible for almost everyone who is interested in trying it out itself.

Certainly the tutorial shouldn't also be written like a boulevard newspaper, but clearly understandable to reward everyone reading it...

And i would like to use the newest technologies availlable, like the Visual Studio 11 Developers preview with the .NET Framework 4.5, which can be downloaded and used free for one year.

Due to the fact, that I'm a student of applied sciences I would love to create a tutorial based on a real sample. I was thinking of creating a little helper tool, which can be used in a multiplayer game to automatically inform your team members of intersting events that can occur.

What should that tool do: if the game is fully loaded and your team is assembled and ready for battle, or to explore the environment the tool should send a first messages to your teammembers, that it is ready. It should also set it's intern timer to measure the time for how long the game is running to 00:00.

After a specified key is pressed by the user who runs that tool, it should send a message to the teammembers, when exactly (measured in game time) the next important event occurs.

When the game is finished, the tool should go into a "listen state" and wait for the next game session to be started.

So far the theory and the needings. Now what do I know / what did i do:

I've dissasembled the game (or did I just tried it, I don't really know, because that's not one of my strengths ^^). But what did I see there was some nice looking functions that maybe could be used for the approach mentioned above:

the dissasembler said something like this:

function .text 0058A4D4 Controller_SendChatMessage()

if I follow the function call in the main game application we get something like this:

;
; imports from anotherdll.dll
;
.idata : 00962D08 extrn __imp_Controller_SendChatMessage:dword
; DATA XREF: Controller_SendChatMessage ^r


the returnvalue of this functions seems to be an integer and the arguments is some x, (which is also an integer, could that be???)

I've found also the Direct3DCreate9 function calls at: .text 006D2712

and the DirectInput8Create function at: 006D27E4

I tried then to API-Hijack this function and attached my programm with WINJECT. poor luck for me this apporach didn't work. I tried many things, also modified many C++ samples to get some nitty piece of information, if I could acces the function. No chance, I couldn't get anything to work. The reason: I don't understand enough of the use of hijaking api's or dll-injection...

So i tried another thing, that worked very well, but was very, very low-performance. I used managed Code (C# with .NET) to capture a defined key that is pressed for the initial message to be sent (realised that with SendKeys.SendWait(""); and GetKeyState(Keys nVirtKey); from the user32.dll

Now I want to try a combination of both and document this for further use...

I'm thinking of some code looking like this (written in pseudocode) FIRST APPROACH:

in C++:

creating a dll that can use the SendChatMessage with params to send a message to your teammates...
...that can capture key events by using the DirectInput functionalities in game and (maybe in the far future can display via Direct3dD an overlay ingame that presents a status text or an timer ticking in a corner of the User Interface).

so the dll should be implemented like this:

SendChatMessage(string message);
{
//todo: call the function in the game with the message argument;
}
boolean GetKeyboardInput()
{
//todo: dont actually know the name for the direct x function, that is called, when a key is pressed, will figure that out...
if keypressed = definedkeyformessage then
// have to figure out, how the keys are used in direct x, but that souldn't be so hard.
return true;
else
return false;
}
DrawOverlayText(string Text, int x, int y)
{
//call some Direct3D Code to draw the Text with position x and y over the graphics device used a function call.
drawthetext(Text, x, y);
}


in C#:

This could be a small desktop application with a form, that shows some additional informations in the background of the game (maybe good for debugging during the development process)
It is the main application that calls the functionalities out of the c++ dll.
I don't know if this managed code program can attach the dll to the main game process, or if this has to be done in the c++ dll itself.

When the program starts the following should happen:

While(true) //or some timer event...
{
call attachdll();//just attach dll once, so if attached, don't call this function again...
}

private attachdll()
{
if game is running
{attach dll to game();
set textbox on form: "dll succesfull attached";
}
}

Now my question to the Code Gurus is: what do I have to be aware of? Is this approach generally possible, or do I missing something? I don't ask for a complete program, not even for some code. I first want to clarify, if this could be done like this and if not so, how else?

Thanks for reading and maybe answering. :-)

Sponsor:

#2 Ketzer2002   Members   -  Reputation: 100

Like
0Likes
Like

Posted 25 March 2012 - 05:09 AM

So many readings and no replies... :-)

So I'm going to post some more content to discuss.

I've created a Win 32 C++ Programm (not that hard with VS 2010), which should inject itself into the notepad.exe... but there are some problems, maybe i can start at this point, by getting some help of the codegurus.

so here it is: the Winmain.cpp consists of the following relevant code:

int APIENTRY _tWinMain(HINSTANCE hInstance,
					 HINSTANCE hPrevInstance,
					 LPTSTR	lpCmdLine,
					 int	   nCmdShow)
{
DWORD dwThreadID = 0;
HWND hWnd = FindWindow(NULL,L"Unnamed - Notepad");
dwThreadID = GetWindowThreadProcessId(hWnd,NULL);
fnSetMyHook(dwThreadID);
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
MSG msg;
HACCEL hAccelTable;
// Globale Zeichenfolgen initialisieren
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_WINDOWSHOOK, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Anwendungsinitialisierung ausführen:
if (!InitInstance (hInstance, nCmdShow))
{
  return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINDOWSHOOK));
// Hauptnachrichtenschleife:
while (GetMessage(&msg, NULL, 0, 0))
{
  if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
  {
   TranslateMessage(&msg);
   DispatchMessage(&msg);
  }
}
return (int) msg.wParam;
}

if I use the following code out of this:

DWORD dwThreadID = 0;
HWND hWnd = FindWindow(NULL,L"Unnamed - Notepad");
dwThreadID = GetWindowThreadProcessId(hWnd,NULL);
fnSetMyHook(dwThreadID);

dwThreadID gets an Thread ID of my Notepad.exe (the title of Notepad.exe in german windows sounds: "Unbenannt - Editor" so I don't exactly know the title name in english windows systems).

If I use fnSetMyHook(dwThreadID) with the right ThreadID it calls the code in my injector.cpp:

#include "stdafx.h"
#define INJECTIONDLL_API __declspec(dllexport)
#include "InjectionDLL.h"
HANDLE g_DllHandle;
HHOOK g_hMyHook;
LRESULT CALLBACK fnMyCallBack(int nCode, WPARAM wParam, LPARAM lParam);
BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
  {
   g_DllHandle = hModule;
  }
  break;
case DLL_THREAD_ATTACH:
  break;
case DLL_THREAD_DETACH:
  break;
case DLL_PROCESS_DETACH:
  break;
}
return TRUE;
}
INJECTIONDLL_API int fnSetMyHook(DWORD dwThreadId)
{
int nRetVal = 1;
g_hMyHook = SetWindowsHookEx(WH_GETMESSAGE,fnMyCallBack,(HINSTANCE)g_DllHandle,dwThreadId);
if(!g_hMyHook)
{
  nRetVal = 0;
}
return nRetVal;
}
LRESULT CALLBACK fnMyCallBack(int nCode, WPARAM wParam, LPARAM lParam)
{
MSG * pmsg = (MSG*)lParam;
static bool fDone = FALSE;
switch(pmsg->message)
{
case WM_DESTROY:
  {
   if(!fDone)
   {
	MessageBox(NULL,L"Messagebox called by target program.",L"Injected DLL",MB_OK);
	UnhookWindowsHookEx(g_hMyHook);
	fDone = TRUE;
   }
  }
  break;
}
return (CallNextHookEx (g_hMyHook,nCode,wParam,lParam));
}

This function is called:

INJECTIONDLL_API int fnSetMyHook(DWORD dwThreadId)
{
int nRetVal = 1;
g_hMyHook = SetWindowsHookEx(WH_GETMESSAGE,fnMyCallBack,(HINSTANCE)g_DllHandle,dwThreadId);
if(!g_hMyHook)
{
  nRetVal = 0;
}
return nRetVal;
}

but it always returns me a 0. Does anyone know why? Oh Yes, here is the injector.h file:

#ifndef INJECTIONDLL_API
#define INJECTIONDLL_API __declspec(dllexport)
#endif
INJECTIONDLL_API int fnSetMyHook(DWORD dwThreadId);

Any Help would be appreciated. Also I don't know how to go on then, which methods should be called in the injector.cpp next, if I wan't to catch the WM_Quit Message from Notepad.exe? And how can I use non standard Windows API functions? Like functions that only are implemented in Notepad.exe?

Anyone? Please, I really want to solve, understand and document this kind of problems.

Edit: Tools Available to use: OllyDB and Visual Studio 2010 or Visual Studio 11 developers preview.

#3 Litheon   Members   -  Reputation: 263

Like
0Likes
Like

Posted 25 March 2012 - 06:06 AM

I think everybody is confused of what you exactly want to accomplish. Or on which game?

For example, to get keypresses, if the game uses DirectInput you can hook directinput else you need to do it with SetWindowHookEx etc.

To hook directx there is a topic + example here : http://www.gamedev.n...ge__hl__hooking

Also on http://www.codeproject.com there are several hooking examples.

There is also the API of Microsoft http://research.micr...ojects/detours/ that can be very helpful.

First I would try to hook dx or opengl or win32 functions and then maybe see if you can hook functions in an .exe.

#4 Ketzer2002   Members   -  Reputation: 100

Like
0Likes
Like

Posted 25 March 2012 - 06:54 AM

Hi Litheon,

> "First I would try to hook dx or opengl or win32 functions and then maybe see if you can hook functions in an .exe."

That is exactly what I'm trying first, before stepping deeper into hooking. I've tried in my above example to catch the WM_DESTROY Message of Notepad.exe, but without success...

Furthermore I don't want to post the exact game titel at this moment to prevent spreading OT Posts. First I want to create a step by step how to do it with actuall technologies.

Codeproject and co have many examples... I have allready installed the detours library and also have older versions of that dll. the problem with detours is, that i have to inject this dll with WINJECT, which is IMHO not the best way, if you want to setup an easy to use solution for everyone. I've seen the examples of Muhammad Haggag, but that is not exactly what I call a good tutorial... on the other hand he did a very good job, by writing all the needed directX functionality into one C++ Project, but that is useless for me at all if I try to understand, whats happening in detail...

Greetings.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS