Tutorial How to Call a Game Function

Hexui Undetected CSGO Cheats Sinkicheat PUBG Cheat

Rake

Cesspool Admin
Administrator
Jan 21, 2014
12,073
78,998
2,371
Requirements: Intermediate knowledge of ASM and C++ and the stack, internal access to process

1)Find the address of the function you want to call

Example:
If you want to call the function that does damage to players, you would find your entity address, the enemy's entity address, do a "Find what Accesses This Address" on the enemy's health. Shoot the enemy once. Find the instruction that has only been executed once. This could be the function DoDamage() or it could be a function like DecreaseHealth() that gets called by the DoDamage() function. If it's DecreaseHealth() you will have to trace backwards to the function that calls it. If it's DoDamage() you will want to right click on this instruction in Cheat Engine and click "Select Function". Scroll to the top of the selected function, the top address is the address of your function.

2)Discover the calling convention of the function

You do this by viewing how the arguments are pushed onto the stack or placed in registers by the caller before the function is called and also how they are popped off the stack by either the caller or the callee.

When a function is called the callee creates a new stack frame using EBP and ESP, each function has it's own stack frame which is local storage that the function needs.

Read about stack frames here:
https://en.wikipedia.org/wiki/Call_stack#Structure
https://en.wikibooks.org/wiki/X86_Disassembly/Functions_and_Stack_Frames
https://www.cs.cornell.edu/courses/cs412/2008sp/lectures/lec20.pdf


Example: For the DoDamge() function you would examine the PUSH instructions before the call and breakpoint the first instruction of the DoDamage() function and examine the registers. Find the address of your entity and of the enemy either on the stack or in the registers.

Read up on calling conventions:
https://www.codeproject.com/Articles/1388/Calling-Conventions-Demystified
https://www.codeproject.com/Articles/9457/Inside-Calling-Conventions
https://guidedhacking.com/showthread.php?7302-Calling-Conventions-and-why-you-need-to-know-them

3) Discover the arguments and the argument types

Using IDA is the easiest. If class objects are being passed in you will need to reverse those objects and recreate them in your code. Before your function gets called, you will see arguments get pushed onto the stack, usually in right to left order.
You can use ReClass to create those classes https://guidedhacking.com/showthread.php?7823-Quick-Reclass-Tutorial

4)Recreate the function prototype in your code and create a typedef to it and then call it

Here are some examples:
C++:
//typedef the function prototype
typedef cvar_t*(__cdecl * _Cvar_Get)(const char *var_name, const char *var_value, int flags);

//Create an instance of the function and assign it to an address
_Cvar_Get Cvar_Get = (_Cvar_Get)0x043F688;

//Call it like this
Cvar_Get("cl_gamepath", "OpenArena", 0);

//typedef the function prototype
typedef clipHandle_t(__cdecl *_CM_InlineModel)(int index);

//Create an instance of the function and assign it to an address
_CM_InlineModel CM_InlineModel = (_CM_InlineModel)0x00426a5c;

//Call it like this
CM_InlineModel(5);
mambda was also kind enough to share a shorter way of doing this using the code that Nazalas shared here:
https://guidedhacking.com/showthread.php?7812-Output-to-Assault-Cube-in-game-console

C++:
//multiline method:
typedef void(__cdecl * _contoutf)(const char* string, ...);
_contoutf contoutf = (_contoutf)0x46b060;
contoutf((char*)"Hello");       
 
//one line method:
((void(__cdecl*)(const char* string))0x46b060)("do the shit");
Alternatively if the calling convention is giving you trouble you can just push the variables onto the stack and call the function using inline ASM as I did in this thread:
https://guidedhacking.com/showthread.php?6695-Calling-traceline-with-inline-ASM&highlight=traceline

If you're using the wrong calling convention you will corrupt the stack and the game will crash. Sometimes I try all the calling convention until one works hehe :EleGiggle:

Please reply if you have something to add to this article!
 

MegaByte

Newbie
Full Member
May 11, 2016
37
2,323
2
Cheers,

Additionally if you just want to call a game function using Cheat engine to try out your idea.

You can use a script like so.

C++:
[enable]
alloc(MyCode,1024)
CreateThread(MyCode)

MyCode:
// As Example
//CALL SomeGameAddress
// or do other code
ret // exit thread

[disable]
dealloc(mycode)
https://blog.extendedgames.com/2012/09/cheat-engine-call-game-code-in-new.html

Obviously this is from a new thread so look out if the code is not thread safe.

You might be able to improve this by putting it in a try catch/critical section I think it is called?
So that the game does not crash outright if you screw something up... Im not sure.

Best of luck.
 

PwndDepot

I has a status
Dank Tier VIP
Trump Tier Donator
Dank Tier Donator
Nov 5, 2014
239
7,748
19
Something I noticed with the cheat engine "select function" utility the other day is it only selected up to the first found "return" instruction, and not the actual start of the stack frame (push epb then mov ebp, esp). At least for assaultcube's dodamage or decreasehealth function or whatever, thats what I tested it on.
 

Rake

Cesspool Admin
Administrator
Jan 21, 2014
12,073
78,998
2,371
yeah I guess that fucker doesn't always work perfecto :(
 

Yasiin

