private void btnDisAsm_Click(object sender, EventArgs e) { rtbHexDump.Clear(); //Console.WriteLine("Version: " + BeaEngine.Version); //Console.WriteLine("Revision: " + BeaEngine.Revision); //UnmanagedBuffer buffer = new UnmanagedBuffer(File.ReadAllBytes("BeaEngine.dll")); uint address = Convert.ToUInt32(tbOffsetToWatch.Text, 16); uint naddress = address + (uint)baseAddressModule; UnmanagedBuffer buffer = new UnmanagedBuffer(procTools.Memory.ReadBytes(naddress, 1120)); var disasm = new Disasm(); //disasm.EIP = new IntPtr(buffer.Ptr.ToInt64() + 0x400); disasm.EIP = new IntPtr(buffer.Ptr.ToInt64()); for (int counter = 0; counter < 100; ++counter) { int result = BeaEngine.Disasm(disasm); if (result == (int)BeaConstants.SpecialInfo.UNKNOWN_OPCODE) { break; } //rtbHexDump.AppendText("0x" + disasm.EIP.ToString("X") + " " + disasm.CompleteInstr+"\r\n"); rtbHexDump.AppendText("0x" + address.ToString("X") + "\t" + disasm.CompleteInstr + "\r\n"); disasm.EIP = new IntPtr(disasm.EIP.ToInt64() + result); address += (uint)result; } }
/// <summary> /// Disassembles the given code /// </summary> /// <param name="generatedCode">The generated code</param> public string Disassemble(IList <byte> generatedCode) { var output = new StringBuilder(); var buffer = new UnmanagedBuffer(generatedCode.ToArray()); var disasm = new Disasm() { Archi = 64 }; int offset = 0; while (offset < generatedCode.Count) { disasm.EIP = new IntPtr(buffer.Ptr.ToInt64() + offset); int result = BeaEngine64.Disasm(disasm); if (result == (int)BeaConstants.SpecialInfo.UNKNOWN_OPCODE) { break; } //strBuffer.AppendLine("0x" + offset.ToString("X") + " " + disasm.CompleteInstr); output.AppendLine(disasm.CompleteInstr); offset += result; } return(output.ToString()); }
public X86IMUL(Disasm rawInstruction) : base() { Operands = new IX86Operand[3]; Operands[0] = GetOperand(rawInstruction.Argument1); Operands[1] = GetOperand(rawInstruction.Argument2); Operands[2] = GetOperand(rawInstruction.Argument3); }
/// <summary> /// Creates a new disassembler /// </summary> /// <param name="compilationData">The compilation data</param> public Disassembler(AbstractCompilationData compilationData) { this.compilationData = compilationData; this.codeBuffer = new UnmanagedBuffer(compilationData.Function.GeneratedCode.ToArray()); this.disassembler = new Disasm() { Archi = 64, EIP = new IntPtr(this.codeBuffer.Ptr.ToInt64()) }; }
/// <summary> /// Disassemble a given piece of shellcode. /// </summary> /// <param name="disasmBytes">The byte array to disassemble</param> /// <param name="architecture">The architecture to target. Either 32 or 64 bit Windows</param> /// <param name="disasmBox">The listbox to place the disassembly</param> /// <param name="showOffsets">Boolean to determine whether or not to display address offsets in the disassembly listing.</param> public void disassembleSC(byte[] disasmBytes, uint architecture, System.Windows.Forms.RichTextBox disasmBox, bool showOffsets) { var disasm = new Disasm(); disasm.Options = 0x200;//display in NASM syntax if (architecture == 32) { disasm.Archi = 32; } else if (architecture == 64) { disasm.Archi = 64; } int size = disasmBytes.Length; IntPtr executionPointer = System.Runtime.InteropServices.Marshal.AllocHGlobal(size); System.Runtime.InteropServices.Marshal.Copy(disasmBytes, 0, executionPointer, size); disasm.EIP = new IntPtr(executionPointer.ToInt64()); int result; var disasmPtr = Marshal.AllocHGlobal(Marshal.SizeOf(disasm)); disasmBox.AppendText("Disassembled shellcode with " + architecture + "bit\n"); var EIPrange = (executionPointer.ToInt64() + size/2); try { while (disasm.EIP.ToInt64() < EIPrange) { System.Runtime.InteropServices.Marshal.StructureToPtr(disasm, disasmPtr, false); result = BeaEngine.Disasm(disasmPtr); Marshal.PtrToStructure(disasmPtr, disasm); if (result == (int)BeaConstants.SpecialInfo.UNKNOWN_OPCODE) { disasmBox.AppendText("Unknown opcode error @ " + disasm.EIP.ToString("X") + "\n"); break; } if (showOffsets) disasmBox.AppendText(disasm.EIP.ToString("X") + "h : " + disasm.CompleteInstr.ToString() + "\n"); else disasmBox.AppendText(disasm.CompleteInstr.ToString() + "\n"); if (disasm.Instruction.Opcode.ToString("X") == "C3") break; disasm.EIP = new IntPtr(disasm.EIP.ToInt64() + result); } } catch { disasmBox.AppendText("Something went wrong with disassembly\n"); } }
public DisassemblyInstruction(Disasm disasm, int length, byte[] instructionData) { Length = length; InstructionData = instructionData; CompleteInstruction = disasm.CompleteInstr; Architecture = disasm.Archi; Options = disasm.Options; Instruction = disasm.Instruction; Argument1 = disasm.Argument1; Argument2 = disasm.Argument2; Argument3 = disasm.Argument3; Prefix = disasm.Prefix; }
public static Disasm Clone(Disasm disasm) { return(new Disasm { Archi = disasm.Archi, Argument1 = disasm.Argument1, Argument2 = disasm.Argument2, Argument3 = disasm.Argument3, CompleteInstr = disasm.CompleteInstr, EIP = disasm.EIP, Instruction = disasm.Instruction, Options = disasm.Options, Prefix = disasm.Prefix, SecurityBlock = disasm.SecurityBlock, VirtualAddr = disasm.VirtualAddr }); }
public void Execute(uint offset, UnmanagedBuffer buffer, bool followCalls = false) { try { Esp.Value -= 4; // Assume we are calling from the beginning of a function. return address is on the stack Disasm disasm = new Disasm(); disasm.EIP = new IntPtr(buffer.Ptr.ToInt64() + offset); // new IntPtr(buffer.Ptr.ToInt64()/* + offset*/); while (true) { var result = BeaEngine.Disassemble(disasm); if (result == BeaConstants.SpecialInfo.UNKNOWN_OPCODE) { return; } // Returns true if jumped or following calls var jumped = ExecuteASM(disasm, buffer, followCalls); if ((disasm.CompleteInstr.Contains("leave") || disasm.CompleteInstr.Contains("ret")) && !jumped) { break; } Debugger.TryTrigger(this, BreakpointType.InstructionName, disasm.Instruction.Mnemonic); if (!jumped) { disasm.EIP = new IntPtr(disasm.EIP.ToInt64() + (int)result); } } for (var i = 0; i < CallOffsets.Count; ++i) { CallOffsets[i] += 0x400C00; } } catch (Exception e) { Console.WriteLine(e); } }
static void Main(string[] args) { Console.WriteLine("Version: " + BeaEngine.Version); Console.WriteLine("Revision: " + BeaEngine.Revision); UnmanagedBuffer buffer = new UnmanagedBuffer(File.ReadAllBytes("BeaEngine.dll")); var disasm = new Disasm(); disasm.EIP = new IntPtr(buffer.Ptr.ToInt64() + 0x400); for (int counter = 0; counter < 100; ++counter) { int result = BeaEngine.Disasm(disasm); if (result == (int)BeaConstants.SpecialInfo.UNKNOWN_OPCODE) { break; } Console.WriteLine("0x" + disasm.EIP.ToString("X") + " " + disasm.CompleteInstr); disasm.EIP = new IntPtr(disasm.EIP.ToInt64() + result); } }
public static IEnumerable<DisassemblyInstruction> Disassemble(IntPtr pAddr, int maxInstructionCount = 0) { if (pAddr == IntPtr.Zero) throw new ArgumentNullException("pAddr"); const int maxInstructionSize = 15; const int maxBufferSize = 4096; // default buffer of 100 x maxInstructionSize bytes (1500 bytes) // unless maxInstructionCount is specified var bufferSize = (maxInstructionCount == 0 ? 100 : maxInstructionCount)*maxInstructionSize; // ensure we don't allocate too large a buffer if a huge instruction count is specified bufferSize = Math.Min(bufferSize, maxBufferSize); // allocate an unmanaged buffer (instead of reading into managed byte array) var pBuffer = IntPtr.Zero; try { pBuffer = Process.GetCurrentProcess().Allocate(IntPtr.Zero, (uint) bufferSize); // TODO: this is probably horribly inefficient Marshal.Copy(pAddr.ReadArray<byte>(bufferSize), 0, pBuffer, bufferSize); var pDisasmLoc = pBuffer; var virtualAddr = (uint) pAddr; // TODO: currently doesnt support x64 var disasm = new Disasm {EIP = pDisasmLoc, VirtualAddr = virtualAddr}; int length; var instructionsRead = 0; var bufferOffset = 0; while ((length = BeaEngine.Disasm(disasm)) != (int) BeaConstants.SpecialInfo.UNKNOWN_OPCODE) { instructionsRead++; var disasmInstr = new DisassemblyInstruction(disasm, length, virtualAddr.ReadArray<byte>(length)); yield return disasmInstr; pDisasmLoc += length; virtualAddr += (uint) length; bufferOffset += length; if (maxInstructionCount > 0 && instructionsRead >= maxInstructionCount) break; // if we don't have an instruction limit and we're less than maxInstructionSize away // from the end of the buffer, reread buffer data from current location if ((bufferSize - bufferOffset) < maxInstructionSize) { // Copy new bytes to buffer from current location Marshal.Copy(virtualAddr.ReadArray<byte>(bufferSize), 0, pBuffer, bufferSize); // reset pointers etc pDisasmLoc = pBuffer; bufferOffset = 0; } disasm.EIP = pDisasmLoc; disasm.VirtualAddr = virtualAddr; } } finally { if (pBuffer != IntPtr.Zero) Process.GetCurrentProcess().Free(pBuffer); } }
public static IEnumerable <DisassemblyInstruction> Disassemble(IntPtr pAddr, int maxInstructionCount = 0) { if (pAddr == IntPtr.Zero) { throw new ArgumentNullException("pAddr"); } const int maxInstructionSize = 15; const int maxBufferSize = 4096; // default buffer of 100 x maxInstructionSize bytes (1500 bytes) // unless maxInstructionCount is specified var bufferSize = (maxInstructionCount == 0 ? 100 : maxInstructionCount) * maxInstructionSize; // ensure we don't allocate too large a buffer if a huge instruction count is specified bufferSize = Math.Min(bufferSize, maxBufferSize); // allocate an unmanaged buffer (instead of reading into managed byte array) var pBuffer = IntPtr.Zero; try { pBuffer = Process.GetCurrentProcess().Allocate(IntPtr.Zero, (uint)bufferSize); // TODO: this is probably horribly inefficient Marshal.Copy(pAddr.ReadArray <byte>(bufferSize), 0, pBuffer, bufferSize); var pDisasmLoc = pBuffer; var virtualAddr = (uint)pAddr; // TODO: currently doesnt support x64 var disasm = new Disasm { EIP = pDisasmLoc, VirtualAddr = virtualAddr }; int length; var instructionsRead = 0; var bufferOffset = 0; while ((length = BeaEngine.Disasm(disasm)) != (int)BeaConstants.SpecialInfo.UNKNOWN_OPCODE) { instructionsRead++; var disasmInstr = new DisassemblyInstruction(disasm, length, virtualAddr.ReadArray <byte>(length)); yield return(disasmInstr); pDisasmLoc += length; virtualAddr += (uint)length; bufferOffset += length; if (maxInstructionCount > 0 && instructionsRead >= maxInstructionCount) { break; } // if we don't have an instruction limit and we're less than maxInstructionSize away // from the end of the buffer, reread buffer data from current location if ((bufferSize - bufferOffset) < maxInstructionSize) { // Copy new bytes to buffer from current location Marshal.Copy(virtualAddr.ReadArray <byte>(bufferSize), 0, pBuffer, bufferSize); // reset pointers etc pDisasmLoc = pBuffer; bufferOffset = 0; } disasm.EIP = pDisasmLoc; disasm.VirtualAddr = virtualAddr; } } finally { if (pBuffer != IntPtr.Zero) { Process.GetCurrentProcess().Free(pBuffer); } } }
private void ParseInstructions(MethodDef method) { var rawInstructions = new List <Disasm>(); while (true) { byte[] bytes = ReadChunk(method, _module); var disasm = new Disasm(); var buff = new UnmanagedBuffer(bytes); disasm.EIP = new IntPtr(buff.Ptr.ToInt32()); var instruction = BeaEngine.Disasm(disasm); _readOffset -= 8 - instruction; // revert offset back for each byte that was not a part of this instruction var mnemonic = disasm.Instruction.Mnemonic.Trim(); if (mnemonic == "ret") //TODO: Check if this is the only return in function, e.g. check for jumps that go beyond this address { Marshal.FreeHGlobal(buff.Ptr); break; } rawInstructions.Add(Clone(disasm)); //disasm.EIP = new IntPtr(disasm.EIP.ToInt32() + instruction); Marshal.FreeHGlobal(buff.Ptr); } //while(rawInstructions.First().Instruction.Mnemonic.Trim() == "pop") // rawInstructions.Remove(rawInstructions.First()); while (rawInstructions.Last().Instruction.Mnemonic.Trim() == "pop") { rawInstructions.Remove(rawInstructions.Last()); } foreach (var instr in rawInstructions) { switch (instr.Instruction.Mnemonic.Trim()) { case "mov": Instructions.Add(new X86MOV(instr)); break; case "add": Instructions.Add(new X86ADD(instr)); break; case "sub": Instructions.Add(new X86SUB(instr)); break; case "imul": Instructions.Add(new X86IMUL(instr)); break; case "div": Instructions.Add(new X86DIV(instr)); break; case "neg": Instructions.Add(new X86NEG(instr)); break; case "not": Instructions.Add(new X86NOT(instr)); break; case "xor": Instructions.Add(new X86XOR(instr)); break; case "pop": Instructions.Add(new X86POP(instr)); break; } } }
private bool ExecuteJump(string disasmStr, Disasm disasm, string mnemonic) { bool shouldJump = false; if (mnemonic == "jmp") { shouldJump = true; } else if (mnemonic == "je" || mnemonic == "jz") // Jump short if equal (ZF=1). { shouldJump = EFlags.HasFlag(EFlags.ZeroFlag); } else if (mnemonic == "jne" || mnemonic == "jnz") // Jump short if not equal (ZF=0). { shouldJump = !EFlags.HasFlag(EFlags.ZeroFlag); } else if (mnemonic == "ja" || mnemonic == "jnbe") // Jump short if not below or equal (CF=0 and ZF=0). { shouldJump = !EFlags.HasFlag(EFlags.CarryFlag) && !EFlags.HasFlag(EFlags.ZeroFlag); } else if (mnemonic == "jb" || mnemonic == "jc" || mnemonic == "jnae") // Jump short if not above or equal (CF=1). { shouldJump = EFlags.HasFlag(EFlags.CarryFlag); } else if (mnemonic == "jng" || mnemonic == "jle") // Jump short if not greater (ZF=1 or SF != OF). { shouldJump = EFlags.HasFlag(EFlags.ZeroFlag) || (EFlags.HasFlag(EFlags.SignFlag) != EFlags.HasFlag(EFlags.OverflowFlag)); } else if (mnemonic == "jnc" || mnemonic == "jnb" || mnemonic == "jae") // Jump short if not carry (CF=0). { shouldJump = !EFlags.HasFlag(EFlags.CarryFlag); } else if (mnemonic == "jna" || mnemonic == "jbe") // Jump short if not above (CF=1 or ZF=1). { shouldJump = EFlags.HasFlag(EFlags.CarryFlag) || EFlags.HasFlag(EFlags.ZeroFlag); } else if (mnemonic == "jge" || mnemonic == "jnl") // Jump short if greater or equal (SF=OF). { shouldJump = EFlags.HasFlag(EFlags.SignFlag) == EFlags.HasFlag(EFlags.OverflowFlag); } else if (mnemonic == "jg" || mnemonic == "jnle") // Jump short if greater (ZF=0 and SF=OF). { shouldJump = !EFlags.HasFlag(EFlags.ZeroFlag) && (EFlags.HasFlag(EFlags.SignFlag) == EFlags.HasFlag(EFlags.OverflowFlag)); } else if (mnemonic == "jl" || mnemonic == "jnge") // Jump short if less (SF != OF). { shouldJump = EFlags.HasFlag(EFlags.SignFlag) != EFlags.HasFlag(EFlags.OverflowFlag); } else if (mnemonic == "jecxz") // Jump short if ECX register is 0. { shouldJump = Ecx.Value == 0; } else if (mnemonic == "jcxz") // Jump short if CX register is 0. { shouldJump = Ecx.Cx == 0; } else if (mnemonic == "jno") // Jump short if not overflow (OF=0) { shouldJump = !EFlags.HasFlag(EFlags.OverflowFlag); } else if (mnemonic == "jnp" || mnemonic == "jpo") // Jump short if not parity (PF=0) { shouldJump = !EFlags.HasFlag(EFlags.ParityFlag); } else if (mnemonic == "jns") // Jump short if not sign (SF=0) { shouldJump = !EFlags.HasFlag(EFlags.SignFlag); } else if (mnemonic == "jo") // Jump short if overflow (OF=1) { shouldJump = !EFlags.HasFlag(EFlags.OverflowFlag); } else if (mnemonic == "jp" || mnemonic == "jpe") // Jump short if parity (PF=1) { shouldJump = !EFlags.HasFlag(EFlags.ParityFlag); } else if (mnemonic == "js") // Jump short if sign (SF=1) { shouldJump = !EFlags.HasFlag(EFlags.SignFlag); } else { throw new Exception("Invalid jump type detected."); } if (!shouldJump) { return(false); } // We should jump. return(true); }
private bool ExecuteASM(Disasm disasm, UnmanagedBuffer buffer, bool followCalls) { if (Interrupted) { return(false); } var entryPoint = buffer.Ptr.ToInt32(); var disassemblyString = disasm.CompleteInstr; // Sanitize the instruction. if (disassemblyString.IndexOf(";") != -1) { disassemblyString = disassemblyString.Remove(disassemblyString.IndexOf(";")); } disassemblyString = Regex.Replace(disassemblyString, @"\s+", " ", RegexOptions.IgnoreCase).Trim(); if (Regex.IsMatch(disassemblyString, @"[!@#$%^&()={}\\|/?<>.~`""'_]")) { return(false); } if (disassemblyString.Length == 0 || disassemblyString.EndsWith(":")) { return(false); } var tokens = disassemblyString.Split(' '); var mnemonic = tokens[0]; //Console.WriteLine("0x{0:X8} {1}", disasm.EIP.ToInt64(), disasm.CompleteInstr); if (disassemblyString.Contains("call far") || disassemblyString.Contains("xmm")) { return(false); } List <InstructionArgument> arguments = new List <InstructionArgument>(); // TODO Support for floating point opcodes var parametersList = disassemblyString.Replace(mnemonic, String.Empty).Trim().Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); foreach (var parameter in parametersList) { arguments.Add(new InstructionArgument(this, parameter.Trim())); } if (mnemonic[0] == 'j') { if (ExecuteJump(disassemblyString, disasm, mnemonic)) { var jumpOffset = arguments[0].GetValue(); if (arguments[0].Type == ArgumentType.Memory) { jumpOffset += (uint)entryPoint - 0x400C00; } disasm.EIP = new IntPtr(jumpOffset); return(true); } else { return(false); } } else { InstructionArgument src = null; InstructionArgument dst = null; InstructionArgument extra = null; if (parametersList.Length == 1) { dst = src = arguments[0]; } else if (parametersList.Length == 2) { dst = arguments[0]; src = arguments[1]; } else if (parametersList.Length == 3) { extra = arguments[2]; } switch (mnemonic) { case "ret": case "retn": // Actually use the stack here. if (JumpBacks.Count > 0) { Pop(4); disasm.EIP = new IntPtr(JumpBacks[0]); JumpBacks.RemoveAt(0); return(true); } return(false); case "leave": break; case "nop": break; #region Data transfer case "mov": if (parametersList.Length != 2 || dst.Type == ArgumentType.Immediate) { break; } if (src.Type == ArgumentType.Immediate && src.Size > dst.Size) { break; } if (src.Type != ArgumentType.Immediate && src.Size != dst.Size) { break; } dst.SetValue(src.GetValue()); break; case "movzx": { if (parametersList.Length != 2 || dst.Type != ArgumentType.Register || src.Type == ArgumentType.Immediate || src.Size >= dst.Size) { break; } //! TODO Unhack this - Handles indirect jumptables //! TODO: Really need to fix memory - this superbly fails now //if (dst.Register == null) //{ /*if (src.Size == 4) * addr = buffer.ReadDword(src.Address - 0x400C00); * else if (src.Size == 2) * addr = (uint)buffer.ReadWord(src.Address - 0x400C00); * else if (src.Size == 1) * addr = (uint)buffer.ReadByte(src.Address - 0x400C00);*/ //} dst.SetValue(src.GetValue()); break; } case "movsb": WriteByteToMemory(Edi.Value, ReadByteFromMemory(Esi.Value)); Ecx.Value--; if (EFlags.HasFlag(EFlags.DirectionFlag)) { Edi.Value--; Esi.Value--; } else { Edi.Value++; Esi.Value++; } break; case "movsw": WriteWordToMemory(Edi.Value, ReadWordFromMemory(Esi.Value)); Ecx.Value--; if (EFlags.HasFlag(EFlags.DirectionFlag)) { Edi.Value -= 2; Esi.Value -= 2; } else { Edi.Value += 2; Esi.Value += 2; } break; case "movsd": WriteDwordToMemory(Edi.Value, ReadDwordFromMemory(Esi.Value)); Ecx.Value--; if (EFlags.HasFlag(EFlags.DirectionFlag)) { Edi.Value -= 4; Esi.Value -= 4; } else { Edi.Value += 4; Esi.Value += 4; } break; case "stosb": WriteByteToMemory(Edi.Value, Eax.Al); Ecx.Value--; if (EFlags.HasFlag(EFlags.DirectionFlag)) { Edi.Value--; Esi.Value--; } else { Edi.Value++; Esi.Value++; } break; case "stosw": WriteWordToMemory(Edi.Value, Eax.Ax); Ecx.Value--; if (EFlags.HasFlag(EFlags.DirectionFlag)) { Edi.Value -= 2; Esi.Value -= 2; } else { Edi.Value += 2; Esi.Value += 2; } break; case "stosd": WriteDwordToMemory(Edi.Value, Eax.Value); Ecx.Value--; if (EFlags.HasFlag(EFlags.DirectionFlag)) { Edi.Value -= 4; Esi.Value -= 4; } else { Edi.Value += 4; Esi.Value += 4; } break; case "xchg": if (parametersList.Length != 2 || dst.Type != ArgumentType.Register || src.Type == ArgumentType.Immediate || src.Size != dst.Size) { break; } uint tmp = src.GetValue(); src.SetValue(dst.GetValue()); dst.SetValue(tmp); break; case "lea": if (parametersList.Length == 2 && dst.Type == ArgumentType.Register && src.Type == ArgumentType.Memory && src.Size > 1) { dst.SetValue(src.Address); } break; #endregion #region Basic maths case "inc": if (parametersList.Length == 1 && dst.Type != ArgumentType.Immediate) { ulong val = (ulong)dst.GetValue() + 1; UpdateFlags(val, dst.Size, EFlags.OverflowFlag | EFlags.SignFlag | EFlags.ZeroFlag | EFlags.AdjustFlag | EFlags.ParityFlag); dst.SetValue((uint)val); } break; case "dec": if (parametersList.Length == 1 && dst.Type != ArgumentType.Immediate) { ulong val = (ulong)dst.GetValue() - 1; UpdateFlags(val, dst.Size, EFlags.OverflowFlag | EFlags.SignFlag | EFlags.ZeroFlag | EFlags.AdjustFlag | EFlags.ParityFlag); dst.SetValue((uint)val); } break; case "not": if (parametersList.Length == 1 && dst.Type != ArgumentType.Immediate) { dst.SetValue(~dst.GetValue()); } break; case "neg": if (parametersList.Length == 1 && dst.Type != ArgumentType.Immediate) { ulong val = (ulong)(-(long)dst.GetValue()); UpdateFlags(val, dst.Size, EFlags.OverflowFlag | EFlags.SignFlag | EFlags.ZeroFlag | EFlags.AdjustFlag | EFlags.ParityFlag | EFlags.CarryFlag); dst.SetValue((uint)val); } break; case "bswap": if (parametersList.Length != 1 || dst.Type != ArgumentType.Register || dst.Size != 4) { break; } uint dval = dst.GetValue(); dst.SetValue((uint)((dval << 24) | ((dval & 0xFF00) << 8) | ((dval & 0xFF0000) >> 8) | (dval >> 24))); break; case "add": if (parametersList.Length == 2) { ulong val = (ulong)dst.GetValue() + src.GetValue(); UpdateFlags(val, dst.Size, EFlags.OverflowFlag | EFlags.SignFlag | EFlags.ZeroFlag | EFlags.AdjustFlag | EFlags.ParityFlag | EFlags.CarryFlag); dst.SetValue((uint)val); } break; case "sub": if (parametersList.Length == 2) { ulong val = (ulong)dst.GetValue() - (ulong)src.GetValue(); UpdateFlags(val, dst.Size, EFlags.OverflowFlag | EFlags.SignFlag | EFlags.ZeroFlag | EFlags.AdjustFlag | EFlags.ParityFlag | EFlags.CarryFlag); dst.SetValue((uint)val); } break; case "mul": // unsigned multiply // The OF and CF flags are set to 0 if the upper half of the result is 0, otherwise they are set to 1 if (parametersList.Length != 1 || src.Type == ArgumentType.Immediate) { break; } switch (src.Size) { case 1: ushort r16 = (ushort)(Eax.Al * src.GetValue()); Eax.Ax = r16; ToggleFlagIf(EFlags.OverflowFlag | EFlags.CarryFlag, (r16 >> 8) == 0); break; case 2: uint r32 = Eax.Ax * src.GetValue(); Edx.Dx = (ushort)(r32 >> 16); // high order Eax.Ax = (ushort)(r32 & 0xFFFF); // low order ToggleFlagIf(EFlags.OverflowFlag | EFlags.CarryFlag, Edx.Dx == 0); break; case 4: ulong r64 = Eax.Ax * src.GetValue(); Edx.Value = (uint)(r64 >> 32); // high order Eax.Value = (uint)(r64 & 0xFFFFFFFF); // low order ToggleFlagIf(EFlags.OverflowFlag | EFlags.CarryFlag, Edx.Value == 0); break; } break; case "div": if (src.Type == ArgumentType.Immediate) { break; } ulong dividend, quotient; uint divisor = src.GetValue(); if (divisor == 0) { break; } if (src.Size == 1) { dividend = Eax.Ax; quotient = dividend / divisor; if (quotient > 0xFF) { break; } Eax.Al = (byte)quotient; Eax.Ah = (byte)(dividend % divisor); } else if (src.Size == 2) { dividend = ((uint)Edx.Dx << 16) & Eax.Ax; quotient = dividend / divisor; if (quotient > 0xFFFF) { break; } Eax.Ax = (ushort)quotient; Edx.Dx = (ushort)(dividend % divisor); } else if (src.Size == 4) { dividend = ((ulong)Edx.Value << 32) & Eax.Value; quotient = dividend / divisor; if (quotient > 0xFFFFFFFF) { break; } Eax.Value = (uint)quotient; Edx.Value = (uint)(dividend % divisor); } break; case "imul": // Signed multiply case "idiv": // Signed division break; // NYI #endregion #region Bitwise operators case "and": if (parametersList.Length == 2) { uint result = dst.GetValue() & src.GetValue(); dst.SetValue(result); ClearFlags(EFlags.OverflowFlag | EFlags.CarryFlag); UpdateFlags(result, dst.Size, EFlags.SignFlag | EFlags.ZeroFlag | EFlags.ParityFlag); } break; case "or": if (parametersList.Length == 2) { uint result = dst.GetValue() | src.GetValue(); dst.SetValue(result); ClearFlags(EFlags.OverflowFlag | EFlags.CarryFlag); UpdateFlags(result, dst.Size, EFlags.SignFlag | EFlags.ZeroFlag | EFlags.ParityFlag); } else { throw new ArgumentException(); } break; case "xor": if (parametersList.Length == 2) { uint result = dst.GetValue() ^ src.GetValue(); dst.SetValue(result); ClearFlags(EFlags.OverflowFlag | EFlags.CarryFlag); UpdateFlags(result, dst.Size, EFlags.SignFlag | EFlags.ZeroFlag | EFlags.ParityFlag); } break; case "stc": // set carry flag SetFlags(EFlags.CarryFlag); break; case "std": // set direction flag SetFlags(EFlags.DirectionFlag); break; case "clc": // clear carry flag ClearFlags(EFlags.CarryFlag); break; case "cld": // clear direction flag ClearFlags(EFlags.DirectionFlag); break; case "shr": // shift right { if (parametersList.Length != 2 || dst.Type == ArgumentType.Immediate || src.Type == ArgumentType.Memory || (src.Type == ArgumentType.Register && src.RegisterName != "cl")) { break; } uint result = dst.GetValue() >> (byte)src.GetValue(); dst.SetValue(result); if (src.Type == ArgumentType.Immediate && src.GetValue() == 1) { UpdateFlags(result, dst.Size, EFlags.OverflowFlag | EFlags.SignFlag | EFlags.ZeroFlag | EFlags.ParityFlag | EFlags.CarryFlag); } else { UpdateFlags(result, dst.Size, EFlags.SignFlag | EFlags.ZeroFlag | EFlags.ParityFlag | EFlags.CarryFlag); } break; } case "shl": // shift left case "sal": // shift arithmetic left (signed) { if (parametersList.Length != 2 || dst.Type == ArgumentType.Immediate || src.Type == ArgumentType.Memory || (src.Type == ArgumentType.Register && src.RegisterName != "cl")) { break; } ulong result = (ulong)dst.GetValue() << (byte)src.GetValue(); dst.SetValue((uint)result); if (src.Type == ArgumentType.Immediate && src.GetValue() == 1) { UpdateFlags(result, dst.Size, EFlags.OverflowFlag | EFlags.SignFlag | EFlags.ZeroFlag | EFlags.ParityFlag | EFlags.CarryFlag); } else { UpdateFlags(result, dst.Size, EFlags.SignFlag | EFlags.ZeroFlag | EFlags.ParityFlag | EFlags.CarryFlag); } break; } case "sar": // shift arithmetic right (signed) { if (parametersList.Length != 2 || dst.Type == ArgumentType.Immediate || src.Type == ArgumentType.Memory || (src.Type == ArgumentType.Register && src.RegisterName != "cl")) { break; } uint result = (uint)((int)dst.GetValue() >> (byte)src.GetValue()); dst.SetValue(result); if (src.Type == ArgumentType.Immediate && src.GetValue() == 1) { UpdateFlags(result, dst.Size, EFlags.OverflowFlag | EFlags.SignFlag | EFlags.ZeroFlag | EFlags.ParityFlag | EFlags.CarryFlag); } else { UpdateFlags(result, dst.Size, EFlags.SignFlag | EFlags.ZeroFlag | EFlags.ParityFlag | EFlags.CarryFlag); } break; } case "ror": // rotate right { // bits >> n | (bits << (32 - n)); uint data = dst.GetValue(); uint bitsToShift = src.GetValue(); data = data >> (int)bitsToShift | (data << (32 - (int)bitsToShift)); dst.SetValue(data); if (src.Type == ArgumentType.Immediate && src.GetValue() == 1) { UpdateFlags(data, dst.Size, EFlags.OverflowFlag | EFlags.CarryFlag); } else { UpdateFlags(data, dst.Size, EFlags.CarryFlag); } break; } case "rol": // rotate left { // bits << n | (bits >> (32 - n)); uint data2 = dst.GetValue(); uint bitsToShift2 = src.GetValue(); uint data = data2 << (int)bitsToShift2 | (data2 >> (32 - (int)bitsToShift2)); dst.SetValue(data); if (src.Type == ArgumentType.Immediate && src.GetValue() == 1) { UpdateFlags(data, dst.Size, EFlags.OverflowFlag | EFlags.CarryFlag); } else { UpdateFlags(data, dst.Size, EFlags.CarryFlag); } break; } #endregion case "call": // TODO Use the stack to keep s and r (saved registers (0) and jumpback offset (+4)) // TODO Half done. (see below) var offset = (int)disasm.Instruction.AddrValue - buffer.Ptr.ToInt32(); CallOffsets.Add((uint)offset); if (followCalls) { Push(offset + 5); // Push the return address on the stack JumpBacks.Add((uint)(disasm.EIP.ToInt32() + 5)); disasm.EIP = new IntPtr((int)disasm.Instruction.AddrValue); return(true); } return(false); case "cmp": UpdateFlags((ulong)dst.GetValue() - (ulong)src.GetValue(), dst.Size, EFlags.OverflowFlag | EFlags.SignFlag | EFlags.ZeroFlag | EFlags.AdjustFlag | EFlags.ParityFlag | EFlags.CarryFlag); break; case "test": ClearFlags(EFlags.OverflowFlag | EFlags.CarryFlag); UpdateFlags(dst.GetValue() & src.GetValue(), dst.Size, EFlags.SignFlag | EFlags.ZeroFlag | EFlags.ParityFlag); break; case "sbb": if (parametersList.Length != 2) { break; } ulong newValue = (ulong)dst.GetValue() - (ulong)src.GetValue(); if (EFlags.HasFlag(EFlags.CarryFlag)) { newValue -= 1; } dst.SetValue((uint)newValue); UpdateFlags(newValue, dst.Size, EFlags.OverflowFlag | EFlags.SignFlag | EFlags.ZeroFlag | EFlags.AdjustFlag | EFlags.CarryFlag); break; #region Stack operations case "push": // todo: check for stack overflow (stack pointer < base address) if (parametersList.Length == 1) { uint s = dst.Size; if (s == 2 || s == 4) { WriteMemory(Esp - s, dst.GetValue()); Esp.Value -= s; } } break; case "pop": // todo: check for stack overflow (stack pointer > base address + memory size) if (parametersList.Length == 1 && dst.Type != ArgumentType.Immediate) { uint s = dst.Size; if (s == 2 || s == 4) { dst.SetValue(ReadMemory(Esp, s)); Esp.Value += s; } } break; case "pusha": if (parametersList.Length == 0) { WriteMemory(Esp - 2, Eax.Ax); WriteMemory(Esp - 4, Ecx.Cx); WriteMemory(Esp - 6, Edx.Dx); WriteMemory(Esp - 8, Ebx.Bx); WriteMemory(Esp - 10, Esp.Sp); WriteMemory(Esp - 12, Ebp.Bp); WriteMemory(Esp - 14, Esi.Si); WriteMemory(Esp - 16, Edi.Di); Esp.Value -= 16; } break; case "pushad": if (parametersList.Length == 0) { WriteMemory(Esp - 4, Eax.Value); WriteMemory(Esp - 8, Ecx.Value); WriteMemory(Esp - 12, Edx.Value); WriteMemory(Esp - 16, Ebx.Value); WriteMemory(Esp - 20, Esp.Value); WriteMemory(Esp - 24, Ebp.Value); WriteMemory(Esp - 28, Esi.Value); WriteMemory(Esp - 32, Edi.Value); Esp.Value -= 32; } break; case "popa": if (parametersList.Length == 0) { Edi.Di = ReadWordFromMemory(Esp); Esi.Si = ReadWordFromMemory(Esp + 2); Ebp.Bp = ReadWordFromMemory(Esp + 4); //Esp.Sp = ReadWord(Esp + 6); // ignored Ebx.Bx = ReadWordFromMemory(Esp + 8); Edx.Dx = ReadWordFromMemory(Esp + 10); Ecx.Cx = ReadWordFromMemory(Esp + 12); Eax.Ax = ReadWordFromMemory(Esp + 14); Esp.Value += 16; } else { throw new ArgumentException(); } break; case "popad": if (parametersList.Length == 0) { Edi.Value = ReadDwordFromMemory(Esp); Esi.Value = ReadDwordFromMemory(Esp + 4); Ebp.Value = ReadDwordFromMemory(Esp + 8); //Esp.Value = ReadDoubleword(Esp + 12); // ignored Ebx.Value = ReadDwordFromMemory(Esp + 16); Edx.Value = ReadDwordFromMemory(Esp + 20); Ecx.Value = ReadDwordFromMemory(Esp + 24); Eax.Value = ReadDwordFromMemory(Esp + 28); Esp.Value += 32; } break; // todo: pushf and popf, and effects on eflags #endregion } } return(false); }
public X86PUSH(Disasm rawInstruction) : base() { Operands = new IX86Operand[1]; Operands[0] = GetOperand(rawInstruction.Argument1); }
/// <summary> /// Initializes a new instance of the OnyxDetour class. /// </summary> public OnyxDetour(IntPtr _targetAddress, Delegate _detour, string _detourName = null) { if (_detourName != null) { m_name = _detourName; } if (_targetAddress == IntPtr.Zero) { throw new ArgumentNullException("_targetAddress"); } if (_detour == null) { throw new ArgumentNullException("_detour"); } m_detour = _detour; m_targetAddress = _targetAddress; IntPtr detourAddress = Marshal.GetFunctionPointerForDelegate(_detour); m_checkThread = CheckThread; var pCheckThread = Marshal.GetFunctionPointerForDelegate(m_checkThread); var fasm = new RemoteFasm(); fasm.Clear(); fasm.AddLine("@checkthread:"); fasm.AddLine("call $+5"); fasm.AddLine("add dword [esp], {0}", 5 + 4 + 1); fasm.AddLine("push 0{0:X}h", pCheckThread.ToInt64()); fasm.AddLine("retn"); fasm.AddLine("@checkthread_TestResults:"); fasm.AddLine("test eax,eax"); fasm.AddLine("jz @functionretn"); fasm.AddLine("@userfunction:"); fasm.AddLine("push 0{0:X}h", detourAddress.ToInt64()); fasm.AddLine("retn"); fasm.AddLine("@functionretn:"); var jumperBytes = fasm.Assemble(); pJumperCodeCave = Onyx.Instance.Memory.AllocateMemory(256); Onyx.Instance.Memory.WriteBytes(pJumperCodeCave, jumperBytes); fasm.Clear(); fasm.AddLine("push 0{0:X}h", pJumperCodeCave.ToInt64()); fasm.AddLine("retn"); m_detourBytes = fasm.Assemble(); disasm = new Disasm(); var realEip = m_targetAddress; var bytesDisassembled = 0; while (bytesDisassembled < m_detourBytes.Length) { var managedInstructionBuffer = Onyx.Instance.Memory.ReadBytes(realEip, 15); var instructionBuffer = new UnmanagedBuffer(managedInstructionBuffer); disasm.EIP = instructionBuffer.Ptr; var length = BeaEngine32.Disasm(disasm); if ((length != (int)BeaConstants.SpecialInfo.OUT_OF_BLOCK) && (length != (int)BeaConstants.SpecialInfo.UNKNOWN_OPCODE)) { bytesDisassembled += length; if ((disasm.Instruction.BranchType == (int)BeaConstants.BranchType.JmpType) && (disasm.Instruction.AddrValue != 0)) { // jmp = modify EIP //disasm.EIP = (IntPtr)disasm.Instruction.AddrValue; } realEip = (IntPtr)((ulong)realEip + (ulong)length); } else { throw new Exception(String.Format("Disassembly error occured, exception code = {0}", length)); } } //Store the orginal bytes of decoded instructions in memory after jumper code m_originalBytes = Onyx.Instance.Memory.ReadBytes(m_targetAddress, bytesDisassembled); var pOriginalFunction = pJumperCodeCave.Add((UInt32)jumperBytes.Length); Onyx.Instance.Memory.WriteBytes(pOriginalFunction, m_originalBytes); m_originalFunction = Marshal.GetDelegateForFunctionPointer(pOriginalFunction, _detour.GetType()); var pReturnerCodeCave = pJumperCodeCave.Add((UInt32)jumperBytes.Length + (UInt32)bytesDisassembled); fasm.Clear(); fasm.AddLine("push 0{0:X}h", m_targetAddress.Add((UInt32)bytesDisassembled).ToInt64()); fasm.AddLine("retn"); var returnerBytes = fasm.Assemble(); Onyx.Instance.Memory.WriteBytes(pReturnerCodeCave, returnerBytes); // adding calling thread to exclusions Onyx.Instance.Detours.GlobalExcludedThreadId.Add(OnyxNative.GetCurrentThreadId()); }
/// <summary> /// Disassemble a given piece of shellcode. /// </summary> /// <param name="disasmBytes">The byte array to disassemble</param> /// <param name="architecture">The architecture to target. Either 32 or 64 bit Windows</param> /// <param name="disasmBox">The listbox to place the disassembly</param> /// <param name="showOffsets">Boolean to determine whether or not to display address offsets in the disassembly listing.</param> public void disassembleSC(byte[] disasmBytes, uint architecture, System.Windows.Forms.RichTextBox disasmBox, bool showOffsets) { var disasm = new Disasm(); disasm.Options = 0x200;//display in NASM syntax if (architecture == 32) { disasm.Archi = 32; } else if (architecture == 64) { disasm.Archi = 64; } int size = disasmBytes.Length; IntPtr executionPointer = System.Runtime.InteropServices.Marshal.AllocHGlobal(size); System.Runtime.InteropServices.Marshal.Copy(disasmBytes, 0, executionPointer, size); disasm.EIP = new IntPtr(executionPointer.ToInt64()); int result; var disasmPtr = Marshal.AllocHGlobal(Marshal.SizeOf(disasm)); disasmBox.AppendText("Disassembled shellcode with " + architecture + "bit\n"); var EIPrange = (executionPointer.ToInt64() + size / 2); try { while (disasm.EIP.ToInt64() < EIPrange) { System.Runtime.InteropServices.Marshal.StructureToPtr(disasm, disasmPtr, false); result = BeaEngine.Disasm(disasmPtr); Marshal.PtrToStructure(disasmPtr, disasm); if (result == (int)BeaConstants.SpecialInfo.UNKNOWN_OPCODE) { disasmBox.AppendText("Unknown opcode error @ " + disasm.EIP.ToString("X") + "\n"); break; } if (showOffsets) { disasmBox.AppendText(disasm.EIP.ToString("X") + "h : " + disasm.CompleteInstr.ToString() + "\n"); } else { disasmBox.AppendText(disasm.CompleteInstr.ToString() + "\n"); } if (disasm.Instruction.Opcode.ToString("X") == "C3") { break; } disasm.EIP = new IntPtr(disasm.EIP.ToInt64() + result); } } catch { disasmBox.AppendText("Something went wrong with disassembly\n"); } }
public static Instruction[] PeToInstructions(string FilePath) { UnmanagedBuffer buffer = new UnmanagedBuffer(File.ReadAllBytes(FilePath)); List <Instruction> instructs = new List <Instruction>(); Disasm disasm = new Disasm(); disasm.EIP = new IntPtr(buffer.Ptr.ToInt64() + 0x400); List <int> Addresses = new List <int>(); while (true) { int result = Asm.Net.src.BeaEngine.BeaEngine.Disasm(disasm); Addresses.Add(disasm.EIP.ToInt32()); if (result == (int)BeaConstants.SpecialInfo.UNKNOWN_OPCODE) { break; } //Console.WriteLine("0x" + disasm.EIP.ToString("X") + " " + disasm.CompleteInstr); //convert the data to instructions so we are able to execute it in Asm.Net //We also need to change the pointers for push, call, inc, dec etc... so Asm.Net is able to understand it switch (disasm.Instruction.Opcode) { case (int)OpcodeList.CALL: { string tmp = disasm.Argument1.ArgMnemonic.Substring(0, disasm.Argument1.ArgMnemonic.Length - 1).Replace("FFFFFFFF", ""); int Jmpvalue = Convert.ToInt32(tmp, 16); CALL call = new CALL(Jmpvalue); call.NativeVirtualAddress.Address = disasm.EIP.ToInt32(); instructs.Add(call); break; } case (int)OpcodeList.INC_EAX: { INC_EAX IncEax = new INC_EAX(); IncEax.NativeVirtualAddress.Address = disasm.EIP.ToInt32(); instructs.Add(IncEax); break; } case (int)OpcodeList.INC_EDX: { break; } case (int)OpcodeList.JE: { break; } case (int)OpcodeList.JMP: { string tmp = disasm.Argument1.ArgMnemonic.Substring(0, disasm.Argument1.ArgMnemonic.Length - 1); int Jmpvalue = Convert.ToInt32(tmp.Replace("FFFFFFFF", ""), 16); JMP jmp = new JMP(Jmpvalue); jmp.NativeVirtualAddress.Address = disasm.EIP.ToInt32(); //instructs.Add(jmp); break; } case (int)OpcodeList.JNZ: { string tmp = disasm.Argument1.ArgMnemonic.Substring(0, disasm.Argument1.ArgMnemonic.Length - 1); int Jmpvalue = Convert.ToInt32(tmp.Replace("FFFFFFFF", ""), 16); JNZ jnz = new JNZ(Jmpvalue); jnz.NativeVirtualAddress.Address = disasm.EIP.ToInt32(); //instructs.Add(jnz); break; } case (int)OpcodeList.MOV_EAX: { string tmp = disasm.Argument2.ArgMnemonic.Substring(0, disasm.Argument2.ArgMnemonic.Length - 1); int MovValue = Convert.ToInt32(tmp, 16); MOV_EAX MovEAX = new MOV_EAX(new VirtualAddress(0, MovValue)); MovEAX.NativeVirtualAddress.Address = disasm.EIP.ToInt32(); instructs.Add(MovEAX); break; } case (int)OpcodeList.NOP: { NOP nop = new NOP(); nop.NativeVirtualAddress.Address = disasm.EIP.ToInt32(); instructs.Add(nop); break; } case (int)OpcodeList.PUSH_EAX: { break; } case (int)OpcodeList.RET: { RET ret = new RET(); ret.NativeVirtualAddress.Address = disasm.EIP.ToInt32(); instructs.Add(ret); break; } case (int)OpcodeList.ADD: { //need to reverse check the opcodes... Instruction ADD = null; switch (disasm.Argument1.ArgMnemonic) { case "eax": { switch (disasm.Argument2.ArgMnemonic) { case "al": { ADD = new ADD_BYTE_PTR_EAX_AL(); break; } } break; } } if (ADD != null) { ADD.NativeVirtualAddress.Address = disasm.EIP.ToInt32(); instructs.Add(ADD); } break; } case (int)OpcodeList.XOR_REGISTER: { Instruction xor = null; switch (disasm.Argument1.ArgMnemonic) { case "eax": { switch (disasm.Argument2.ArgMnemonic) { case "eax": { xor = new XOR_EAX_EAX(); break; } case "ecx": { xor = new XOR_EAX_ECX(); break; } case "edx": { xor = new XOR_EAX_EDX(); break; } case "ebx": { xor = new XOR_EAX_EBX(); break; } case "esp": { xor = new XOR_EAX_ESP(); break; } case "ebp": { xor = new XOR_EAX_EBP(); break; } case "esi": { xor = new XOR_EAX_ESI(); break; } case "edi": { xor = new XOR_EAX_EDI(); break; } } break; } case "ecx": { switch (disasm.Argument2.ArgMnemonic) { case "eax": { xor = new XOR_ECX_EAX(); break; } case "ecx": { xor = new XOR_ECX_ECX(); break; } case "edx": { xor = new XOR_ECX_EDX(); break; } case "ebx": { xor = new XOR_ECX_EBX(); break; } case "esp": { xor = new XOR_ECX_ESP(); break; } case "ebp": { xor = new XOR_ECX_EBP(); break; } case "esi": { xor = new XOR_ECX_ESI(); break; } case "edi": { xor = new XOR_ECX_EDI(); break; } } break; } case "edx": { switch (disasm.Argument2.ArgMnemonic) { case "eax": { xor = new XOR_EDX_EAX(); break; } case "ecx": { xor = new XOR_EDX_ECX(); break; } case "edx": { xor = new XOR_EDX_EDX(); break; } case "ebx": { xor = new XOR_EDX_EBX(); break; } case "esp": { xor = new XOR_EDX_ESP(); break; } case "ebp": { xor = new XOR_EDX_EBP(); break; } case "esi": { xor = new XOR_EDX_ESI(); break; } case "edi": { xor = new XOR_EDX_EDI(); break; } } break; } case "ebx": { switch (disasm.Argument2.ArgMnemonic) { case "eax": { xor = new XOR_EBX_EAX(); break; } case "ecx": { xor = new XOR_EBX_ECX(); break; } case "edx": { xor = new XOR_EBX_EDX(); break; } case "ebx": { xor = new XOR_EBX_EBX(); break; } case "esp": { xor = new XOR_EBX_ESP(); break; } case "ebp": { xor = new XOR_EBX_EBP(); break; } case "esi": { xor = new XOR_EBX_ESI(); break; } case "edi": { xor = new XOR_EBX_EDI(); break; } } break; } case "esp": { switch (disasm.Argument2.ArgMnemonic) { case "eax": { xor = new XOR_ESP_EAX(); break; } case "ecx": { xor = new XOR_ESP_ECX(); break; } case "edx": { xor = new XOR_ESP_EDX(); break; } case "ebx": { xor = new XOR_ESP_EBX(); break; } case "esp": { xor = new XOR_ESP_ESP(); break; } case "ebp": { xor = new XOR_ESP_EBP(); break; } case "esi": { xor = new XOR_ESP_ESI(); break; } case "edi": { xor = new XOR_ESP_EDI(); break; } } break; } case "ebp": { switch (disasm.Argument2.ArgMnemonic) { case "eax": { xor = new XOR_EBP_EAX(); break; } case "ecx": { xor = new XOR_EBP_ECX(); break; } case "edx": { xor = new XOR_EBP_EDX(); break; } case "ebx": { xor = new XOR_EBP_EBX(); break; } case "esp": { xor = new XOR_EBP_ESP(); break; } case "ebp": { xor = new XOR_EBP_EBP(); break; } case "esi": { xor = new XOR_EBP_ESI(); break; } case "edi": { xor = new XOR_EBP_EDI(); break; } } break; } case "esi": { switch (disasm.Argument2.ArgMnemonic) { case "eax": { xor = new XOR_ESI_EAX(); break; } case "ecx": { xor = new XOR_ESI_ECX(); break; } case "edx": { xor = new XOR_ESI_EDX(); break; } case "ebx": { xor = new XOR_ESI_EBX(); break; } case "esp": { xor = new XOR_ESI_ESP(); break; } case "ebp": { xor = new XOR_ESI_EBP(); break; } case "esi": { xor = new XOR_ESI_ESI(); break; } case "edi": { xor = new XOR_ESI_EDI(); break; } } break; } case "edi": { switch (disasm.Argument2.ArgMnemonic) { case "eax": { xor = new XOR_EDI_EAX(); break; } case "ecx": { xor = new XOR_EDI_ECX(); break; } case "edx": { xor = new XOR_EDI_EDX(); break; } case "ebx": { xor = new XOR_EDI_EBX(); break; } case "esp": { xor = new XOR_EDI_ESP(); break; } case "ebp": { xor = new XOR_EDI_EBP(); break; } case "esi": { xor = new XOR_EDI_ESI(); break; } case "edi": { xor = new XOR_EDI_EDI(); break; } } break; } } if (xor != null) //this check is just for temp, not all the XOR instructions are added { xor.NativeVirtualAddress.Address = disasm.EIP.ToInt32(); instructs.Add(xor); } break; } } disasm.EIP = new IntPtr(disasm.EIP.ToInt64() + result); } //set all the pointers correct int offset = Options.MemoryBaseAddress; foreach (Instruction instruction in instructs) { switch (instruction.ToByteArray()[0]) { case (int)OpcodeList.CALL: { break; } case (int)OpcodeList.INC_EAX: { break; } case (int)OpcodeList.INC_EDX: { break; } case (int)OpcodeList.JE: { break; } case (int)OpcodeList.JMP: { //lets set our new jmp pointer, We also should load the modules which are required to run this program //We need to load the Import Table and get all the .dll's from it and getting all the instructions from it bool NewSet = false; foreach (Instruction instruct in instructs) { if (Addresses.Contains(((IJump)instruction).JumpAddress)) { //Set the ASM.net pointer int index = Addresses.IndexOf(((IJump)instruction).JumpAddress) - 1; } //if (((IJump)instruction).JumpAddress == instruct.NativeVirtualAddress.Address) //{ //} } //if (!NewSet) // throw new Exception("Unable to find the JMP Pointer, Invalid memory address ?"); break; } case (int)OpcodeList.MOV_EAX: { break; } case (int)OpcodeList.NOP: { break; } case (int)OpcodeList.PUSH_EAX: { break; } case (int)OpcodeList.RET: { break; } } instruction.VirtualAddress.Address = offset; offset += instruction.VirtualAddress.Size; } return(instructs.ToArray()); }