Raised This Month: $32 Target: $400
 8% 

Hooking BaseEntity Functions in CSGO


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
spidershift
Member
Join Date: Oct 2014
Old 10-21-2014 , 13:13   Hooking BaseEntity Functions in CSGO
Reply With Quote #1

Hello, I'm new to MM:S and have been reading almost everything I can find over the past 3-4 days, but haven't been really getting anywhere. I've been trying for the life of me to hook a few things in BaseEntity and cannot get my plugin to compile at all.

I'm trying to start with the following:

PHP Code:
SH_DECL_HOOK1_void(CBaseEntityFireBulletsSH_NOATTRIB0, const FireBulletsInfo_t &); 
And I can't even get that one basic thing to compile, because I can't figure out what includes I require. I've tried including baseentity.h without any luck, so I must have some kind of misunderstanding of how to make this work. None of the errors being reported by VS2013 are of any help, and just like to complain about the syntax, such as suggesting that that line needs a type identifier.

After finding out on the first day that the standard MM:S download doesn't even include a CSGO option in the sample and stub, and finding the one on GitHub, I was finally able to get the stub to compile with CSGO, but that's about as far as I've gotten.

All the example plugins I find are only using basic ServerGame hooks and don't require any special includes. Plus most of the plugins I find to look at the source code to gain a better understanding of things are usually all obsolete and have broken links. It's becoming quite difficult to get started with all this, so I was hoping someone could help me understand what I'm supposed to do to hook the functions in the BaseEntity class or certain classes that derive from it. Any help is greatly appreciated. Thanks.
spidershift is offline
psychonic

BAFFLED
Join Date: May 2008
Old 10-21-2014 , 14:14   Re: Hooking BaseEntity Functions in CSGO
Reply With Quote #2

You'll want to use manual hooks for those functions and either hardcode or put the offset of the function in a config file. In general, any header outside of public/ should not be included. They're already out of date for most games and change too often anyway. SourceMod's SDKTools extension has a not-too-convoluted example of this in its hooks.cpp. (or the SDKHooks extension almost entirely consists of manual hooks but is a bit of a mess).

On that note, CS:GO (and most other games) don't actually call the virtual FireBullets, but rather have a different, game-specific implementation.

Last edited by psychonic; 10-21-2014 at 14:15.
psychonic is offline
spidershift
Member
Join Date: Oct 2014
Old 10-21-2014 , 16:07   Re: Hooking BaseEntity Functions in CSGO
Reply With Quote #3

Thank you for your help psychonic. I appreciate the quick response. That would explain why I couldn't find the proper header information in /public. The example in hooks.cpp is also very straightforward as you said, so that should help me gain a better understanding of manual hooks.

Now with that, since CSGO doesn't make use of FireBullets() and has its own specific implementation, do you know if it's possible to find out what that is and to hook that function? Do I need to get a certain offset within CSSPlayer or something of that nature? Is there any way to manually alter a bullet's origin and direction before any ray casting is performed?

In the mean time, I'll start to familiarize myself with working with offsets and storing them in a config file. If I run into any trouble with that I'll let you know. Thanks again.

Last edited by spidershift; 10-21-2014 at 16:23.
spidershift is offline
psychonic

BAFFLED
Join Date: May 2008
Old 10-21-2014 , 18:08   Re: Hooking BaseEntity Functions in CSGO
Reply With Quote #4

I don't remember the name of the CS:GO function offhand, it might have just been CCSPlayer::CSFireBullets or something similar. Regardless, I'm fairly certain that it was not virtual, and thus would not be able to be hooked with SourceHook. You could however detour it, such as with something similar to SM's CDetour (although it would need some adjustments to work outside of an SM extension).
psychonic is offline
spidershift
Member
Join Date: Oct 2014
Old 10-22-2014 , 08:42   Re: Hooking BaseEntity Functions in CSGO
Reply With Quote #5

So after spending the entire night dusting off the cobwebs of my C++ and trying to understand how detours work, I'm very ashamed to say that this is all a little over my head. Hooking virtual functions with SourceHook is one thing (especially when there are quite a few examples out there), but trying to gain a strong understanding of how detours work didn't really get me too far.

