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

Using Game DLL Functions Safely


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
showdax
Senior Member
Join Date: Dec 2004
Old 12-07-2005 , 02:23   Using Game DLL Functions Safely
Reply With Quote #1

I think the following would be a better way to use DLL-related functions like things in CBaseEntity.

First, a forward declaration:
Code:
class CBasePlayer;
A handy typedef for casting a void pointer to our function pointer:
Code:
typedef void (*ShowViewPortPanel_Function)(CBasePlayer *, char const *, bool, KeyValues *);
The global variable for the function pointer:
Code:
void (*ShowViewPortPanel)(CBasePlayer *, char const *, bool, KeyValues *) = NULL;
And then we find the memory address to the function (signature scanning):
Code:
ShowViewPortPanel = (ShowViewPortPanel_Function) someScanFunctionThatReturnsAVoidPointer();
And finally:
Code:
CBasePlayer *player = (CBasePlayer *) entity->GetUnknown()->GetBaseEntity();

if (player)
{
	ShowViewPortPanel(player, "info", shown, panel);
}
This works fine for me under Linux. According to BAILOPAN, it isn't as simple as giving member function pointers the instance as the first argument under Windows. I think all plugins that use these kinds of functions should use a method like this, with it gracefully disabling commands when it can't find functions.

But then you have things like inline functions which access member variables (like CBaseEntity::AddEFlags) and then you're fucked. For this I was thinking of reverse-engineering the current CBaseEntity/whatever definitions from what's in the CS:S and DOD:S binaries. Then the plugin would have a cvar that enables or disables functionality that uses member variables so one can avoid crashes when Valve updates it again.

The only thing is I'm not really sure how classes are defined in ELF or PE binaries. We'd really only need a definition for the member variables, but I don't know where to start.
showdax is offline
Send a message via MSN to showdax
showdax
Senior Member
Join Date: Dec 2004
Old 12-13-2005 , 02:22  
Reply With Quote #2

Well, I'm kind of surprised no one has said anything about this, though I guess it's not that amazing. My little admin plugin does all of the following now:
Code:
"admin_slay"
 - <name> - Slays specified player(s)
"admin_slap"
 - <name> [amount] - Slaps specified player(s)
"admin_teleport"
 - <name> <x> <y> <z> - Teleports specified player(s)
"admin_model"
 - <name> <model> - Sets model of specified player(s)
"admin_freeze"
 - <name> <1/0/on/off> - Freezes or unfreezes specified player(s)
"admin_speedy"
 - <name> <1/0/on/off> - Possibly makes player(s) run faster
"admin_noclip"
 - <name> <1/0/on/off> - Enables or disables noclip for specified player(s)
"admin_url"
 - <name> <url> [hidden: 0/1] - Opens MOTD to specified URL for specified player(s)
"admin_item"
 - <name> <item> - Gives item to specified player(s)
"admin_spawn"
 - <name> - Respawns specified player(s)
And it works in CS:S, DOD:S and HL2:DM! I'm not even including baseentity.h or player.h, I just have those forward declarations.

I'm wanting to implement god-mode and weapon restrictions now though, but I'm not sure how to hook virtual functions without a class definition. I can get the address to the functions I want to hook, but what do I do after that? I'd really like to use SourceHook with this as well. I don't want to overwrite instructions in memory.
showdax is offline
Send a message via MSN to showdax
BAILOPAN
Join Date: Jan 2004
Old 12-13-2005 , 05:39  
Reply With Quote #3

You can "fake" the class definitions with preprocessor hacks. For example, my baseentity.h has this above Teleport:

#if defined CSS_SDK_DEC1
virtual void DummyFunc1() { }
virtual void DummyFunc2() { }
#endif

Which causes the vfunc table to be properly aligned with the latest CS:S update.

For calling these from Windows, there are two ways:
Code:
__asm {
   mov ecx, thisptr;
   push param2;
   push param1;
   call func;
}
Is the basic form of calling a __thiscall. Since in MSVC 7.1 you can't directly use "thiscall" as a convention, you must use inline assembly. The other method, of course, is to use __fastcall. Pass the instance pointer into the first parameter (fastcall throws this in ECX). Pass garbage in for the second pointer (fastcall throws this in EDX, which we don't care about), and pass the rest of the parameters normally).
__________________
egg
BAILOPAN is offline
showdax
Senior Member
Join Date: Dec 2004
Old 12-13-2005 , 08:05  
Reply With Quote #4

