use of net.runelite.asm.attributes.code.instructions.LMul in project runelite by runelite.
the class MultiplyOneDeobfuscator method visit.
private void visit(MethodContext mctx) {
for (InstructionContext ictx : mctx.getInstructionContexts()) {
Instruction instruction = ictx.getInstruction();
if (!(instruction instanceof IMul) && !(instruction instanceof LMul)) {
continue;
}
Instructions ins = ictx.getInstruction().getInstructions();
if (ins == null) {
continue;
}
List<Instruction> ilist = ins.getInstructions();
if (!ilist.contains(ictx.getInstruction())) {
// already done
continue;
}
StackContext one = ictx.getPops().get(0);
StackContext two = ictx.getPops().get(1);
StackContext other = null;
int removeIdx = -1;
if (one.getPushed().getInstruction() instanceof PushConstantInstruction && DMath.equals((Number) ((PushConstantInstruction) one.getPushed().getInstruction()).getConstant(), 1)) {
removeIdx = 0;
other = two;
} else if (two.getPushed().getInstruction() instanceof PushConstantInstruction && DMath.equals((Number) ((PushConstantInstruction) two.getPushed().getInstruction()).getConstant(), 1)) {
removeIdx = 1;
other = one;
}
if (removeIdx == -1) {
continue;
}
if (onlyConstants && !(other.getPushed().getInstruction() instanceof PushConstantInstruction)) {
continue;
}
if (!MultiplicationDeobfuscator.isOnlyPath(ictx, removeIdx == 0 ? one : two)) {
continue;
}
// remove 1
ictx.removeStack(removeIdx);
// remove mul
ins.remove(instruction);
++count;
}
}
use of net.runelite.asm.attributes.code.instructions.LMul in project runelite by runelite.
the class MultiplyZeroDeobfuscator method visit.
private void visit(MethodContext mctx) {
for (InstructionContext ictx : mctx.getInstructionContexts()) {
Instruction instruction = ictx.getInstruction();
Instructions ins = instruction.getInstructions();
if (ins == null) {
continue;
}
if (!(instruction instanceof IMul) && !(instruction instanceof LMul)) {
continue;
}
List<Instruction> ilist = ins.getInstructions();
StackContext one = ictx.getPops().get(0);
StackContext two = ictx.getPops().get(1);
Instruction ione = one.getPushed().getInstruction(), itwo = two.getPushed().getInstruction();
boolean remove = false;
if (ione instanceof PushConstantInstruction) {
PushConstantInstruction pci = (PushConstantInstruction) ione;
Number value = (Number) pci.getConstant();
if (DMath.equals(value, 0)) {
remove = true;
}
}
if (itwo instanceof PushConstantInstruction) {
PushConstantInstruction pci = (PushConstantInstruction) itwo;
Number value = (Number) pci.getConstant();
if (DMath.equals(value, 0)) {
remove = true;
}
}
if (remove == false) {
continue;
}
if (!ilist.contains(instruction)) {
// already done
continue;
}
if (!MultiplicationDeobfuscator.isOnlyPath(ictx, null)) {
continue;
}
// remove both, remove imul, push 0
ictx.removeStack(1);
ictx.removeStack(0);
if (instruction instanceof IMul) {
ins.replace(instruction, new LDC(ins, 0));
} else if (instruction instanceof LMul) {
ins.replace(instruction, new LDC(ins, 0L));
} else {
throw new IllegalStateException();
}
++count;
}
}
use of net.runelite.asm.attributes.code.instructions.LMul in project runelite by runelite.
the class DupDeobfuscator method visit.
private void visit(InstructionContext i) {
if (!(i.getInstruction() instanceof DupInstruction)) {
return;
}
DupInstruction di = (DupInstruction) i.getInstruction();
// stack values being duplicated
List<StackContext> sctxs = di.getDuplicated(i);
for (StackContext sctx : sctxs) {
InstructionContext ic = sctx.getPushed();
if (ic.getInstruction() instanceof IMul) {
if (i.getInstruction() instanceof Dup) {
logger.debug("Dup instruction {} duplicates multiplication result {}", i, ic);
undup(i);
++count;
return;
}
if (i.getInstruction() instanceof Dup_X1) {
logger.debug("Dup_X1 instruction {} duplicates multiplication result {}", i, ic);
undup_x1(i);
++count;
return;
}
logger.warn("Dup instruction {} pops imul", i);
} else if (ic.getInstruction() instanceof LMul) {
if (i.getInstruction() instanceof Dup2_X1) {
logger.debug("Dup_X2 instruction {} duplicates multiplication result {}", i, ic);
undup2_x1(i);
++count;
return;
}
logger.warn("Dup instruction {} pops lmul", i);
}
}
// find if mul pops anything duplicated
sctxs = di.getCopies(i);
for (StackContext sctx : sctxs) {
for (InstructionContext ic : sctx.getPopped()) {
if (ic.getInstruction() instanceof IMul) {
if (i.getInstruction() instanceof Dup) {
logger.debug("imul {} pops dup instruction {}", ic, i);
undup(i);
++count;
return;
}
if (i.getInstruction() instanceof Dup_X1) {
logger.debug("imul {} pops dup x1 instruction {}", ic, i);
undup_x1(i);
++count;
return;
}
logger.warn("imul pops dup instruction {}", i);
} else if (ic.getInstruction() instanceof LMul) {
if (i.getInstruction() instanceof Dup2_X1) {
logger.debug("imul {} pops dup2 x1 instruction {}", ic, i);
undup2_x1(i);
++count;
return;
}
logger.warn("lmul pops dup instruction {}", i);
}
}
}
}
use of net.runelite.asm.attributes.code.instructions.LMul in project runelite by runelite.
the class InjectGetter method injectGetter.
public void injectGetter(ClassFile clazz, java.lang.reflect.Method method, Field field, Number getter) {
assert clazz.findMethod(method.getName()) == null;
assert field.isStatic() || field.getClassFile() == clazz;
Signature sig = new Signature.Builder().setReturnType(Inject.classToType(method.getReturnType())).build();
Method getterMethod = new Method(clazz, method.getName(), sig);
getterMethod.setAccessFlags(ACC_PUBLIC);
// create code
Code code = new Code(getterMethod);
getterMethod.setCode(code);
Instructions instructions = code.getInstructions();
List<Instruction> ins = instructions.getInstructions();
if (field.isStatic()) {
code.setMaxStack(1);
ins.add(new GetStatic(instructions, field.getPoolField()));
} else {
code.setMaxStack(2);
ins.add(new ALoad(instructions, 0));
ins.add(new GetField(instructions, field.getPoolField()));
}
if (getter != null) {
code.setMaxStack(2);
assert getter instanceof Integer || getter instanceof Long;
if (getter instanceof Integer) {
ins.add(new LDC(instructions, (int) getter));
ins.add(new IMul(instructions));
} else {
ins.add(new LDC(instructions, (long) getter));
ins.add(new LMul(instructions));
}
}
InstructionType returnType;
if (field.getType().isPrimitive() && field.getType().getDimensions() == 0) {
switch(field.getType().toString()) {
case "B":
case "C":
case "I":
case "S":
case "Z":
returnType = InstructionType.IRETURN;
break;
case "D":
returnType = InstructionType.DRETURN;
break;
case "F":
returnType = InstructionType.FRETURN;
break;
case "J":
returnType = InstructionType.LRETURN;
break;
default:
throw new RuntimeException("Unknown type");
}
} else {
returnType = InstructionType.ARETURN;
}
ins.add(new Return(instructions, returnType));
clazz.addMethod(getterMethod);
++injectedGetters;
}
use of net.runelite.asm.attributes.code.instructions.LMul in project runelite by runelite.
the class InjectSetter method injectSetter.
/**
* inject a setter into the vanilla classgroup
*
* @param targetClass Class where to inject the setter (field's class,
* or client)
* @param targetApiClass API targetClass implements, which may have the
* setter declared
* @param field Field of vanilla that will be set
* @param exportedName exported name of field
* @param setter
*/
public void injectSetter(ClassFile targetClass, Class<?> targetApiClass, Field field, String exportedName, Number setter) {
java.lang.reflect.Method method = inject.findImportMethodOnApi(targetApiClass, exportedName, true);
if (method == null) {
logger.warn("Setter injection for field {} but an API method was not found on {}", exportedName, targetApiClass);
return;
}
if (method.getParameterCount() != 1) {
logger.warn("Setter {} with not parameter count != 1?", exportedName);
return;
}
logger.info("Injecting setter for {} on {}", exportedName, targetApiClass);
assert targetClass.findMethod(method.getName()) == null;
assert field.isStatic() || field.getClassFile() == targetClass;
Signature sig = new Signature.Builder().setReturnType(Type.VOID).addArgument(Inject.classToType(method.getParameterTypes()[0])).build();
Method setterMethod = new Method(targetClass, method.getName(), sig);
setterMethod.setAccessFlags(ACC_PUBLIC);
targetClass.addMethod(setterMethod);
++injectedSetters;
Code code = new Code(setterMethod);
setterMethod.setCode(code);
Instructions instructions = code.getInstructions();
List<Instruction> ins = instructions.getInstructions();
// load this
if (!field.isStatic()) {
ins.add(new ALoad(instructions, 0));
}
// load argument
Type argumentType = sig.getTypeOfArg(0);
ins.add(inject.createLoadForTypeIndex(instructions, argumentType, 1));
// cast argument to field type
Type fieldType = field.getType();
if (!argumentType.equals(fieldType)) {
CheckCast checkCast = new CheckCast(instructions);
checkCast.setType(fieldType);
ins.add(checkCast);
}
if (setter != null) {
assert setter instanceof Integer || setter instanceof Long;
if (setter instanceof Integer) {
ins.add(new LDC(instructions, (int) setter));
ins.add(new IMul(instructions));
} else {
ins.add(new LDC(instructions, (long) setter));
ins.add(new LMul(instructions));
}
}
if (field.isStatic()) {
ins.add(new PutStatic(instructions, field));
} else {
ins.add(new PutField(instructions, field));
}
ins.add(new VReturn(instructions));
}
Aggregations