private x86OpCode RetrieveNextOpCode() { x86OpCode returnOpCode = x86OpCode.Create(x86OpCodes.Unknown); byte opcodeByte = reader.ReadByte(); returnOpCode.opcodebytes = new byte[] { opcodeByte }; x86OpCode[] matchingOpcodes = MatchWithOpCodes(opcodeByte); // if there is one match, set the returning opcode to that match. If not, then it's an instruction // from an opcode group, and select it by checking the next byte. if (matchingOpcodes.Length == 1) { returnOpCode = x86OpCode.Create(matchingOpcodes[0]); } else if (matchingOpcodes.Length > 1) { x86OpCode selected = SelectOpCodeFromToken(matchingOpcodes, reader.ReadByte()); if (selected != null) { returnOpCode = selected; } if (selected == null || selected.variableByteIndex > -1) { reader.BaseStream.Seek(-1, SeekOrigin.Current); } } return(returnOpCode); }
private void ProcessVariableByteIndex(ref x86OpCode opcode) { if (opcode.variableByteIndex >= 0) { opcode.opcodebytes[opcode.variableByteIndex] = reader.ReadByte(); } }
private byte[] ReadRawOperand(x86OpCode opcode) { switch (opcode.GetNormalOperandType()) { case x86OperandType.Byte: case x86OperandType.ShortInstructionAddress: return(new byte[] { reader.ReadByte() }); case x86OperandType.Dword: case x86OperandType.InstructionAddress: return(reader.ReadBytes(sizeof(int))); case x86OperandType.Fword: return(reader.ReadBytes(6)); case x86OperandType.Word: return(reader.ReadBytes(sizeof(ushort))); case x86OperandType.WordAndByte: return(reader.ReadBytes(sizeof(ushort) + sizeof(byte))); case x86OperandType.Qword: return(reader.ReadBytes(sizeof(ulong))); case x86OperandType.Multiple32Register: case x86OperandType.Multiple16Register: case x86OperandType.Multiple32Or8Register: case x86OperandType.Register32: case x86OperandType.RegisterLeaRegister: break; } return(null); }
public static Myx86Instruction Create(x86OpCode opcode, Opnd operand1, Opnd operand2) { Myx86Instruction newInstruction = new Myx86Instruction(); newInstruction.OpCode = opcode; newInstruction.operand1 = operand1; newInstruction.operand2 = operand2; newInstruction.GenerateBytes(); return newInstruction; }
/// <summary> /// Creates an instance of a x86 instruction with two operands. /// </summary> /// <param name="assembly">The parent assembly.</param> /// <param name="opcode">The opcode to use.</param> /// <param name="operand1">The first operand to use.</param> /// <param name="operand2">The second operand to use.</param> /// <returns></returns> public static x86Instruction Create(x86OpCode opcode, Operand operand1, Operand operand2) { x86Instruction newInstruction = new x86Instruction(); newInstruction.OpCode = opcode; newInstruction.operand1 = operand1; newInstruction.operand2 = operand2; newInstruction.GenerateBytes(); return(newInstruction); }
internal static x86OpCode Create(x86OpCode code) { // copies an opcode. we don't want to change the opcode bytes of the list. x86OpCode newCode = new x86OpCode(); newCode.name = code.name; newCode.originalbytes = code.originalbytes; newCode.opcodebytes = code.opcodebytes; newCode.operandtype = code.operandtype; newCode.operandlength = code.operandlength; newCode.variableByteIndex = code.variableByteIndex; return(newCode); }
private void DecodeDoubleRegisters(ref x86Instruction instruction, byte registersToken) { x86Instruction result = instruction; x86OpCode resultopcode = instruction.OpCode; if (resultopcode.variableByteIndex == -1) { return; } resultopcode.opcodebytes[instruction.OpCode.variableByteIndex] = registersToken; result.OpCode = resultopcode; // lea instructions has got different notations. bool isLEA = instruction.OpCode.IsBasedOn(x86OpCodes.Lea); x86Register register1; x86Register register2; DecodeRegisterPair(instruction, registersToken, out register1, out register2); // one register is a dword pointer if (registersToken <= 0x3F) { instruction.operand1 = new Operand(register1, OperandType.DwordPointer); instruction.operand2 = new Operand(register2, OperandType.Normal); } // one register is a dword pointer with an sbyte addition else if (registersToken > 0x3F && registersToken < 0x7F) { instruction.operandbytes = reader.ReadBytes(1); instruction.code.operandlength++; instruction.operand1 = new Operand(register1, isLEA ? OperandType.LeaRegister : OperandType.DwordPointer, ASMGlobals.ByteToSByte(instruction.operandbytes[0])); instruction.operand2 = new Operand(register2, OperandType.Normal); } // one register is a dword pointer with an int32 addition else if (registersToken >= 0x80 && registersToken <= 0xBF) { instruction.operandbytes = reader.ReadBytes(4); instruction.code.operandlength += 4; int addition = BitConverter.ToInt32(instruction.operandbytes, 0); instruction.operand1 = new Operand(register1, isLEA ? OperandType.LeaRegister : OperandType.DwordPointer, addition); instruction.operand2 = new Operand(register2, OperandType.Normal); } // normal multiple registers. else if (registersToken >= 0xC0 && registersToken <= 0xFF) { instruction.operand1 = new Operand(register1, isLEA ? OperandType.LeaRegister : OperandType.Normal); instruction.operand2 = new Operand(register2, OperandType.Normal); } }
/// <summary> /// Returns a boolean value if the current opcode is based on the given opcode. /// </summary> /// <param name="code">The Opcode to compare with.</param> /// <returns></returns> public bool IsBasedOn(x86OpCode code) { return(code.originalbytes == this.originalbytes); }
/// <summary> /// Returns a boolean value if the current opcode is based on the given opcode. /// </summary> /// <param name="code">The Opcode to compare with.</param> /// <returns></returns> public bool IsBasedOn(x86OpCode code) { return code._originalBytes == this._originalBytes; }
/// <summary> /// Creates an instance of a x86 instruction with two operands. /// </summary> /// <param name="assembly">The parent assembly.</param> /// <param name="opcode">The opcode to use.</param> /// <param name="operand1">The first operand to use.</param> /// <param name="operand2">The second operand to use.</param> /// <returns></returns> public static x86Instruction Create(Win32Assembly assembly, x86OpCode opcode, Operand operand1, Operand operand2) { x86Instruction newInstruction = new x86Instruction(assembly); newInstruction.OpCode = opcode; newInstruction.operand1 = operand1; newInstruction.operand2 = operand2; newInstruction.GenerateBytes(); return newInstruction; }
private void ProcessVariableByteIndex(ref x86OpCode opcode) { if (opcode.variableByteIndex >= 0) { opcode.opcodebytes[opcode.variableByteIndex] = image.ReadByte(); } }
/// <summary> /// Creates an instance of a x86 instruction without an operand. /// </summary> /// <param name="assembly">The parent assembly.</param> /// <param name="opcode">The opcode to use.</param> /// <returns></returns> public static x86Instruction Create(Win32Assembly assembly, x86OpCode opcode) { return Create(assembly, opcode, null, null); }
/// <summary> /// Creates an instance of a x86 instruction with a single operand. /// </summary> /// <param name="assembly">The parent assembly.</param> /// <param name="opcode">The opcode to use.</param> /// <param name="operand">The operand to use.</param> /// <returns></returns> public static x86Instruction Create(Win32Assembly assembly, x86OpCode opcode, Operand operand) { return Create(assembly, opcode, operand, null); }
/// <summary> /// Creates an instance of a x86 instruction with a single operand. /// </summary> /// <param name="assembly">The parent assembly.</param> /// <param name="opcode">The opcode to use.</param> /// <param name="operand">The operand to use.</param> /// <returns></returns> public static x86Instruction Create(x86OpCode opcode, Operand operand) { return(Create(opcode, operand, null)); }
private byte[] ReadRawOperand(x86OpCode opcode) { switch (opcode.operandtype) { case x86OperandType.Byte: case x86OperandType.ShortInstructionAddress: return new byte[] { image.ReadByte() }; case x86OperandType.Dword: case x86OperandType.DwordPtr: case x86OperandType.InstructionAddress: case x86OperandType.RegisterAndDword: return image.ReadBytes(sizeof(int)) ; case x86OperandType.Fword: case x86OperandType.FwordPtr: return image.ReadBytes(6); case x86OperandType.Word: return image.ReadBytes(sizeof(ushort)); case x86OperandType.WordAndByte: return image.ReadBytes(sizeof(ushort) + sizeof(byte)); case x86OperandType.Qword: return image.ReadBytes(sizeof(ulong)); case x86OperandType.Multiple32Register: case x86OperandType.Multiple16Register: case x86OperandType.Multiple32Or8Register: case x86OperandType.Register: case x86OperandType.RegisterAndByte: case x86OperandType.RegisterLeaRegister: case x86OperandType.RegisterOffset: case x86OperandType.RegisterPointer: break; } return null; }
/// <summary> /// Creates an instance of a x86 instruction with a single operand. /// </summary> /// <param name="assembly">The parent assembly.</param> /// <param name="opcode">The opcode to use.</param> /// <param name="operand">The operand to use.</param> /// <returns></returns> public static x86Instruction Create(x86OpCode opcode, Operand operand) { return Create(opcode, operand, null); }
/// <summary> /// Creates an instance of a x86 instruction without an operand. /// </summary> /// <param name="assembly">The parent assembly.</param> /// <param name="opcode">The opcode to use.</param> /// <returns></returns> public static x86Instruction Create(x86OpCode opcode) { return(Create(opcode, null, null)); }
private void DecodeSingleRegister(ref x86Instruction instruction, byte registerstoken) { x86Instruction result = instruction; x86OpCode resultopcode = instruction.OpCode; resultopcode.opcodebytes[instruction.OpCode.variableByteIndex] = registerstoken; result.OpCode = resultopcode; bool isGroupOpCode = MatchWithOpCodes(instruction.OpCode.opcodebytes[0]).Length > 1; int actualregister = registerstoken % 8; OperandType registerValueType = OperandType.Normal; int addition = 0; if (registerstoken < 0x40) { //normal dword pointer if (!isGroupOpCode && registerstoken >= 0x8) { ProcessInvalidInstruction(ref instruction); return; } registerValueType = OperandType.DwordPointer; } else if (registerstoken >= 0x40 && registerstoken < 0x80) { //dword pointer + sbyte addition if (!isGroupOpCode && registerstoken >= 0x48) { ProcessInvalidInstruction(ref instruction); return; } registerValueType = OperandType.DwordPointer; instruction.operandbytes = new byte[] { reader.ReadByte() }; instruction.OpCode.operandlength = 1; addition = ASMGlobals.ByteToSByte(instruction.operandbytes[0]); } else if (registerstoken >= 0x80 && registerstoken < 0xC0) { //dword pointer + int addition if (!isGroupOpCode && registerstoken >= 0x88) { ProcessInvalidInstruction(ref instruction); return; } registerValueType = OperandType.DwordPointer; instruction.operandbytes = reader.ReadBytes(4); instruction.OpCode.operandlength = 4; addition = BitConverter.ToInt32(instruction.operandbytes, 0); } else if (registerstoken >= 0xC0 && registerstoken <= 0xFF) { // normal register -> do nothing. if (!isGroupOpCode && registerstoken >= 0xC8) { ProcessInvalidInstruction(ref instruction); return; } } else { // TODO: Invalid single register token. } if (instruction.OpCode.operandtype.HasFlag(x86OperandType.Register8)) { actualregister |= (byte)x86Register.Bit8Mask; } instruction.operand1 = new Operand((x86Register)actualregister, registerValueType, addition); }
private x86OpCode SelectOpCodeFromToken(x86OpCode[] matches, byte token) { byte groupIndex = matches[0]._opcodeBytes[0]; byte hByte = (byte)(token >> 4 << 4); byte lByte = (byte)(token - hByte); int index = (int)Math.Floor((double)(token % 0x40) / (double)8.0f); // 0xff group has got more than 8 instructions with some special tokens. if (groupIndex == 0xFF) { // instructions with lowerbyte of 5 or D are an exception. if (lByte == 0x5 || lByte == 0xD) return matches.FirstOrDefault(m => m._opcodeBytes[1] == token); else index *= 2; } if (index < 0 || index >= matches.Length) return null; return matches[index]; }
internal byte[] ReadRawOperand(x86OpCode opcode) { switch (opcode.GetNormalOperandType()) { case x86OperandType.Byte: case x86OperandType.ShortInstructionAddress: return new byte[] { reader.ReadByte() }; case x86OperandType.Dword: case x86OperandType.InstructionAddress: return reader.ReadBytes(sizeof(int)); case x86OperandType.Fword: return reader.ReadBytes(6); case x86OperandType.Word: return reader.ReadBytes(sizeof(ushort)); case x86OperandType.WordAndByte: return reader.ReadBytes(sizeof(ushort) + sizeof(byte)); case x86OperandType.Qword: return reader.ReadBytes(sizeof(ulong)); case x86OperandType.Multiple32Register: case x86OperandType.Multiple16Register: case x86OperandType.Multiple32Or8Register: case x86OperandType.Register32: case x86OperandType.RegisterLeaRegister: break; } return null; }
internal void ProcessVariableByteIndex(ref x86OpCode opcode) { if (opcode._variableByteIndex >= 0) { opcode._opcodeBytes[opcode._variableByteIndex] = reader.ReadByte(); } }
private x86OpCode SelectOpCodeFromToken(x86OpCode[] matches, byte token) { byte groupIndex = matches[0].opcodebytes[0]; int index = token / 8; if (index >= 0x8) index = token - ((token / 8) * 8); // 0xff group has got more than 8 instructions with some special tokens. if (groupIndex == 0xFF) { // instructions with lowerbyte of 5 or D are an exception. byte lByte = (byte)(token - ((token >> 4) << 4)); if (lByte == 0x5 || lByte == 0xD) return matches.FirstOrDefault(m => m.opcodebytes[1] == token); else index *= 2; } if (index >= matches.Length) return null; return matches[index]; }
internal static x86OpCode Create(x86OpCode code) { // copies an opcode. we don't want to change the opcode bytes of the list. x86OpCode newCode = new x86OpCode(); newCode._name = code._name; newCode._originalBytes = code._originalBytes; newCode._opcodeBytes = code._opcodeBytes; newCode._operandType = code._operandType; newCode._operandLength = code._operandLength; newCode._variableByteIndex = code._variableByteIndex; return newCode; }
/// <summary> /// Creates an instance of a x86 instruction without an operand. /// </summary> /// <param name="assembly">The parent assembly.</param> /// <param name="opcode">The opcode to use.</param> /// <returns></returns> public static x86Instruction Create(x86OpCode opcode) { return Create(opcode, null, null); }