jeivarmarr (02-15-2014),Jhem (02-22-2014)
I'll give the source with some explaination of some functions in the cracky7 hack. I'll do alot in inline asm because i find that easy Im dutch so i'll have some dutch names for it.
Introduction
Most of the time codecaves made by inline asm will be done. Codecaves mean that on a certain adress we'll jump to somewhere else simply because there's no room to edit in the Original code. With a codecave we do it like this:
Adress (Place of a function we want to edit)
->Empty space (Place for our modified function)
->Jump back to Original code (So the code can continou)
I use inline asm because its easy to edit valuables with c++.
I hope this part is clear. Let's make OPK!!!!!!
Opk
Explained OpkCode:#define ASM_OPKX 0x00466960 #define MEM_POSX 0x00C2B518 #define MEM_POSY 0x00C2B51C #define MEM_POSZ 0x00C2B520 DWORD Callbackbase = (ASM_OPKX+0x13);//posx float PositieX; float PositieY; float PositieZ; void __declspec(naked) playerbase() { __asm { jmp [toccopkon]//jmp tocodecave toccopkon://codecave to opk mov eax, PositieX // PositieX means PositionX add edx, 0D8h mov [edx],eax mov ecx,PositieY mov [edx+4],ecx mov eax,PositieZ jmp [Callbackbase]//jump back to Original 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);//off byte eerste 2 regels }
The Original code of Opk is like this:
// // Get the value of eax in edx+8. ( With hack our positiony is in eax. So everybody will teleport to us in Z-axis)[/code]Code:.text:0046695A mov edx, [esi+1BCh] // edx = pointer + 1BC (believe its pointer to struc of all players, i call it basepointer) .text:00466960 mov eax, [edi] // Value of edi is stored in eax. This is the X position (We can use this to store our position in eax, so all players will teleport to us) .text:00466962 add edx, 0D8h // Add 0xD8 to edx (PlayerpositionX = esi+1BC+D8 => basepointer+D8) .text:00466968 mov [edx], eax // Get the value of eax in edx. ( With hack our positionx is in eax. So everybody will teleport to us in X-axis) .text:0046696A mov ecx, [edi+4] // Value of edi+4 is stored in eax. This is the Y position (We can use this to store our position in eax, so all players will teleport to us) .text:0046696D mov [edx+4], ecx // Get the value of eax in edx+4. ( With hack our positiony is in eax. So everybody will teleport to us in Y-axis) .text:00466970 mov eax, [edi+8] // Value of edi+8 is stored in eax. This is the Z position (We can use this to store our position in eax, so all players will teleport to us) .text:00466973 mov edi, [esp+2Ch+var_1C] .text:00466977 mov [edx+8], eax
So with this we basicly have the stuff needed to make opk.
Now the last part, making our modified function work:Code:mov eax, PositieX // Get our position on X-axis in eax add edx, 0D8h // edx+D8 is where enemy position is. mov [edx],eax // Get our positionX in edx, so all enemy players will teleport to us. mov ecx,PositieY // Get our position on Y-axis in eax mov [edx+4],ecx // Get our positionY in edx, so all enemy players will teleport to us. mov eax,PositieZ // Get our position on X-axis in eax jmp [Callbackbase]//jump back to Original code. We will jump back to this part: 00466973 mov edi, [esp+2Ch+var_1C]. This is where we stopped modifying the Original code.
Please if I explained badly tell me, also when i made a mistake pls tell me.Code:if(item.opk==1)// when opk is turned on { PositieX = *(float*)MEM_POSX; // get our positionX into PositieX (used in opk) PositieY = *(float*)(MEM_POSX + 0x4); // get our positionY into PositieY (used in opk) PositieZ = *(float*)(MEM_POSX + 0x8);// get our positionZ into PositieZ (used in opk) cdetour->DetourFunc((PBYTE)ASM_OPKX, (PBYTE)playerbase,5);// The jmp will be 5 bytes long }else { ctool->WriteAsm((void*)ASM_OPKX,(PBYTE)"\x8B\x07\x81\xC2\xD8\x00\x00\x00",8); } Offbyte explained: .text:00466960 mov eax, [edi] // ASM_OPKX , where we begin our modification (2 bytes long, 0x8B 0x07) .text:00466962 add edx, 0D8h // See above ( 6 bytes long, 0x81 0xC2 0xD8 0x00 0x00 0x00) .text:00466968 mov [edx], eax // because our jmp to jump to codecave is 5 bytes long will need to restore add edx, 0D8h aswell. The offbytes of both will be 0x8B 0x07 0x81 0xC2 0xD8 0x00 0x00 0x00. After this the original code wont go to the place where we modify it.
I hope you understand how to make it.. Im planning on adding more like unl ammo with refill or quickdraw.
Please becarefull with what u do and dont hack to Obvious! Im also not responsible for bans..
Log:
12-02-2014 - Begin, Opk added
jeivarmarr (02-15-2014),Jhem (02-22-2014)
Didn't know that I couldn't edit my post to edit. So I'll add them in reply's to this thread. I'll add unliminated ammo for primary secondary weapon for now.
Unliminated ammo 1 (primary & secondary weapon)
Unl ammo1 (primary and secundary) Explained:Code:#define ASM_UNLAMMO1 0x004A7A09 DWORD Callbackunlammo1 = (ASM_UNLAMMO1+0x5); DWORD lowerammo1; DWORD refillammo1; void __declspec(naked) UNLAMMO1() { __asm { jmp [toccunl1]//jmp naar codecave toccunl1://codecave 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 } } 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); }
The original code(that we'll modify) is:
Now we know this we can do alot with this code. We can stop the bullets from decreasing. We can even make the number bullets increase. These are very easy options. To stop the bullets from decreasing we only have to make it so 4A7A0B does nothing(nop 0x90). For increasing the amounts of bullets when we shoot we have to make it: .text:004A7A0B inc ecx. I dont know the bytes of these, look it up in cheat engines.Code://.text:004A7A09 mov ecx, eax // store the amount of bullets in ecx //.text:004A7A0B dec ecx // decrease the amount of bullets by 1 //.text:004A7A0C mov [edi], ecx // Set the new bullet value in edi
I'll explain how to make the bullets decreasing but refill to a certain number when it has reached a value. For example when your bullets has reached 1 then set your bullets to 30. Thats I'll explain now.
We need a codecave again to make the code because the new modified code doesnt fit in the original code.
This is how we want to modify the unl ammo 1 refill option.Code:DWORD Callbackunlammo1 = (ASM_UNLAMMO1+0x5); // We'll modify the mov ecx,eax and inc ecx and mov [edi],ecx. Those are 5 bytes long so we can jump back to inc dword ptr [esi]. DWORD lowerammo1; DWORD refillammo1; void __declspec(naked) UNLAMMO1() { __asm { jmp [toccunl1]//jmp to codecave toccunl1://codecave cmp eax, [lowerammo1] // compares eax to lowerammo1. In eax was the bulletvalue stored. je [toccunl1even] // jump if eax is equal to lowerammo1, then jump to toccunl1even. So when ur ammo value has reached the value when u want to refill ur ammo. mov ecx, eax // if the bullet value isn't equal to the value when u want to refill. Then decrease the bullets value dec ecx // decrease bullet mov [edi],ecx // set bullets in edi jmp [Callbackunlammo1] // jump back to original code toccunl1even: // when the bulletvalue is equal to the amount of bullets that you want to refill at then: mov ecx, [refillammo1] // put your bullet value that u want to refill to, in ecx. mov [edi], ecx // Put our new bullet value in edi. jmp [Callbackunlammo1]//jump back to oorspronkelijke code } }
Now we need to enable it in the hack:
I use my menu to change the value from item.unlammo1refill and item.unlammo1refillto. So users can change this value in the menu like this:Code:if(item.unlammo11==1) // when you turned on the hack { cdetour->DetourFunc((PBYTE)ASM_UNLAMMO1, (PBYTE)UNLAMMO1,5); // activate the codecave, the jmp to codecave is 5 bytes long. if(item.unlammo1refill>0) // when the refill value is 1 or greater so lowerammo1 cant be negative. { lowerammo1 = item.unlammo1refill-1;//put the value from item.unlammo1refill in lowerammo1. This is the ammo value when u want to refill it. } if(item.unlammo1refillto>0) // same as above { refillammo1 = item.unlammo1refillto-1; // put the value where u want to refill to in refillammo1 } }else { ctool->WriteAsm((PBYTE*)ASM_UNLAMMO1,(PBYTE)"\x8B\xC8\x49\x89\x0F",5);//off byte // mov ecx,eax = 0x8B 0xC8 // dec ecx = 0x49 // mov [edi],ecx = 0x89 0x0F }
EnjoyCode: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); }
jeivarmarr (02-15-2014),Jhem (02-22-2014)
i don't get it but your smart. thanks.
These things can all be done easialy with making a jump. But I want to be able to make some extra option for functions.
Quickdraw 1 (primary weapon)
Quick draw 1 (primary weapon) explained:Code:#define ASM_QUICKDRAW1 0x0053FB93 #define ASM_QUICKDRAW2 0x0053FE2B DWORD Callbackzoomin = (ASM_QUICKDRAW1-0x2); DWORD Inzoomtimer; void __declspec(naked) QUICKDRAW1() { __asm { mov eax, [Inzoomtimer] add esp, 10h jmp [Callbackzoomin]//jump terug naar oorspronkelijke code } } if(item.quickdraw1) { Inzoomtimer = 9-item.quickdraw1; cdetour->DetourFunc((PBYTE)ASM_QUICKDRAW1-0x7, (PBYTE)QUICKDRAW1,5); }else { ctool->WriteAsm((PBYTE*)QUICKDRAW1-0x7,(PBYTE)"\x8B\x02\x83\xC4\x10",5);//off byten 1regel }
The Original code is(this is a long time ago since i made this, so I hope I remember correctly):
The standard value of esi+2BC is 9 if im right. So when ebx is 10 (A), then it is completly zoomed in. We want that to happen faster or instantanious.Code:.text:00540176 mov edx, [esi+2BCh] // get the value of [esi+2BC] in edx (how many times it will take to zoom in) .text:0054017C mov eax, [edx] // get value of edx in eax .text:0054017E add esp, 10h // add 10 bytes to esp .text:00540181 cmp ebx, eax // compares ebx with eax (ebx is if I remember correctly the value of how many times it looped) .text:00540183 jle loc_54020D// jump if less or equal (jump if it's not completly zoomed in
So I'll make a function that can make the weapon zoom within a second, or a bit faster then normal.
Now we have to make this working:Code:DWORD Callbackzoomin = (ASM_QUICKDRAW1-0x2); DWORD Inzoomtimer; void __declspec(naked) QUICKDRAW1() { __asm { mov eax, [Inzoomtimer] // get our value in eax, so when for example Inzoomtimer is 5, so the weapon will be zoomed in after 5 loops instead of 9. add esp, 10h // not really important for us, but must be in it since the jump to this codecade is 5 bytes long. Longer then mov eax, [edx] jmp [Callbackzoomin]//jump back to Original code } }
In menu:Code:if(item.quickdraw1) { Inzoomtimer = 9-item.quickdraw1; // controlls in menu. When item.quickdraw is getting bigger. Then Inzoomtimer is getting closer to 0(faster) cdetour->DetourFunc((PBYTE)ASM_QUICKDRAW1-0x7, (PBYTE)QUICKDRAW1,5); // make codecave }else { ctool->WriteAsm((PBYTE*)QUICKDRAW1-0x7,(PBYTE)"\x8B\x02\x83\xC4\x10",5);//Off bytes }
Huib->AddItem(" Quickdraw1", quickdraw, &item.quickdraw1,10);
Quick draw 2(secondary)
For secundary its the same as quickdraw 1. Only some eax etc will change but the logica is the same. So i wont explain that but just give the code.
Also if you want it easier change:Code:DWORD Callbackzoomout = (ASM_QUICKDRAW2-0x2);//posx DWORD Outzoomtimer; void __declspec(naked) QUICKDRAW2() { __asm { jmp [tocczoomout]//jmp naar codecave tocczoomout://codecave mov ecx, [Outzoomtimer] add esp, 10h jmp [Callbackzoomout]//jump terug naar oorspronkelijke code } } if(item.quickdraw2) { Outzoomtimer = 9-item.quickdraw2; cdetour->DetourFunc((PBYTE)ASM_QUICKDRAW2-0x7, (PBYTE)QUICKDRAW2,5); }else { ctool->WriteAsm((PBYTE*)QUICKDRAW2-0x7,(PBYTE)"\x8B\x02\x83\xC4\x10",5);//off byten 1regel }
.text:00540183 jle loc_54020D
into:
.text:00540183 nop (6x) if im right. Then it will zoom in within a second
This can also be done easier, but I want to controll how fast it goes.Code:No weapon switch time
The first part is (ASM_NWST1):Code:#define ASM_NWST1 0x0053F7B3 #define ASM_NWST2 0x0053F836 DWORD Callbacknwst = (ASM_NWST2+0x8); DWORD nwsttimer; void __declspec(naked) NWST() { __asm { add eax, [nwsttimer] pop edi mov [esi+21Ch], eax jmp [Callbacknwst] } } 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); }
We can make it switch imidiatly by making 53FDA3 not jump. We'll do this by nopping it( 0x90 0x90)Code:.text:0053FDA0 cmp eax, [ecx] // compares eax with ecx .text:0053FDA2 push edi .text:0053FDA3 jle short loc_53FDE8 // jump if less or equal.
The second part is where we can controll how fast you're switching.
.text:0053FE26 inc eax
This is increasing eax by one untill it has reached the end of the weapon switching part. If we can make it so it will increase by 2 everytime it passes. Then switching a weapon will be twice as fast. We can do this by: add eax,2. Now it will be twice as fast. The problem is that inc eax is only one byte and add eax,2 is 3. So it doesnt fit. We need to make a codecave
thats how nwst works. I dont feel like explaining it futher since my hand hurts because of this post ^^Code:DWORD Callbacknwst = (ASM_NWST2+0x8);//nwst DWORD nwsttimer; void __declspec(naked) NWST() { __asm { add eax, [nwsttimer] // add how many times faster u want to go in eax pop edi mov [esi+21Ch], eax jmp [Callbacknwst]//jump terug naar oorspronkelijke code } }
Btw Thanks all