use of net.runelite.asm.attributes.code.Instruction in project runelite by runelite.
the class MultiplicationDeobfuscatorTest method test13.
// sipush 512
// ldc -688421113
// imul
// ldc -585812297
// imul
// putstatic class134/field2009 I
@Test
public void test13() {
ClassGroup group = ClassGroupFactory.generateGroup();
Code code = group.findClass("test").findMethod("func").getCode();
Instructions ins = code.getInstructions();
code.setMaxStack(2);
LDC constant1 = new LDC(ins, -688421113);
LDC constant2 = new LDC(ins, -585812297);
Instruction[] body = { new SiPush(ins, (short) 512), constant1, new IMul(ins), constant2, new IMul(ins), new VReturn(ins) };
for (Instruction i : body) {
ins.addInstruction(i);
}
Execution e = new Execution(group);
e.populateInitialMethods();
e.run();
assert constant1.getConstantAsInt() * constant2.getConstantAsInt() == 1;
Deobfuscator d = new MultiplicationDeobfuscator();
d.run(group);
Assert.assertEquals(1, constant1.getConstantAsInt());
Assert.assertEquals(1, constant2.getConstantAsInt());
}
use of net.runelite.asm.attributes.code.Instruction in project runelite by runelite.
the class MultiplyOneDeobfuscatorTest method test2.
// iconst_1
// iconst_m1
// iload 5
// if_icmpeq LABEL0x56d1
// iload 5
// iconst_1
// if_icmpne LABEL0x56e8
// goto LABEL0x56d1
// LABEL0x56d1:
// getstatic class139/field2130 I
// ldc_w -1440517609
// imul
// goto LABEL0x5708
// LABEL0x56e8:
// getstatic class139/field2130 I
// ldc_w -1440517609
// imul
// getstatic client/field377 I
// iadd
// iconst_2
// idiv
// LABEL0x5708:
// imul
// putstatic client/field377 I
//
// client.field377 = 1 * (-1 != var5 && var5 != 1?(class139.field2130 + client.field377) / 2:class139.field2130);
@Test
public void test2() {
ClassGroup group = ClassGroupFactory.generateGroup();
Code code = group.findClass("test").findMethod("func").getCode();
Instructions ins = code.getInstructions();
code.setMaxStack(2);
// vars[0] = 3
Instruction[] prepareVariables = { new LDC(ins, 3), new IStore(ins, 0), new LDC(ins, 2), new IStore(ins, 1) };
for (Instruction i : prepareVariables) ins.addInstruction(i);
Label label = new Label(ins), label2 = new Label(ins), label3 = new Label(ins);
LDC one = new LDC(ins, 1);
IMul mul = new IMul(ins);
Instruction[] body = { one, new LDC(ins, -1), new ILoad(ins, 0), new IfICmpEq(ins, label), new Goto(ins, label2), label, new ILoad(ins, 1), new LDC(ins, -1440517609), new IDiv(ins), new Goto(ins, label3), label2, new ILoad(ins, 1), new LDC(ins, -1440517609), new IDiv(ins), label3, mul, new VReturn(ins) };
for (Instruction i : body) ins.addInstruction(i);
// check execution runs ok
Execution e = new Execution(group);
e.populateInitialMethods();
e.run();
Deobfuscator d = new MultiplyOneDeobfuscator(false);
d.run(group);
Assert.assertTrue(one.getInstructions() == null);
Assert.assertTrue(mul.getInstructions() == null);
}
use of net.runelite.asm.attributes.code.Instruction in project runelite by runelite.
the class DrawAfterWidgets method injectDrawAfterWidgets.
private void injectDrawAfterWidgets() throws InjectionException {
/*
This call has to be injected using raw injection because the
drawWidgets method gets inlined in some revisions. If it wouldn't be,
mixins would be used to add the call to the end of drawWidgets.
--> This hook depends on the positions of "if (535573958 * kl != -1)" and "jz.db();".
Revision 153 - client.ll():
______________________________________________________
if (535573958 * kl != -1) {
me = 0;
var1 = kl * 1593233303;
var2 = 523525871 * q;
var3 = -1668171507 * h.n;
if (!bo.p(var1, (byte)111)) {
for(var4 = 0; var4 < 100; ++var4) {
mb[var4] = true;
}
} else {
z.lj = null;
bl.hz(fa.g[var1], -1, 0, 0, var2, var3, 0, 0, -1, 1505114436);
if (z.lj != null) {
bl.hz(z.lj, -1412584499, 0, 0, var2, var3, 1475313862 * bq.la, aq.lc * 1205565233, -1, 2123188146);
z.lj = null;
}
}
}
// <-- INJECT CALL HERE
jz.db(); <-- noClip method
______________________________________________________
*/
boolean injected = false;
Method noClip = findStaticMethod("noClip");
if (noClip == null) {
throw new InjectionException("Mapped method \"noClip\" could not be found.");
}
net.runelite.asm.pool.Method poolNoClip = noClip.getPoolMethod();
for (ClassFile c : inject.getVanilla().getClasses()) {
for (Method m : c.getMethods()) {
if (m.getCode() == null) {
continue;
}
Instructions instructions = m.getCode().getInstructions();
Set<Label> labels = new HashSet<>();
// Let's find "invokestatic <some class>.noClip()" and its label
ListIterator<Instruction> labelIterator = instructions.getInstructions().listIterator();
while (labelIterator.hasNext()) {
Instruction i = labelIterator.next();
if (!(i instanceof InvokeStatic)) {
continue;
}
InvokeStatic is = (InvokeStatic) i;
if (!is.getMethod().equals(poolNoClip)) {
continue;
}
labelIterator.previous();
Instruction i2 = labelIterator.previous();
labelIterator.next();
labelIterator.next();
// Find the label that marks the code path for the instruction
if (!(i2 instanceof Label)) {
continue;
}
// There can be several noClip invocations in a method, so let's catch them all
labels.add((Label) i2);
}
if (labels.isEmpty()) {
// If we get here, we're either in the wrong method
// or Jagex has removed the "if (535573958 * kl != -1)"
logger.debug("Could not find the label for jumping to the " + noClip + " call in " + m);
continue;
}
Set<Label> labelsToInjectAfter = new HashSet<>();
ListIterator<Instruction> jumpIterator = instructions.getInstructions().listIterator();
while (jumpIterator.hasNext()) {
Instruction i = jumpIterator.next();
if (!(i instanceof JumpingInstruction)) {
continue;
}
JumpingInstruction ji = (JumpingInstruction) i;
Label label = null;
for (Label l : labels) {
if (ji.getJumps().contains(l)) {
label = l;
break;
}
}
if (label == null) {
continue;
}
jumpIterator.previous();
Set<Instruction> insns = new HashSet<>();
insns.add(jumpIterator.previous());
insns.add(jumpIterator.previous());
insns.add(jumpIterator.previous());
insns.add(jumpIterator.previous());
// Get the iterator back to i's position
jumpIterator.next();
jumpIterator.next();
jumpIterator.next();
jumpIterator.next();
jumpIterator.next();
/*
Check that these instruction types are passed into the if-statement:
ICONST_M1
GETSTATIC client.kr : I
LDC 634425425
IMUL
We cannot depend on the order of these because of the obfuscation,
so let's make it easier by just checking that they are there.
*/
if (insns.stream().filter(i2 -> i2 instanceof PushConstantInstruction).count() != 2 || insns.stream().filter(i2 -> i2 instanceof IMul).count() != 1 || insns.stream().filter(i2 -> i2 instanceof GetStatic).count() != 1) {
continue;
}
// At this point, we have found the real injection point
labelsToInjectAfter.add(label);
}
for (Label l : labelsToInjectAfter) {
InvokeStatic invoke = new InvokeStatic(instructions, new net.runelite.asm.pool.Method(new net.runelite.asm.pool.Class(HOOKS), "drawAfterWidgets", new Signature("()V")));
instructions.addInstruction(instructions.getInstructions().indexOf(l) + 1, invoke);
logger.info("injectDrawAfterWidgets injected a call after " + l);
injected = true;
}
}
}
if (!injected) {
throw new InjectionException("injectDrawAfterWidgets failed to inject!");
}
}
use of net.runelite.asm.attributes.code.Instruction in project runelite by runelite.
the class InjectHookMethod method injectHookMethod.
private void injectHookMethod(Annotation hook, Method deobMethod, Method vanillaMethod) throws InjectionException {
String hookName = hook.getElement().getString();
Instructions instructions = vanillaMethod.getCode().getInstructions();
Signature.Builder builder = new Signature.Builder().setReturnType(// Hooks always return void
Type.VOID);
for (Type type : deobMethod.getDescriptor().getArguments()) {
builder.addArgument(inject.deobfuscatedTypeToApiType(type));
}
assert deobMethod.isStatic() == vanillaMethod.isStatic();
if (!deobMethod.isStatic()) {
// Add variable to signature
builder.addArgument(0, inject.deobfuscatedTypeToApiType(new Type(deobMethod.getClassFile().getName())));
}
Signature signature = builder.build();
List<Integer> insertIndexes = findHookLocations(hook, vanillaMethod);
insertIndexes.sort((a, b) -> Integer.compare(b, a));
for (int insertPos : insertIndexes) {
if (!deobMethod.isStatic()) {
instructions.addInstruction(insertPos++, new ALoad(instructions, 0));
}
// current variable index
int index = deobMethod.isStatic() ? 0 : 1;
for (int i = index; i < signature.size(); ++i) {
Type type = signature.getTypeOfArg(i);
Instruction load = inject.createLoadForTypeIndex(instructions, type, index);
instructions.addInstruction(insertPos++, load);
index += type.getSize();
}
// Invoke callback
InvokeStatic invoke = new InvokeStatic(instructions, new net.runelite.asm.pool.Method(new net.runelite.asm.pool.Class(HOOKS), hookName, signature));
instructions.addInstruction(insertPos++, invoke);
}
logger.info("Injected method hook {} in {} with {} args: {}", hookName, vanillaMethod, signature.size(), signature.getArguments());
}
use of net.runelite.asm.attributes.code.Instruction in project runelite by runelite.
the class CodeVisitor method visitInsn.
@Override
public void visitInsn(int opcode) {
switch(opcode) {
case DCONST_0:
{
Instruction i = new LDC(code.getInstructions(), 0d);
code.getInstructions().addInstruction(i);
break;
}
case DCONST_1:
{
Instruction i = new LDC(code.getInstructions(), 1d);
code.getInstructions().addInstruction(i);
break;
}
case FCONST_0:
{
Instruction i = new LDC(code.getInstructions(), 0f);
code.getInstructions().addInstruction(i);
break;
}
case FCONST_1:
{
Instruction i = new LDC(code.getInstructions(), 1f);
code.getInstructions().addInstruction(i);
break;
}
case FCONST_2:
{
Instruction i = new LDC(code.getInstructions(), 2f);
code.getInstructions().addInstruction(i);
break;
}
case ICONST_M1:
{
Instruction i = new LDC(code.getInstructions(), -1);
code.getInstructions().addInstruction(i);
break;
}
case ICONST_0:
{
Instruction i = new LDC(code.getInstructions(), 0);
code.getInstructions().addInstruction(i);
break;
}
case ICONST_1:
{
{
Instruction i = new LDC(code.getInstructions(), 1);
code.getInstructions().addInstruction(i);
break;
}
}
case ICONST_2:
{
Instruction i = new LDC(code.getInstructions(), 2);
code.getInstructions().addInstruction(i);
break;
}
case ICONST_3:
{
Instruction i = new LDC(code.getInstructions(), 3);
code.getInstructions().addInstruction(i);
break;
}
case ICONST_4:
{
Instruction i = new LDC(code.getInstructions(), 4);
code.getInstructions().addInstruction(i);
break;
}
case ICONST_5:
{
Instruction i = new LDC(code.getInstructions(), 5);
code.getInstructions().addInstruction(i);
break;
}
case LCONST_0:
{
Instruction i = new LDC(code.getInstructions(), 0L);
code.getInstructions().addInstruction(i);
break;
}
case LCONST_1:
{
Instruction i = new LDC(code.getInstructions(), 1L);
code.getInstructions().addInstruction(i);
break;
}
default:
createInstructionFromOpcode(opcode);
}
}
Aggregations