[SOLVED] Deallocating thread memory without killing game

Anything Cheat Engine related, bugs, suggestions, helping others, etc..
Post Reply
HK51
What is cheating?
What is cheating?
Posts: 1
Joined: Thu Jul 25, 2019 5:00 pm
Reputation: 0

[SOLVED] Deallocating thread memory without killing game

Post by HK51 »

Hello, guys, I am new to assembly and cheat engine in general and kinda stack while trying to call VirtualFree because the game crashes. I tried to google but it seems I am doing the correct thing but still incorrectly?
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:

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)
Fetching health value from game:

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
}
But above is not that important as the problem is in VirtualFree? I call it as next (I am on x86/IA32):

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
on condition if the code is disabled. But when I deactivate script in CE it is still running, when I reactivate it there appears the next instance of it in game, and finally when I deactivate it the second time the game tells me to back off just crashes. I've seen on forums that I should add the fourth parameter to VirtualFree (as seen [Link]) but I don't understand what that fourth parameter represents? Return address? Why the fourth parameter if VirtualFree accepts only three arguments? Or maybe the problem is not in VirtualFree and maybe I ruined something else? Thanks in advance.


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
Looked up the solution and correction to it there. I presume the linking there is forbidden and auto-corrected by system, sorry.

Post Reply

Who is online

Users browsing this forum: darksage140