[Help] .NET Injection - Calling CGObject_C virtual functions menu

Shout-Out

User Tag List

Page 1 of 2 12 LastLast
Results 1 to 15 of 18
  1. #1
    adaephon's Avatar Active Member
    Reputation
    76
    Join Date
    May 2009
    Posts
    167
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    [Help] .NET Injection - Calling CGObject_C virtual functions

    Hi all,

    I have a question for those of you who are injecting and hosting the .NET CLR inside WoW. I've been encountering crashes in my own solution whilst attempting to call any WoW object virtual function (GetName being the primary one I have been trying to get working).

    I haven't had the chance to debug it too much yet and obviously I will keep looking into it, trying to solve it myself. However, I thought I'd ask here in the meantime just to make sure I wasn't doing something obviously wrong with setting up / registering delegates etc.

    The relevant code for the relevant objects:
    WoWObject:
    Code:
    // CGObject_C
    class WoWObject
    {
    	...
    	
    	public enum VTable
    	{
    		GetBag = 9,
    		GetPosition = 11,
    		GetFacing = 13,
    		GetScale = 14,
    		GetModel = 23,
    		Interact = 42,
    		GetName = 52,
    	}
    	
    	...
    
    	[UnmanagedFunctionPointer(CallingConvention.Winapi)]
    	public delegate string GetNameDelegate(IntPtr instance);
    	
    	...
    	
    	public IntPtr BaseAddress { get; protected set; }
    	
    	...
    	
    	public virtual string Name
    	{
    		get
    		{
    			return "";
    		}
    	}
    	...
    }
    WoWUnit:
    Code:
    class WoWUnit : WoWObject
    {
    	...
    	
    	private GetNameDelegate _getName;
    	public override string Name
    	{
    		get
    		{
    			if (_getName == null)
    			{
    				_getName = Memory.RegisterDelegate<GetNameDelegate>(Memory.GetObjectVTableFunctionPointer(BaseAddress, (int)VTable.GetName));
    			}
    			return _getName(BaseAddress);
    		}
    	}
    	
    	...
    }
    Firstly, is this the correct way to set up / call a virtual function for an object deriving from CGObject_C? From the bits and pieces I've put together from searching this seems to be the general approach, although most people seem to either use C++ or BlackMagic ASM injection.

    The object list is pulsed from an EndScene hook (hooking mostly credits to WhiteMagic by Apoc, rewritten into my framework, and object stuff mostly based off Apoc's thread on object management, credits once again). This all works fine - I can spit out objects' GUIDs and any other properties that are read from the descriptors etc. However, the moment I make a call to WoWUnit.Name, the program crashes (crash dump: NoMorePasting.com).

    I've tried a few different methods of debugging but admittedly given the minimal time I've had to spend on it and my still limited knowledge of ASM etc, that hasn't found me a solution yet. I've tried putting a breakpoint in Olly on 0x006BD710 (CGUnit_C__GetUnitName according to info dump) both with clean WoW and with my code injected. It appears that the code follows a different path when I call it than when the game calls it.

    Code:
    .text:006BD729                 test    byte ptr [esi+0F42h], 80h
    .text:006BD730                 jz      loc_6BD7ED
    My call appears to fail that test, causing it to proceed and eventually enter the loop beginning at loc_6BD753. The crash eventually occurs attempting to read invalid memory at loc_6BD787, but according to debugging it appears to go through about 10 iterations of the loop before it fails. This much I've been able to determine from debugging, and as I've said I haven't been able to put that much time into it; also, my knowledge of ASM is somewhat limited making it more difficult to understand what the function / loop is actually doing and thus why it might be crashing. However, I thought I'd at least check if there was anything glaringly obvious.

    Any help / pointers / comments appreciated. Constructive ridicule would also be appreciated .

    Cheers!

    [Help] .NET Injection - Calling CGObject_C virtual functions
  2. #2
    Apoc's Avatar Angry Penguin
    Reputation
    1388
    Join Date
    Jan 2008
    Posts
    2,750
    Thanks G/R
    0/13
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    It's a ThisCall.

    Not a WinApi.

    Is it really that hard to figure out? Do you even bother trying to understand the code, or do you just copy/paste and hope it works?

    Lastly; learn how the marshaler works, and how .NET handles unmanaged strings. Better yet, SEARCH.

  3. #3
    adaephon's Avatar Active Member
    Reputation
    76
    Join Date
    May 2009
    Posts
    167
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Gah... fail on my part. I initially had that as ThisCall and was getting crashes so attempted to change it to WinApi to see what happened (getting confused late at night and ><) didn't realise I hadn't changed it back. I had also assumed that string marshalling could've been a problem and thus tried using GetScale or w/e it is callled hoping that marshalling couldn't cause too many issues with a float return type. Was still getting crashes, but must've still had WinApi as calling convention.

    *sigh* Well like I said, constructive ridicule appreciated. That'll learn me for changing more than one potential problem between tests....
    EDIT: Thanks btw
    Last edited by adaephon; 02-09-2010 at 07:35 AM.

  4. #4
    Azzie2k8's Avatar Member
    Reputation
    11
    Join Date
    Apr 2009
    Posts
    190
    Thanks G/R
    0/0
    Trade Feedback
    1 (100%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Okay, I am going to ask this here since it seems appropiate. I have been stuck with this for some time now and I am getting nowhere...

    My basic question is: Which Object Types have those virtual function like GetName and GetPosition ? So far I assumed(after being told by Robske ) that they belong to the general WowObject class but I am getting exceptions and so on.

    So far it seems like only Units have the GetName function. Is that correct ?

  5. #5
    Viano's Avatar Active Member
    Reputation
    37
    Join Date
    May 2008
    Posts
    172
    Thanks G/R
    0/1
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I would love to see what functions Apoc is using with his WhiteMagic to get object names with VMT, it seems to cause trouble around here anyway.

    For example am I doing it right?

    Code:
    [UnmanagedFunctionPointer(CallingConvention.ThisCall, CharSet = CharSet.Unicode)]
            public delegate IntPtr GetNameDelegate(IntPtr instance);
    ...
    public static GetNameDelegate GetName;
    ...
    
     public static string Name(uint ptr)
            {
                GetName = (GetNameDelegate)Marshal.GetDelegateForFunctionPointer(
                    _magic.GetObjectVtableFunction(_magic.Read<IntPtr>(ptr), 52), typeof(GetNameDelegate));
                return Marshal.PtrToStringUni(GetName(new IntPtr(ptr)));
            }
    This is not getting me any names :/
    Last edited by Viano; 02-09-2010 at 04:56 PM.
    Viano

  6. #6
    Apoc's Avatar Angry Penguin
    Reputation
    1388
    Join Date
    Jan 2008
    Posts
    2,750
    Thanks G/R
    0/13
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    This is the only time I'll post this.

    If you guys can't figure this stuff out for yourself, I'm not going to help any more.

    Code:
            [UnmanagedFunctionPointer(CallingConvention.ThisCall, CharSet = CharSet.Ansi)]
            [return: MarshalAs(UnmanagedType.LPStr)]
            private delegate string GetNameDelegate(IntPtr instance);

  7. #7
    Viano's Avatar Active Member
    Reputation
    37
    Join Date
    May 2008
    Posts
    172
    Thanks G/R
    0/1
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Apoc View Post
    This is the only time I'll post this.

    If you guys can't figure this stuff out for yourself, I'm not going to help any more.
    ...
    Well actually I am doing this but still, no useful result (updated my post above).
    Viano

  8. #8
    Apoc's Avatar Angry Penguin
    Reputation
    1388
    Join Date
    Jan 2008
    Posts
    2,750
    Thanks G/R
    0/13
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You didn't read very well. Look at it again, you'll notice the difference between the two declarations.

  9. #9
    Viano's Avatar Active Member
    Reputation
    37
    Join Date
    May 2008
    Posts
    172
    Thanks G/R
    0/1
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Apoc View Post
    You didn't read very well. Look at it again, you'll notice the difference between the two declarations.
    I can't read but I love you ;-) Works now.
    Viano

  10. #10
    adaephon's Avatar Active Member
    Reputation
    76
    Join Date
    May 2009
    Posts
    167
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks again for the help Apoc. Turns out it was 'working' before I posted this and had it as a ThisCall, but there is some other issue causing crashes which I am yet to figure out.

    Returning a string adorned with MarshalAs.LPStr doesn't seem to work consistently for me, but returning an IntPtr and marshalling it myself does. Interestingly almost identical code seemed to work for Players but wouldn't work for Units. My problem is I've fiddled with so many values now that I can't remember which ones worked. Nevertheless, marshalling the pointer seems to work for now so I'll leave the rest to research another day.

  11. #11
    Apoc's Avatar Angry Penguin
    Reputation
    1388
    Join Date
    Jan 2008
    Posts
    2,750
    Thanks G/R
    0/13
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by adaephon View Post
    Thanks again for the help Apoc. Turns out it was 'working' before I posted this and had it as a ThisCall, but there is some other issue causing crashes which I am yet to figure out.

    Returning a string adorned with MarshalAs.LPStr doesn't seem to work consistently for me, but returning an IntPtr and marshalling it myself does. Interestingly almost identical code seemed to work for Players but wouldn't work for Units. My problem is I've fiddled with so many values now that I can't remember which ones worked. Nevertheless, marshalling the pointer seems to work for now so I'll leave the rest to research another day.
    If you've been testing within the last day or two and getting random returns (completely screwy looking names) it's not your code. It's the servers being screwed up.

    The same issue was (and probably still is) happening to me.

  12. #12
    adaephon's Avatar Active Member
    Reputation
    76
    Join Date
    May 2009
    Posts
    167
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Apoc View Post
    If you've been testing within the last day or two and getting random returns (completely screwy looking names) it's not your code. It's the servers being screwed up.

    The same issue was (and probably still is) happening to me.
    Hmm interesting. Have been on and off in the last day or two, but wasn't getting garbled results - it was very definite crashes :P. Seemed to be occurring in mscorwks.dll so without looking into it too much I'm assuming some CLR issue, probably marshalling related. Like I said they started working when I just marshalled a returned IntPtr myself, and that will do as an interim until I can be bothered looking into it again.

  13. #13
    RoKFenris's Avatar Member
    Reputation
    16
    Join Date
    Jun 2008
    Posts
    69
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Since last tuesday even straight LUA addons have been crashing, since the servers seems very slow to send info on almost anything, including Items, Mobs, Quests, etc. Anything that does not gracefully handle the case where the needed info from the caches is not available is prone to crash.
    Fortunately for me I was already double checking the availability of data before reading it (I sometimes have lots of latency, so for me it's needed in order to have a semblance of stability in my project).

  14. #14
    Viano's Avatar Active Member
    Reputation
    37
    Join Date
    May 2008
    Posts
    172
    Thanks G/R
    0/1
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Is it actually possible to get Unicode names? I fail hard with the following method.

    Code:
    [UnmanagedFunctionPointer(CallingConvention.ThisCall, CharSet = CharSet.Unicode)]
            [return: MarshalAs(UnmanagedType.LPWStr)]
            private delegate string GetNameDelegate(IntPtr instance);
    Viano

  15. #15
    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)
    IIRC, CharSet.Unicode specifies UCS-16 encoding. You want UTF-8, which is like ANSI with a twist...

    Edit: O/T rant: with UTF-8 becoming the de facto Unicode web standard, why oh why are there no built-in UTF-8 marshalling helpers? Right now, you have to marshal as an ANSI string, then get bytes and re-encode as UTF-8. Kludgey.
    Don't believe everything you think.

Page 1 of 2 12 LastLast

Similar Threads

  1. "pure virtual function call" c++ error
    By Kzuly in forum Diablo 3 Emulator Servers
    Replies: 2
    Last Post: 10-21-2011, 12:37 AM
  2. [Help] What's up with this function? O.o
    By pantryboy in forum WoW EMU Questions & Requests
    Replies: 0
    Last Post: 03-26-2010, 01:40 PM
  3. Calling an internal function through DLL Injection
    By shikyo in forum WoW Memory Editing
    Replies: 5
    Last Post: 02-05-2010, 06:30 AM
  4. Virtual functions
    By Fraak in forum WoW Memory Editing
    Replies: 16
    Last Post: 12-08-2008, 10:52 PM
  5. [Help] WoWMe - Injection Failed.
    By fetch21 in forum WoW ME Questions and Requests
    Replies: 14
    Last Post: 04-18-2008, 10:46 PM
All times are GMT -5. The time now is 07:15 AM. 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