XMM Question

Memory scanning, code injection, debugger internals and other gamemodding related discussion
Post Reply
User avatar
Kalas
Expert Cheater
Expert Cheater
Posts: 244
Joined: Fri Mar 03, 2017 9:49 am
Reputation: 26

XMM Question

Post by Kalas » Wed Mar 15, 2017 9:55 am

How can I write what's in xmm1 into xmm1, like a loop or so, sort of a nop.

Code: Select all

[ENABLE]

aobscanmodule(aobAmber,Styx2-Win64-Shipping.exe,F3 0F 11 89 E0 03 00 00)
alloc(newmem,$100,"Styx2-Win64-Shipping.exe"+285D67)

label(code)
label(return)

newmem:

code:
  movss [rcx+000003E0],xmm1
  jmp return

aobAmber:
  jmp newmem
  nop
  nop
  nop
return:
registersymbol(aobAmber)

[DISABLE]

aobAmber:
  db F3 0F 11 89 E0 03 00 00

unregistersymbol(aobAmber)
dealloc(newmem)

{
// ORIGINAL CODE - INJECTION POINT: "Styx2-Win64-Shipping.exe"+285D67

"Styx2-Win64-Shipping.exe"+285D58: CC                       -  int 3 
"Styx2-Win64-Shipping.exe"+285D59: CC                       -  int 3 
"Styx2-Win64-Shipping.exe"+285D5A: CC                       -  int 3 
"Styx2-Win64-Shipping.exe"+285D5B: CC                       -  int 3 
"Styx2-Win64-Shipping.exe"+285D5C: CC                       -  int 3 
"Styx2-Win64-Shipping.exe"+285D5D: CC                       -  int 3 
"Styx2-Win64-Shipping.exe"+285D5E: CC                       -  int 3 
"Styx2-Win64-Shipping.exe"+285D5F: CC                       -  int 3 
"Styx2-Win64-Shipping.exe"+285D60: 0F 57 C0                 -  xorps xmm0,xmm0
"Styx2-Win64-Shipping.exe"+285D63: F3 0F 5F C8              -  maxss xmm1,xmm0
// ---------- INJECTING HERE ----------
"Styx2-Win64-Shipping.exe"+285D67: F3 0F 11 89 E0 03 00 00  -  movss [rcx+000003E0],xmm1
// ---------- DONE INJECTING  ----------
"Styx2-Win64-Shipping.exe"+285D6F: C3                       -  ret 
"Styx2-Win64-Shipping.exe"+285D70: 0F 57 C0                 -  xorps xmm0,xmm0
"Styx2-Win64-Shipping.exe"+285D73: F3 0F 5F C8              -  maxss xmm1,xmm0
"Styx2-Win64-Shipping.exe"+285D77: F3 0F 11 89 DC 03 00 00  -  movss [rcx+000003DC],xmm1
"Styx2-Win64-Shipping.exe"+285D7F: C3                       -  ret 
"Styx2-Win64-Shipping.exe"+285D80: 8B 02                    -  mov eax,[rdx]
"Styx2-Win64-Shipping.exe"+285D82: 89 81 E4 03 00 00        -  mov [rcx+000003E4],eax
"Styx2-Win64-Shipping.exe"+285D88: C3                       -  ret 
"Styx2-Win64-Shipping.exe"+285D89: CC                       -  int 3 
"Styx2-Win64-Shipping.exe"+285D8A: CC                       -  int 3 
}

User avatar
FreeER
Cheater
Cheater
Posts: 41
Joined: Fri Mar 10, 2017 7:11 pm
Reputation: 5
Contact:

Re: XMM Question

Post by FreeER » Wed Mar 15, 2017 5:34 pm

um.... maybe something like

Code: Select all

// save xmm2 to stack
sub esp, #16
movdqu  dqword [esp], xmm2

// move 1 into 2 and then 2 into 1 (essentially move 1 into 1)
movss xmm2, xmm1
movss xmm1, xmm2

