Beispiel #1
0
    public bool WriteAsm(StreamWriter sw, MethodData md)
    {
        bool   ok   = true;
        string name = md.FullName;

        sw.WriteLine("; {0}", name);
        sw.WriteLine("{0}:", Util.MangleFunction(md));
        ArrayList list = new ArrayList();

        if (md.LocalVars != null || md.ParamCount > 0)
        {
            list.Add(new X86Code("push", "bp"));
            list.Add(new X86Code("mov", "bp", "sp"));
            if (md.LocalVars != null)
            {
                list.Add(new X86Code("sub", "sp", (md.LocalVars.Count * 2).ToString()));
            }
        }
        foreach (object obj in ConvertNative(md))
        {
            X86Codes codes = obj as X86Codes;
            if (codes == null)
            {
                ILCode il = obj as ILCode;
                codes = ConvertIL(md, il);
                if (codes == null)
                {
                    ok = false;
                    Console.WriteLine("ERROR PE_{0:X8}: {1} in {2}", il.Address, il.OpCode, md.FullName);
                    continue;
                }
            }
            codes.Output(list);
        }
        switch (this.optimize)
        {
        case 1:
            X86Code.Optimize(list);
            break;

        case 2:
            this.Optimize(list, md);
            break;
        }
        foreach (object obj in list)
        {
            X86Code x = obj as X86Code;
            x.Write(sw);
        }
        return(ok);
    }
Beispiel #2
0
    public void Output(ArrayList list)
    {
        bool first = true;

        foreach (object obj in this.Codes)
        {
            X86Code x = obj as X86Code;
            if (first)
            {
                x.Label      = string.Format("PE_{0:X8}", this.Address);
                x.IsBrTarget = this.IsBrTarget;
                if (this.Comment != "")
                {
                    x.Comment = this.Comment;
                }
                first = false;
            }
            list.Add(x);
        }
    }
Beispiel #3
0
    public static X86Code GetPrevious(ArrayList list, int pos, int count)
    {
        if (pos <= 0 || pos >= list.Count)
        {
            return(null);
        }

        for (int i = pos - 1; i >= 0; i--)
        {
            X86Code x = list[i] as X86Code;
            if (x != null && !x.ignore && (--count) < 1)
            {
                return(x);
            }
            if (x.IsBrTarget || x.Mnemonic == "call")
            {
                break;
            }
        }
        return(null);
    }
Beispiel #4
0
    public static void Optimize(ArrayList list)
    {
        for (int i = 1; i < list.Count; i++)
        {
            X86Code x0 = list[i] as X86Code;
            if (x0 == null || x0.ignore || x0.IsBrTarget)
            {
                continue;
            }

            ArrayList listx = new ArrayList();
            listx.Add(x0);
            for (int j = 1;; j++)
            {
                X86Code xx = GetPrevious(list, i, j);
                if (xx == null)
                {
                    break;
                }
                listx.Add(xx);
            }
            if (listx.Count < 2)
            {
                continue;
            }

            X86Code[] x = listx.ToArray(typeof(X86Code)) as X86Code[];
            if (IsMovEtc(x[0].Mnemonic) && !IsXS(x[0].Operand1) && IsXX(x[0].Operand2) && x[0].Operand1 != x[0].Operand2)
            {
                for (int j = 1; j < x.Length; j++)
                {
                    if (x[j].Mnemonic == "mov" && x[j].Operand1 == x[0].Operand2 && !IsXS(x[j].Operand2) &&
                        !(IsAddr(x[0].Operand1) && IsAddr(x[j].Operand2)))
                    {
                        if (x[0].Operand1 != x[j].Operand2 && (IsXX(x[0].Operand1) || IsXX(x[j].Operand2)))
                        {
                            x[j].Ignore();
                            x[0].Ignore();
                            X86Code xx = new X86Code(x[0].Mnemonic, x[0].Operand1, x[j].Operand2);
                            xx.Notes = "[optimize] add";
                            list.Insert(i + 1, xx);
                        }
                    }
                    else if (IsMovEtc(x[j].Mnemonic) && x[j].Operand1 != x[0].Operand2)
                    {
                        continue;
                    }
                    break;
                }
                if (x[0].ignore)
                {
                    continue;
                }
            }
            switch (x[0].Mnemonic)
            {
            case "pop":
            {
                Hashtable t = new Hashtable();
                for (int j = 1; j < x.Length; j++)
                {
                    if (x[j].Mnemonic == "push")
                    {
                        if (!t.Contains(x[j].Operand1))
                        {
                            if (x[j].Operand1 == x[0].Operand1)
                            {
                                x[j].Ignore();
                                x[0].Ignore();
                            }
                            else if (IsXX(x[j].Operand1) || IsXX(x[0].Operand1))
                            {
                                x[j].Ignore();
                                x[0].Ignore();
                                X86Code xx = new X86Code("mov", x[0].Operand1, x[j].Operand1);
                                xx.Notes = "[optimize] add";
                                list.Insert(i + 1, xx);
                            }
                        }
                        else if (!t.Contains(x[0].Operand1))
                        {
                            if (IsXX(x[j].Operand1) || IsXX(x[0].Operand1))
                            {
                                x[j].Ignore();
                                x[0].Ignore();
                                X86Code xx = new X86Code("mov", x[0].Operand1, x[j].Operand1);
                                xx.Notes = "[optimize] add";
                                i        = list.IndexOf(x[j]);
                                list.Insert(i + 1, xx);
                            }
                        }
                    }
                    else if (IsMovEtc(x[j].Mnemonic))
                    {
                        t[x[j].Operand1] = true;
                        continue;
                    }
                    break;
                }
                break;
            }

            case "cmp":
                if (IsXX(x[0].Operand1) && IsDigit(x[0].Operand2))
                {
                    for (int j = 1; j < x.Length; j++)
                    {
                        if (x[j].Mnemonic == "mov" && x[j].Operand1 == x[0].Operand1)
                        {
                            x[j].Ignore();
                            x[0].Ignore();
                            X86Code xx = new X86Code("cmp", x[j].Operand2, x[0].Operand2);
                            xx.Notes = "[optimize] add";
                            list.Insert(i + 1, xx);
                        }
                        else if (IsMovEtc(x[j].Mnemonic) && x[j].Operand1 != x[0].Operand1)
                        {
                            continue;
                        }
                        break;
                    }
                }
                break;

            case "je":
            case "jne":
            case "jz":
            case "jnz":
                if (x[1].Mnemonic == "cmp" && IsXX(x[1].Operand1) && !IsDigit(x[1].Operand2))
                {
                    for (int j = 2; j < x.Length; j++)
                    {
                        if (x[j].Mnemonic == "mov" && x[j].Operand1 == x[1].Operand1)
                        {
                            x[j].Ignore();
                            x[1].Ignore();
                            X86Code xx = new X86Code("cmp", x[1].Operand2, x[j].Operand2);
                            xx.Notes = "[optimize] add";
                            i        = list.IndexOf(x[1]);
                            list.Insert(i + 1, xx);
                        }
                        else if (IsMovEtc(x[j].Mnemonic) && x[j].Operand1 != x[1].Operand1)
                        {
                            continue;
                        }
                        break;
                    }
                }
                break;

            case "mov":
                if (x.Length > 2 && IsAddEtc(x[1].Mnemonic) && x[2].Mnemonic == "mov" &&
                    x[0].Operand2 == x[1].Operand1 && x[1].Operand1 == x[2].Operand1)
                {
                    if (x[1].Mnemonic == "inc" || x[1].Mnemonic == "dec")
                    {
                        x[2].Ignore();
                        x[1].Ignore();
                        x[0].Ignore();
                        X86Code xx = new X86Code(x[1].Mnemonic, x[0].Operand1);
                        xx.Notes = "[optimize] add";
                        list.Insert(i + 1, xx);
                    }
                    else if (x[0].Operand1 == x[1].Operand2 && !IsAddr(x[2].Operand2))
                    {
                        x[2].Ignore();
                        x[1].Ignore();
                        x[0].Ignore();
                        X86Code xx = new X86Code(x[1].Mnemonic, x[0].Operand1, x[2].Operand2);
                        xx.Notes = "[optimize] add";
                        list.Insert(i + 1, xx);
                    }
                    else if (x[0].Operand1 == x[2].Operand2 && !IsAddr(x[1].Operand2))
                    {
                        x[2].Ignore();
                        x[1].Ignore();
                        x[0].Ignore();
                        X86Code xx = new X86Code(x[1].Mnemonic, x[0].Operand1, x[1].Operand2);
                        xx.Notes = "[optimize] add";
                        list.Insert(i + 1, xx);
                    }
                }
                break;

            case "add":
                if (x[0].Operand2 == "1")
                {
                    x[0].Ignore();
                    X86Code xx = new X86Code("inc", x[0].Operand1);
                    xx.Notes = "[Optimize] add";
                    list.Insert(i + 1, xx);
                }
                break;

            case "sub":
                if (x[0].Operand2 == "1")
                {
                    x[0].Ignore();
                    X86Code xx = new X86Code("dec", x[0].Operand1);
                    xx.Notes = "[Optimize] add";
                    list.Insert(i + 1, xx);
                }
                break;
            }
        }

        StringCollection jmp = new StringCollection();

        for (int i = 0; i < list.Count; i++)
        {
            X86Code x = list[i] as X86Code;
            if (x == null || x.ignore)
            {
                continue;
            }

            if (x.Mnemonic == "mov" && X86Code.IsXX(x.Operand1) && x.Operand2 == "0")
            {
                x.Ignore();
                X86Code xx = new X86Code("xor", x.Operand1, x.Operand1);
                xx.Notes = "[optimize] add";
                list.Insert(i + 1, xx);
            }
            else if (x.Mnemonic == "mov" && x.Operand1 == x.Operand2)
            {
                x.Ignore();
            }
            else if (x.Mnemonic.StartsWith("j"))
            {
                jmp.Add(x.Operand1);
            }
        }
        for (int i = 0; i < list.Count; i++)
        {
            X86Code x = list[i] as X86Code;
            if (x == null)
            {
                continue;
            }

            if (x.IsBrTarget && !jmp.Contains(x.Label))
            {
                x.IsBrTarget = false;
            }
        }
    }
