Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


How to make a conditional value control

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine
View previous topic :: View next topic  
Author Message
ConanOfOz
Newbie cheater
Reputation: 0

Joined: 13 Jul 2015
Posts: 12

PostPosted: Sat Jul 30, 2016 2:18 am    Post subject: How to make a conditional value control Reply with quote

I'm working on Star Trek Bridge Commander (STBC), and I need to find out how to make a script that can decide when to change a value.

I've managed to locate the photon torpedoes, and the 4-byte array which indicates their status. See attachment - I don't know how to make these show in hex.Sad

There are four forward tubes, and two rear. When loaded and ready to fire, each array will read "00 00 80 BF" (0 0 128 191 in decimal).

When a tube is fired, "BF" changes to "3F". The first three bytes appear to go through a counting cycle. "3F" will change to "40, 41, 42" successively, then jumps to "BF" again, with the array back to its original state; tube ready to fire again.

During the cycle, if I change the fourth byte to "42", the cycle immediately resets to original, and the tube is ready to fire again. However, if I lock this array in its original form, the tube goes red and can never be fired again until the game is exited and reloaded.

I want to find out how to write a script that will watch each of the arrays' 4th byte; when this value drops below "42", write "42" to that address which will result in the counting cycle terminating instantly, and correctly.

The pointerscan I used to find the torpedoes pointer returned many results; the one I'm using is...
"stbc.exe"+0057A810.

There are 5 offsets used...
F4, 34, C8, 16C, 15C.

I found that the 6 torpedo tube arrays are at fixed offsets to this address. So, for example, the front tube outer-left (OL) is the torpedo count address offset -253FC. Subtracting the F4 used in the pointer, the pointer offsets for OL then become...
-25308, 34, C8, 16C, 15C.

Anyone willing to coach me through creating an AA script?



Table.PNG
 Description:
tables
 Filesize:  5.84 KB
 Viewed:  8407 Time(s)

Table.PNG




Last edited by ConanOfOz on Sat Jul 30, 2016 6:42 am; edited 1 time in total
Back to top
View user's profile Send private message
Zanzer
I post too much
Reputation: 126

Joined: 09 Jun 2013
Posts: 3278

PostPosted: Sat Jul 30, 2016 6:18 am    Post subject: Reply with quote

Find out what instruction is accessing your byte and post the AOB template here.
Back to top
View user's profile Send private message
ConanOfOz
Newbie cheater
Reputation: 0

Joined: 13 Jul 2015
Posts: 12

PostPosted: Sun Jul 31, 2016 5:05 am    Post subject: Reply with quote

Zanzer wrote:
Find out what instruction is accessing your byte and post the AOB template here.

There are three pieces of code accessing this address (as a 4-byte value).
One that triggers when torpedoes are fired.
One that runs rapidly while the count cycles.
One that triggers when the tube resets.

Which one do you need to see, and how do I create an "AOB template" from this code?
Back to top
View user's profile Send private message
Zanzer
I post too much
Reputation: 126

Joined: 09 Jun 2013
Posts: 3278

PostPosted: Sun Jul 31, 2016 7:51 am    Post subject: Reply with quote

If the byte has the 3F value you mentioned in that first instruction, then that one should do.
In Memory View, Tools > Auto Assemble > Template > AOB Injection
Back to top
View user's profile Send private message
ConanOfOz
Newbie cheater
Reputation: 0

Joined: 13 Jul 2015
Posts: 12

PostPosted: Sun Jul 31, 2016 6:51 pm    Post subject: Reply with quote

This is the first "access" code, triggered when the torpedo is fired.
Code:
alloc(newmem,2048)
label(returnhere)
label(originalcode)
label(exit)

newmem: //this is allocated memory, you have read,write,execute access
//place your code here

originalcode:
mov [ecx+edi*4],00000000

exit:
jmp returnhere

"stbc.exe"+17CA71:
jmp newmem
nop
nop
returnhere:


This is the part that caused the cycling (I refrain from calling it a counter)
Code:
alloc(newmem,2048)
label(returnhere)
label(originalcode)
label(exit)

newmem: //this is allocated memory, you have read,write,execute access
//place your code here

originalcode:
fstp dword ptr [ecx]
mov ebp,[esi+000000AC]

exit:
jmp returnhere

"stbc.exe"+17C701:
jmp newmem
nop
nop
nop
returnhere:

