Which is better, and why?

Anything Cheat Engine related, bugs, suggestions, helping others, etc..
Post Reply
Sigan
Expert Cheater
Expert Cheater
Posts: 267
Joined: Fri May 26, 2017 1:23 am
Reputation: 124

Which is better, and why?

Post by Sigan »

If I have multiple options for where to inject, and two of them are:

Code: Select all

fstp dword ptr [eax+50]

Code: Select all

fld dword ptr [ebx+50]
In general, which would you choose to inject before? The goal is to zero out [e_x+50], so the final code will look something like this:

Code: Select all

push edx
mov edx,[zer0]
mov [eax+50]         //for example
fstp dword ptr [eax+50]
pop edx
Would it be better to inject in front of one rather than the other? I don't understand the code revolving around floats very well, and I just want some opinions on what I should prioritize, and how is most efficient. If there's any kind of error checking I'm supposed to incorporate, I wouldn't know.

Thank you for your opinion, in advance.

GreenHouse
Expert Cheater
Expert Cheater
Posts: 857
Joined: Fri Oct 12, 2018 10:25 pm
Reputation: 889

Re: Which is better, and why?

Post by GreenHouse »

If it's a literal float, the better way is to just do a mov, not use fstp/fld.

Code: Select all

mov [eax+50],(float)0

Sigan
Expert Cheater
Expert Cheater
Posts: 267
Joined: Fri May 26, 2017 1:23 am
Reputation: 124

Re: Which is better, and why?

Post by Sigan »

Oh, so I can just replace that line with a mov? And I can do that with either one?

Do you see anything wrong with this code? Is "mov [eax+50],edi" the same as "ftsp dword ptr [eax+50]?"

Code: Select all

alloc(newmem,$1000)
globalalloc(_softDisposition,4)
label(dispositionVar)
label(code)
label(return)

newmem:
  mov [_softDisposition],eax
  push edi
  mov edi,[dispositionVar]
  mov [eax+50],edi
  pop edi
code:
  fstp dword ptr [eax+50]
  wait
  fld tword ptr [Exanima.exe+16BE3C]
  jmp return

dispositionVar:
  dd (float)0

INJECT:
  jmp newmem
  nop 5
return:
registersymbol(INJECT)
registersymbol(dispositionVar)
[DISABLE]

INJECT:
  db D9 58 50 9B DB 2D 3C BE 56 00

unregistersymbol(INJECT)
unregistersymbol(dispositionVar)
dealloc(newmem)

GreenHouse
Expert Cheater
Expert Cheater
Posts: 857
Joined: Fri Oct 12, 2018 10:25 pm
Reputation: 889

Re: Which is better, and why?

Post by GreenHouse »

Still why do mov edi,[dispositionVar] to set a specific value that won't change?
When you can do what I said: mov edi,(float)0 or just mov edi,0.

Also, you need to remove the fstp, as that will change the value back.
FLD = Load value into the stack.
FSTP = Set the value from the stack into what you want and pop it(Remove it from the stack).

Code: Select all

alloc(newmem,$1000)
globalalloc(_softDisposition,4)
label(code)
label(return)

newmem:
  mov [_softDisposition],eax
  mov [eax+50],(float)0
  
code:
  fld tword ptr [Exanima.exe+16BE3C]
  jmp return
 
INJECT:
  jmp newmem
  nop 5
return:
registersymbol(INJECT)
registersymbol(dispositionVar)
[DISABLE]

INJECT:
  db D9 58 50 9B DB 2D 3C BE 56 00

unregistersymbol(INJECT)
unregistersymbol(dispositionVar)
dealloc(newmem)

aSwedishMagyar
Table Makers
Table Makers
Posts: 670
Joined: Mon Jul 06, 2020 3:19 am
Reputation: 1190

Re: Which is better, and why?

Post by aSwedishMagyar »