Beispiel #5
0
    public static void Optimize(ArrayList list)
    {
        for (int i = 1; i < list.Count; i++)
        {
            X86Code x0 = list[i] as X86Code;
            if (x0 == null || x0.ignore || x0.IsBrTarget) continue;

            ArrayList listx = new ArrayList();
            listx.Add(x0);
            for (int j = 1;; j++)
            {
                X86Code xx = GetPrevious(list, i, j);
                if (xx == null) break;
                listx.Add(xx);
            }
            if (listx.Count < 2) continue;

            X86Code[] x = listx.ToArray(typeof(X86Code)) as X86Code[];
            if (IsMovEtc(x[0].Mnemonic) && !IsXS(x[0].Operand1) && IsXX(x[0].Operand2) && x[0].Operand1 != x[0].Operand2)
            {
                for (int j = 1; j < x.Length; j++)
                {
                    if (x[j].Mnemonic == "mov" && x[j].Operand1 == x[0].Operand2 && !IsXS(x[j].Operand2)
                        && !(IsAddr(x[0].Operand1) && IsAddr(x[j].Operand2)))
                    {
                        if (x[0].Operand1 != x[j].Operand2 && (IsXX(x[0].Operand1) || IsXX(x[j].Operand2)))
                        {
                            x[j].Ignore();
                            x[0].Ignore();
                            X86Code xx = new X86Code(x[0].Mnemonic, x[0].Operand1, x[j].Operand2);
                            xx.Notes = "[optimize] add";
                            list.Insert(i + 1, xx);
                        }
                    }
                    else if (IsMovEtc(x[j].Mnemonic) && x[j].Operand1 != x[0].Operand2)
                    {
                        continue;
                    }
                    break;
                }
                if (x[0].ignore) continue;
            }
            switch (x[0].Mnemonic)
            {
                case "pop":
                {
                    Hashtable t = new Hashtable();
                    for (int j = 1; j < x.Length; j++)
                    {
                        if (x[j].Mnemonic == "push")
                        {
                            if (!t.Contains(x[j].Operand1))
                            {
                                if (x[j].Operand1 == x[0].Operand1)
                                {
                                    x[j].Ignore();
                                    x[0].Ignore();
                                }
                                else if (IsXX(x[j].Operand1) || IsXX(x[0].Operand1))
                                {
                                    x[j].Ignore();
                                    x[0].Ignore();
                                    X86Code xx = new X86Code("mov", x[0].Operand1, x[j].Operand1);
                                    xx.Notes = "[optimize] add";
                                    list.Insert(i + 1, xx);
                                }
                            }
                            else if (!t.Contains(x[0].Operand1))
                            {
                                if (IsXX(x[j].Operand1) || IsXX(x[0].Operand1))
                                {
                                    x[j].Ignore();
                                    x[0].Ignore();
                                    X86Code xx = new X86Code("mov", x[0].Operand1, x[j].Operand1);
                                    xx.Notes = "[optimize] add";
                                    i = list.IndexOf(x[j]);
                                    list.Insert(i + 1, xx);
                                }
                            }
                        }
                        else if (IsMovEtc(x[j].Mnemonic))
                        {
                            t[x[j].Operand1] = true;
                            continue;
                        }
                        break;
                    }
                    break;
                }
                case "cmp":
                    if (IsXX(x[0].Operand1) && IsDigit(x[0].Operand2))
                    {
                        for (int j = 1; j < x.Length; j++)
                        {
                            if (x[j].Mnemonic == "mov" && x[j].Operand1 == x[0].Operand1)
                            {
                                x[j].Ignore();
                                x[0].Ignore();
                                X86Code xx = new X86Code("cmp", x[j].Operand2, x[0].Operand2);
                                xx.Notes = "[optimize] add";
                                list.Insert(i + 1, xx);
                            }
                            else if (IsMovEtc(x[j].Mnemonic) && x[j].Operand1 != x[0].Operand1)
                            {
                                continue;
                            }
                            break;
                        }
                    }
                    break;
                case "je":
                case "jne":
                case "jz":
                case "jnz":
                    if (x[1].Mnemonic == "cmp" && IsXX(x[1].Operand1) && !IsDigit(x[1].Operand2))
                    {
                        for (int j = 2; j < x.Length; j++)
                        {
                            if (x[j].Mnemonic == "mov" && x[j].Operand1 == x[1].Operand1)
                            {
                                x[j].Ignore();
                                x[1].Ignore();
                                X86Code xx = new X86Code("cmp", x[1].Operand2, x[j].Operand2);
                                xx.Notes = "[optimize] add";
                                i = list.IndexOf(x[1]);
                                list.Insert(i + 1, xx);
                            }
                            else if (IsMovEtc(x[j].Mnemonic) && x[j].Operand1 != x[1].Operand1)
                            {
                                continue;
                            }
                            break;
                        }
                    }
                    break;
                case "mov":
                    if (x.Length > 2 && IsAddEtc(x[1].Mnemonic) && x[2].Mnemonic == "mov"
                        && x[0].Operand2 == x[1].Operand1 && x[1].Operand1 == x[2].Operand1)
                    {
                        if (x[1].Mnemonic == "inc" || x[1].Mnemonic == "dec")
                        {
                            x[2].Ignore();
                            x[1].Ignore();
                            x[0].Ignore();
                            X86Code xx = new X86Code(x[1].Mnemonic, x[0].Operand1);
                            xx.Notes = "[optimize] add";
                            list.Insert(i + 1, xx);
                        }
                        else if (x[0].Operand1 == x[1].Operand2 && !IsAddr(x[2].Operand2))
                        {
                            x[2].Ignore();
                            x[1].Ignore();
                            x[0].Ignore();
                            X86Code xx = new X86Code(x[1].Mnemonic, x[0].Operand1, x[2].Operand2);
                            xx.Notes = "[optimize] add";
                            list.Insert(i + 1, xx);
                        }
                        else if (x[0].Operand1 == x[2].Operand2 && !IsAddr(x[1].Operand2))
                        {
                            x[2].Ignore();
                            x[1].Ignore();
                            x[0].Ignore();
                            X86Code xx = new X86Code(x[1].Mnemonic, x[0].Operand1, x[1].Operand2);
                            xx.Notes = "[optimize] add";
                            list.Insert(i + 1, xx);
                        }
                    }
                    break;
                case "add":
                    if (x[0].Operand2 == "1")
                    {
                        x[0].Ignore();
                        X86Code xx = new X86Code("inc", x[0].Operand1);
                        xx.Notes = "[Optimize] add";
                        list.Insert(i + 1, xx);
                    }
                    break;
                case "sub":
                    if (x[0].Operand2 == "1")
                    {
                        x[0].Ignore();
                        X86Code xx = new X86Code("dec", x[0].Operand1);
                        xx.Notes = "[Optimize] add";
                        list.Insert(i + 1, xx);
                    }
                    break;
            }
        }

        StringCollection jmp = new StringCollection();
        for (int i = 0; i < list.Count; i++)
        {
            X86Code x = list[i] as X86Code;
            if (x == null || x.ignore) continue;

            if (x.Mnemonic == "mov" && X86Code.IsXX(x.Operand1) && x.Operand2 == "0")
            {
                x.Ignore();
                X86Code xx = new X86Code("xor", x.Operand1, x.Operand1);
                xx.Notes = "[optimize] add";
                list.Insert(i + 1, xx);
            }
            else if (x.Mnemonic == "mov" && x.Operand1 == x.Operand2)
            {
                x.Ignore();
            }
            else if (x.Mnemonic.StartsWith("j"))
            {
                jmp.Add(x.Operand1);
            }
        }
        for (int i = 0; i < list.Count; i++)
        {
            X86Code x = list[i] as X86Code;
            if (x == null) continue;

            if (x.IsBrTarget && !jmp.Contains(x.Label)) x.IsBrTarget = false;
        }
    }
Beispiel #6
0
    public void Optimize(ArrayList list, MethodData md)
    {
        X86Code.Optimize(list);

        bool bx = true;
        Hashtable locals = new Hashtable();
        int max = 0;
        string target = null;
        for (int i = 0; i < list.Count; i++)
        {
            X86Code x = list[i] as X86Code;
            if (x == null || x.ignore) continue;

            if (x.Mnemonic == "int" || x.Operand1 == "bx") bx = false;
            int p1a = x.Operand1.IndexOf("[ss:bp-"), p1b = x.Operand1.LastIndexOf(']');
            if (0 <= p1a && p1a < p1b)
            {
                string var = x.Operand1.Substring(p1a + 1, p1b - p1a - 1);
                int v = !locals.Contains(var) ? 1 : ((int)locals[var]) + 1;
                locals[var] = v;
                if (max < v)
                {
                    max = v;
                    target = var;
                }
            }
            int p2a = x.Operand2.IndexOf("[ss:bp-"), p2b = x.Operand2.LastIndexOf(']');
            if (0 <= p2a && p2a < p2b)
            {
                string var = x.Operand2.Substring(p2a + 1, p2b - p2a - 1);
                int v = !locals.Contains(var) ? 1 : ((int)locals[var]) + 1;
                locals[var] = v;
                if (max < v)
                {
                    max = v;
                    target = var;
                }
            }
        }
        if (bx && target != null)
        {
            for (int i = 0; i < list.Count; i++)
            {
                X86Code x = list[i] as X86Code;
                if (x == null || x.ignore) continue;

                string op1 = x.Operand1, op2 = x.Operand2;
                int p1 = op1.IndexOf(target), p2 = op2.IndexOf(target);
                if (p1 >= 0) op1 = "bx";
                if (p2 >= 0) op2 = "bx";
                if (p1 < 0 && p2 < 0) continue;

                x.Ignore();
                X86Code xx = new X86Code(x.Mnemonic, op1, op2);
                xx.Notes = "[optimize] add";
                list.Insert(i + 1, xx);
            }
            if (md.LocalVars != null && md.LocalVars.Count == 1 && target.StartsWith("ss:bp-"))
            {
                for (int i = 0; i < list.Count; i++)
                {
                    X86Code x = list[i] as X86Code;
                    if (x == null || x.ignore) continue;

                    if (x.Mnemonic == "sub" && x.Operand1 == "sp")
                    {
                        x.Ignore();
                        break;
                    }
                }
                for (int i = list.Count - 1; i >= 0; i--)
                {
                    X86Code x = list[i] as X86Code;
                    if (x == null || x.ignore) continue;

                    if (x.Mnemonic == "mov" && x.Operand1 == "sp")
                    {
                        x.Ignore();
                        break;
                    }
                }
            }
        }
        X86Code.Optimize(list);
        if (md.LocalVars != null || md.ParamCount > 0 || !bx)
        {
            X86Code xb1 = new X86Code("push", "bx"), xb2 = new X86Code("pop", "bx");
            xb1.Notes = xb2.Notes = "[optimize] add";
            list.Insert(0, xb1);
            for (int i = 0; i < list.Count; i++)
            {
                X86Code x = list[i] as X86Code;
                if (x == null || x.ignore) continue;

                if (x.Mnemonic == "ret")
                {
                    list.Insert(i, xb2);
                    i++;
                }
            }
        }
    }
