/// <summary>
        /// Refer to http://www.cnblogs.com/gjahead/archive/2007/06/18/787654.html
        /// </summary>
        /// <param name="response"></param>
        protected override void WriteFile(HttpResponseBase response)
        {
            #region --验证:HttpMethod,请求的文件是否存在
            switch (request.HttpMethod.ToUpper())
            {
            case "GET":
            case "HEAD":
                break;

            default:
                response.StatusCode = 501;
                return;
            }
            if (!File.Exists(filePath))
            {
                response.StatusCode = 404;
                response.End();
                return;
            }
            #endregion

            #region 定义局部变量
            var startBytes = 0L;
            //分块读取,每块10K bytes
            var packSize          = 1024 * 10;
            var fileName          = Path.GetFileName(filePath);
            var file              = MemoryMappedFile.CreateFromFile(filePath).CreateViewStream();
            var fileLength        = file.Length;
            var sleep             = 0;
            var lastUpdateTiemStr = File.GetLastWriteTimeUtc(filePath).ToString("r");
            //便于恢复下载时提取请求头;
            var eTag = HttpUtility.UrlEncode(fileName, Encoding.UTF8) + lastUpdateTiemStr;
            #endregion

            #region --验证:文件是否太大,是否是续传,且在上次被请求的日期之后是否被修
            //文件太大
            if (file.Length > Int32.MaxValue)
            {
                response.StatusCode = 413;//请求实体太大
            }

            //对应响应头ETag:文件名+文件最后修改时间
            if (request.Headers["If-Range"] != null)
            {
                //上次被请求的日期之后被修改过
                if (request.Headers["If-Range"].Replace("\"", "") != eTag)
                {
                    response.StatusCode = 412;//预处理失败
                }
            }
            #endregion

            using (var br = new BinaryReader(file))
            {
                #region -------添加重要响应头、解析请求头、相关验证-------------------
                response.Clear();
                response.Buffer = false;
                //用于验证文件
                // TODO: 验证MD5生成方式是否正确,这里对整个文件Hash,似乎有问题。
                response.AddHeader("Content-MD5", GetMd5Hash(file));
                //重要:续传必须
                response.AddHeader("Accept-Ranges", "bytes");
                //重要:续传必须
                response.AppendHeader("ETag", "\"" + eTag + "\"");
                response.AppendHeader("Last-Modified", lastUpdateTiemStr); //把最后修改日期写入响应
                response.ContentType = "application/octet-stream";         //MIME类型:匹配任意文件类型
                response.AddHeader("Content-Length", (fileLength - startBytes).ToString());
                response.AddHeader("Connection", "Keep-Alive");
                // 不要设置Content-Distribution,FileResult会自动设置这个属性。
                response.ContentEncoding = Encoding.UTF8;
                //如果是续传请求,则获取续传的起始位置,即已经下载到客户端的字节数
                if (request.Headers["Range"] != null)
                {
                    //重要:续传必须,表示局部范围响应。初始下载时默认为200
                    response.StatusCode = 206;
                    //"bytes=1474560-"
                    string[] range = request.Headers["Range"].Split(new char[] { '=', '-' });
                    //已经下载的字节数,即本次下载的开始位置
                    startBytes = Convert.ToInt64(range[1]);
                    //无效的起始位置
                    if (startBytes < 0 || startBytes >= fileLength)
                    {
                        return;
                    }
                }
                //如果是续传请求,告诉客户端本次的开始字节数,总长度,以便客户端将续传数据追加到startBytes位置后
                if (startBytes > 0)
                {
                    response.AddHeader("Content-Range", string.Format(" bytes {0}-{1}/{2}", startBytes, fileLength - 1, fileLength));
                }
                #endregion

                #region -------向客户端发送数据块-------------------
                br.BaseStream.Seek(startBytes, SeekOrigin.Begin);
                //分块下载,剩余部分可分成的块数
                var maxCount = (int)Math.Ceiling((fileLength - startBytes + 0.0) / packSize);
                for (var i = 0; i < maxCount && response.IsClientConnected; i++)
                {
                    //客户端中断连接,则暂停
                    response.BinaryWrite(br.ReadBytes(packSize));
                    response.Flush();
                    if (sleep > 1)
                    {
                        Thread.Sleep(sleep);
                    }
                }
                #endregion
            }
        }
示例#2
0
        public unsafe static int CreateInstance(ref DSConfig config)
        {
            byte[] bytes;
            UInt32 inst_len = Convert.ToUInt32(Marshal.SizeOf(typeof(DSInstance)));

            D.Print("Entering CreateInstance()");

            // Initialize Instance struct
            DSInstance inst = new Helper().InitStruct("DSInstance");

            // Add module size to instance len
            if (config.inst_type == Constants.DONUT_INSTANCE_PIC)
            {
                D.Print($"Adding module size {config.mod_len} to instance size");
                inst_len += Convert.ToUInt32(Marshal.SizeOf(typeof(DSModule)) + 32) + Convert.ToUInt32(config.mod_len);
            }

            // Generate instance key and counter
            bytes = Helper.RandomBytes(32);
            for (var i = 0; i < bytes.Length; i++)
            {
                if (i < 16)
                {
                    inst.key.ctr[i] = bytes[i];
                }
                else
                {
                    inst.key.mk[i - 16] = bytes[i];
                }
            }
            D.Print($"Instance CTR:\t{BitConverter.ToString(inst.key.ctr).Replace("-", "")}");
            D.Print($"Instance MK :\t{BitConverter.ToString(inst.key.mk).Replace("-", "")}");

            // Generate module key and counter
            bytes = Helper.RandomBytes(32);
            for (var i = 0; i < bytes.Length; i++)
            {
                if (i < 16)
                {
                    inst.mod_key.ctr[i] = bytes[i];
                }
                else
                {
                    inst.mod_key.mk[i - 16] = bytes[i];
                }
            }
            D.Print($"Module CTR:\t{BitConverter.ToString(inst.mod_key.ctr).Replace("-", "")}");
            D.Print($"Module MK :\t{BitConverter.ToString(inst.mod_key.mk).Replace("-", "")}");

            // Create Verifier string
            Helper.Copy(inst.sig, Helper.RandomString(8));
            D.Print($"Decryption Verfier String: {Helper.String(inst.sig)}");

            // Create IV
            inst.iv = BitConverter.ToUInt64(Helper.RandomBytes(8), 0);
            D.Print($"IV for Maru Hash:\t{BitConverter.ToString(bytes).Replace("-", "")}");

            // Generate DLL and API hashes
            Helper.APIImports(ref inst);

            // Assign GUIDs and other vals
            if (config.mod_type == Constants.DONUT_MODULE_NET_DLL || config.mod_type == Constants.DONUT_MODULE_NET_EXE)
            {
                inst.xIID_AppDomain        = Constants.xIID_AppDomain;
                inst.xIID_ICLRMetaHost     = Constants.xIID_ICLRMetaHost;
                inst.xCLSID_CLRMetaHost    = Constants.xCLSID_CLRMetaHost;
                inst.xIID_ICLRRuntimeInfo  = Constants.xIID_ICLRRuntimeInfo;
                inst.xIID_ICorRuntimeHost  = Constants.xIID_ICorRuntimeHost;
                inst.xCLSID_CorRuntimeHost = Constants.xCLSID_CorRuntimeHost;
            }
            else if (config.mod_type == Constants.DONUT_MODULE_VBS || config.mod_type == Constants.DONUT_MODULE_JS)
            {
                inst.xIID_IUnknown                = Constants.xIID_IUnknown;
                inst.xIID_IDispatch               = Constants.xIID_IDispatch;
                inst.xIID_IHost                   = Constants.xIID_IHost;
                inst.xIID_IActiveScript           = Constants.xIID_IActiveScript;
                inst.xIID_IActiveScriptSite       = Constants.xIID_IActiveScriptSite;
                inst.xIID_IActiveScriptSiteWindow = Constants.xIID_IActiveScriptSiteWindow;
                inst.xIID_IActiveScriptParse32    = Constants.xIID_IActiveScriptParse32;
                inst.xIID_IActiveScriptParse64    = Constants.xIID_IActiveScriptParse64;

                Helper.Copy(inst.wscript, "WScript");
                Helper.Copy(inst.wscript_exe, "wscript.exe");

                if (config.mod_type == Constants.DONUT_MODULE_VBS)
                {
                    inst.xCLSID_ScriptLanguage = Constants.xCLSID_VBScript;
                }
                else
                {
                    inst.xCLSID_ScriptLanguage = Constants.xCLSID_JScript;
                }
            }
            else if (config.mod_type == Constants.DONUT_MODULE_XSL)
            {
                inst.xCLSID_DOMDocument30 = Constants.xCLSID_DOMDocument30;
                inst.xIID_IXMLDOMDocument = Constants.xIID_IXMLDOMDocument;
                inst.xIID_IXMLDOMNode     = Constants.xIID_IXMLDOMNode;
            }

            Helper.Copy(inst.amsi.s, "AMSI");
            Helper.Copy(inst.amsiInit, "AmsiInitialize");
            Helper.Copy(inst.amsiScanBuf, "AmsiScanBuffer");
            Helper.Copy(inst.amsiScanStr, "AmsiScanString");
            Helper.Copy(inst.clr, "CLR");
            Helper.Copy(inst.wldp, "WLDP");
            Helper.Copy(inst.wldpQuery, "WldpQueryDynamicCodeTrust");
            Helper.Copy(inst.wldpIsApproved, "WldpIsClassInApprovedList");

            // Assign inst type
            inst.type = config.inst_type;

            // If URL type, assign URL
            if (inst.type == Constants.DONUT_INSTANCE_URL)
            {
                inst.http.url  = new char[Constants.DONUT_MAX_URL];
                inst.http.req  = new char[8];
                config.modname = Helper.RandomString(Constants.DONUT_MAX_MODNAME).ToCharArray();
                Helper.Copy(inst.http.url, Helper.String(config.url) + Helper.String(config.modname));
                Helper.Copy(inst.http.req, "GET");

                D.Print($"Payload will be downloaded from {Helper.String(inst.http.url)}");
            }

            // Update struct lengths
            inst.mod_len    = config.mod_len;
            inst.len        = inst_len;
            config.inst     = inst;
            config.inst_len = inst_len;

            // Generate MAC
            inst.mac = Helper.Maru(Helper.String(inst.sig), ref inst);

            // Copy Instance to memory
            var instptr = Marshal.AllocHGlobal(Convert.ToInt32(config.inst_len));

            Marshal.StructureToPtr(inst, instptr, false);

            // Copy Module to memory
            var modptr = Marshal.AllocHGlobal(Convert.ToInt32(config.mod_len));

            Marshal.StructureToPtr(config.mod, modptr, false);

            // Calculate offsets
            var encoffset  = Marshal.OffsetOf(typeof(DSInstance), "api_cnt").ToInt32();
            var encptr     = IntPtr.Add(instptr, encoffset);
            var modoffset  = Marshal.OffsetOf(typeof(DSInstance), "module").ToInt32();
            var moddata    = IntPtr.Add(instptr, modoffset);
            var fileoffset = Marshal.OffsetOf(typeof(DSModule), "data").ToInt32();

            // Copy Module to Instance
            Buffer.MemoryCopy(modptr.ToPointer(), moddata.ToPointer(), Marshal.SizeOf(typeof(DSModule)), Marshal.SizeOf(typeof(DSModule)));

            // if URL, copy stuff
            if (inst.type == Constants.DONUT_INSTANCE_URL)
            {
                D.Print($"Copying URL module data to instance");
                //inst.module.p = config.mod;
            }

            // if PIC, copy payload to instance
            if (inst.type == Constants.DONUT_INSTANCE_PIC)
            {
                D.Print($"Copying PIC module data to instance");
                // Copy payload file to end of module
                var   mmfile  = MemoryMappedFile.CreateFromFile(Helper.String(config.file), FileMode.Open);
                var   view    = mmfile.CreateViewAccessor();
                byte *fileptr = (byte *)0;
                view.SafeMemoryMappedViewHandle.AcquirePointer(ref fileptr);
                Buffer.MemoryCopy(fileptr, IntPtr.Add(moddata, fileoffset).ToPointer(), config.mod.len, config.mod.len);
                mmfile.Dispose();
            }

            // Release module
            Marshal.FreeHGlobal(modptr);

            // Encrypt instance
            D.Print("Encrypting Instance");
            Helper.Encrypt(inst.key.mk, inst.key.ctr, encptr, Convert.ToUInt32(inst.len - encoffset));

            // Writes raw instance if DEBUG
            D.WriteInst(config, instptr);

            // Generate final shellcode
            int ret = Shellcode(ref config, instptr);

            if (ret != Constants.DONUT_ERROR_SUCCESS)
            {
                Console.WriteLine("[x] Error " + Helper.GetError(ret));
                return(ret);
            }
            return(Constants.DONUT_ERROR_SUCCESS);
        }