Sigan wrote:
Wed Jul 14, 2021 7:38 am
Oh, so I can just replace that line with a mov? And I can do that with either one?

Do you see anything wrong with this code? Is "mov [eax+50],edi" the same as "ftsp dword ptr [eax+50]?"
...
Be mindful when modifying FPU instructions. If the game is using fstp to write to that address then you need to ensure the FPU is in the correct state after your injection and pop a value off of it. The fstp instruction pops the value in st(0) and writes it to whatever address you give it as an argument. So if you just wanted to zero the value out you could use something like:

Code: Select all

fstp st(0)
mov [eax+50],0
fstp st(0) will simply discard the value in the top of the FPU stack, without needing to write it to anything. Then you just do as Greenhouse said and use a mov to zero out the value.

Sigan
Expert Cheater
Expert Cheater
Posts: 267
Joined: Fri May 26, 2017 1:23 am
Reputation: 124

Re: Which is better, and why?

Post by Sigan »

That's really helpful! Thank you both!

Sigan
Expert Cheater
Expert Cheater
Posts: 267
Joined: Fri May 26, 2017 1:23 am
Reputation: 124

Re: Which is better, and why?

Post by Sigan »

Another question on a completely different subject that I'd like to ask, but don't know if creating a new topic is worth it is:

If there is something in the game that you would like to find, but it's something that will only happen once, ever, in a playthrough, what is your recommendation for finding that value?

For instance, say you wanted to find a way to never consume an item that isn't stackable, when used. When these items are used up, they are either a different item, or they're empty of their charge (a range, maybe, or a 1/0). Searching out something like that seems impossible to find.

Any good recommendations?

User avatar
EpicBirdi
Fearless Donors
Fearless Donors
Posts: 64
Joined: Sat Jul 21, 2018 2:22 pm
Reputation: 58

Re: Which is better, and why?

Post by EpicBirdi »

I would say try seeing if you can trace a function that is run when any item is consumed, rather than any specific item. I'm no real expert but that'd be my first attempt, anyway. If you don't have any stackable items to try finding such a function with, see what the item modifies and work backwards from there:
> If it restored health, work backwards from what updated your health > How much it was restored by > What set this value > If it was an item, see if this upper function runs on any item usage.. etc.

User avatar
SunBeam
Administration
Administration
Posts: 4704
Joined: Sun Feb 04, 2018 7:16 pm
Reputation: 4287

Re: Which is better, and why?

Post by SunBeam »

The FPU instruction set is so x86. The only reason you use it is cuz it's simpler and you don't have to remember much. fld and fstp and that's that. However, x64 engines have evolved since and use the SSE instructions. You will rarely see Microsoft Visual Studio compile FPU instructions in the games of today.

So.. I would advise using movss instruction to both read and write:

movss xmm0-15,[r64+offset]
movss [r64+offset],xmm0-xmm15

You can do a shit lot of operations with SSE/2, such as reading/writing 4 floats at the same time etc.

Your call :)

P.S.: The instructions are x86 compatible as well.

Sigan
Expert Cheater
Expert Cheater
Posts: 267
Joined: Fri May 26, 2017 1:23 am
Reputation: 124

Re: Which is better, and why?

Post by Sigan »

I'm wondering if there's a tutorial, on our forums, somewhere about this.

The xmm registers aren't being used around this code. I usually use those when I can find them showing up somewhere, but nothing I've found uses them. Granted, I don't know a LOT about what I'm doing, so it could have to do with my methodology for finding injection locations. If I better understood break and trace, or how to understand the tool for dissecting a structure, I think I also might be able to find what I'm looking for, quicker, and a better location for things. As it stands, I'm reaching the limits of my current knowledge on the game I've been focusing on recently.

All that said, SunBeam, I understand what you advise, and what you mean by read and write. The rest of everything you wrote there is speaking above my head. I want to understand, though... so, if you have the time to ELI5, I'll just listen.

Post Reply

Who is online

Users browsing this forum: No registered users