Beispiel #7
0
    public X86Codes ConvertIL(MethodData md, ILCode il)
    {
        string mne = il.OpCode.Name;
        if (mne == null) return null;

        X86Codes ret = new X86Codes();
        ret.Address = il.Address;
        ret.IsBrTarget = il.IsBrTarget;
        if (il.Operand is byte)
        {
            ret.Comment = string.Format("{0} {1:X2}", mne, il.Operand);
        }
        else if (il.Operand is short)
        {
            ret.Comment = string.Format("{0} {1:X4}", mne, il.Operand);
        }
        else if (il.Operand is int)
        {
            ret.Comment = string.Format("{0} {1:X8}", mne, il.Operand);
        }
        else
        {
            ret.Comment = mne;
        }

        int mne_last = mne.Length < 1 ? 0 : (int)(mne[mne.Length - 1] - '0');
        int nOp = Util.GetOperandValue(il);
        switch (mne)
        {
            case "ldc.i4":
            case "ldc.i4.s":
            case "ldc.i4.0":
            case "ldc.i4.1":
            case "ldc.i4.2":
            case "ldc.i4.3":
            case "ldc.i4.4":
            case "ldc.i4.5":
            case "ldc.i4.6":
            case "ldc.i4.7":
            case "ldc.i4.8":
                ret.Codes.Add(new X86Code("mov", "ax", nOp.ToString()));
                ret.Codes.Add(new X86Code("push", "ax"));
                break;
            case "ldloc":
            case "ldloc.s":
            case "ldloc.0":
            case "ldloc.1":
            case "ldloc.2":
            case "ldloc.3":
                ret.Codes.Add(new X86Code("push", string.Format("word [ss:bp-{0}]", (nOp + 1) * 2)));
                break;
            case "ldloca":
            case "ldloca.s":
                ret.Codes.Add(new X86Code("mov", "ax", "bp"));
                ret.Codes.Add(new X86Code("sub", string.Format("ax, {0}", (nOp + 1) * 2)));
                ret.Codes.Add(new X86Code("push", "ax"));
                break;
            case "stloc":
            case "stloc.s":
            case "stloc.0":
            case "stloc.1":
            case "stloc.2":
            case "stloc.3":
                ret.Codes.Add(new X86Code("pop", string.Format("word [ss:bp-{0}]", (nOp + 1) * 2)));
                break;
            case "ldarg":
            case "ldarg.s":
            case "ldarg.0":
            case "ldarg.1":
            case "ldarg.2":
            case "ldarg.3":
                ret.Codes.Add(new X86Code("push", string.Format("word [ss:bp+{0}]", Util.GetArgPos(md, nOp, this.optimize))));
                break;
            case "starg":
            case "starg.s":
                ret.Codes.Add(new X86Code("pop", string.Format("word [ss:bp+{0}]", Util.GetArgPos(md, nOp, this.optimize))));
                break;
            case "ldstr":
            {
                int us = ((int)il.Operand) & 0xffffff;
                if (!this.listUS.Contains(us)) this.listUS.Add(us);
                ret.Codes.Add(new X86Code("mov", "ax", string.Format("US_{0:X8}", us)));
                ret.Codes.Add(new X86Code("push", "ax"));
                break;
            }
            case "ldsfld":
            {
                TableBase tb = this.pedata.idxm.GetTable((int)il.Operand);
                ret.Codes.Add(new X86Code("push", string.Format("word [cs:{0}]", MangleField(tb as FieldTable))));
                break;
            }
            case "stsfld":
            {
                TableBase tb = this.pedata.idxm.GetTable((int)il.Operand);
                ret.Codes.Add(new X86Code("pop", string.Format("word [cs:{0}]", MangleField(tb as FieldTable))));
                break;
            }
            case "pop":
                ret.Codes.Add(new X86Code("pop", "ax"));
                break;
            case "br":
            case "br.s":
                ret.Codes.Add(new X86Code("jmp", string.Format("PE_{0:X8}", Girl.PEAnalyzer.Util.GetBrTarget(il))));
                if (this.optimize > 0 && nOp == 0) ret.Ignore();
                break;
            case "beq":
            case "beq.s":
                ret.Codes.Add(new X86Code("pop", "ax"));
                ret.Codes.Add(new X86Code("pop", "dx"));
                ret.Codes.Add(new X86Code("cmp", "ax", "dx"));
                ret.Codes.Add(new X86Code("je", string.Format("PE_{0:X8}", Girl.PEAnalyzer.Util.GetBrTarget(il))));
                if (this.optimize > 0 && nOp == 0) ret.Ignore();
                break;
            case "bne.un":
            case "bne.un.s":
                ret.Codes.Add(new X86Code("pop", "ax"));
                ret.Codes.Add(new X86Code("pop", "dx"));
                ret.Codes.Add(new X86Code("cmp", "ax", "dx"));
                ret.Codes.Add(new X86Code("jne", string.Format("PE_{0:X8}", Girl.PEAnalyzer.Util.GetBrTarget(il))));
                if (this.optimize > 0 && nOp == 0) ret.Ignore();
                break;
            case "bgt":
            case "bgt.s":
                ret.Codes.Add(new X86Code("pop", "ax"));
                ret.Codes.Add(new X86Code("pop", "dx"));
                ret.Codes.Add(new X86Code("cmp", "ax", "dx"));
                ret.Codes.Add(new X86Code("jc", string.Format("PE_{0:X8}", Girl.PEAnalyzer.Util.GetBrTarget(il))));
                if (this.optimize > 0 && nOp == 0) ret.Ignore();
                break;
            case "blt":
            case "blt.s":
                ret.Codes.Add(new X86Code("pop", "ax"));
                ret.Codes.Add(new X86Code("pop", "dx"));
                ret.Codes.Add(new X86Code("cmp", "dx", "ax"));
                ret.Codes.Add(new X86Code("jc", string.Format("PE_{0:X8}", Girl.PEAnalyzer.Util.GetBrTarget(il))));
                if (this.optimize > 0 && nOp == 0) ret.Ignore();
                break;
            case "ble":
            case "ble.s":
                ret.Codes.Add(new X86Code("pop", "ax"));
                ret.Codes.Add(new X86Code("pop", "dx"));
                ret.Codes.Add(new X86Code("cmp", "ax", "dx"));
                ret.Codes.Add(new X86Code("jnc near", string.Format("PE_{0:X8}", Girl.PEAnalyzer.Util.GetBrTarget(il))));
                if (this.optimize > 0 && nOp == 0) ret.Ignore();
                break;
            case "bge":
            case "bge.s":
                ret.Codes.Add(new X86Code("pop", "ax"));
                ret.Codes.Add(new X86Code("pop", "dx"));
                ret.Codes.Add(new X86Code("cmp", "dx", "ax"));
                ret.Codes.Add(new X86Code("jnc", string.Format("PE_{0:X8}", Girl.PEAnalyzer.Util.GetBrTarget(il))));
                if (this.optimize > 0 && nOp == 0) ret.Ignore();
                break;
            case "brfalse":
            case "brfalse.s":
                ret.Codes.Add(new X86Code("pop", "ax"));
                ret.Codes.Add(new X86Code("or", "ax", "ax"));
                ret.Codes.Add(new X86Code("jz", string.Format("PE_{0:X8}", Girl.PEAnalyzer.Util.GetBrTarget(il))));
                if (this.optimize > 0 && nOp == 0) ret.Ignore();
                break;
            case "brtrue":
            case "brtrue.s":
                ret.Codes.Add(new X86Code("pop", "ax"));
                ret.Codes.Add(new X86Code("or", "ax", "ax"));
                ret.Codes.Add(new X86Code("jnz", string.Format("PE_{0:X8}", Girl.PEAnalyzer.Util.GetBrTarget(il))));
                if (this.optimize > 0 && nOp == 0) ret.Ignore();
                break;
            case "call":
            {
                TableBase tb = this.pedata.idxm.GetTable((int)il.Operand);
                MethodData tb_md = tb.Tag as MethodData;
                ret.Codes.Add(new X86Code("call", string.Format("{0}", Util.MangleFunction(tb_md))));
                if (tb_md.RetType.Element != ELEMENT_TYPE.VOID) ret.Codes.Add(new X86Code("push", "ax"));
                break;
            }
            //case "callvirt":
            //{
            //	TableBase tb = this.pedata.idxm.GetTable((int)il.Operand);
            //	MethodData tb_md = tb.Tag as MethodData;
            //	string func = Util.MangleFunction(tb_md);
            //	if (func.StartsWith("instance__")) func = func.Substring(10, func.Length - 10);
            //	sw.WriteLine("\tcall _virtual__{0}", func);
            //	if (tb_md.RetType.Element != ELEMENT_TYPE.VOID) sw.WriteLine("\tpush ax");
            //	break;
            //}
            case "ret":
                if (this.optimize == 0 || il == this.lastRet)
                {
                    if (md.RetType.Element != ELEMENT_TYPE.VOID)
                    {
                        ret.Codes.Add(new X86Code("pop", "ax"));
                    }
                    if (md.LocalVars != null || md.ParamCount > 0)
                    {
                        if (md.LocalVars != null) ret.Codes.Add(new X86Code("mov", "sp", "bp"));
                        ret.Codes.Add(new X86Code("pop", "bp"));
                    }
                    int st = Util.GetStackSize(md);
                    if (st == 0)
                    {
                        ret.Codes.Add(new X86Code("ret"));
                    }
                    else
                    {
                        ret.Codes.Add(new X86Code("ret", st.ToString()));
                    }
                }
                else
                {
                    X86Code x = new X86Code("jmp", string.Format("PE_{0:X8}", this.lastRet.Address));
                    x.Notes = "[optimize] modify";
                    ret.Codes.Add(x);
                    this.lastRet.IsBrTarget = true;
                }
                break;
            case "ceq":
                ret.Codes.Add(new X86Code("pop", "ax"));
                ret.Codes.Add(new X86Code("pop", "dx"));
                ret.Codes.Add(new X86Code("cmp", "ax", "dx"));
                ret.Codes.Add(new X86Code("je", string.Format("NM_{0:X8}", this.number)));
                ret.Codes.Add(new X86Code("xor", "ax", "ax"));
                ret.Codes.Add(new X86Code("jmp", string.Format("NM_{0:X8}", this.number + 1)));
                ret.Codes.Add(new X86Code(string.Format("NM_{0:X8}", this.number), true, "ceq internal", "mov", "ax", "1"));
                ret.Codes.Add(new X86Code(string.Format("NM_{0:X8}", this.number + 1), true, "ceq internal", "push", "ax"));
                this.number += 2;
                break;
            case "add":
            case "and":
            case "or":
                ret.Codes.Add(new X86Code("pop", "ax"));
                ret.Codes.Add(new X86Code("pop", "dx"));
                ret.Codes.Add(new X86Code(mne, "ax", "dx"));
                ret.Codes.Add(new X86Code("push", "ax"));
                break;
            case "sub":
                ret.Codes.Add(new X86Code("pop", "dx"));
                ret.Codes.Add(new X86Code("pop", "ax"));
                ret.Codes.Add(new X86Code("sub", "ax", "dx"));
                ret.Codes.Add(new X86Code("push", "ax"));
                break;
            case "mul":
                ret.Codes.Add(new X86Code("pop", "ax"));
                ret.Codes.Add(new X86Code("pop", "dx"));
                ret.Codes.Add(new X86Code("mul", "dx"));
                ret.Codes.Add(new X86Code("push", "ax"));
                break;
            case "div":
                ret.Codes.Add(new X86Code("pop", "cx"));
                ret.Codes.Add(new X86Code("pop", "ax"));
                ret.Codes.Add(new X86Code("xor", "dx", "dx"));
                ret.Codes.Add(new X86Code("div", "cx"));
                ret.Codes.Add(new X86Code("push", "ax"));
                break;
            case "rem":
                ret.Codes.Add(new X86Code("pop", "cx"));
                ret.Codes.Add(new X86Code("pop", "ax"));
                ret.Codes.Add(new X86Code("xor", "dx", "dx"));
                ret.Codes.Add(new X86Code("div", "cx"));
                ret.Codes.Add(new X86Code("push", "dx"));
                break;
            case "neg":
                ret.Codes.Add(new X86Code("pop", "ax"));
                ret.Codes.Add(new X86Code("neg", "ax"));
                ret.Codes.Add(new X86Code("push", "ax"));
                break;
            case "shr":
            case "shl":
                ret.Codes.Add(new X86Code("pop", "cx"));
                ret.Codes.Add(new X86Code("pop", "ax"));
                ret.Codes.Add(new X86Code(mne, "ax", "cl"));
                ret.Codes.Add(new X86Code("push", "ax"));
                break;
            case "conv.u1":
                ret.Codes.Add(new X86Code("pop", "ax"));
                ret.Codes.Add(new X86Code("mov", "ah", "0"));
                ret.Codes.Add(new X86Code("push", "ax"));
                break;
            case "conv.i2":
            case "conv.u2":
            case "conv.i4":
            case "conv.u4":
                // ignore in 16bit
                return ret;
            //case "box":
            //{
            //	TypeRefTable t = this.pedata.idxm.GetTable((int)il.Operand) as TypeRefTable;
            //	sw.WriteLine("\tcall _box__{0}@4", GetTypeName(this.pedata.idxm.GetName(t)));
            //	sw.WriteLine("\tpush ax");
            //	break;
            //}
        }
        if (ret.Codes.Count < 1) return null;
        return ret;
    }
