Debug Shellcode in a Managed C# .NET Program with Visual Studio

87 views Asked by At

I'm looking at this project that shows how to call unmanaged shellcode from a C# program. I want to debug and step through the shellcode but can't seem to make this happen. I can step into the unmanaged code and VS single steps and will eventually finish stepping through the shellcode but I can't see any disassembly in the Disassembly window (only the managed C# disassembly, where it makes a call instruction to the unmanaged code). How can I see this unmanaged disassembly? enter image description here

I've tried "Enable native code debugging" in the project Debug properties. Unchecking "Enable Just my code" in the VS -> Tools -> Options -> Debugging -> General. I've even tried attaching WinDbg Preview to the running process with a non-invasive attach (with the goal of starting a new instance and attaching invasively), but when I try to detach VS (must have Enable native code debugging disabled first) it just hangs and won't become responsive again until I detach or stop the debugging session with WinDbg.

Here's a copy of the code with a simple shellcode embedded:

using System;
using System.Runtime.InteropServices;
using System.Text;

namespace Shell {
    class Program {

        [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
        static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);

        [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
        static extern IntPtr VirtualFree(IntPtr lpAddress, uint dwSize, uint dwFreeType);

        delegate UInt32 HashPrototype(byte[] InputText);

        static void Main(string[] args) {

            byte[] shellcode = new byte[] 
            {
                0xBA, 0xC5, 0x9D, 0x1C, 0x81, 0xEB, 0x0B, 0x0F, 0xBE, 0xC0, 0x33, 0xC2, 0x69, 0xD0, 0x93, 0x01,
                0x00, 0x01, 0x8A, 0x01, 0x48, 0xFF, 0xC1, 0x84, 0xC0, 0x75, 0xEC, 0x8B, 0xC2, 0xC3
            };

            IntPtr buffer = VirtualAlloc(IntPtr.Zero, (uint)shellcode.Length, 0x1000, 0x40);
            Marshal.Copy(shellcode, 0, buffer, shellcode.Length);
            HashPrototype MyHashingFunction = (HashPrototype)Marshal.GetDelegateForFunctionPointer(buffer, typeof(HashPrototype));

            byte[] stringArray = ASCIIEncoding.ASCII.GetBytes("Fergo\0");
            UInt32 hashedResult = MyHashingFunction(stringArray);

            VirtualFree(buffer, 0, 0x8000);

            Console.WriteLine("Here is hashed result in hex: {0:X8}", hashedResult);

            Console.ReadLine();
        }
    }
}
0

There are 0 answers