Page 1 of 1

Confused why the jump occurs two comparison cycles too late

Posted: Wed Sep 27, 2017 3:23 am
by Karyoplasma
Game in question is FTL: Faster than Light.

Alright, so I wanted to write a script that lets crew fully level up on the first skill training they get. I found out that the opcode that handles the skill training is a simple inc [eax] and dissected the data on the eax address. Basically, the skills of a cremember a scored in ints like this:

Code: Select all

int skill1
int skill1_maximumValue
int skill2
int skill2_maximumValue
...
int skill6_maximumValue
Problem here is that I need to find the address for skill1 so I can start moving the maxValues into all skills. Conveniently, the value in the address 4 bytes before skill1 is always a really big number, so my plan was to compare the value in eax to a threshold number and if it's too big to be a skill then jump to maxing the skills. So here is what I wrote:

Code: Select all

  sub eax,4 //put the eax to skillX-1_maximumValue to start comparing
  @@: //1
  cmp [eax],#150 //compare the value of eax to 150
  jg @f //if it's bigger, it cannot be a skill anymore, so eax carries the address skill1-4, jump to 2
  sub eax,8 //if it was not bigger, we are still in the skill section, so go to skill_maxValue before this one
  jmp @b //jump to 1
  @@: //2
  push edx //borrow register
  mov edx,[eax+8] //move skill1_maxValue in register
  mov [eax+4],edx //move register in skill1
  mov edx,[eax+10] //move skill2_maxValue in register
  mov [eax+c],edx //move register in skill2
  mov edx,[eax+18] //move skill3_maxValue in register
  mov [eax+14],edx //move register in skill3
  mov edx,[eax+20] //move skill4_maxValue in register
  mov [eax+1c],edx //move register in skill4
  mov edx,[eax+28] //move skill5_maxValue in register
  mov [eax+24],edx //move register in skill5
  mov edx,[eax+30] //move skill6_maxValue in register
  mov [eax+2c],edx //move register in skill6
  pop edx //restore register
  mov eax,[esp+14] //standard game instruction because jump needed more bytes
  jmp return
I tested the code and to my confusion, only the skills 3 to 6 were trained, so I put a breakpoint on the instructions and the trace showed me that even tho it compared the value of the address at skill1-4 to 150 and it was bigger, it continued comparing twice more, before it jumped to my code. It consistently does that, so for now I modified my script to accommodate for that and it works, but I still am rather confused as to why it happens in the first place. Anyone got an idea?

EDIT:
Using an unsigned comparison fixed it. So I guess it was as easy as replacing jg with ja.

Re: Confused why the jump occurs two comparison cycles too late

Posted: Wed Sep 27, 2017 7:08 am
by seikur0
You should look for the place eax gets set in the first place, something like "lea eax,[ebx+8*ecx]".
From there you can just take the base address, ebx, instead of doing it the roundabout way.

Well it's working either way :P