Script behaving incorrectly, conditional jumps are ignored.

Memory scanning, code injection, debugger internals and other gamemodding related discussion
Post Reply
User avatar
EyeOfTheMind86
Expert Cheater
Expert Cheater
Posts: 61
Joined: Sun Mar 12, 2017 5:39 pm
Reputation: 33

Script behaving incorrectly, conditional jumps are ignored.

Post by EyeOfTheMind86 »

Hi there folks, this is my second issue I got with the game Soulstice.
I'm adding one more script to the "one hit kill code" which should get rid of any armor some enemies have. Before I could just one shot people without armor and the armor needed to be depleted normally, this time I can directly pulverise the target, but there's a catch.
I am using a onehitkill flag which, when set to 1, makes my script jump to the section where the code zeroes the armor, otherwise it just behaves normally, however the script, once activated, just sets the armor to 0, ignoring the flag I added.
The opcode has been obtained by moving by +2E from the initial AOBScan, as that specific opcode doesn't have an unique AOB and therefore I played it safe by landing on the beginning of the instruction and then changing offset.

Code: Select all

Armor_Data_mem:
cmp [OneHitKill],1
je code_onehit_armor
jmp code_armor

code_onehit_armor:
  push eax
  mov eax,(float)0
  cvtsi2ss xmm0,eax
  pop eax
  jmp code_armor

code_armor:
  movss [rcx+20],xmm0
  mov [target_armor_health],rcx
  jmp return_armor

Armor_Data_AOB+2E:
  jmp Armor_Data_mem
return_armor:
Instruction before performing the AOBScan
Image

Instruction before jumping
Image

Instruction after jumping
Image

The opcode I'm altering is this:

Code: Select all

Soulstice.exe+F0020E - F3 0F11 41 20         - movss [rcx+20],xmm0
Do you have any idea why this is happening? I'm using the same flag for both this armor script and the health one, so it shouldn't be a problem.
Thank you very much for your help, looking forward to your reply.

User avatar
LeFiXER
LeFixer
LeFixer
Posts: 489
Joined: Wed Mar 24, 2021 9:35 am
Reputation: 251

Re: Script behaving incorrectly, conditional jumps are ignored.

Post by LeFiXER »

Try this:

Code: Select all

Armor_Data_mem:
  // compare byte pointer flag
  cmp byte ptr [OneHitKill],1
  // if not 1 then jump to original block
  jne original
  // else jump to code_onehit_armor block
  jmp code_onehit_armor

code_onehit_armor:
  // No need for pushing/popping a register;
  // Just XOR the register with itself to zero it.
  xorps xmm0,xmm0
  jmp code_armor

code_armor:
  movss [rcx+20],xmm0
  mov [target_armor_health],rcx
  jmp return_armor

  // It's _always_ a good idea to keep the original instructions
original:
  movss [rcx+20],xmm0
  jmp return_armor

Armor_Data_AOB+2E:
  jmp Armor_Data_mem
return_armor:

User avatar
Rixef
Cheater
Cheater
Posts: 27
Joined: Wed May 10, 2023 7:43 am
Reputation: 21

Re: Script behaving incorrectly, conditional jumps are ignored.

Post by Rixef »

EyeOfTheMind86 wrote:
Wed May 31, 2023 12:45 pm
Instruction after jumping
Image
LeFiXER's quick lol, I'll leave this one to him but just wanted to point out one thing I noticed; in that third image there, you're pushing Rax(64bit long version) and then using Eax(32bit int register) and then pop'ing Rax again. So that could've been part of the issue. 🤔

EDIT:
Disregard; maybe that was just an old screeny you took before fixing that little typo error. Besides that, that's probably not what's meddling with your script after all now that I re-read your post as what it sounds like is that the script is always zeroing armor whether you want it to or not?

User avatar
EyeOfTheMind86
Expert Cheater
Expert Cheater
Posts: 61
Joined: Sun Mar 12, 2017 5:39 pm
Reputation: 33

Re: Script behaving incorrectly, conditional jumps are ignored.

Post by EyeOfTheMind86 »

