public byte[] Assemble(Operand op1, out bool fullyAssembled, Shellcode shellcode) { byte[] res_opcode = Opcode; byte[] res_ModRegRM = new byte[0]; byte[] res_end = new byte[0]; fullyAssembled = true; if (op1.Imm) { UInt64 imm = op1.GetValue(out fullyAssembled, shellcode); if (shellcode.IsWin64) { res_end = res_end.Concat(MemoryFunctions.ToByteArray(imm)).ToArray(); } else { res_end = res_end.Concat(MemoryFunctions.ToByteArray((UInt32)imm)).ToArray(); } } else if (op1.Reg && Plusr) { // Add register code to the last byte of the opcode and return res_opcode[res_opcode.Length - 1] = (byte)(res_opcode[res_opcode.Length - 1] + (byte)AssemblyDefines.Registers[op1.GetRegisterName()]); } else { fullyAssembled = false; throw new Exception("Opcode Assembler Error: Failed to assemble instruction with opcode " + MemoryFunctions.ByteArrayToString(Opcode)); } return res_opcode.Concat(res_ModRegRM).Concat(res_end).ToArray(); }
public byte[] Assemble(Operand op1, Operand op2, out bool fullyAssembled, Shellcode shellcode) { // Double-operand assembler byte[] res_opcode = Opcode; byte[] res_ModRegRM = new byte[0]; byte[] res_end = new byte[0]; fullyAssembled = true; if (op1.Imm) { UInt64 imm = op1.GetValue(out fullyAssembled, shellcode); if (shellcode.IsWin64) { res_end = res_end.Concat(MemoryFunctions.ToByteArray(imm)).ToArray(); } else { res_end = res_end.Concat(MemoryFunctions.ToByteArray((UInt32)imm)).ToArray(); } } else if (op1.Reg && Plusr) { // Add register code to the last byte of the opcode and return res_opcode[res_opcode.Length - 1] = (byte)(res_opcode[res_opcode.Length - 1] + (byte)AssemblyDefines.Registers[op1.GetRegisterName()]); } else if (op1.Reg && ModRegRM == byte.MaxValue) { // Add register code to the start of the res_reg stream in ModRegRM format if (res_ModRegRM.Length == 0) { byte mod = 0x3; byte reg1 = (byte)AssemblyDefines.Registers[op1.GetRegisterName()]; res_ModRegRM = new byte[1] { (byte)((byte)(mod << 7) + (byte)(reg1 << 3)) }; } } else { fullyAssembled = false; throw new Exception("Opcode Assembler Error: Failed to assemble instruction during processing of first operand with opcode " + MemoryFunctions.ByteArrayToString(Opcode)); } if (op2.Imm) { bool partFullyAssembled = true; UInt64 imm = op2.GetValue(out partFullyAssembled, shellcode); if (!partFullyAssembled) fullyAssembled = false; if (shellcode.IsWin64) { res_end = res_end.Concat(MemoryFunctions.ToByteArray(imm)).ToArray(); } else { res_end = res_end.Concat(MemoryFunctions.ToByteArray((UInt32)imm)).ToArray(); } } else if (op2.Reg && Plusr) { // Add register code to the last byte of the opcode and return res_opcode[res_opcode.Length - 1] = (byte)(res_opcode[res_opcode.Length - 1] + (byte)AssemblyDefines.Registers[op1.GetRegisterName()]); } else if (op1.Reg && ModRegRM == byte.MaxValue) { // Add register code to the start of the res_reg stream in ModRegRM format if (res_ModRegRM.Length == 1) { res_ModRegRM[0] |= (byte)AssemblyDefines.Registers[op1.GetRegisterName()]; } } else { fullyAssembled = false; throw new Exception("Opcode Assembler Error: Failed to assemble instruction during processing of second operand with opcode " + MemoryFunctions.ByteArrayToString(Opcode)); } return res_opcode.Concat(res_ModRegRM).Concat(res_end).ToArray(); }
public OpcodeDescriptor(string mnem, Operand op1, Operand op2) { Mnem = mnem; HasOperand1 = true; Deref1 = op1.Deref; Imm1 = op1.Imm; HasOperand2 = true; Deref2 = op2.Deref; Imm2 = op2.Imm; }