Newbie
Dec 29, 2017
4
254
0
Quick question, is it necessary to have to use a typedef? Also could you explain why? I'm a tad bit braindead compared to everyone. :V
 

Teuvin

now I am become Death
Dank Tier VIP
Trump Tier Donator
Dec 8, 2016
403
10,388
65
Quick question, is it necessary to have to use a typedef? Also could you explain why? I'm a tad bit braindead compared to everyone. :V
Directly from the cppreference.com
typedef - creates an alias that can be used anywhere in place of a (possibly complex) type name.
Typedef allows you to cast an address to the function prototype and allows you to call it.
 

Rake

Cesspool Admin
Administrator
Jan 21, 2014
12,073
78,998
2,371
Quick question, is it necessary to have to use a typedef? Also could you explain why? I'm a tad bit braindead compared to everyone. :V
In the post you just replied to it is shown that you can do it without a typedef :)
C++:
((void(__cdecl*)(const char* string))0x46b060)("do the shit");
 

baka

Full Member
Apr 24, 2018
7
24
0
Thanks, great tutorial!
But there's one thing I don't understand about the typedefs: what does "cvar_t" and "clipHandle_t" at the beginning of the typedef do?
 

Rake

Cesspool Admin
Administrator
Jan 21, 2014
12,073
78,998
2,371
Thanks, great tutorial!
But there's one thing I don't understand about the typedefs: what does "cvar_t" and "clipHandle_t" at the beginning of the typedef do?
It's the return type of the function
 

Rake

Cesspool Admin
Administrator
Jan 21, 2014
12,073
78,998
2,371
I don't quite understand. What's the difference between the two and does it matter what you name them?
Functions have return values and types. functions that are declared as void have no return.

"int DoStuff()" for instance returns an integer. In the case of the original post, cvar_t* and clipHandle_t are the return types of the functions.

Lemme break it down for you a bit
C++:
typedef clipHandle_t(__cdecl *_CM_InlineModel)(int index);
typedef = this is a typedef
clidHandle_t = return type of the function
__cdecl * = function pointer of type cdecl
_CM_InlineModel = name of the function (you give it whatever name you want here)
(int index) = the argument to the function, in this case there is only one

If this is too hard for you learn more C++
 
Last edited:

baka

Full Member
Apr 24, 2018
7
24
0
Functions have return values and types. functions that are declared as void have no return.

"int DoStuff()" for instance returns an integer. In the case of the original post, cvar_t* and clipHandle_t are the return types of the functions.

Lemme break it down for you a bit
C++:
typedef clipHandle_t(__cdecl *_CM_InlineModel)(int index);
typedef = this is a typedef
clidHandle_t = return type of the function
__cdecl * = function pointer of type cdecl
_CM_InlineModel = name of the function (you give it whatever name you want here)
(int index) = the argument to the function, in this case there is only one

If this is too hard for you learn more C++
I still don't understand what type clipHandle_t is. Are you defining that yourself? If it's a handle, can't you just do typedef HANDLE(...) (...)
 

Rake

Cesspool Admin
Administrator
Jan 21, 2014
12,073
78,998
2,371
I still don't understand what type clipHandle_t is. Are you defining that yourself? If it's a handle, can't you just do typedef HANDLE(...) (...)
It's just an example
 

Rake

Cesspool Admin
Administrator
Jan 21, 2014
12,073
78,998
2,371
Oh, so it does it matter what return type you set it to? If so, how do you know which return type to use
You reverse engineering the function. This thread has info on it and we have a "how to call game functions" 3 part video tutorial in the GH video tutorial section
 

Traxin

Escobar Tier VIP
Dank Tier Donator
Aug 3, 2015
1,041
25,378
154
Oh, so it does it matter what return type you set it to? If so, how do you know which return type to use
You don't necessarily need to figure out exactly what the return type is depending on what you're using it for.

For example, if the function returns a pointer to an object but you don't need access to any of its members then you can just say the function returns a void* in your hack. Hell, you can say the function returns an int if you're working on a 32bit game because ints are the same size as pointers on 32bit. As long as the size of each data type expected in the signature is the same in your typedef you should be fine.

I feel like that last sentence may cause more confusion then anything else so here's a quick little code example...
C++:
//Lets say we have this function here.
CEntity* GetLocalPlayer();

//in our hack, typedef your function pointer, assuming you have a class called CEntity in your hack
typedef CEntity*(__cdecl * _GetLocalPlayer)(void);

//Otherwise, you can simply just say it's a void*
typedef void*(__cdecl * _GetLocalPlayer)(void);

//and to prove a point, if this is a 32bit game you can even do this and it'll still work because the return type is still of the same size
typedef int(__cdecl * _GetLocalPlayer)(void);
 
Attention! Before you post:

Read the How to Ask Questions Guide
99% of questions are answered in the Beginner's Guide, do it before asking a question.

No Hack Requests. Post in the correct section.  Search the forum first. Read the rules.

How to make a good post:

  • Fill out the form correctly
  • Tell us the game name & coding language
  • Post everything we need to know to help you
  • Ask specific questions, be descriptive
  • Post errors, line numbers & screenshots
  • Post code snippets using code tags
  • If it's a large project, zip it up and attach it

If you do not comply, your post may be deleted.  We want to help, please make a good post and we will do our best to help you.

Community Mods