Skip to content

Commit

Permalink
Update
Browse files Browse the repository at this point in the history
-ConstantFolder long support
-Remove illegal annotations
-Fix error in Radon transformer v2
  • Loading branch information
ThisTestUser committed Jul 19, 2021
1 parent 72b6e57 commit 833c5ed
Show file tree
Hide file tree
Showing 4 changed files with 273 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ public boolean transform() throws Throwable {
case ISHL:
case ISHR:
case IUSHR:
case IOR:
case IAND:
case IXOR: {
List<Frame> frames = result.getFrames().get(ain);
if (frames == null) {
Expand Down Expand Up @@ -86,6 +88,10 @@ public boolean transform() throws Throwable {
results.add(bottomValue >> topValue);
} else if (ain.getOpcode() == IUSHR) {
results.add(bottomValue >>> topValue);
} else if (ain.getOpcode() == IOR) {
results.add(bottomValue | topValue);
} else if (ain.getOpcode() == IAND) {
results.add(bottomValue & topValue);
} else if (ain.getOpcode() == IXOR) {
results.add(bottomValue ^ topValue);
}
Expand Down Expand Up @@ -268,6 +274,106 @@ public boolean transform() throws Throwable {
}
break;
}
case LADD:
case LSUB:
case LMUL:
case LDIV:
case LAND:
case LOR:
case LREM:
case LXOR: {
if (!getConfig().isLongFolding()) {
break;
}
List<Frame> frames = result.getFrames().get(ain);
if (frames == null) {
break;
}
Set<Long> results = new HashSet<>();
for (Frame frame0 : frames) {
MathFrame frame = (MathFrame) frame0;
if (frame.getTargets().size() != 2) {
throw new RuntimeException("weird: " + frame);
}
Frame top = frame.getTargets().get(0);
Frame bottom = frame.getTargets().get(1);
if (top instanceof LdcFrame && bottom instanceof LdcFrame) {
long bottomValue = ((Number) ((LdcFrame) bottom).getConstant()).longValue();
long topValue = ((Number) ((LdcFrame) top).getConstant()).longValue();
if (ain.getOpcode() == LADD) {
results.add(bottomValue + topValue);
} else if (ain.getOpcode() == LMUL) {
results.add(bottomValue * topValue);
} else if (ain.getOpcode() == LREM) {
results.add(bottomValue % topValue);
} else if (ain.getOpcode() == LSUB) {
results.add(bottomValue - topValue);
} else if (ain.getOpcode() == LDIV) {
results.add(bottomValue / topValue);
} else if (ain.getOpcode() == LXOR) {
results.add(bottomValue ^ topValue);
} else if (ain.getOpcode() == LOR) {
results.add(bottomValue | topValue);
} else if (ain.getOpcode() == LAND) {
results.add(bottomValue & topValue);
}
} else {
break opcodes;
}
}
if (results.size() == 1) {
InsnList replacement = new InsnList();
replacement.add(new InsnNode(POP2));
replacement.add(new InsnNode(POP2));
replacement.add(Utils.getLongInsn(results.iterator().next()));
replacements.put(ain, replacement);
folded.getAndIncrement();
}
break;
}
case LSHL:
case LSHR:
case LUSHR: {
if (!getConfig().isLongFolding()) {
break;
}
List<Frame> frames = result.getFrames().get(ain);
if (frames == null) {
break;
}
Set<Long> results = new HashSet<>();
for (Frame frame0 : frames) {
MathFrame frame = (MathFrame) frame0;
if (frame.getTargets().size() != 2) {
throw new RuntimeException("weird: " + frame);
}
Frame top = frame.getTargets().get(0);
Frame bottom = frame.getTargets().get(1);
if (top instanceof LdcFrame && bottom instanceof LdcFrame) {
long bottomValue = ((Number) ((LdcFrame) bottom).getConstant()).longValue();
int topValue = ((Number) ((LdcFrame) top).getConstant()).intValue();
if (ain.getOpcode() == LSHL) {
results.add(bottomValue << topValue);
} else if (ain.getOpcode() == LSHR) {
results.add(bottomValue >> topValue);
} else if (ain.getOpcode() == LUSHR) {
results.add(bottomValue >>> topValue);
break;
}
} else {
break opcodes;
}
}
if (results.size() == 1) {
InsnList replacement = new InsnList();
replacement.add(new InsnNode(POP));
replacement.add(new InsnNode(POP2));
replacement.add(Utils.getLongInsn(results.iterator().next()));
replacements.put(ain, replacement);
folded.getAndIncrement();
}
break;
}
case POP:
case POP2: {
if (!getConfig().isExperimentalPopFolding()) {
Expand All @@ -290,7 +396,14 @@ public boolean transform() throws Throwable {
}
remove.add(result.getMapping().get(deletedFrame));
}
} else {
} else if (ain.getOpcode() == POP2 && frame.getRemoved().size() == 1 && frame.getRemoved().get(0) instanceof LdcFrame && ((LdcFrame)frame.getRemoved().get(0)).getConstant() instanceof Long) {
for (Frame deletedFrame : frame.getRemoved()) {
if (deletedFrame.getChildren().size() > 1) {
break opcodes;
}
remove.add(result.getMapping().get(deletedFrame));
}
}else {
if(frame.getRemoved().size() == 1)
{
//Load + pop
Expand Down Expand Up @@ -357,6 +470,7 @@ public boolean transform() throws Throwable {

public static class Config extends TransformerConfig {
private boolean experimentalPopFolding;
private boolean longFolding = true;

public Config() {
super(ConstantFolder.class);
Expand All @@ -369,5 +483,13 @@ public boolean isExperimentalPopFolding() {
public void setExperimentalPopFolding(boolean experimentalPopFolding) {
this.experimentalPopFolding = experimentalPopFolding;
}

public boolean isLongFolding() {
return longFolding;
}

public void setLongFolding(boolean longFolding) {
this.longFolding = longFolding;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* Copyright 2017 Sam Sun <[email protected]>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.javadeobfuscator.deobfuscator.transformers.general.removers;

import com.javadeobfuscator.deobfuscator.config.TransformerConfig;

import java.util.Iterator;
import java.util.List;

import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AnnotationNode;
import org.objectweb.asm.util.CheckClassAdapter;
import org.objectweb.asm.util.CheckFieldAdapter;
import org.objectweb.asm.util.CheckMethodAdapter;

import com.javadeobfuscator.deobfuscator.transformers.Transformer;

public class IllegalAnnotationRemover extends Transformer<TransformerConfig> {
@Override
public boolean transform() throws Throwable {
CheckClassAdapter classAdapter = new CheckClassAdapter(null);
CheckMethodAdapter methodAdapter = new CheckMethodAdapter(null);
CheckFieldAdapter fieldAdapter = new CheckFieldAdapter(null);
classAdapter.visit(Opcodes.V1_5, 0, "java/lang/Object", null, null, null);
classNodes().forEach(classNode -> {
removeInvalidAnnotations(classAdapter, classNode.invisibleAnnotations, false);
removeInvalidAnnotations(classAdapter, classNode.visibleAnnotations, true);
classNode.methods.forEach(methodNode -> {
removeInvalidAnnotations(methodAdapter, methodNode.invisibleAnnotations, false);
removeInvalidAnnotations(methodAdapter, methodNode.visibleAnnotations, true);
});
classNode.fields.forEach(fieldNode -> {
removeInvalidAnnotations(fieldAdapter, fieldNode.invisibleAnnotations, false);
removeInvalidAnnotations(fieldAdapter, fieldNode.visibleAnnotations, true);
});
});
return true;
}

private void removeInvalidAnnotations(Object visitor, List<AnnotationNode> annots, boolean visible)
{
if(annots == null)
return;
Iterator<AnnotationNode> itr = annots.iterator();
while(itr.hasNext())
{
AnnotationNode type = itr.next();
try {
if(visitor instanceof CheckClassAdapter)
((CheckClassAdapter)visitor).visitAnnotation(type.desc, visible);
else if(visitor instanceof CheckMethodAdapter)
((CheckMethodAdapter)visitor).visitAnnotation(type.desc, visible);
else
((CheckFieldAdapter)visitor).visitAnnotation(type.desc, visible);
} catch (IllegalArgumentException | IllegalStateException ignored) {
itr.remove();
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* Copyright 2017 Sam Sun <[email protected]>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.javadeobfuscator.deobfuscator.transformers.general.removers;

import com.javadeobfuscator.deobfuscator.config.TransformerConfig;

import java.util.Iterator;
import java.util.List;

import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.TypeAnnotationNode;
import org.objectweb.asm.util.CheckClassAdapter;
import org.objectweb.asm.util.CheckFieldAdapter;
import org.objectweb.asm.util.CheckMethodAdapter;

import com.javadeobfuscator.deobfuscator.transformers.Transformer;

public class IllegalTypeAnnotationRemover extends Transformer<TransformerConfig> {
@Override
public boolean transform() throws Throwable {
CheckClassAdapter classAdapter = new CheckClassAdapter(null);
CheckMethodAdapter methodAdapter = new CheckMethodAdapter(null);
CheckFieldAdapter fieldAdapter = new CheckFieldAdapter(null);
classAdapter.visit(Opcodes.V1_5, 0, "java/lang/Object", null, null, null);
classNodes().forEach(classNode -> {
removeInvalidTypeAnnotations(classAdapter, classNode.invisibleTypeAnnotations, false);
removeInvalidTypeAnnotations(classAdapter, classNode.visibleTypeAnnotations, true);
classNode.methods.forEach(methodNode -> {
removeInvalidTypeAnnotations(methodAdapter, methodNode.invisibleTypeAnnotations, false);
removeInvalidTypeAnnotations(methodAdapter, methodNode.visibleTypeAnnotations, true);
});
classNode.fields.forEach(fieldNode -> {
removeInvalidTypeAnnotations(fieldAdapter, fieldNode.invisibleTypeAnnotations, false);
removeInvalidTypeAnnotations(fieldAdapter, fieldNode.visibleTypeAnnotations, true);
});
});
return true;
}

private void removeInvalidTypeAnnotations(Object visitor, List<TypeAnnotationNode> typeAnnots, boolean visible)
{
if(typeAnnots == null)
return;
Iterator<TypeAnnotationNode> itr = typeAnnots.iterator();
while(itr.hasNext())
{
TypeAnnotationNode type = itr.next();
try {
if(visitor instanceof CheckClassAdapter)
((CheckClassAdapter)visitor).visitTypeAnnotation(type.typeRef, type.typePath, type.desc, visible);
else if(visitor instanceof CheckMethodAdapter)
((CheckMethodAdapter)visitor).visitTypeAnnotation(type.typeRef, type.typePath, type.desc, visible);
else
((CheckFieldAdapter)visitor).visitTypeAnnotation(type.typeRef, type.typePath, type.desc, visible);
} catch (IllegalArgumentException | IllegalStateException ignored) {
itr.remove();
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -187,9 +187,9 @@ public boolean canCheckEquality(JavaValue first, JavaValue second, Context conte
modifier.apply(m);
}
}
classes.remove(atOwner.name);
classpath.remove(atOwner.name);
}
classes.remove(atOwner.name);
classpath.remove(atOwner.name);
}
//Bad Annotations
for (ClassNode classNode : classNodes()) {
Expand Down

0 comments on commit 833c5ed

Please sign in to comment.