{ // '{' opens a block of comments =========================================== Game Title : The Haunted - Hells Reach (64 bits, DX9) Game Version : 1.0.8788.0 Process Name : HauntedGame.exe Script Version: 1.0 CE Version : 6.1 Release date : 13-Dec-2011 Author : Recifense Features: - God Mode - Unlimited Ammo =========================================== } // '}' closes a block of comments [ENABLE] //========================================= // Check if script is compatible to this game version // If false the script will not be loaded assert(HauntedGame.exe+085069,48 8b 54 24 70 48 89 46 10 48 8b 44 24 78 45 33 c0) // The script is only loaded if assert returns TRUE assert(HauntedGame.exe+061897,8b 44 24 50 29 03 8b 03 48 8b 5c 24 40 89 06 48 83 c4 20)// The script is only loaded if assert returns TRUE //========================================= alloc(MyCode,1024) // Allocating memory. 1024 (1Kb) is enough. //========================================= // Declaration section label(_MonAmmo) // Declaring a label label(_BackMA) // Declaring a label label(_ExitMA) // Declaring a label label(_GodMode) // Declaring a label label(_GodM0) // Declaring a label label(_GodM1) // Declaring a label label(_BackGM) // Declaring a label label(_ExitGM) // Declaring a label label(pPlayer) // Declaring a label label(pHP) // Declaring a label label(pAmmo) // Declaring a label label(pWeapon) // Declaring a label label(iEnableGM) // Declaring a label label(iEnableMA) // Declaring a label //========================================= // Registering Symbols registersymbol(MyCode) // Registering "MyCode", so it can be easily find it in the memory viewer. registersymbol(pPlayer) // Registering "pPlayer", so it can be easily used in a table or structure. registersymbol(pHP) // Registering "pHP", so it can be easily used in a table or structure. registersymbol(pAmmo) // Registering "pAmmo", so it can be easily used in a table or structure. registersymbol(pWeapon) // Registering "pWeapon", so it can be easily used in a table or structure. registersymbol(iEnableGM) // Registering "iEnableGM", so it can be easily used in a table or structure. registersymbol(iEnableMA) // Registering "iEnableMA", so it can be easily used in a table or structure. //========================================= MyCode: //========================================= // This script will: // 1) Check if the information is valid -> the content of offsets 00c8 and 010c are equal and not NULL (0) // 2) Identify the addresses of Hero's HP and Ammo // 3) If Unlimited Ammo is enabled (iEnableMA <> 0), current ammo = maximum ammo and current reserve = maximum // RSI = Base of Weapon structure (Don't confuse Base with Bottom. Base here is the first address of a structure) // RDX is free for use since it is modified by the original code // RCX is free for use since it is modified right after the original code (see main code) _MonAmmo: mov rdx,[rsi+000000c8] // Load register RDX with the content of offset 00c8 test rdx,rdx // Test it jz _ExitMA // jcc is a conditional jump. The condition here is Z (if zero). cmp rdx,[rsi+0000010c] // Verify if the content of offset 010c is equal to that of offset 00c8. jne _ExitMA // jcc is a conditional jump. The condition here is NE (not equal to). mov [pPlayer],rdx // RDX is the base of the HP structure. Save it for debugging; mov [pWeapon],rsi // RSI is the base of the Ammo structure. Save it for debugging; lea rdx,[rdx+00000374] // Make RDX = RDX + Offset of current HP; mov [pHP],rdx // RDX points to the exact address of current HP. Save it for further use. lea rdx,[rsi+000003c0] // Make RDX = RSI + Offset of current Ammo; mov [pAmmo],rdx // RDX points to the exact address of current Ammo. Save it for further use. cmp dword ptr [iEnableMA],0 // If the content of the memory address pointed by label iEnableMA is 0... je _ExitMA // ... the script will continue at the label _ExitMA (jcc -> E = equal to) mov edx,[rsi+000003bc] // Load EDX with the content of offset 03bc (Maximum Ammo) mov [rsi+000003c0],edx // and copy it to the offset 03c0 (Current Ammo) mov edx,[rsi+000003a0] // Load EDX with the content of offset 03a0 (Maximum Reserve Ammo) mov [rsi+0000039c],edx // and copy it to the offset 039c (Current Reserve Ammo) _ExitMA: pop rcx // Adjust to the original RSP (by popping the returning address) mov rdx,[rsp+70] // Original code mov [rsi+10],rax // Original code mov rax,[rsp+78] // Original code xor r8d,r8d // Original code jmp rcx // Back to main code //========================================= // This script will (if enabled: iEnableMA <> 0 and/or iEnableGM <> 0): // 1) Not let the value to be decreased, if it is at Hero's HP address or at the Hero's Ammo address. // 2) Make the current value equal to maximum // RBX points to the address of the value to be decreased // RAX is free for use since it is modified by the original code // RDI is free for use since it is modified right after the original code (see main code) _GodMode: pop rdi // Adjust to the original RSP (by popping the returning address) cmp rbx,[pAmmo] // Is it the hero's ammo. je _GodM0 // jcc is a conditional jump. The condition here is E (equal to). cmp rbx,[pHP] // Is it the hero's HP. jne _ExitGM // jcc is a conditional jump. The condition here is NE (NOT equal to). cmp dword ptr [iEnableGM],0 // If the content of the memory address pointed by label iEnableGM is 0... je _GodM0 // ... the script will continue at the label _GodM0 (jcc -> E = equal to) mov eax,[rbx+04] // Load EAX with Maximum HP mov [rbx],eax // and copy it to Current HP address jmp _GodM1 // Continue at the label _GodM2 _GodM0: cmp dword ptr [iEnableMA],0 // If the content of the memory address pointed by label iEnableMA is 0... je _ExitGM // ... the script will continue at the label _ExitGM (jcc -> E = equal to) mov eax,[rbx-04] // Load EAX with Maximum Ammo mov [rbx],eax // and copy it to Current Ammo address _GodM1: xor eax,eax // Make EAX = 0 (A xor A = 0) mov [rsp+50],eax // Make value to be decreased at the stack offset 10 = 0 _ExitGM: mov eax,[rsp+50] // Original code (EAX = value to be decreased) sub [rbx],eax // Original code mov eax,[rbx] // Original code mov rbx,[rsp+40] // Original code mov [rsi],eax // Original code add rsp,20 // Original code jmp rdi // Back to main code //========================================= db '=======================>' // The memory at this location is filled with this string db 'CE6.1 Script by Recifense 121311' // The memory at this location is filled with this string //========================================= // Variables // We can put the variables here, right after the last script. iEnableGM: // The variable name followed by : (in fact, it is a lable) dd 1 // Reserving 4 bytes and initializing its value with 1 iEnableMA: // The variable name followed by : (in fact, it is a lable) dd 1 // Reserving 4 bytes and initializing its value with 1 pPlayer: // The variable name followed by : (in fact, it is a lable) dq MyCode // Reserving 8 bytes and initializing its value with MyCode address value pHP: // The variable name followed by : (in fact, it is a lable) dq MyCode // Reserving 8 bytes and initializing its value with MyCode address value pAmmo: // The variable name followed by : (in fact, it is a lable) dq MyCode // Reserving 8 bytes and initializing its value with MyCode address value pWeapon: // The variable name followed by : (in fact, it is a lable) dq MyCode // Reserving 8 bytes and initializing its value with MyCode address value //========================================= // Hacking Points // It can also be placed before the scripts. But let's put it after them, just to remind us // that the script was created and loaded into the computer memory and now can be accessed. HauntedGame.exe+085069: // The address to be intercepted call _MonAmmo // (*) Calling to the script (this instruction is 16 bytes long in a 64 bits system) nop // Adding a NOP (90h) instruction to complete 17 bytes (remember this!) _BackMA: // This label is the address to go back. It is HauntedGame.exe+065121 plus 17 bytes. HauntedGame.exe+061897: // The address to be intercepted call _GodMode // (*) Calling to the script (this instruction is 16 bytes long in a 32 bits system) db 90,90,90 // Adding 3 NOPs (90h) instruction to complete 19 bytes (remember this!) _BackGM: // This label is the address to go back. It is HauntedGame.exe+04810d plus 6 bytes. //(*) Why not JMP? Because AA has a bug and you cannot jump back. The labels are 4 bytes long and ... // ... inside the script a MOV RXX,gamexxx.exe+0YYYYYY is truncated to 32 bits. [DISABLE] //========================================= // This part is performed when we disable the script by unchecking its active box. // Here we should: // - Restore the original codes // - Unregister the symbols // - Deallocate (free) the memory HauntedGame.exe+085069: // The address to restore the code // mov rdx,[rsp+70] // The code to be restored (this instruction is 5 bytes long) // mov [rsi+10],rax // The code to be restored (this instruction is 4 bytes long) // mov rax,[rsp+78] // The code to be restored (this instruction is 5 bytes long) // xor r8d,r8d // The code to be restored (this instruction is 3 bytes long) db 48 8b 54 24 70 48 89 46 // The instruction in byte sequence representation... db 10 48 8b 44 24 78 45 33 c0 // ...The instruction in byte sequence representation HauntedGame.exe+061897: // The address to restore the code // mov eax,[rsp+50] // The code to be restored (this instruction is 4 bytes long) // sub [rbx],eax // The code to be restored (this instruction is 2 bytes long) // mov eax,[rbx] // The code to be restored (this instruction is 2 bytes long) // mov rbx,[rsp+40] // The code to be restored (this instruction is 5 bytes long) // mov [rsi],eax // The code to be restored (this instruction is 2 bytes long) // add rsp,20 // The code to be restored (this instruction is 4 bytes long) db 8b 44 24 50 29 03 8b 03 48 // The instruction in byte sequence representation... db 8b 5c 24 40 89 06 48 83 c4 20 // ...The instruction in byte sequence representation //========================================= // Unregistering Symbols unregistersymbol(MyCode) // UNregistering "MyCode", so it cannot be accessed anymore. unregistersymbol(iEnableGM) // UNregistering "iEnableGM", so it cannot be accessed anymore. unregistersymbol(iEnableMA) // UNregistering "iEnableMA", so it cannot be accessed anymore. unregistersymbol(pPlayer) // UNregistering "pPlayer", so it cannot be accessed anymore. unregistersymbol(pHP) // UNregistering "pHP", so it cannot be accessed anymore. unregistersymbol(pAmmo) // UNregistering "pAmmo", so it cannot be accessed anymore. unregistersymbol(pWeapon) // UNregistering "pWeapon", so it cannot be accessed anymore. //========================================= dealloc(MyCode) // DE-allocating memory so the system can use it for other purposes. //============= Scripts End =============== // **************************************** // NOTES // **************************************** { struct WEAPON: 00c8 = pHero 010c = pHero 039c = current_Reserved_Ammo 03a0 = maximum_Reserved_Ammo 03bc = maximum_Ammo_onCLIP 03c0 = current_Ammo_onCLIP struct HERO: 010c = pSelf 0374 = current_HP 0378 = maximum_HP 0494 = pWeapon }