Exemple #1
0
        /// <summary>
        /// Optimize
        /// </summary>
        /// <param name="script">Script</param>
        /// <param name="entryPoints">Entry points</param>
        /// <param name="parserTypes">Optmize parser, currently, there are four parsers:
        /// <para> DELETE_DEAD_CODDE -- delete dead code parser, default parser</para>
        /// <para> USE_SHORT_ADDRESS -- use short address parser. eg: JMP_L -> JMP, JMPIF_L -> JMPIF, default parser</para>
        /// <para> DELETE_NOP -- delete nop parser</para>
        /// <para> DELETE_USELESS_JMP -- delete useless jmp parser, eg: JPM 2</para>
        /// <para> DELETE_USELESS_EQUAL -- delete useless equal parser, eg: EQUAL 01 01 </para></param>
        /// <param name="addrConvertTable">Convert table for addresses</param>
        /// <returns>Optimized script</returns>
        public static byte[] Optimize(byte[] script, int[] entryPoints, OptimizeParserType parserTypes, out Dictionary <int, int> addrConvertTable)
        {
            var optimizer = new NefOptimizer();

            foreach (OptimizeParserType e in Enum.GetValues(typeof(OptimizeParserType)))
            {
                if (e == OptimizeParserType.NONE)
                {
                    continue;
                }
                if ((e & parserTypes) > 0)
                {
                    object[] objAttrs = typeof(OptimizeParserType).GetField(e.ToString()).GetCustomAttributes(typeof(OptimizeParserAttribute), false);
                    if (objAttrs is null || objAttrs.Length == 0)
                    {
                        continue;
                    }
                    var attribute = (OptimizeParserAttribute)objAttrs[0];
                    var obj       = Activator.CreateInstance(attribute.Type);
                    if (obj is null)
                    {
                        continue;
                    }
                    IOptimizeParser parser = (IOptimizeParser)obj;
                    optimizer.AddOptimizeParser(parser);
                }
            }

            addrConvertTable = null;

            //优化是一个管线,一次就应该解决问题,这个循环有些蠢,另开issue讨论
            // 10 iterations max
            for (int x = 0; x < 10; x++)
            {
                //step01 Load
                using (var ms = new MemoryStream(script))
                {
                    optimizer.LoadNef(ms, entryPoints);
                }

                //step02 doOptimize
                optimizer.Optimize();

                //step03 link
                using (var ms = new MemoryStream())
                {
                    optimizer.LinkNef(ms);

                    if (addrConvertTable is null)
                    {
                        addrConvertTable = optimizer.GetAddrConvertTable();
                    }
                    else
                    {
                        Dictionary <int, int> addrConvertTableTemp = optimizer.GetAddrConvertTable();
                        addrConvertTable = optimizer.RebuildAddrConvertTable(addrConvertTable, addrConvertTableTemp);
                    }

                    //updateEntryPoints for next loop
                    entryPoints = optimizer.GetEntryPoint();

                    var bytes = ms.ToArray();
                    if (bytes.SequenceEqual(script))
                    {
                        // Sometimes the script could be bigger but more efficient
                        // int.Max+INC (6 bytes) => PUSHInt64 (9 bytes)
                        break;
                    }
                    script = bytes;
                }

                // Execute it while decrease the size
            }

            return(script);
        }
Exemple #2
0
 public static byte[] Optimize(byte[] script, int[] entryPoints, OptimizeParserType parserTypes)
 {
     return(Optimize(script, entryPoints, parserTypes, out _));
 }