Any secrets, Tips, etc. for finding GOOD/Unique values in stack to use for compares?

G

gideon25

Expert Cheater
Table Maker
Joined
Mar 20, 2017
Messages
438
So I am making a table for a game maker game so I am going to use the stack for some compares. I found a great tutorial on youtube by Stephen Chapman about it.

Anyway initially I had lots of problem with crashes but once I decided to just start testing the stack filter/compare BEFORE changing anything, that helped :p. It was on an instruction that accessed around a thousand or so values. So I needed a compare for resources for the game (4 values) so I found one that really looked unique and was shared by my 4 values..I even checked several other addresses (but not all obviously there were 1000 of them) and so I thought I have it! Well no, after activating the script and checking what addresses it accessed after the compare there were still 30 of them. So I tried again, finding another one I thought was unique and checked MOST of the other values. Nope, it effected 5 values, 1 extra value than I needed. So finally I find another one shared among the 4 and I finally have it. The code looks like this:

newmem:
movsd xmm0,[esp+10]
push ecx
mov ecx,[ebp+80]
pushf
cmp ecx,1
jne code
mov ecx,[ebp+C]
cmp ecx,2
jne code
mov ecx,[ebp+18]
cmp ecx,1
jne code
popf
movsd xmm0,[resource]
movsd [esi],xmm0
pop ecx
jmp return

code:
popf
pop ecx
movsd xmm0,[esp+10]
movsd [esi],xmm0
jmp return

resource:
dq (double)5000


Anyway I was wondering if there was a better way? I mean how can you guys tell its not shared by the other addresses? Any secrets, tips, etc or is it all trial and error or by whittling down using multiple compares like I had to. Or is it just because it was a game maker game? Thanks!
 
Dread_Pony_Roberts

Dread_Pony_Roberts

Code Cracker
Table Maker
Joined
Dec 9, 2018
Messages
231
If had to use this harder method, I would use the commonalities function as demonstrated in this video.
https://www.youtube.com/watch?v=-jBmeWXndKA

However, there does exist an easier method which I have used in my more recent tables.

Open the Dissect data/structures with the address you want to compare out. Add the top address to your table. Find what access that address. With any luck you would have some (or lots) of code constantly addressing that address. After you stopped scanning, go through each code in search of one which only accesses your address. If you find one then you are in luck, as they are generally very stable. If you don't find any constantly addressing that address, then you can try other addresses on the dissect data/structures list in case you have better luck with them.

To use it in your compares, you will want to write something like this.
Code:
<i>
</i>  //assume esi holds your base address

alloc(base,4)
registersymbol(base)

label(code)
label(return)

newmem:
  mov [base],eax
code:
  mov ecx,[eax+72]
  jmp return
  
  //remember to dealloc and unregistersymbol as well
You would want this code as an activator, as your actual code won't work unless this is active.

Now the original code would look something like this.
Code:
<i>
</i>//play around with the code as needed

newmem:
movsd xmm0,[esp+10]
push ecx
pushf
cmp [base],esi
jne code
popf
movsd xmm0,[resource]
movsd [esi],xmm0
pop ecx
jmp return

code:
popf
pop ecx
//movsd xmm0,[esp+10]      I'm leaving this deleted because (from what little I see) it seems like this could cause issues if left in
movsd [esi],xmm0
jmp return
 
SunBeam

SunBeam

Administrator
Staff member
Administrator
Joined
Feb 4, 2018
Messages
3,496
^ I really recommend tracing your code or doing back-tracing. Why? Because more than often I found myself in the scenario where, later on in the game or through some action I've not tested at the time of coding, there were OTHER functions calling the function I hooked. As such, what you see in your stack at [esp+10] might never be there when that action occurs. Furthermore, depending on what you do with [esp+10], your game might inexplicably crash. Then you will wonder why, cuz your code is "perfect". Then spend hours not realizing that your function with the hook MIGHT BE CALLED from other places.

So.. while in theory whatever's been said in this topic works.. please do your due diligence and thoroughly CHECK that your hook and stack are not hit from other unknown places to you. That you test not only what meets the immediate eye.

BR,
Sun
 
Rysefox

Rysefox

Expert Cheater
Table Maker
Joined
Jun 23, 2018
Messages
826
anonmalia said:
Sorry if it's the same question, but..

I have an instruction that accesses too many values and I need to use cmp to change only what I want to. So I'd use that 'dissect data/structures'.. doing this I'LL have the list of it.. the question is: how can I find 'unique' number to cmp? And is that possible?
CODE: SELECT ALL

ucomisd xmm6,[rbx+28] //inside the instruction said
CODE: SELECT ALL

0174 - 4 Bytes 275B4114 : 4294967295 275B3D04 : 0 275B3BC4 : 1082081280 275B3F84 : 0 //in this case the 1st one, 2nd one, 3rd one and 4th are about money, knowledge points, level and level experience
So I have 4294967295 as number to cmp to change only money, but when I cmp that money doesn't change.. just like code below.
CODE: SELECT ALL

