So im not really doing that much with the stuff I wrote a half a year ago. So i decided to share it. Hopefully other people find it handy
Im not explaining how it works thats way to much work and I dont remember everything.
I did alot in inline assembly using codecaves. I did this because I find it easier, and to make sure I didn't have to search alot of memory adresses every update. It's probably poorly coded aswell but hey... it works
Adresses:
Code:
// ========== [ Chams ] =========== //
#define ASM_CHAMS1 0x00538E66 // Head
#define ASM_CHAMS2 0x00538F05 // Body
// =========== [ Asm ] ============ //
#define ASM_OPKX 0x004667B0
#define ASM_OPKY 0x004667BA
#define ASM_OPKZ 0x004667C0
#define ASM_QUICKDRAW1 0x00541363
#define ASM_QUICKDRAW2 0x005415FB
#define ASM_UNLAMMO1 0x004A8229
#define ASM_UNLAMMO2 0x004A8248
#define ASM_NORELOAD 0x00493097
#define ASM_NWST1 0x00540F83
#define ASM_NWST2 0x00541006
#define ASM_STAMINA1 0x00489AA0
#define ASM_STAMINA2 0x00489AA5
#define ASM_STW 0x0049F4F1
#define ASM_NONADEBOUNCE 0x004665BB //006EF2A4
//// ========== [ Player ] =========== //
#define MEM_SPEED 0x00C6BE98
#define MEM_JUMPHEIGHT 0x00C6BE9C
#define MEM_STAMINAREFILL 0x00C6BEA4
#define MEM_POSX 0x00C6B308
#define MEM_POSY 0x00C6B30C
#define MEM_POSZ 0x00C6B310
#define MEM_GRAVITYX 0x00C6B314
#define MEM_GRAVITYY 0x00C6B318
#define MEM_GRAVITYZ 0x00C6B31C
#define MEM_YAW 0x00C6B320
#define MEM_PITCH 0x00C6B324
#define MEM_ROLL 0x00C6B328
#define MEM_YAWSPEED 0x00C6B32C
#define MEM_PITCHSPEED 0x00C6B330
#define MEM_FOV 0x00C6B33C
#define MEM_CANJUMP1 0x00C6BEB4
#define MEM_CANJUMP2 0x00C6BE98
#define MEM_NOSPREAD1 0x00C79BB0
#define MEM_NOSPREAD2 0x00C79CE4
#define MEM_NOSPREAD3 0x00C7BB6C
#define MEM_NOSPREAD4 0x00C7BB70
//// ============= [ probeersel ] =========== //
#define ASM_NODECMOV 0x00489F64
#define ASM_JUMPHEIGHTMUL 0x0048AB6C
#define ASM_NADEEXPLOSION 0x00464EFE
#define ASM_GETESP 0x004666C0
One position kill (OPK)
Alot of credits goes to SEGnosis. I used his adress to search the current opk address.
Inline asm part:
Code:
DWORD Callbackbase = (ASM_OPKX+0x13);//posx
float PositieX;
float PositieY;
float PositieZ;
void __declspec(naked) playerbase()
{
__asm{
mov eax, [PositieX]
add edx, 0D8h
mov [edx],eax
mov ecx,[PositieY]
mov [edx+4],ecx
mov eax,[PositieZ]
jmp [Callbackbase]
}
}
Function:
Code:
if(item.opk==1)
{
PositieX = *(float*)MEM_POSX;
PositieY = *(float*)(MEM_POSX + 0x4);
PositieZ = *(float*)(MEM_POSX + 0x8);
cdetour->DetourFunc((PBYTE)ASM_OPKX, (PBYTE)playerbase,5);
}else
{
ctool->WriteAsm((void*)ASM_OPKX,(PBYTE)"\x8B\x07\x81\xC2\xD8\x00\x00\x00",8);
}
Decreased movement speed
This basicly makes your state the normal walk state. So you will keep your walk speed and zoom speed.
Inline:
Code:
DWORD Callbackdecmovspeedsprint = (ASM_NODECMOV+0x5);
DWORD stancespeedsprint;
DWORD stancespeedinzoom;
DWORD stancespeedphrone;
DWORD stancespeedzoomphrone;
void __declspec(naked) DECMOVSPEED()
{
__asm {
cmp edi,stancespeedsprint // compare stand with 36 (sprint)
je [decmovno] // jmp if equal to 36(sprint)
cmp edi,stancespeedinzoom // compare stand with 1B (inzoom)
je [decmovno] // jmp if equal to 1B(inzoom)
cmp edi,stancespeedphrone // compare stand with 9 (phrone)
je [decmovno] // jmp if equal to 9(phrone)
cmp edi,stancespeedzoomphrone // compare stand with 24 (zoomed in + phrone)
je [decmovno] // jmp if equal to 24 (zoomed in + phrone)
jmp [Callbackdecmovspeedsprint] // if nothing changed then go back to normal without doing anything
decmovno:
mov edi,0x0//set stance to 0 (normal walk mode , speed)
jmp [Callbackdecmovspeedsprint]//jump terug naar oorspronkelijke code
}
}
Function:
Code:
if(item.decmovspeed)
{
cdetour->DetourFunc((PBYTE)ASM_NODECMOV, (PBYTE)DECMOVSPEED,5);
}else if(item.decmovspeed==0 && item.decmovspeedsprint==0 && item.decmovspeedinzoom==0 && item.decmovspeedphrone==0)
{
ctool->WriteAsm((PBYTE*)ASM_NODECMOV,(PBYTE)"\x39\x7E\x40\x74\x45",5);//off byten 1regel
}
if(item.decmovspeedsprint==1)
{
stancespeedsprint = 0x36;
}else if(item.decmovspeedsprint==0)
{
stancespeedsprint = 0x1;
}
if(item.decmovspeedinzoom==1)
{
stancespeedinzoom = 0x1B;
}else if(item.decmovspeedinzoom==0)
{
stancespeedinzoom = 0x1;
}
if(item.decmovspeedphrone==1)
{
stancespeedphrone = 0x9;
}else if(item.decmovspeedphrone==0)
{
stancespeedphrone = 0x1;
}
if(item.decmovspeedzoomphrone==1)
{
stancespeedzoomphrone = 0x24;
}else if(item.decmovspeedzoomphrone==0)
{
stancespeedzoomphrone = 0x1;
}
In the menu like this:
Code:
Huib->AddFolder("=l[ Player", Moptfolder, &folder.PLAYER, 2);
if(folder.PLAYER){
Huib->AddCategory(">Dec mov speed", Moptonoff, &item.decmovspeed,2);
if(item.decmovspeed==1){
Huib->AddItem(">| Sprint", Moptonoff, &item.decmovspeedsprint, 2);
Huib->AddItem(">| Zoomed", Moptonoff, &item.decmovspeedinzoom, 2);
Huib->AddItem(">| Phrone", Moptonoff, &item.decmovspeedphrone, 2);
Huib->AddItem(">| Zoom + Phrone", Moptonoff, &item.decmovspeedzoomphrone, 2);
}
Shoot Through Walls
Function:
Code:
if(item.stw==1){ ctool->WriteAsm((void*)ASM_STW,(LPBYTE)"\xE9\x74\x01\x00\x00 ",5);//jump
}else{ ctool->WriteAsm((void*)ASM_STW,(LPBYTE)"\x0F\x84\x73\x01\x00\x00",6);}
Stamina
Inline:
Code:
DWORD Callbackstamina = (ASM_STAMINA1+0xB);//stamina
DWORD staminavalue; //= 0x35;
DWORD stamemptyspeed; //= 0x1;
DWORD staminarefill ;//= 0x25;
DWORD staminarefillto; //= 0x60;
void __declspec(naked) STAMINA()
{
__asm {
cmp item.staminafreeze, 1 // compares the value of staminafreeze (set to 1 in menu), with 1
jnge [tostaminafreeze] // jmp if staminafreeze isnt turned on
mov eax, [staminavalue] // if its turned on then set stamina value in eax
jmp [tostaminafreezefurther] // jump to continu the code without resetting the stamina what would happen in mov eax, [edi]
tostaminafreeze:
mov eax, [edi]//[staminavalue] // if staminafreeze isnt turned on then give it a value
tostaminafreezefurther:
mov ecx, [ebp+0] // set value( standard 100 or 0x64) in ecx
add esp, 10h // add 10 bytes to esp
cmp ecx, eax // eax is stamina , ecx is value when stamina can decrease (100)
jl [tostaminais100] // jmp if eax is less (not greater or equal) to ecx. So when your stamina is lower then 100 so stamina can decrease
sub eax, [stamemptyspeed] // decrease stamina by value (standard 3)
mov [edi],eax // put the decreased value in edi
tostaminais100:
mov eax, [staminarefill]
cmp dword ptr [edi], eax // compare stamina to 1
jge [Callbackstaminajmp] // if stamina is equal or greater then jump
mov ecx, [staminarefillto]
mov dword ptr [edi], ecx // when stamina is less then 1, set stamina value to 1. So it cant be negative
Callbackstaminajmp:
jmp [Callbackstamina] // go back to original value
}
}
Function:
Code:
if(item.staminagroup)
{
cdetour->DetourFunc((PBYTE)(ASM_STAMINA1-0x12), (PBYTE)STAMINA,5);
if(item.staminaemptyspeed>=0)
{
stamemptyspeed = item.staminaemptyspeed+1;
}
if(item.staminarefillspeed==1) { *(float*)MEM_STAMINAREFILL = 0; }
if(item.staminarefillspeed==2) { *(float*)MEM_STAMINAREFILL = (1/1.0); }
if(item.staminarefillspeed==3) { *(float*)MEM_STAMINAREFILL = (1/5.0); }
if(item.staminarefillspeed==4) { *(float*)MEM_STAMINAREFILL = (1/10.0); }
if(item.staminarefillspeed==5) { *(float*)MEM_STAMINAREFILL = (1/15.0); }
if(item.staminarefillspeed==6) { *(float*)MEM_STAMINAREFILL = (1/20.0); }
if(item.staminarefillspeed==0) { *(float*)MEM_STAMINAREFILL = (1/11.35); }
if(item.stamina == 1 && item.staminarefill >= 1 && item.staminarefillto >= 1)
{
staminarefill = (item.staminarefill*10);
staminarefillto = (item.staminarefillto*10);
}
else if(item.stamina != 1)
{
staminarefill = 0x1;
staminarefillto = 0x1;
}
if(item.stamina == 2)
{
if(item.staminafreeze)
{
staminavalue = (item.staminafreeze*10)+item.staminaemptyspeed+1;
}
}else if(item.stamina != 2){
item.staminafreeze=0;
}
}else
{
ctool->WriteAsm((void*)(ASM_STAMINA1-0x12),(PBYTE)"\x8B\x07\x8B\x4D\x00",5);//off byte eerste 2 regels
}
Menu:
Code:
char *Stamina[] = { "Off", "Refill", "Freeze" };
char *Staminarefill[] = { "1", "10", "20", "30", "40", "50", "60", "70", "80", "90", "100" };
char *Staminarefillspeed[] = { "Standard","Instant", "1 p/sec", "5 p/sec","10 p/sec","15 p/sec","20 p/sec" };
char *Staminaemptyspeed[] = { "1 p/sec", "2 p/sec", "Standard","4 p/sec","5 p/sec" };
if(item.staminagroup==1)
{
Huib->AddItem(" Emptyspeed", Staminaemptyspeed, &item.staminaemptyspeed, 5);
Huib->AddItem(" Refillspeed", Staminarefillspeed, &item.staminarefillspeed,7);
Huib->AddCategory(">Stamina", Stamina, &item.stamina,3);
if(item.stamina==1){
Huib->AddItem(" Refill Value", Staminarefill, &item.staminarefill, 11);
Huib->AddItem(" Refillto Value", Staminarefill, &item.staminarefillto, 11);
}
if(item.stamina==2){
Huib->AddItem(" Freeze Value", Staminarefill, &item.staminafreeze, 11);
}
}
Quickdraw 1 & 2
Inline:
Code:
DWORD Callbackzoomin = (ASM_QUICKDRAW1-0x2);//posx
DWORD Inzoomtimer;
void __declspec(naked) QUICKDRAW1()
{
__asm {
mov eax, [Inzoomtimer]
add esp, 10h
jmp [Callbackzoomin]//jump terug naar oorspronkelijke code
}
}
DWORD Callbackzoomout = (ASM_QUICKDRAW2-0x2);//posx
DWORD Outzoomtimer;
void __declspec(naked) QUICKDRAW2()
{
__asm {
mov ecx, [Outzoomtimer]
add esp, 10h
jmp [Callbackzoomout]//jump terug naar oorspronkelijke code
}
}
Function:
Code:
if(item.quickdraw1)
{
Inzoomtimer = 9-item.quickdraw1;
cdetour->DetourFunc((PBYTE)(ASM_QUICKDRAW1-0x7), (PBYTE)QUICKDRAW1,5);
}else
{
ctool->WriteAsm((PBYTE*)(ASM_QUICKDRAW1-0x7),(PBYTE)"\x8B\x02\x83\xC4\x10",5);//off byten 1regel
}
if(item.quickdraw2)
{
Outzoomtimer = 9-item.quickdraw2;
cdetour->DetourFunc((PBYTE)(ASM_QUICKDRAW2-0x7), (PBYTE)QUICKDRAW2,5);
}else
{
ctool->WriteAsm((PBYTE*)(ASM_QUICKDRAW2-0x7),(PBYTE)"\x8B\x08\x83\xC4\x10",5);//off byten 1regel
}
Menu:
Code:
char *quickdraw[] = { "Off", "8", "7", "6", "5", "4", "3", "2", "1", "Instant"};
Huib->AddItem(" Quickdraw1", quickdraw, &item.quickdraw1,10);
Huib->AddItem(" Quickdraw2", quickdraw, &item.quickdraw2,10);
No spread, No reload, Nade explosion and No nade bounce
Function:
Code:
if(item.nadebounce==1){ ctool->WriteAsm((void*)ASM_NONADEBOUNCE,(LPBYTE)"\x90\x90\x90\x90\x90\x90",6);
}else{ ctool->WriteAsm((void*)ASM_NONADEBOUNCE,(LPBYTE)"\x0F\x84\x73\x01\x00\x00",6);}
if(item.noreload==1){ ctool->WriteAsm((void*)ASM_NORELOAD,(LPBYTE)"\x90\x90",2);
}else{ ctool->WriteAsm((void*)ASM_NORELOAD,(LPBYTE)"\x89\x11",2);}
if(item.nadeexplosion==1)
{
if(GetAsyncKeyState(VK_NUMPAD4)&1)
{
ctool->WriteAsm((void*)ASM_NADEEXPLOSION,(PBYTE)"\xEB\x06",2);
}else{
ctool->WriteAsm((void*)ASM_NADEEXPLOSION,(PBYTE)"\x90\x90",2);
}
}else{
ctool->WriteAsm((void*)ASM_NADEEXPLOSION,(PBYTE)"\x7B\x06",2);
}
if(item.spread==1){
*(float*)MEM_NOSPREAD1 = 0;
*(float*)MEM_NOSPREAD2 = 0;
*(float*)MEM_NOSPREAD3 = -12.5;
*(float*)MEM_NOSPREAD4 = -12.5;
}
No weapon switch time(NWST)
Inline:
Code:
DWORD Callbacknwst = (ASM_NWST2+0x8);//nwst
DWORD nwsttimer;
void __declspec(naked) NWST()
{
__asm {
add eax, [nwsttimer]
pop edi
mov [esi+21Ch], eax
jmp [Callbacknwst]//jump terug naar oorspronkelijke code
}
}
Function:
Code:
if(item.weapswitch>1)
{
nwsttimer = item.weapswitch - 1;
ctool->WriteAsm((PBYTE)ASM_NWST1, (PBYTE)"\x7E\x43",2);
cdetour->DetourFunc((PBYTE)ASM_NWST2, (PBYTE)NWST,5);
}
if(item.weapswitch==1)
{
ctool->WriteAsm((PBYTE)ASM_NWST1, (PBYTE)"\x90\x90",2);
}
if(item.weapswitch==0)
{
ctool->WriteAsm((PBYTE)ASM_NWST1, (PBYTE)"\x7E\x43",2);
ctool->WriteAsm((PBYTE)ASM_NWST2, (PBYTE)"\x40\x5F\x89\x86\x1C\x02\x00\x00",8);
}
Menu:
Code:
char *nwst[] = { "Off", "Instant", "2x", "3x", "4x", "5x"};
Huib->AddItem(" Nwst", nwst, &item.weapswitch,6);
Unl ammo 1 & 2
Inline:
Code:
DWORD Callbackunlammo1 = (ASM_UNLAMMO1+0x5);
DWORD lowerammo1;
DWORD refillammo1;
void __declspec(naked) UNLAMMO1()
{
__asm {
cmp eax, [lowerammo1]
je [toccunl1even]
mov ecx, eax
dec ecx
mov [edi],ecx
jmp [Callbackunlammo1]
toccunl1even:
mov ecx, [refillammo1]
mov [edi], ecx
jmp [Callbackunlammo1]//jump terug naar oorspronkelijke code
}
}
Function:
Code:
if(item.unlammo11==1)
{
if(item.unlammo1refill>0)
{
lowerammo1 = item.unlammo1refill-1;
}
if(item.unlammo1refillto>0)
{
refillammo1 = item.unlammo1refillto-1;
}
cdetour->DetourFunc((PBYTE)ASM_UNLAMMO1, (PBYTE)UNLAMMO1,5);
}else
{
ctool->WriteAsm((PBYTE*)ASM_UNLAMMO1,(PBYTE)"\x8B\xC8\x49\x89\x0F",5);//off byte 48 89 06 83 7F 14 01
}
if(item.unlammo22==1){
ctool->WriteAsm((PBYTE*)ASM_UNLAMMO2,(PBYTE)"\x90",1);
}else{
ctool->WriteAsm((PBYTE*)ASM_UNLAMMO2,(PBYTE)"\x49",1);
}
Menu:
Code:
char *Tellen[] = { "Off", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39"};
Huib->AddCategory(" Unl ammo1", Unlammo, &item.unlammo11,2);
if(item.unlammo11==1){
Huib->AddItem(" Refill", Tellenunl, &item.unlammo1refill,31);
Huib->AddItem(" Refill to", Tellenunl, &item.unlammo1refillto,31);
}
Huib->AddItem(" Unl ammo2", Moptonoff, &item.unlammo22,2);
Getting playeradress and ID
Put this in to activate it from beginning:
Code:
cdetour->DetourFunc((PBYTE)ASM_GETESP, (PBYTE)GetPlayerID,5);
Inline part:
Code:
DWORD Callbackgetplayerid = ASM_GETESP+0xD;
void __declspec(naked) GetPlayerID()
{
__asm{
pushad
}
dwdeel1 = *(DWORD*)0x00C8CBD0;
dwdeel2 = *(DWORD*)dwdeel1;
dwdeel3 = *(DWORD*)(dwdeel2+0x10);
__asm{
popad
mov ecx, [eax+0x10] // this is almost the same as dwdeel3 = *(DWORD*)(dwdeel2+0x10);
lea edx,[esp+0xC]
mov [esi+0x1BC], ecx
mov [playerAdr],ecx // get player adress from ecx
push edx // save edx
mov edx,dwdeel3 // put the adress from dwdeel3 in edx
cmp playerAdr,edx // compare playeradress with edx. So we can see if it made a full loop. Every player will get an ID.
pop edx // restore edx
je [restartteller] // jump if a everyplayer got an ID. If not then increase playerID.
push eax // save eax
mov eax,[playerID] // put the playerID in eax
inc eax // increase playerID by 1
mov [playerID],eax // put the increased value back in playerID
pop eax // restore eax
jmp [afsluiting] // jump to the ending of the codecave
restartteller: // the reset playerID counter to 1 part.
mov [playerID],1// reset playerID to 1
jmp [afsluiting] // jump to the ending of the codecave
afsluiting:
pushad // save all
call [LogplayerLoop] // option to log some value's. Was handy for me to make everything work..
call [Userfinder]// The userfinder function is called here
//call [Aimbot] // unfinshed aimbot was here. Esp could be made aswell.
popad // restore all
jmp [Callbackgetplayerid] // jump back to original code.
}
}
The playeradress is now in playerAdr and the ID is in playerID. This is used to make the userfinder. The code above also calls userfinder and logplayerloop. This is the next part. Userfinder with callplayer and tp to player
Userfinder
Code:
void __declspec(naked)Userfinder()
{
FINDER_ADR = playerAdr;
FINDER_ID = playerID;
if(item.userfinder)
{
if(item.userfinder==playerID)
{
if(item.teleporttouser==1)
{
if(GetAsyncKeyState(VK_NUMPAD5)&&*(float*)(playerAdr+0xD8)!=0)
{
*(float*) MEM_POSX = *(float*)(playerAdr+0xD8);
*(float*) MEM_POSY = *(float*)(playerAdr+0xDC)+100;
*(float*) MEM_POSZ = *(float*)(playerAdr+0xE0);
}
}
if(item.calluser==1)
{
if(*(float*)(playerAdr+0xD8)!=0)
{
*(float*)(playerAdr+0xD8) = *(float*) MEM_POSX;
*(float*)(playerAdr+0xDC) = *(float*) MEM_POSY+20;
*(float*)(playerAdr+0xE0) = *(float*) MEM_POSZ;
}
}
sprintf(Char.remoteuserplayeradr , "Adress: %X", playerAdr);
sprintf(Char.remoteusername , "Name: %s", (void*)(playerAdr+0x3C));
sprintf(Char.remoteuserposx , "Posx: %.2f", *(float*)(playerAdr+0xD8));
sprintf(Char.remoteuserposy , "Posy: %.2f", *(float*)(playerAdr+0xDC));
sprintf(Char.remoteuserposz , "Posz: %.2f", *(float*)(playerAdr+0xE0));
sprintf(Char.remoteuserhealth , "Health: %i", *(int*)(playerAdr+0x114));
sprintf(Char.remoteuserkills , "Kills: %i", *(int*)(playerAdr+0xF0));
sprintf(Char.remoteuserdeaths , "Deaths: %i", *(int*)(playerAdr+0xF4));
sprintf(Char.remoteuserhs , "HS: %i", *(int*)(playerAdr+0xFC));
sprintf(Char.remoteuseralive , "A****** %i", *(int*)(playerAdr+0x104));
sprintf(Char.remoteusernear , "Near: %i", *(int*)(playerAdr+0x108));
}
}
__asm{
ret
}
}
The next part is so you can log the value's in de ecx etc. Handy for if you want to see if you are right.
Code:
DWORD playerID;
DWORD playerAdr;
DWORD PLAYERSINROOM;
DWORD PLAYERSINROOM2;
DWORD FINDER_ADR;
DWORD FINDER_ID;
DWORD dwdeel1;
DWORD dwdeel2;
DWORD dwdeel3;
void __declspec(naked)LogplayerLoop ()
{
PLAYERSINROOM2 = *(DWORD*)(0x00C4CBEC);
if(item.logplayer==1){
AddLog("PlayerID========[%i]",playerID);
//AddLog("PlayerRoom-< %X",dwdeel3);
AddLog("waardeecx-> %X",playerAdr);
AddLog("cmpmet-> %X",dwdeel3);
AddLog("Naam-> %s",(playerAdr+0x3C));
//AddLog("room-> %i",(DWORD)PLAYERSINROOM2);
//AddLog("waardeedx-> %X",waardeedx);
//AddLog("waardeesi-> %X",waardeesi);
// AddLog("waardeeax-> %X",waardeeax);
AddLog("");
}
__asm{
ret
}
}
With this you have enough to make an aimbot and esp!
I hope it's handy. Enjoy!