So I was watching the youtube video about automatic health recovery, then read the cheat engine forums about all this, then read a bit of manuals and tutorials. And came up with this:
whole code
The dedicated thread for health recovery:
Fetching health value from game:
Code: Select all
[ENABLE]
alloc(regen,2048)
registersymbol(regen)
label(enabled)
registersymbol(enabled)
label(compare)
label(heal)
alloc(lostHP,20)
registersymbol(lostHP)
label(refresh)
alloc(refreshrate,20)
registersymbol(refreshrate)
createthread(regen)
regen:
// call heal or sleep
compare:
// check if [health] defined/accessable
push 4
lea eax,[[health]]
push eax
call IsBadReadPtr // return nonzero if no access
// should I add to esp after each function call???
mov [lostHP],eax // can't compare eax to 0 itself? // lostHP is not used as it should - just a placeholder for eax value
xor eax,eax
cmp dword ptr[lostHP],0
jne refresh
// continue if [health] accessable
fld [[health]+4] // max HP: st(1)
fld [[health]] // current HP: st(0)
fsubp // st1-st; store in st1; pop st; st1->st
fstp [lostHP] // pop st; store result
nop // test
fld [lostHP] // st1
fldz // st0
fcomip st,st(1) // cmp st0&st1; pop st; st1->st
//above sets: ZF on st===st(1), CF on st<st(1)
fstp st(0) // clear stack
nop // test
jb heal // if lostHP > zero
jmp refresh // wait to be hurt
// heal hero for [st1] HP in [refreshrate]
heal:
fld1 // st1
fld [[health]] // st0
faddp // pop st0; result in st1; st1->st0
fstp [[health]] // pop st into [health]
jmp refresh
refresh:
push dword ptr[refreshrate]
call Sleep // sleep thread for [refreshrate]ms
nop // test
cmp byte ptr[enabled],#%1
je compare
//freemem:
//settings args for virtualfree
push 8000 // dwFreeType MEM_RELEASE
push 0 // dwSize on MEM_RELEASE always 0
push regen // lpAddress (VirtualAlloc)
// can't make it work :(
jmp VirtualFree
// default values:
refreshrate:
dd (int)1000
lostHP:
dd (float)0.0
enabled:
db 1
[DISABLE]
enabled:
db 0
unregistersymbol(lostHP)
unregistersymbol(refreshrate)
unregistersymbol(enabled)
unregistersymbol(regen)
Code: Select all
[ENABLE]
aobscanmodule(findhealth,FOBS_A_ver1.19.exe,D9 04 81 8B 8C 24 00 02 00 00)
alloc(newmem,$1000)
label(compare)
label(herocode)
label(originalcode)
label(return)
alloc(health,4)
registersymbol(health)
health:
dd 0
newmem:
compare:
pushf
cmp esi,3
je herocode
jmp originalcode
herocode:
// asign health
push edx
lea edx,[ecx+eax*4]
mov [health],edx
pop edx
jmp originalcode
originalcode:
popf
fld dword ptr [ecx+eax*4]
mov ecx,[esp+00000200]
jmp return
findhealth:
jmp newmem
nop
nop
nop
nop
nop
return:
registersymbol(findhealth)
[DISABLE]
findhealth:
db D9 04 81 8B 8C 24 00 02 00 00
unregistersymbol(findhealth)
dealloc(newmem)
unregistersymbol(health)
dealloc(health)
{
"FOBS_A_ver1.19.exe"+1A0AD: C3 - ret
"FOBS_A_ver1.19.exe"+1A0AE: 8B 0D 9C F8 43 00 - mov ecx,[FOBS_A_ver1.19.exe+3F89C]
// ---------- INJECTING HERE ----------
"FOBS_A_ver1.19.exe"+1A0B4: D9 04 81 - fld dword ptr [ecx+eax*4]
"FOBS_A_ver1.19.exe"+1A0B7: 8B 8C 24 00 02 00 00 - mov ecx,[esp+00000200]
// ---------- DONE INJECTING ----------
"FOBS_A_ver1.19.exe"+1A0BE: 33 CC - xor ecx,esp
"FOBS_A_ver1.19.exe"+1A0C0: E8 3B 52 00 00 - call FOBS_A_ver1.19.exe+1F300
"FOBS_A_ver1.19.exe"+1A0C5: 81 C4 04 02 00 00 - add esp,00000204
}
Code: Select all
//settings args for virtualfree (first->last)
push 8000 // dwFreeType MEM_RELEASE
push 0 // dwSize on MEM_RELEASE always 0
push regen // lpAddress (VirtualAlloc)
// can't make it work :(
jmp VirtualFree
Edit:
fixed that thing. now no crashes and frees memory as it should:
Code: Select all
push 0 // Exit code for RtlExitUserThread
push 8000 // MEM_RELEASE
push 0
push regen // lpAddress / region to be freed
push ntdll.RtlExitUserThread
jmp VirtualFree