Page 1 of 1

Which is better, and why?

Posted: Wed Jul 14, 2021 5:41 am
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.

Re: Which is better, and why?

Posted: Wed Jul 14, 2021 6:22 am
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

Re: Which is better, and why?

Posted: Wed Jul 14, 2021 7:38 am
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)

Re: Which is better, and why?

Posted: Wed Jul 14, 2021 8:12 am
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)

Re: Which is better, and why?

Posted: Wed Jul 14, 2021 8:24 am
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.

Re: Which is better, and why?

Posted: Thu Jul 15, 2021 6:12 am
by Sigan
That's really helpful! Thank you both!

Re: Which is better, and why?

Posted: Thu Jul 15, 2021 6:50 am
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?

Re: Which is better, and why?

Posted: Thu Jul 15, 2021 7:41 am
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.

Re: Which is better, and why?

Posted: Thu Jul 15, 2021 4:28 pm
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.

Re: Which is better, and why?

Posted: Fri Jul 16, 2021 4:24 am
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.