Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


Help with trying to compare xmm0

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General Gamehacking
View previous topic :: View next topic  
Author Message
Classicus
Advanced Cheater
Reputation: 0

Joined: 22 Dec 2011
Posts: 51

PostPosted: Thu Oct 01, 2015 6:08 pm    Post subject: Help with trying to compare xmm0 Reply with quote

I tried searching for something related but couldn't necessarily find the info I'm looking for. I'm trying to compare xmm0 to a float value of 1.1, but I'm still inexperienced with float values and how to write assembly for them. Any help is appreciated!

Here is the original code:

Code:
originalcode:
movss [r14+rax],xmm0


I want to compare xmm0 to (float) 1.1, and if xmm0 is greater than (float) 1.1, then jump to a new code which will move (float) 1.1 into xmm0 then jump to code. Assuming cmp works with xmm0 [which it does not], here is what I'm trying to achieve:

Code:
newmem:
cmp xmm0,(float)1.1
jg newcode
jmp originalcode

newcode:
movss xmm0,(float)1.1

originalcode:
movss [r14+rax],xmm0
jmp return
Back to top
View user's profile Send private message
panraven
Grandmaster Cheater
Reputation: 55

Joined: 01 Oct 2008
Posts: 941

PostPosted: Thu Oct 01, 2015 8:54 pm    Post subject: Reply with quote

xmm register seems only work with xmm register or a memory address,
(float)1.1 is an immediate value, will not work as well as integer register.

May try ucomiss/comiss http://x86.renejeschke.de/html/file_module_x86_id_44.html

It seems jle or jge will always fail after these 2 command, should only use jl or jg. To simulate jle or jge combine with the corresponding test jmp individually, eg

Code:

globalalloc(__,$4000)

__+10:
dd (float)1.1,(float)1.0

__+80:
push rax

movss    xmm0,[__+10]
ucomiss  xmm0,[__+14]
jl       @f
je      @f
inc      dword ptr [__+18]
@@:
inc      dword ptr [__+18]
pop  rax
ret


createThread(__+80)


_________________
- Retarded.
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 138

Joined: 06 Jul 2014
Posts: 4275

PostPosted: Thu Oct 01, 2015 8:58 pm    Post subject: This post has 1 review(s) Reply with quote

OP:
You can use cmpss to do this, but there's a bit more to this instruction than the simpler instruction cmp.

cmpss needs a destination XMM, a source XMM/m32, and an imm8 that tells it what type of comparison to perform. It stores the result (True = 0xFFFFFFFF, False = 0x00000000) into the lowest dword of the destination operand.
More info on CMPSS
Code:
alloc(newmem,500)
alloc(number,4)
label(newcode)
label(originalcode)

number:
 dd (float)1.1

newmem:
  push eax
  movss xmm1,[number]
  cmpss xmm1,xmm0,2
  movd eax,xmm1
  test eax,eax
  je originalcode
newcode:
  movss xmm0,[number]
originalcode:
  pop eax
  movss [r14+rax],xmm0
  jmp return

movss completely wipes an xmm destination register if the source is a m32, so if the program was using xmm1, find a different register that it's not using. If you can't and need help backing up xmm1, let me know.

Edit: oh yeah, forgot about comiss. Use that; it's easier to understand than my previous code:
Code:
alloc(newmem,500)
alloc(number,4)
label(newcode)
label(originalcode)

number:
 dd (float)1.1

newmem:
  comiss xmm0,[number]
  jl originalcode
newcode:
  movss xmm0,[number]
originalcode:
  movss [r14+rax],xmm0
  jmp return

Also, comiss sets the OF, SF, and AF flags to 0, so jge and jle won't work properly. If you really don't want "newcode" to be run when xmm0 == 1.1, you can add je originalcode right after jl originalcode (that's fine since jcc instructions don't modify any flags).

_________________
I don't know where I'm going, but I'll figure it out when I get there.
Back to top
View user's profile Send private message
Classicus
Advanced Cheater
Reputation: 0

Joined: 22 Dec 2011
Posts: 51

PostPosted: Fri Oct 02, 2015 3:56 am    Post subject: Reply with quote

Thanks for the links, good to read!

panraven:
Thanks for the info. I tried this code but it froze the game.

