<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Rezo</title>
    <description>The latest articles on DEV Community by Rezo (@gervantofryvia).</description>
    <link>https://dev.to/gervantofryvia</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2613363%2Feef0705d-7486-4a87-95a3-894950f4d45d.jpg</url>
      <title>DEV Community: Rezo</title>
      <link>https://dev.to/gervantofryvia</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gervantofryvia"/>
    <language>en</language>
    <item>
      <title>DLL injection of managed code into native process</title>
      <dc:creator>Rezo</dc:creator>
      <pubDate>Fri, 27 Dec 2024 10:47:21 +0000</pubDate>
      <link>https://dev.to/gervantofryvia/dll-injection-of-managed-code-into-native-process-3jo6</link>
      <guid>https://dev.to/gervantofryvia/dll-injection-of-managed-code-into-native-process-3jo6</guid>
      <description>&lt;h1&gt;
  
  
  &lt;strong&gt;Getting started&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Project repository with full code is accessible on GitHub &lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/RtlZeroMemory/Injector.C" rel="noopener noreferrer"&gt;Link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;DLL injection is a powerful technique that allows us to inject custom code into a third-party process. It can be useful in various scenarios.&lt;/p&gt;

&lt;p&gt;DLL injection is often used by &lt;strong&gt;malware&lt;/strong&gt; to inject code into running processes, such as system processes like &lt;code&gt;svchost.exe&lt;/code&gt; or &lt;code&gt;explorer.exe&lt;/code&gt;, and execute malicious functionality within them.&lt;/p&gt;

&lt;p&gt;Malware usually resides inside existing process and acts as parasite to be harder to detect. It can use either DLL injection or full PE injection which is much more sophisticated method. &lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Extending Program Functionality with DLL Injection&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;DLL injection isn't just for malicious purposes—it can also be a legitimate tool for &lt;strong&gt;extending existing program functionality&lt;/strong&gt;. For example, you can use it to develop plugins for software.&lt;/p&gt;

&lt;p&gt;Imagine you want to &lt;strong&gt;log every action&lt;/strong&gt; that happens inside a process, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Network calls&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;File system writes&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By using &lt;strong&gt;function hooking&lt;/strong&gt;, you can intercept method calls within the process after injecting your DLL. &lt;/p&gt;

&lt;p&gt;Function hooking allows you to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Intercept and monitor API calls&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modify input/output of functions&lt;/strong&gt; as needed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Extend a process's behavior&lt;/strong&gt; dynamically without modifying its source code.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This makes DLL injection a versatile tool for developers, researchers, and security professionals alike.&lt;/p&gt;

&lt;p&gt;For instance:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hook the &lt;code&gt;WriteFile&lt;/code&gt; function to capture details about file writes happening inside the process.&lt;/li&gt;
&lt;li&gt;Log this information for debugging, monitoring, or analysis.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;How WINAPI Works&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;When a Windows process (PE - &lt;strong&gt;Portable Executable&lt;/strong&gt;) is started by the operating system's &lt;strong&gt;PE loader&lt;/strong&gt;, it loads all essential libraries required for the process into its address space.&lt;/p&gt;

