| 
			
				|  | Cheat Engine The Official Site of Cheat Engine
 
 
 |  
 
	
		| View previous topic :: View next topic |  
		| Author | Message |  
		| Classicus Advanced Cheater
 
 ![]() Reputation: 0 
 Joined: 22 Dec 2011
 Posts: 51
 
 
 | 
			
				|  Posted: Thu Oct 01, 2015 6:08 pm    Post subject: Help with trying to compare xmm0 |   |  
				| 
 |  
				| 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 |  |  
		|  |  
		| panraven Grandmaster Cheater
 
 ![]() Reputation: 62 
 Joined: 01 Oct 2008
 Posts: 958
 
 
 | 
			
				|  Posted: Thu Oct 01, 2015 8:54 pm    Post subject: |   |  
				| 
 |  
				| 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 |  |  
		|  |  
		| ParkourPenguin I post too much
 
  Reputation: 152 
 Joined: 06 Jul 2014
 Posts: 4706
 
 
 | 
			
				|  Posted: Thu Oct 01, 2015 8:58 pm    Post subject: |     |  
				| 
 |  
				| 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 |  |  
		|  |  
		| Classicus Advanced Cheater
 
 ![]() Reputation: 0 
 Joined: 22 Dec 2011
 Posts: 51
 
 
 | 
			
				|  Posted: Fri Oct 02, 2015 3:56 am    Post subject: |   |  
				| 
 |  
				| 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 |  |  
		|  |  
		| ParkourPenguin I post too much
 
  Reputation: 152 
 Joined: 06 Jul 2014
 Posts: 4706
 
 
 | 
			
				|  Posted: Fri Oct 02, 2015 8:47 am    Post subject: |   |  
				| 
 |  
				| 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 |  |  
		|  |  
		| Zanzer I post too much
 
 ![]() Reputation: 126 
 Joined: 09 Jun 2013
 Posts: 3278
 
 
 | 
			
				|  Posted: Fri Oct 02, 2015 3:53 pm    Post subject: |   |  
				| 
 |  
				| Your injection is jumping to "code" instead of "newmem" like you want.   |  |  
		| Back to top |  |  
		|  |  
		| Classicus Advanced Cheater
 
 ![]() Reputation: 0 
 Joined: 22 Dec 2011
 Posts: 51
 
 
 | 
			
				|  Posted: Fri Oct 02, 2015 5:10 pm    Post subject: |   |  
				| 
 |  
				| 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 |  |  
		|  |  
		| ParkourPenguin I post too much
 
  Reputation: 152 
 Joined: 06 Jul 2014
 Posts: 4706
 
 
 |  |  
		| Back to top |  |  
		|  |  
		| Classicus Advanced Cheater
 
 ![]() Reputation: 0 
 Joined: 22 Dec 2011
 Posts: 51
 
 
 | 
			
				|  Posted: Fri Oct 02, 2015 7:27 pm    Post subject: |   |  
				| 
 |  
				| 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 |  |  
		|  |  
		| mgr.inz.Player I post too much
 
  Reputation: 222 
 Joined: 07 Nov 2008
 Posts: 4438
 Location: W kraju nad Wisla. UTC+01:00
 
 | 
			
				|  Posted: Sun Oct 11, 2015 7:14 am    Post subject: |     |  
				| 
 |  
				|  	  | 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 |  |  
		|  |  
		| Classicus Advanced Cheater
 
 ![]() Reputation: 0 
 Joined: 22 Dec 2011
 Posts: 51
 
 
 | 
			
				|  Posted: Sun Oct 11, 2015 11:51 pm    Post subject: |   |  
				| 
 |  
				| 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 |  |  
		|  |  
		|  |  
  
	| 
 
 | 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
 
 |  |