LeFiXER wrote:
Wed May 31, 2023 12:57 pm
Try this:

Code: Select all

Armor_Data_mem:
  // compare byte pointer flag
  cmp byte ptr [OneHitKill],1
  // if not 1 then jump to original block
  jne original
  // else jump to code_onehit_armor block
  jmp code_onehit_armor

code_onehit_armor:
  // No need for pushing/popping a register;
  // Just XOR the register with itself to zero it.
  xorps xmm0,xmm0
  jmp code_armor

code_armor:
  movss [rcx+20],xmm0
  mov [target_armor_health],rcx
  jmp return_armor

  // It's _always_ a good idea to keep the original instructions
original:
  movss [rcx+20],xmm0
  jmp return_armor

Armor_Data_AOB+2E:
  jmp Armor_Data_mem
return_armor:
Thank you leFixer for the headsup about the register, it spares me a few useless lines of code, and yeah you're right about keeping a copy of the code, but I usually refer to the [disable] section of the code for it, but keeping it close to the code block it's actually a better practice.
The result it's still the same though. Same problem, the armor is zeroed instantly.
Rixef wrote:
Wed May 31, 2023 1:11 pm
EyeOfTheMind86 wrote:
Wed May 31, 2023 12:45 pm
Instruction after jumping
Image
Yeah it was a typo error, my eyes are starting to make fun of me. However the code keeps doing the same thing and the armor just breaks as soon as I touch the enemy, the value is in fact 0. I have no idea why it's happening.

User avatar
EyeOfTheMind86
Expert Cheater
Expert Cheater
Posts: 61
Joined: Sun Mar 12, 2017 5:39 pm
Reputation: 33

Re: Script behaving incorrectly, conditional jumps are ignored.

Post by EyeOfTheMind86 »

LeFiXER wrote:
Wed May 31, 2023 12:57 pm
Try this:

Code: Select all

Armor_Data_mem:
  // compare byte pointer flag
  cmp byte ptr [OneHitKill],1
  // if not 1 then jump to original block
  jne original
  // else jump to code_onehit_armor block
  jmp code_onehit_armor

code_onehit_armor:
  // No need for pushing/popping a register;
  // Just XOR the register with itself to zero it.
  xorps xmm0,xmm0
  jmp code_armor

code_armor:
  movss [rcx+20],xmm0
  mov [target_armor_health],rcx
  jmp return_armor

  // It's _always_ a good idea to keep the original instructions
original:
  movss [rcx+20],xmm0
  jmp return_armor

Armor_Data_AOB+2E:
  jmp Armor_Data_mem
return_armor:
Thank you leFixer for the headsup about the register, it spares me a few useless lines of code, and yeah you're right about keeping a copy of the code, but I usually refer to the [disable] section of the code for it, but keeping it close to the code block it's actually a better practice.
The result it's still the same though. Same problem, the armor is zeroed instantly.
Rixef wrote:
Wed May 31, 2023 1:11 pm
EyeOfTheMind86 wrote:
Wed May 31, 2023 12:45 pm
Instruction after jumping
Image
Yeah it was a typo error, my eyes are starting to make fun of me. However the code keeps doing the same thing and the armor just breaks as soon as I touch the enemy, the value is in fact 0. I have no idea why it's happening.

Edit: Sorry I edited the post but it just double posted it. Anyway, could the instruction at:

Code: Select all

Soulstice.exe+F00213 - ja Soulstice.exe+F0021F
be ignored some how? When I jump back, I jump straight to that instruction, but right after it another opcode zeroes that armor address by default.

Image
It shouldn't be ignored right?

User avatar
Rixef
Cheater
Cheater
Posts: 27
Joined: Wed May 10, 2023 7:43 am
Reputation: 21

Re: Script behaving incorrectly, conditional jumps are ignored.

Post by Rixef »

EyeOfTheMind86 wrote:
Wed May 31, 2023 12:45 pm
Instruction before jumping
Image
Ohh okay I think I see what's happening here. So in this 2nd image; there's a comiss xmm0,xmm2 and then 2 instructions down from that one is ja Soulstice.exe+F0021F.

