Home Upgrade Search Memberlist Extras Hacker Tools Award Goals Help Wiki Contact

C# 

Executing Shellcode In C# (No Imports Required)

Someone on Tuts4You made a request to make a way to invoke shellcode within C# without any imports to things such as VirtualAlloc / VirtualProtect etc. I came up with this method as all of C#'s built-in memory allocations via the Marshal class and similar all create with no execution access for protection purposes.

This method makes use of a memory mapped file which can be created with any protections that you want instead. This can be done all via the .NET frameworks built-in classes and such with no imports via DllImport. This is a simple example of creating a function via shellcode to get the PEB of a process. (Cheers to evlncrn8 for adjusting the shellcode from my original post to be more optimized.)

PHP Code

<?php 
/**
 * C# Shellcode Example
 * (c) 2017 atom0s [[email protected]]
 *
 * Demonstrates how to invoke shellcode within C# using a memory mapped file.
 */
 
namespace ShellcodeExample
{
    
using System;
    
using System.IO.MemoryMappedFiles;
    
using System.Runtime.InteropServices;
 
    class 
Program
    
{
        
/// <summary>
        /// Function delegate to invoke the shellcode.
        /// </summary>
        /// <returns></returns>
        
private delegate IntPtr GetPebDelegate();
 
        
/// <summary>
        /// Shellcode function used to obtain the PEB of the process.
        /// </summary>
        /// <returns></returns>
        
private unsafe static IntPtr GetPeb()
        {
           var 
shellcode = new byte[]
               {
                   
0x64, 0xA1, 0x30, 0x00, 0x00, 0x00,         // mov eax, dword ptr fs:[30]
                   
0xC3                                        // ret
               
};
 
            
MemoryMappedFile mmf = null;
            
MemoryMappedViewAccessor mmva = null;
 
            try
            {
                
// Create a read/write/executable memory mapped file to hold our shellcode..
                
mmf = MemoryMappedFile.CreateNew("__shellcode", shellcode.Length, MemoryMappedFileAccess.ReadWriteExecute);
 
                
// Create a memory mapped view accessor with read/write/execute permissions..
                
mmva = mmf.CreateViewAccessor(0, shellcode.Length, MemoryMappedFileAccess.ReadWriteExecute);
 
                
// Write the shellcode to the MMF..
                
mmva.WriteArray(0, shellcode, 0, shellcode.Length);
 
                
// Obtain a pointer to our MMF..
                
var pointer = (byte*)0;
                
mmva.SafeMemoryMappedViewHandle.AcquirePointer(ref pointer);
 
                
// Create a function delegate to the shellcode in our MMF..
                
var func = (GetPebDelegate)Marshal.GetDelegateForFunctionPointer(new IntPtr(pointer), typeof(GetPebDelegate));
 
                
// Invoke the shellcode..
                
return func();
            }
            catch
            {
                return 
IntPtr.Zero;
            }
            finally
            {
                
mmva?.Dispose();
                
mmf?.Dispose();
            }
        }
 
        
/// <summary>
        /// Entry point.
        /// </summary>
        /// <param name="args"></param>
        
static void Main(string[] args)
        {
            var 
peb = GetPeb();
            
Console.WriteLine("PEB is located at: {0:X8}", peb.ToInt32());
        }
    }
} 

I am aware of the various assembly projects made for C# such as FASM and AssemblyJitter etc. however these projects all require external imports which was the goal of this idea, to not need any.
Short and simple piece of code but works well
good release buddy
Didn't know you were on here atom0s. Nice post and also I like your Lua stuff from back in the day
[Image: Syr3DlV.png]
(May 3, 2017 07:17 PM)gigajew Wrote:  Didn't know you were on here atom0s. Nice post and also I like your Lua stuff from back in the day

Oh, hello there giga :)

Yes, good to have a completely managed solution.
[Image: PVoDiqS.png]
the thing is that its work just with unsafe code so you cant use it with vb net
but theres a trick to get it in vb too
and needed framework 4
[Image: bitcoin.png] Be Nice For Once 15hVUVz7xA4kazHdk2BuErENGCskVwjYXP
(May 3, 2017 07:17 PM)gigajew Wrote:  Didn't know you were on here atom0s. Nice post and also I like your Lua stuff from back in the day