cmp [rbx+174],#4294967295 //it's 4bytes so should I use #, none or dword ptr?
jne code
addsd xmm6,xmm0
movsd [rbx+28],xmm6
(When define new structure.. should I use 4096, less or more?)

Well I think finding some number to cmp is hard cos when I find some offset that I see the 1st one is 1 and 2nd one is 0.. some times the 2nd one turns into 1 both values (ingame) will change.
Maybe try:
Code:
<i>
</i>
[ENABLE]
your stuff 

alloc(ammo,8)

ammo:
dq (double)999

newmem:
cmp [rbx+174],#4294967295
jne code
fld qword ptr [ammo]
fstp qword ptr [rbx+174]
jmp return

code:
your code

....
 
G

gideon25

Expert Cheater
Table Maker
Joined
Mar 20, 2017
Messages
438
SunBeam said:
^ I really recommend tracing your code or doing back-tracing. Why? Because more than often I found myself in the scenario where, later on in the game or through some action I've not tested at the time of coding, there were OTHER functions calling the function I hooked. As such, what you see in your stack at [esp+10] might never be there when that action occurs. Furthermore, depending on what you do with [esp+10], your game might inexplicably crash. Then you will wonder why, cuz your code is "perfect". Then spend hours not realizing that your function with the hook MIGHT BE CALLED from other places.

So.. while in theory whatever's been said in this topic works.. please do your due diligence and thoroughly CHECK that your hook and stack are not hit from other unknown places to you. That you test not only what meets the immediate eye.

BR,
Sun
Back tracing can help until its gets a little too complicated for pseudo-beginners like me. Take this thread:
https://fearlessrevolution.com/viewtopic.php?f=15&t=11748

Where cfemen talks about back tracing ALL the way back to a function that ONLY addresses, say money for instance. Pretty complicated. I would LOVE to see a video tutorial that talks about backtracing values when you get a game that only uses VCRuntime for instance for all its stuff or a game only uses ONE function for thousands (or ALL of its values) and see someone back trace the hell out of it, all the way back to unique functions for various values, explaining various concepts as he does it. As far as I can tell no such video exists! All I have seen are VERY simple videos where someone will only backtrace on a very simple game and the back tracing is extremely minimal and unsophisticated.

Anyway if anyone knows of such a video please post it here! Thanks!
 
G

gideon25

Expert Cheater
Table Maker
Joined
Mar 20, 2017
Messages
438
anonmalia said:
@Dread_Pony_Roberts thank you so much for you time sharing that video.
There are LOTS of ways to approach compares for shared instructions:
Have you looked at stephen chapmans videos on structure compares and registers for shared instructions?
Here he demonstrates data structure compares:
https://www.youtube.com/watch?v=qoKVUP7SPAA
Here he demonstrates using the registers to compare:
https://www.youtube.com/watch?v=O5tUj6A0lL0
this is the one on how to hack game master games using the stack for compares (which was what I was talking about in my first post):
https://www.youtube.com/watch?v=5fJFSOPGZyQ
Anyway those might help.

UNFORTUNATELY there is a serious lack of tutorial videos on complex back tracing on difficult games. Its all back trace once or twice on a simple game or backtrace once and get lucky, etc. I would love to see some back tracing videos where someone back traces multiple steps all the way to several unique instructions off of say a UE4 game that runs everything thru VcRuntime for instance like was described here:
https://fearlessrevolution.com/viewtopic.php?f=15&t=11748
 
G

gideon25

Expert Cheater
Table Maker
Joined
Mar 20, 2017
Messages
438
Dread_Pony_Roberts said:
However, there does exist an easier method which I have used in my more recent tables.