So here's what's happening; That comiss is a compare of scalar singles(floats). So it's comparing xmm0 to xmm2 and then setting a flag whether it's true or false that is normally dealt with by the ja Soulstice.exe+F0021F 2 instructions below. Now ja means "jump if above". So normally it's saying, "Compare xmm0 to xmm2 and jump to Soulstice.exe+F0021F if xmm0 is above/greater than xmm2". And it would set a 1/0 flag saying whether xmm0 was above xmm2 or not.

However, it's doing that comiss compare and then jumping to your allocated memory where the first instruction in your memory is another compare which is your cmp [OneHitKill],1 instruction. So it's doing your compare for instance when [OneHitKill] is 0, it's saying, "Compare [OneHitKill](which is 0) to 1" <---that's gonna set the flag saying that [OneHitKill] is not above 1.

So now if you look at that instruction 2 down from the comiss; the ja Soulstice.exe+F0021F and look at the instruction right under that one; mov [rcx+20],00000000 it's hitting that. That's why it's always zeroing your armor regardless of what [OneHitKill] is set to. This is because at the end of your allocated memory, you are jumping to that ja Soulstice.exe+F0021F after it has the compare flag carried from your cmp [OneHitKill],1. It's seeing that 0 is not above 1 so instead of jumping over the mov [rcx+20],00000000 it's going right to it and putting 0 into [rcx+20].

Possible Solution:
instead of a
jmp return at the end of your allocated memory code, do:
jmp return+C (12 bytes past the return so it's jumping over the mov [rcx+20],0) I messed up sorry, it's C(12 bytes) past the one you're jumping to not 11 hex.
Last edited by Rixef on Wed May 31, 2023 2:09 pm, edited 1 time in total.

User avatar
Rixef
Cheater
Cheater
Posts: 27
Joined: Wed May 10, 2023 7:43 am
Reputation: 21

Re: Script behaving incorrectly, conditional jumps are ignored.

Post by Rixef »

Haha I just saw your edit, you caught on to that as well! Nice! Yee, so you should be able to jump past that just fine with jmp return+0C*. 👍

AlexS
Expert Cheater
Expert Cheater
Posts: 322
Joined: Sun Apr 08, 2018 3:46 pm
Reputation: 192

Re: Script behaving incorrectly, conditional jumps are ignored.

Post by AlexS »

EyeOfTheMind86 wrote:
Wed May 31, 2023 1:23 pm
it spares me a few useless lines of code
(Google translation)

Note that the "xorps" command also resets the "xmm" register completely, including the upper bits, just like the "movd" command you used earlier. You can use it if you are sure that the upper bits of the "xmm" register do not contain useful game data, as they will also be lost.
The piece of code that I showed you as an example (and that you used) allows you to save the upper bits of the register, as well as write any number (not just zero) to the lower bits of the register. Also note that the "eax" register is filled with an integer, not a floating point number (like you have in the screenshot).

EyeOfTheMind86 wrote:
Wed May 31, 2023 12:45 pm
Instruction before jumping
(Google translation)

Note that there is a register compare command "comiss xmm0,xmm2" before the injection point, and the conditional jump is after the injection point. Flags are set immediately after the comparison, but if you use the compare command in your script, these flags will be overwritten and the conditional jump after injection will not work correctly.
To avoid this problem, you can use the commands to save and restore the "pushf" and "popf" flags, or choose a different injection point.

User avatar
EyeOfTheMind86
Expert Cheater
Expert Cheater
Posts: 61
Joined: Sun Mar 12, 2017 5:39 pm
Reputation: 33

Re: Script behaving incorrectly, conditional jumps are ignored.

Post by EyeOfTheMind86 »

Jumping away from the comparing instruction wasn't the right approach as the armor decreased into negative and my compare was still screwing the flag either way.
My solution was instead to change jmp offset and editing the code directly on the comiss. What I did was, when the onehitkill is 1, I jump directly to mov [rcx+20],0000000 by using my AOB as reference and moving to offset +35 and let the natural flow of execution from there. If onehitkill is 0 I just let the code run normally with the comiss and everything that comes after.
I thought was the cleanest approach possible. But I could solve this problem because you highlighted me comiss and explained that it was just another cmp, but for xmm registers. From there was just simple logic.
Thank you very much Rixef, your help is always crucial, and also thanks to fixer which taught me a sexy way of zeroing xmm registers without writing bloat code.

User avatar
EyeOfTheMind86
Expert Cheater
Expert Cheater
Posts: 61
Joined: Sun Mar 12, 2017 5:39 pm
Reputation: 33

Re: Script behaving incorrectly, conditional jumps are ignored.

Post by EyeOfTheMind86 »

AlexS wrote:
Wed May 31, 2023 2:58 pm
EyeOfTheMind86 wrote:
Wed May 31, 2023 1:23 pm
it spares me a few useless lines of code
(Google translation)

Note that the "xorps" command also resets the "xmm" register completely, including the upper bits, just like the "movd" command you used earlier. You can use it if you are sure that the upper bits of the "xmm" register do not contain useful game data, as they will also be lost.
The piece of code that I showed you as an example (and that you used) allows you to save the upper bits of the register, as well as write any number (not just zero) to the lower bits of the register. Also note that the "eax" register is filled with an integer, not a floating point number (like you have in the screenshot).

EyeOfTheMind86 wrote:
Wed May 31, 2023 12:45 pm
Instruction before jumping
(Google translation)

Note that there is a register compare command "comiss xmm0,xmm2" before the injection point, and the conditional jump is after the injection point. Flags are set immediately after the comparison, but if you use the compare command in your script, these flags will be overwritten and the conditional jump after injection will not work correctly.
To avoid this problem, you can use the commands to save and restore the "pushf" and "popf" flags, or choose a different injection point.
Hey there Alexs, we basically replied at the same time, I solved the issue but I'll give a look to pushf and popf as I'm sure those will be useful later on.

User avatar
LeFiXER
LeFixer
LeFixer
Posts: 489
Joined: Wed Mar 24, 2021 9:35 am
Reputation: 251

Re: Script behaving incorrectly, conditional jumps are ignored.

Post by LeFiXER »

Glad to see you resolved this :). Feel free to reach out any time with any more questions. This community has a wealth of members willing to help people who want to learn. :)