I pop on from time to time, haven't posted much at all lately though.

(May 4, 2017 08:23 AM)HFDone Wrote:  the thing is that its work just with unsafe code so you cant use it with vb net
but theres a trick to get it in vb too
and needed framework 4

I don't code in Vb.NET since it is basically trash. Plus the point of this was to be done in C# anyway. I suggest you move to a better language rather than sticking it out with Vb.NET if that is what you code in.
i code in many languages. i say it cuz its the net section and even with C# you need to use unsafe code option.
as i said theres a trick that you can use it without unsafe code anyway its good to have option to do it without using apis.
[Image: bitcoin.png] Be Nice For Once 15hVUVz7xA4kazHdk2BuErENGCskVwjYXP
I actually didn't know that this was possible. Good release!
You are forgetting to release the acquired pointer within a CER region of your code. There's other issues with this if you tested on various operating systems, this is specific to x32 processes only; PEB isn't at fs:[0x30] in x64.

edit:
Code
private delegate IntPtr GetPebDelegate();

private static unsafe IntPtr GetPeb()
{
    byte *pCode = null;
    MemoryMappedFile mmf = null;
    MemoryMappedViewAccessor mmva = null;

    var asm = new[]
    {
        new byte[]
        {
            0x64, 0xA1, 0x30, 0x00, 0x00, 0x00, // mov eax, dword ptr fs:30
            0xC3 // ret
        },
        new byte[]
        {
            0x65, 0x48, 0x8B, 0x04, 0x25, 0x60, 0x00, 0x00, 0x00, // mov rax, qword ptr gs:0x60
            0xC3 // ret
        }
    };

    var shellcode = asm[IntPtr.Size / 8];
    RuntimeHelpers.PrepareConstrainedRegions();
    try
    {
        mmf = MemoryMappedFile.CreateNew("__PEB_Address", shellcode.Length, MemoryMappedFileAccess.ReadWriteExecute);
        mmva = mmf.CreateViewAccessor(0, shellcode.Length, MemoryMappedFileAccess.ReadWriteExecute);
        mmva.WriteArray(0, shellcode, 0, shellcode.Length);
        mmva.SafeMemoryMappedViewHandle.AcquirePointer(ref pCode);

        if (pCode != null)
        {
            return ((GetPebDelegate)Marshal.GetDelegateForFunctionPointer(new IntPtr(pCode), typeof(GetPebDelegate)))();
        }
    }
    catch (Exception ex)
    {
        Debug.WriteLine(ex.ToString());
    }
    finally
    {
        if (mmva != null)
        {
            if (pCode != null)
            {
                mmva.SafeMemoryMappedViewHandle.ReleasePointer();
            }
            mmva.Dispose();
        }
        mmf?.Dispose();
    }

    return IntPtr.Zero;
}
Getting Started: C/C++
[C/C++/.NET/x86 ASM - Automation Programmer]
(May 7, 2017 01:18 PM)0xDEAD10CC Wrote:  You are forgetting to release the acquired pointer within a CER region of your code. There's other issues with this if you tested on various operating systems, this is specific to x32 processes only; PEB isn't at fs:[0x30] in x64.

I'm aware of the 32bit limitation, the purpose of the example was just to demonstrate the abilities on how to do this. And was pointed out on my Tuts4You post but forgot to mention it here. Granted I'm sure people that understand how this works and would understand how to use it can put the brain cells together to figure that out themselves.

As for full error checking and all that junk, that's up to the user to implement and more less anti-copy/pasta for the derps that land up erroring things.


Possibly Related Threads...
Thread / Author Replies Views Last Post
by CL1BFeb 4, 2026 04:24 AM 0 115 Feb 4, 2026 04:24 AM
Last Post: CL1B
[C#] by SmokyMay 4, 2024 07:40 AM 4 367 May 4, 2024 07:40 AM
Last Post: COCKBOT
by hanterokJun 26, 2023 01:04 PM 4 399 Jun 26, 2023 01:04 PM
Last Post: hanterok