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 


Endless Space AA help

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General Gamehacking
View previous topic :: View next topic  
Author Message
Shigan
Master Cheater
Reputation: 0

Joined: 23 Jan 2008
Posts: 422

PostPosted: Fri Mar 22, 2013 12:56 pm    Post subject: Endless Space AA help Reply with quote

So I've decided to try to dive into Assembly with the game Endless Space and I need a bit of hands on help. I've looked at a few of the tutorials lurking in the tutorials section involving AA, but I can't quite grasp how to apply it to what I want to do. My goal right now is to remove the attribute point limit on faction creation. I've done the precursor steps of finding the address that displays the number of points and attached the debugger to that address to find what writes to it.

Image 1

I've already dicked around with nop'ing out codes for quick fixes yesterday, but I'd like to make a change that is much easier to apply than having to repeatedly go through the steps again and again in order to change these points.

Image 2

Just nop'ing it out has worked for me in the past like I've said, but I want to try to avoid the easy way out in the sake of learning. I figure I could just assign a value of 0 to eax by changing
Code:
1F9600B1 - 03 C1                 - add eax,ecx
to
Code:
1F9600B1 - 03 C1                 - mov eax,0


But that doesn't seem to work for me. I'm guessing it has something to do with all of the steps required to get the value of eax becoming redundant after assigning a static value to it. How could I go about either making a script or changing the opcodes to fit what I want to do here?

I copied down the opcodes and put them on pastebin in case anyone needs them to help.

Pastebin
Back to top
View user's profile Send private message MSN Messenger
SteveAndrew
Master Cheater
Reputation: 21

Joined: 02 Sep 2012
Posts: 258

PostPosted: Fri Mar 22, 2013 2:24 pm    Post subject: This post has 1 review(s) Reply with quote

Okay well so that address you found with a value of '26' is the number of points you have right now right?

So in that case that code you found mov [edi+cc],eax is the one responsible for writing how many points you have left after it deducts them?

Which is the instruction that you nopped which had the effect you wanted? Was it that one or the other one mov [edi+cc],00000000?

I don't have this game so I'm purely winging this here! lol

If you look at what was in EAX and ECX when after that instruction executed (it shows on the bottom of that 'the following opcodes write to blahh..' window, or if you press more information it shows what was in the registers as well)

It appears the game was already moving a value of zero into that memory location [edi+CC] so if that's what the game does normally that doesn't seem like what you want...

Have you tried moving a different value besides zero in there instead? One would think if you put a value of 26 into eax before that 'mov [edi+cc],eax' instruction executes it would force you to always have 26 points no matter how many you use...

When you said you did a mov eax,0 did you just single line assemble it, or did you actually make an injectable script? (note a quick / better way to zero a register is to xor it with it self.. (example: xor eax,eax) will make eax zero no matter what it contained before...

why I'm asking is because 'mov eax,00000000' is actually a five byte instruction, so there isn't room for it there, and you'll actually (if you select yes overwrite with nops) be overwriting the 'mov [edi+cc],eax' instruction with nops along with changing that instruction 'add eax,ecx'

A script like this I mean (presuming that address doesn't change 1f9600b3 [else you'll have to make an AOBScan version])
Code:

[enable]
alloc(EndlessSpaceHack,64)
label(EndlessSpaceHackRet)

EndlessSpaceHack:
mov eax,#26 //force a value of 26 into eax register
mov [edi+cc],eax //this is what actually applies it, this should set your points address's value to 26 decimal
jmp EndlessSpaceHackRet

1f9600b3:
jmp EndlessSpaceHack
nop
EndlessSpaceHackRet:

[disable]

1f9600b3:
mov [edi+cc],eax

dealloc(EndlessSpaceHack)



But really it's okay to nop, you are just saying you don't want to have to scan the value and debug and get back to that address each time right?

well you could do something like this:

Code:

[enable]

1f9600b3:
db 90 90 90 90 90 90 //instruction is 6 bytes so 6 nops

[disable]

1f9600b3:
mov [edi+cc],eax //upon disabling put that instruction back




