iw3sp stürzt ab nach dem d3d hooken

01/27/2011 14:16 germanhacker#1
Hallo epvp,

Hab ein Problem und zwar möchte ich ein pinkes Rechteck oben links zeichnen lassen. Aber wenn ich es mithilfe eines Hotkeys anzeigen lassen möchte, sieht man das Rechteck kurz und dann stürzt das Programm ab. Ohne die Hotkey Funktion klappt das super, aber man möchte ja sein d3d menu auch wieder schließen o.O

Hier mein Source Code:

Code:
#pragma once
#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")

#include <windows.h>
#include <d3d9.h>
#include <d3dx9.h>
typedef HRESULT (D3DAPI* Reset_t)(IDirect3DDevice9* pDevice, D3DPRESENT_PARAMETERS* pPresentationParameters);
typedef HRESULT (WINAPI* tEndScene)(LPDIRECT3DDEVICE9 pDevice);
tEndScene pEndScene = NULL;
Reset_t pReset = 0;
 DWORD dwEndScene;
 DWORD dwDrawIndexedPrimitive;


D3DCOLOR txtPink = D3DCOLOR_ARGB(255,255, 0, 255);

void Funktionen();
void *DetourFunc(BYTE *src, const BYTE *dst, const int len);

bool bDataCompare(const BYTE* pData, const BYTE* bMask, const char* szMask)
{
    for(;*szMask;++szMask,++pData,++bMask)
        if(*szMask=='x' && *pData!=*bMask ) 
            return false;
    return (*szMask) == NULL;
 }
DWORD dwFindPattern(DWORD dwAddress,DWORD dwLen,BYTE *bMask,char * szMask)
{
    for(DWORD i=0; i < dwLen; i++)
        if( bDataCompare( (BYTE*)( dwAddress+i ),bMask,szMask) )
            return (DWORD)(dwAddress+i);
    
    return 0;
 }

void Rechteck (LPDIRECT3DDEVICE9 Device_t, int X, int Y, int L, int H, D3DCOLOR color)
{
D3DRECT rect = {X, Y, X+L, Y+H};
Device_t->Clear(1, &rect, D3DCLEAR_TARGET, color, 0, 0); 
}

HRESULT D3DAPI hkReset(IDirect3DDevice9* pDevice, D3DPRESENT_PARAMETERS* pPresentationParameters)
{
    return pReset(pDevice, pPresentationParameters);
}
HRESULT WINAPI hkEndScene(LPDIRECT3DDEVICE9 pDevice)
{  
	Rechteck (pDevice, 10, 10, 200, 200, txtPink);
    return pEndScene(pDevice); 
}

void Funktionen()
{
        HMODULE hModule = NULL;
        while( !hModule )
        {
                hModule = GetModuleHandleA( "d3d9.dll" );
                Sleep( 100 );							
        }

		 bool draw = false;
for(;;) {
	   __asm pushad;
	   if(GetAsyncKeyState(VK_INSERT)&1) {
				draw = !draw;
			}
	   if (draw)
	   {
dwEndScene = (DWORD)hModule + 0x871A0;
DWORD* VTableStart = 0;                  
DWORD FoundByGordon = dwFindPattern((DWORD)hModule, 0x128000,
(PBYTE)"\xC7\x06\x00\x00\x00\x00\x89\x86\x00\x00\x00\x00\x89\x86", "xx????xx????xx");
memcpy(&VTableStart, (void*)(FoundByGordon+2), 4);
dwDrawIndexedPrimitive = (DWORD)VTableStart[82]; // für mehr: blick in die d3d9.h werfen!
dwEndScene = (DWORD)VTableStart[42];
pEndScene = (tEndScene )DetourFunc((PBYTE)  dwEndScene ,(PBYTE)hkEndScene, 5); 
}
	   Sleep(100);
			__asm popad;
}
}
int WINAPI DllMain(HINSTANCE hInst,DWORD reason,LPVOID reserved) 
{
        switch(reason)
        {
        case DLL_PROCESS_ATTACH:
				MessageBoxA(0, "* * * Coded By Michi * * *", "Draw a Box !", 0);
                CreateThread(0, 0, (LPTHREAD_START_ROUTINE) Funktionen, 0, 0, 0);
                break;
        }
        return true;
}