ParkourPenguin:
In this case, I do not want to use the newcode if xmm0 equals (float)1.1, so using jl is what I'd need. I tried both codes you posted. The first one crashed the game, I think because xmm1 is being used above the code. The second script didn't work. Maybe this is because of the surrounding code? Pasted surrounding code below:

Code:
"mgsvtpp.exe"+3930ADF: F3 44 0F 10 43 38           -  movss xmm8,[rbx+38]
"mgsvtpp.exe"+3930AE5: F3 41 0F 10 0C 06           -  movss xmm1,[r14+rax]
"mgsvtpp.exe"+3930AEB: 0F 2F CE                    -  comiss xmm1,xmm6
"mgsvtpp.exe"+3930AEE: 0F 86 0D 01 00 00           -  jbe mgsvtpp.exe+3930C01
"mgsvtpp.exe"+3930AF4: 0F 28 C1                    -  movaps xmm0,xmm1
"mgsvtpp.exe"+3930AF7: F3 41 0F 5C C0              -  subss xmm0,xmm8
"mgsvtpp.exe"+3930AFC: 0F 2F C6                    -  comiss xmm0,xmm6
"mgsvtpp.exe"+3930AFF: 73 03                       -  jae mgsvtpp.exe+3930B04
"mgsvtpp.exe"+3930B01: 0F 28 C6                    -  movaps xmm0,xmm6
"mgsvtpp.exe"+3930B04: 0F 2F CF                    -  comiss xmm1,xmm7
// ---------- INJECTING HERE ----------
"mgsvtpp.exe"+3930B07: F3 41 0F 11 04 06           -  movss [r14+rax],xmm0
// ---------- DONE INJECTING  ----------
"mgsvtpp.exe"+3930B0D: 0F 86 EE 00 00 00           -  jbe mgsvtpp.exe+3930C01
"mgsvtpp.exe"+3930B13: 48 8B 86 A0 01 00 00        -  mov rax,[rsi+000001A0]
"mgsvtpp.exe"+3930B1A: 41 0F 2F 3C 06              -  comiss xmm7,[r14+rax]
"mgsvtpp.exe"+3930B1F: 0F 82 DC 00 00 00           -  jb mgsvtpp.exe+3930C01
"mgsvtpp.exe"+3930B25: 41 0F B7 C3                 -  movzx eax,r11w
"mgsvtpp.exe"+3930B29: 41 BD 06 00 00 00           -  mov r13d,00000006
"mgsvtpp.exe"+3930B2F: 41 BC 0C 00 00 00           -  mov r12d,0000000C
"mgsvtpp.exe"+3930B35: 8D 0C 40                    -  lea ecx,[rax+rax*2]
"mgsvtpp.exe"+3930B38: 48 8B 86 78 01 00 00        -  mov rax,[rsi+00000178]
"mgsvtpp.exe"+3930B3F: C1 E1 02                    -  shl ecx,02


Also, here is the full script I'm working with. I tried adding the comiss xmm1,xmm7 at the end to restore that compare since we were using a compare, although not sure if this is correct and it made no difference anyway.

Code:
[ENABLE]

aobscanmodule(Zhukrockets_cooldown,mgsvtpp.exe,F3 41 0F 11 04 06 0F)
alloc(newmem,$1000,"mgsvtpp.exe"+3930B07)
alloc(number,4)
registersymbol(Zhukrockets_cooldown)
label(code)
label(return)

number:
dd (float)1.1

newmem:
comiss xmm0,[number]
jl code
movss xmm0,[number]

code:
  movss [r14+rax],xmm0
  comiss xmm1,xmm7 //restoring a compare
  jmp return

Zhukrockets_cooldown:
  jmp code
  nop
return:

[DISABLE]

Zhukrockets_cooldown:
  db F3 41 0F 11 04 06

unregistersymbol(Zhukrockets_cooldown)
dealloc(number)

dealloc(newmem)
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 138

Joined: 06 Jul 2014
Posts: 4275

PostPosted: Fri Oct 02, 2015 8:47 am    Post subject: Reply with quote

My bad. You're suppose to use (edit)JB/JBE/JA/JAE for comparing values using comiss. See the Jcc reference for more info on what flags all the conditional jumps check.

