package fr.inria.diversify.transformation.bytecode; import fr.inria.diversify.util.Log; import javassist.CtMethod; import javassist.bytecode.BadBytecode; import javassist.bytecode.CodeAttribute; import javassist.bytecode.CodeIterator; import javassist.bytecode.MethodInfo; import org.json.JSONException; import org.json.JSONObject; import java.util.Arrays; import java.util.List; /** * User: Simon * Date: 11/6/13 * Time: 5:29 PM */ public class BytecodeReplace extends BytecodeTransformation { protected byte[] byteCodeToReplace; public BytecodeReplace(CtMethod method, int index, byte[] bytecode, List<CtMethod> methods) { methodLocation = method; opcodeIndex = index; byteCodeToReplace = bytecode; this.methods = methods; name = "replace"; type = "adrBytecode"; } public BytecodeReplace() { name = "replace"; type = "adrBytecode"; } @Override public JSONObject toJSONObject() throws JSONException { JSONObject object = super.toJSONObject(); object.put("methodLocation", methodLocation.getLongName()); object.put("opcodeIndex",opcodeIndex); object.put("byteCodeToReplace", Arrays.toString(byteCodeToReplace)); return object; } @Override protected void apply() throws BadBytecode { MethodInfo minfo = methodLocation.getMethodInfo(); CodeAttribute ca = minfo.getCodeAttribute(); List<Integer> opCodeIndexList = opCodeIndexList(ca); Log.debug("transformation: {}, {}",type,name); Log.info("replace opcode in method {} at index {} (size: {})", methodLocation.getName(), opCodeIndexList.get(opcodeIndex), byteCodeToReplace.length); deleteOpcode(ca, opCodeIndexList.get(opcodeIndex), byteCodeSize(ca, opCodeIndexList, opcodeIndex)); addOpcode(ca, opCodeIndexList.get(opcodeIndex),byteCodeToReplace); } protected void deleteOpcode(CodeAttribute ca, int index, int size) { CodeIterator i = ca.iterator(); byte[] NOPByte = new byte[size]; i.write(NOPByte,index); } protected void addOpcode(CodeAttribute ca, int index, byte[] bytecode) throws BadBytecode { CodeIterator i = ca.iterator(); i.insert(index, bytecode); } public void setByteCodeToReplace(byte[] byteCodeToReplace) { this.byteCodeToReplace = byteCodeToReplace; } }