Originally Posted by
evilid
Can someone help me with the viewport height and width hook.
I'm now searching for:
getstatic client.or:int
ldc 711889975 (java.lang.Integer)
imul
iconst_2
idiv
But in rev 119 for example it will give the viewportwidth, but in 125, 126 etc. it gives the viewportheight.
So there's two patterns (ONE if your deob is good -- I will assume worst case for this example) to identify the ViewPort-Width and ViewPort-Height.
The first is:
IMUL, ILOAD_X, IMUL, ILOAD_1, IDIV
followed by:
GETSTATIC, LDC, IMUL, ICONST_2, IDIV.
---
The second is:
GETSTATIC, LDC, IMUL, ICONST_2, IDIV, IMUL, GETSTATIC, LDC
followed by:
IMUL, ILOAD_X, IMUL, ILOAD_1, IDIV.
The are pretty much the exact same pattern (it just matters whether or not you normalize all multipliers to be on the right or left side of the variable).
---
In both cases the following are common:
IMUL, ILOAD_X, IMUL, ILOAD_1, IDIV
and
GETSTATIC, LDC, IMUL, ICONST_2, IDIV.
To determine which is the "Width", the "ILOAD_X" will be "ILOAD_0" and for the "Height" it will be "ILOAD_4".
Example:
Java Code:
if(var1 >= 50) {
client.gq = 1603721491 * (client.oe * 1778564539 * var0 / var1 + client.op * 1026734741 / 2); //Width has "var0" / "var1".
client.gc = -512248033 * (client.or * 711889975 / 2 + client.oe * 1778564539 * var9 / var1); //Height has "var9" / "var1".
}
//Another revision:
if(var1 >= 50) {
client.gt = (client.ol * -504930707 / 2 + client.oz * -483184759 * var0 / var1) * 1568639237; //Again "var0" / "var1".
client.ga = (client.ou * 695601873 / 2 + client.oz * -483184759 * var9 / var1) * 1892081559; //Again "var9" / "var1".
}
Both are found in a method with the signature: "(III)V" with accessors STATIC and FINAL.
Now put it together:
Java Code:
//UsagefindField
(nodes,
"ViewPort-Width",
0);findField
(nodes,
"ViewPort-Height",
4);//----private ClassField findField
(Collection
<ClassNode
> nodes,
String fieldName,
int identifierValue
) { final int[] pattern
= new int[]{Opcodes.
GETSTATIC, Opcodes.
LDC, Opcodes.
IMUL, Opcodes.
ICONST_2, Opcodes.
IDIV}; final int[] idPattern
= new int[]{Opcodes.
IMUL, Opcodes.
ILOAD, Opcodes.
IMUL, Opcodes.
ILOAD, Opcodes.
IDIV}; for (ClassNode n
: nodes
) { for (MethodNode m
: n.
methods) { if (hasAccess
(m, Opcodes.
ACC_STATIC) && hasAccess
(m, Opcodes.
ACC_FINAL) && m.
desc.
equals("(III)V")) { int i
= new Finder
(m
).
findPattern(pattern
); while (i
!= -1) { int j
= -1; if (m.
instructions.
get(i
- 1).
getOpcode() == Opcodes.
IDIV) { j
= new Finder
(m
).
findPreviousPattern(i, idPattern
); } else { j
= new Finder
(m
).
findNextPattern(i, idPattern
); } if (j
!= -1) { if (((VarInsnNode
)m.
instructions.
get(j
+ 1)).
var == identifierValue
|| ((VarInsnNode
)m.
instructions.
get(j
+ 3)).
var == identifierValue
) { FieldInsnNode f
= (FieldInsnNode
)m.
instructions.
get(i
); long multi
= (int) ((LdcInsnNode
)m.
instructions.
get(i
+ 1)).
cst; if (f.
owner.
equals("client") && f.
desc.
equals("I")) { return new ClassField
(fieldName, f.
owner + "." + f.
name, f.
desc, multi
); } } } i
= new Finder
(m
).
findPattern(pattern, i
+ 1); } } } } return new ClassField
("ViewPortWidth",
"N/A");}