DirectInput Injected DLL

02/24/2012 11:41 theredvex#16
So ich bin dann jetzt soweit , dass ich das GetDeviceState gehookt habe nur möchte ich jetzt auch gern eigene Keys senden. So wie ich das bisher verstanden habe wird GetDeviceState ja nur verwendet wenn auch eine Bewegung(Maus)/Tastaturdruck(Tasta...) stattgefunden hat oder liege ich da falsch?
wäre cool wenn mir jemand einen gedankenanstoß geben könnte
02/24/2012 11:45 MoepMeep#17
Was wollt ihr alle immer mit Tastendrücken? Wollt ihr nicht ernstgenommen werden? :/ Such die entsprechenden Funktionen bzw hook/detour send und recv.
02/24/2012 14:49 Dr. Coxxy#18
GetDeviceState wird vermutlich in einer endlosschleife abgefragt.
wenn du eine taste simulieren möchtest, verfälschst du einfach beim nächsten aufruf deines hooks den übergebenen buffer.
02/24/2012 17:39 theredvex#19
HRESULT __stdcall hookedGetDeviceState(LPDIRECTINPUTDEVICE Device,DWORD dData,LPVOID lpvData)
{
//static BYTE buffer[256];
char* ptr = (char*)lpvData;
HRESULT temp = DI_OK;
temp = MyGetDeviceState(Device,dData,lpvData);
if(dData == 256)
{
ptr[DIK_E] = 0;
}
return temp;
}

müsste es durch diesen code nicht möglich sein keine E taste zuzulassen? bei mir geht es nämlich trotzdem noch <<
02/24/2012 17:47 Dr. Coxxy#20
ja, d.h.:
1. entweder du hast bei deinem hook was schiefgebaut.
2. das spiel hat zwar directinput drin, benutzt es aber nicht
3. das spiel macht doublechecks
4. das spiel hat deinen hook erkannt und wieder dehookt
5. etc...

schonmal ausgeben lassen ob/wie oft dein hook überhaupt aufgerufen wird?

es kann btw. gut sein, dass das chatsystem unabhängig vom directinput ist, also du im chatfenster immer noch E eingeben kannst, aber ingame hotkeys ignoriert werden etc...
02/24/2012 17:55 theredvex#21
Quote:
Originally Posted by Dr. Coxxy View Post
es kann btw. gut sein, dass das chatsystem unabhängig vom directinput ist, also du im chatfenster immer noch E eingeben kannst, aber ingame hotkeys ignoriert werden etc...
Das ist es auf jedenfall denn dort kann man sogar mit PostMessage arbeiten..
02/24/2012 18:17 Dr. Coxxy#22
Quote:
"schonmal ausgeben lassen ob/wie oft dein hook überhaupt aufgerufen wird?"
...
02/24/2012 18:23 theredvex#23
Quote:
Originally Posted by Dr. Coxxy View Post
...
Ja ich habe eine LogFunktion eingebaut.
Ich sehe das er jedesmal die dData/cbData mit 256 ausgibt. dehooked wird das ganze auch nicht denn ich sehe nebenbei wie die Log größer wird.

aber eine andere frage habe ich die richtigen overloads für die Funktion? ich hab im internet ein paar seiten gefunden wo das nur mit cbData und lpvData angegeben wird. quasi ohne Device
02/24/2012 18:30 Dr. Coxxy#24
ja, ist richtig, wenn du das tut aufmerksam gelesen hättest wüsstest du auch warum.
02/24/2012 19:36 theredvex#25
Quote:
Originally Posted by Dr. Coxxy View Post
ja, ist richtig, wenn du das tut aufmerksam gelesen hättest wüsstest du auch warum.
So ich hab mir jetzt auch mal die lpvData Loggen lassen.. da ist mir aufgefallen, dass es nur 1x Loggt wenn ich das Fenster Aktiviere.
Wenn ich im Spiel einfach 10x hintereinander W drücke loggt er nichts. heißt das, dass das spiel doch kein DInput zum bewegen nimmt??
02/24/2012 20:42 Dr. Coxxy#26
getdevicestate sollte mehrmals in der sekunde aufgerufen werden, nicht wenn du eine taste drückst oder sonstwas machst.
entweder bei deinem hook läuft gehörig was schief, oder das spiel benutzt directinput nur sporadisch für i-etwas.
kannst ja mal den ganzen buffer jedes mal NULLen und gucken, ob sich i-was ändert.
02/28/2012 19:40 insert-name-here#27
das Ganze könnte etwa sp ausehn fals das spiel dinput8.dll zum abfragen der tasten nutzt
Code:
#pragma once
 
