Confused why the jump occurs two comparison cycles too late


What is cheating?
Jun 25, 2017
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:
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:
  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?

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


Novice Cheater
Aug 26, 2017
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