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 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 #3
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 #4
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 #5
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);
    }