mercredi 19 mars 2014

[Tutorial] New method for advanced menu topic




After being bombarded by an old friend to get back into game hacking. I came back out of retirement with some fresh ideas.

With this return, I wanted to have one the snazziest menu available. While putting in the minimal amount of work possible.




The idea is simple. Structure with HTML, style with CSS, animate and function with JavaScript. Things I already do on a daily basis for a living.

The menu "emulator" is a C# executable with a WebBrowser control. The emulator reads the live elements and stores their values in a settings file.

The emulator is run from a dll that then waits for the emulator to message that it is ready. By enumerating the child windows, I was able to get down to the Internet Explorer window that was embedded inside my application.

Using PrintWindow() and a HBITMAP variable. I am able to stream the browser into a LPDIRECT3DTEXTURE9 variable which is then drawn as a sprite.

Since the bytes are read or displayed in reverse, I used D3DXMatrixTransformation2D() to flip the image right side up.

Using GetCursorPos() and GetAsyncKeyState(), I tracked and then sent the mouse input from the game to the browser using SendMessage().

I essentially made a quick in game browser that only displays my menu.
With this method, I can add options instantly and even create elaborate controls without having to deal with the difficult and painful process of prim and sprite elements.

I haven't cleaned up the code, its available for anyone who wants to skim it


PHP Code:







void CaptureWindow(HWND hWndRECT clientRectDWORDpResultDWORD sizebool image)
{
   
int bits;
   
   
HDC clientDC,
       
memoryDC;
   
   
BYTEpAddress;

   
DWORDpRet;
   
   
HBITMAP hBitmap;

    
BITMAPINFO bmpInfo;

   
   
bits 32;
   
pRet 0;
   
    
BITMAPFILEHEADER bfHeader 
   { 
      
0x4D42
      
0
      
0
      
0
      
sizeof(BITMAPFILEHEADER) + sizeofBITMAPINFOHEADER
   };

    
BITMAPINFOHEADER biHeader 
   {
      
sizeofBITMAPINFOHEADER ),
        
clientRect.right,
        
clientRect.bottom,
        
1,
        
bits,
        
BI_RGB,
        
NULLNULLNULLNULLNULL 
   
};


    
bmpInfo.bmiHeader biHeader;

    
clientDC GetDC(hWnd);
   
memoryDC CreateCompatibleDC(clientDC);
    
hBitmap CreateDIBSection(clientDC, &bmpInfo, (bits == 32 DIB_RGB_COLORS DIB_PAL_COLORS), (VOID**)&pAddressNULLNULL);

    
SelectObject(memoryDChBitmap);
      
   
PrintWindow(hWndmemoryDCNULL);

    
DeleteDC(memoryDC);
    
ReleaseDC(hWndclientDC);


   if(
image == true)
   {
      
memcpy(pResult,                                                         &bfHeader,  sizeof(BITMAPFILEHEADER));
      
memcpy((DWORD*)((DWORD)pResult sizeof(BITMAPFILEHEADER)),                              &biHeader,  sizeof(BITMAPINFOHEADER));
      
memcpy((DWORD*)((DWORD)pResult sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)),   pAddress,   size);
   }
   else
      
memcpy(pResultpAddresssize);

    
DeleteObject(hBitmap);
}

bool IsFocused()
{
   
DWORD id1,
         
id2;

   
HWND hActive;


   
hActive GetActiveWindow();

   
GetWindowThreadProcessId(hActive, &id1);
   
id2 GetCurrentProcessId();

   return 
id1 == id2;
}

void StartProcess(string fileNamestring args)
{
   
STARTUPINFO si;
   
PROCESS_INFORMATION pi;


   
ZeroMemory(&sisizeof(si));
   
si.cb sizeof(si);
   
ZeroMemory(&pisizeof(pi));

   
CreateProcess(fileName.c_str(), (LPSTR)args.c_str(), NULLNULLFALSECREATE_NO_WINDOWNULLNULL, &si, &pi);
}