Open the Dissect data/structures with the address you want to compare out. Add the top address to your table. Find what access that address. With any luck you would have some (or lots) of code constantly addressing that address. After you stopped scanning, go through each code in search of one which only accesses your address. If you find one then you are in luck, as they are generally very stable. If you don't find any constantly addressing that address, then you can try other addresses on the dissect data/structures list in case you have better luck with them.
Yea, unfortunately lately been running into lots of games that run all of its values thru only one opcode. I do a little backtracing then use a combination of compares on the registers at the time of break to whittle down the results, look at whats still shared and THEN use the data structures on whats left .. But I really need better back tracing skills :(

Heres one I did recently on Superlife (rpg) that was UE4 and ran everything thru one opcode in VCRuntime Memcopy. I did a conditional break and trace on the instruction (which was moving RDX) in VCRuntime with my address for XP to get to the actual call in the game memory. So I know that R8 is what gets moved into rdx vcruntime. So I traced back to the call in the actual game memory and then did a conditional break and trace a few instructions up on R8 with my address I found for experience. I then looked at the registers and started the comparing. So I do the registers that don't have any addresses, only values in them first. STILL to many adresses shared. So I know by looking at the structure for experience (R8 is experience). I found all kinds of other things, like energy, time of day, money, etc. NEAR the experience. I also knew that energy is ALWAYS between 0 and 10 and time of day is ALWAYS between 1 and 24. So after those additional compares I only had like 5 addresses left and I just used a structure compare for those 5. See here:

newmem:
pushf
cmp rbx,0
jne code
cmp rdx,4
jne code
cmp r12,0
jne code
cmp [r8+14],#0 //energy range
jl code
cmp [r8+14],#11 //energy range
jge code
cmp [r8+10],#1 //hours left in day range
jl code
cmp [r8+10],#24 //hours left in day range
jg code
cmp [r8+E4],#128 //Compare whats left
jne code
popf
mov [xp],r8
mov rax,[rcx]
mov rdx,r9
jmp return

code:
popf
mov rax,[rcx]
mov rdx,r9
jmp return


Being a better back tracer is what I am eventually hoping to become though!
 
SunBeam

SunBeam

Administrator
Staff member
Administrator
Joined
Feb 4, 2018
Messages
3,496
Like I said, you want some solid logic. If you want, you can get IDA, open you .exe in IDA, then let it finish the analysis. Then go to your function and see how many xrefs are to it (assuming it's not a dynamic function, called in the fashion "call qword ptr [rax+D0]"). Based on that you can tell which other places are going to call the function you're about to hook. Thus obtain a better certainty that, if the function is called from a different location than expected, your stack will look good and the [esp+offset] will always contain what you're looking for.

On the other hand, it's not always registers comparing. Have you ever checked out what the ADDRESS in the register contains? Most, if not all, functions are called with parameters.

In C++ world an example would be DealDamage( Character, amount ).

In x86 ASM that would be:

push amount //+8 to esp
push Character //+8 to esp
call DoDamage //+8 to esp when looked at from inside the function

In x64 ASM that would be:

mov rdx,amount //2nd param
mov rcx,Character // 1st param
call DoDamage

So in x86 your "Character" structure (thus an address) will be in [esp+8]. Amount is in [esp+10].

In the x64 version, your "Character" structure (the address) will be in RCX. The amount in RDX.

So rather than discussing shit from 2000+ when people still flaunted these "compare registers" crap, please pull yourselves together and learn how a function is structured and called. The calling conventions. You can then later on devise "comparison" approaches.

Right now you're just mumbling and creating convoluted code that, while it's working and you're feeling self-sufficient, it's nowhere close to the programming logic of how these games were conceived. If you're happy it works and can't be bothered to learn more, then so be it.

Code:
<i>
</i>newmem:
pushf
cmp rbx,0
jne code
cmp rdx,4
jne code
cmp r12,0
jne code
cmp [r8+14],#0 //energy range
jl code
cmp [r8+14],#11 //energy range
jge code
cmp [r8+10],#1 //hours left in day range
jl code
cmp [r8+10],#24 //hours left in day range
jg code
cmp [r8+E4],#128 //Compare whats left
jne code
popf
mov [xp],r8
mov rax,[rcx]
mov rdx,r9
jmp return

code:
popf
mov rax,[rcx]
mov rdx,r9
jmp return
What if r8 is 0? Are you checking that anywhere? Cuz "cmp [r8+14]" will result in a big ass crash. Please don't say "yeah, but I know r8 is valid there, cuz I debugged the code". If so, then please read again what I said 2 posts back and the beginning of this post. I really doubt you've thoroughly tested all possibilities of your code being used by OTHER callers. So.. while r8 now is valid, there may be a loading screen in which your hook is ran and r8 is 0. Then you'll waste several more hours not understanding why it crashes, when you could've done this:

test r8,r8
je exit // if 0
Code:
<i>
</i>newmem:
pushf
cmp rbx,0
jne code
  cmp rdx,4
  jne code
    cmp r12,0
    jne code
      test r8,r8
      je code
      cmp [r8+14],#0 //energy range
      jl code
        cmp [r8+14],#11 //energy range
        jge code
          cmp [r8+10],#1 //hours left in day range
          jl code
            cmp [r8+10],#24 //hours left in day range
            jg code
              cmp [r8+E4],#128 //Compare whats left
              jne code
@@:
popf
mov [xp],r8
mov rax,[rcx]
mov rdx,r9
jmp return

code:
popf
mov rax,[rcx]
mov rdx,r9
jmp return
BR,
Sun
 
kantoboy69

kantoboy69

Expert Cheater
Table Maker
Joined
Aug 30, 2019
Messages
90
Try to find the code that is executed when you trigger something once that uses that code.

e.g.
function code for playerAttack will call function code decreaseHP

you're modifying from decreaseHP and you can backtrace the function code of playerAttack (in theory)
so I'll set an aa script on that first function code playerAttack and will registerasymbol isAttack and set it with value of 1 whenever it is called
then another aa script for decreaseHP code that will check registerasymbol isAttack if 1 or 0
if 1 then it was called by func backtrace code then set isAttack to 0 and do your thing
so if another function call decreaseHP like enemyAttack then isAttack is always 0

This way you don't have to rely on registers and stack too much

This what I did with xenonauts 2, finding the address for the quantity in the store list.
I trigger it when selling item. Back trace to that part and created registered symbol isFetchSellItem
To know that the value I need from get_value is when I click sell item
https://fearlessrevolution.com/viewtopic.php?f=15&t=12308#p134819
 
Top