And finally, this gets called and everything gets reset to original values, and the tube is ready to fire again.
Code:
alloc(newmem,2048)
label(returnhere)
label(originalcode)
label(exit)

newmem: //this is allocated memory, you have read,write,execute access
//place your code here

originalcode:
mov [edx+ebx*4],BF800000

exit:
jmp returnhere

"stbc.exe"+17D93B:
jmp newmem
nop
nop
returnhere:


There is something important going on in the middle fragment. Remember I said if I set the most significant byte to 42, the counter (nearly) instantly completes whatever cycle it is doing, and everything resets correctly, ready to fire again? So something in this counter code is reading from this address.

I've attached an image of some of the code around the target instruction in the counter section. (I still can't link url images - sorry).

BTW, I tried setting the "00000000" in the first code sample to "42000000" thinking to simulate me manually altering this address - didn't work. "Broke" the tube and it wouldn't fire again. The counting cycle is doing something essential to a successful reset; I think either we have to monitor/write to the address as I originally asked about, or modify the counting cycle in some way - not sure what you have in mind there.



Code Fragment.PNG
 Description:
 Filesize:  38.3 KB
 Viewed:  8197 Time(s)

Code Fragment.PNG


Back to top
View user's profile Send private message
Zanzer
I post too much
Reputation: 126

Joined: 09 Jun 2013
Posts: 3278

PostPosted: Sun Jul 31, 2016 7:37 pm    Post subject: Reply with quote

Sorry to break it to you, but your value is a simple float. Smile
It starts at -1.0 when it's ready to fire.

That first instruction sets the value to 0.0.
The problem is that instruction looks like it touches several other addresses.
So I'm not sure that is the proper place for your injection.

Instead of the 00000000 that it has, you can try this instead:
Code:
mov [ecx+edi*4],(float)0.01

Let me know if that works and doesn't break anything else.

I'm not sure if your counter goes up or down while waiting for the cooldown. You can also try:
Code:
mov [ecx+edi*4],(float)0.99

Actually, since you claimed the byte goes up to 42, that's the float value 32.0.
So you probably want to use something like:
Code:
mov [ecx+edi*4],(float)30

Or just go all out and tell it that 1000 seconds have elapsed:
Code:
mov [ecx+edi*4],(float)1000

I would assume this instruction touches all cooldowns, so be prepared for rapid fire from the enemy too.

If all else fails, try this for the second instruction:
Code:
alloc(newmem,2048)
label(returnhere)
label(originalcode)
label(exit)
label(myvar) //added

newmem:
fadd dword ptr [myvar] //added

originalcode:
fstp dword ptr [ecx]
mov ebp,[esi+000000AC]

exit:
jmp returnhere

myvar: // added
  dd (float)100 // added

"stbc.exe"+17C701:
jmp newmem
nop
nop
nop
returnhere:

Final note: you used Code Injection, you want to use AOB Injection instead.
Back to top
View user's profile Send private message
ConanOfOz
Newbie cheater
Reputation: 0

Joined: 13 Jul 2015
Posts: 12

PostPosted: Mon Aug 01, 2016 12:01 am    Post subject: Reply with quote

Zanzer wrote:
Sorry to break it to you, but your value is a simple float. Smile
It starts at -1.0 when it's ready to fire.

I'll take your word for it Smile

Quote:
I would assume this instruction touches all cooldowns, so be prepared for rapid fire from the enemy too.

And there is the rub. I found a trainer that does this, and carries a warning that the enemy too get insta-reloads.

Quote:
Final note: you used Code Injection, you want to use AOB Injection instead.

I was wondering why I didn't see "AOB Injection", and assumed that was a typo.

Have now upgraded 6.3 to 6.5.1 -- "AOB Injection is now available.


Back to the core problem...

I don't understand why we must look at the code, and not create a little script to monitor/change the 6 values relating to MY torpedo tubes. Manually altered in the way I mentioned does in fact work.

Is there something I'm not understanding about all this?

I mean, can I make a script to set 6 pointers or something to my tubes, like "OL" for my front-outer-left, then do something like...
Code:
cmp [OL],$42
jl ... ;code to set [OL] to $42


Is this doable, or am I simply showing my ignorance? I really know almost nothing about assembler or CE, so I'm groping in the dark mostly. That's probably not even workable code, but hopefully my intent is clear.

=====

On another note...

