1. Post #1
    mmavipc's Avatar
    February 2009
    845 Posts
    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, ... )
    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?

  2. Post #2
    haushippo's Avatar
    June 2010
    374 Posts
    Code:
    (void(*)(tchar const*,...))&DevMsg;
    (void(*)(tchar const*,int,tchar const*,...))&DevMsg;
    if i can remember correctly.
    Reply With Quote Edit / Delete Reply Canada Show Events Agree Agree x 1 (list)

  3. Post #3
    mmavipc's Avatar
    February 2009
    845 Posts
    how does that help me?

  4. Post #4
    haushippo's Avatar
    June 2010
    374 Posts
    how does that help me?
    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.
    Reply With Quote Edit / Delete Reply Canada Show Events Agree Agree x 1Funny Funny x 1Disagree Disagree x 1 (list)

  5. Post #5
    mmavipc's Avatar
    February 2009
    845 Posts
    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"));
    If I change the parameters of MyDevMsg, it will crash. What should I be doing?

  6. Post #6
    haushippo's Avatar
    June 2010
    374 Posts
    uhm
    Code:
    ; Exported entry 242. DevMsg
    ; int __cdecl DevMsg(int, char *, char)
    Edited:

    i don't even want to ask about that hook function.

  7. Post #7
    mmavipc's Avatar
    February 2009
    845 Posts
    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, ... );
    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( ... ) {}
    They are still exported though. So, how can I hook them, if they're getting two different parameter sets?

  8. Post #8
    Wyzard's Avatar
    June 2008
    1,243 Posts
    To look up the address of a C++ function with GetProcAddress() you'll need to use its mangled name, which contains the type information that differentiates the overloads.

    However:
    Code:
    inline void DevMsg( ... ) {}
    inline void DevWarning( ... ) {}
    inline void DevLog( ... ) {}
    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.

  9. Post #9
    mmavipc's Avatar
    February 2009
    845 Posts
    To look up the address of a C++ function with GetProcAddress() you'll need to use its mangled name, 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.
    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
    That fucntion is getting two different sets of inputs, how do i differentiate between the two

    Edited:

    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"));
    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
    Edited:

    I need ONE function to handle two different kind of inputs

  10. Post #10
    Wyzard's Avatar
    June 2008
    1,243 Posts
    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 this 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?

  11. Post #11
    mmavipc's Avatar
    February 2009
    845 Posts
    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?

  12. Post #12
    Wyzard's Avatar
    June 2008
    1,243 Posts
    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?

  13. Post #13
    mmavipc's Avatar
    February 2009
    845 Posts
    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?

  14. Post #14
    Wyzard's Avatar
    June 2008
    1,243 Posts
    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 http://en.wikipedia.org/wiki/Stdarg.h

  15. Post #15
    mmavipc's Avatar
    February 2009
    845 Posts
    There has to be some hacky asm way to do it

  16. Post #16
    Wyzard's Avatar
    June 2008
    1,243 Posts
    Actually, there's no point trying to target that no-args variadic version of the function. Look at its definition:
    inline void DevMsg( ... ) {}
    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.

  17. Post #17
    mmavipc's Avatar
    February 2009
    845 Posts
    I looked, one is mangled, the other is an extern C. OVERLOAD is the mangled one.

  18. Post #18
    Wyzard's Avatar
    June 2008
    1,243 Posts
    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).

  19. Post #19
    mmavipc's Avatar
    February 2009
    845 Posts
    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).
    I know it was calling atleast the extern c one, because it kept crashing on my inside my hook function