示例#3
0
        private static MemoryMappedFile CreateFile()
        {
            var controlStream = new FileStream("control", FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);

            return(MemoryMappedFile.CreateFromFile(controlStream, "control", 8, MemoryMappedFileAccess.ReadWrite, HandleInheritability.Inheritable, false));
        }
 public MemoryMappedFileSlim(string fileNamePath)
     : this(MemoryMappedFile.CreateFromFile(fileNamePath, FileMode.OpenOrCreate, mapName : null), fileNamePath)
 {
 }
示例#5
0
    public bool runTest()
    {
        try
        {
            ////////////////////////////////////////////////////////////////////////
            // CreateOrOpen(mapName, capcity)
            ////////////////////////////////////////////////////////////////////////

            // [] mapName

            // mapname > 260 chars
            VerifyCreate("Loc111", new String('a', 1000), 4096);

            // null
            VerifyException <ArgumentNullException>("Loc112", null, 4096);

            // empty string disallowed
            VerifyException <ArgumentException>("Loc113", String.Empty, 4096);

            // all whitespace
            VerifyCreate("Loc114", "\t \n\u00A0", 4096);

            // MMF with this mapname already exists (pagefile backed)
            using (MemoryMappedFile mmf = MemoryMappedFile.CreateNew("COO_map115a", 1000))
            {
                VerifyOpen("Loc115a", "COO_map115a", 1000, MemoryMappedFileAccess.ReadWrite);
            }

            // MMF with this mapname already exists (filesystem backed)
            String fileText = "Non-empty file for MMF testing.";
            File.WriteAllText("CreateOrOpen_test2.txt", fileText);
            using (MemoryMappedFile mmf = MemoryMappedFile.CreateFromFile("CreateOrOpen_test2.txt", FileMode.Open, "COO_map115b"))
            {
                VerifyOpen("Loc115b", "COO_map115b", 1000, MemoryMappedFileAccess.ReadWrite);
            }

            // MMF with this mapname existed, but was closed - new MMF
            VerifyCreate("Loc116", "COO_map115a", 500);

            // "global/" prefix
            VerifyCreate("Loc117", "global/COO_mapname", 4096);

            // "local/" prefix
            VerifyCreate("Loc118", "local/COO_mapname", 4096);

            // [] capacity

            // >0 capacity
            VerifyCreate("Loc211", "COO_mapname211", 50);

            // 0 capacity
            VerifyException <ArgumentOutOfRangeException>("Loc211", "COO_mapname211", 0);

            // negative
            VerifyException <ArgumentOutOfRangeException>("Loc213", "COO_mapname213", -1);

            // negative
            VerifyException <ArgumentOutOfRangeException>("Loc214", "COO_mapname214", -4096);

            // Int64.MaxValue - cannot exceed local address space
            if (IntPtr.Size == 4)
            {
                VerifyException <ArgumentOutOfRangeException>("Loc215", "COO_mapname215", Int64.MaxValue);
            }
            else // 64-bit machine
            {
                VerifyException <IOException>("Loc215b", "COO_mapname215", Int64.MaxValue); // valid but too large
            }
            // ignored for existing file (smaller)
            using (MemoryMappedFile mmf = MemoryMappedFile.CreateNew("COO_mapname216", 1000, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None))
            {
                VerifyOpen("Loc216", "COO_mapname216", 100, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None, MemoryMappedFileAccess.ReadWrite);
            }

            // ignored for existing file (larger)
            using (MemoryMappedFile mmf = MemoryMappedFile.CreateNew("COO_mapname217", 1000, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None))
            {
                VerifyOpen("Loc217", "COO_mapname217", 10000, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None, MemoryMappedFileAccess.ReadWrite);
            }

            // existing file - invalid - still exception
            using (MemoryMappedFile mmf = MemoryMappedFile.CreateNew("COO_mapname218", 1000, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None))
            {
                VerifyException <ArgumentOutOfRangeException>("Loc218", "COO_mapname218", 0, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None);
            }

            ////////////////////////////////////////////////////////////////////////
            // CreateOrOpen(mapName, capcity, MemoryMappedFileAccess)
            ////////////////////////////////////////////////////////////////////////

            // [] access

            // Write is disallowed
            VerifyException <ArgumentException>("Loc330", "COO_mapname330", 1000, MemoryMappedFileAccess.Write);

            // valid access - new file
            MemoryMappedFileAccess[] accessList = new MemoryMappedFileAccess[] {
                MemoryMappedFileAccess.Read,
                MemoryMappedFileAccess.ReadWrite,
                MemoryMappedFileAccess.CopyOnWrite,
                MemoryMappedFileAccess.ReadExecute,
                MemoryMappedFileAccess.ReadWriteExecute,
            };
            foreach (MemoryMappedFileAccess access in accessList)
            {
                VerifyCreate("Loc331_" + access, "COO_mapname331_" + access, 1000, access);
            }

            // invalid enum value
            accessList = new MemoryMappedFileAccess[] {
                (MemoryMappedFileAccess)(-1),
                (MemoryMappedFileAccess)(6),
            };
            foreach (MemoryMappedFileAccess access in accessList)
            {
                VerifyException <ArgumentOutOfRangeException>("Loc332_" + ((int)access), "COO_mapname332_" + ((int)access), 1000, access);
            }

            // default security - all valid for existing file
            using (MemoryMappedFile mmf = MemoryMappedFile.CreateNew("COO_mapname333", 1000))
            {
                accessList = new MemoryMappedFileAccess[] {
                    MemoryMappedFileAccess.CopyOnWrite,
                    MemoryMappedFileAccess.Read,
                    MemoryMappedFileAccess.Write,
                    MemoryMappedFileAccess.ReadWrite,
                    MemoryMappedFileAccess.ReadExecute,
                    MemoryMappedFileAccess.ReadWriteExecute,
                };
                foreach (MemoryMappedFileAccess access in accessList)
                {
                    VerifyOpen("Loc333_" + access, "COO_mapname333", 1000, access, access);
                }
            }

            ////////////////////////////////////////////////////////////////////////
            // CreateOrOpen(String, long, MemoryMappedFileAccess, MemoryMappedFileOptions,
            //    MemoryMappedFileSecurity, HandleInheritability)
            ////////////////////////////////////////////////////////////////////////

            // [] mapName

            // mapname > 260 chars
            VerifyCreate("Loc411", new String('a', 1000), 4096, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None);

            // null
            VerifyException <ArgumentNullException>("Loc412", null, 4096, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None);

            // empty string disallowed
            VerifyException <ArgumentException>("Loc413", String.Empty, 4096, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None);

            // all whitespace
            VerifyCreate("Loc414", "\t \n\u00A0", 4096, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None);

            // MMF with this mapname already exists (pagefile backed)
            using (MemoryMappedFile mmf = MemoryMappedFile.CreateNew("COO_map415a", 1000))
            {
                using (MemoryMappedFile mmf2 = MemoryMappedFile.CreateOrOpen("COO_map415a", 1000))
                {
                    VerifyOpen("Loc415a", "COO_map415a", 1000, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None, MemoryMappedFileAccess.ReadWrite);
                }
            }

            // MMF with this mapname already exists (filesystem backed)
            File.WriteAllText("CreateOrOpen_test2.txt", fileText);
            using (MemoryMappedFile mmf = MemoryMappedFile.CreateFromFile("CreateOrOpen_test2.txt", FileMode.Open, "COO_map415b"))
            {
                VerifyOpen("Loc415b", "COO_map415b", 1000, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None, MemoryMappedFileAccess.ReadWrite);
            }

            // MMF with this mapname existed, but was closed - new MMF
            VerifyCreate("Loc416", "COO_map415a", 500, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None);

            // "global/" prefix
            VerifyCreate("Loc417", "global/COO_mapname", 4096, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None);

            // "local/" prefix
            VerifyCreate("Loc418", "local/COO_mapname", 4096, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None);

            // [] capacity

            // >0 capacity
            VerifyCreate("Loc421", "COO_mapname421", 50, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None);

            // 0 capacity
            VerifyException <ArgumentOutOfRangeException>("Loc422", "COO_mapname422", 0, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None);

            // negative
            VerifyException <ArgumentOutOfRangeException>("Loc423", "COO_mapname423", -1, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None);

            // negative
            VerifyException <ArgumentOutOfRangeException>("Loc424", "COO_mapname424", -4096, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None);

            // Int64.MaxValue - cannot exceed local address space
            if (IntPtr.Size == 4)
            {
                VerifyException <ArgumentOutOfRangeException>("Loc425", "COO_mapname425", Int64.MaxValue, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None);
            }
            else // 64-bit machine
            {
                VerifyException <IOException>("Loc425b", "COO_mapname425", Int64.MaxValue, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None); // valid but too large
            }
            // ignored for existing file (smaller)
            using (MemoryMappedFile mmf = MemoryMappedFile.CreateNew("COO_mapname426", 1000, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None))
            {
                VerifyOpen("Loc426", "COO_mapname426", 100, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None, MemoryMappedFileAccess.ReadWrite);
            }

            // ignored for existing file (larger)
            using (MemoryMappedFile mmf = MemoryMappedFile.CreateNew("COO_mapname427", 1000, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None))
            {
                VerifyOpen("Loc427", "COO_mapname427", 10000, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None, MemoryMappedFileAccess.ReadWrite);
            }

            // existing file - invalid - still exception
            using (MemoryMappedFile mmf = MemoryMappedFile.CreateNew("COO_mapname428", 1000, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None))
            {
                VerifyException <ArgumentOutOfRangeException>("Loc428", "COO_mapname428", 0, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None);
            }

            // [] access

            // Write is disallowed for new file
            VerifyException <ArgumentException>("Loc430", "COO_mapname430", 1000, MemoryMappedFileAccess.Write, MemoryMappedFileOptions.None, HandleInheritability.None);

            // valid access for a new file
            accessList = new MemoryMappedFileAccess[] {
                MemoryMappedFileAccess.Read,
                MemoryMappedFileAccess.ReadWrite,
                MemoryMappedFileAccess.CopyOnWrite,
                MemoryMappedFileAccess.ReadExecute,
                MemoryMappedFileAccess.ReadWriteExecute,
            };
            foreach (MemoryMappedFileAccess access in accessList)
            {
                VerifyCreate("Loc431_" + access, "COO_mapname431_" + access, 1000, access, MemoryMappedFileOptions.None, HandleInheritability.None);
            }

            // invalid enum value
            accessList = new MemoryMappedFileAccess[] {
                (MemoryMappedFileAccess)(-1),
                (MemoryMappedFileAccess)(6),
            };
            foreach (MemoryMappedFileAccess access in accessList)
            {
                VerifyException <ArgumentOutOfRangeException>("Loc432_" + ((int)access), "COO_mapname432_" + ((int)access), 1000, access, MemoryMappedFileOptions.None, HandleInheritability.None);
            }

            // default security - all valid
            using (MemoryMappedFile mmf = MemoryMappedFile.CreateNew("COO_mapname433", 1000))
            {
                accessList = new MemoryMappedFileAccess[] {
                    MemoryMappedFileAccess.CopyOnWrite,
                    MemoryMappedFileAccess.Read,
                    MemoryMappedFileAccess.Write,
                    MemoryMappedFileAccess.ReadWrite,
                    MemoryMappedFileAccess.ReadExecute,
                    MemoryMappedFileAccess.ReadWriteExecute,
                };
                foreach (MemoryMappedFileAccess access in accessList)
                {
                    VerifyOpen("Loc433_" + access, "COO_mapname433", 1000, access, MemoryMappedFileOptions.None, HandleInheritability.None, access);
                }
            }

            // default security, original (lesser) viewAccess is respected
            using (MemoryMappedFile mmf = MemoryMappedFile.CreateNew("COO_mapname434", 1000, MemoryMappedFileAccess.Read))
            {
                accessList = new MemoryMappedFileAccess[] {
                    MemoryMappedFileAccess.CopyOnWrite,
                    MemoryMappedFileAccess.Read,
                    MemoryMappedFileAccess.ReadWrite,
                    MemoryMappedFileAccess.ReadExecute,
                    MemoryMappedFileAccess.ReadWriteExecute,
                };
                foreach (MemoryMappedFileAccess access in accessList)
                {
                    VerifyOpen("Loc434_" + access, "COO_mapname434", 1000, access, MemoryMappedFileOptions.None, HandleInheritability.None, MemoryMappedFileAccess.Read);
                }
                VerifyOpen("Loc434_Write", "COO_mapname434", 1000, MemoryMappedFileAccess.Write, MemoryMappedFileOptions.None, HandleInheritability.None, (MemoryMappedFileAccess)(-1));  // for current architecture, rights=Write implies ReadWrite access but not Read, so no expected access here
            }

            // [] options

            // Default
            VerifyCreate("Loc440a", "COO_mapname440a", 4096 * 1000);
            VerifyCreate("Loc440b", "COO_mapname440b", 4096 * 10000);

            // None - new file
            VerifyCreate("Loc441", "COO_mapname441", 4096 * 10000, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None);

            // DelayAllocatePages - new file
            VerifyCreate("Loc442", "COO_mapname442", 4096 * 10000, MemoryMappedFileAccess.Read, MemoryMappedFileOptions.DelayAllocatePages, HandleInheritability.None);

            // invalid
            VerifyException <ArgumentOutOfRangeException>("Loc443", "COO_mapname443", 100, MemoryMappedFileAccess.ReadWrite, (MemoryMappedFileOptions)(-1), HandleInheritability.None);

            // ignored for existing file
            using (MemoryMappedFile mmf = MemoryMappedFile.CreateNew("COO_mapname444", 1000, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None))
            {
                VerifyOpen("Loc444", "COO_mapname444", 100, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.DelayAllocatePages, HandleInheritability.None, MemoryMappedFileAccess.ReadWrite);
            }

            // [] memoryMappedFileSecurity

            // null, tested throughout this file

            // valid non-null
            VerifyCreate("Loc451", "COO_mapname451", 1000, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None);

            // ignored for existing
            using (MemoryMappedFile mmf = MemoryMappedFile.CreateOrOpen("COO_mapname452", 1000, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None))
            {
                VerifyOpen("Loc452", "COO_mapname452", 1000, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None, MemoryMappedFileAccess.ReadWrite);
            }

            // [] inheritability

            // None - new file
            VerifyCreate("Loc461", "COO_mapname461", 100, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None);

            // Inheritable - new file
            VerifyCreate("Loc462", "COO_mapname462", 100, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.Inheritable);

            // Mix and match: None - existing file w/Inheritable
            using (MemoryMappedFile mmf = MemoryMappedFile.CreateNew("COO_mapname464", 1000, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.Inheritable))
            {
                VerifyOpen("Loc464a", "COO_mapname464", 100, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None, MemoryMappedFileAccess.ReadWrite);
            }

            // Mix and match: Inheritable - existing file w/None
            using (FileStream fs = new FileStream("CreateOrOpen_test2.txt", FileMode.Open))
            {
                using (MemoryMappedFile mmf = MemoryMappedFile.CreateFromFile(fs, "COO_mapname465", 1000, MemoryMappedFileAccess.ReadWrite, HandleInheritability.None, false))
                {
                    VerifyOpen("Loc465b", "COO_mapname465", 100, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.Inheritable, MemoryMappedFileAccess.ReadWrite);
                }
            }

            // invalid
            VerifyException <ArgumentOutOfRangeException>("Loc467", "COO_mapname467", 100, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, (HandleInheritability)(-1));
            VerifyException <ArgumentOutOfRangeException>("Loc468", "COO_mapname468", 100, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, (HandleInheritability)(2));


            /// END TEST CASES

            if (iCountErrors == 0)
            {
                return(true);
            }
            else
            {
                Console.WriteLine("FAiL! iCountErrors==" + iCountErrors);
                return(false);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("ERR999: Unexpected exception in runTest, {0}", ex);
            return(false);
        }
    }
示例#6
0
        // Проверка таблицы с индексами
        static void Main5(string[] args)
        {
            Console.WriteLine("Start");
            string   path     = @"..\..\..\Databases\";
            string   filename = path + "table.pac";
            Random   rnd      = new Random(3333);
            PaCell   table    = new PaCell(new PTypeSequence(new PType(PTypeEnumeration.integer)), filename, false);
            DateTime tt0      = DateTime.Now;
            int      nvalues  = 1000000000;

            bool toload = false;

            if (toload)
            {
                table.Clear();
                table.Fill(new object[0]);
                for (int i = 0; i < nvalues; i++)
                {
                    table.Root.AppendElement(i);
                }
                table.Flush();
                Console.WriteLine("Load ok. duration={0}", (DateTime.Now - tt0).Ticks / 10000L); tt0 = DateTime.Now;
                return;
            }
            int portion = 100000;

            for (int i = 0; i < portion; i++)
            {
                int ind = rnd.Next(nvalues - 1);
                var v   = table.Root.Element(ind).Get();
            }
            Console.WriteLine("Test1 ok. duration={0}", (DateTime.Now - tt0).Ticks / 10000L); tt0 = DateTime.Now;

            table.Close();
            System.IO.Stream       fs = new System.IO.FileStream(filename, System.IO.FileMode.Open, System.IO.FileAccess.Read);
            System.IO.BinaryReader br = new System.IO.BinaryReader(fs);
            for (int i = 0; i < portion; i++)
            {
                int  ind = rnd.Next(nvalues - 1);
                long off = 40 + (long)ind * 4;
                fs.Position = off;
                int v = br.ReadInt32();
            }

            fs.Close();
            Console.WriteLine("Test2 ok. duration={0}", (DateTime.Now - tt0).Ticks / 10000L); tt0 = DateTime.Now;
            using (MemoryMappedFile mmf = MemoryMappedFile.CreateFromFile(filename))
            {
                for (int i = 0; i < portion; i++)
                {
                    int  ind = rnd.Next(nvalues - 1);
                    long off = 40 + (long)ind * 4;
                    using (var accessor = mmf.CreateViewAccessor(off, 4))
                    {
                        int v = accessor.ReadInt32(0);
                    }
                }
                Console.WriteLine("Test3 ok. duration={0}", (DateTime.Now - tt0).Ticks / 10000L); tt0 = DateTime.Now;
                using (var accessor = mmf.CreateViewAccessor(0, (long)nvalues * 4 + 40))
                {
                    tt0 = DateTime.Now;
                    for (int i = 0; i < portion; i++)
                    {
                        int  ind = rnd.Next(nvalues - 1);
                        long off = 40 + (long)ind * 4;
                        //using (var accessor = mmf.CreateViewAccessor(off, 4))
                        //{
                        //    int v = accessor.ReadInt32(0);
                        //}
                        int v = accessor.ReadInt32(off);
                    }
                }
            }
            Console.WriteLine("Test4 ok. duration={0}", (DateTime.Now - tt0).Ticks / 10000L); tt0 = DateTime.Now;
        }
        public void OnNext(string path)
        {
            string   filename = Path.GetFileNameWithoutExtension(path);
            FileInfo fi       = new FileInfo(path);
            Mutex    m        = new Mutex(false, "m" + filename);

            filename += Convert.ToString(objects.Count);
            MemoryMappedFile mappedFile = null;

            m.WaitOne();
            try
            {
                mappedFile = MemoryMappedFile.CreateFromFile(path, FileMode.Open, filename, 0);
            }
            catch (IOException) { return; }
            MemoryMappedViewAccessor accessor = mappedFile.CreateViewAccessor();
            uint         offsetPE             = accessor.ReadUInt32(60); // Считываем сдвиг заголовка PE
            AVScanObject obj = null;

            // Проверяем размер файла
            if (offsetPE <= accessor.Capacity)
            {
                byte[] peSignature = new byte[4];
                accessor.ReadArray(offsetPE, peSignature, 0, 4);              // Считываем сигнатуру
                if (Encoding.ASCII.GetString(peSignature) == "PE\0\0")        // Для PE-файла должно быть равно PE\0\0
                {
                    ushort magic        = accessor.ReadUInt16(offsetPE + 24); // Считываем поле magic определяющее вид PE-заголовка
                    uint   peHeaderSize = 0;
                    if (magic == 267)
                    {
                        peHeaderSize = 248;                              // Для PE32
                    }
                    else
                    {
                        peHeaderSize = 264;                                 // Для PE32+
                    }
                    uint sectionsNum   = accessor.ReadUInt16(offsetPE + 6); // Считываем количество секций
                    uint pFirstSection = offsetPE + peHeaderSize;
                    for (uint i = 0; i < sectionsNum; i++)
                    {
                        uint pCurSection    = pFirstSection + i * 40;
                        uint characteristic = accessor.ReadUInt32(pCurSection + 36);
                        uint executeFlag    = 0x20000000;
                        // Проверяем содержимое поля характеристики
                        // Eсли сегмент исполняемый, то создаем AVScanObject с этим сегментом
                        if ((characteristic & executeFlag) == executeFlag)
                        {
                            uint pDataStart  = accessor.ReadUInt32(pCurSection + 20);
                            uint pDataLength = accessor.ReadUInt32(pCurSection + 16);
                            MemoryMappedViewAccessor sectionAccessor = mappedFile.CreateViewAccessor(pDataStart, pDataLength, MemoryMappedFileAccess.Read);
                            obj = new AVScanObject(sectionAccessor, mappedFile, path);
                        }
                    }
                }
            }
            m.ReleaseMutex();
            // По окончанию проверки файла, добавляем в список obj, который, если файл не исполняемый равен null
            objects.Add(obj);
            foreach (IObserver <AVScanObject> observer in observers)     // И оповещаем всех слушателей
            {
                observer.OnNext(obj);
            }
        }
示例#8
0
        public static void write_file_MMF <T>(T[] data, string path_folder, string file_name)
        {
            if (!path_folder.Contains(':'))
            {
                path_folder = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + @"\" + path_folder;
            }
            if (!Directory.Exists(path_folder))
            {
                Directory.CreateDirectory(path_folder);
            }

            MemoryMappedFileSecurity mSec = new MemoryMappedFileSecurity();

            mSec.AddAccessRule(new AccessRule <MemoryMappedFileRights>(new SecurityIdentifier(WellKnownSidType.WorldSid, null),
                                                                       MemoryMappedFileRights.FullControl, AccessControlType.Allow));


            string file = path_folder + @"\" + file_name + ".mmf";

            file = file.Replace("\\\\", "\\");

            Task.Factory.StartNew((object obj) =>
            {
                Tuple <string, T[]> rs = (obj as Tuple <string, T[]>);
                string v_file          = rs.Item1;
                T[] v_data             = rs.Item2;

                int buffer_size = 0;
                try
                {
                    using (MemoryStream stream = new MemoryStream())
                    {
                        BinaryFormatter bf = new BinaryFormatter();
                        bf.Serialize(stream, v_data);
                        byte[] bw = stream.ToArray();

                        buffer_size = bw.Length;

                        long file_size = 0;
                        if (File.Exists(v_file))
                        {
                            FileInfo fi = new FileInfo(v_file);
                            file_size   = fi.Length;
                        }

                        long capacity = buffer_size;
                        if (capacity < file_size)
                        {
                            capacity = file_size;
                        }


                        using (MemoryMappedFile w = MemoryMappedFile.CreateFromFile(v_file, FileMode.OpenOrCreate, null, capacity))
                        {
                            using (MemoryMappedViewAccessor mmfWriter = w.CreateViewAccessor(0, capacity))
                            {
                                mmfWriter.WriteArray <byte>(0, bw, 0, buffer_size);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    string msg = ex.Message;
                }
            }, new Tuple <string, T[]>(file, data));
        }//end function
 public void InvalidArguments_Inheritability(HandleInheritability inheritability)
 {
     // Out of range values for inheritability
     using (TempFile file = new TempFile(GetTestFilePath()))
         using (FileStream fs = File.Open(file.Path, FileMode.Open))
         {
             Assert.Throws <ArgumentOutOfRangeException>("inheritability", () => MemoryMappedFile.CreateFromFile(fs, CreateUniqueMapName(), 4096, MemoryMappedFileAccess.ReadWrite, inheritability, true));
         }
 }
        public static void DoPass(RewriteGlobalContext context, UnhollowerOptions options)
        {
            if (string.IsNullOrEmpty(options.GameAssemblyPath))
            {
                Pass15GenerateMemberContexts.HasObfuscatedMethods = false;
                return;
            }
            if (!Pass15GenerateMemberContexts.HasObfuscatedMethods)
            {
                return;
            }

            var methodToCallersMap = new ConcurrentDictionary <long, List <XrefInstance> >();
            var methodToCalleesMap = new ConcurrentDictionary <long, List <long> >();

            using var mappedFile = MemoryMappedFile.CreateFromFile(options.GameAssemblyPath, FileMode.Open, null, 0, MemoryMappedFileAccess.Read);
            using var accessor   = mappedFile.CreateViewAccessor(0, 0, MemoryMappedFileAccess.Read);

            IntPtr gameAssemblyPtr;

            unsafe
            {
                byte *fileStartPtr = null;
                accessor.SafeMemoryMappedViewHandle.AcquirePointer(ref fileStartPtr);
                gameAssemblyPtr = (IntPtr)fileStartPtr;
            }

            context.MethodStartAddresses.Sort();

            // Scan xrefs
            context.Assemblies.SelectMany(it => it.Types).SelectMany(it => it.Methods).AsParallel().ForAll(
                originalTypeMethod =>
            {
                var address = originalTypeMethod.FileOffset;
                if (address == 0)
                {
                    return;
                }

                if (!options.NoXrefCache)
                {
                    var pair = XrefScanMetadataGenerationUtil.FindMetadataInitForMethod(originalTypeMethod, (long)gameAssemblyPtr);
                    originalTypeMethod.MetadataInitFlagRva  = pair.FlagRva;
                    originalTypeMethod.MetadataInitTokenRva = pair.TokenRva;
                }

                var nextMethodStart = context.MethodStartAddresses.BinarySearch(address + 1);
                if (nextMethodStart < 0)
                {
                    nextMethodStart = ~nextMethodStart;
                }
                var length = nextMethodStart >= context.MethodStartAddresses.Count ? 1024 * 1024 : (context.MethodStartAddresses[nextMethodStart] - address);
                foreach (var callTargetGlobal in XrefScanner.XrefScanImpl(XrefScanner.DecoderForAddress(IntPtr.Add(gameAssemblyPtr, (int)address), (int)length), true))
                {
                    var callTarget = callTargetGlobal.RelativeToBase((long)gameAssemblyPtr + originalTypeMethod.FileOffset - originalTypeMethod.Rva);
                    if (callTarget.Type == XrefType.Method)
                    {
                        var targetRelative = (long)callTarget.Pointer;
                        methodToCallersMap.GetOrAdd(targetRelative, _ => new List <XrefInstance>()).AddLocked(new XrefInstance(XrefType.Method, (IntPtr)originalTypeMethod.Rva, callTarget.FoundAt));
                        methodToCalleesMap.GetOrAdd(originalTypeMethod.Rva, _ => new List <long>()).AddLocked(targetRelative);
                    }

                    if (!options.NoXrefCache)
                    {
                        originalTypeMethod.XrefScanResults.Add(callTarget);
                    }
                }
            });

            MapOfCallers = methodToCallersMap;

            void MarkMethodAlive(long address)
            {
                if (!NonDeadMethods.Add(address))
                {
                    return;
                }
                if (!methodToCalleesMap.TryGetValue(address, out var calleeList))
                {
                    return;
                }

                foreach (var callee in calleeList)
                {
                    MarkMethodAlive(callee);
                }
            }

            // Now decided which of them are possible dead code
            foreach (var assemblyRewriteContext in context.Assemblies)
            {
                foreach (var typeRewriteContext in assemblyRewriteContext.Types)
                {
                    foreach (var methodRewriteContext in typeRewriteContext.Methods)
                    {
                        if (methodRewriteContext.FileOffset == 0)
                        {
                            continue;
                        }

                        var originalMethod = methodRewriteContext.OriginalMethod;
                        if (!originalMethod.Name.IsObfuscated(options) || originalMethod.IsVirtual)
                        {
                            MarkMethodAlive(methodRewriteContext.Rva);
                        }
                    }
                }
            }
        }
示例#11
0
        public static void write_MMF <T>(T item, string path_folder, string file_name) where T : struct
        {
            if (!path_folder.Contains(':'))
            {
                path_folder = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + @"\" + path_folder;
            }
            if (!Directory.Exists(path_folder))
            {
                Directory.CreateDirectory(path_folder);
            }

            MemoryMappedFileSecurity mSec = new MemoryMappedFileSecurity();

            mSec.AddAccessRule(new AccessRule <MemoryMappedFileRights>(new SecurityIdentifier(WellKnownSidType.WorldSid, null),
                                                                       MemoryMappedFileRights.FullControl, AccessControlType.Allow));


            string filePath = path_folder + @"\" + file_name + ".mmf";

            filePath = filePath.Replace("\\\\", "\\");

            int buffer_size = 0;

            try
            {
                using (MemoryStream stream = new MemoryStream())
                {
                    int    objsize = Marshal.SizeOf(typeof(T));
                    byte[] bw      = new byte[objsize];
                    IntPtr buff    = Marshal.AllocHGlobal(objsize);
                    Marshal.StructureToPtr(item, buff, true);
                    Marshal.Copy(buff, bw, 0, objsize);
                    Marshal.FreeHGlobal(buff);

                    buffer_size = bw.Length;

                    long file_size = 0;
                    if (File.Exists(filePath))
                    {
                        FileInfo fi = new FileInfo(filePath);
                        file_size = fi.Length;
                    }

                    long capacity = buffer_size;
                    if (capacity < file_size)
                    {
                        capacity = file_size;
                    }


                    using (MemoryMappedFile w = MemoryMappedFile.CreateFromFile(filePath, FileMode.OpenOrCreate, null, capacity))
                    {
                        using (MemoryMappedViewAccessor mmfWriter = w.CreateViewAccessor(0, capacity))
                        {
                            mmfWriter.WriteArray <byte>(0, bw, 0, buffer_size);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                string msg = ex.Message;
            }
        }//end function
示例#12
0
        public LogFile MMFConcurrentRead(LogFile logFile, BackgroundWorker backgroundWorker)
        {
            Debug.Print("MMFConcurrentRead: enter");
            GetEncoding(logFile);
            // not sure why this here. messing up temp file
            //logFile.IsNew = false;
            //logFile.Modified = false;

            if (!File.Exists(logFile.Tag))
            {
                Debug.Print("MMFConcurrentRead:error, file does not exist: " + logFile.Tag);
                return(logFile);
            }

            byte[] bytes = new byte[new FileInfo(logFile.Tag).Length];
            // 4,8,12
            int threadCount = 1;

            if (bytes.Length > 1000000)
            {
                threadCount = 8;
            }

            int bposition = logFile.HasBom ? logFile.Encoding.GetPreamble().Length : 0;
            int blen      = bytes.Length / threadCount;

            MemoryMappedFile memoryMappedFile = MemoryMappedFile.CreateFromFile(logFile.Tag, FileMode.Open, "mmf", bytes.Length, MemoryMappedFileAccess.Read);

            ManualResetEvent[]         completedEvents = new ManualResetEvent[threadCount];
            List <List <LogFileItem> > list            = new List <List <LogFileItem> >();

            for (int i = 0; i < threadCount; i++)
            {
                list.Add(new List <LogFileItem>());
                completedEvents[i] = new ManualResetEvent(false);
            }

            for (int mmfCount = 0; mmfCount < threadCount; mmfCount++)
            {
                if (mmfCount != 0)
                {
                    bposition += blen;
                }

                if (mmfCount == threadCount - 1)
                {
                    blen = bytes.Length - bposition;
                }

                TaskMMFInfo taskInfo = new TaskMMFInfo()
                {
                    mmf            = memoryMappedFile,
                    stringList     = list[mmfCount],
                    logFile        = logFile,
                    position       = bposition,
                    length         = blen,
                    completedEvent = completedEvents[mmfCount],
                    bgWorker       = backgroundWorker
                };

                ThreadPool.QueueUserWorkItem(new WaitCallback(ParallelMMFRead), taskInfo);
            }

            Debug.Print(string.Format("mmf thread length: {0}", blen));

            WaitHandle.WaitAll(completedEvents);

            if (memoryMappedFile != null)
            {
                memoryMappedFile.Dispose();
            }

            if (backgroundWorker.CancellationPending)
            {
                Debug.Print("MMFConcurrentRead:cancelled");
                return(logFile);
            }

            bool patch = false;

            List <LogFileItem> finalList = new List <LogFileItem>();

            for (int listCount = 0; listCount < threadCount; listCount++)
            {
                if (patch)
                {
                    // merge last line with first line in current list
                    finalList[finalList.Count - 1].Content = finalList[finalList.Count - 1].Content + list[listCount][0].Content;
                    list[listCount].RemoveAt(0);
                    patch = false;
                }

                finalList.AddRange(list[listCount]);
                list[listCount].Clear();

                // need to check for partial lines look in last index for needsPatch string
                if (finalList.Count > 0)
                {
                    if (finalList[finalList.Count - 1].Content == _needsPatch)
                    {
                        finalList.RemoveAt(finalList.Count - 1);
                        patch = true;
                    }
                    else
                    {
                        patch = false;
                    }
                }
            }

            // set index
            int counter = 1;

            foreach (LogFileItem item in finalList)
            {
                item.Index = counter++;
            }

            Debug.Print("MMFConcurrentRead:exit");

            logFile.ContentItems = new ObservableCollection <LogFileItem>(finalList);

            return(logFile);
        }
示例#13
0
 private MemoryMappedFile GetMemoryMappedFile()
 {
     return(MemoryMappedFile.CreateFromFile(this.updatedIndexPath, FileMode.Open));
 }
示例#14
0
 public void Extract(Stream output)
 {
     using (var file = MemoryMappedFile.CreateFromFile(this.ParentFile, FileMode.Open))
     {
         using (var viewstream = file.CreateViewStream((Offset * 4096) + 9, ZSize, MemoryMappedFileAccess.Read))
         {
             uint fmt = 0;
             if (Dxt == 7)
             {
                 fmt = 1;
             }
             else if (Dxt == 8)
             {
                 fmt = 4;
             }
             else if (Dxt == 10)
             {
                 fmt = 4;
             }
             else if (Dxt == 13)
             {
                 fmt = 3;
             }
             else if (Dxt == 14)
             {
                 fmt = 6;
             }
             else if (Dxt == 15)
             {
                 fmt = 4;
             }
             else if (Dxt == 253)
             {
                 fmt = 0;
             }
             else if (Dxt == 0)
             {
                 fmt = 0;
             }
             else
             {
                 throw new Exception("Invalid image!");
             }
             var  cubemap = (Type == 3 || Type == 0) && (Typeinfo == 6);
             uint depth   = 0;
             if (Typeinfo > 1 && Type == 4)
             {
                 depth = Typeinfo;
             }
             if (Type == 3 && Dxt == 253)
             {
                 Bpp = 32;
             }
             var header = new DDSHeader().generate(Width, Height, 1, fmt, Bpp, cubemap, depth)
                          .Concat(new[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 }).ToArray();
             output.Write(header, 0, header.Length);
             if (!(Typeinfo == 6 && (Dxt == 253 || Dxt == 0)))
             {
                 var zlib = new ZlibStream(viewstream, CompressionMode.Decompress);
                 zlib.CopyTo(output);
             }
         }
     }
 }
示例#15
0
        public void Test_Flush()
        {
            MemoryMappedViewByteBuffer mmbRead;

            // buffer was not mapped in read/write mode
            using (FileStream fileInputStream = new FileStream(tmpFile.FullName, FileMode.Open, FileAccess.Read))
            {
                using (var fileChannelRead = MemoryMappedFile.CreateFromFile(fileInputStream, null, 0, MemoryMappedFileAccess.Read,
#if FEATURE_MEMORYMAPPEDFILESECURITY
                                                                             null,
#endif
                                                                             HandleInheritability.None, true))
                {
                    //FileChannel fileChannelRead = fileInputStream.getChannel();
                    //MappedByteBuffer mmbRead = fileChannelRead.map(MapMode.READ_ONLY, 0,
                    //        fileChannelRead.size());

                    mmbRead = fileChannelRead.CreateViewByteBuffer(0, (int)fileInputStream.Length, MemoryMappedFileAccess.Read);
                    mmbRead.Flush();
                }

                //using (FileStream inputStream = new FileStream(tmpFile.FullName, FileMode.Open, FileAccess.Read))
                using (var fileChannelR = MemoryMappedFile.CreateFromFile(fileInputStream, null, 0, MemoryMappedFileAccess.Read,
#if FEATURE_MEMORYMAPPEDFILESECURITY
                                                                          null,
#endif
                                                                          HandleInheritability.None, false))
                {
                    //FileInputStream inputStream = new FileInputStream(tmpFile);
                    //FileChannel fileChannelR = inputStream.getChannel();
                    //MappedByteBuffer resultRead = fileChannelR.map(MapMode.READ_ONLY, 0,
                    //        fileChannelR.size());
                    MemoryMappedViewByteBuffer resultRead = fileChannelR.CreateViewByteBuffer(0, (int)fileInputStream.Length, MemoryMappedFileAccess.Read);

                    //If this buffer was not mapped in read/write mode, then invoking this method has no effect.
                    assertEquals(
                        "Invoking force() should have no effect when this buffer was not mapped in read/write mode",
                        mmbRead, resultRead);
                }
            }

            MemoryMappedViewByteBuffer mmbReadWrite;

            // Buffer was mapped in read/write mode
            using (FileStream randomFile = new FileStream(tmpFile.FullName, FileMode.Open, FileAccess.ReadWrite))
            {
                using (var fileChannelReadWrite = MemoryMappedFile.CreateFromFile(randomFile, null, 0, MemoryMappedFileAccess.ReadWrite,
#if FEATURE_MEMORYMAPPEDFILESECURITY
                                                                                  null,
#endif
                                                                                  HandleInheritability.None, true))
                {
                    //RandomAccessFile randomFile = new RandomAccessFile(tmpFile, "rw");
                    //FileChannel fileChannelReadWrite = randomFile.getChannel();
                    //MappedByteBuffer mmbReadWrite = fileChannelReadWrite.map(
                    //        FileChannel.MapMode.READ_WRITE, 0, fileChannelReadWrite.size());
                    mmbReadWrite = fileChannelReadWrite.CreateViewByteBuffer(0, (int)randomFile.Length, MemoryMappedFileAccess.ReadWrite);
                    mmbReadWrite.Put((byte)'o');
                    mmbReadWrite.Flush();
                }


                //using (FileStream random = new FileStream(tmpFile.FullName, FileMode.Open, FileAccess.ReadWrite))
                using (var fileChannelRW = MemoryMappedFile.CreateFromFile(randomFile, null, 0, MemoryMappedFileAccess.ReadWrite,
#if FEATURE_MEMORYMAPPEDFILESECURITY
                                                                           null,
#endif
                                                                           HandleInheritability.None, false))
                {
                    //RandomAccessFile random = new RandomAccessFile(tmpFile, "rw");
                    //FileChannel fileChannelRW = random.getChannel();
                    //MappedByteBuffer resultReadWrite = fileChannelRW.map(
                    //        FileChannel.MapMode.READ_WRITE, 0, fileChannelRW.size());

                    MemoryMappedViewByteBuffer resultReadWrite = fileChannelRW.CreateViewByteBuffer(0, (int)randomFile.Length, MemoryMappedFileAccess.ReadWrite);

                    // Invoking force() will change the buffer
                    assertFalse(mmbReadWrite.Equals(resultReadWrite));
                }
            }

            //fileChannelRead.close();
            //fileChannelR.close();
            //fileChannelReadWrite.close();
            //fileChannelRW.close();
            //}
        }
 public void InvalidArguments_FileStream()
 {
     // null is an invalid stream
     Assert.Throws <ArgumentNullException>("fileStream", () => MemoryMappedFile.CreateFromFile(null, CreateUniqueMapName(), 4096, MemoryMappedFileAccess.Read, HandleInheritability.None, true));
 }
示例#17
0
            public void TestBasic()
            {
                byte[] srcData = new byte[20];
                for (int i = 0; i < 20; i++)
                {
                    srcData[i] = 3;
                }
                //File blah = File.createTempFile("blah", null);
                //blah.deleteOnExit();

                var blah = new FileInfo(Path.GetTempFileName());

                using (FileStream fos = new FileStream(blah.FullName, FileMode.Open, FileAccess.ReadWrite))
                {
                    //FileChannel fc = fos.getChannel();
                    //fc.write(ByteBuffer.wrap(srcData));
                    //fc.close();
                    fos.Write(ByteBuffer.Wrap(srcData));
                }

                MemoryMappedViewByteBuffer mbb;

                using (FileStream fis = new FileStream(blah.FullName, FileMode.Open, FileAccess.Read))
                    using (var fc = MemoryMappedFile.CreateFromFile(fis, null, 0, MemoryMappedFileAccess.Read,
#if FEATURE_MEMORYMAPPEDFILESECURITY
                                                                    null,
#endif
                                                                    HandleInheritability.None, false))
                    {
                        //fc = fis.getChannel();
                        //MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_ONLY, 0, 10);
                        mbb = fc.CreateViewByteBuffer(0, 10, MemoryMappedFileAccess.Read);
                        //mbb.load();
                        //mbb.isLoaded();
                        mbb.Flush();
                        assertTrue("Incorrect isReadOnly", mbb.IsReadOnly);

                        // repeat with unaligned position in file
                        //mbb = fc.map(FileChannel.MapMode.READ_ONLY, 1, 10);
                        mbb = fc.CreateViewByteBuffer(0, 10, MemoryMappedFileAccess.Read);
                        //mbb.load();
                        //mbb.isLoaded();
                        mbb.Flush();
                    }

                using (FileStream raf = new FileStream(blah.FullName, FileMode.Open, FileAccess.Read))
                    using (var fc = MemoryMappedFile.CreateFromFile(raf, null, 0, MemoryMappedFileAccess.Read,
#if FEATURE_MEMORYMAPPEDFILESECURITY
                                                                    null,
#endif
                                                                    HandleInheritability.None, false))
                    {
                        //RandomAccessFile raf = new RandomAccessFile(blah, "r");
                        //fc = raf.getChannel();
                        //mbb = fc.map(FileChannel.MapMode.READ_ONLY, 0, 10);
                        mbb = fc.CreateViewByteBuffer(0, 10, MemoryMappedFileAccess.Read);
                        assertTrue("Incorrect isReadOnly", mbb.IsReadOnly);
                    }

                using (FileStream raf = new FileStream(blah.FullName, FileMode.Open, FileAccess.ReadWrite))
                    using (var fc = MemoryMappedFile.CreateFromFile(raf, null, 0, MemoryMappedFileAccess.ReadWrite,
#if FEATURE_MEMORYMAPPEDFILESECURITY
                                                                    null,
#endif
                                                                    HandleInheritability.None, false))
                    {
                        //raf = new RandomAccessFile(blah, "rw");
                        //fc = raf.getChannel();
                        //mbb = fc.map(FileChannel.MapMode.READ_WRITE, 0, 10);
                        assertTrue("Incorrect isReadOnly", mbb.IsReadOnly);
                    }

                // clean-up
                mbb = null;
                //System.gc();
                GC.Collect();
                Thread.Sleep(500);
                DeleteFile(blah);
            }
 private MemoryMappedFile Open(long size = 0)
 {
     return(MemoryMappedFile.CreateFromFile(path, FileMode.OpenOrCreate, Guid.NewGuid().ToString(), size));
 }
示例#19
0
        private static IEnumerable <ReadTestResult> Read_Archive_Items(IEnumerable <FileEntry> files)
        {
            var results = new ConcurrentBag <ReadTestResult>();

            var filesGroups = files.Select((f, i) => new { Value = f, Index = i })
                              .GroupBy(item => item.Value.Archive.ArchiveAbsolutePath);

            foreach (var fileGroup in filesGroups)
            {
                var fileList = fileGroup.ToList();

                var ar = s_bm.Archives.Lookup(fileGroup.Key).Value as Archive;

                using var fs  = new FileStream(fileGroup.Key, FileMode.Open, FileAccess.Read, FileShare.Read);
                using var mmf = MemoryMappedFile.CreateFromFile(fs, null, 0, MemoryMappedFileAccess.Read, HandleInheritability.None, false);

#if IS_PARALLEL
                Parallel.ForEach(fileList, tmpFile =>
#else
                foreach (var tmpFile in fileList)
#endif
                {
                    var file = tmpFile.Value;
                    try
                    {
                        using var ms = new MemoryStream();
                        ar?.CopyFileToStream(ms, file.NameHash64, false, mmf);
                        ms.Seek(0, SeekOrigin.Begin);

                        using var reader = new CR2WReader(ms);
                        var readResult   = reader.ReadFile(out var c, DECOMPRESS_BUFFERS);

                        switch (readResult)
                        {
                        case RED4.Archive.IO.EFileReadErrorCodes.NoCr2w:
                            results.Add(new ReadTestResult
                            {
                                FileEntry  = file,
                                Success    = true,
                                ReadResult = ReadTestResult.ReadResultType.NoCr2W
                            });
                            break;

                        case RED4.Archive.IO.EFileReadErrorCodes.UnsupportedVersion:
                            results.Add(new ReadTestResult
                            {
                                FileEntry  = file,
                                Success    = false,
                                ReadResult = ReadTestResult.ReadResultType.UnsupportedVersion,
                                Message    = $"Unsupported Version ({c.MetaData.Version})"
                            });
                            break;

                        case RED4.Archive.IO.EFileReadErrorCodes.NoError:
                            c.MetaData.FileName = file.NameOrHash;

                            var res = ReadTestResult.ReadResultType.NoError;
                            var msg = "";

                            var additionalCr2WFileBytes =
                                (int)(reader.BaseStream.Length - reader.BaseStream.Position);
                            if (additionalCr2WFileBytes > 0)
                            {
                                res |= ReadTestResult.ReadResultType.HasAdditionalBytes;
                                msg += $"Additional Bytes: {additionalCr2WFileBytes}";
                            }

                            results.Add(new ReadTestResult
                            {
                                FileEntry       = file,
                                Success         = true /*!hasAdditionalBytes && !hasUnknownBytes*/,
                                ReadResult      = res,
                                Message         = msg,
                                AdditionalBytes = additionalCr2WFileBytes
                            });
                            break;

                        default:
                            throw new Exception();
                        }
                    }
                    catch (Exception e)
                    {
                        results.Add(new ReadTestResult
                        {
                            FileEntry     = file,
                            Success       = false,
                            ReadResult    = ReadTestResult.ReadResultType.RuntimeException,
                            ExceptionType = e.GetType(),
                            Message       = $"{e.Message}"
                        });
                    }
#if IS_PARALLEL
                });
示例#20
0
        public void StreamAccessReadWriteMemoryMappedProjectedFile()
        {
            string        filename        = @"Test_EPF_WorkingDirectoryTests\StreamAccessReadWriteMemoryMappedProjectedFile.cs";
            string        fileVirtualPath = this.Enlistment.GetVirtualPathTo(filename);
            string        contents        = fileVirtualPath.ShouldBeAFile(this.fileSystem).WithContents();
            StringBuilder contentsBuilder = new StringBuilder(contents);

            using (MemoryMappedFile mmf = MemoryMappedFile.CreateFromFile(fileVirtualPath))
            {
                // Length of the Byte-order-mark that will be at the start of the memory mapped file.
                // See https://msdn.microsoft.com/en-us/library/windows/desktop/dd374101(v=vs.85).aspx
                int bomOffset = 3;

                // offset -> Number of bytes from the start of the file where the view starts
                int    offset     = 64;
                int    size       = contents.Length;
                string newContent = "**NEWCONTENT**";

                using (MemoryMappedViewStream streamAccessor = mmf.CreateViewStream(offset, size - offset + bomOffset))
                {
                    streamAccessor.CanRead.ShouldEqual(true);
                    streamAccessor.CanWrite.ShouldEqual(true);

                    for (int i = offset; i < size - offset; ++i)
                    {
                        streamAccessor.ReadByte().ShouldEqual(contents[i - bomOffset]);
                    }

                    // Reset to the start of the stream (which will place the streamAccessor at offset in the memory file)
                    streamAccessor.Seek(0, SeekOrigin.Begin);
                    byte[] newContentBuffer = Encoding.ASCII.GetBytes(newContent);

                    streamAccessor.Write(newContentBuffer, 0, newContent.Length);

                    for (int i = 0; i < newContent.Length; ++i)
                    {
                        contentsBuilder[offset + i - bomOffset] = newContent[i];
                    }

                    contents = contentsBuilder.ToString();
                }

                // Verify the file has the new contents inserted into it
                using (MemoryMappedViewStream streamAccessor = mmf.CreateViewStream(offset: 0, size: size + bomOffset))
                {
                    // Skip the BOM
                    for (int i = 0; i < bomOffset; ++i)
                    {
                        streamAccessor.ReadByte();
                    }

                    for (int i = 0; i < size; ++i)
                    {
                        streamAccessor.ReadByte().ShouldEqual(contents[i]);
                    }
                }
            }

            // Confirm the new contents was written to disk
            fileVirtualPath.ShouldBeAFile(this.fileSystem).WithContents(contents);
        }
示例#21
0
 public void OpenMMF()
 {
     PSTMMF = MemoryMappedFile.CreateFromFile(Path, FileMode.Open);
 }
 public DecompressFileManager(string file, long size)
 {
     _file = file;
     _mmf  = MemoryMappedFile.CreateFromFile(file, FileMode.OpenOrCreate, "map", size);
 }
 public MemoryMappedFileSlim(string fileNamePath, long fileLength)
     : this(MemoryMappedFile.CreateFromFile(fileNamePath, FileMode.OpenOrCreate, mapName : null, capacity : fileLength), fileNamePath)
 {
 }
示例#24
0
        void EncryptedFileCopy(FileStream file, Xp3Entry xp3entry, Stream output, bool compress)
        {
            if (file.Length > int.MaxValue)
            {
                throw new FileSizeException();
            }

            using (var map = MemoryMappedFile.CreateFromFile(file, null, 0,
                                                             MemoryMappedFileAccess.Read, null, HandleInheritability.None, true))
            {
                uint unpacked_size = (uint)file.Length;
                xp3entry.UnpackedSize = (uint)unpacked_size;
                xp3entry.Size         = (uint)unpacked_size;
                using (var view = map.CreateViewAccessor(0, unpacked_size, MemoryMappedFileAccess.Read))
                {
                    var segment = new Xp3Segment {
                        IsCompressed = compress,
                        Offset       = output.Position,
                        Size         = unpacked_size,
                        PackedSize   = unpacked_size,
                    };
                    if (compress)
                    {
                        output = new ZLibStream(output, CompressionMode.Compress, CompressionLevel.Level9, true);
                    }
                    unsafe
                    {
                        byte[] read_buffer = new byte[81920];
                        byte * ptr         = view.GetPointer(0);
                        try
                        {
                            var  checksum         = new Adler32();
                            bool hash_after_crypt = xp3entry.Cipher.HashAfterCrypt;
                            if (!hash_after_crypt)
                            {
                                xp3entry.Hash = checksum.Update(ptr, (int)unpacked_size);
                            }
                            int offset    = 0;
                            int remaining = (int)unpacked_size;
                            while (remaining > 0)
                            {
                                int amount = Math.Min(remaining, read_buffer.Length);
                                remaining -= amount;
                                Marshal.Copy((IntPtr)(ptr + offset), read_buffer, 0, amount);
                                xp3entry.Cipher.Encrypt(xp3entry, offset, read_buffer, 0, amount);
                                if (hash_after_crypt)
                                {
                                    checksum.Update(read_buffer, 0, amount);
                                }
                                output.Write(read_buffer, 0, amount);
                                offset += amount;
                            }
                            if (hash_after_crypt)
                            {
                                xp3entry.Hash = checksum.Value;
                            }
                        }
                        finally
                        {
                            view.SafeMemoryMappedViewHandle.ReleasePointer();
                            if (compress)
                            {
                                var dest = (output as ZLibStream).BaseStream;
                                output.Dispose();
                                segment.PackedSize = (uint)(dest.Position - segment.Offset);
                                xp3entry.Size      = segment.PackedSize;
                            }
                            xp3entry.Segments.Add(segment);
                        }
                    }
                }
            }
        }
示例#25
0
        public void StreamAndRandomAccessReadWriteMemoryMappedProjectedFile()
        {
            string fileVirtualPath = this.Enlistment.GetVirtualPathTo("Test_EPF_WorkingDirectoryTests", "StreamAndRandomAccessReadWriteMemoryMappedProjectedFile.cs");

            StringBuilder contentsBuilder = new StringBuilder();

            // Length of the Byte-order-mark that will be at the start of the memory mapped file.
            // See https://msdn.microsoft.com/en-us/library/windows/desktop/dd374101(v=vs.85).aspx
            int bomOffset = 3;

            using (MemoryMappedFile mmf = MemoryMappedFile.CreateFromFile(fileVirtualPath))
            {
                // The text length of StreamAndRandomAccessReadWriteMemoryMappedProjectedFile.cs was determined
                // outside of this test so that the test would not hydrate the file before we access via MemoryMappedFile
                int fileTextLength = 13762;

                int size = bomOffset + fileTextLength;

                int streamAccessWriteOffset = 64;
                int randomAccessWriteOffset = 128;

                string newStreamAccessContent = "**NEW_STREAM_CONTENT**";
                string newRandomAccessConents = "&&NEW_RANDOM_CONTENT&&";

                // Read (and modify) contents using stream accessor
                using (MemoryMappedViewStream streamAccessor = mmf.CreateViewStream(offset: 0, size: size))
                {
                    streamAccessor.CanRead.ShouldEqual(true);
                    streamAccessor.CanWrite.ShouldEqual(true);

                    for (int i = 0; i < size; ++i)
                    {
                        contentsBuilder.Append((char)streamAccessor.ReadByte());
                    }

                    // Reset to the start of the stream (which will place the streamAccessor at offset in the memory file)
                    streamAccessor.Seek(streamAccessWriteOffset, SeekOrigin.Begin);
                    byte[] newContentBuffer = Encoding.ASCII.GetBytes(newStreamAccessContent);

                    streamAccessor.Write(newContentBuffer, 0, newStreamAccessContent.Length);

                    for (int i = 0; i < newStreamAccessContent.Length; ++i)
                    {
                        contentsBuilder[streamAccessWriteOffset + i] = newStreamAccessContent[i];
                    }
                }

                // Read (and modify) contents using random accessor
                using (MemoryMappedViewAccessor randomAccessor = mmf.CreateViewAccessor(offset: 0, size: size))
                {
                    randomAccessor.CanRead.ShouldEqual(true);
                    randomAccessor.CanWrite.ShouldEqual(true);

                    // Confirm the random accessor reads the same content that was read (and written) by the stream
                    // accessor
                    for (int i = 0; i < size; ++i)
                    {
                        ((char)randomAccessor.ReadByte(i)).ShouldEqual(contentsBuilder[i]);
                    }

                    // Write some new content
                    for (int i = 0; i < newRandomAccessConents.Length; ++i)
                    {
                        // Convert to byte before writing rather than writing as char, because char version will write a 16-bit
                        // unicode char
                        randomAccessor.Write(i + randomAccessWriteOffset, Convert.ToByte(newRandomAccessConents[i]));
                        ((char)randomAccessor.ReadByte(i + randomAccessWriteOffset)).ShouldEqual(newRandomAccessConents[i]);
                    }

                    for (int i = 0; i < newRandomAccessConents.Length; ++i)
                    {
                        contentsBuilder[randomAccessWriteOffset + i] = newRandomAccessConents[i];
                    }
                }

                // Verify the file one more time with a stream accessor
                using (MemoryMappedViewStream streamAccessor = mmf.CreateViewStream(offset: 0, size: size))
                {
                    for (int i = 0; i < size; ++i)
                    {
                        streamAccessor.ReadByte().ShouldEqual(contentsBuilder[i]);
                    }
                }
            }

            // Remove the BOM before comparing with the contents of the file on disk
            contentsBuilder.Remove(0, bomOffset);

            // Confirm the new contents was written to the file
            fileVirtualPath.ShouldBeAFile(this.fileSystem).WithContents(contentsBuilder.ToString());
        }
示例#26
0
        /// <summary>
        /// This Method is a utility to remove the code-signature (if any)
        /// from a MachO AppHost binary.
        ///
        /// The tool assumes the following layout of the executable:
        ///
        /// * MachoHeader (64-bit, executable, not swapped integers)
        /// * LoadCommands
        ///     LC_SEGMENT_64 (__PAGEZERO)
        ///     LC_SEGMENT_64 (__TEXT)
        ///     LC_SEGMENT_64 (__DATA)
        ///     LC_SEGMENT_64 (__LINKEDIT)
        ///     ...
        ///     LC_SYMTAB
        ///     ...
        ///     LC_CODE_SIGNATURE (last)
        ///
        ///  * ... Different Segments ...
        ///
        ///  * The __LINKEDIT Segment (last)
        ///      * ... Different sections ...
        ///      * SYMTAB
        ///      * (Some alignment bytes)
        ///      * The Code-signature
        ///
        /// In order to remove the signature, the method:
        /// - Removes (zeros out) the LC_CODE_SIGNATURE command
        /// - Adjusts the size and count of the load commands in the header
        /// - Truncates the size of the __LINKEDIT segment to the end of SYMTAB
        /// - Truncates the apphost file to the end of the __LINKEDIT segment
        ///
        /// </summary>
        /// <param name="stream">Stream containing the AppHost</param>
        /// <returns>
        ///  True if
        ///    - The input is a MachO binary, and
        ///    - It is a signed binary, and
        ///    - The signature was successfully removed
        ///   False otherwise
        /// </returns>
        /// <exception cref="AppHostMachOFormatException">
        /// The input is a MachO file, but doesn't match the expect format of the AppHost.
        /// </exception>
        public static unsafe bool RemoveSignature(FileStream stream)
        {
            uint signatureSize = 0;

            using (var mappedFile = MemoryMappedFile.CreateFromFile(stream,
                                                                    mapName: null,
                                                                    capacity: 0,
                                                                    MemoryMappedFileAccess.ReadWrite,
                                                                    HandleInheritability.None,
                                                                    leaveOpen: true))
            {
                using (var accessor = mappedFile.CreateViewAccessor())
                {
                    byte *file = null;
                    try
                    {
                        accessor.SafeMemoryMappedViewHandle.AcquirePointer(ref file);
                        Verify(file != null, MachOFormatError.MemoryMapAccessFault);

                        MachHeader *header = (MachHeader *)file;

                        if (!header->IsValid())
                        {
                            // Not a MachO file.
                            return(false);
                        }

                        Verify(header->Is64BitExecutable(), MachOFormatError.Not64BitExe);

                        file += sizeof(MachHeader);
                        SegmentCommand64 *   linkEdit  = null;
                        SymtabCommand *      symtab    = null;
                        LinkEditDataCommand *signature = null;

                        for (uint i = 0; i < header->ncmds; i++)
                        {
                            LoadCommand *command = (LoadCommand *)file;
                            if (command->cmd == Command.LC_SEGMENT_64)
                            {
                                SegmentCommand64 *segment = (SegmentCommand64 *)file;
                                if (segment->SegName.Equals("__LINKEDIT"))
                                {
                                    Verify(linkEdit == null, MachOFormatError.DuplicateLinkEdit);
                                    linkEdit = segment;
                                }
                            }
                            else if (command->cmd == Command.LC_SYMTAB)
                            {
                                Verify(symtab == null, MachOFormatError.DuplicateSymtab);
                                symtab = (SymtabCommand *)command;
                            }
                            else if (command->cmd == Command.LC_CODE_SIGNATURE)
                            {
                                Verify(i == header->ncmds - 1, MachOFormatError.SignCommandNotLast);
                                signature = (LinkEditDataCommand *)command;
                                break;
                            }

                            file += command->cmdsize;
                        }

                        if (signature != null)
                        {
                            Verify(linkEdit != null, MachOFormatError.MissingLinkEdit);
                            Verify(symtab != null, MachOFormatError.MissingSymtab);

                            var symtabEnd    = symtab->stroff + symtab->strsize;
                            var linkEditEnd  = linkEdit->fileoff + linkEdit->filesize;
                            var signatureEnd = signature->dataoff + signature->datasize;
                            var fileEnd      = (ulong)stream.Length;

                            Verify(linkEditEnd == fileEnd, MachOFormatError.LinkEditNotLast);
                            Verify(signatureEnd == fileEnd, MachOFormatError.SignBlobNotLast);

                            Verify(symtab->symoff > linkEdit->fileoff, MachOFormatError.SymtabNotInLinkEdit);
                            Verify(signature->dataoff > linkEdit->fileoff, MachOFormatError.SignNotInLinkEdit);

                            // The signature blob immediately follows the symtab blob,
                            // except for a few bytes of padding.
                            Verify(signature->dataoff >= symtabEnd && signature->dataoff - symtabEnd < 32, MachOFormatError.SignBlobNotLast);

                            // Remove the signature command
                            header->ncmds--;
                            header->sizeofcmds -= signature->cmdsize;
                            Unsafe.InitBlock(signature, 0, signature->cmdsize);

                            // Remove the signature blob (note for truncation)
                            signatureSize = (uint)(fileEnd - symtabEnd);

                            // Adjust the __LINKEDIT segment load command
                            linkEdit->filesize -= signatureSize;

                            // codesign --remove-signature doesn't reset the vmsize.
                            // Setting the vmsize here makes the output bin-equal with the original
                            // unsigned apphost (and not bin-equal with a signed-unsigned-apphost).
                            linkEdit->vmsize = linkEdit->filesize;
                        }
                    }
                    finally
                    {
                        if (file != null)
                        {
                            accessor.SafeMemoryMappedViewHandle.ReleasePointer();
                        }
                    }
                }
            }

            if (signatureSize != 0)
            {
                // The signature was removed, update the file length
                stream.SetLength(stream.Length - signatureSize);
                return(true);
            }

            return(false);
        }
示例#27
0
 private static MemoryMappedFile CreateFromFile(System.IO.FileStream fileStream, string mapName, long capacity, System.IO.MemoryMappedFiles.MemoryMappedFileAccess access, System.IO.HandleInheritability inheritability, bool leaveOpen)
 {
     return(MemoryMappedFile.CreateFromFile(fileStream, mapName, capacity, access, inheritability, leaveOpen));
 }
示例#28
0
        /// <summary>
        /// This Method is a utility to adjust the apphost MachO-header
        /// to include the bytes added by the single-file bundler at the end of the file.
        ///
        /// The tool assumes the following layout of the executable
        ///
        /// * MachoHeader (64-bit, executable, not swapped integers)
        /// * LoadCommands
        ///     LC_SEGMENT_64 (__PAGEZERO)
        ///     LC_SEGMENT_64 (__TEXT)
        ///     LC_SEGMENT_64 (__DATA)
        ///     LC_SEGMENT_64 (__LINKEDIT)
        ///     ...
        ///     LC_SYMTAB
        ///
        ///  * ... Different Segments
        ///
        ///  * The __LINKEDIT Segment (last)
        ///      * ... Different sections ...
        ///      * SYMTAB (last)
        ///
        /// The MAC codesign tool places several restrictions on the layout
        ///   * The __LINKEDIT segment must be the last one
        ///   * The __LINKEDIT segment must cover the end of the file
        ///   * All bytes in the __LINKEDIT segment are used by other linkage commands
        ///     (ex: symbol/string table, dynamic load information etc)
        ///
        /// In order to circumvent these restrictions, we:
        ///    * Extend the __LINKEDIT segment to include the bundle-data
        ///    * Extend the string table to include all the bundle-data
        ///      (that is, the bundle-data appear as strings to the loader/codesign tool).
        ///
        ///  This method has certain limitations:
        ///    * The bytes for the bundler may be unnecessarily loaded at startup
        ///    * Tools that process the string table may be confused (?)
        ///    * The string table size is limited to 4GB. Bundles larger than that size
        ///      cannot be accommodated by this utility.
        ///
        /// </summary>
        /// <param name="filePath">Path to the AppHost</param>
        /// <returns>
        ///  True if
        ///    - The input is a MachO binary, and
        ///    - The additional bytes were successfully accommodated within the MachO segments.
        ///   False otherwise
        /// </returns>
        /// <exception cref="AppHostMachOFormatException">
        /// The input is a MachO file, but doesn't match the expect format of the AppHost.
        /// </exception>
        public static unsafe bool AdjustHeadersForBundle(string filePath)
        {
            ulong fileLength = (ulong)new FileInfo(filePath).Length;

            using (var mappedFile = MemoryMappedFile.CreateFromFile(filePath))
            {
                using (var accessor = mappedFile.CreateViewAccessor())
                {
                    byte *file = null;
                    try
                    {
                        accessor.SafeMemoryMappedViewHandle.AcquirePointer(ref file);
                        Verify(file != null, MachOFormatError.MemoryMapAccessFault);

                        MachHeader *header = (MachHeader *)file;

                        if (!header->IsValid())
                        {
                            // Not a MachO file.
                            return(false);
                        }

                        Verify(header->Is64BitExecutable(), MachOFormatError.Not64BitExe);

                        file += sizeof(MachHeader);
                        SegmentCommand64 *   linkEdit  = null;
                        SymtabCommand *      symtab    = null;
                        LinkEditDataCommand *signature = null;

                        for (uint i = 0; i < header->ncmds; i++)
                        {
                            LoadCommand *command = (LoadCommand *)file;
                            if (command->cmd == Command.LC_SEGMENT_64)
                            {
                                SegmentCommand64 *segment = (SegmentCommand64 *)file;
                                if (segment->SegName.Equals("__LINKEDIT"))
                                {
                                    Verify(linkEdit == null, MachOFormatError.DuplicateLinkEdit);
                                    linkEdit = segment;
                                }
                            }
                            else if (command->cmd == Command.LC_SYMTAB)
                            {
                                Verify(symtab == null, MachOFormatError.DuplicateSymtab);
                                symtab = (SymtabCommand *)command;
                            }

                            file += command->cmdsize;
                        }

                        Verify(linkEdit != null, MachOFormatError.MissingLinkEdit);
                        Verify(symtab != null, MachOFormatError.MissingSymtab);

                        // Update the string table to include bundle-data
                        ulong newStringTableSize = fileLength - symtab->stroff;
                        if (newStringTableSize > uint.MaxValue)
                        {
                            // Too big, too bad;
                            return(false);
                        }
                        symtab->strsize = (uint)newStringTableSize;

                        // Update the __LINKEDIT segment to include bundle-data
                        linkEdit->filesize = fileLength - linkEdit->fileoff;
                        linkEdit->vmsize   = linkEdit->filesize;
                    }
                    finally
                    {
                        if (file != null)
                        {
                            accessor.SafeMemoryMappedViewHandle.ReleasePointer();
                        }
                    }
                }
            }

            return(true);
        }
示例#29
0
 public void CreateFromFile_Null()
 {
     AssertThrows <ArgumentNullException> (delegate() {
         MemoryMappedFile.CreateFromFile(null);
     });
 }
示例#30
0
        /// <summary>
        /// Downloads the uri and saves it to filename.
        /// </summary>
        /// <param name="cancellationToken">
        /// The cancellation token.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        public Task Download(CancellationToken cancellationToken = new CancellationToken())
        {
            return(Task.Run(
                       () =>
            {
                using (var fileStream = new FileStream(this.Filename, FileMode.Create))
                {
                    fileStream.SetLength(this.Size);
                }

                using (var memoryMappedFile = MemoryMappedFile.CreateFromFile(this.Filename, FileMode.Open))
                {
                    var tasks = new List <Tuple <Task, CancellationTokenSource> >();
                    for (var i = 0; i < this.numberOfConnections; i++)
                    {
                        var cancellationTokenSource = new CancellationTokenSource();
                        tasks.Add(
                            Tuple.Create(
                                this.StartDownloader(memoryMappedFile, cancellationTokenSource.Token),
                                cancellationTokenSource));
                    }

                    while (!cancellationToken.IsCancellationRequested)
                    {
                        tasks.Add(
                            Tuple.Create <Task, CancellationTokenSource>(
                                Task.Delay(TimeSpan.FromSeconds(0.5)), null));

                        int index = Task.WaitAny(tasks.Select(tuple => tuple.Item1).ToArray());
                        lock (this.stateLock)
                        {
                            if (this.chunkPosition == this.numberOfChunks)
                            {
                                break;
                            }
                        }

                        tasks.RemoveAt(index);
                        lock (this.numberOfConnectionsLock)
                        {
                            while (tasks.Count != this.NumberOfConnections)
                            {
                                if (tasks.Count > this.NumberOfConnections)
                                {
                                    Tuple <Task, CancellationTokenSource> tuple = tasks[tasks.Count - 1];
                                    tasks.RemoveAt(tasks.Count - 1);
                                    tuple.Item2.Cancel();
                                    tuple.Item1.Wait();
                                }
                                else
                                {
                                    var cancellationTokenSource = new CancellationTokenSource();
                                    tasks.Add(
                                        Tuple.Create(
                                            this.StartDownloader(
                                                memoryMappedFile, cancellationTokenSource.Token),
                                            cancellationTokenSource));
                                }
                            }
                        }
                    }

                    if (cancellationToken.IsCancellationRequested)
                    {
                        foreach (var tuple in tasks.Where(tuple => tuple.Item2 != null))
                        {
                            tuple.Item2.Cancel();
                        }
                    }

                    Task.WaitAll(tasks.Select(tuple => tuple.Item1).ToArray());
                }
            }));
        }