Beispiel #8
0
    public object[] ConvertNative(MethodData md)
    {
        Stack st1 = new Stack();

        foreach (ILCode il in md.ILCodes)
        {
            st1.Push(il);
        }

        this.lastRet = null;
        Stack st2 = new Stack();

        while (st1.Count > 0)
        {
            ILCode il = st1.Pop() as ILCode;
            if (il.OpCode.Name == "ret" && this.lastRet == null)
            {
                this.lastRet = il;
            }
            else if (il.OpCode.Name == "pop" && st1.Count > 0)
            {
                ILCode il2 = st1.Peek() as ILCode;
                if (il2.OpCode.Name == "newobj")
                {
                    TableBase  tb    = this.pedata.idxm.GetTable((int)il2.Operand);
                    MethodData tb_md = tb.Tag as MethodData;
                    if (tb_md.Name == "[I8086]I8086.Inline::.ctor" && st1.Count > 1)
                    {
                        st1.Pop();
                        ILCode il3 = st1.Peek() as ILCode;
                        if (il3 != null && il3.OpCode.Name == "ldstr")
                        {
                            st1.Pop();
                            X86Codes nc = new X86Codes();
                            nc.Address    = il3.Address;
                            nc.IsBrTarget = il3.IsBrTarget;
                            nc.Comment    = "[native] inline";
                            nc.Codes.Add(X86Code.Parse(this.hashUS[((int)il3.Operand) & 0xffffff] as string));
                            st2.Push(nc);
                            continue;
                        }
                        st1.Push(il2);
                    }
                }
            }
            if (il.OpCode.Name == "call")
            {
                TableBase  tb    = this.pedata.idxm.GetTable((int)il.Operand);
                MethodData tb_md = tb.Tag as MethodData;
                string     name  = tb_md.Name;
                if (name.StartsWith("[I8086]I8086.Registers::set_"))
                {
                    string reg = name.Substring(name.Length - 2, 2).ToLower();
                    if (st1.Count > 0 && !name.EndsWith("S"))
                    {
                        ILCode il2 = st1.Peek() as ILCode;
                        string mne = il2.OpCode.Name;
                        int    nOp = Util.GetOperandValue(il2);
                        if (mne.StartsWith("ldc.i4"))
                        {
                            st1.Pop();
                            X86Codes nc = new X86Codes();
                            nc.Address    = il2.Address;
                            nc.IsBrTarget = il2.IsBrTarget;
                            nc.Comment    = "[native] set register";
                            nc.Codes.Add(new X86Code("mov", reg, nOp.ToString()));
                            st2.Push(nc);
                            continue;
                        }
                        else if (mne.StartsWith("ldloc"))
                        {
                            st1.Pop();
                            X86Codes nc = new X86Codes();
                            nc.Address    = il2.Address;
                            nc.IsBrTarget = il2.IsBrTarget;
                            nc.Comment    = "[native] set register";
                            nc.Codes.Add(new X86Code("mov", reg, string.Format("[ss:bp-{0}]", (nOp + 1) * 2)));
                            st2.Push(nc);
                            continue;
                        }
                        else if (mne.StartsWith("ldarg"))
                        {
                            st1.Pop();
                            X86Codes nc = new X86Codes();
                            nc.Address    = il2.Address;
                            nc.IsBrTarget = il2.IsBrTarget;
                            nc.Comment    = "[native] set register";
                            nc.Codes.Add(new X86Code("mov", reg, string.Format("[ss:bp+{0}]", Util.GetArgPos(md, nOp, this.optimize))));
                            st2.Push(nc);
                            continue;
                        }
                    }
                    if (name.EndsWith("X") || name.EndsWith("I") || name.EndsWith("S"))
                    {
                        X86Codes nc = new X86Codes();
                        nc.Address    = il.Address;
                        nc.IsBrTarget = il.IsBrTarget;
                        nc.Comment    = "[native] set register";
                        nc.Codes.Add(new X86Code("pop", reg));
                        st2.Push(nc);
                        continue;
                    }
                }
                else if (name.StartsWith("[I8086]I8086.Registers::get_"))
                {
                    X86Codes nc = new X86Codes();
                    nc.Address    = il.Address;
                    nc.IsBrTarget = il.IsBrTarget;
                    nc.Comment    = "[native] get register";
                    nc.Codes.Add(new X86Code("push", name.Substring(name.Length - 2, 2).ToLower()));
                    st2.Push(nc);
                    continue;
                }
                else if (name == "[I8086]I8086.IO::In" && st1.Count > 0)
                {
                    ILCode   il2 = st1.Peek() as ILCode;
                    string   mne = il2.OpCode.Name;
                    int      nOp = Util.GetOperandValue(il2);
                    X86Codes nc  = new X86Codes();
                    nc.Comment = "[native] in";
                    if (mne.StartsWith("ldc.i4"))
                    {
                        st1.Pop();
                        nc.Address    = il2.Address;
                        nc.IsBrTarget = il2.IsBrTarget;
                        nc.Codes.Add(new X86Code("in", "al", nOp.ToString()));
                    }
                    else
                    {
                        nc.Address    = il.Address;
                        nc.IsBrTarget = il.IsBrTarget;
                        nc.Codes.Add(new X86Code("pop", "dx"));
                        nc.Codes.Add(new X86Code("in", "al", "dx"));
                    }
                    nc.Codes.Add(new X86Code("mov", "ah", "0"));
                    nc.Codes.Add(new X86Code("push", "ax"));
                    st2.Push(nc);
                    continue;
                }
                else if (name == "[I8086]I8086.IO::Out")
                {
                    X86Codes nc = new X86Codes();
                    nc.Address    = il.Address;
                    nc.IsBrTarget = il.IsBrTarget;
                    nc.Comment    = "[native] out";
                    nc.Codes.Add(new X86Code("pop", "ax"));
                    nc.Codes.Add(new X86Code("pop", "dx"));
                    nc.Codes.Add(new X86Code("out", "dx", "al"));
                    st2.Push(nc);
                    continue;
                }
                else if (name == "[I8086]I8086.StringPtr::Get")
                {
                    continue;
                }
                else if (name.StartsWith("[I8086]I8086.Flags::get_"))
                {
                    string mne = "jz";
                    int    p   = name.IndexOf('_') + 1;
                    switch (name.Substring(p, name.Length - p))
                    {
                    case "NZ":
                    case "NE":
                        mne = "jnz";
                        break;

                    case "C":
                        mne = "jc";
                        break;

                    case "NC":
                        mne = "jnc";
                        break;
                    }
                    X86Codes nc = new X86Codes();
                    nc.Address    = il.Address;
                    nc.IsBrTarget = il.IsBrTarget;
                    nc.Comment    = "[native] get flag";
                    nc.Codes.Add(new X86Code(mne, string.Format("NM_{0:X8}", this.number)));
                    nc.Codes.Add(new X86Code("xor", "ax", "ax"));
                    nc.Codes.Add(new X86Code("jmp", string.Format("NM_{0:X8}", this.number + 1)));
                    nc.Codes.Add(new X86Code(string.Format("NM_{0:X8}", this.number), true, "[native] get flag internal", "mov", "ax", "1"));
                    nc.Codes.Add(new X86Code(string.Format("NM_{0:X8}", this.number + 1), true, "[native] get flag internal", "push", "ax"));
                    st2.Push(nc);
                    this.number += 2;
                    continue;
                }
            }
            st2.Push(il);
        }
        return(st2.ToArray());
    }