Many of the examples I found in my search were VSPs (I think), and I have absolutely no idea how I would go about obtaining a list of all the non-virtual functions on CCSPlayer and obtaining signatures for the ones I'm interested in detouring. This is what I get for working mostly with C# and JavaScript over the past few years at my job. Would you be able to point me in the direction of a resource that could explain how one goes about obtaining signatures? I saw the big signature thread in this forum where one of the posters said he was going to provide a tutorial, but I never ended up seeing him post one. This is obviously a skill a need to acquire if I plan on updating my signatures whenever Valve decides to break them with their updates.

Finally, I hate to ask but do you think you could help me get started with an example for what I'm trying to accomplish with this detour? I couldn't even really find any MM:S documentation regarding detours, and for someone just starting out with MM:S such as myself, I doubt even if I tried working more on this the next couple of nights that I'd even have the ability to formulate a detour.

I already have a majority of what I'm looking to accomplish with my plugin ready to go, but unfortunately, I need to alter the origin and direction properties of the parameter of type FireBulletsInfo_t, if that's even what CSGO uses for their custom implementation of FireBullets(). I'm looking for the detour to call the original function, but with my new parameter for FireBulletsInfo_t. It's just very disheartening and frustrating to have all this math and code put together and not having the ability to test anything outside of drawing some lasers using TE_SetupBeamPoints() in a small SourceMod plugin that I used to test with.

Thanks again for all your help and guidance.
spidershift is offline
kadet.89
Veteran Member
Join Date: Nov 2012
Location: Serbia
Old 10-23-2014 , 13:38   Re: Hooking BaseEntity Functions in CSGO
Reply With Quote #6

https://forums.alliedmods.net/showthread.php?t=159876 - a very simple example. Just try to add in this extension another hook (grenade spawn for example). Final result you can find on the third page

This video explains how to find signatures:
http://www.twitch.tv/prodigysim/c/2536037
Only don't forget to change these options in IDA:
1) Options -> General -> Dissasembly -> Number of opcode bytes ->8 (it replaces hex editor)
2) Options -> General -> Cross-references -> Number of displayed xrefs-> 20

You can find all the functions by name in the CTRL+L menu:
CBaseEntity::FireBullets(FireBulletsInfo_t const&) 00522730 (virtual !!!)

Last edited by kadet.89; 10-25-2014 at 08:15.
kadet.89 is offline
Send a message via Skype™ to kadet.89
spidershift
Member
Join Date: Oct 2014
Old 10-24-2014 , 14:44   Re: Hooking BaseEntity Functions in CSGO
Reply With Quote #7

Thank you, thank you, thank you!

That's exactly the kind of example I was looking for! I haven't had the chance to try it out myself yet but I familiarized myself with the source code, how they're putting together the SourceMod extension, and most importantly, a solid and simple real-world example of some detour code.

I haven't had the chance to try it out myself yet because I spent the entire night watching that video a couple times and it is amazing. It's very detailed on how to create well formulated windows signatures. He even explains in detail how he compares the linux binary to the windows binary, and his process for wildcarding as well.

Again, thank you so much! I will be sure to post again if I run into any trouble but based on everything I went over last night, I'm very excited to put this all together!
spidershift is offline
spidershift
Member
Join Date: Oct 2014
Old 10-27-2014 , 14:12   Re: Hooking BaseEntity Functions in CSGO
Reply With Quote #8

So I appear to be stuck while trying to get this detour to work. Here is my game data:

