Sir, You Are Being Hunted

Slade

Expert Cheater
Apr 29, 2017
78
3
8
#1
I know there is a table for this already, but it's a basic table, and I wanted to write a scripted version that might survive an update. So far, I've got Vitality working fine, but for some odd reason, Health is being difficult.

I've found the value/location. That's easy. The same routine is used to futz with both the player and the enemies health. So the obvious thing is to find a value to compare against. I've done that as well, but it still doesn't work.



In the above image, [rdi+30] holds the current players health, [RDI+28] holds the maximum health (which the game moves into different xmm registers I've noticed). Also of note is that [rdi+30] is always the same, '1' for the enemies and '0.349999994' for the player. So I thought I would write the following code to differentiate between the player and the enemy:
Code:
label(code)
label(return)
label(player)

newmem:
  push rax
  mov rax, [rdi+30]
  cmp rax,(float)1
  pop rax
  jl player

code:
  movss [rdi+34],xmm15
  jmp return

player:
  mov [rdi+14],(float)100
  movss xmm15,[rdi+14]
  jmp code
But it doesn't work. I've tried a few different things, but for some odd reason, any compares I do just fail. If anyone can point me onto the path of salvation (or at least a working script), then I'd be a happy person.

Cheers.
 

Schnitzelmaker

Expert Cheater
Mar 3, 2017
105
0
16
#2
Since it uses xmm registers, i suggest to look into comiss.

Example:
Code:
movss [temp], xmm0 //store orginial value
movss xmm0, [rdi+30]
comiss xmm0, [yourfloatvalue]
movss xmm0, [temp] //restore value
//jmp instruction
jl code
...

jmp return

yourfloatvalue:
  dd (float)1.0
  
temp:
  dd 0

Without xmm register its an anoying stuff with fcom. Not sure what values are required for test ah,... and if it should be jump if parry (jp) or jump if not parry (jnp)
Code:
push rax
fld dword ptr [rdi+30]
fcomp dword ptr [yourfloatvalue]
fnstsw ax // store compare flags in ah
test ah,41 // check flags
pop rax
jnp code // or jp code
...
jmp return

yourfloatvalue:
  dd (float)1.0
 

Slade

Expert Cheater
Apr 29, 2017
78
3
8
#3
Thanks, that's a big help.

I rewrote the script, using your code to come up with this:
Code:
label(code)
label(return)
label(player)

newmem:
movss [temp], xmm0 //store orginial value
movss xmm0, [yourfloatvalue]
comiss xmm0, [rdi+30]
movss xmm0, [temp] //restore value
jne code
jmp player

code:
  movss [rdi+34],xmm15
  jmp return

player:
  mov [rdi+14],(float)100
  movss xmm15,[rdi+14]
  jmp code

yourfloatvalue:
  dd (float)0.349999994

temp:
  dd 0
Which works well, so far. I'm sure I could simplify it by not having that player: section, but it works for now, so I'm not going to play with it too much.

I had to google comiss, it appears to be the x64 version of a cmp, yeah ?

And is this:
Code:
yourfloatvalue:
  dd (float)0.349999994
the asm version of this:
Code:
Float myVar = 6.3;
?

Thanks again for the assist.
 

Schnitzelmaker

Expert Cheater
Mar 3, 2017
105
0
16
#4
Slade post_id=10786 time=1497353827 user_id=3704 said:
And is this:
Code:
yourfloatvalue:
  dd (float)0.349999994
the asm version of this:
Code:
Float myVar = 6.3;
?

Thanks again for the assist.

Yes. Its one of the define Byte/Word/Doubleword... and converts specified values into bytes and write them into memory for access.

DB - Define Byte. 8 bits
DW - Define Word. Generally 2 bytes on a typical x86 32-bit system
DD - Define double word. Generally 4 bytes on a typical x86 32-bit system
Code:
db      0x55                ; just the byte 0x55
db      0x55,0x56,0x57      ; three bytes in succession
db      'a',0x55            ; character constants are OK
db      'hello',13,10,'$'   ; so are string constants
dw      0x1234              ; 0x34 0x12
dw      'A'                 ; 0x41 0x00 (it's just a number)
dw      'AB'                ; 0x41 0x42 (character constant)
dw      'ABC'               ; 0x41 0x42 0x43 0x00 (string)
dd      0x12345678          ; 0x78 0x56 0x34 0x12
dq      0x1122334455667788  ; 0x88 0x77 0x66 0x55 0x44 0x33 0x22 0x11
dd      1.234567e20         ; floating-point constant
dq      1.234567e20         ; double-precision float
dt      1.234567e20         ; extended-precision float
 

FreeER

RCE Fanatics
Talents
Mar 10, 2017
82
2
8
#5
Code:
dw      'A'                 ; 0x41 0x00 (it's just a number)
dw      'AB'                ; 0x41 0x42 (character constant)
dw      'ABC'               ; 0x41 0x42 0x43 0x00 (string)
might not do what you expect.

Here's 3 quick test scripts ("Tutorial-i386.exe"+290 (400290) is a code cave of 0 bytes in the CE tutorial v3.3 that I often use for testing):
Code:
[ENABLE]
"Tutorial-i386.exe"+290:
  dw      'A'
  db 90
  dw      'AB'  // 0x41 0x42 (character constant)
  db 90
  dw      'ABC' // 0x41 0x42 0x43 0x00 (string)
  db 90
/*
my result in CE 6.7
41 00
90
41 42
90
41 42
90
*/
[DISABLE]
"Tutorial-i386.exe"+290:
  db 0 0 0 0 0 0 0 0 0
Code:
[ENABLE]
"Tutorial-i386.exe"+290:
  db      'A'
  db 90
  db      'AB'  // 0x41 0x42 (character constant)
  db 90
  db      'ABC' // 0x41 0x42 0x43 0x00 (string)
  db 90
/*
my result in CE 6.7
41
90
41 42
90
41 42 43
90
*/
[DISABLE]
"Tutorial-i386.exe"+290:
  db 0 0 0 0 0 0 0 0 0
Code:
[ENABLE]
"Tutorial-i386.exe"+290:
  dw      #65
  db 90
  dw      41 42  // 0x41 0x42 (character constant)
  db 90
  dw      41 42 43 0 // 0x41 0x42 0x43 0x00 (string)
  db 90
/*
my results in CE 6.7
41 00
90
41 00 42 00
90
41 00 42 00 43 00 00 00
90
*/
[DISABLE]
"Tutorial-i386.exe"+290:
{$lua}
return "db " .. string.rep("00 ", 18)
{$asm}
edit:

the floats also don't work as shown
Code:
[ENABLE]
"Tutorial-i386.exe"+290:
dd      1.234567e20         // floating-point constant
db 90
dq      1.234567e20         // double-precision float
db 90
// CE just flat out complains about dt, even manually in disassembler context "Assembler" / enter option
//dt      1.234567e20         // extended-precision float
//db 90
/*
my results in CE 6.7
00 00 00 00
90
00 00 00 00 00 00 00 80
90
*/
[DISABLE]
"Tutorial-i386.exe"+290:
{$lua}
return "db " .. string.rep('00 ', 4+8+10)
{$asm}
pretty simple to fix this one though
Code:
[ENABLE]
"Tutorial-i386.exe"+290:
dd      (float)1.234567e20         // floating-point constant
db 90
dq      (double)1.234567e20         // double-precision float
db 90
// CE just flat out complains about dt, even manually in disassembler context "Assembler" / enter option
//dt      1.234567e20         // extended-precision float
//db 90
/*
my results in CE 6.7
CA 29 D6 60 // verified as 1.234567016E20 in address list (addr 400290, float type)
90
DF 87 31 3A 39 C5 1A 44 // verified as 1.234567E20 in address list (addr 400295, double type)
90
*/
[DISABLE]
"Tutorial-i386.exe"+290:
{$lua}
return "db " .. string.rep('00 ', 4+8+10)
{$asm}
 
Top Bottom