Beispiel #9
0
    public X86Codes ConvertIL(MethodData md, ILCode il)
    {
        string mne = il.OpCode.Name;

        if (mne == null)
        {
            return(null);
        }

        X86Codes ret = new X86Codes();

        ret.Address    = il.Address;
        ret.IsBrTarget = il.IsBrTarget;
        if (il.Operand is byte)
        {
            ret.Comment = string.Format("{0} {1:X2}", mne, il.Operand);
        }
        else if (il.Operand is short)
        {
            ret.Comment = string.Format("{0} {1:X4}", mne, il.Operand);
        }
        else if (il.Operand is int)
        {
            ret.Comment = string.Format("{0} {1:X8}", mne, il.Operand);
        }
        else
        {
            ret.Comment = mne;
        }

        int mne_last = mne.Length < 1 ? 0 : (int)(mne[mne.Length - 1] - '0');
        int nOp      = Util.GetOperandValue(il);

        switch (mne)
        {
        case "ldc.i4":
        case "ldc.i4.s":
        case "ldc.i4.0":
        case "ldc.i4.1":
        case "ldc.i4.2":
        case "ldc.i4.3":
        case "ldc.i4.4":
        case "ldc.i4.5":
        case "ldc.i4.6":
        case "ldc.i4.7":
        case "ldc.i4.8":
            ret.Codes.Add(new X86Code("mov", "ax", nOp.ToString()));
            ret.Codes.Add(new X86Code("push", "ax"));
            break;

        case "ldloc":
        case "ldloc.s":
        case "ldloc.0":
        case "ldloc.1":
        case "ldloc.2":
        case "ldloc.3":
            ret.Codes.Add(new X86Code("push", string.Format("word [ss:bp-{0}]", (nOp + 1) * 2)));
            break;

        case "ldloca":
        case "ldloca.s":
            ret.Codes.Add(new X86Code("mov", "ax", "bp"));
            ret.Codes.Add(new X86Code("sub", string.Format("ax, {0}", (nOp + 1) * 2)));
            ret.Codes.Add(new X86Code("push", "ax"));
            break;

        case "stloc":
        case "stloc.s":
        case "stloc.0":
        case "stloc.1":
        case "stloc.2":
        case "stloc.3":
            ret.Codes.Add(new X86Code("pop", string.Format("word [ss:bp-{0}]", (nOp + 1) * 2)));
            break;

        case "ldarg":
        case "ldarg.s":
        case "ldarg.0":
        case "ldarg.1":
        case "ldarg.2":
        case "ldarg.3":
            ret.Codes.Add(new X86Code("push", string.Format("word [ss:bp+{0}]", Util.GetArgPos(md, nOp, this.optimize))));
            break;

        case "starg":
        case "starg.s":
            ret.Codes.Add(new X86Code("pop", string.Format("word [ss:bp+{0}]", Util.GetArgPos(md, nOp, this.optimize))));
            break;

        case "ldstr":
        {
            int us = ((int)il.Operand) & 0xffffff;
            if (!this.listUS.Contains(us))
            {
                this.listUS.Add(us);
            }
            ret.Codes.Add(new X86Code("mov", "ax", string.Format("US_{0:X8}", us)));
            ret.Codes.Add(new X86Code("push", "ax"));
            break;
        }

        case "ldsfld":
        {
            TableBase tb = this.pedata.idxm.GetTable((int)il.Operand);
            ret.Codes.Add(new X86Code("push", string.Format("word [cs:{0}]", MangleField(tb as FieldTable))));
            break;
        }

        case "stsfld":
        {
            TableBase tb = this.pedata.idxm.GetTable((int)il.Operand);
            ret.Codes.Add(new X86Code("pop", string.Format("word [cs:{0}]", MangleField(tb as FieldTable))));
            break;
        }

        case "pop":
            ret.Codes.Add(new X86Code("pop", "ax"));
            break;

        case "br":
        case "br.s":
            ret.Codes.Add(new X86Code("jmp", string.Format("PE_{0:X8}", Girl.PEAnalyzer.Util.GetBrTarget(il))));
            if (this.optimize > 0 && nOp == 0)
            {
                ret.Ignore();
            }
            break;

        case "beq":
        case "beq.s":
            ret.Codes.Add(new X86Code("pop", "ax"));
            ret.Codes.Add(new X86Code("pop", "dx"));
            ret.Codes.Add(new X86Code("cmp", "ax", "dx"));
            ret.Codes.Add(new X86Code("je", string.Format("PE_{0:X8}", Girl.PEAnalyzer.Util.GetBrTarget(il))));
            if (this.optimize > 0 && nOp == 0)
            {
                ret.Ignore();
            }
            break;

        case "bne.un":
        case "bne.un.s":
            ret.Codes.Add(new X86Code("pop", "ax"));
            ret.Codes.Add(new X86Code("pop", "dx"));
            ret.Codes.Add(new X86Code("cmp", "ax", "dx"));
            ret.Codes.Add(new X86Code("jne", string.Format("PE_{0:X8}", Girl.PEAnalyzer.Util.GetBrTarget(il))));
            if (this.optimize > 0 && nOp == 0)
            {
                ret.Ignore();
            }
            break;

        case "bgt":
        case "bgt.s":
            ret.Codes.Add(new X86Code("pop", "ax"));
            ret.Codes.Add(new X86Code("pop", "dx"));
            ret.Codes.Add(new X86Code("cmp", "ax", "dx"));
            ret.Codes.Add(new X86Code("jc", string.Format("PE_{0:X8}", Girl.PEAnalyzer.Util.GetBrTarget(il))));
            if (this.optimize > 0 && nOp == 0)
            {
                ret.Ignore();
            }
            break;

        case "blt":
        case "blt.s":
            ret.Codes.Add(new X86Code("pop", "ax"));
            ret.Codes.Add(new X86Code("pop", "dx"));
            ret.Codes.Add(new X86Code("cmp", "dx", "ax"));
            ret.Codes.Add(new X86Code("jc", string.Format("PE_{0:X8}", Girl.PEAnalyzer.Util.GetBrTarget(il))));
            if (this.optimize > 0 && nOp == 0)
            {
                ret.Ignore();
            }
            break;

        case "ble":
        case "ble.s":
            ret.Codes.Add(new X86Code("pop", "ax"));
            ret.Codes.Add(new X86Code("pop", "dx"));
            ret.Codes.Add(new X86Code("cmp", "ax", "dx"));
            ret.Codes.Add(new X86Code("jnc near", string.Format("PE_{0:X8}", Girl.PEAnalyzer.Util.GetBrTarget(il))));
            if (this.optimize > 0 && nOp == 0)
            {
                ret.Ignore();
            }
            break;

        case "bge":
        case "bge.s":
            ret.Codes.Add(new X86Code("pop", "ax"));
            ret.Codes.Add(new X86Code("pop", "dx"));
            ret.Codes.Add(new X86Code("cmp", "dx", "ax"));
            ret.Codes.Add(new X86Code("jnc", string.Format("PE_{0:X8}", Girl.PEAnalyzer.Util.GetBrTarget(il))));
            if (this.optimize > 0 && nOp == 0)
            {
                ret.Ignore();
            }
            break;

        case "brfalse":
        case "brfalse.s":
            ret.Codes.Add(new X86Code("pop", "ax"));
            ret.Codes.Add(new X86Code("or", "ax", "ax"));
            ret.Codes.Add(new X86Code("jz", string.Format("PE_{0:X8}", Girl.PEAnalyzer.Util.GetBrTarget(il))));
            if (this.optimize > 0 && nOp == 0)
            {
                ret.Ignore();
            }
            break;

        case "brtrue":
        case "brtrue.s":
            ret.Codes.Add(new X86Code("pop", "ax"));
            ret.Codes.Add(new X86Code("or", "ax", "ax"));
            ret.Codes.Add(new X86Code("jnz", string.Format("PE_{0:X8}", Girl.PEAnalyzer.Util.GetBrTarget(il))));
            if (this.optimize > 0 && nOp == 0)
            {
                ret.Ignore();
            }
            break;

        case "call":
        {
            TableBase  tb    = this.pedata.idxm.GetTable((int)il.Operand);
            MethodData tb_md = tb.Tag as MethodData;
            ret.Codes.Add(new X86Code("call", string.Format("{0}", Util.MangleFunction(tb_md))));
            if (tb_md.RetType.Element != ELEMENT_TYPE.VOID)
            {
                ret.Codes.Add(new X86Code("push", "ax"));
            }
            break;
        }

        //case "callvirt":
        //{
        //	TableBase tb = this.pedata.idxm.GetTable((int)il.Operand);
        //	MethodData tb_md = tb.Tag as MethodData;
        //	string func = Util.MangleFunction(tb_md);
        //	if (func.StartsWith("instance__")) func = func.Substring(10, func.Length - 10);
        //	sw.WriteLine("\tcall _virtual__{0}", func);
        //	if (tb_md.RetType.Element != ELEMENT_TYPE.VOID) sw.WriteLine("\tpush ax");
        //	break;
        //}
        case "ret":
            if (this.optimize == 0 || il == this.lastRet)
            {
                if (md.RetType.Element != ELEMENT_TYPE.VOID)
                {
                    ret.Codes.Add(new X86Code("pop", "ax"));
                }
                if (md.LocalVars != null || md.ParamCount > 0)
                {
                    if (md.LocalVars != null)
                    {
                        ret.Codes.Add(new X86Code("mov", "sp", "bp"));
                    }
                    ret.Codes.Add(new X86Code("pop", "bp"));
                }
                int st = Util.GetStackSize(md);
                if (st == 0)
                {
                    ret.Codes.Add(new X86Code("ret"));
                }
                else
                {
                    ret.Codes.Add(new X86Code("ret", st.ToString()));
                }
            }
            else
            {
                X86Code x = new X86Code("jmp", string.Format("PE_{0:X8}", this.lastRet.Address));
                x.Notes = "[optimize] modify";
                ret.Codes.Add(x);
                this.lastRet.IsBrTarget = true;
            }
            break;

        case "ceq":
            ret.Codes.Add(new X86Code("pop", "ax"));
            ret.Codes.Add(new X86Code("pop", "dx"));
            ret.Codes.Add(new X86Code("cmp", "ax", "dx"));
            ret.Codes.Add(new X86Code("je", string.Format("NM_{0:X8}", this.number)));
            ret.Codes.Add(new X86Code("xor", "ax", "ax"));
            ret.Codes.Add(new X86Code("jmp", string.Format("NM_{0:X8}", this.number + 1)));
            ret.Codes.Add(new X86Code(string.Format("NM_{0:X8}", this.number), true, "ceq internal", "mov", "ax", "1"));
            ret.Codes.Add(new X86Code(string.Format("NM_{0:X8}", this.number + 1), true, "ceq internal", "push", "ax"));
            this.number += 2;
            break;

        case "add":
        case "and":
        case "or":
            ret.Codes.Add(new X86Code("pop", "ax"));
            ret.Codes.Add(new X86Code("pop", "dx"));
            ret.Codes.Add(new X86Code(mne, "ax", "dx"));
            ret.Codes.Add(new X86Code("push", "ax"));
            break;

        case "sub":
            ret.Codes.Add(new X86Code("pop", "dx"));
            ret.Codes.Add(new X86Code("pop", "ax"));
            ret.Codes.Add(new X86Code("sub", "ax", "dx"));
            ret.Codes.Add(new X86Code("push", "ax"));
            break;

        case "mul":
            ret.Codes.Add(new X86Code("pop", "ax"));
            ret.Codes.Add(new X86Code("pop", "dx"));
            ret.Codes.Add(new X86Code("mul", "dx"));
            ret.Codes.Add(new X86Code("push", "ax"));
            break;

        case "div":
            ret.Codes.Add(new X86Code("pop", "cx"));
            ret.Codes.Add(new X86Code("pop", "ax"));
            ret.Codes.Add(new X86Code("xor", "dx", "dx"));
            ret.Codes.Add(new X86Code("div", "cx"));
            ret.Codes.Add(new X86Code("push", "ax"));
            break;

        case "rem":
            ret.Codes.Add(new X86Code("pop", "cx"));
            ret.Codes.Add(new X86Code("pop", "ax"));
            ret.Codes.Add(new X86Code("xor", "dx", "dx"));
            ret.Codes.Add(new X86Code("div", "cx"));
            ret.Codes.Add(new X86Code("push", "dx"));
            break;

        case "neg":
            ret.Codes.Add(new X86Code("pop", "ax"));
            ret.Codes.Add(new X86Code("neg", "ax"));
            ret.Codes.Add(new X86Code("push", "ax"));
            break;

        case "shr":
        case "shl":
            ret.Codes.Add(new X86Code("pop", "cx"));
            ret.Codes.Add(new X86Code("pop", "ax"));
            ret.Codes.Add(new X86Code(mne, "ax", "cl"));
            ret.Codes.Add(new X86Code("push", "ax"));
            break;

        case "conv.u1":
            ret.Codes.Add(new X86Code("pop", "ax"));
            ret.Codes.Add(new X86Code("mov", "ah", "0"));
            ret.Codes.Add(new X86Code("push", "ax"));
            break;

        case "conv.i2":
        case "conv.u2":
        case "conv.i4":
        case "conv.u4":
            // ignore in 16bit
            return(ret);
            //case "box":
            //{
            //	TypeRefTable t = this.pedata.idxm.GetTable((int)il.Operand) as TypeRefTable;
            //	sw.WriteLine("\tcall _box__{0}@4", GetTypeName(this.pedata.idxm.GetName(t)));
            //	sw.WriteLine("\tpush ax");
            //	break;
            //}
        }
        if (ret.Codes.Count < 1)
        {
            return(null);
        }
        return(ret);
    }
