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);
        }