Is there any way to do this dynamically though? Or should I just have seperate classes for each mod? Would it be better to use a "detour?" I just don't want to have to deal with making a seperate class for each mod and dealing with it constantly breaking.
showdax is offline
Send a message via MSN to showdax
BAILOPAN
Join Date: Jan 2004
Old 12-13-2005 , 08:31  
Reply With Quote #5

detours are hooking non-vfuncs, they've nothing to do with what you're asking I think.

What do you mean "dynamically"?
__________________
egg
BAILOPAN is offline
showdax
Senior Member
Join Date: Dec 2004
Old 12-13-2005 , 08:40  
Reply With Quote #6

Well I don't care how it gets done, I just want to override what some functions do. And what I mean by dynamically is that I'd like this to work for as many mods as possible, without seperate binaries. And ideally I wouldn't need to update it if there were a change to any of the classes, the plugin would figure it out, or at the very least there could be some sort of text file that the plugin reads when it loads that describes the class's layout.

Specifically though, I want to override CBaseEntity::OnTakeDamage() and make it return 0 for a god mode-related command. I also want to hook weapon-related functions so I can do weapon restrictions (forcing someone to drop a restricted weapon of they pick it up, switch to it, etc.)
showdax is offline
Send a message via MSN to showdax
Thraka
AlliedModders Donor
Join Date: Aug 2005
Old 12-16-2005 , 18:52  
Reply With Quote #7

Have you found a way to do what you want to do showdax?? I would love to be able to do this also...

Specifically in DoDs would be to modify the players speed, weapon damage, remove hud elements (just while they are in my server!), block specific cl_ settings from being changed (while on my server!), ect...
Thraka is offline
ichthys
Veteran Member
Join Date: Dec 2004
Location: []*[]
Old 12-16-2005 , 19:10  
Reply With Quote #8

Quote:
Originally Posted by showdax
Well, I'm kind of surprised no one has said anything about this, though I guess it's not that amazing. My little admin plugin does all of the following now:
Code:
"admin_slay"
 - <name> - Slays specified player(s)
"admin_slap"
 - <name> [amount] - Slaps specified player(s)
"admin_teleport"
 - <name> <x> <y> <z> - Teleports specified player(s)
"admin_model"
 - <name> <model> - Sets model of specified player(s)
"admin_freeze"
 - <name> <1/0/on/off> - Freezes or unfreezes specified player(s)
"admin_speedy"
 - <name> <1/0/on/off> - Possibly makes player(s) run faster
"admin_noclip"
 - <name> <1/0/on/off> - Enables or disables noclip for specified player(s)
"admin_url"
 - <name> <url> [hidden: 0/1] - Opens MOTD to specified URL for specified player(s)
"admin_item"
 - <name> <item> - Gives item to specified player(s)
"admin_spawn"
 - <name> - Respawns specified player(s)
And it works in CS:S, DOD:S and HL2M! I'm not even including baseentity.h or player.h, I just have those forward declarations.

I'm wanting to implement god-mode and weapon restrictions now though, but I'm not sure how to hook virtual functions without a class definition. I can get the address to the functions I want to hook, but what do I do after that? I'd really like to use SourceHook with this as well. I don't want to overwrite instructions in memory.
which plugin is this? Sorry to go off topic but I couldn't find it.
__________________
ichthys is offline
showdax
Senior Member
Join Date: Dec 2004
Old 12-16-2005 , 20:53  
Reply With Quote #9

Quote:
Originally Posted by Thraka
Have you found a way to do what you want to do showdax?? I would love to be able to do this also...

Specifically in DoDs would be to modify the players speed, weapon damage, remove hud elements (just while they are in my server!), block specific cl_ settings from being changed (while on my server!), ect...
There's the "isometric" movement mode which is basically like being stuck in sprint mode. I don't know about doing any of those other things though, but I doubt it would be easy.

Quote:
Originally Posted by ichthys
which plugin is this? Sorry to go off topic but I couldn't find it. :?
It hasn't been released yet. Right now I'm working on implementing something like NemoD's nm_sprayinfo command, and weapon restrictions. The initial release will only be for Linux; I don't have signatures for the functions in the win32 binaries.
showdax is offline
Send a message via MSN to showdax
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 15:37.


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