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
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 hWnd, RECT clientRect, DWORD* pResult, DWORD size, bool image)
{
int bits;
HDC clientDC,
memoryDC;
BYTE* pAddress;
DWORD* pRet;
HBITMAP hBitmap;
BITMAPINFO bmpInfo;
bits = 32;
pRet = 0;
BITMAPFILEHEADER bfHeader =
{
0x4D42,
0,
0,
0,
sizeof(BITMAPFILEHEADER) + sizeof( BITMAPINFOHEADER)
};
BITMAPINFOHEADER biHeader =
{
sizeof( BITMAPINFOHEADER ),
clientRect.right,
clientRect.bottom,
1,
bits,
BI_RGB,
NULL, NULL, NULL, NULL, NULL
};
bmpInfo.bmiHeader = biHeader;
clientDC = GetDC(hWnd);
memoryDC = CreateCompatibleDC(clientDC);
hBitmap = CreateDIBSection(clientDC, &bmpInfo, (bits == 32 ? DIB_RGB_COLORS : DIB_PAL_COLORS), (VOID**)&pAddress, NULL, NULL);
SelectObject(memoryDC, hBitmap);
PrintWindow(hWnd, memoryDC, NULL);
DeleteDC(memoryDC);
ReleaseDC(hWnd, clientDC);
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(pResult, pAddress, size);
DeleteObject(hBitmap);
}
bool IsFocused()
{
DWORD id1,
id2;
HWND hActive;
hActive = GetActiveWindow();
GetWindowThreadProcessId(hActive, &id1);
id2 = GetCurrentProcessId();
return id1 == id2;
}
void StartProcess(string fileName, string args)
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
CreateProcess(fileName.c_str(), (LPSTR)args.c_str(), NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &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 DWORD* pResult;
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(fileName, params);
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(hBrowser, GW_CHILD);
hBrowserMenu = GetWindow(hBrowserMenu, GW_CHILD);
hBrowserMenu = GetWindow(hBrowserMenu, GW_CHILD);
hBrowserMenu = GetWindow(hBrowserMenu, GW_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(hBrowserMenu, menuSizeRect, pResult, pixelAmount, true);
D3DXCreateTextureFromFileInMemoryEx(pDevice, pResult, imageAmount, D3DX_DEFAULT_NONPOW2, D3DX_DEFAULT_NONPOW2, D3DX_DEFAULT, 0, D3DFMT_R8G8B8, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &texBackground);
//printf("Captured the menu\n");
}
}
}
if(frameCount%2 == 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(hBrowserMenu, menuSizeRect, pResult, pixelAmount, false);
texBackground->LockRect(0, &lockedRect, &menuSizeRect, NULL);
memcpy(lockedRect.pBits, pResult, pixelAmount);
texBackground->UnlockRect(0);
if(IsFocused() == true)
ShowWindow(hBrowser, 8);
else
ShowWindow(hBrowser, SW_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.0f, 0.0f, cD3D::Instance()->GetScreenWidth(), cD3D::Instance()->GetScreenHeight(), D3DCOLOR_ARGB(iOverlayOpacity, 0, 0, 0));
if(texBackground != NULL && hBrowser != NULL && pixelAmount > 0)
{
// Center browser
vCenteredPos = cD3D::Instance()->GetScreenCenter();
vCenteredPos.x -= menuSizeRect.right/2 - iMenuOffset;
vCenteredPos.y -= menuSizeRect.bottom/2;
// Draw browser
D3DXMatrixTransformation2D(&mat, &D3DXVECTOR2(0.0f, (FLOAT)menuSizeRect.bottom/2.0f), 0.0, &D3DXVECTOR2(1.0f, -1.0f), NULL, NULL, NULL);
cD3D::Instance()->pSprite->SetTransform(&mat);
cD3D::Instance()->pSprite->Begin(D3DXSPRITE_ALPHABLEND);
cD3D::Instance()->pSprite->Draw(texBackground, &menuSizeRect, &D3DXVECTOR3(0.0f, 0.0f, 0.0f), &D3DXVECTOR3((FLOAT)vCenteredPos.x, (FLOAT)-vCenteredPos.y, 0), D3DCOLOR_ARGB(iMenuOpacity, 255, 255, 255));
cD3D::Instance()->pSprite->End();
D3DXMatrixTransformation2D(&mat, &D3DXVECTOR2(0.0f, (FLOAT)menuSizeRect.bottom/2.0f), 0.0, &D3DXVECTOR2(1.0f, 1.0f), NULL, NULL, NULL);
cD3D::Instance()->pSprite->SetTransform(&mat);
// Send mouse controls
GetCursorPos(&ptCursor);
ScreenToClient(GetActiveWindow(), &ptCursor);
ptCursor.x -= (LONG)vCenteredPos.x;
ptCursor.y -= (LONG)vCenteredPos.y;
if(GetAsyncKeyState(VK_LBUTTON) != 0)
{
lParam |= MK_LBUTTON;
SendMessage(hBrowserMenu, WM_LBUTTONDOWN, MK_LBUTTON, MAKELONG(ptCursor.x, ptCursor.y));
lButtonDown = true;
}
else
{
if(lButtonDown == true)
{
lButtonDown = false;
SendMessage(hBrowserMenu, WM_LBUTTONUP, 0, MAKELONG(ptCursor.x, ptCursor.y));
}
}
if(ptLastCursor.x != ptCursor.x || ptLastCursor.y != ptCursor.y)
{
SendMessage(hBrowserMenu, WM_MOUSEMOVE, lParam, MAKELONG(ptCursor.x, ptCursor.y));
ptLastCursor = ptCursor;
}
}
else
{
vCenteredPos = cD3D::Instance()->GetScreenCenter();
cD3D::Instance()->DrawSafeCenteredText(vCenteredPos.x, vCenteredPos.y, D3DCOLOR_XRGB(255, 255, 255), "Loading...");
}
}
else
{
if(iOverlayOpacity > 0)
iOverlayOpacity -= 10;
if(iMenuOpacity - 5 < 0)
iMenuOpacity = 0;
else if(iMenuOpacity > 0)
iMenuOpacity -= 5;
if(iMenuOffset < 100)
iMenuOffset += 10;
}
}
Aucun commentaire:
Enregistrer un commentaire