// restore xmm2 from stack
movdqu  xmm2, dqword [esp]
add     esp, #16
Though since this has literally 0 effect... why not just use nop, or do nothing at all meaning literally don't write any code because you aren't doing anything...?

----------------

A loop is very different from code with no effect (aka nop - "no operation"). The code in a loop (can) be run multiple times, meaning it jumps back to the start of the loop when it reaches the end, conditionally if it's not an infinite loop.. often it does something useful at some point like copying a value or incrementing a counter / timer etc.

A nop simply doesn't change anything when it's done, "nop" in x86 is actually the instruction for xchg eax, eax which would more literally be what you were talking about with xmm1, exchange the value in operand 1 (eax) with the value in operand 2 (eax) so eax = eax which does, essentially, nothing just like anding with -1 or oring with 0 if you save and restore the flags so that they aren't changed.

Now, if you have some code that's changing what xmm1 is and you want to prevent it from changing xmm1 then the simple answer is to nop the instruction(s) that change it, meaning replace it's bytes with bytes that, overall, do nothing. Typically done by replacing each byte with 0x90 which is the xchg eax,eax instruction mentioned earlier, typically shown with the mnemonic "nop" though it could also be a jump which skips to the next instruction or to another jmp which would skip past it (that's what happens if you use the templates in CE where it allocates memory and then you just delete the code and leave it empty except for the jmp to return).

The instruction your injecting at (movss [rcx+000003E0],xmm1) however is storing the (float) value of xmm1 into [rcx+3E0], not changing xmm1. Though the maxss instruction just before the instruction you're injecting at could be changing it, to prevent that all you'd have to do is nop out that instruction.

The code injection method would be like this:

Code: Select all

Styx2-Win64-Shipping.exe"+285D63:
  db 90 90 90 90
with some extra boiler plate so you can add it to the table and disable it.

The aob would probably be more like this if you didn't allocate memory:

Code: Select all

aobscanmodule(aobAmber,Styx2-Win64-Shipping.exe, F3 0F 5F C8 F3 0F 11 89 E0 03 00 00)
aobAmber:
  db 90 90 90 90
again, with some extra boiler plate code.

or if you did allocate memory something like this:

Code: Select all

aobscanmodule(aobAmber,Styx2-Win64-Shipping.exe, F3 0F 5F C8 F3 0F 11 89 E0 03 00 00)
alloc(newmem,1000)
label(return)

newmem:
  // maxss xmm1, xmm0 // comment out / delete the maxss instruction we don't want to run
  movss [rcx+000003E0],xmm1 // instruction after the maxss we wanted to nop, unfortunately had to overwrite for the jmp
  jmp return // go to instruction after the movss which was just ran
 
aobAmber:
  jmp newmem // jmp needs 5 bytes while the maxss is only 4 so have to nop out the rest of the movss we're overwriting
  db 90 90 90 90 90 90 90
return:
+ boilerplate.

User avatar
Kalas
Expert Cheater
Expert Cheater
Posts: 244
Joined: Fri Mar 03, 2017 9:49 am
Reputation: 26

Re: XMM Question

Post by Kalas » Wed Mar 15, 2017 5:42 pm

Yea I decided to go with simple nop

Though even xorps xmm1,xmm1 works if I want the value to go to 0.

User avatar
FreeER
Cheater
Cheater
Posts: 41
Joined: Fri Mar 10, 2017 7:11 pm
Reputation: 5
Contact:

Re: XMM Question

Post by FreeER » Wed Mar 15, 2017 6:42 pm

yeah, xorps xmm1,xmm1 is pretty much the same as xor eax,eax (but with an SSE register), since it's taking the exclusive or with itself it will always end up as 0 (since if a bit is 0 then 0 xor 0 is 0 and if it's not then 1 xor 1 is also 0, leaving every bit as 0). Not exactly a nop since it does have an effect (assuming xmm1 isn't always 0) but if it's ok for it to be 0 then it's just as good a replacement as the typical nop is if you need to take up a multiple of 3 bytes (or if the size doesn't matter).

Post Reply

Who is online

Users browsing this forum: No registered users