Beispiel #10
0
    public void Optimize(ArrayList list, MethodData md)
    {
        X86Code.Optimize(list);

        bool      bx     = true;
        Hashtable locals = new Hashtable();
        int       max    = 0;
        string    target = null;

        for (int i = 0; i < list.Count; i++)
        {
            X86Code x = list[i] as X86Code;
            if (x == null || x.ignore)
            {
                continue;
            }

            if (x.Mnemonic == "int" || x.Operand1 == "bx")
            {
                bx = false;
            }
            int p1a = x.Operand1.IndexOf("[ss:bp-"), p1b = x.Operand1.LastIndexOf(']');
            if (0 <= p1a && p1a < p1b)
            {
                string var = x.Operand1.Substring(p1a + 1, p1b - p1a - 1);
                int    v   = !locals.Contains(var) ? 1 : ((int)locals[var]) + 1;
                locals[var] = v;
                if (max < v)
                {
                    max    = v;
                    target = var;
                }
            }
            int p2a = x.Operand2.IndexOf("[ss:bp-"), p2b = x.Operand2.LastIndexOf(']');
            if (0 <= p2a && p2a < p2b)
            {
                string var = x.Operand2.Substring(p2a + 1, p2b - p2a - 1);
                int    v   = !locals.Contains(var) ? 1 : ((int)locals[var]) + 1;
                locals[var] = v;
                if (max < v)
                {
                    max    = v;
                    target = var;
                }
            }
        }
        if (bx && target != null)
        {
            for (int i = 0; i < list.Count; i++)
            {
                X86Code x = list[i] as X86Code;
                if (x == null || x.ignore)
                {
                    continue;
                }

                string op1 = x.Operand1, op2 = x.Operand2;
                int    p1 = op1.IndexOf(target), p2 = op2.IndexOf(target);
                if (p1 >= 0)
                {
                    op1 = "bx";
                }
                if (p2 >= 0)
                {
                    op2 = "bx";
                }
                if (p1 < 0 && p2 < 0)
                {
                    continue;
                }

                x.Ignore();
                X86Code xx = new X86Code(x.Mnemonic, op1, op2);
                xx.Notes = "[optimize] add";
                list.Insert(i + 1, xx);
            }
            if (md.LocalVars != null && md.LocalVars.Count == 1 && target.StartsWith("ss:bp-"))
            {
                for (int i = 0; i < list.Count; i++)
                {
                    X86Code x = list[i] as X86Code;
                    if (x == null || x.ignore)
                    {
                        continue;
                    }

                    if (x.Mnemonic == "sub" && x.Operand1 == "sp")
                    {
                        x.Ignore();
                        break;
                    }
                }
                for (int i = list.Count - 1; i >= 0; i--)
                {
                    X86Code x = list[i] as X86Code;
                    if (x == null || x.ignore)
                    {
                        continue;
                    }

                    if (x.Mnemonic == "mov" && x.Operand1 == "sp")
                    {
                        x.Ignore();
                        break;
                    }
                }
            }
        }
        X86Code.Optimize(list);
        if (md.LocalVars != null || md.ParamCount > 0 || !bx)
        {
            X86Code xb1 = new X86Code("push", "bx"), xb2 = new X86Code("pop", "bx");
            xb1.Notes = xb2.Notes = "[optimize] add";
            list.Insert(0, xb1);
            for (int i = 0; i < list.Count; i++)
            {
                X86Code x = list[i] as X86Code;
                if (x == null || x.ignore)
                {
                    continue;
                }

                if (x.Mnemonic == "ret")
                {
                    list.Insert(i, xb2);
                    i++;
                }
            }
        }
    }