AlexS
Expert Cheater
Expert Cheater
Posts: 322
Joined: Sun Apr 08, 2018 3:46 pm
Reputation: 192

Re: Script behaving incorrectly, conditional jumps are ignored.

Post by AlexS »

EyeOfTheMind86 wrote:
Wed May 31, 2023 3:08 pm
I solved the issue
(Google translation)

Very good. :)

I'll add a little more.
It seemed to me that you are trying to reduce the number of commands in the script. In this case, your task can be solved by replacing just one byte in the code. In this case, the script will turn out to be very simple, you will not need to inject, jump, or convert numbers, or allocate memory, etc.

For example, you can do this:

Code: Select all

[ENABLE]

Soulstice.exe+F0020A
 db C0

[DISABLE]

Soulstice.exe+F0020A
 db C1
Or like this:

Code: Select all

[ENABLE]

Soulstice.exe+F0020D
 db C0

[DISABLE]

Soulstice.exe+F0020D
 db C2
Or you can use "nop":

Code: Select all

[ENABLE]

Soulstice.exe+F00213
 db 90 90

[DISABLE]

Soulstice.exe+F00213
 db 77 0A
To enable/disable the script, you need to set a hotkey (or two separate keys) that you use to toggle the "OneHitKill" condition.

User avatar
EyeOfTheMind86
Expert Cheater
Expert Cheater
Posts: 61
Joined: Sun Mar 12, 2017 5:39 pm
Reputation: 33

Re: Script behaving incorrectly, conditional jumps are ignored.

Post by EyeOfTheMind86 »

The db 90 approach (nopping) is the one I use the most, I find it very useful when I need to disable specific opcodes, thanks for the suggestion though. And I actually didn't think about just modding the bytes instead of the entire opcode using jumps, I think this can save me from writing more bloat code as well. Thanks for this!

Post Reply

Who is online

Users browsing this forum: No registered users