I'd recommend replacing the jl code with jbe code since it avoids a useless move (if xmm0 == [number], moving [number] into xmm0 is useless).

But yes, you should save the flags and restore them later. Generally, it would be better to use PUSHFQ / POPFQ (edit: pushf/pushfd/pushfq are the same bytecode, just different mnemonics for different bit modes); however, in this case, it's perfectly fine to do the comparison again since you don't modify any flags it doesn't modify.

_________________
I don't know where I'm going, but I'll figure it out when I get there.


Last edited by ParkourPenguin on Sun Oct 11, 2015 8:57 am; edited 1 time in total
Back to top
View user's profile Send private message
Zanzer
I post too much
Reputation: 126

Joined: 09 Jun 2013
Posts: 3278

PostPosted: Fri Oct 02, 2015 3:53 pm    Post subject: Reply with quote

Your injection is jumping to "code" instead of "newmem" like you want. Smile
Back to top
View user's profile Send private message
Classicus
Advanced Cheater
Reputation: 0

Joined: 22 Dec 2011
Posts: 51

PostPosted: Fri Oct 02, 2015 5:10 pm    Post subject: Reply with quote

Wow, thanks Zanzer! What an oversight on my part, lol.

Combined that with using jb and it's working now. Awesome, thanks for your help everyone! And thanks for the info too.

I know about pushad/popad when dealing with other instructions. Is pushfq/popfq for dealing with floats like xmm0 or fstp dword ptr?

Also, for pushad/popad, I know when dealing with x64 applications, those don't work and you have to push/pop everything individually to achieve the same result. Might this also be the case with pushfq/popfq?
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 138

Joined: 06 Jul 2014
Posts: 4275

PostPosted: Fri Oct 02, 2015 5:56 pm    Post subject: Reply with quote

Zanzer - derp. Can't believe I missed that Embarassed

Classicus - pushfq/popfq are for pushing and popping the eflags register- it's the thing that controls what the jumps do (e.g. je checks the zero flag, jb checks the carry flag).

_________________
I don't know where I'm going, but I'll figure it out when I get there.
Back to top
View user's profile Send private message
Classicus
Advanced Cheater
Reputation: 0

Joined: 22 Dec 2011
Posts: 51

PostPosted: Fri Oct 02, 2015 7:27 pm    Post subject: Reply with quote

ParkourPenguin - Ok I think I understand. So pushfq/popfq would be especially useful in situations like my script here if I didn't add comiss xmm1,xmm7 at the end? I always wondered if there was a better way to deal with a code I want to modify when it's between a compare and a jump (and I'm adding a new compare).
Back to top
View user's profile Send private message
mgr.inz.Player
I post too much
Reputation: 218

Joined: 07 Nov 2008
Posts: 4438
Location: W kraju nad Wisla. UTC+01:00

PostPosted: Sun Oct 11, 2015 7:14 am    Post subject: This post has 1 review(s) Reply with quote

Quote:
JB/JBE/JG/JGE for comparing values using comiss

Wrong. Do not use JG or JL after using COMISS.



comiss sets those flags: ZF,PF,CF

So, you have to use JCC instructions which check ONLY those.
So, JA, JAE, JB, JBE, JE, JNA, JNB, (check the rest in manual)


COMISS (intel manual)
http://www.jaist.ac.jp/iscenter-new/mpc/altix/altixdata/opt/intel/vtune/doc/users_guide/mergedProjects/analyzer_ec/mergedProjects/reference_olh/mergedProjects/instructions/instruct32_hh/vc45.htm


JCC (intel manual)
http://www.jaist.ac.jp/iscenter-new/mpc/altix/altixdata/opt/intel/vtune/doc/users_guide/mergedProjects/analyzer_ec/mergedProjects/reference_olh/mergedProjects/instructions/instruct32_hh/vc144.htm

_________________
Back to top
View user's profile Send private message MSN Messenger
Classicus
Advanced Cheater
Reputation: 0

Joined: 22 Dec 2011
Posts: 51

PostPosted: Sun Oct 11, 2015 11:51 pm    Post subject: Reply with quote

mgr.inz.Player - Thanks for the reply. I figured it was a typo and he meant JA/JAE instead of JG/JGE. Looks like he corrected it in his post too. Thanks for the links as well, good to save and read.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> General Gamehacking All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites