• Hooking an overloaded function
    18 replies, posted
  • I'm hooking a function that has two types of parameters heading to it. Here are the two functions [code]void DevMsg( tchar const* pMsg, ... ) void DevMsg( tchar const *pGroupName, int level, tchar const *pMsg, ... ) [/code] Both of those are going to a function that does nothing and retrns; I'm hooking that function, but, how should I code my function so that it chooses the right parameter scheme?
  • [code](void(*)(tchar const*,...))&DevMsg; (void(*)(tchar const*,int,tchar const*,...))&DevMsg;[/code] if i can remember correctly.
  • [QUOTE=mmavipc;26593677]how does that help me?[/QUOTE] it obtains the pointer for right overloaded function i think. if that still doesn't help, you probably have no clue about what you're doing.
  • Here's what i'm doing [code] typedef void (*vfunc)(void); void MyDevMsg( ... ) { //va_list vl; //va_start(vl, pWhoKnows); __asm nop; } void Hook(vfunc ours, vfunc theirs) { unsigned int addr = (unsigned int)theirs; unsigned int offset = 0; char newcrap[5], oldcrap[5]; offset = (unsigned int)ours - (addr+5); printf("lol %x %x\n",addr,offset); memcpy(newcrap,&"\xe9",1); memcpy((char*)((int)newcrap+1),&offset,4); DWORD idk; int error = VirtualProtect((void*)addr,5,PAGE_EXECUTE_READWRITE,&idk); memcpy(oldcrap,(void*)addr,5); memcpy((void*)addr,newcrap,5); } Hook((vfunc)MyDevMsg,(vfunc)GetProcAddress(tier0,"DevMsg")); Hook((vfunc)MyDevMsg,(vfunc)GetProcAddress(tier0,"DevWarning")); Hook((vfunc)MyDevMsg,(vfunc)GetProcAddress(tier0,"DevLog")); [/code] If I change the parameters of MyDevMsg, it will crash. What should I be doing?
  • uhm [code]; Exported entry 242. DevMsg ; int __cdecl DevMsg(int, char *, char) [/code] [editline]9th December 2010[/editline] i don't even want to ask about that hook function.
  • The hook function overwrites the first 5 bytes of the function with a jmp to my function [code]DBG_INTERFACE void DevMsg( int level, tchar const* pMsg, ... ); DBG_INTERFACE void DevWarning( int level, tchar const *pMsg, ... ); DBG_INTERFACE void DevLog( int level, tchar const *pMsg, ... ); /* default level versions (level 1) */ DBG_OVERLOAD void DevMsg( char const* pMsg, ... ); DBG_OVERLOAD void DevWarning( char const *pMsg, ... ); DBG_OVERLOAD void DevLog( char const *pMsg, ... );[/code] That's how it is normally in the .h file, but in the program I'm hooking it's [code]inline void DevMsg( ... ) {} inline void DevWarning( ... ) {} inline void DevLog( ... ) {}[/code] They are still exported though. So, how can I hook them, if they're getting two different parameter sets?
  • To look up the address of a C++ function with GetProcAddress() you'll need to use its [url=http://en.wikipedia.org/wiki/Name_mangling]mangled name[/url], which contains the type information that differentiates the overloads. However: [QUOTE=mmavipc;26594906][code]inline void DevMsg( ... ) {} inline void DevWarning( ... ) {} inline void DevLog( ... ) {}[/code][/QUOTE] You can't hook an inline function, because it doesn't exist as a distinct function in the compiled binary. (It's compiled "into" all the places that call it instead.) Either GetProcAddress() won't find it, or you'll get the address of an "out-of-line" copy that isn't actually called by anything.
  • [QUOTE=Wyzard;26595122]To look up the address of a C++ function with GetProcAddress() you'll need to use its [url=http://en.wikipedia.org/wiki/Name_mangling]mangled name[/url], which contains the type information that differentiates the overloads. However: You can't hook an inline function, because it doesn't exist as a distinct function in the compiled binary. (It's compiled "into" all the places that call it instead.) Either GetProcAddress() won't find it, or you'll get the address of an "out-of-line" copy that isn't actually called by anything.[/QUOTE] I've checked the exported functions with IDA, they're getting exported as [code].text:10003160 public DevMsg .text:10003160 DevMsg proc near ; CODE XREF: .text:1000323Cp .text:10003160 ; InitPME+4Bp ... .text:10003160 retn .text:10003160 DevMsg endp .text:10003160 [/code] That fucntion is getting two different sets of inputs, how do i differentiate between the two [editline]10th December 2010[/editline] [code]void MyDevMsg( int level, tchar const* pMsg, ... ){} void MyDevWarning( int level, tchar const *pMsg, ... ){} void MyDevLog( int level, tchar const *pMsg, ... ){} /* default level versions (level 1) */ void MyDevMsg( char const* pMsg, ... ){} void MyDevWarning( char const *pMsg, ... ){} void MyDevLog( char const *pMsg, ... ){} Hook((vfunc)MyDevMsg,(vfunc)GetProcAddress(tier0,"DevMsg")); Hook((vfunc)MyDevMsg,(vfunc)GetProcAddress(tier0,"DevWarning")); Hook((vfunc)MyDevMsg,(vfunc)GetProcAddress(tier0,"DevLog")); [/code] Is giving me [code]1>c:\nexon\vindictus\fuckyou\fuckyou\dllmain.cpp(179): error C2440: 'type cast' : cannot convert from 'overloaded-function' to 'vfunc' 1> None of the functions with this name in scope match the target type 1>c:\nexon\vindictus\fuckyou\fuckyou\dllmain.cpp(180): error C2440: 'type cast' : cannot convert from 'overloaded-function' to 'vfunc' 1> None of the functions with this name in scope match the target type 1>c:\nexon\vindictus\fuckyou\fuckyou\dllmain.cpp(181): error C2440: 'type cast' : cannot convert from 'overloaded-function' to 'vfunc' 1> None of the functions with this name in scope match the target type[/code] [editline]10th December 2010[/editline] I need [b]ONE[/b] function to handle two different kind of inputs
  • OK, apparently those aren't C++ overloaded functions. C++ overloads are really different functions; this is a case of a single (plain C) function that happens to be declared twice in a header, with different parameters. I'm not sure why that doesn't cause a compile error. Is [url=http://media.kane.cx/~kane/public/tier0/dbg.h]this[/url] the header you're looking at? It looks like DBG_INTERFACE and DBG_OVERLOAD are #define'd as DLL_IMPORT and DLL_GLOBAL_IMPORT respectively. Presumably DLL_IMPORT is #define'd as something like __declspec(dllimport), but what does DLL_GLOBAL_IMPORT mean? Hooking aside, how does the normal implementation of DevMsg() figure out what to do with its parameters?
  • the ifdef fails, so the function header really is void DevMsg( ... ); If there is a va, but no argument infront of it, what do I pass as the second parameter to va_start?
  • Hmm, that file contains templates, so apparently it is C++ source, not C. So we need to determine what kind of linkage that function has. If it uses C++ linkage, the two declarations with different parameters are OK, but they'll produce mangled names in the DLL. If they use C linkage, no name mangling will be done, but then the two declarations conflict with each other and should produce a compile error. Do the definitions of DLL_IMPORT and/or DLL_GLOBAL_IMPORT use the 'extern "C"' construct?
  • [quote]void DevMsg( ... ); If there is a va( a ...), but no argument infront of it, what do I pass as the second parameter to va_start? [/quote]
  • Regarding varargs, it looks like with <stdarg.h> you can't have a function with no fixed parameters. With the deprecated <varargs.h>, va_start() doesn't take a second parameter. See [url]http://en.wikipedia.org/wiki/Stdarg.h[/url]
  • Actually, there's no point trying to target that no-args variadic version of the function. Look at its definition: [cpp]inline void DevMsg( ... ) {}[/cpp] It's inline with an empty body. Calling it is a no-op. You need to figure out what definitions were in effect when the game (or whatever it is that you're targeting) was compiled. If it was compiled against the DBG_INTERFACE/DBG_OVERLOAD versions, it'll call the DLL function that you can hook. If it was compiled against the empty inline version, you're out of luck: the program won't call the function at all, even if it exists in the DLL.
  • I looked, one is mangled, the other is an extern C. OVERLOAD is the mangled one.
  • OK, that makes sense, and resolves the problem of handling the different types of parameters. You'll need to hook each one separately, with an appropriate hook function for its parameter types, and hope that the game's actually calling them (rather than having been built with the no-op inline definition).
  • [QUOTE=Wyzard;26598701]OK, that makes sense, and resolves the problem of handling the different types of parameters. You'll need to hook each one separately, with an appropriate hook function for its parameter types, and hope that the game's actually calling them (rather than having been built with the no-op inline definition).[/QUOTE] I know it was calling atleast the extern c one, because it kept crashing on my inside my hook function