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