#define _CRT_SECURE_NO_WARNINGS								// ignore some warnings...
#define _CRT_NON_CONFORMING_SWPRINTFS						// ...
 
#include <Windows.h>
#include <cstdio>
#include <time.h> 
#include <dinput.h>
 
const DWORD GDS_OFFSET = 0x62B1;
 
DWORD WINAPI HookThread();
void* DetourFunc(BYTE *src, const BYTE *dst, const int len);
void add_log(char* format, ...);
 
typedef HRESULT(__stdcall* GetDeviceState_t)(LPDIRECTINPUTDEVICE, DWORD, LPVOID);
HRESULT __stdcall hkGetDeviceState(LPDIRECTINPUTDEVICE pDevice, DWORD cbData, LPVOID lpvData);
 
HANDLE tmpHandle = NULL;
HMODULE hModDInput8 = NULL;
FARPROC dwGetDeviceState = NULL;
FARPROC dwDirectInput8Create = NULL;
 
GetDeviceState_t pGetDeviceState;
 
BOOL WINAPI DllMain(HINSTANCE hinstDll,DWORD Reason,LPVOID Reserved)
{
	switch(Reason)
	{
		case DLL_PROCESS_ATTACH:
			add_log("==========LOG START==========");
			add_log("DLL Attached");
			add_log("Creating Thread...");
			tmpHandle = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&HookThread, 0, 0, 0);
			if (!tmpHandle)
			{
				add_log("ThreadCreation Failed!");
			}
			break;
		case DLL_PROCESS_DETACH:
			add_log("DLL Detached");
			add_log("==========LOG END==========\n\n\n");
			break;
	}
	return 1;
}
 
 
DWORD WINAPI HookThread()
{
	add_log("Thread Created");
 
	while (!hModDInput8)
	{
		add_log("Searching dinput8.dll...");
		hModDInput8 = GetModuleHandle(L"dinput8.dll");
		Sleep(100);
	}
	add_log("Found dinput8.dll: %x !", hModDInput8);
 
	while (!dwDirectInput8Create)
	{
		add_log("Searching GetDeviceState...");
		dwDirectInput8Create = GetProcAddress(hModDInput8, "DirectInput8Create");
		Sleep(100);
	}
	add_log("Found DirectInput8Create: %x !", dwDirectInput8Create);
 
	dwGetDeviceState = (FARPROC) ((DWORD)dwDirectInput8Create - GDS_OFFSET);
	add_log("GetDevicestate is here (DirectInput8Create - 0x62B1): %x", dwGetDeviceState);
 
	add_log("Hooking GetDeviceState...");
	pGetDeviceState = (GetDeviceState_t) DetourFunc((PBYTE) dwGetDeviceState, (PBYTE) hkGetDeviceState, 5);
	add_log("Hooked GetDeviceState - Trampolin: %x - New: %x !", pGetDeviceState, hkGetDeviceState);
 
	add_log("Going into Main Loop...");
	while (true)
	{
		// ...
		Sleep(1000);
	}
	return 0;
}
 
