View previous topic :: View next topic |
Author |
Message |
LeonBlade How do I cheat?
Reputation: 0
Joined: 25 Jan 2019 Posts: 9
|
Posted: Fri Jan 25, 2019 8:22 am Post subject: 64-bit Function Calling |
|
|
Hello,
I've resisted asking this question on here considering there have been many similar questions asked, many of them saying roughly the same thing. I'll describe my situation and the information I have and have learned while trying to solve my problem.
What am I trying to do?
To put it simply, I'm trying to call a specific function in a created thread most likely. There are a few entries into the function that I have traced back both in Cheat Engine and in IDA.
What do I know?
As it's been stated many times when these questions come up, I should understand calling conventions for 64-bit (which is what my select game is using). I know that specific registers will act as params. I've also looked into the stack as well.
What research have I done?
As stated, I've drilled back through the function I'm trying to call because I know I need to replicate the arguments and even the stack in order to get my desired outcome. However, this is where I'm struggling.
Despite having done many break and traces with full stack view capturing I'm having a hard time fully grasping what I need to replicate. RSP is functioning as the stack pointer in my case. I've noted commonality between a few entries into the function to see what is being passed in and what stays consistent. As expected, a single point of entry has the same register values each time. The alternative paths into the function however have different values with some being the same. Many of these values seem to be pointers to pointers to who knows where and it's hard to follow everything and fully understand what's going on.
Is this normal? I am contemplating triggering the function manually (in game) and just relying on my code injection alone but I would like to be able to trigger this function automatically as well. Debugging also can be a chore considering this is an online game and if I stay on a breakpoint for too long it will just disconnect me which doesn't help.
One point of entry into the function goes back to where a huge chunk of free stack space seems to be allocated but then later on values are pulled from the stack quite a large offset away. This discourages me from trying to emulate the stack because it seems that it will almost be impossible to recreate what's necessary without missing something.
If anyone wants additional information I can provide whatever necessary to better explain my situation.
Thank you.
|
|
Back to top |
|
 |
ParkourPenguin I post too much
Reputation: 152
Joined: 06 Jul 2014 Posts: 4703
|
Posted: Fri Jan 25, 2019 10:42 am Post subject: |
|
|
Are you sure you aligned the stack correctly and provided shadow space for the 4 register parameters? Most people forget that even if they remember some parameters are passed through registers. Also, xmm0-xmm3 are used in place of rcx-r9 respectively as floating point parameters if it's relevant.
I guess you could find a call to that function and break and trace it to see what it's doing. Besides general tips on reverse engineering, I'm not sure what other help you're hoping for.
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
Back to top |
|
 |
Dark Byte Site Admin
Reputation: 470
Joined: 09 May 2003 Posts: 25804 Location: The netherlands
|
Posted: Fri Jan 25, 2019 10:45 am Post subject: |
|
|
The function is most likely a class method
Usually the first parameter passed (rcx in 64 bit) is a pointer to an instance of that specific class
To be able to call that class method you need the pointer to the class instance. It's best to do that from a hook in a function that is more frequently called in that class. (Alternatively, a groupscan for the class instance can work. Often the first pointer is a pointer to a static memory location)
It's recommended to call functions from inside the original thread instead of createthread to prevent threading issues.
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
Back to top |
|
 |
LeonBlade How do I cheat?
Reputation: 0
Joined: 25 Jan 2019 Posts: 9
|
Posted: Fri Jan 25, 2019 5:25 pm Post subject: |
|
|
ParkourPenguin wrote: | Are you sure you aligned the stack correctly and provided shadow space for the 4 register parameters? Most people forget that even if they remember some parameters are passed through registers. Also, xmm0-xmm3 are used in place of rcx-r9 respectively as floating point parameters if it's relevant.
I guess you could find a call to that function and break and trace it to see what it's doing. Besides general tips on reverse engineering, I'm not sure what other help you're hoping for. |
I haven't got to the point where I'm actually calling the function, I'm just trying to figure out how at this point. There are floats used in this function, but I'm not sure they're passed in that way. I have done that, but I'm still a bit lost.
Dark Byte wrote: |
The function is most likely a class method
Usually the first parameter passed (rcx in 64 bit) is a pointer to an instance of that specific class
To be able to call that class method you need the pointer to the class instance. It's best to do that from a hook in a function that is more frequently called in that class. (Alternatively, a groupscan for the class instance can work. Often the first pointer is a pointer to a static memory location)
It's recommended to call functions from inside the original thread instead of createthread to prevent threading issues. |
Okay, that makes a lot of sense. I was considering doing something like that as well; something that can loop and I can just trigger it on with a simple condition. Thank you, I'll see if I can make more sense of it now with this information.
|
|
Back to top |
|
 |
LeonBlade How do I cheat?
Reputation: 0
Joined: 25 Jan 2019 Posts: 9
|
Posted: Sat Jan 26, 2019 9:48 pm Post subject: |
|
|
Just wanted to make a follow up to say I figured out my issue! Thank you Dark Byte for your help!
The RCX being a pointer to a class proved to be true as expected. There are a few of the calls I didn't understand without being able to create a struct for it but it wasn't necessary.
Also understanding this and of course the calling conventions I was able to figure out how the methods were being called.
The thing that made it all come together though was finding a place in the same thread to execute my function call instead of spawning a new thread. I was able to trace back a place that calls my function that runs on a loop. From here I injected my own code where I could then trigger the function myself and after making sure to save and load the registers to restore them back to how they were it worked perfectly!
IDA Pro was invaluable in learning more about these functions so I suggest anyone that can get their hands on it uses it if you're doing work like this as being able to decompile the assembly into pseudo code helps when you're like me with limited assembly information. Even with the free version you can use it to find references to function calls which helps a lot as well.
I'm not sure if this will help many people, but I'm glad that just a simple bit of advice from someone more knowledgeable was able to put things into perspective.
I can't thank you enough.
|
|
Back to top |
|
 |
|