Calling an internal function through DLL Injection menu

User Tag List

Results 1 to 6 of 6
  1. #1
    shikyo's Avatar Member
    Reputation
    3
    Join Date
    Dec 2008
    Posts
    10
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Calling an internal function through DLL Injection

    I know questions asked without first doing research is frowned upon, and rightfully so, so I just want to assure everyone I have searched and read through _a lot_ of posts on this forum aswell as a lot of information found through google.

    With that being said, I have encountered a problem which seems like I can not solve by myself. Previously, I have done an out of process bot in C# with basic functionality which sends messages to wow's message queue to do keyturns, etc. I decide, for this remake (in Java combined with JNative and DLL's written in C++ *shrugs*), to use Click To Move instead.
    I did some research and came to some conclusions:

    I would want to do this by calling wow's internal functions (both WorldToScreen computing with simulated mouse clicks and writing directly to the CTM structure I did not considere a viable option). I have so far been able (with much struggeling with JNative) been able to inject a DLL into wow's process, the DLL then invokes a call to user32's MessageBox from Wow's procedure. The MessageBox is displayed correctly, and when using Process Explorer I can see my DLL is loaded into WoW.

    The code this first version DLL should call was only this:
    Code:
    MessageBox(NULL, TEXT("DLL attached."), TEXT("Message"), MB_OK);
    I was unsure how to actually do a function call, so I decided to try something easy and went for ResetCamera. By looking through other posts I assumed the calling convention would look something like this:

    Code:
    MessageBox(NULL, TEXT("DLL attached."), TEXT("Message"), MB_OK); // From previous DLL version.
    // 0059AAB0    CGCamera__ResetView
    typedef void (__thiscall* CGCamera__ResetView)();
    
    CGCamera__ResetView ResetView = (CGCamera__ResetView)0x0059AAB0;
    ResetView();
    (That is the actual code getting called on DLL_PROCESS_ATTACH)

    I noticed that the MessageBox still gets displayed, however the camera is not moved to default position and, on top of that, the DLL is no longer present in Process Explorer.

    My conclusion was that the call I added is not approved by WoW and somehow that causes it to be Ejected. Now, given that I'm very new to all this memory editing, etc. my conclusion may be way off.

    So, my question is really what I am doing wrong that's causing my module to get ejected? (I assumed the actual code for injection is not of importance since I can inject the DLL without the ResetView call with no problems).

    Thanks alot for any help. Sorry for the long post and the noobish question.

    EDIT: Forgot to add I use LoadLibraryA and CreateRemoteThread to inject the DLL.
    Last edited by shikyo; 01-31-2010 at 04:35 PM.

    Calling an internal function through DLL Injection
  2. #2
    SKU's Avatar Contributor
    Reputation
    306
    Join Date
    May 2007
    Posts
    565
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I assume this is for the current wow version? If so, the address is wrong (0059AE60 CGCamera__ResetView, posted by Apoc in the dump thread, page 4), and the signature is wrong aswell.

    Code:
    .text:0059AE60 var_4           = dword ptr -4
    .text:0059AE60 arg_0           = dword ptr  8
    .text:0059AE60
    .text:0059AE60                 push    ebp
    .text:0059AE61                 mov     ebp, esp
    .text:0059AE63                 push    ecx
    .text:0059AE64                 mov     eax, [ebp+arg_0]
    .text:0059AE67                 test    eax, eax
    .text:0059AE69                 push    esi
    .text:0059AE6A                 mov     [ebp+var_4], ecx
    
    ...
    
    .text:0059AE6F                 xor     esi, esi
    .text:0059AE71                 jmp     short loc_59AE76
    .text:0059AE73                 mov     ecx, [ebp+var_4]
    .text:0059AE76                 push    esi
    .text:0059AE77                 call    sub_59AE60
    .text:0059AE7C                 add     esi, 1
    .text:0059AE7F                 cmp     esi, 8
    .text:0059AE82                 jl      short loc_59AE73
    
    ...
    
    .text:0059AEFA                 retn    4
    Code:
    typedef int (__thiscall * tCGCamera__ResetView)(CGCamera* pThis, int32 Unk1);
    tCGCamera__ResetView oCGCamera__ResetView = reinterpret_cast<tCGCamera__ResetView>(0x0059AE60);
    oCGCamera__ResetView(pCamera, Arg2);
    Untested.
    Last edited by SKU; 01-31-2010 at 06:41 PM.

  3. #3
    amadmonk's Avatar Active Member
    Reputation
    124
    Join Date
    Apr 2008
    Posts
    772
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Also, *please* don't do complicated/time consuming stuff in DllMain. I don't know if you're actually doing this or not (you didn't post actual code), but it's a fairly well-documented fact that DllMain is *not* where you do real work. Best choice is to spin up a thread and do the work in that thread.

    I see people breaking this rule so many times, and then wondering why things act weird. Mostly, it's just loader lock issues that can crop up, but it's still wise to consider this a general rule of thumb: don't do your work in DllMain.
    Don't believe everything you think.

  4. #4
    shikyo's Avatar Member
    Reputation
    3
    Join Date
    Dec 2008
    Posts
    10
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks alot for your answers. (Amdmonk: I did call it in the dll main, but it was just for testing purposes, thanks for the remark though.)

    I got the Click to Move function set up properly. I've also managed to call it from my Java application. For anyone interested in what my DLL code looks like this (DLL main and some other exports excluded, this is just for the CTM function I was looking for)

    Code:
    DWORD* g_PlayerBase = 0;
    
    struct WoWPos
    {
    	float X;
    	float Y;
    	float Z;
    };
    
    extern "C" __declspec(dllexport) void Initialize()
    {
    	DWORD *pb1, *pb2, *playerbase;
    	pb1 = (DWORD*)0x00A7B434;
    	pb2 = (DWORD*)(*pb1+0x0c);
    	playerbase = (DWORD*)(*pb2+0x24);
    	g_PlayerBase = playerbase;
    }
    
    extern "C" __declspec(dllexport) void MoveToPosition(int lpPosAddress)
    {
    	if (g_PlayerBase == 0)
    		return;
    
    	typedef bool (__thiscall* tCGPlayer_C__ClickToMove)(void* pBase, int ClickToMoveType, unsigned __int64* interactGUID, WoWPos* clickPos, float precision);
    	tCGPlayer_C__ClickToMove CGPlayer_C__ClickToMove = reinterpret_cast<tCGPlayer_C__ClickToMove>(0x006BA610);
    
    	WoWPos *pos = (WoWPos*)lpPosAddress;
    
    	unsigned __int64 *allocatedPointer = new unsigned __int64;
    	*allocatedPointer = 0;
    	CGPlayer_C__ClickToMove((void*)*g_PlayerBase, 0x4, allocatedPointer, pos, 0);
    }
    Note: If you're curious about the java solution I don't mind sharing (although it's fugly code to say the least).
    Last edited by shikyo; 02-02-2010 at 01:05 PM.

  5. #5
    flo8464's Avatar Active Member
    Reputation
    30
    Join Date
    Apr 2009
    Posts
    434
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Never store addresses in a signed int variable.
    Use DWORD or better DWORD_PTR, which also works correctly on 64bit systems.
    Hey, it compiles! Ship it!

  6. #6
    shikyo's Avatar Member
    Reputation
    3
    Join Date
    Dec 2008
    Posts
    10
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by flo8464 View Post
    Never store addresses in a signed int variable.
    Use DWORD or better DWORD_PTR, which also works correctly on 64bit systems.
    Java (or more specifically JNative) requires a signed integer to be the address passed as the parameter for CreateRemoteThread's LPVOID lpParameter parameter, and yes that that can create problems on 64 bit systems (and probably 32 bit systems too?), but afaik JNative (which I'm using) doesn't support 64 bit anyways.
    Last edited by shikyo; 02-05-2010 at 06:32 AM.

Similar Threads

  1. Replies: 8
    Last Post: 07-22-2013, 01:24 AM
  2. [Help] .NET Injection - Calling CGObject_C virtual functions
    By adaephon in forum WoW Memory Editing
    Replies: 17
    Last Post: 02-12-2010, 08:52 PM
  3. Calling Lua Functions from DLL
    By Viano in forum WoW Memory Editing
    Replies: 19
    Last Post: 07-28-2009, 07:56 PM
  4. DLL injection with windows SP3
    By Therrm in forum World of Warcraft Bots and Programs
    Replies: 3
    Last Post: 12-06-2008, 03:03 PM
  5. What are the risks with DLL injection?
    By object in forum WoW Memory Editing
    Replies: 14
    Last Post: 08-22-2008, 09:23 PM
All times are GMT -5. The time now is 02:50 AM. Powered by vBulletin® Version 4.2.3
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2024 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search