Windows Injection - First Attempt - 2 Questions menu

User Tag List

Results 1 to 14 of 14
  1. #1
    Tanaris4's Avatar Contributor Authenticator enabled
    Reputation
    148
    Join Date
    Oct 2008
    Posts
    646
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Windows Injection - First Attempt - 2 Questions

    So this is my first poor attempt at taking advantage of Windows Injection, I'm using the great example posted by PferdOne aka Flowerew in C++. I was hoping I could get some help on this, specifically in the Initialize function (to make sure I have the syntax correct) as well as helping me debug a compiler error. This is the DLL that will be injected, the injection code is working great :-)

    Here is the source:

    Code:
    /*
      Written by PferdOne aka Flowerew on 23rd Jan., 2010
      Credits go to mmowned.com & gamedeception community for all the information.
    
      Overview:
        - Simple injector class to inject a dll into another process and load it
        - Very simple EndScene hook method via VTable
        - ClientConnection, CGCurMgr_C and CGObject_C included to show where it all begins
    
      Define an environment variable with the name WOWDIR which points to your World of
      Warcraft directory. That's where the dll will be put.
    
      Note: Don't ask dumb questions. Your question has probably been answered a hundred
            times. And by probably I mean most definitely. */
    
    #include <stdint.h>
    #include <windows.h>
    
    HINSTANCE proc_addr = NULL;
    
    //signed int __usercall sub_750230<eax>(int a1<ecx>, double a2<st0>, __int16 a3, int a4, unsigned int a5)
    signed int *_real_receive_packet = NULL;
    signed int _hook_receive_packet( int a1, double a2, int16_t a3, int a4, unsigned int a5);
    
    #define RECEIVE_FUNC_ADDRESS 0x750230
    
    void Initialize();
    void Deinitialize();
    
    
    //------------------------------------------------------------------------------
    BOOL APIENTRY DllMain(HINSTANCE hInstDll, DWORD dwReason, LPVOID pReserved) {
      proc_addr = hInstDll;
    
      switch (dwReason) {
        case DLL_PROCESS_ATTACH: {
          OutputDebugString(TEXT("DLL_PROCESS_ATTACH\n"));
          Initialize();
          break; }
        case DLL_THREAD_ATTACH: {
          OutputDebugString(TEXT("DLL_THREAD_ATTACH\n"));
          break; }
        case DLL_PROCESS_DETACH: {
          OutputDebugString(TEXT("DLL_PROCESS_DETACH\n"));
          Deinitialize();
          break; }
        case DLL_THREAD_DETACH: {
          OutputDebugString(TEXT("DLL_THREAD_DETACH\n"));
          break; }
      }
    
      return TRUE;
    }
    
    signed int _hook_receive_packet( int a1, double a2, int16_t a3, int a4, unsigned int a5){
    
    	signed int res = (signed int)(*_real_receive_packet)( a1, a2, a3, a4, a5 );
    
    	// do something??
    
    	return res;
    }
    
    //------------------------------------------------------------------------------
    void Initialize() {
    
      unsigned int func_base = RECEIVE_FUNC_ADDRESS;
      unsigned int *func_addr = reinterpret_cast<unsigned int*>(func_base);
      
      _real_receive_packet = reinterpret_cast<int*>(*func_addr);
    
      // simply overwrite the vtable function address with our hook func_addr
      *func_addr = reinterpret_cast<unsigned int>(_hook_receive_packet);
    }
    
    //------------------------------------------------------------------------------
    void Deinitialize() {
    
      // unhook function
      //unsigned int func_addr = *reinterpret_cast<unsigned int*>(RECEIVE_FUNC_ADDRESS);
      //*func_addr = (unsigned int*)orig_receive_packet;
    }
    I'm getting an error when I actually try to call the _real_ function within the hooked function, the error is: "error C2064: term does not evaluate to a function taking 5 arguments". If I try to actually put the arguments near the declaration at the top of the code, it gives me a linking error. So I'm not entirely sure how to call a function just when you have the address.

    Any help would be GREATLY appreciated! Thanks all!
    https://tanaris4.com

    Windows Injection - First Attempt - 2 Questions
  2. #2
    wraithZX's Avatar Active Member
    Reputation
    43
    Join Date
    May 2007
    Posts
    122
    Thanks G/R
    0/1
    Trade Feedback
    1 (100%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    signed int (*_real_receive_packet)(int, double, int16_t, int, unsigned int) = NULL;

    Go read up on function pointers.

  3. #3
    Tanaris4's Avatar Contributor Authenticator enabled
    Reputation
    148
    Join Date
    Oct 2008
    Posts
    646
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    How should I have the
    Code:
    _real_receive_packet = reinterpret_cast<int*>(*func_addr);
    assignment?
    https://tanaris4.com

  4. #4
    mnbvc's Avatar Banned
    Reputation
    120
    Join Date
    Jul 2009
    Posts
    273
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

  5. #5
    Tanaris4's Avatar Contributor Authenticator enabled
    Reputation
    148
    Join Date
    Oct 2008
    Posts
    646
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I don't see how that's helpful at all

    I should just stick to OS X, ugh
    https://tanaris4.com

  6. #6
    Cypher's Avatar Kynox's Sister's Pimp
    Reputation
    1358
    Join Date
    Apr 2006
    Posts
    5,368
    Thanks G/R
    0/6
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    This has NOTHING to do with the OS, it's just basic C++.

    Look at how you've declared "_real_receive_packet":
    signed int *_real_receive_packet = NULL;

    You've told the compiler that it's a pointer to a signed integer.

    wraithZX was correct. You can't call an integer...

  7. #7
    Tanaris4's Avatar Contributor Authenticator enabled
    Reputation
    148
    Join Date
    Oct 2008
    Posts
    646
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Guess I'm just confused by the reinterpret stuff, on OS X I declare the function header as:
    Code:
    int (*_real_GetWorldState)(int a1);
    Guess I just have to take out a1 for windows
    https://tanaris4.com

  8. #8
    wraithZX's Avatar Active Member
    Reputation
    43
    Join Date
    May 2007
    Posts
    122
    Thanks G/R
    0/1
    Trade Feedback
    1 (100%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The only difference between Win32 and OSX may be that the resulting calling convention used by each specific compiler may be different.
    I know that the way MSVC and GCC handle virtual functions is different, these sorts of things may very well be the cause of confusion when transitioning from OSX to Win32.

  9. #9
    tymezz's Avatar Member
    Reputation
    9
    Join Date
    Nov 2007
    Posts
    44
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Tanaris4 View Post
    Guess I'm just confused by the reinterpret stuff, on OS X I declare the function header as:
    Code:
    int (*_real_GetWorldState)(int a1);
    Guess I just have to take out a1 for windows

    You declared _real_GetWorldState as a pointer to a function that returns an integer .

    However, as Cypher pointed out, you declared _real_receive_packet as just a pointer to signed integer.

  10. #10
    Bananenbrot's Avatar Contributor
    Reputation
    153
    Join Date
    Nov 2009
    Posts
    384
    Thanks G/R
    1/3
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Why do you include stdint.h if you don't make use of those typedefs consistently?
    Or since you are programming in Win32, why don't you use the typedefs (DWORD etc.) and naming conventions...
    Either way your code would be much more readable^^

  11. #11
    GliderPro's Avatar Member
    Reputation
    -1
    Join Date
    Mar 2009
    Posts
    93
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You should consider using HadesMem. It is more readable and easier to understand. Here is a link to the my post where I created an EndScene hook with it. http://www.mmowned.com/forums/world-...cene-hook.html

    Now back to your specific question. As others have pointed out you are "calling" a pointer to an integer and that will never compile. You need to either define the real pointer with a typedef or cast the simple pointer before you call it. Here is how Cypher did it in his HadesMem examples.

    Code:
      typedef HRESULT (WINAPI *tEndScene)(IDirect3DDevice9 *);
      HRESULT hr = reinterpret_cast<tEndScene>(MyPatch->GetTrampoline())(thisPtr);
    Note the typedef and cast. The GetTramp function is simply returning a void pointer.

    Here is a more complex function call.

    Code:
      typedef HRESULT (WINAPI *tCreateDevice)(IDirect3D9 *,UINT,D3DDEVTYPE,HWND,
        DWORD, D3DPRESENT_PARAMETERS*, IDirect3DDevice9** );
      HRESULT hr = reinterpret_cast<tCreateDevice>(MyPatch->GetTrampoline())(thisPtr,
        Adapter,DeviceType,hFocusWindow,BehaviorFlags,pPresentationParameters,
        ppReturnedDeviceInterface);

  12. #12
    Tanaris4's Avatar Contributor Authenticator enabled
    Reputation
    148
    Join Date
    Oct 2008
    Posts
    646
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    What if the function is a __usercall vs __stdcall ? (I tried googling this but couldn't find anything on __usercall) I'm assuming this doesn't matter?

    Thanks for the feedback :-)
    https://tanaris4.com

  13. #13
    GliderPro's Avatar Member
    Reputation
    -1
    Join Date
    Mar 2009
    Posts
    93
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    __usercall is not a VC++ keyword. I did a google search too and it looks like that keyword is related to the new appcall feature in IDA.

  14. #14
    XTZGZoReX's Avatar Active Member
    Reputation
    32
    Join Date
    Apr 2008
    Posts
    173
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    __usercall is not a VC++ keyword. I did a google search too and it looks like that keyword is related to the new appcall feature in IDA.
    Uhmm...
    One very common case of this is a function, which returns the result in an unusual register, e.g. ECX. Please explicitly specify the function type and tell IDA the exact location of the return value. For example:

    int __usercall myfunc<ecx>(void);
    Hex-Rays Decompiler - Frequently asked questions

Similar Threads

  1. First Attempt AT Photoshop
    By Synyster in forum Art & Graphic Design
    Replies: 7
    Last Post: 08-05-2007, 04:33 PM
  2. First Attempt
    By Fault in forum Art & Graphic Design
    Replies: 6
    Last Post: 06-05-2007, 02:37 PM
  3. a first attempt
    By MechaAngelus in forum WoW ME Questions and Requests
    Replies: 10
    Last Post: 08-21-2006, 03:30 PM
  4. a first attempt
    By MechaAngelus in forum World of Warcraft Model Editing
    Replies: 3
    Last Post: 08-17-2006, 03:13 PM
All times are GMT -5. The time now is 10:48 PM. Powered by vBulletin® Version 4.2.3
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Google Authenticator verification provided by Two-Factor Authentication (Free) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search