HRESULT __stdcall hkGetDeviceState(LPDIRECTINPUTDEVICE lpDevice, DWORD cbData, LPVOID lpvData)	// Parameter: die device - die größe der daten - der buffer in den geschrieben wird
{
	HRESULT temp = NULL;
	char* ptr = (char*) lpvData;
	temp = pGetDeviceState(lpDevice, cbData, lpvData);			// originalfunktion aufrufen
	if (cbData == 256) // wenn eine keyboard abfrage stattfindet... siehe: http://msdn.microsoft.com/en-us/library/microsoft.directx_sdk.idirectinputdevice8.idirectinputdevice8.getdevicestate%28v=VS.85%29.aspx
	{
		// memset(lpvData, 0, cbData);								// buffer leeren -> keine taste gedrückt
		ptr[DIK_E] = 0;												// um z.b. die taste E komplett zu blocken...
	}
	return temp;
}
 
 
void* DetourFunc(BYTE *src, const BYTE *dst, const int len)		//saved <len> bytes in ein trampolin, überschreibt die ersten 5 bytes der originalfunktion mit einem jump auf die hookfunktion und gibt einen pointer auf das trampolin zurück, der die gesicherten bytes und einen jump auf die originalfunktion NACH dem hook beinhaltet.
{
	BYTE *jmp = (BYTE*)malloc(len+5);
	DWORD dwback;
	VirtualProtect(src, len, PAGE_READWRITE, &dwback);
	memcpy(jmp, src, len);
	jmp += len;
	jmp[0] = 0xE9;
	*(DWORD*)(jmp+1) = (DWORD)(src+len - jmp) - 5;
	src[0] = 0xE9;
	*(DWORD*)(src+1) = (DWORD)(dst - src) - 5;
	VirtualProtect(src, len, dwback, &dwback);
	return (jmp-len);
}
 
 
void add_log(char* format, ...)
{
	HANDLE filehandle;
	DWORD dwReadBytes;
	char buffer[2048];
	char writebuffer[2048];
	va_list args;
	va_start(args, format);
	vsprintf (buffer, format, args);
	filehandle = CreateFile(L"Log.txt", GENERIC_WRITE, 0, 0, OPEN_ALWAYS, 0, 0);
	SetFilePointer(filehandle, 0, 0, FILE_END);
	char date[18];
	_strdate(date);
	date[8] = ' ';
	_strtime(date+9);
	sprintf_s(writebuffer, 2048, "Log Added (%s): %s\r\n", date, buffer);
	WriteFile(filehandle, writebuffer, strlen(writebuffer), &dwReadBytes, 0);
	CloseHandle(filehandle);
und kommunizieren könntest du über eine pipe

ps der code ist aus [Only registered and activated users can see links. Click Here To Register...]
02/28/2012 20:38 theredvex#28
Quote:
Originally Posted by insert-name-here View Post
das Ganze könnte etwa sp ausehn fals das spiel dinput8.dll zum abfragen der tasten nutzt
Code:
#pragma once
 
#define _CRT_SECURE_NO_WARNINGS                                // ignore some warnings...
#define _CRT_NON_CONFORMING_SWPRINTFS                        // ...
 
#include <Windows.h>
#include <cstdio>
#include <time.h> 
#include <dinput.h>
 
const DWORD GDS_OFFSET = 0x62B1;
 
DWORD WINAPI HookThread();
void* DetourFunc(BYTE *src, const BYTE *dst, const int len);
void add_log(char* format, ...);
 
typedef HRESULT(__stdcall* GetDeviceState_t)(LPDIRECTINPUTDEVICE, DWORD, LPVOID);
HRESULT __stdcall hkGetDeviceState(LPDIRECTINPUTDEVICE pDevice, DWORD cbData, LPVOID lpvData);
 
HANDLE tmpHandle = NULL;
HMODULE hModDInput8 = NULL;
FARPROC dwGetDeviceState = NULL;
FARPROC dwDirectInput8Create = NULL;
 
GetDeviceState_t pGetDeviceState;
 
BOOL WINAPI DllMain(HINSTANCE hinstDll,DWORD Reason,LPVOID Reserved)
{
    switch(Reason)
    {
        case DLL_PROCESS_ATTACH:
            add_log("==========LOG START==========");
            add_log("DLL Attached");
            add_log("Creating Thread...");
            tmpHandle = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&HookThread, 0, 0, 0);
            if (!tmpHandle)
            {
                add_log("ThreadCreation Failed!");
            }
            break;
        case DLL_PROCESS_DETACH:
            add_log("DLL Detached");
            add_log("==========LOG END==========\n\n\n");
            break;
    }
    return 1;
}
 
 
DWORD WINAPI HookThread()
{
    add_log("Thread Created");
 
    while (!hModDInput8)
    {
        add_log("Searching dinput8.dll...");
        hModDInput8 = GetModuleHandle(L"dinput8.dll");
        Sleep(100);
    }
    add_log("Found dinput8.dll: %x !", hModDInput8);
 
    while (!dwDirectInput8Create)
    {
        add_log("Searching GetDeviceState...");
        dwDirectInput8Create = GetProcAddress(hModDInput8, "DirectInput8Create");
        Sleep(100);
    }
    add_log("Found DirectInput8Create: %x !", dwDirectInput8Create);
 
    dwGetDeviceState = (FARPROC) ((DWORD)dwDirectInput8Create - GDS_OFFSET);
    add_log("GetDevicestate is here (DirectInput8Create - 0x62B1): %x", dwGetDeviceState);
 
    add_log("Hooking GetDeviceState...");
    pGetDeviceState = (GetDeviceState_t) DetourFunc((PBYTE) dwGetDeviceState, (PBYTE) hkGetDeviceState, 5);
    add_log("Hooked GetDeviceState - Trampolin: %x - New: %x !", pGetDeviceState, hkGetDeviceState);
 
    add_log("Going into Main Loop...");
    while (true)
    {
        // ...
        Sleep(1000);
    }
    return 0;
}
 
