using System; using System.Runtime.InteropServices; using System.IO; public delegate uint ExportCallback(IntPtr pbData, [In, Out] MemoryStream memstr, uint cbData); public class RawEFS { [DllImport("advapi32")] public static extern uint OpenEncryptedFileRaw(String filename, uint ulFlags, ref IntPtr pvContext); [DllImport("advapi32")] public static extern uint ReadEncryptedFileRaw(ExportCallback fcback, MemoryStream memstr, IntPtr pvContext ); [DllImport("advapi32")] public static extern void CloseEncryptedFileRaw(IntPtr pvContext); static uint ERROR_SUCCESS = 0; public static void Main(String[] args) { IntPtr pCntxt = IntPtr.Zero; if(args.Length == 0) return; String filename = args[0]; if (filename == "") //exit while(true) loop return; if (!File.Exists(filename)) { Console.WriteLine("File \"{0}\" does not exist!\n", filename); return; } uint openresult = OpenEncryptedFileRaw( filename, 0, ref pCntxt); if(openresult != ERROR_SUCCESS){ Console.WriteLine("Failed to open encrypted file '{0}'", filename); return; } else Console.WriteLine("Opened EFS encrypted file '{0}'", filename) ; ExportCallback myCallback = new ExportCallback(RawEFS.DumpEFS); MemoryStream memstr = new MemoryStream(4000) ; ReadEncryptedFileRaw(myCallback, memstr, pCntxt) ; //get raw efs file data and write to MemoryStream byte[] rawefsdata = memstr.ToArray(); memstr.Close(); if(openresult == ERROR_SUCCESS) CloseEncryptedFileRaw(pCntxt); ShowBytes("\n\nEncrypted EFS raw data", rawefsdata) ; PutFileBytes("_rawEFSdata", rawefsdata, rawefsdata.Length) ; } public static uint DumpEFS(IntPtr pbData, MemoryStream memstr, uint cbData) { byte[] data = new byte[cbData]; Marshal.Copy(pbData, data, 0, (int)cbData) ; memstr.Write(data, 0, (int) cbData) ; return ERROR_SUCCESS ; } private static void ShowBytes(String info, byte[] data){ Console.WriteLine("{0} [{1} bytes]", info, data.Length); for(int i=1; i<=data.Length; i++){ Console.Write("{0:X2} ", data[i-1]) ; if(i%16 == 0) Console.WriteLine(); } Console.WriteLine("\n\n"); } private static void PutFileBytes(String outfile, byte[] data, int bytes) { FileStream fs = null; if(bytes > data.Length) { Console.WriteLine("Too many bytes"); return; } try{ fs = new FileStream(outfile, FileMode.Create); fs.Write(data, 0, bytes); } catch(Exception e) { Console.WriteLine(e.Message) ; } finally { fs.Close(); } } }