void *DetourFunc(BYTE *src, const BYTE *dst, const int len)
{															
    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);
}
Ich hoffe mir kann jemand helfen :)
01/27/2011 14:39 xNopex#2
Du kannst das so natürlich nicht machen, da du in einer Schleife den Hook immer wieder neu einrichtest, wenn 'draw' true ist. Und das führt natürlich zu einem Absturz.
Du musst in der EndScene-Funktion prüfen, ob das Rechteck gezeichnet werden soll, oder nicht. Nach deinem jetzigen Code funktioniert das nur über eine globale Variable.

Pseudocode:
Code:
BOOL draw = FALSE;

//...

FUNCTION EndScene(DEVICE)
{
     if( draw == TRUE )
        RECKTECK_MALEN();

      //...
}

THREAD MainThread(PARAM)
{
      while( TRUE )
      {
            if( INSERT_KEY_PRESSED )
                draw = TRUE;
      }
}
01/27/2011 14:45 germanhacker#3
Quote:
Originally Posted by xNopex View Post
Du kannst das so natürlich nicht machen, da du in einer Schleife den Hook immer wieder neu einrichtest, wenn 'draw' true ist. Und das führt natürlich zu einem Absturz.
Du musst in der EndScene-Funktion prüfen, ob das Rechteck gezeichnet werden soll, oder nicht. Nach deinem jetzigen Code funktioniert das nur über eine globale Variable.

Pseudocode:
Code:
BOOL draw = FALSE;

//...

FUNCTION EndScene(DEVICE)
{
     if( draw == TRUE )
        RECKTECK_MALEN();

      //...
}

THREAD MainThread(PARAM)
{
      while( TRUE )
      {
            if( INSERT_KEY_PRESSED )
                draw = TRUE;
      }
}
Vielen Dank für die schnelle Hilfe ! :)

// €dit:

Och man ich bekomm des nit hin <.<

kann mir jemand in diesem code erklären, wo da des rechteck gemalt wird. Da müsst ja dann des if (draw) davor..

Quote:
void Funktionen()
{
HMODULE hModule = NULL;
while( !hModule )
{
hModule = GetModuleHandleA( "d3d9.dll" );
Sleep( 100 );
}

dwEndScene = (DWORD)hModule + 0x871A0;
DWORD* VTableStart = 0;
DWORD FoundByGordon = dwFindPattern((DWORD)hModule, 0x128000,
(PBYTE)"\xC7\x06\x00\x00\x00\x00\x89\x86\x00\x00\x 00\x00\x89\x86", "xx????xx????xx");
memcpy(&VTableStart, (void*)(FoundByGordon+2), 4);
dwDrawIndexedPrimitive = (DWORD)VTableStart[82]; // für mehr: blick in die d3d9.h werfen!
dwEndScene = (DWORD)VTableStart[42];
pEndScene = (tEndScene )DetourFunc((PBYTE) dwEndScene ,(PBYTE)hkEndScene, 5);
}
denn das funzt ja iwie net:


Quote:
HRESULT WINAPI hkEndScene(LPDIRECT3DDEVICE9 pDevice)
{
if (draw)
Rechteck (pDevice, 10, 10, 200, 200, txtPink);
return pEndScene(pDevice);
}



// €dit:

Nach langem ausprobieren hab ichs doch noch geschafft :)

Hier der Code, falls ihn jemand benötigt:

Quote:
HRESULT WINAPI hkEndScene(LPDIRECT3DDEVICE9 pDevice)
{
_asm pushad
if (draw == true)
{
D3DXCreateFont(pDevice, 14, 0, FW_NORMAL, 1, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,ANTIALIASED_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Arial", &g_pFont );
Rechteck (pDevice, 10, 20, 200, 200, txtPink);
DrawFont ( 300, 50, txtPink, "Hello" );
}
if(GetAsyncKeyState(VK_INSERT) &1) // Öffnen mit Einfg
{
draw = !draw; // Ein od. Aus
}
_asm popad
return pEndScene(pDevice);
}
01/27/2011 17:27 MrSm!th#4
Der Absturz durch das mehrmalige Setzen des hooks kommt übrigens nur von dieser schlechten DetourFunc.
Mit MS Detours würde das nicht passieren.
Übrigens: so etwas kommt beim copypasten raus, also lass es lieber.