Well, basically what this thread is about is in the title
. I want it to be an overview of EVERYTHING this site has to say on how to hack games. So here goes. Because I'm new, there will probably be lots of stuff missing so please post corrections, especially where I have used a term wrongly or asked for help. The idea is that someone completely new, but with a knowledge of C++, could read this thread and by the end be pointed in the right dirction of constructing his/her own hack. Basically it tells you all the steps to making a completely PB proof hack (hopefully!), though without going into so much detail that it becomes hard to read or takes too long. It should be general enough that the concept can be used for any game, while specific enough that it can be used for any game.
It is designed to prevent having to trawl all the seperate forums in order to figure out what goes where - how everything fits together in one thread. I will try to keep it updated when people post helpful comments or links. So here goes...
Step 1
Go away and learn C++ if you haven't already.
Personally I prefer http://msdn2.microsoft.com/en-us/beginner/cc305129.aspx and the links that are on there. But it's a matter of personal preference - whatever works for you.
Also some ASM. I recommend Cheat Engine :: View topic - A Very In Depth Tutorial on Auto Assembler for the basics. [Tutorial] - ASM for Beginners - UnKnoWnCheaTs is much more in depth., but I'm not entirely sure if all of it is necessary.
Step 2
There are a few different types of hacks. Direct3D, Client Hook, OpenGL, or combinations of the above, called Hybrids. Having both graphical (eg. chams) and coded (eg. no recoil) make these the most effective.
A very basic client hook will just virtual protect, then memcpy a few bytes here and there. I recommend this as a starting hack, similar to just changing them in a debugger (eg. Ollydbg). FOR EXAMPLE:
Code:
void DoPatch(int address, unsigned char *patchbytes, int sizeofpatchbytes)
{
unsigned long Protection;
VirtualProtect ( (void*)address, sizeofpatchbytes, PAGE_READWRITE, &Protection ) ;
memcpy ( (void*)address, (const void*)patchbytes, sizeofpatchbytes ) ;
VirtualProtect ( (void*)address, sizeofpatchbytes, Protection, 0 ) ;
}
unsigned char NoRecoil[2] = { 0x75, 0x12 } ; // the hacked bytes
unsigned char NoRecoilOrig [2] = { 0x74,0x12 } ; // the original bytes
BOOL WINAPI DllMain (HINSTANCE hModule, DWORD dwAttached, LPVOID lpvReserved)
{
DoPatch (0x457DFF, NoRecoil, sizeof(NoRecoil) ) ;
} // this is no recoil for CoD4 v1.5 as demonstrated by Quicktime Step 3
Aimbots;
Most aimbots work by using Client Hooks. Client Hook hacks work by looking at the data sent to you by the server, taking the useful bits, and then doing whatever is necessary for the hack to work. As we are making an aimbot, the general idea is that it aims and shoots for you. The idea behind this is that it takes the position of the enemy, your position, works out where your mouse needs to be, and 'clicks' - all at the speed of your computer
.
To make the client hook itself you basically use a 'detour' - see this page for info on making the client hook. Ok so what do you hook? The enemy position and your position, as has been said. However, as you do not need to actually CHANGE anything, a detour is not necessary for an aimbot. A bot just needs to read the right addresses for information (eg. enemy position) then move your mouse accordingly.
So how do you find out the addresses to be has been hooked? Look them up here on CU
or find them out yourself by searching. For example,
From jmpnop;
As anyone who has done some reversing/offset finding can tell you, locating ascii strings within an executable is the fastest way to, well, find offsets or reverse areas of interest - like wiping out multihack violations That means we search for text within an executable, and when we find something useful we pounce
and manipulate it for our own ends. I would advise the simple no-recoil tutorial by Quicktime as an example to get started quickly. Basically the idea is;
Code:
Ok I know its not code but the box helps to seperate stuff out :)
Start up game.
Start new server (password it - its just for testings - recommended use time unlimited).
Attach Ollydbg.
Alt+E (Search for Executable Modules).
iw3mp.exe (double-click)
Right-click on main area
Search for -> All referenced text strings
Then right-click again, Search for text
Search for your chosen text string (eg FireWeapon for CoD4 no recoil hack). Choose entire scope at the bottom left of the search box.
Press search and double click on the string you want
It takes you straight to the function which is next to your referenced string. In my example, for no recoil, I suggest fiddling with CMP and JMP variants (eg. JE or JNZ)...
If you know nothing of ASM (eg. CMP and JMP) then look at this also this (both the same tutorial, just different links). VERY GOOD TUTORIAL ON ASM! just click on one of the word 'this' further back
You then work out the angle your gun needs to aim at - see this page. When you have all the angles, you can (hopefully) script your gun to aim at the correct angle, and then fire when something is under it, as is demonstrated by any aimbot sources.
The following code (I believe) is the Autoshoot function from Nexus, and thus a good example. Obviously some of it is specific to the game, and most of it is not defined here, but it is a start, and the rest of the code can be found here in the download section.
PHP Code:
void CNexAimbot::doAutoShoot(bool shoot)
{
// Don't shoot if we're specing/following a player
if (nex.cg_clientNum != nex.cg_snap->ps.clientNum)
return;
if (shoot) {
if (nex.mod->type == MOD_TCE) {
staticbool lastFrameAttack = false;
if (!lastFrameAttack) {
nexSyscall.SendConsoleCommand("+attack\n");
lastFrameAttack = true;
} else {
nexSyscall.SendConsoleCommand("-attack\n");
lastFrameAttack = false;
}
} else {
// Check for sniper weapon delay
if (((nex.cg_entities[nex.cg_clientNum].currentState->weapon == WP_K43_SCOPE) || (nex.cg_entities[nex.cg_clientNum].currentState->weapon == WP_GARAND_SCOPE)) && !BG_PlayerMounted(nex.cg_snap->ps.eFlags)) {
staticint lastShootTime = 0;
if ((nex.cg_time - lastShootTime) >= nexValue[VAR_SNIPERDELAY]) {
nexSyscall.SendConsoleCommand("+attack\n");
lastShootTime = nex.cg_time;
} else {
nexSyscall.SendConsoleCommand("-attack\n");
}
// Check for weapon overheating
#define OVERHEATING_LIMIT 200
} elseif (nexValue[VAR_OVERHEAT] && (nex.cg_snap->ps.curWeapHeat > OVERHEATING_LIMIT)) {
nexSyscall.SendConsoleCommand("-attack\n");
} else {
nexSyscall.SendConsoleCommand("+attack\n");
}
}
} else {
nexSyscall.SendConsoleCommand("-attack\n");
}
}
Some of the code for the aimbot you should probably write yourself
such as limiting the field of view or something like that.
Humanised aimbotting is a very specific type. Things to make it less easily detectable, and more 'human' are employed. Simple examples, like limiting the field of view for the aimbot (so it won't suddenly swing 180 degrees to pwn the person sneaking up on you), limiting the speed at which it can turn the mouse, or introducing a fire delay (eg. will not fire as soon as crosshair is on target, or will fire before crosshair is on target) should be easy. More complicated are things like changing the accuracy, and the amount of times it aims for headshots, maybe even depending on the gun you have! (eg. with sniper rifles it goes for headshots more often than with pistol). There are many different ways to make an aimbot more 'human' but the very best are usually hard to detect.
Step 5
The memory hacks;
Ok so we have got an aimbot...what next?
Wallhack
Tags
Warnings
A crosshair
A menu
The theory is that all that data necessary for these things is sent to you by the server already - it just doesn't display that on screen. So all we need to do is to make it display the data that it already knows - sounds simple huh?
Sometimes wallhacks can be accomplished by just changing a single byte as demonstrated here by crx. A hack might display nametags by changing the function which checks what team you are on (and thus whether to display the nametags). You find this address by again searching CU, or then again you could find them for yourself (more help needed here!!!).
Of course, these are best combined with D3D elements. For example, reading player names and locations from memory, then using Direct3D to print them to screen. The principle applies for just about everything related the the players - so name tags, rank/level tags, distance tags, class tags, activity tags, etc. etc.
Warnings could also be done this way The low ammo indicator should probably be linked to the gun you are wielding, so, for example in pseudo-code; Code:
if (player.health < 30) //30% health
{
Display "Health low" //where display is your function for showing something on screen
}
or
if (player.gun = lightmg) //if you have a gun with a large ammo belt
{
if (player.ammoremaining < 10) // if you have less than ten bullets left
{
display "Ammo low" // then show the message
}
}
if (player.gun = sniperrifle) // if you have a sniper rifle, say with a clip size of 10
{
if (player.ammoremaining < 3) // less than three bullets left
{
display "Ammo low" // then show the message
}
}
A menu is harder, especially if one wishes to have a cursor (as opposed to operable with the arrow keys). Have a look at Wurzil/N7's cham example, which comes with a menu, found here. A crosshair can easily be acheived by just calling direct draw to draw two lines onscreen at the centre of our screen, like this, from the same source (credits to Wurzil and sinner).
Code:
if ( bCrossHair )
{
MyDraw.vFillRGBA( PosX1 + 1, PosY1 + 2, 75, 18, 24, 34, 21,255 );
PrintString(menu_font1,Xoff1 - 2, PosY1+5,255,255,0, 255,"Crosshair");
}
else
{
//MyDraw.vFillRGBA( PosX1 + 2, PosY1 + 3, 75, 18, 140, 140, 140,255 );
MyDraw.vFillRGBA( PosX1 + 1, PosY1 + 2, 75, 18, 42, 62, 49, 255 );
PrintString(menu_font1,Xoff1 -2, PosY1+5,255,255,0, 255,"Crosshair");
}
Step 6
Chams
Engine;
There will be a rendering function to show stuff on screen. If you hook/detour this function, and check what argument has been passed, you can tell what model it is, and thus whether to colour it or not (using D3D or OpenGL). Have a look at Sinner's example of this for CoD4 @ COD4: D3D Model rec with strings - Game Deception - Forums.
OpenGL; Someone will have to tell me how, but the idea is that you can call the functions of OpenGL with your injected .dll to display stuff on screen. With this, you script it so that enemies (for example) are red, enemies behind walls are yellow, friendlies are green, and friendlies behind walls are blue. The easiest, alternative way of doing this for OpenGL is including a cracked driver, whereby the games call the display functions as normal, but when your cracked driver recognises that it is asking to display players, it displays the players differently on screen (ie. with camos!).
Wurzil says you can do OpenGL chams using 'counts'. The example for CoD2 is here.
D3D; (Direct3D) There are two things worth mentioning here. Firstly, you can use it simply to colour the models you identified earlier from the engine rendering functions, or you can used model recognition. Model recognition looks at the 'thing' being draw on screen as a series of numbers - the number of vertices (numVerts), the number of primitives (primCount). As most models will have unique combinations of these, they can be used as identifying features. Kidebr's CoD4 menu source includes these model recs.
PHP Code:
#define Opfor ((NumVertices == 3124 && primCount == 4132) || (NumVertices == 1970 && primCount == 2186) || (NumVertices == 1252 && primCount == 1160) || (NumVertices == 470 && primCount == 352) || (NumVertices == 3531 && primCount == 4526) || (NumVertices == 2188 && primCount == 2386) || (NumVertices == 1325 && primCount == 1194) || (NumVertices == 499 && primCount == 352) || (NumVertices == 2715 && primCount == 3588) || (NumVertices == 1620 && primCount == 1886) || (NumVertices == 943 && primCount == 908) || (NumVertices == 441 && primCount == 308) || (NumVertices == 2816 && primCount == 3642) || (NumVertices == 1773 && primCount == 2022) || (NumVertices == 1150 && primCount == 1086) || (NumVertices == 435 && primCount == 320) || (NumVertices == 250 && primCount == 304) || (NumVertices == 2818 && primCount == 3672) || (NumVertices == 150 && primCount == 142) || (NumVertices == 1715 && primCount == 1950) || (NumVertices == 1101 && primCount == 1066) || (NumVertices == 481 && primCount == 350) )
#define Marines ((NumVertices == 681 && primCount == 588 ) || (NumVertices == 2613 && primCount == 3248) || (NumVertices == 1842 && primCount == 1978) || (NumVertices == 1144 && primCount == 814) || (NumVertices == 1034 && primCount == 904) || (NumVertices == 447 && primCount == 312) || (NumVertices == 3790 && primCount == 4078) || (NumVertices == 2784 && primCount == 2384) || (NumVertices == 1572 && primCount == 1166) || (NumVertices == 634 && primCount == 372) || (NumVertices == 233 && primCount == 330) || (NumVertices == 3597 && primCount == 4280) || (NumVertices == 2301 && primCount == 2364) || (NumVertices == 1341 && primCount == 1132) || (NumVertices == 580 && primCount == 380) || (NumVertices == 689 && primCount == 1172) || (NumVertices == 367 && primCount == 298) || (NumVertices == 4050 && primCount == 4486) || (NumVertices == 308 && primCount == 212) || (NumVertices == 2540 && primCount == 2444) || (NumVertices == 628 && primCount == 670) || (NumVertices == 1488 && primCount == 1114) || (NumVertices == 105 && primCount == 74) || (NumVertices == 592 && primCount == 374) || (NumVertices == 2516 && primCount == 2940) || (NumVertices == 106 && primCount == 114) || (NumVertices == 1726 && primCount == 1760) || (NumVertices == 1020 && primCount == 872) || (NumVertices == 587 && primCount == 370) || (NumVertices==204 && primCount==172) || (NumVertices== 681 && primCount==588) || (NumVertices== 63 && primCount== 62) ||(NumVertices== 822 && primCount== 1084)||(NumVertices== 2516 && primCount== 2940)||(NumVertices== 394 && primCount== 274) ||(NumVertices== 275 && primCount== 322) ||(NumVertices== 1409 && primCount== 868) ||(NumVertices== 716 && primCount== 962) ||(NumVertices== 394 && primCount== 274) ||(NumVertices== 178 && primCount== 166) ||(NumVertices== 1344 && primCount== 944) ||(NumVertices== 599 && primCount== 418) ||(NumVertices== 49 && primCount== 50) ||(NumVertices== 855 && primCount== 1100)||(NumVertices== 56 && primCount== 44) ||(NumVertices== 183 && primCount== 112) ||(NumVertices== 3790 && primCount== 4078)||(NumVertices== 56 && primCount== 44) ||(NumVertices== 34 && primCount== 30) ||(NumVertices== 874 && primCount== 1228) || (NumVertices== 213 && primCount== 282) ||(NumVertices== 367 && primCount== 298) ||(NumVertices== 306 && primCount== 274) ||(NumVertices== 1495 && primCount== 982) ||(NumVertices== 1198 && primCount== 842) ||(NumVertices== 306 && primCount== 274) ||(NumVertices== 4050 && primCount== 4486)|| (NumVertices== 686 && primCount== 952 )||(NumVertices== 828 && primCount== 1300)||(NumVertices== 3597 && primCount== 4280)||(NumVertices== 356 && primCount== 262 )||(NumVertices== 110 && primCount== 122 )||(NumVertices== 2613 && primCount== 3248)||(NumVertices== 1001 && primCount== 964) )
#define Spetnaz ((NumVertices == 4358 && primCount == 4864) || (NumVertices == 3278 && primCount == 3188) || (NumVertices == 503 && primCount == 704) || (NumVertices == 1633 && primCount == 1332) || (NumVertices == 840 && primCount == 618) || (NumVertices == 783 && primCount == 1168) || (NumVertices == 4242 && primCount == 5028) || (NumVertices == 2391 && primCount == 2488) || (NumVertices == 1689 && primCount == 1422) || (NumVertices == 384 && primCount == 250) || (NumVertices == 969 && primCount == 708) || (NumVertices == 4270 && primCount == 4804) || (NumVertices == 2755 && primCount == 2494) || (NumVertices == 1317 && primCount == 1054) || (NumVertices == 809 && primCount == 590) || (NumVertices == 793 && primCount == 834) || (NumVertices == 3891 && primCount == 4598) || (NumVertices == 592 && primCount == 532) || (NumVertices == 2510 && primCount == 2470) || (NumVertices == 171 && primCount == 114) || (NumVertices == 1398 && primCount == 1176) || (NumVertices == 384 && primCount == 250) || (NumVertices == 384 && primCount == 250) || (NumVertices == 994 && primCount == 714) || (NumVertices == 529 && primCount == 540) || (NumVertices == 353 && primCount == 346) || (NumVertices == 726 && primCount == 556) || (NumVertices == 1315 && primCount == 1170) || (NumVertices == 2140 && primCount == 2310) || (NumVertices == 3326 && primCount == 4336) || (NumVertices == 3254 && primCount == 4122) || (NumVertices == 1730 && primCount == 1938) || (NumVertices == 398 && primCount == 410) || (NumVertices == 327 && primCount == 500) || (NumVertices == 2388 && primCount == 2040) || (NumVertices == 222 && primCount == 298) || (NumVertices == 1111 && primCount == 986) || (NumVertices == 1186 && primCount == 1184) || (NumVertices == 339 && primCount == 248) || (NumVertices == 994 && primCount == 714) )
#define SAS ((NumVertices == 2334 && primCount == 2826) || (NumVertices == 438 && primCount == 376) || (NumVertices == 447 && primCount == 312) || (NumVertices == 1034 && primCount == 904) || (NumVertices == 1842 && primCount == 1978) || (NumVertices == 2613 && primCount == 3248) || (NumVertices == 1001 && primCount == 964) || (NumVertices == 3935 && primCount == 5226) || (NumVertices == 960 && primCount == 1072) || (NumVertices == 2640 && primCount == 3070) || (NumVertices == 212 && primCount == 288) || (NumVertices == 214 && primCount == 202) || (NumVertices == 1373 && primCount == 1256) || (NumVertices == 585 && primCount == 440) || (NumVertices == 634 && primCount == 372) || (NumVertices == 1572 && primCount == 1166) || (NumVertices == 2784 && primCount == 2384) || (NumVertices == 3790 && primCount == 4078) || (NumVertices == 3585 && primCount == 4858) || (NumVertices == 1498 && primCount == 1304) || (NumVertices == 2525 && primCount == 3022) || (NumVertices == 695 && primCount == 478) || (NumVertices == 193 && primCount == 140) || (NumVertices == 580 && primCount == 380) || (NumVertices == 1341 && primCount == 1132) || (NumVertices == 802 && primCount == 800) || (NumVertices == 2301 && primCount == 2364) || (NumVertices == 275 && primCount == 322) || (NumVertices == 3597 && primCount == 4280) || (NumVertices == 3716 && primCount == 5064) || (NumVertices == 2578 && primCount == 2994) || (NumVertices == 1412 && primCount == 1330) || (NumVertices == 568 && primCount == 470) || (NumVertices == 689 && primCount == 1172) || (NumVertices == 367 && primCount == 298) || (NumVertices == 4050 && primCount == 4486) || (NumVertices == 308 && primCount == 212) || (NumVertices == 2540 && primCount == 2444) || (NumVertices == 628 && primCount == 670) || (NumVertices == 1488 && primCount == 1114) || (NumVertices == 105 && primCount == 74) || (NumVertices == 592 && primCount == 374) || (NumVertices == 3562 && primCount == 4784) || (NumVertices == 2509 && primCount == 2954) || (NumVertices == 1402 && primCount == 1164) || (NumVertices == 628 && primCount == 450) || (NumVertices == 1615 && primCount == 1706) || (NumVertices == 541 && primCount == 366) || (NumVertices == 3667 && primCount == 4952) || (NumVertices == 2460 && primCount == 2882) || (NumVertices == 1479 && primCount == 1402) || (NumVertices == 552 && primCount == 452) )
Usage??
Place in Azorbix's Starter Kit;
Code:
HRESULT APIENTRY hkIDirect3DDevice9::DrawIndexedPrimitive(D3DPRIMITIVETYPE Type,INT BaseVertexIndex,UINT MinVertexIndex,UINT NumVertices,UINT startIndex,UINT primCount)
{
if (MODEL REC) // eg. if Opfor (using the example above)
{
m_pD3Ddev->SetTexture(0, RedTex); //make it red :D
}
return m_pD3Ddev->DrawIndexedPrimitive(Type,BaseVertexIndex, MinVertexIndex, NumVertices, startIndex, primCount);
}
Of course, you can also make it wallhacked (as above) and colour it different colours depending on whether it's behind a wall or not. This is done by enabling/disabling the zbufffer. The zbuffer stores objects distances from yourself. And of course, if it's disabled, it can't tell if something is in the way, because it can't tell which is closer, so the thing being drawn with no zbuffer always displays. So, more complex than above,
Code:
HRESULT APIENTRY hkIDirect3DDevice9::DrawIndexedPrimitive(D3DPRIMITIVETYPE Type,INT BaseVertexIndex,UINT MinVertexIndex,UINT NumVertices,UINT startIndex,UINT primCount)
{
if (ModelRec) // again our model recognition eg. if (NumVerts == 136 && PrimCount == 2409)
{
m_pD3Ddev->SetRenderState(D3DRS_ZENABLE, false); // disable the zbuffer
m_pD3Ddev->SetTexture(0, texYellow); // if its behind the wall colour it yellow
m_pD3Ddev->DrawIndexedPrimitive(Type,BaseVertexIndex, MinVertexIndex, NumVertices, startIndex, primCount); // draw everything
m_pD3Ddev->SetRenderState(D3DRS_ZENABLE, true);//Re enable the zbuffer
m_pD3Ddev->SetTexture(0, RedTex); // if it would still be drawn to screen (with the zbuffer enabled) colour it red
}
}
Step 7
This is meant to by the step where we make it undetectable. Hum. I'm not quite sure how. But have a look at [Coding] - CoD4 Memory Hack Base (PBHACK) - UnKnoWnCheaTs.
Screenshots. The best idea for screenshots it do turn the hack off for the single frame that the screenshot takes, then turn them back on straight away after the screenshot has been taken. Basically this involves another detour when, for example, Punkbuster calls the screenshot function, you instantly turn the hacks off, rerout to the original to take the screenshot, then rout it to turn the hacks on again (or more simply have it on a timer, so 3 seconds after the screenshot is taken (on the safe side!) you turn them on).
Thanks, Nosferatu (means Vampire)
Bookmarks