public TransformationAddingJunkBytes(IInstructionWithAddressOperandDecider instructionWithAddressOperandDecider, IInstructionWithAddressOperandTransform instructionWithAddressOperandTransform, ICodeInMemoryLayoutFactory codeInMemoryLayoutFactory, ICodeFactory codeFactory, IInstructionWithAddressOperandTransform jumpInstrucionTransform, ICodeTransform codeTransform, IStatistics statistics, IRelocationDirectoryFromNewCode relocationDirectoryFromNewCode, IJunkBytesProvider junkBytesProvider, IDisassemblerFactory disassemblerFactory) : base(instructionWithAddressOperandDecider, instructionWithAddressOperandTransform, codeFactory, codeInMemoryLayoutFactory, codeTransform, statistics, relocationDirectoryFromNewCode) { m_junkBytesProvider = junkBytesProvider ?? throw new ArgumentNullException(nameof(junkBytesProvider)); m_disassemblerFactory = disassemblerFactory ?? throw new ArgumentNullException(nameof(disassemblerFactory)); }
private bool TryGenerateJunkInstruction(IBasicBlock basicBlock, IJunkBytesProvider junkBytesProvider, IStatistics statistics, out IAssemblyInstructionForTransformation junkInstruction) { junkInstruction = null; bool retVal = false; //get junk bytes byte[] junkBytes = junkBytesProvider.GetJunkBytes(); if (junkBytes == null) { throw new NullReferenceException(nameof(junkBytes)); } //get basic block bytes byte[] basicBlockBytes = basicBlock.GetAllBytes(); //the size of the junk we try to insert uint junkBytesSize = (uint)junkBytes.Count(); //the inde of the most far insruction that has been syncronized uint mostFarSyncInstructionIdx = 0; //the partial instruction that causes the synchronization to be far as possible uint bestPartialInstructionSize = 0; //check what sub array of the inserted junk causes the most of confusion //so instruction are disassembled not correctly as far as possible while (junkBytesSize > 0) { uint sizeOfNewBytesArray = basicBlock.NumberOfBytes + junkBytesSize; byte[] newBasicBlockBytes = new byte[sizeOfNewBytesArray]; //copy junk bytes and then basic block bytes Array.Copy(junkBytes, newBasicBlockBytes, junkBytesSize); basicBlockBytes.CopyTo(newBasicBlockBytes, junkBytesSize); //the index of first identical disassembled instruction to original uint?indexOfFirstIdenticalInstruction = CompareDisassembleToOriginal(newBasicBlockBytes, basicBlock, m_disassemblerFactory); //in case that there is no even one instruction that synchronizes, so try another sequence //because the parsing error can not proceed to the next block if (!indexOfFirstIdenticalInstruction.HasValue) { junkBytesSize--; continue; } if (indexOfFirstIdenticalInstruction.Value > mostFarSyncInstructionIdx) { mostFarSyncInstructionIdx = indexOfFirstIdenticalInstruction.Value; bestPartialInstructionSize = junkBytesSize; } junkBytesSize--; } //update basic block with the instruction that causes the synchronization to be as far as //possible if (mostFarSyncInstructionIdx > 0) { byte[] junkBytesSelected = new byte[bestPartialInstructionSize]; for (int i = 0; i < bestPartialInstructionSize; i++) { junkBytesSelected[i] = junkBytes[i]; } var disasm = m_disassemblerFactory.Create(junkBytesSelected); junkInstruction = disasm.Disassemble().First(); junkInstruction.IsNew = true; statistics.IncrementMissinterpretedInstructions(mostFarSyncInstructionIdx); statistics.IncrementJunkInstructions(1, (uint)junkInstruction.Length); retVal = true; } return(retVal); }