&lt;p&gt;This includes libraries such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;kernel32.dll&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ntdll.dll&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;user32.dll&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each Windows process can obtain access (&lt;strong&gt;HANDLE&lt;/strong&gt;) to libraries loaded into it using the &lt;code&gt;GetModuleHandle&lt;/code&gt; method. It can then retrieve individual methods using &lt;code&gt;GetProcAddress&lt;/code&gt; and call them.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;kernel32.dll&lt;/strong&gt;: Contains higher-level functions for tasks like memory management, file handling, and threading.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ntdll.dll&lt;/strong&gt;: Contains lower-level counterparts, usually prefixed with "Nt", such as &lt;code&gt;NtQuerySystemInformation&lt;/code&gt;, which retrieves information about running processes in the operating system.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;The Flow of a WinAPI Call&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;When you call a WinAPI function, control is passed to &lt;code&gt;ntdll.dll&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ntdll.dll&lt;/code&gt; uses a special routine like &lt;code&gt;KiFastSystemCall&lt;/code&gt; to pass control to the &lt;strong&gt;Windows kernel&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Inside the kernel, a lookup table called the &lt;strong&gt;System Service Dispatch Table (SSDT)&lt;/strong&gt; is used to locate the actual implementation of the function.&lt;/li&gt;
&lt;li&gt;The function executes in &lt;strong&gt;kernel mode&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Once complete, control is returned back to &lt;strong&gt;user mode&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;How DLL Injection Works&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Steps to Inject a DLL&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Open the Target Process&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
Use &lt;code&gt;OpenProcess&lt;/code&gt; to get a handle to the target process with sufficient privileges.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Allocate Memory in the Target Process&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
Call &lt;code&gt;VirtualAllocEx&lt;/code&gt; to reserve space in the target process for the DLL path or custom code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Write the DLL Path&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
Use &lt;code&gt;WriteProcessMemory&lt;/code&gt; to copy the DLL path or custom code into the allocated memory.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Load the DLL&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
Locate the address of &lt;code&gt;LoadLibraryA&lt;/code&gt; or &lt;code&gt;LoadLibraryW&lt;/code&gt; using &lt;code&gt;GetProcAddress&lt;/code&gt;, and then use &lt;code&gt;CreateRemoteThread&lt;/code&gt; to execute it in the target process. This loads the DLL into the process.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Execute the DLL Code&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
Once the DLL is loaded, its &lt;code&gt;DllMain&lt;/code&gt; function is called by the process's loader.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;What Happens After Injection&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Your DLL is &lt;strong&gt;loaded&lt;/strong&gt; into the target process's address space via &lt;code&gt;LoadLibrary&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;Windows PE loader&lt;/strong&gt; calls your DLL’s &lt;code&gt;DllMain&lt;/code&gt; entry point.&lt;/li&gt;
&lt;li&gt;Any code in your DLL, such as hooks or logging, starts running &lt;strong&gt;in the context of the target process&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;Full flow of this program&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Injects a native C library&lt;/strong&gt; into a native running process, such as &lt;code&gt;notepad.exe&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The injected library &lt;strong&gt;loads the CoreCLR runtime&lt;/strong&gt; into the target process.&lt;/li&gt;
&lt;li&gt;It then &lt;strong&gt;loads a managed C# DLL&lt;/strong&gt; into the process's address space and calls its entry point method (&lt;code&gt;Main&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;The C# DLL &lt;strong&gt;executes within the unmanaged process&lt;/strong&gt; and calls the &lt;code&gt;MessageBox&lt;/code&gt; function.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This DLL outputs current process information in a MessageBox after being injected into native process, in this case notepad. &lt;/p&gt;

&lt;p&gt;After starting injector end result looks like this&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvawebqsxfgz415s3om4n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvawebqsxfgz415s3om4n.png" alt="Image description" width="800" height="75"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frn6u54k1ojg94gpx11hz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frn6u54k1ojg94gpx11hz.png" alt="Image description" width="316" height="151"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;NOTES:&lt;/p&gt;

&lt;p&gt;To run this example you can clone repository and edit source code to include correct path to CoreCLR and injected library inside source code. Right now everything is hardcoded. &lt;br&gt;
Code for injected DLL:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
csharp
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace InjectLib.Managed
{
    public static class InjectLibManaged
    {
        const uint MB_OK = 0x00000000;
        const uint MB_ICONFIRMATION = 0x00000040; 

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern int MessageBox(IntPtr hWnd, string text, string caption, uint type);

        public static void Main()
        {
            var proc = Process.GetCurrentProcess();
            MessageBox(
                IntPtr.Zero,
                $"Hello from Process with Id: {proc.Id}, {proc.ProcessName}",
                "Hello from injected DLL",
                MB_OK | MB_ICONFIRMATION
            );

            Thread.Sleep(50000);
        }
    }
}



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>net</category>
      <category>winapi</category>
      <category>cybersecurity</category>
      <category>dllinjection</category>
    </item>
  </channel>
</rss>
