__fastcall with C# using a C++ wrapper? menu

User Tag List

Results 1 to 10 of 10
  1. #1
    Reghero's Avatar Member
    Reputation
    11
    Join Date
    Jun 2017
    Posts
    35
    Thanks G/R
    29/7
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    __fastcall with C# using a C++ wrapper?

    I've spent the best part of the last week trying to get my head around this part of the implementation and I've hit a point where I'm not quite sure what to do.

    Originally read through this: https://drewkestell.us/Article/6/Chapter/7 which I believe is slightly outdated now as I think the signature has changed from (pseudo) __fastcall ((int, int), int) to __fastcall((__fastcall)(int, int), int)). If I try and call the C++ function as is with no changes using the following:

    Code:
    void __declspec(dllexport) __stdcall EnumerateVisibleObjects(unsigned int callback, int filter, unsigned int ptr)
        {    	
            typedef char __fastcall func(unsigned int callback, int64_t filter);
            func* function = (func*)ptr;
            function(callback, filter);
        }
    C# caller

    Code:
    [DllImport("FastCall.dll", EntryPoint = "EnumerateVisibleObjects")]
            static extern void EnumerateVisibleObjects(IntPtr callback, long filter, IntPtr ptr);
    
            internal static void EnumerateVisibleObjects(IntPtr callback, long filter) =>
                EnumerateVisibleObjects(
                    callback,
                    filter,
                    System.Diagnostics.Process.GetCurrentProcess().MainModule.BaseAddress + 0x12DECA0
                );
    
    
    void Test()
    {
    var callbackPtr = Marshal.GetFunctionPointerForDelegate(callback);
    
                    ThreadSynchronizer.RunOnMainThread(() =>
                    {
                        Functions.EnumerateVisibleObjects(callbackPtr, 0);
                    });
    }
    
    static int Callback(IntPtr one, IntPtr two)
            {
                MessageBox.Show("Got call");
    
                return 1;
            }
    The app is injected and running within the Wow process.

    __fastcall with C# using a C++ wrapper?
  2. #2
    0xa4fba0's Avatar Member Authenticator enabled
    Reputation
    2
    Join Date
    May 2020
    Posts
    7
    Thanks G/R
    0/1
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    x64 only uses the __fastcall

    you should change unsigned int -> unitptr_t
    the uint is uint32_t (where ptr on x64 is not)

  3. Thanks Reghero (1 members gave Thanks to 0xa4fba0 for this useful post)
  4. #3
    Reghero's Avatar Member
    Reputation
    11
    Join Date
    Jun 2017
    Posts
    35
    Thanks G/R
    29/7
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by 0xa4fba0 View Post
    x64 only uses the __fastcall

    you should change unsigned int -> unitptr_t
    the uint is uint32_t (where ptr on x64 is not)
    Thanks.

    I've made that change:

    Code:
    void __declspec(dllexport) __stdcall EnumerateVisibleObjects(uintptr_t callback, int filter, unsigned int ptr)
        {    	
            typedef char __fastcall func(uintptr_t callback, int64_t filter);
            func* function = (func*)ptr;
            function(callback, filter);
        }
    C#

    Code:
    [DllImport("FastCall.dll", EntryPoint = "EnumerateVisibleObjects")]
            static extern void EnumerateVisibleObjects(IntPtr callback, long filter, IntPtr ptr);
    
            internal static void EnumerateVisibleObjects(IntPtr callback, long filter) =>
                EnumerateVisibleObjects(
                    callback,
                    filter,
                    System.Diagnostics.Process.GetCurrentProcess().MainModule.BaseAddress + 0x12DECA0
                );
    This still gets me:

    crashmem.PNG

  5. #4
    0xa4fba0's Avatar Member Authenticator enabled
    Reputation
    2
    Join Date
    May 2020
    Posts
    7
    Thanks G/R
    0/1
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    your crash location looks wrong

    System.Diagnostics.Process.GetCurrentProcess().MainModule.BaseAddress <- should be baseaddr of wow.exe

  6. #5
    Jadd's Avatar 🐸 Premium Seller
    Reputation
    1511
    Join Date
    May 2008
    Posts
    2,432
    Thanks G/R
    81/333
    Trade Feedback
    1 (100%)
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Why do you use a C++ stub? It's completely unnecessary.

  7. #6
    InnerSilence's Avatar Active Member
    Reputation
    29
    Join Date
    Oct 2019
    Posts
    92
    Thanks G/R
    13/16
    Trade Feedback
    0 (0%)
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Jadd View Post
    Why do you use a C++ stub? It's completely unnecessary.
    As Jadd mentioned you dont need cpp stub.,
    Also you were still using unsigned int as a pointer "ptr" in your C code

  8. #7
    Reghero's Avatar Member
    Reputation
    11
    Join Date
    Jun 2017
    Posts
    35
    Thanks G/R
    29/7
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Jadd View Post
    Why do you use a C++ stub? It's completely unnecessary.
    Would you mind expanding? My understanding was that C# had no ability to call unmanaged fastcall direct in process.

    Originally Posted by InnerSilence View Post
    As Jadd mentioned you dont need cpp stub.,
    Also you were still using unsigned int as a pointer "ptr" in your C code
    Thanks, I've changed that but with similar results.

    Originally Posted by 0xa4fba0 View Post
    your crash location looks wrong

    System.Diagnostics.Process.GetCurrentProcess().MainModule.BaseAddress <- should be baseaddr of wow.exe
    I double checked the base address and it is based on Wowclassic.exe and comparing that to the one that Process.NET gets me, they are both the same.
    Last edited by Reghero; 07-11-2021 at 04:16 AM.

  9. #8
    InnerSilence's Avatar Active Member
    Reputation
    29
    Join Date
    Oct 2019
    Posts
    92
    Thanks G/R
    13/16
    Trade Feedback
    0 (0%)
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Reghero View Post
    Would you mind expanding? My understanding was that C# had no ability to call unmanaged fastcall direct in process.



    Thanks, I've changed that but with similar results.



    I double checked the base address and it is based on Wowclassic.exe and comparing that to the one that Process.NET gets me, they are both the same.
    In the 64-bit apps, pinvoke marshaller only supports the x64 ABI which is based on __fastcall anyway. Using Marshal.GetDelegateForFunctionPointer u should be able to create a delegate and call that function.

  10. #9
    0xa4fba0's Avatar Member Authenticator enabled
    Reputation
    2
    Join Date
    May 2020
    Posts
    7
    Thanks G/R
    0/1
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    you can check Errors folder for crash stack
    wow code addresses are close to 0x00007ffxxxxxxx typically

  11. #10
    Reghero's Avatar Member
    Reputation
    11
    Join Date
    Jun 2017
    Posts
    35
    Thanks G/R
    29/7
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Got it working! Thanks all:

    Code:
    [UnmanagedFunctionPointer(CallingConvention.StdCall)]
            delegate long EnumerateVisibleObjectsCallback(IntPtr a, long b);
    
            static EnumerateVisibleObjectsCallback callback;
    
            private static List<WowObject> ObjectBuffer = new List<WowObject>();
    
            public ObjectsController()
            {
                callback = Callback;
                callbackPtr = Marshal.GetFunctionPointerForDelegate(callback);
            }
    
    [Route("enumObjects")]
            public IHttpActionResult GetEnumObjects()
            {
                var pointer = System.Diagnostics.Process.GetCurrentProcess().MainModule.BaseAddress + ENUMERATE_VISIBLE_OBJECTS_FUN_PTR;
                EnumerateVisibleObjectsFunc func = (EnumerateVisibleObjectsFunc)Marshal.GetDelegateForFunctionPointer(pointer, typeof(EnumerateVisibleObjectsFunc));
                ObjectBuffer.Clear();
                var rc = func(this.callbackPtr, 0);
                
    
    
                return Json(true);
            }
    
    static long Callback(IntPtr ptr, long guid)
            {
                ObjectBuffer.Add(new WowObject(new ProcessSharp("WowClassic", MemoryType.Local), ptr));
                return 1;
            }
    Has anyone recently injected WPF into WoW? I've stopping trying to get my WPF solution working in process and have instead resorted to using a gRPC service to handle communication between the UI and the bot itself. Would love to know if it's possible to inject in WPF without instantly crashing wow though!

Similar Threads

  1. [Hack] Make a Guild Name with Numbers using OllyDBG
    By wickermanz in forum World of Warcraft Bots and Programs
    Replies: 14
    Last Post: 11-06-2015, 11:17 AM
  2. [Help] Interact with addon using macro
    By xMythx in forum WoW UI, Macros and Talent Specs
    Replies: 2
    Last Post: 07-27-2011, 09:12 PM
  3. Float in Air With Vehicles (Useful in WG)
    By Scrubs in forum World of Warcraft Exploits
    Replies: 13
    Last Post: 06-29-2009, 06:06 PM
  4. Wow Angelbot with Memory using
    By hamburger1 in forum WoW Memory Editing
    Replies: 1
    Last Post: 05-03-2009, 02:15 PM
All times are GMT -5. The time now is 04:13 PM. 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