Ejemplo n.º 1
0
        /// <summary>
        /// Process the field and add to datamember
        /// </summary>
        /// <param name="aField">The field to process</param>
        private void ProcessField(FieldInfo aField)
        {
            var xName    = aField.FullName();
            int xTheSize = 4;

            Type xFieldTypeDef = aField.FieldType;

            if (!xFieldTypeDef.IsClass || xFieldTypeDef.IsValueType)
            {
                xTheSize = aField.FieldType.SizeOf();
            }

            // We use marshal and read c# assembly memory to get the value of static field
            byte[] xData = new byte[xTheSize];
            try
            {
                object xValue = aField.GetValue(null);
                if (xValue != null)
                {
                    try
                    {
                        xData = new byte[xTheSize];
                        if (xValue.GetType().IsValueType)
                        {
                            for (int x = 0; x < xTheSize; x++)
                            {
                                xData[x] = Marshal.ReadByte(xValue, x);
                            }
                        }
                    }
                    catch
                    {
                        // Do nothing, if error...we won't care it
                    }
                }
            }
            catch
            {
                // Do nothing, if error...we won't care it
            }
            // Add it to data member
            Core.InsertData(new AsmData(xName, xData));

            // Add it build definations
            BuildDefinations.Add(aField);
        }
Ejemplo n.º 2
0
        public static void main()
        {
            const uint MultibootMagic  = 0x1BADB002;
            const uint MultibootFlags  = 0x10007;
            const uint InitalStackSize = 0x50000;

            /* Multiboot Config */
            AssemblyHelper.AssemblerCode.Add(new Literal("MultibootSignature dd {0}", MultibootMagic));
            AssemblyHelper.AssemblerCode.Add(new Literal("MultibootFlags dd {0}", 65543));
            AssemblyHelper.AssemblerCode.Add(new Literal("MultibootChecksum dd {0}", -(MultibootMagic + MultibootFlags)));
            AssemblyHelper.AssemblerCode.Add(new Literal("MultibootHeaderAddr dd {0}", 0));
            AssemblyHelper.AssemblerCode.Add(new Literal("MultibootLoadAddr dd {0}", 0));
            AssemblyHelper.AssemblerCode.Add(new Literal("MultibootLoadEndAddr dd {0}", 0));
            AssemblyHelper.AssemblerCode.Add(new Literal("MultibootBSSEndAddr dd {0}", 0));
            AssemblyHelper.AssemblerCode.Add(new Literal("MultibootEntryAddr dd {0}", 0));

            AssemblyHelper.InsertData(new AsmData("InitialStack", InitalStackSize));

            AssemblyHelper.AssemblerCode.Add(new Label("_Kernel_Main"));

            /* Here is Entrypoint Method */
            AssemblyHelper.AssemblerCode.Add(new Cli()); //Clear interrupts first !!

            //Setup Stack pointer, We do rest things later (i.e. Another method) because they are managed :)
            AssemblyHelper.AssemblerCode.Add(new Mov {
                DestinationReg = Registers.ESP, SourceRef = "InitialStack"
            });
            AssemblyHelper.AssemblerCode.Add(new Add {
                DestinationReg = Registers.ESP, SourceRef = InitalStackSize.ToString()
            });

            AssemblyHelper.AssemblerCode.Add(new Push {
                DestinationReg = Registers.EAX
            });
            AssemblyHelper.AssemblerCode.Add(new Push {
                DestinationReg = Registers.EBX
            });                                                                           //Push Multiboot Header Info Address
            AssemblyHelper.AssemblerCode.Add(new Call("Kernel_Start"));
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Scan the normal method and find inline calls of virtual or real method to add it into queue
        /// After that Process method and add its assembly to main Array
        /// </summary>
        /// <param name="aMethod">The normal mathod =)</param>
        private void ScanMethod(MethodBase aMethod)
        {
            // Just a basic patch to fix Null reference exception
            var xBody = aMethod.GetMethodBody();

            var xAssemblyName = aMethod.DeclaringType.Assembly.GetName().Name;

            if (RestrictedAssembliesName.Contains(xAssemblyName) && Plugs.ContainsValue(aMethod.FullName()))
            {
                return;
            }

            if (ILHelper.IsDelegate(aMethod.DeclaringType))
            {
                ProcessDelegate(aMethod);
                return;
            }

            if (xBody == null) // Don't try to build null method
            {
                return;
            }

            // Tell logger that we are processing a method with given name and declaring type
            // Well declaring type is necessary because when we have a plugged method than
            // Its full name is the plugged value so we will not get where the plug is implemented
            // So declaring type help us to determine that
            ILCompiler.Logger.Write("@Processor", aMethod.FullName(), "Scanning Method()");
            ILCompiler.Logger.Write("Type: " + aMethod.DeclaringType.FullName);
            ILCompiler.Logger.Write("Assembly: " + xAssemblyName);

            /* Scan Method for inline virtual or real methods call */
            var xParams     = aMethod.GetParameters();
            var xParamTypes = new Type[xParams.Length];

            for (int i = 0; i < xParams.Length; i++)
            {
                xParamTypes[i] = xParams[i].ParameterType;
                QueuedMember.Enqueue(xParamTypes[i]);
            }

            bool DynamicMethod = (aMethod.DeclaringType == null);

            if (!DynamicMethod)
            {
                QueuedMember.Enqueue(aMethod.DeclaringType);
            }

            if (aMethod is MethodInfo)
            {
                QueuedMember.Enqueue(((MethodInfo)aMethod).ReturnType);
            }

            if (!DynamicMethod && aMethod.IsVirtual)
            {
                #warning Need to implement currently
            }

            /* Process method and get out its IL's array */
            // @Newlabels:   New labels is the branches where we have to assign method
            //               a label for branch/call IL's operations to perform.
            //               we make its array while making the IL's array so its make our task easier
            List <int> NewLabels = new List <int>();
            var        OpCodes   = aMethod.Process(NewLabels);

            // Here seems to be going something wrong
            ILCompiler.Logger.Write("MSIL Codes Loaded... Count::" + OpCodes.Count);

            string xMethodLabel = aMethod.FullName();

            /* Method begin */
            Core.AssemblerCode.Add(new Label(xMethodLabel));

            TryToMakeGlobalSymbol(aMethod);

            Core.AssemblerCode.Add(new Comment(Worker.OPTIMIZATION_START_FLAG));
            if (aMethod.IsStatic && aMethod is ConstructorInfo)
            {
                string aData = "cctor_" + xMethodLabel;
                Core.InsertData(new AsmData(aData, new byte[] { 0x00 }));
                Core.AssemblerCode.Add(new Cmp()
                {
                    DestinationRef = aData, DestinationIndirect = true, SourceRef = "0x0", Size = 8
                });
                Core.AssemblerCode.Add(new Jmp()
                {
                    Condition = ConditionalJumpEnum.JE, DestinationRef = Label.PrimaryLabel + ".Load"
                });
                /* Footer of method */
                Core.AssemblerCode.Add(new Mov {
                    DestinationReg = Registers.ECX, SourceRef = "0x0"
                });
                Core.AssemblerCode.Add(new Ret());

                Core.AssemblerCode.Add(new Label(".Load"));
                Core.AssemblerCode.Add(new Mov()
                {
                    DestinationRef = aData, DestinationIndirect = true, SourceRef = "0x1", Size = 8
                });
            }
            /* Calli instructions */
            Core.AssemblerCode.Add(new Push()
            {
                DestinationReg = Registers.EBP
            });
            Core.AssemblerCode.Add(new Mov()
            {
                DestinationReg = Registers.EBP, SourceReg = Registers.ESP
            });

            /* Calculate Method Variables Size */
            int Size = (from item in xBody.LocalVariables
                        select item.LocalType.SizeOf().Align()).Sum();

            if (Size > 0)
            {
                // Make a space for local variables
                Core.AssemblerCode.Add(new Sub {
                    DestinationReg = Registers.ESP, SourceRef = "0x" + Size.Align().ToString("X")
                });
            }

            ILCompiler.Logger.Write("Listening OpCodes");

            /* Exceute IL Codes */
            foreach (var Op in OpCodes)
            {
                // Check if we need exception to push?
                var xNeedsExceptionPush = (Op.Ehc != null) && (((Op.Ehc.HandlerOffset > 0 && Op.Ehc.HandlerOffset == Op.Position) || ((Op.Ehc.Flags & ExceptionHandlingClauseOptions.Filter) > 0 && Op.Ehc.FilterOffset > 0 && Op.Ehc.FilterOffset == Op.Position)) && (Op.Ehc.Flags == ExceptionHandlingClauseOptions.Clause));

                ILCompiler.Logger.Write(Op.ToString() + "; Stack Count => " + Core.vStack.Count);
                // Check if current position inside the list of label list, if yes than break label and make a new one
                if (NewLabels.Contains(Op.Position))
                {
                    var xLbl = new Label(ILHelper.GetLabel(aMethod, Op.Position));
                    if (!Core.AssemblerCode.Contains(xLbl))
                    {
                        Core.AssemblerCode.Add(xLbl);
                    }
                }

                // If catch IL here than push current error so, that catch IL pop and do what it want
                if (xNeedsExceptionPush)
                {
                    Core.AssemblerCode.Add(new Push {
                        DestinationRef = "0x0"
                    });
                    Core.AssemblerCode.Add(new Call(Helper.lblGetException, true));
                    Core.vStack.Push(4, typeof(Exception));
                }

                // Well this is just to comment whole output Assembly
                if (!DoOptimization)
                {
                    Core.AssemblerCode.Add(new Comment(Op.ToString() + "; " + Core.vStack.Count));
                }

                // Check if this IL is in out implementation
                if (MSIL.ContainsKey(Op.Code))
                {
                    // If yes than execute it
                    MSIL[Op.Code].Execute(Op, aMethod);
                }
                else
                {
                    // If it is not implementation than throw error while compilation
                    throw new Exception(Op.ToString() + "; " + xMethodLabel);
                }
                #region Queue Inline calls
                if (Op is OpMethod)
                {
                    QueuedMember.Enqueue(((OpMethod)Op).Value);
                }
                else if (Op is OpType)
                {
                    QueuedMember.Enqueue(((OpType)Op).Value);
                }
                else if (Op is OpField)
                {
                    QueuedMember.Enqueue(((OpField)Op).Value.DeclaringType);
                    if (((OpField)Op).Value.IsStatic)
                    {
                        QueuedMember.Enqueue(((OpField)Op).Value);
                    }
                }
                else if (Op is OpToken)
                {
                    var x = ((OpToken)Op);
                    if (x.ValueIsType)
                    {
                        QueuedMember.Enqueue(x.ValueType);
                    }

                    if (x.ValueIsField)
                    {
                        QueuedMember.Enqueue(x.ValueField.DeclaringType);
                        if (x.ValueField.IsStatic)
                        {
                            QueuedMember.Enqueue(x.ValueField);
                        }
                    }
                }
                #endregion
            }
            // End the method and return method, without exception
            Core.AssemblerCode.Add(new Label(xMethodLabel + ".End"));
            // We assume that if the ecx is 0x0 then the method is done without any exception
            // it can be assumed by test instruction followed by conditional jump while calling a function
            Core.AssemblerCode.Add(new Mov {
                DestinationReg = Registers.ECX, SourceRef = "0x0"
            });

            Core.AssemblerCode.Add(new Label(xMethodLabel + ".Error"));
            // Now below code save the return value to EBP varaible
            // And calculate size
            int ArgSize = ILHelper.GetArgumentsSize(aMethod);

            int ReturnSize = ILHelper.GetReturnTypeSize(aMethod);
            if (ReturnSize > 0)
            {
                // For return type Method
                var xOffset = ILHelper.GetResultCodeOffset(ReturnSize, ArgSize);
                for (int i = 0; i < ReturnSize / 4; i++)
                {
                    Core.AssemblerCode.Add(new Pop {
                        DestinationReg = Registers.EAX
                    });
                    Core.AssemblerCode.Add(new Mov
                    {
                        DestinationReg          = Registers.EBP,
                        DestinationIndirect     = true,
                        DestinationDisplacement = (int)(xOffset + ((i + 0) * 4)),
                        SourceReg = Registers.EAX
                    });
                }
            }
            Core.AssemblerCode.Add(new Comment(Worker.OPTIMIAZTION_END_FLAG));

            byte RetSize = (byte)Math.Max(0, ILHelper.GetArgumentsSize(aMethod) - ILHelper.GetReturnTypeSize(aMethod));

            // Leave this method mean regain original EBP and ESP offset
            Core.AssemblerCode.Add(new Leave());
            // Return to parent method with given stack offset
            Core.AssemblerCode.Add(new Ret {
                Address = RetSize
            });

            // Add this method to build definations so we will not build it again
            BuildDefinations.Add(aMethod);

            // And log it
            ILCompiler.Logger.Write("Method Build Done()");
        }