Here's an in depth tutorial on how wallhack/chams work, and how to make them.
This assumes you have basic knowledge of C++ and have constructed a working Game-hook, that can hook D3D.
Oh yea, and this is for Direct3D9, but simple changes it can be made for use with different versions.
First off, a little explanation on how Chams/Wallhack works.
Wallhack:
The method that a wallhack works, is purely through D3D no memory address hooking is needed whatsoever, although it IS possible through memory hooking, that's another story though..
What a wallhack does, is disable the Z Buffer in the game.
What is the Z Buffer?
The Z Buffer is a presentation parameter for DirectX, it is a Depth Buffer. it is used to determine how rendered objects occlude with each other.
Originally Posted by
wiki
In computer graphics, z-buffering is the management of image depth coordinates in three-dimensional (3-D) graphics, usually done in hardware, sometimes in software. It is one solution to the visibility problem, which is the problem of deciding which elements of a rendered scene are visible, and which are hidden. The painter's algorithm is another common solution which, though less efficient, can also handle non-opaque scene elements. Z-buffering is also known as depth buffering.
To simplify that, the Z buffer basically tells the camera, if it's behind another object, don't show it, if it's in front another object, show it.
Now, with that said, you can't just disable the Z Buffer and expect to have a working wallhack, it doesn't work like that. if you do that, you will notice, you can see everything, through everything. in other words.
You have to declare what you want to disable the buffer on, ie: Strides, NumVertices, and PrimitiveCounts.
those three things are key in defining what you want to see through the walls/objects. which in most cases is the Player model.
Now lets get to the code for a simple wallhack.
#define PlayerBody ( Stride == 44 || Stride == 40 )
// Note for retards, the " || " Operator means "Or" as in: "PlayerBody is equal to stride number 44, or 40."
Notice how i used the Variable 'Stride' this actually depends on how you hook is set up, the arguments can be different, therefore you will have to declare it the same as the argument in your functions.
Now, to actually Disable the Z Buffer.
the following code belongs in your function that hooks the DrawIndexedPrimitive of the game.
if (PlayerBody){
DWORD dwReEnableZB = D3DZB_TRUE;
//Note to Retards: Change psyDevice to your D3D9Device.
psyDevice->GetRenderState(D3DRS_ZENABLE, &dwReEnableZB); //Make sure the Buffer is enabled
psyDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE); // Disable it
psyDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_NEVER);// Reject the pixels (shaders)
}
There you go, a basic wallhack.
Cham(s):
Chams, is just a shortened way of saying Chameleon Wallhack. it is just a regular wallhack, with a texture overlay.
So, utilizing the code above, we just have to declare our textures.
like so:
bool Generate = true; // <-- to prevent flicker. will be explained later.
LPDIRECT3DTEXTURE9 texYellow, texRed;
Now we just need a function to generate our textures for us, you can write your own, but the following one is by Azorbix.
HRESULT GenerateTexture(IDirect3DDevice9 *pD3Ddev, IDirect3DTexture9 **ppD3Dtex, DWORD colour32)
{
if( FAILED(pD3Ddev->CreateTexture(8, 8, 1, 0, D3DFMT_A4R4G4B4, D3DPOOL_MANAGED, ppD3Dtex, NULL)) )
return E_FAIL;
WORD colour16 = ((WORD)((colour32>>28)&0xF)<<12)
|(WORD)(((colour32>>20)&0xF)<<8)
|(WORD)(((colour32>>12)&0xF)<<4)
|(WORD)(((colour32>>4)&0xF)<<0);
D3DLOCKED_RECT d3dlr;
(*ppD3Dtex)->LockRect(0, &d3dlr, 0, 0);
WORD *pDst16 = (WORD*)d3dlr.pBits;
for(int xy=0; xy < 8*8; xy++)
*pDst16++ = colour16;
(*ppD3Dtex)->UnlockRect(0);
return S_OK;
}
Now, in our endscene we need to actually use that function and generate those textures.
//this belongs in your ENDSCENE
/*
Remember our BOOL Generate? this is here so that your chams don't
flicker, over and over rapidly, cause it's ****ing annoying.
so, this bool makes sure that they're only generated once when the endscene is first initiated.
and not over, and over.
*/
if (Generate)
{
GenerateTexture(psyDevice, &texRed,D3DCOLOR_ARGB(255,255,0,0));
GenerateTexture(psyDevice, &texYellow,D3DCOLOR_ARGB(255,255,255,0));
Generate = false;
}
Now, the Final Bit. actually overlaying the textures.
Find your Wallhack code, and replace it with this:
if (PlayerBody){
DWORD dwReEnableZB = D3DZB_TRUE;
//Note to Retards: Change psyDevice to your D3D9Device.
psyDevice->SetTexture(0, texRed);// Turn the playerbody Red
psyDevice->GetRenderState(D3DRS_ZENABLE, &dwReEnableZB); //Enable the zBuffer
psyDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE); // Disable it
psyDevice->SetTexture(0, texYellow);// Turn the playerbody Yellow
psyDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_NEVER);// Reject the pixels (shaders)
}
If you were wondering how the chams code actually works, it is a Loop, and Loops through itself every time the PlayerBody is present.
So, here is how it works:
- if the Player is shown:
- Make him Red.
- Enable the Z buffer, so he displays Red when he is IN FRONT an object.
- disable the Z buffer.
- Make the Enemy/PlayerBody Yellow, so he displays Yellow when he is BEHIND an object.
- Disable stencil shaders.
and then, rinse, lather, repeat.
there you go, The basic definition of Chams/Wallhack, How they work, and the code to do it.
by Psycho