HRESULT __stdcall hkGetDeviceState(LPDIRECTINPUTDEVICE lpDevice, DWORD cbData, LPVOID lpvData)    // Parameter: die device - die größe der daten - der buffer in den geschrieben wird
{
    HRESULT temp = NULL;
    char* ptr = (char*) lpvData;
    temp = pGetDeviceState(lpDevice, cbData, lpvData);            // originalfunktion aufrufen
    if (cbData == 256) // wenn eine keyboard abfrage stattfindet... siehe: http://msdn.microsoft.com/en-us/library/microsoft.directx_sdk.idirectinputdevice8.idirectinputdevice8.getdevicestate%28v=VS.85%29.aspx
    {
        // memset(lpvData, 0, cbData);                                // buffer leeren -> keine taste gedrückt
        ptr[DIK_E] = 0;                                                // um z.b. die taste E komplett zu blocken...
    }
    return temp;
}
 
 
void* DetourFunc(BYTE *src, const BYTE *dst, const int len)        //saved <len> bytes in ein trampolin, überschreibt die ersten 5 bytes der originalfunktion mit einem jump auf die hookfunktion und gibt einen pointer auf das trampolin zurück, der die gesicherten bytes und einen jump auf die originalfunktion NACH dem hook beinhaltet.
{
    BYTE *jmp = (BYTE*)malloc(len+5);
    DWORD dwback;
    VirtualProtect(src, len, PAGE_READWRITE, &dwback);
    memcpy(jmp, src, len);
    jmp += len;
    jmp[0] = 0xE9;
    *(DWORD*)(jmp+1) = (DWORD)(src+len - jmp) - 5;
    src[0] = 0xE9;
    *(DWORD*)(src+1) = (DWORD)(dst - src) - 5;
    VirtualProtect(src, len, dwback, &dwback);
    return (jmp-len);
}
 
 
void add_log(char* format, ...)
{
    HANDLE filehandle;
    DWORD dwReadBytes;
    char buffer[2048];
    char writebuffer[2048];
    va_list args;
    va_start(args, format);
    vsprintf (buffer, format, args);
    filehandle = CreateFile(L"Log.txt", GENERIC_WRITE, 0, 0, OPEN_ALWAYS, 0, 0);
    SetFilePointer(filehandle, 0, 0, FILE_END);
    char date[18];
    _strdate(date);
    date[8] = ' ';
    _strtime(date+9);
    sprintf_s(writebuffer, 2048, "Log Added (%s): %s\r\n", date, buffer);
    WriteFile(filehandle, writebuffer, strlen(writebuffer), &dwReadBytes, 0);
    CloseHandle(filehandle);
und kommunizieren könntest du über eine pipe

ps der code ist aus [Only registered and activated users can see links. Click Here To Register...]
Ist alles logisch. mein Code sieht sogar teilweise so aus. habe mittlerweile aber rausgefunden, dass das Spiel die "GetDeviceData"-Funktion ausnutzt.

bin nur leider noch nicht schlauer wie ich da jetzt Tasten sende
03/01/2012 14:46 insert-name-here#29
also in den obigen fall war sieht das senden glaub so aus
ptr[DIK_F1] |= 1<<7;
03/01/2012 23:41 MrSm!th#30
^Exakt.

Ob eine Taste gedrückt ist, sieht man nämlich daran, dass ptr[DIK_CODE] & 0x80 true ergibt; der obige Code setzt die Bits genau so, dass dies zutrifft.