public bool TryTransformJumpInstructionTo4BytesOperandSize(IAssemblyInstructionForTransformation instruction, out IAssemblyInstructionForTransformation transformedInstruction) { transformedInstruction = instruction; if (instruction == null) { throw new ArgumentNullException(nameof(instruction)); } if (!m_InstructionWithAddressOperandDecider.IsJumpInstruction(instruction.Mnemonic)) { throw new ArgumentException("instruction is not a jump instruction"); } if (!m_InstructionWithAddressOperandDecider.IsJumpInstructionWithRelativeAddressOperand(instruction)) { return(false); } if (!m_dictionaryJumpInstructionBytes.ContainsKey(instruction.Mnemonic)) { return(false); } if (instruction.Operands[0].Size == 32) { return(false); //because the size of operand is already 4 bytes } var operand = instruction.Operands[0]; if (operand == null) { throw new ApplicationException("Jump instruction transformation didn't find an operand with JIMM type. program doesnt support other types."); } //get an expanded jump instruction with 4 bytes, which have empty (or incorrect operand bytes). var newInstructionBytes = GetEmptyExapndedJumpInstructionWith4Bytes(instruction); //fill the target address with the new operand bytes var newInstructionBytesWithTargetAddress = FillInstructionWithOperandBytes(instruction, newInstructionBytes); //create new insruction from the bytes of new instruction transformedInstruction = m_disasmFactory.Create(newInstructionBytes, false).Disassemble().First(); transformedInstruction.SetOffset(instruction.Offset); transformedInstruction.SetPC(instruction.PC); return(true); }
public IAssemblyInstructionForTransformation CreateInstructionWithNewAddress(ICode code, IAssemblyInstructionForTransformation instruction, ulong newProgramCounter, ulong newOffset, ulong oldAddressInOperand, ulong newAddressInOperand) { if (instruction == null) { throw new ArgumentNullException(nameof(instruction)); } if (code == null) { throw new ArgumentNullException(nameof(code)); } if (instruction.Operands == null) { throw new ArgumentException("parameters operands can be 0", "instruction.Operands"); } if (instruction.Operands.Count() == 0) { throw new ArgumentException("parameters operands can not be 0"); } var opr = instruction.Operands[0]; //same instruction target, no change is needed if (oldAddressInOperand == newAddressInOperand) { instruction.SetOffset(newOffset); instruction.SetPC(newProgramCounter); return(instruction); } byte[] oldAddressBytes = BitConverter.GetBytes((uint)oldAddressInOperand); byte[] newAddressBytes = BitConverter.GetBytes((uint)newAddressInOperand); int idx = FindOriginalBytesIndex(instruction.Bytes, oldAddressBytes); if (idx < 0) { throw new ApplicationException("Could not replace target address in instruction"); } byte[] newInstructionBytes = instruction.Bytes.Clone() as byte[]; replaceBytes(newInstructionBytes, idx, newAddressBytes); //create new instruction based on the new bytes var disasm = m_disasmFactory.Create(newInstructionBytes); var newInstruction = disasm.Disassemble().First(); newInstruction.SetOffset(newOffset); newInstruction.SetPC(newProgramCounter); //validate new instructions ulong parsedAddress; if (!newInstruction.TryGetAbsoluteAddressFromAnyOperand(code.CodeInMemoryLayout, out parsedAddress) || newAddressInOperand != parsedAddress) { throw new ApplicationException("updating jump instruction target address failed"); } return(newInstruction); }
public IAssemblyInstructionForTransformation CreateJumpInstructionWithNewTargetAddress( IAssemblyInstructionForTransformation instruction, ulong newProgramCounter, ulong newOffset, ulong newTargetAddress) { if (instruction == null) { throw new ArgumentNullException(nameof(instruction)); } if (instruction.Operands == null) { throw new ArgumentException("parameters operands can be 0", "instruction.Operands"); } if (instruction.Operands.Count() == 0) { throw new ArgumentException("parameters operands can not be 0"); } if (instruction.Operands[0].Type != ud_type.UD_OP_JIMM) { throw new ArgumentException("parameters operand must be of type 'JIMM'"); } var opr = instruction.Operands[0]; //same instruction target, no change is needed if (instruction.GetAbsoluteAddressFromRelativeAddress(newProgramCounter) == newTargetAddress) { instruction.SetOffset(newOffset); instruction.SetPC(newProgramCounter); return(instruction); } byte[] bytesWithAddressShift = null; byte[] bytesOriginal = null; byte[] newInstructionBytes = instruction.Bytes.Clone() as byte[]; int offsetValue = newTargetAddress > newProgramCounter ? (int)(newTargetAddress - newProgramCounter) : (int)(newProgramCounter - newTargetAddress) * -1; switch (opr.Size) { case 8: if (offsetValue > (long)sbyte.MaxValue) { throw new ApplicationException("operand value is more than 128 which is the max value. operand size have to be extended!"); } if (offsetValue < (long)sbyte.MinValue) { throw new ApplicationException("operand value is less than -127 which is the min value. operand size have to be extended!"); } bytesWithAddressShift = new byte[] { (byte)(offsetValue) }; bytesOriginal = new byte[] { (byte)(opr.LvalSByte) }; break; case 16: if (offsetValue > short.MaxValue) { throw new ApplicationException("operand value is more than 32,768 which is the max value. operand size have to be extended!"); } if (offsetValue < short.MinValue) { throw new ApplicationException("operand value is more than -32,767 which is the max value. operand size have to be extended!"); } bytesWithAddressShift = BitConverter.GetBytes((short)(offsetValue)); bytesOriginal = BitConverter.GetBytes(opr.LvalSWord); break; case 32: if (offsetValue > int.MaxValue) { throw new ApplicationException("operand value is more than 2,147,483,648 which is the max value.operand size have to be extended!"); } if (offsetValue < int.MinValue) { throw new ApplicationException("operand value is less than -2,147,483,647 which is the max value.operand size have to be extended!"); } bytesWithAddressShift = BitConverter.GetBytes(offsetValue); break; } int idx = instruction.Bytes.Length - (opr.Size / 8); if (idx > -1) { replaceBytes(newInstructionBytes, idx, bytesWithAddressShift); } else { throw new ApplicationException("Could not replace target address in instruction"); } //create new instruction based on the new bytes var disasm = m_disasmFactory.Create(newInstructionBytes); var newInstruction = disasm.Disassemble().First(); newInstruction.SetOffset(newOffset); newInstruction.SetPC(newProgramCounter); if (newTargetAddress != newInstruction.GetAbsoluteAddressFromRelativeAddress()) { throw new ApplicationException("updating jump instruction target address failed"); } return(newInstruction); }