I see the "Dissect Code" option might be what I need. Looking for tutorials... It seems the CE Tutorial part 9 is a similar situation; multiple things changed by the same code block. Looking to see if I can use this.
Back to top
View user's profile Send private message
Zanzer
I post too much
Reputation: 126

Joined: 09 Jun 2013
Posts: 3278

PostPosted: Mon Aug 01, 2016 7:07 pm    Post subject: Reply with quote

Did any of those scripts work? Worry about a player-specific script after you get it working first.

Change your pointer types from array of bytes into floats instead.
It will be much clearer how the value works.
Back to top
View user's profile Send private message
ConanOfOz
Newbie cheater
Reputation: 0

Joined: 13 Jul 2015
Posts: 12

PostPosted: Mon Aug 01, 2016 9:56 pm    Post subject: Reply with quote

An aobscanmodule is required, as the code moves between restarts.

The following works great...
Code:
[ENABLE]

aobscanmodule(Counter,stbc.exe,C7 04 B9 00 00 00 00 53 8B CE E8 A0 0F 00 00 6A 00 68 8C 85 8D 00)

alloc(newmem,$1000)

label(code)
label(return)

newmem:

code:
  mov [ecx+edi*4],$421F0000 // Trigger instant reload
  jmp return

Counter:
  jmp code
  nop
  nop
return:
registersymbol(Counter)

[DISABLE]

Counter:
  db C7 04 B9 00 00 00 00

unregistersymbol(Counter)
dealloc(newmem)

From the default AOB Injection template code, all I changed was...
Code:
mov [ecx+edi*4],00000000

...to...
Code:
mov [ecx+edi*4],$421F0000 // Trigger instant reload

However, it works for the enemy too.

I tried modifying this myself, but it doesn't activate in CE...
Code:
[ENABLE]

aobscanmodule(Counter,stbc.exe,C7 04 B9 00 00 00 00 53 8B CE E8 A0 0F 00 00 6A 00 68 8C 85 8D 00)
aobscanmodule(Tubes,stbc.exe,00 00 80 BF ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 00 00 80 BF ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 00 00 80 BF ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 00 00 80 BF ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 00 00 80 BF ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 00 00 80 BF)

alloc(newmem,$1000)

label(code)
label(return)
label(enemy)

newmem:

code:
  cmp [ecx],Tubes // Test if ecx is pointing to Tubes (mine)
  jne enemy // If not equal, this is for the enemy - jmp to normal code
  mov [ecx+edi*4],$421F0000 // Trigger instant reload
  jmp return
enemy:
  mov [ecx+edi*4],00000000 // Trigger normal reload
  jmp return

Counter:
  jmp code
  nop
  nop
return:
registersymbol(Counter)

[DISABLE]

Counter:
  db C7 04 B9 00 00 00 00

unregistersymbol(Counter)
dealloc(newmem)


I noticed that ecx contains the address of the start of my tube data block, and the offsets for each specific tube were multiples of 4, with Outer-Left being +0 (and I saw that edi was 0 for this tube).

So I figured that a simple test of ecx to see if it pointed to my data would enable me to make this work for myself only. You can see the logic in the coding.

But, this code will not activate. Something wrong with the new "aobscanmodule" maybe. Search pattern too long? I tried "aobscan" as well but the code still doesn't activate.
Back to top
View user's profile Send private message
Zanzer
I post too much
Reputation: 126

Joined: 09 Jun 2013
Posts: 3278

PostPosted: Mon Aug 01, 2016 10:37 pm    Post subject: Reply with quote

Maybe try the normal aobscan() instead:
Code:
aobscan(Tubes,00 00 80 BF ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 00 00 80 BF ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 00 00 80 BF ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 00 00 80 BF ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 00 00 80 BF ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 00 00 80 BF)

Also, not sure, but you might've wanted
Code:
  cmp ecx,Tubes

You could also use your pointer in the compare.
Code:
  push eax
  mov eax,[stbc.exe+0057A810]
  mov eax,[eax+F4]
  mov eax,[eax+34]
  mov eax,[eax+C8]
  mov eax,[eax+16C]
  mov eax,[eax+15C]
  cmp eax,ecx
  pop eax
  jne enemy
Back to top
View user's profile Send private message
ConanOfOz
Newbie cheater
Reputation: 0

Joined: 13 Jul 2015
Posts: 12

PostPosted: Tue Aug 02, 2016 2:51 am    Post subject: Reply with quote

