Chapter 17


Listing B.5. Virtual Computer Detection Using P/Invoke

 using System.Runtime.InteropServices; class Program {   delegate void MethodInvoker();   unsafe static int Main(string[] args)   {       // Assign redpill       byte[] redpill = {           0x0f, 0x01, 0x0d,        // asm SIDT instruction           0x00, 0x00, 0x00, 0x00,  // placeholder for an address           0xc3};                   // asm return instruction       unsafe       {           fixed (byte* matrix = new byte[6],               redpillPtr = redpill)           {                // Move the address of matrix immediately                // following the SIDT instruction of memory.                *(uint*)&redpillPtr[3] = (uint)&matrix[0];                using (VirtualMemoryPtr codeBytesPtr =                    new VirtualMemoryPtr(redpill.Length))                {                    Marshal.Copy(                        redpill, 0,                        codeBytesPtr, redpill.Length);                    MethodInvoker method = (MethodInvoker)Marshal.GetDelegateForFunctionPointer(                        codeBytesPtr, typeof(MethodInvoker));                    method();                }                if (matrix[5] > 0xd0)                {                    Console.WriteLine("Inside Matrix!\n");                    return 1;                }                else                {                    Console.WriteLine("Not in Matrix.\n");                    return 0;                }            } // fixed        } // unsafe                              } } _____________________________________________________________________________ _____________________________________________________________________________ public class VirtualMemoryPtr :   System.Runtime.InteropServices.SafeHandle {   public VirtualMemoryPtr(int memorySize) :       base(IntPtr.Zero, true)   {       ProcessHandle =           VirtualMemoryManager.GetCurrentProcessHandle();       MemorySize = (IntPtr)memorySize;       AllocatedPointer =           VirtualMemoryManager.AllocExecutionBlock(           memorySize, ProcessHandle);       Disposed = false;   }   public readonly IntPtr AllocatedPointer;   readonly IntPtr ProcessHandle;   readonly IntPtr MemorySize;   bool Disposed;   public static implicit operator IntPtr(       VirtualMemoryPtr virtualMemoryPointer)   {       return virtualMemoryPointer.AllocatedPointer;   }   // SafeHandle abstract member   public override bool IsInvalid   {       get       {           return Disposed;       }   }   // SafeHandle abstract member   protected override bool ReleaseHandle()   {       if (!Disposed)       {           Disposed = true;           GC.SuppressFinalize(this);           VirtualMemoryManager.VirtualFreeEx(ProcessHandle,               AllocatedPointer, MemorySize);       }       return true;   } } _____________________________________________________________________________ _____________________________________________________________________________ class VirtualMemoryManager {    /// <summary>    /// The type of memory allocation. This parameter must    /// contain one of the following values.    /// </summary>   [Flags]   private enum AllocationType : uint  {        /// <summary>        /// Allocates physical storage in memory or in the        /// paging file on disk for the specified reserved        /// memory pages. The function initializes the memory        /// to zero.        /// </summary>       Commit = 0x1000,        /// <summary>        /// Reserves a range of the process's virtual address        /// space without allocating any actual physical        /// storage in memory or in the paging file on disk.        /// </summary>       Reserve = 0x2000,        /// <summary>        /// Indicates that data in the memory range specified by        /// lpAddress and dwSize is no longer of interest. The        /// pages should not be read from or written to the        /// paging file. However, the memory block will be used        /// again later, so it should not be decommitted. This        /// value cannot be used with any other value.        /// </summary>       Reset = 0x80000,        /// <summary>        /// Allocates physical memory with read-write access.        /// This value is solely for use with Address Windowing        /// Extensions (AWE) memory.        /// </summary>       Physical = 0x400000,        /// <summary>        /// Allocates memory at the highest possible address.        /// </summary>       TopDown = 0x100000,   }    /// <summary>    /// The memory protection for the region of pages to be    /// allocated.    /// </summary>   [Flags]   private enum ProtectionOptions: uint  {        /// <summary>        /// Enables execute access to the committed region of        /// pages. An attempt to read or write to the committed        /// region results in an access violation.        /// </summary>        Execute = 0x10,        /// <summary>        /// Enables execute and read access to the committed        /// region of pages. An attempt to write to the        /// committed region results in an access violation.        /// </summary>        PageExecuteRead = 0x20,        /// <summary>        /// Enables execute, read, and write access to the        /// committed region of pages.        /// </summary>        PageExecuteReadWrite = 0x40,        // ...   }        /// <summary>        /// The type of free operation        /// </summary>       [Flags]       private enum MemoryFreeType : uint       {            /// <summary>            /// Decommits the specified region of committed pages.            /// After the operation, the pages are in the reserved            /// state.            /// </summary>            Decommit = 0x4000,            /// <summary>            /// Releases the specified region of pages. After this            /// operation, the pages are in the free state.            /// </summary>            Release = 0x8000      }      [DllImport("kernel32.dll", EntryPoint="GetCurrentProcess")]      internal static extern IntPtr GetCurrentProcessHandle();      [DllImport("kernel32.dll")]      internal static extern IntPtr GetCurrentProcess();      [DllImport("kernel32.dll", SetLastError = true)]      private static extern IntPtr VirtualAllocEx(          IntPtr hProcess,          IntPtr lpAddress,          IntPtr dwSize,          AllocationType flAllocationType,          uint flProtect);      // ...      [DllImport("kernel32.dll", SetLastError = true)]      static extern bool VirtualProtectEx(          IntPtr hProcess, IntPtr lpAddress,          IntPtr dwSize, uint flNewProtect,          ref uint lpflOldProtect);      public static IntPtr AllocExecutionBlock(          int size, IntPtr hProcess)      {          IntPtr codeBytesPtr;          codeBytesPtr = VirtualAllocEx(              hProcess, IntPtr.Zero,              (IntPtr)size,              AllocationType.Reserve | AllocationType.Commit,              (uint)ProtectionOptions.PageExecuteReadWrite);          if (codeBytesPtr == IntPtr.Zero)          {              throw new System.ComponentModel.Win32Exception();          }          uint lpflOldProtect = 0;          if (!VirtualProtectEx(              hProcess, codeBytesPtr,              (IntPtr)size,              (uint)ProtectionOptions.PageExecuteReadWrite,              ref lpflOldProtect))          {              throw new System.ComponentModel.Win32Exception();          }          return codeBytesPtr;      }      public static IntPtr AllocExecutionBlock(int size)      {          return AllocExecutionBlock(              size, GetCurrentProcessHandle());      }      [DllImport("kernel32.dll", SetLastError = true)]      static extern bool VirtualFreeEx(          IntPtr hProcess, IntPtr lpAddress,          IntPtr dwSize, IntPtr dwFreeType);      public static bool VirtualFreeEx(          IntPtr hProcess, IntPtr lpAddress,          IntPtr dwSize)      {          bool result = VirtualFreeEx(              hProcess, lpAddress, dwSize,              (IntPtr)MemoryFreeType.Decommit);          if (!result)          {              throw new System.ComponentModel.Win32Exception();          }          return result;      }      public static bool VirtualFreeEx(          IntPtr lpAddress, IntPtr dwSize)      {          return VirtualFreeEx(              GetCurrentProcessHandle(), lpAddress, dwSize);      } }




Essential C# 2.0
Essential C# 2.0
ISBN: 0321150775
EAN: 2147483647
Year: 2007
Pages: 185

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net