public override void Execute(Context context) { ProxyCallsUtils proxyCallsUtils = new ProxyCallsUtils(context); CallFlags flags = CallFlags.InvokeStatic | CallFlags.InvokeVirtual; foreach (MethodDefinition method in context.Class.Methods.ToArray()) { if (context.Engine.UntouchableMethods.Contains(method)) { continue; } for (int i = 0; i < method.Body.Instructions.Count; i++) { ByteCodeInstruction byteCodeInstruction = method.Body.Instructions[i]; MethodDefinition newMethod = null; IMethod operand = null; if (byteCodeInstruction.OpCode.Equal(ByteOpCodes.InvokeVirtual)) { operand = (IMethod)byteCodeInstruction.Operand; if (flags.HasFlag(CallFlags.InvokeVirtual)) { newMethod = proxyCallsUtils.Create(operand, byteCodeInstruction, true); } } else if (byteCodeInstruction.OpCode.Equal(ByteOpCodes.InvokeStatic)) { operand = (IMethod)byteCodeInstruction.Operand; if (flags.HasFlag(CallFlags.InvokeStatic)) { newMethod = proxyCallsUtils.Create(operand, byteCodeInstruction, false); } } if (newMethod == null) { continue; } context.Engine.UntouchableMethods.Add(newMethod); context.Class.Methods.Add(newMethod); method.Body.Instructions[i] = new ByteCodeInstruction(ByteOpCodes.InvokeStatic, new MethodReference(newMethod.Name, context.Class, newMethod.Descriptor)); } } context.Engine.UntouchableMethods.Clear(); }
public override void Execute(Context context) { foreach (MethodDefinition method in context.Class.Methods.ToArray()) { if (context.Engine.UntouchableMethods.Contains(method)) { continue; } for (int i = 0; i < method.Body.Instructions.Count; i++) { ByteCodeInstruction byteCodeInstruction = method.Body.Instructions[i]; if (byteCodeInstruction.OpCode.Equal(ByteOpCodes.Ldc)) { object operand = byteCodeInstruction.Operand; Type operandType = operand.GetType(); if (operandType == typeof(string)) { string value = (string)operand; string encodedValue = Encode(value); var newString = new ClassReference("java/lang/String"); var getDecoder = new MethodReference("getDecoder", new ClassReference("java/util/Base64"), new MethodDescriptor(new ObjectType("java/util/Base64$Decoder"))); var decode = new MethodReference("decode", new ClassReference("java/util/Base64$Decoder"), new MethodDescriptor(new ArrayType(new BaseType(BaseTypeValue.Byte)), ObjectType.String)); var initString = new MethodReference("<init>", new ClassReference("java/lang/String"), new MethodDescriptor(BaseType.Void, new ArrayType(new BaseType(BaseTypeValue.Byte)))); method.Body.Instructions[i] = new ByteCodeInstruction(ByteOpCodes.New, newString); method.Body.Instructions.Insert(i + 1, new ByteCodeInstruction(ByteOpCodes.Dup)); method.Body.Instructions.Insert(i + 2, new ByteCodeInstruction(ByteOpCodes.InvokeStatic, getDecoder)); method.Body.Instructions.Insert(i + 3, new ByteCodeInstruction(ByteOpCodes.Ldc, encodedValue)); method.Body.Instructions.Insert(i + 4, new ByteCodeInstruction(ByteOpCodes.InvokeVirtual, decode)); method.Body.Instructions.Insert(i + 5, new ByteCodeInstruction(ByteOpCodes.InvokeSpecial, initString)); i += 5; } } } } }
public MethodDefinition Create(IMethod method, ByteCodeInstruction instr, bool virtual_) { MethodDescriptor methodDescriptor = new MethodDescriptor(method.Descriptor.ReturnType, method.Descriptor.ParameterTypes); if (virtual_) { methodDescriptor.ParameterTypes.Insert(0, new ObjectType(method.DeclaringClass.Name)); } MethodDefinition newMethod = new MethodDefinition(context.StringGenerator.Generate(), methodDescriptor) { AccessFlags = MethodAccessFlags.Public | MethodAccessFlags.Static }; ByteCodeMethodBody methodBody = new ByteCodeMethodBody(); for (int i = 0; i < newMethod.Descriptor.ParameterTypes.Count; i++) { var k = new LocalVariable("arg_" + i, new FieldDescriptor(newMethod.Descriptor.ParameterTypes[i])); methodBody.Variables.Add(k); methodBody.Instructions.Add(new ByteCodeInstruction(ByteOpCodes.ALoad, i)); k.Start = methodBody.Instructions[0]; } methodBody.Instructions.Add(instr); if (method.Descriptor.ReturnType.Prefix == 'V') { methodBody.Instructions.Add(new ByteCodeInstruction(ByteOpCodes.Return)); } else { methodBody.Instructions.Add(new ByteCodeInstruction(ByteOpCodes.AReturn)); } newMethod.Body = methodBody; return(newMethod); }
public override void Execute(Context context) { OutlinerUtils outlinerUtils = new OutlinerUtils(context); OutlinerFlags flags = OutlinerFlags.Strings | OutlinerFlags.Ints | OutlinerFlags.Floats | OutlinerFlags.Doubles; foreach (MethodDefinition method in context.Class.Methods.ToArray()) { if (context.Engine.UntouchableMethods.Contains(method)) { continue; } for (int i = 0; i < method.Body.Instructions.Count; i++) { ByteCodeInstruction byteCodeInstruction = method.Body.Instructions[i]; if (byteCodeInstruction.OpCode.Equal(ByteOpCodes.Ldc)) { MethodDefinition newMethod = null; object operand = byteCodeInstruction.Operand; Type operandType = operand.GetType(); if (operandType == typeof(string)) { if (flags.HasFlag(OutlinerFlags.Strings)) { newMethod = outlinerUtils.Create((string)operand, OutlinerTarget.String); } } else if (operandType == typeof(int)) { if (flags.HasFlag(OutlinerFlags.Ints)) { newMethod = outlinerUtils.Create((int)operand, OutlinerTarget.Int); } } else if (operandType == typeof(double)) { if (flags.HasFlag(OutlinerFlags.Doubles)) { newMethod = outlinerUtils.Create((double)operand, OutlinerTarget.Double); } } else if (operandType == typeof(float)) { if (flags.HasFlag(OutlinerFlags.Floats)) { newMethod = outlinerUtils.Create((float)operand, OutlinerTarget.Float); } } if (newMethod == null) { continue; } context.Engine.UntouchableMethods.Add(newMethod); context.Class.Methods.Add(newMethod); method.Body.Instructions[i] = new ByteCodeInstruction(ByteOpCodes.InvokeStatic, new MethodReference(newMethod.Name, context.Class, newMethod.Descriptor)); } } } context.Engine.UntouchableMethods.Clear(); }