 |
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: 61
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: 150
Joined: 06 Jul 2014 Posts: 4652
|
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: 150
Joined: 06 Jul 2014 Posts: 4652
|
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: 150
Joined: 06 Jul 2014 Posts: 4652
|
|
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: 221
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
|
|