public static OpCode FromName(string op, Addr32 op1) { switch (op) { case "push": return new OpCode(new byte[] { 0xff }, null, new Addr32(op1, 6)); case "pop": return new OpCode(new byte[] { 0x8f }, null, op1); case "inc": return new OpCode(new byte[] { 0xff }, null, op1); case "dec": return new OpCode(new byte[] { 0xff }, null, new Addr32(op1, 1)); case "not": return new OpCode(new byte[] { 0xf7 }, null, new Addr32(op1, 2)); case "neg": return new OpCode(new byte[] { 0xf7 }, null, new Addr32(op1, 3)); case "mul": return new OpCode(new byte[] { 0xf7 }, null, new Addr32(op1, 4)); case "imul": return new OpCode(new byte[] { 0xf7 }, null, new Addr32(op1, 5)); case "div": return new OpCode(new byte[] { 0xf7 }, null, new Addr32(op1, 6)); case "idiv": return new OpCode(new byte[] { 0xf7 }, null, new Addr32(op1, 7)); default: throw new Exception("invalid operator: " + op); } }
public static OpCode FromName(string op, Mm op1, Addr32 op2) { byte b; switch (op) { case "movd": b = 0x6e; break; default: b = GetCode(op); break; } return new OpCode(new byte[] { 0x0f, b }, null, new Addr32(op2, (byte)op1)); }
public static OpCode FromName(string op, Xmm op1, Addr32 op2) { byte b1 = 0x66, b2; if (op == "movq" || op == "movdqu") b1 = 0xf3; switch (op) { case "movd": b2 = 0x6e; break; default: b2 = GetCode(op); break; } return new OpCode(new byte[] { b1, 0x0f, b2 }, null, new Addr32(op2, (byte)op1)); }
public static OpCode FromName(string op, Addr32 op1, Mm op2) { byte b; switch (op) { case "movd": b = 0x7e; break; case "movq": b = 0x7f; break; default: throw new Exception("invalid operator: " + op); } return new OpCode(new byte[] { 0x0f, b }, null, new Addr32(op1, (byte)op2)); }
public static OpCode FromNameW(string op, Reg32 op1, Addr32 op2) { byte b; switch (op) { case "movzx": b = 0xb7; break; case "movsx": b = 0xbf; break; default: throw new Exception("invalid operator: " + op); } return new OpCode(new byte[] { 0x0f, b }, null, new Addr32(op2, (byte)op1)); }
public static OpCode[] Call(CallType call, Addr32 func, object[] args) { List<OpCode> ret = new List<OpCode>(); args = args.Clone() as object[]; Array.Reverse(args); foreach (object arg in args) { if (arg is int) ret.Add(Push((uint)(int)arg)); else if (arg is uint) ret.Add(Push((uint)arg)); else if (arg is Val32) ret.Add(Push((Val32)arg)); else if (arg is Addr32) ret.Add(Push((Addr32)arg)); else throw new Exception("Unknown argument."); } ret.Add(Call(func)); if (call == CallType.CDecl) { ret.Add(Add(Reg32.ESP, (byte)(args.Length * 4))); } return ret.ToArray(); }
public static OpCode FromName(string op, Addr32 op1, Xmm op2) { byte b1 = 0x66, b2; if (op == "movdqu") b1 = 0xf3; switch (op) { case "movd": b2 = 0x7e; break; case "movq": b2 = 0xd6; break; case "movdqa": case "movdqu": b2 = 0x7f; break; default: throw new Exception("invalid operator: " + op); } return new OpCode(new byte[] { b1, 0x0f, b2 }, null, new Addr32(op1, (byte)op2)); }
private static void exe2() { var exe = GetOutput("02.exe"); var module = new Module(); var c = new List<OpCode>(); const int STD_INPUT_HANDLE = -10; const int STD_OUTPUT_HANDLE = -11; var ExitProcess = module.GetFunction(CallType.Std, "kernel32.dll", "ExitProcess"); var GetStdHandle = module.GetFunction(CallType.Std, "kernel32.dll", "GetStdHandle"); var ReadConsole = module.GetFunction(CallType.Std, "kernel32.dll", "ReadConsoleW"); var WriteConsole = module.GetFunction(CallType.Std, "kernel32.dll", "WriteConsoleW"); // HANDLE stdin = GetStdHandle(STD_INPUT_HANDLE); var stdin = new Addr32(module.GetInt32("stdin")); c.AddRange(GetStdHandle.Invoke(STD_INPUT_HANDLE)); c.Add(I386.Mov(stdin, Reg32.EAX)); // HANDLE stdout = GetStdHandle(STD_OUTPUT_HANDLE); var stdout = new Addr32(module.GetInt32("stdout")); c.AddRange(GetStdHandle.Invoke(STD_OUTPUT_HANDLE)); c.Add(I386.Mov(stdout, Reg32.EAX)); var dummy = module.GetInt32("dummy"); var buffer = module.GetBuffer("buffer", 16); var hello = "Ola mundo"; var wait = "\r\n\r\nPress [Enter] to exit.\r\n"; c.AddRange(WriteConsole.Invoke(stdout, hello, hello.Length, dummy, 0)); c.AddRange(WriteConsole.Invoke(stdout, wait, wait.Length, dummy, 0)); c.AddRange(ReadConsole.Invoke(stdin, buffer, 1, dummy, 0)); c.AddRange(ExitProcess.Invoke(0)); module.Text.OpCodes = c.ToArray(); try { module.Link(exe); } catch (IOException) { } Process.Start(exe); }
public Function(Module mod, Addr32 addr) { module = mod; address = addr; }
public static OpCode SalW(Addr32 op1, byte op2) { return ShiftW("sal", op1, op2); }
public static OpCode ShlW(Addr32 op1, Reg8 op2) { return ShiftW("shl", op1, op2); }
public OpCode(byte[] d, object op, Addr32 mem) { data = d; op1 = op; op2 = mem; }
public static OpCode IdivB(Addr32 op1) { return FromNameB("idiv", op1); }
public static OpCode Lea(Reg32 op1, Addr32 op2) { return new OpCode(new byte[] { 0x8d }, null, new Addr32(op2, (byte)op1)); }
public static OpCode Jmp(Addr32 op1) { return new OpCode(new byte[] { 0xff }, null, new Addr32(op1, 4)); }
public static OpCode NotB(Addr32 op1) { return FromNameB("not", op1); }
public static OpCode DecB(Addr32 op1) { return FromNameB("dec", op1); }
public static OpCode Shift(string op, Addr32 op1, byte op2) { Addr32 ad; switch (op) { case "shl": case "sal": ad = new Addr32(op1, 4); break; case "shr": ad = new Addr32(op1, 5); break; case "sar": ad = new Addr32(op1, 7); break; default: throw new Exception("invalid operator: " + op); } if (op2 == 1) return new OpCode(new byte[] { 0xd1 }, null, ad); else return new OpCode(new byte[] { 0xc1 }, op2, ad); }
public static OpCode ImulB(Addr32 op1) { return FromNameB("imul", op1); }
public static OpCode Shl(Addr32 op1, byte op2) { return Shift("shl", op1, op2); }
public static OpCode MovzxW(Reg32 op1, Addr32 op2) { return FromNameW("movzx", op1, op2); }
public static OpCode Shr(Addr32 op1, Reg8 op2) { return Shift("shr", op1, op2); }
public static OpCode ShiftW(string op, Addr32 op1, Reg8 op2) { Addr32 ad; switch (op) { case "shl": case "sal": ad = new Addr32(op1, 4); break; case "shr": ad = new Addr32(op1, 5); break; case "sar": ad = new Addr32(op1, 7); break; default: throw new Exception("invalid operator: " + op); } if (op2 != Reg8.CL) throw new Exception("invalid register: " + op2); else return new OpCode(new byte[] { 0x66, 0xd3 }, null, ad); }
public static OpCode Sal(Addr32 op1, Reg8 op2) { return Shift("sal", op1, op2); }
public static OpCode ShrW(Addr32 op1, byte op2) { return ShiftW("shr", op1, op2); }
public static OpCode Sar(Addr32 op1, byte op2) { return Shift("sar", op1, op2); }
public static OpCode SarW(Addr32 op1, Reg8 op2) { return ShiftW("sar", op1, op2); }
public static OpCode IncB(Addr32 op1) { return FromNameB("inc", op1); }
public Function(Module mod, Addr32 addr, CallType call) { module = mod; address = addr; callType = call; }
public static OpCode NegB(Addr32 op1) { return FromNameB("neg", op1); }