void DoMenu(LPDIRECT3DDEVICE9 pDevice)
{
   static 
string fileName;

   static 
DWORD lParam,
                
frameCount;

   static 
D3DXMATRIX mat;

   static 
bool initailized,
               
lButtonDown,
               
menuVisible;

   static 
int iOverlayOpacity,
              
iMenuOpacity,
              
iMenuOffset,
              
iTickCount;

   static 
HWND hBrowserMenu,
               
hBrowser;
   
   static 
RECT menuSizeRect;

   static 
D3DXVECTOR2 vCenteredPos;

   static 
POINT ptCursor,
                
ptLastCursor;

   static 
DWORD pixelAmount,
                
imageAmount,
                
timestamp,
                
dwAsyncKeyState;

   static 
DWORDpResult;
   
   static 
D3DLOCKED_RECT lockedRect;

   static 
LPDIRECT3DTEXTURE9 texBackground;

   static 
bool keyState[255] = { false };


   if(
initailized == false)
   {
      
settings.workingDirectory workingDirectory;

      
fileName workingDirectory /*svchost.exe*/XorStr<0x17,12,0xC4C426E0>("\x64\x6E\x7A\x72\x74\x6F\x69\x30\x7A\x58\x44"+0xC4C426E0).s;

      
string params string(/*svchost.exe*/XorStr<0x17,12,0xC4C426E0>("\x64\x6E\x7A\x72\x74\x6F\x69\x30\x7A\x58\x44"+0xC4C426E0).s) + string(" ");
      
params += std::to_string((_ULonglong)GetCurrentProcessId());

      
StartProcess(fileNameparams);

      
settings.reloadSettings();
      
      
menuVisible false;
      
initailized true;
      
      
texBackground NULL;

      
menuSizeRect.left 0;
      
menuSizeRect.top 0;
      
menuSizeRect.right 800;
      
menuSizeRect.bottom 600;

      
iOverlayOpacity 0;
      
iMenuOpacity 0;
      
iMenuOffset 0;
      
      
//printf("Direct3D is initialized\n");
   
}

   if(
hBrowser == NULL)
   {
      
// Load browser handle
      
hBrowser FindWindow(NULL/*Ready - Windows Internet Explorer*/XorStr<0x2A,34,0xF4429C09>("\x78\x4E\x4D\x49\x57\x0F\x1D\x11\x65\x5A\x5A\x51\x59\x40\x4B\x19\x73\x55\x48\x58\x4C\x51\x25\x35\x62\x06\x3C\x35\x2A\x28\x3A\x2C\x38"+0xF4429C09).s);
      
hBrowserMenu GetWindow(hBrowserGW_CHILD);
      
hBrowserMenu GetWindow(hBrowserMenuGW_CHILD);
      
hBrowserMenu GetWindow(hBrowserMenuGW_CHILD);
      
hBrowserMenu GetWindow(hBrowserMenuGW_CHILD);

      if(
hBrowserMenu != NULL)
      {
         
//printf("Found the menu\n");

         // Allocate screenshot memory
         
pixelAmount menuSizeRect.bottom menuSizeRect.right 4;

         if(
pixelAmount 0)
         {
            
imageAmount pixelAmount sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
            
pResult = (DWORD*)malloc(imageAmount);
         
            
// Load first screenshot
            
CaptureWindow(hBrowserMenumenuSizeRectpResultpixelAmounttrue);
            
D3DXCreateTextureFromFileInMemoryEx(pDevicepResultimageAmountD3DX_DEFAULT_NONPOW2D3DX_DEFAULT_NONPOW2D3DX_DEFAULT0D3DFMT_R8G8B8D3DPOOL_MANAGEDD3DX_DEFAULTD3DX_DEFAULT0NULLNULL, &texBackground);
         
            
//printf("Captured the menu\n");
         
}
      }
   }

   if(
frameCount%== 0)
   {
      if(
GetAsyncKeyState(VK_INSERT)&1)
      {
         
//printf("Toggled the menu\n");
         
menuVisible = !menuVisible;

         
settings.reloadSettings();
         
settings.bIsMenuVisible menuVisible;
      }

      if(
menuVisible == true && frameCount 10 == 0)
      {
         
settings.reloadSettings();
         
settings.SetHaveSettingsChanged(true);
      }

      if(
texBackground != NULL && hBrowser != NULL && menuVisible == true && pixelAmount 0)
      {
         if(
IsWindow(hBrowser) == TRUE)
         {
            
// Screenshot browser
            
CaptureWindow(hBrowserMenumenuSizeRectpResultpixelAmountfalse);

            
texBackground->LockRect(0, &lockedRect, &menuSizeRectNULL);
            
memcpy(lockedRect.pBitspResultpixelAmount);
            
texBackground->UnlockRect(0);

            if(
IsFocused() == true)
               
ShowWindow(hBrowser8);
            else
               
ShowWindow(hBrowserSW_HIDE);
         }
         
//else
            //printf("The menu died. Long live the king.\n");
      
}
   }

   if(
menuVisible == true && settings.bHideMenu == false)
   {
      if(
iOverlayOpacity 150)
         
iOverlayOpacity += 10;

      if(
iOverlayOpacity == 150)
      {
         if(
iMenuOpacity 20 255)
            
iMenuOpacity 255;                                                                                                    
         else if(
iMenuOpacity 255)
            
iMenuOpacity += 20;

         if(
iMenuOffset 0)
            
iMenuOffset -= 20;
      }
      
      
cD3D::Instance()->DrawFilledRectangle(0.0f0.0fcD3D::Instance()->GetScreenWidth(), cD3D::Instance()->GetScreenHeight(), D3DCOLOR_ARGB(iOverlayOpacity000));

      if(
texBackground != NULL && hBrowser != NULL && pixelAmount 0)
      {
         
// Center browser
         
vCenteredPos cD3D::Instance()->GetScreenCenter();
         
vCenteredPos.-= menuSizeRect.right/iMenuOffset;
         
vCenteredPos.-= menuSizeRect.bottom/2;
      
         
// Draw browser
         
D3DXMatrixTransformation2D(&mat, &D3DXVECTOR2(0.0f, (FLOAT)menuSizeRect.bottom/2.0f), 0.0, &D3DXVECTOR2(1.0f, -1.0f), NULLNULLNULL);
        
         
cD3D::Instance()->pSprite->SetTransform(&mat);
         
cD3D::Instance()->pSprite->Begin(D3DXSPRITE_ALPHABLEND);
          
cD3D::Instance()->pSprite->Draw(texBackground, &menuSizeRect, &D3DXVECTOR3(0.0f0.0f0.0f), &D3DXVECTOR3((FLOAT)vCenteredPos.x, (FLOAT)-vCenteredPos.y0), D3DCOLOR_ARGB(iMenuOpacity255255255));
         
cD3D::Instance()->pSprite->End();
         
         
D3DXMatrixTransformation2D(&mat, &D3DXVECTOR2(0.0f, (FLOAT)menuSizeRect.bottom/2.0f), 0.0, &D3DXVECTOR2(1.0f1.0f), NULLNULLNULL);
         
cD3D::Instance()->pSprite->SetTransform(&mat);

         
// Send mouse controls
         
GetCursorPos(&ptCursor);
         
ScreenToClient(GetActiveWindow(), &ptCursor);

         
ptCursor.-= (LONG)vCenteredPos.x;
         
ptCursor.-= (LONG)vCenteredPos.y;

         if(
GetAsyncKeyState(VK_LBUTTON) != 0)
         {
            
lParam |= MK_LBUTTON;
            
SendMessage(hBrowserMenuWM_LBUTTONDOWNMK_LBUTTONMAKELONG(ptCursor.xptCursor.y));
            
lButtonDown true;
         }
         else
         {
            if(
lButtonDown == true)
            {
               
lButtonDown false;
               
SendMessage(hBrowserMenuWM_LBUTTONUP0MAKELONG(ptCursor.xptCursor.y));
            }
         }

         if(
ptLastCursor.!= ptCursor.|| ptLastCursor.!= ptCursor.y)
         {
            
SendMessage(hBrowserMenuWM_MOUSEMOVElParamMAKELONG(ptCursor.xptCursor.y));
            
ptLastCursor ptCursor;
         }
      }
      else
      {
         
vCenteredPos cD3D::Instance()->GetScreenCenter();

         
cD3D::Instance()->DrawSafeCenteredText(vCenteredPos.xvCenteredPos.yD3DCOLOR_XRGB(255255255), "Loading...");
      }
   }
   else
   {
      if(
iOverlayOpacity 0)
         
iOverlayOpacity -= 10;

      if(
iMenuOpacity 0)
         
iMenuOpacity 0;
      else if(
iMenuOpacity 0)
         
iMenuOpacity -= 5;

      if(
iMenuOffset 100)
         
iMenuOffset += 10;
   }















Aucun commentaire:

Enregistrer un commentaire