Destructor's Tutorial: Managed .NET DLL Injection menu

User Tag List

Results 1 to 2 of 2
  1. #1
    ugkbunb's Avatar Member
    Reputation
    3
    Join Date
    May 2008
    Posts
    16
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Destructor's Tutorial: Managed .NET DLL Injection

    Hopefully some of this will find it useful. I am not the author, Destructor posted this over at EON. Feel free to delete this post if you feel it is redudant.

    copypaste'd in full
    Originally Posted by Destructor
    I spent the past couple of days researching the .NET Runtime and how to injected managed libraries. I decided to share my findings with you guys.

    As many of you guys know, there are two types of applications that we are dealing with: native (the standard unmanaged C and C++ applications such as Diablo II) and managed (the .NET type of applications using a runtime).

    At first, I (and many others I'm sure) assumed that there is a huge brick wall divided the two and that the two types are exclusive. This is, in fact, completely incorrect. When I discovered this, I tried what many others have probably tried: injecting the .NET static library into Diablo II. Sure, this works fine. You can look in the target application and verify that the .NET DLL was loaded. But now what to do? There is no entrypoint such as DllMain. After long hours of attempting to define a static entrypoint, I decided to look into another method.

    A few hours of traversing msdn led me to a nice interface: ICLRRuntimeHost. This interface is the key to our managed DLL injection. The following C++ application will host a managed .NET DLL. (Error checking excluded for brevity)


    Code:
    int main()
    {
       ICLRRuntimeHost* pCLR = NULL;
       DWORD result;
    
       // start the .NET Runtime in the current native process
       CorBindToRuntimeEx(NULL, L"wks", NULL, CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (LPVOID*)&pCLR);
       pCLR->Start();
    
       // execute the method "Int32 Test.Program.InjectedMain(String arg)"
       pCLR->ExecuteInDefaultAppDomain(L"C:\\test.dll", L"Test.Program", L"InjectedMain", L"It works!", &result);
    
       // the return value of InjectedMain is stored into "result"
       return result;
    }
    So now that we have successfully called a .NET function, the world is C# world is ours... oh wait... we almost forgot we need Diablo II to run this. Right about now fireworks should be shooting inside your head. We can use CreateRemoteThread to force Diablo to to run the functions. There are a few things to keep in mind:

    1. The functions are stored in the mscoree.dll. This will need to be injected!
    2. All strings are in Unicode, not ANSI.
    3. Only CorBindToRuntimeEx is static, the remaining functions are in the virtual function table.

    Since most of Diablo II uses static functions, I will give a breif explanation of virtual interface functions. The very first field in a class (offset 0x00) is the virtual function table. This contains a list of function pointers corresponding to static functions. Each of these functions contains at least one parameter: the "this" pointer of the owning class. After that all parameters are listed in order. An example is shown below:


    Code:
    class Calc
    {
       private:
          long sum;
    
       public:
          virtual long Add(int a, int b) = 0;
          virtual long Subtract(int a, int b) = 0;
    }
    This gets stored as follows:

    Code:
    static long Add(Calc* instance, int a, int b);
    static long Subtract(Calc* instance, int a, int b);
    
    struct Calc
    {
       FunctionPointer vft[] = { Add, Subtract };
       long sum;   
    }

    Rather than taking the time to understand how to parse the VFT (as this is compiler dependent), I simply dissassembled the functions and found their offsets in the VFT. This way all we have to do is to read the pointer at the offset in the VFT and call it passing the instance and the parameters.

    Offsets in VFT (found via IDA Pro):
    Start - 0x0C
    ExecuteInDefaultAppDomain - 0x2c
    Stop - 0x10
    Release - 0x08

    After a few hours of coding and testing with Diablo II, it worked! I was able to successfully inject my test dll into the Diablo II process, start the .NET runtime, and execute the InjectedMain. To verify that I was actually in the target process, I used this code for InjectedMain:



    Code:
    public delegate void PrintDelegate(Byte[] buffer, Int32 color);
    
    public static IntPtr GetOffset(String module, UInt32 offset)
    {
       IntPtr hModule = Kernel32.GetModuleHandle(module);
       return (IntPtr)(hModule.ToInt32() + offset);
    }
    
    public static T GetDelegateFromOffset<T>(String module, UInt32 offset) where T : class
    {
       IntPtr hProcess = GetOffset(module, offset);
       return Marshal.GetDelegateForFunctionPointer(hProcess, typeof(T)) as T;
    }
    
    public static Int32 InjectedMain(String message)
    {
       try
       {
          PrintDelegate print = GetDelegateFromOffset<PrintDelegate>("d2client", 0x71740);
          print(Encoding.Unicode.GetBytes("Success!"), 4);
       }
       catch (Exception e)
       {
          // make sure to use try-catch to avoid crashing Diablo II
       }
    
       return 0;
    }
    The result? An entire project of only C# code, a gold success message, and a sigh of relief...
    Last edited by ugkbunb; 05-15-2009 at 02:01 PM.

    Destructor's Tutorial: Managed .NET DLL Injection
  2. #2
    Ozzeh's Avatar Member
    Reputation
    1
    Join Date
    Dec 2006
    Posts
    1
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    delete my post please, apparently i cant?

Similar Threads

  1. Replies: 1
    Last Post: 01-19-2012, 03:14 AM
  2. [C#] Managed Dll Injection
    By streppel in forum WoW Memory Editing
    Replies: 26
    Last Post: 06-01-2010, 05:29 AM
  3. exit/unload injected .net dll
    By YetiHunter in forum Programming
    Replies: 5
    Last Post: 02-28-2010, 06:57 AM
  4. [Tutorial] DLL Injection
    By jagged software in forum Programming
    Replies: 22
    Last Post: 04-21-2009, 03:27 AM
  5. [Release] Inject Managed .Net Code!
    By bigtimt in forum WoW Memory Editing
    Replies: 6
    Last Post: 10-12-2008, 03:52 PM
All times are GMT -5. The time now is 11:05 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