If that address of that instruction changes, then you could do an aobscan version of the script like this (note: not sure if these bytes are unique enough, since I don't have the game to test it, but if it works and finds the right address it should nop that instruction)

Code:

[enable]
aobscan(EndlessSpaceHackAddress,f2 0f 2c c8 03 c1 89 87 cc 00 00 00)
label(EndlessSpaceHackAddy)
registersymbol(EndlessSpaceHackAddy)

EndlessSpaceHackAddress+6:
EndlessSpaceHackAddy:
db 90 90 90 90 90 90

[disable]

EndlessSpaceHackAddy:
mov [edi+cc],eax

unregistersymbol(EndlessSpaceHackAddy)



See no hard coded address there Very Happy

Well I hope this helps!


Oh and the reason why it's +6 in that 'EndlessSpaceHackAddress+6' line is because I started the aob from here:

1F9600AD - F2 0F2C C8 - cvttsd2si ecx,xmm0
1F9600B1 - 03 C1 - add eax,ecx
1F9600B3 - 89 87 CC000000 - mov [edi+000000CC],eax

So the address you hook can be different then where you make your aob from, just be sure to add the correct number of bytes to get to the hook address... (1f9600ad + 6 == 1f9600b3) Wink

_________________
Back to top
View user's profile Send private message
Shigan
Master Cheater
Reputation: 0

Joined: 23 Jan 2008
Posts: 422

PostPosted: Fri Mar 22, 2013 3:36 pm    Post subject: Reply with quote

I nopped mov [edi+cc],eax and got the result I wanted, yes. I did xor eax,eax instead of mov eax,0 in the place of add eax,ecx and it worked. Thanks for that tip!

I'm going to try making a script too, because I was single line assembling it. I didn't notice that it was overwriting anything when I put in mov eax,0 over it, though it did tell me it was going to. I suppose that's why the game crashed on me.

Something I just noticed and I have a quick question on. While writing up the script I noticed that the bytes changed.

It went from
Code:
f2 0f 2c c8 03 c1 89 87 cc 00 00 00
to
Code:
f2 0f 2c c8 01 c8 89 87 cc 00 00 00


Instead of 03 c1 it is 01 c8

Now this is after I've already modified it through single line assembly by changing it to xor eax,eax, but I changed it back to add eax,ecx

Is this because I edited it live? I know it was 03 c1 when I first fired it up, and I'd just like a bit of clarification on that matter (restarting the game put the bytes back to 03 c1)

Onward.

Making the script following your aob version (because the addresses do change) gives me a question. Do you still have to allocate memory to the script if you use aobscan and if so how would you do that?

Here is what I have.

Code:
[enable]
alloc(esFactionAP,64)
aobscan(esFactionAPAddress,f2 0f 2c c8 03 c1 89 87 cc 00 00 00)
label(esFactionAPreturn)

esFactionAP:
esFactionAPAddress+4:
esFactionAPreturn:
xor eax,eax

[disable]

esFactionAPAddress+4:
add eax,ecx

unregistersymbol(esFactionAPreturn)
dealloc(esFactionAP)


I decided to xor eax,eax so that the attribute points (AP) will always show and be 0, which will allow me to get any and all buffs for my faction. I'm confused if esFactionAPreturn or esFactionAP are even necessary here.

Edit: I got an error when trying to add my script to CE, even though it works fine.

Image 1

You can see that it's working if you look at my faction ap value, however it won't let me add it to the table. Why isn't esFactionAP+4: a valid address specifier?

I've also tried changing it to esFactionAPreturn and it didn't work. Same error but with esFactionAPreturn instead of esFactionAP+4

Edit 2: God I'm an idiot. I never registered esFactionAPreturn. All works now.

Edit 3: Another problem. If I enable the script and then disable it and then reenable it after that cheat engine freezes up and nothing happens. Is this because those bytes change?
Back to top
View user's profile Send private message MSN Messenger
SteveAndrew
Master Cheater
Reputation: 21

Joined: 02 Sep 2012
Posts: 258

PostPosted: Fri Mar 22, 2013 4:50 pm    Post subject: Reply with quote

Well see this may be a bit confusing, but there are different ways to assemble the same instruction (I think two, but there may be more), meaning it will be the same number of bytes, but could be different bytes used but it means the same thing / is the same instruction...

Take your instruction for example: 'add eax,ecx' you're game has it hardcoded in it's binary as machine code: '03 c1' but CE assembles it as '01 c8'

as shown here: (I had CE single line assemble that into some memory I allocated with it, then manually inserted '03 c1' on the next line)


So I suppose when you use AOBScan it's safer to manually define the bytes when disabling so that in case CE does assemble it differently than the game had it, you can enable it again after you've disabled it! lol Or else your right it wont find those bytes again the second time (unless you restart the game like you've done)


As for allocating memory... YOU ONLY DO THAT, when you actually HOOK the code... (meaning you overwrite some instruction(s) with a JMP (unconditional jump) to your code (which will be where the allocated memory is, whatever you called it) and then you add some of your code, execute the original instruction(s) [what you overwrote with you JMP hook] then jump back to keep the code flow going...

With your script, no you don't need to allocate any memory since you are just changing the instruction within the space that's there (you only hook when there isn't space there to do what you want, and need a little more room to work with)

as for 'Why isn't esFactionAP+4: a valid address specifier? '

It appears you figured it out with your edit Wink but yeah it's because you didn't register that as a symbol!

however like I said you don't need to allocate any memory for just changing those two bytes (xor eax,eax fits perfectly over the instruction add eax,ecx [as they are both two bytes in length, no nops needed and no hook needed Very Happy)

So I would have made the script like this: (with making use of manually defining the bytes upon disabling to how the game had them)

(Also you use the registered symbol label rather then the aobscan, because for some reason [has to do with CE's AA syntax] you can't register the aobscan name as a symbol (I guess it doesn't count as a label) so by registering a separately defined label as a symbol, you can disable it without doing a weird aobscan on disabling which takes into account your changed bytes

Code:

[enable]
aobscan(esFactionAPAddress,f2 0f 2c c8 03 c1 89 87 cc 00 00 00)
label(esFactionAPreturn)
registersymbol(esFactionAPreturn)

esFactionAPAddress+4:
esFactionAPreturn:
xor eax,eax

[disable]

esFactionAPreturn: //you use the registered symbol here rather then the aobscan
db 03 c1 //manually define the bytes back so you can enable it again after disabling

unregistersymbol(esFactionAPreturn)



Very Happy Glad you got it working though, so I guess zeroing it is the effect you wanted!


EDIT: one thing I want to make clear, is that since 'esFactionAPreturn' is underneath 'esFactionAPAddress+4', it already has the +4 added to it Wink that's why when you disable it you don't write 'esFactionAPreturn+4' that would be wrong... Since it already is already is pointing at the address which had initially 'add eax,ecx' and you changed it to 'xor eax,eax'

CE Freezes when enabling an AOBScan script, because it's attempting to locate those AOB bytes, if it doesn't find them CE will unfreeze after a couple / few seconds and the box wont be ticked... So that's what you were experiencing, by forcing it to define the original bytes the game had upon disabling you can avoid that problem Very Happy

_________________
Back to top
View user's profile Send private message
Shigan
Master Cheater
Reputation: 0

Joined: 23 Jan 2008
Posts: 422

PostPosted: Fri Mar 22, 2013 5:09 pm    Post subject: Reply with quote

I did a bit of tweaking for simplicity's sake and because I was fumbling around trying to figure out why I couldn't disable it

Code:
[enable]
aobscan(esFAA,f2 0f 2c c8 03 c1 89 87 cc 00 00 00)
label(esFAR)
registersymbol(esFAR)

esFAA+4:
esFAR:
xor eax,eax

[disable]

esFAR:
add eax,ecx
db 03 c1

unregistersymbol(esFAR)


When I disabled the script after enabling it the first time and then trying to add another item to the list of my attributes my game crashed. Am I missing something?
Back to top
View user's profile Send private message MSN Messenger
SteveAndrew
Master Cheater
Reputation: 21

Joined: 02 Sep 2012
Posts: 258

PostPosted: Fri Mar 22, 2013 5:12 pm    Post subject: Reply with quote

Shigan wrote:
I did a bit of tweaking for simplicity's sake and because I was fumbling around trying to figure out why I couldn't disable it

Code:
[enable]
aobscan(esFAA,f2 0f 2c c8 03 c1 89 87 cc 00 00 00)
label(esFAR)
registersymbol(esFAR)

esFAA+4:
esFAR:
xor eax,eax

[disable]

esFAR:
add eax,ecx
db 03 c1

unregistersymbol(esFAR)


When I disabled the script after enabling it the first time and then trying to add another item to the list of my attributes my game crashed. Am I missing something?


Yep because you totally messed up the code there, do one or the other! Wink

But so that you can disable it I suggest doing the 'db' instead

So just by changing it to:
Code:

[enable]
aobscan(esFAA,f2 0f 2c c8 03 c1 89 87 cc 00 00 00)
label(esFAR)
registersymbol(esFAR)

esFAA+4:
esFAR:
xor eax,eax

[disable]

esFAR:
db 03 c1

unregistersymbol(esFAR)


It fixes it Wink (I'm sure you've probaly read my post by now! but I just removed one line! Very Happy

_________________
Back to top
View user's profile Send private message
Shigan
Master Cheater
Reputation: 0

Joined: 23 Jan 2008
Posts: 422

PostPosted: Fri Mar 22, 2013 5:50 pm    Post subject: Reply with quote

Alright, this works great now. Everything is working like I'd like it to.

Now, if you can help me with a bit more.

Besides just dealing with faction AP, I've figured out plenty of things I can do with this game, such as modifying the money and making my planet systems instantly turn into colonies.

Can you explain to me what fstp is?

I'm trying to modify my money here, but I'm not sure what to do.

The code I'm looking at is the decrease value code. The code above it is for increasing the value.

Image 1

Once again more of the opcode is on pastebin

Pastebin
Back to top
View user's profile Send private message MSN Messenger
SteveAndrew
Master Cheater
Reputation: 21

Joined: 02 Sep 2012
Posts: 258

PostPosted: Fri Mar 22, 2013 6:38 pm    Post subject: Reply with quote

Okay I recently answered this question here:
http://forum.cheatengine.org/viewtopic.php?t=563333&highlight=

So read that as a background...

it seems your money is stored a as a floating point value, floating points are dealt with differently than standard values, working with them in assembler is easy though once you know how!

But more specifically in your case: (This time we are going to have to hook it!)

Try this:
Code:

[enable]
alloc(MoneyHackHook,64)
aobscan(MoneyHackAddress,d9 45 f8 d9 5f 40 8b 47 30 85 c0 74)
label(MoneyHackAddy)
label(MoneyHackHookReturn)
label(DesiredMoneyAmount)
registersymbol(MoneyHackAddy)

MoneyHackHook:
fstp st(0)      //pop off 'you supposed to be money' value off the top of the FPU stack and discard it
fld dword ptr [DesiredMoneyAmount] //Load into FPU stack the amount of money you want
fstp dword ptr [edi+40]            //pop off 'desired money amount' into money address
mov eax,[edi+30]                   //overwritten instruction, just keep it / could be important
jmp MoneyHackHookReturn            //keep the code flow going so you don't crash...

DesiredMoneyAmount: //make sure this is underneath your allocated memory but before where you do JMP MoneyHackHook
dd (float)1337337.7 //$1,337,337.70 :D

MoneyHackAddress+3:
MoneyHackAddy:
jmp MoneyHackHook //this takes up 5 bytes
nop //we need 1 nop because we overwrote 6 bytes in two instructions
MoneyHackHookReturn: //where it will jump back to after our hook code executes

[disable]

MoneyHackAddy:
db d9 5f 40 8b 47 30
//fstp dword ptr [edi+40] these are the instructions we overwrote
//mov eax,[edi+30]        those bytes put them back

dealloc(MoneyHackHook)
unregistersymbol(MoneyHackAddy)


Again I hope that aobscan is unique enough so it finds that right address, and hopefully I didn't forget anything in terms of syntax as I couldn't test it, I just had to write that off the top of my head! Very Happy

If you read the comments it should give you an idea of whats going on!

To sum it up, we hook this address here:

1FA452CD - D9 5F 40 - fstp dword ptr [edi+40]


However since that instruction is only three bytes, a five byte unconditional jump wont fit as you can see... So when we place our jump hook it will overwrite 5 bytes, so these two instructions are overwritten and we put 1 nop after overwriting them both... :


1FA452CD - D9 5F 40 - fstp dword ptr [edi+40]
1FA452D0 - 8B 47 30 - mov eax,[edi+30]



Since we overwrote an FSTP instruction, well lets consult an x86 assembler instruction reference:
http://www.rz.uni-karlsruhe.de/rz/docs/VTune/reference/vc118.htm

"The FSTP instruction performs the same operation as the FST instruction and then pops the register stack. To pop the register stack, the processor marks the ST(0) register as empty and increments the stack pointer (TOP) by 1. The FSTP instruction can also store values in memory in extended-real format."

Because it 'pops the register stack' as it puts it, if you overwrite it, it's a really good idea to do the same, other wise you'll be leaving that value stuck on the top of the stack, which is bad and could possibly crash the game or screw something up...

fstp st(0) pops the stack without doing anything with the value, so it just discards it... which is what we want because we want to set our value of money, rather than the decreased value of money the game was going to pop into your money address...

Then we do:

fld dword ptr [DesiredMoneyAmount] //Load into FPU stack the amount of money you want


which we created a label called DesiredMoneyAmount, which is how much money you want to constantly force yourself to have when it normally would decrease... the label doesn't have to be registered as a symbol but can if you want to be able to change it on the fly easily... Whats important though is that it's defined somewhere underneath your allocated memory and not underneath the found hook address (so that it's part of your allocated memory)

Then:

fstp dword ptr [edi+40] //pop off 'desired money amount' into money address


which was the original instruction, but this time since we popped off the games original value, and loaded our own it will pop the value we want into the money address rather then the crappy value the game was going to put there! lol Very Happy

finally execute the second original overwritten instruction then jump back

mov eax,[edi+30] //overwritten instruction, just keep it / could be important


Because we overwrote it, it's a good idea to execute it in our hook code as well!


jmp MoneyHackHookReturn //keep the code flow going so you don't crash...


Then we jump back! that jump is going to where our MoneyHackHookReturn label is defined, which is after that single nop

So it will continue execution at this address:


1FA452D3 - 85 C0 - test eax,eax


and everything will be hunky dory and not crash and the game wont even know anything is different, but you'll see the effect when that code executes (giving you in this case 1,337,337 $ Very Happy

_________________
Back to top
View user's profile Send private message
Shigan
Master Cheater
Reputation: 0

Joined: 23 Jan 2008
Posts: 422

PostPosted: Fri Mar 22, 2013 7:55 pm    Post subject: Reply with quote

On my phone right now. when I get back to my desktop I will try to implement that and tinker with it. I think I'll try to make a few different money hacks
Back to top
View user's profile Send private message MSN Messenger
foxfire9
Advanced Cheater
Reputation: 0

Joined: 23 Mar 2012
Posts: 57

PostPosted: Fri Mar 22, 2013 8:54 pm    Post subject: Reply with quote

I'm glad that you made a break through, Shigan.
Back to top
View user's profile Send private message
Shigan
Master Cheater
Reputation: 0

Joined: 23 Jan 2008
Posts: 422

PostPosted: Fri Mar 22, 2013 9:02 pm    Post subject: Reply with quote

foxfire9 wrote:
I'm glad that you made a break through, Shigan.


I didn't?
Back to top
View user's profile Send private message MSN Messenger
foxfire9
Advanced Cheater
Reputation: 0

Joined: 23 Mar 2012
Posts: 57

PostPosted: Sat Mar 23, 2013 8:50 pm    Post subject: Reply with quote

Not that, I meant for not using much NOP's.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> General Gamehacking 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)