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; }
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); }