PHP Code:
"Games"
{
    
"csgo"
    
{
        
"Signatures"
        
{
            
"FireBullet"
            
{
                
"library"        "server"
                "windows"        "\x53\x8B\xDC\x83\xEC\x08\x83\xE4\xF0\x83\xC4\x04\x55\x8B\x6B\x04\x89\x6C\x24\x04\x8B\xEC\x81\xEC\x2A\x05\x00\x00\x66\x0F\x6E\x43\x24"
                "linux"            "@_ZN9CCSPlayer10FireBulletE6"
            
}
            
"FX_FireBullets"
            
{
                
"library"        "server"
                "windows"        "\x55\x8B\xEC\x83\xE4\xF8\x81\xEC\xC0\x01\x00\x00\x89\x54\x24\x08"
                "linux"            "@_Z14FX_FireBulletsitRK6"
            
}
        }
    }

I was able to construct the FX_FireBullets() signature on my own, but someone had to help me create the signature for CCSPlayer::FireBullet() because I could not seem to get it. Here are the detours that I'm working with:

PHP Code:
DETOUR_DECL_MEMBER12(DetourFireBulletvoidVectora1QAngle const &, a2floata3floata4inta5inta6inta7floata8CBaseEntity *, a9boola10floata11floata12)
{
    
//int client = gamehelpers->EntityToBCompatRef(reinterpret_cast<CBaseEntity *>(this));

    //cell_t result = Pl_Continue;
    //g_pFireBullet->PushCell(client);
    //g_pFireBullet->Execute(&result);
    
    //DETOUR_MEMBER_CALL(DetourFireBullet)(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12);

    
return;
}
DETOUR_DECL_STATIC12(DetourFXFireBulletsvoidinta1unsigned shorta2Vector  const&, a3QAngle  const&, a4CSWeaponIDa5inta6inta7floata8floata9floata10floata11WeaponSound_ta12)
{
    
cell_t result Pl_Continue;
    
g_pFireBullet->PushCell(0);
    
g_pFireBullet->Execute(&result);

    
//DETOUR_STATIC_CALL(DetourFXFireBullets)(a1, a2, Vector(0, 0, 0), QAngle(0, 0, 0), a5, a6, a7, a8, a9, a10, a11, a12);

    
return;

Even with everything commented out, the detour for CCSPlayer::FireBullet() crashes when called. I get the following error:

Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.

The detour for FX_FireBullets(), which is the only function that references CCSPlayer::FireBullet(), works fine, except if I uncomment the static call. It crashes the server as well, but doesn't give me any error information. Also, with the static call commented out, it still appears that the original FX_FireBullets() is being called, which was not the behavior I was expecting.

Any help moving forward on this is greatly appreciated. Thanks.
spidershift is offline
kadet.89
Veteran Member
Join Date: Nov 2012
Location: Serbia
Old 10-28-2014 , 04:25   Re: Hooking BaseEntity Functions in CSGO
Reply With Quote #9

Is this prototype correct? As I can see here -> https://developer.valvesoftware.com/...ulated_Bullets
this function accepts only one parameter:
void CBaseEntity::FireBullets( const FireBulletsInfo_t &info ),
it's not the same thing as CCSPlayer, but maybe it'll be enough for you to hook this function

Last edited by kadet.89; 10-28-2014 at 04:31.
kadet.89 is offline
Send a message via Skype™ to kadet.89
donrevan
AlliedModders Donor
Join Date: Jul 2010
Old 10-28-2014 , 11:04   Re: Hooking BaseEntity Functions in CSGO
Reply With Quote #10

Quote:
Originally Posted by kadet.89 View Post
Is this prototype correct? As I can see here -> https://developer.valvesoftware.com/...ulated_Bullets
this function accepts only one parameter:
void CBaseEntity::FireBullets( const FireBulletsInfo_t &info ),
it's not the same thing as CCSPlayer, but maybe it'll be enough for you to hook this function
He's not hooking CBaseEntity::FireBullets.

CCSPlayer::FireBullet is called from FX_FireBullet.
I took a quick look at the disasm and was pretty baffled because FX_FireBullet looked like a __thiscall at first but it seems it's just LTCG that is passing iPlayerIndex trough ecx and 'definition index'(a econ thing) trough edx. Just like a MS fastcall..

I haven't tested this hackery:
PHP Code:
// Actual prototype:
//void __fastcall FX_FireBullets(int iPlayerIndex, ushort defIdx, Vector   const&, QAngle const&, CSWeaponID weaponId, int, int, float, float,   float, float, WeaponSound_t)

DETOUR_DECL_STATIC10(DetourFXFireBulletsvoidVector  const&, a3QAngle  const&, a4CSWeaponIDa5inta6inta7floata8floata9floata10floata11WeaponSound_ta12)
{
    
// get all params
    
int iPlayerId;
    
__asm mov iPlayerIdecx
    int definitionIndex
;
    
__asm mov definitionIndexedx

    cell_t result 
Pl_Continue;
    
g_pFireBullet->PushCell(0);
    
g_pFireBullet->Execute(&result);

    
// set params, call original
    
__asm mov ecxiPlayerId
    __asm mov edx
definitionIndex
    DETOUR_STATIC_CALL
(DetourFXFireBullets)(Vector(000), QAngle(000), a5a6a7a8a9a10a11a12);


Last edited by donrevan; 10-28-2014 at 18:21.
donrevan is offline
Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 18:23.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode