 |
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
Xillica Cheater
Reputation: 1
Joined: 28 Jun 2015 Posts: 45
|
Posted: Wed Jul 01, 2015 10:16 am Post subject: Questions about retrieving item_id & assembly related |
|
|
So here goes, multiple questions regarding certain topics. Thanks beforehand .
1. Is there any way to know the item_id & item_name from game without verifying it manually one-by-one? (Like Shinkansen lists, I hope Shinkansen reads this so he/she can give me of what to do or where to starts)
2. What are good AoBs (game code) that less likely to get changed with game update or different game versions? (So I can replace the bad ones with wildcards)
Note:
I tried searching about this, and found Rydian's guide about Good Signature. It tells me not to use AoBs that referencing to memory addresses that may change (such as mov edx,[0049E650]).
So if I find instructions like this mov r9d,[rax+00007714] >> 44 8B 88 14770000 what should I do? I mean the referenced memory address is defined by the rax register and it's offset, but the offset is quite big which concerns me (it doesn't change after game restarts, but is it possible if it differs for each game version or update?)
3. About alloc, is there any reason for us to input the 3rd parameter? ALLOC(allocname,sizeinbytes, preferedregion OPTIONAL)
4. What are good assembly structure for code injection (for readability, performance), or is there any scripts example that anyone recommend?
Note: I created .ct with assembly scripts for Toukiden Kiwami game, but it's my first time. It would be great if anyone can give me pointer on what to improve. The link is in my signature.
Last, Happy Birthday Dark Byte (≧∇≦)/. Thanks for creating cheat engine and this awesome forum. So many amazing people here xD (Dark Byte, Geri, atom0s [what's with the retired signature?],Csimbi, Recifense, ++METHOS, pox, Steve Andrew, Shinkansen, mgr.inz.Player, and the list keeps going on).
_________________
Toukiden Kiwami cheat table: forum.cheatengine.org/viewtopic.php?p=5600876#5600876
Last edited by Xillica on Wed Jul 01, 2015 2:46 pm; edited 1 time in total |
|
Back to top |
|
 |
atom0s Moderator
Reputation: 205
Joined: 25 Jan 2006 Posts: 8587 Location: 127.0.0.1
|
Posted: Wed Jul 01, 2015 2:01 pm Post subject: |
|
|
1. Typically you wont be able to do without comparing things unless you can either find the information online somewhere already discovered or if you read the games data files to find the information needed. One way or another you will have to figure out which location inside of the items information is specifically the id that specifies that item.
2. The referenced offset of what you showed such as 0x7714 has the potential to change, but it is less likely to depending on how the game updates. In some cases, it is best to wildcard offsets like that too in games that update frequently. At that point you would make the signature longer to ensure you got a unique AoB.
But for a rule of thumb:
- Don't use jumps or jump offsets in your signatures.
- Don't use calls in your signatures.
- Don't use raw addresses that are referenced in your signatures.
- Don't use referenced offsets in games that update often.
Once you get used to what things look like it is also best to avoid using things like:
- Stack correction / alignments since they can change in updates.
- Exception filter blocks.
3. Fairly sure that is for if you want to use an existing memory location. Using it will allow you to use an existing memory region with a name attached for CE usage.
4. Check the examples that Cheat Engine generates, they are fairly solid examples of injection for starting off.
_________________
- Retired. |
|
Back to top |
|
 |
Xillica Cheater
Reputation: 1
Joined: 28 Jun 2015 Posts: 45
|
|
Back to top |
|
 |
STN I post too much
Reputation: 43
Joined: 09 Nov 2005 Posts: 2676
|
Posted: Wed Jul 01, 2015 2:53 pm Post subject: |
|
|
#2. Don't use jumps, conditional jumps are sometimes fine and may stick for a couple version changes but not for a lot. The code you posted is fine, it is 64 bit and everything is big due to large address spaces. Offsets don't change often, i have had some games where the offsets remained the same across 10 different versions. In areas where there is a few instructions, offsets is what make the code unique.
There are actually no rules to a good signature except no calls and address being used. It is game dependent. If the developers change the specific function then no matter how good your sig is, it will not work. For example, in a game the devs completely rewrote a function (stats) rendering my sig useless. Sometimes, they will change the offsets and everything else remains the same again making your sig useless.
Do this and you will develop an intuition on how to develop a good sig yourself instead of following others advice which is a good thing because some people advise one way and others will do differently (i always use offsets, the poster above me advises against them e.g).
1.Get 3 or 4 different versions of a game (any game, cracks or patches).
2.Make a signature for the lowest game version
3.Upgrade and notice the changes.
4.Keep upgrading and then notice the changes.
There will come a point where you realize you can't make a completely future proof signature at all, you can try and it depends on the game devs if they will fuck up which is how it really is. This should, however, make you understand what makes a good sig and how you can make your sig survive a few versions.
#3. Is used for 64 bit injection when you want to make your jumps shorter so you specify an address and allocate the cave closer (hence the jump is short). You can use it in 32 bit but there's really need as a random address is fine. See
http://www.cheatengine.org/forum/viewtopic.php?p=5523528
4. For performance ? it is just a few lines of ASM code how the heck do you optimize that lol. Readability is personal preference, just keep things tidy and it is readable. Some people like to comment out a lot, i don't, its a few lines you already know what it does. You make a cave, you jump to it, write your code and get back to game, there isn't a lot of ways you can change that. Besides, asm is the fastest it can be, my code i wrote a decade ago in masm still runs faster than my best optimized code in c++ (sigscanner), for small projects it doesn't even matter with todays processors.
_________________
|
|
Back to top |
|
 |
Xillica Cheater
Reputation: 1
Joined: 28 Jun 2015 Posts: 45
|
Posted: Wed Jul 01, 2015 3:16 pm Post subject: |
|
|
Thank you so much STN (^▽^). I will get other game versions as you said and start working to learn more from there.
Quote: | 4. For performance ? it is just a few lines of ASM code how the heck do you optimize that lol. Readability is personal preference, just keep things tidy and it is readable. Some people like to comment out a lot, i don't, its a few lines you already know what it does. You make a cave, you jump to it, write your code and get back to game, there isn't a lot of ways you can change that. Besides, asm is the fastest it can be, my code i wrote a decade ago in masm still runs faster than my best optimized code in c++ (sigscanner), for small projects it doesn't even matter with todays processors. |
Haha, actually I just want to know how to code as efficiently as possible to develop good habits. But yeah you are right, it doesn't make any real world difference at all.
_________________
Toukiden Kiwami cheat table: forum.cheatengine.org/viewtopic.php?p=5600876#5600876 |
|
Back to top |
|
 |
Zanzer I post too much
Reputation: 126
Joined: 09 Jun 2013 Posts: 3278
|
Posted: Wed Jul 01, 2015 4:33 pm Post subject: |
|
|
You butchered my name!
Here's a little trick to keep your code working even if the offset changes.
Code: | [ENABLE]
aobscan(myaob,44 8B 88 * * * * {more to make this unique})
alloc(newmem,$1000)
alloc(myoffset,4)
alloc(myvar,8)
label(code)
label(return)
myoffset:
readmem(myaob+3,4)
newmem:
mov r9,rax
add r9,dword ptr [myoffset]
mov [myvar],r9
code:
db 44 8B 88
readmem(myaob+3,4)
jmp return
myaob:
jmp newmem
nop
nop
return:
registersymbol(myaob)
registersymbol(myoffset)
registersymbol(myvar)
[DISABLE]
myaob:
db 44 8B 88
readmem(myoffset,4)
unregistersymbol(myaob)
unregistersymbol(myoffset)
unregistersymbol(myvar)
dealloc(newmem)
dealloc(myoffset)
dealloc(myvar) |
|
|
Back to top |
|
 |
Xillica Cheater
Reputation: 1
Joined: 28 Jun 2015 Posts: 45
|
|
Back to top |
|
 |
Zanzer I post too much
Reputation: 126
Joined: 09 Jun 2013 Posts: 3278
|
Posted: Wed Jul 01, 2015 5:11 pm Post subject: |
|
|
Don't feel bad. I didn't even know you could change your name on the forums!
|
|
Back to top |
|
 |
atom0s Moderator
Reputation: 205
Joined: 25 Jan 2006 Posts: 8587 Location: 127.0.0.1
|
Posted: Wed Jul 01, 2015 6:26 pm Post subject: |
|
|
Xillica wrote: | Whoa, Thank you very much atom0s. I'll be sure to note what you said from now on and try to learn with that in mind.
I can understand almost all things you said, but I'm not so sure with these:
Quote: | Once you get used to what things look like it is also best to avoid using things like:
- Stack correction / alignments since they can change in updates.
- Exception filter blocks. |
Stack correction / alignments does this about esp & ebp?
Like this?
push EBP //base pointer for the current stack frame
mov EBP, ESP //points to top of stack?
sub ESP, some_numbers //reserve space on stack
and what are exception filter blocks? What does it looks like in a game code, is that for catching specific instruction or value? |
Yes for the stack correction stuff you posted. You would want to avoid the sub ESP, <number here> part as an update could add or remove an argument from the function call which will alter the adjustment amount to the stack breaking your signature being used.
As for exception filters, in Windows the exception handler frame is stored inside of FS:[0], so you may see code in programs like this:
Code: | 502D1DE0 /$ 55 PUSH EBP ;
502D1DE1 |. 8BEC MOV EBP,ESP
502D1DE3 |. 6A FF PUSH -1
502D1DE5 |. 68 2F412E50 PUSH 502E412F ;
502D1DEA |. 64:A1 0000000 MOV EAX,DWORD PTR FS:[0]
502D1DF0 |. 50 PUSH EAX
502D1DF1 |. 83EC 14 SUB ESP,14
502D1DF4 |. 53 PUSH EBX
502D1DF5 |. 56 PUSH ESI
502D1DF6 |. 57 PUSH EDI
502D1DF7 |. A1 BC6B3250 MOV EAX,DWORD PTR DS:[__security_cookie]
502D1DFC |. 33C5 XOR EAX,EBP
502D1DFE |. 50 PUSH EAX
502D1DFF |. 8D45 F4 LEA EAX,[LOCAL.3] |
This is the start of a function and the first thing you will see is the stack correction and the exception filter being set for the current frame. Stuff like this you will want to avoid using since the try/catch can be removed in an update completely removing that starting chunk of information.
For the offset discussions that people are having here, I would not recommend using them depending on the title / type of game. For single player games, it is not too often that things break or get shifted. For example, think of a player structure like this:
Code: | struct Player
{
unsigned char Health; // + 0 offset
unsigned char MaxHealth; // + 1 offset
unsigned char Mana; // + 2 offset
unsigned char MaxMana; // + 3 offset
float X; // + 4 offset
float Y; // + 8 offset
float Z; // + 12 offset
}; |
So lets say the max health address is being referenced in one version of the game. You may see something like:
Code: | mov eax, [some pointer to our player object]
mov al, byte ptr ds:[eax+00000001] |
Then lets say an update happens and the game changes our Health and MaxHealth to int's instead of unsigned chars cause we can have more health now. That eax+00000001 is now going to be useless and broken for your signature since it will no longer align properly.
Along with that, think about if the game added a new variable before Health. Such as PlayerId. That will shift everything as well making it not align anymore and making any AoB you make useless.
It is something to keep in mind for different games and their update schedules.
In some games where the game is released and never updated or barely ever updated this is not much of a concern. However with how easy it is for game companies to distribute their games and worry about play-testing and fixes afterward, we see a lot more game updates now then before. (For example, on platforms such as Steam, Origin, etc.) Then for online games where updates happen very frequently this is something that you will land up having to do since structure data is not guaranteed to stay put between updates ever.
_________________
- Retired. |
|
Back to top |
|
 |
Zanzer I post too much
Reputation: 126
Joined: 09 Jun 2013 Posts: 3278
|
Posted: Wed Jul 01, 2015 6:41 pm Post subject: |
|
|
That's why I used wildcards for the offset value and saved it separately as a variable.
So no matter what they change it to, my code would grab that new value and add it to the base.
Making "myvar" always point to the health address directly, ignoring the offset.
Yes, in your example, the variable itself is changing from 1-byte to 4-bytes, but that's never likely to happen.
|
|
Back to top |
|
 |
atom0s Moderator
Reputation: 205
Joined: 25 Jan 2006 Posts: 8587 Location: 127.0.0.1
|
Posted: Wed Jul 01, 2015 7:10 pm Post subject: |
|
|
Zanzer wrote: | That's why I used wildcards for the offset value and saved it separately as a variable.
So no matter what they change it to, my code would grab that new value and add it to the base.
Making "myvar" always point to the health address directly, ignoring the offset.
Yes, in your example, the variable itself is changing from 1-byte to 4-bytes, but that's never likely to happen. |
It happens more often then you think especially for games that update regularly with varying content patches, expansions, etc. But the 1 to 4 bytes was just an example of a structure shift that could occur.
_________________
- Retired. |
|
Back to top |
|
 |
Xillica Cheater
Reputation: 1
Joined: 28 Jun 2015 Posts: 45
|
Posted: Wed Jul 01, 2015 11:43 pm Post subject: |
|
|
(^v^)I can't appreciate enough atom0s, I'll be sure keep that in mind when I'm choosing signatures for singleplayer games (I can't move to multiplayer games yet, I need to improve more >_<). Note: reading your replies, always make it clearer and clearer that you are at a whole different level from me related to computers code knowledge lol (which I can never hope to reach, unless I put bloody hard work and real dedication to learn). 'The more you know, the more you know you don't know.' << me in cheatengine forum
Zanzer wrote: | That's why I used wildcards for the offset value and saved it separately as a variable.
So no matter what they change it to, my code would grab that new value and add it to the base.
Making "myvar" always point to the health address directly, ignoring the offset.
Yes, in your example, the variable itself is changing from 1-byte to 4-bytes, but that's never likely to happen. |
Your trick worked for me, I tested in an older version of cracked game and steam release. At least it will work in some singleplayer games (just tested one game only though). But it's a good trick to keep in mind, so thanks again (^ᴗ^).
_________________
Toukiden Kiwami cheat table: forum.cheatengine.org/viewtopic.php?p=5600876#5600876 |
|
Back to top |
|
 |
|
|
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
|
|