I went back to the original code that works.

As soon as I add a second aobscan, it will not activate/run.

Does AA only allow one AOB scan?

P.S. I did use aobscan, not aobscanmodule. Same result.

P.P.S. I also tried reducing the length of the pattern in case that was the problem. Still doesn't work.

P.P.P.S. Can I create a second script, run an aobscan for my data in there, then register the variable?

e.g. :
Code:
[ENABLE]
aobscan(Tubes,stbc.exe,00 00 80 BF * * * * * * * * * * * * 00 00 80 BF)
registersymbol(Tubes)

[DISABLE]
unregistersymbol(Tubes)


P.P.P.P.S. My first statement that the tube status is at a consistent offset to the number of torpedoes was wrong. Currently scanning down pointers so I can test your suggestion about pointers; can't use the torpedo count pointer...
Back to top
View user's profile Send private message
cooleko
Grandmaster Cheater
Reputation: 11

Joined: 04 May 2016
Posts: 717

PostPosted: Tue Aug 02, 2016 11:52 am    Post subject: Reply with quote

Every time i get a counter, I simply perform a compare:
Quote:
"3F" will change to "40, 41, 42" successively, then jumps to "BF"



cmp [counter_address], 3f
je originalcode
cmp [counter_address], bf
je originalcode
cmp [counter_address], 42
jge originalcode
mov [counter_address], 42
originalcode:

Should work.
Back to top
View user's profile Send private message
ConanOfOz
Newbie cheater
Reputation: 0

Joined: 13 Jul 2015
Posts: 12

PostPosted: Tue Aug 02, 2016 1:52 pm    Post subject: Reply with quote

cooleko wrote:
Every time i get a counter, I simply perform a compare:
Quote:
"3F" will change to "40, 41, 42" successively, then jumps to "BF"

...snip...


Thanks for the tip. Unfortunately, this will work for enemy too.

My evening's efforts have actually taken me backward.

1. I discovered, after probably 20 or 30 restarts, that the game sometimes does, in fact, use a different arrangement for the status values of the six tubes; their relationship to each other does change.

2. On three separate attempts, running a series of pointerscans to try to find a source pointer for these values ultimately resulted in 0 entries. That's right, after 4 or 5 cycles through, I ended up with NO matches.

3. I can readily find the four addresses with the basic scan tools in CE. I start the game with all 6 tubes loaded and ready. I do a First Scan looking for the "Exact" 4-byte value "BF800000". Then I manually fire off all 6 tubes, leave the game active, switch back to CE, and do a couple or three scans for "changed value". Very fast. I get all 6 addresses easily.

4. aob injection code that was working earlier is crashing the game now. I have changed it of course, trying to manually insert the six addresses into six "cmp" statements, but now it crashes the game. Maybe someone can pick what's wrong with the code...
Code:
[ENABLE]

aobscanmodule(Counter,stbc.exe,C7 04 ?? 00 00 00 00 ?? 8B CE E8 ?? ?? ?? ?? 6A 00 68 ?? ?? ?? ?? 6A 2C B9)

alloc(newmem,$2048)

label(code)
label(return)
label(mine)
label(enemy)

newmem:

code:
  push eax
  mov eax,$09333E0C
  cmp ecx,eax // Is this OL?
  je mine
  mov eax,$09333FC4
  cmp ecx,eax // Is this IL?
  je mine
  mov eax,$093341DC
  cmp ecx,eax // Is this IR?
  je mine
  mov eax,$093341E4
  cmp ecx,eax // Is this OR?
  je mine
  mov eax,$093347E4
  cmp ecx,eax // Is this L?
  je mine
  mov eax,$09334B7C
  cmp ecx,eax // Is this R?
  je mine
  jmp enemy
mine:
  mov [ecx+edi*4],$42000000 // Trigger instant reload
  pop eax
  jmp return
enemy:
  mov [ecx+edi*4],$00000000
  pop eax
  jmp return

Counter:
  jmp code
  nop
  nop
return:
registersymbol(Counter)

[DISABLE]

Counter:
  db C7 04 B9 00 00 00 00

unregistersymbol(Counter)
dealloc(newmem)


It enables ok, and by watching the "memory region" I can see that the aobscanmodule call is finding the right area and inserting the code.

Of course, I have to test the address being manipulated to find out if the call to this code is for my torpedo launch, or an enemy's. As soon as I fire, however, stbc crashes.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites