Skip to content

Commit

Permalink
fix: Additional fixes to comment parsing and bytecode patching
Browse files Browse the repository at this point in the history
  • Loading branch information
Col-E committed Mar 10, 2021
1 parent 5485e3a commit b3ba422
Show file tree
Hide file tree
Showing 3 changed files with 5 additions and 68 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Expand Up @@ -11,7 +11,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<asm.version>9.1</asm.version>
<analysis.version>1.6.0</analysis.version>
<dude.version>1.1.1</dude.version>
<dude.version>1.2.2</dude.version>
<cfr.version>0.151</cfr.version>
<ff.version>403</ff.version>
<procyon.version>0.5.36</procyon.version>
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/me/coley/recaf/metadata/Comments.java
Expand Up @@ -38,7 +38,7 @@ private void parse(MethodNode method) {
if (method.visibleAnnotations == null) return;
List<AnnotationNode> invalidAnnos = new ArrayList<>();
for (AnnotationNode anno : method.visibleAnnotations) {
if (anno.desc.equals(Comments.TYPE)) {
if (anno.desc.equals(Comments.TYPE) && anno.values.size() % 2 == 0) {
for (int i = 0; i < anno.values.size(); i += 2) {
Object keyInfo = anno.values.get(i);
Object comment = anno.values.get(i + 1);
Expand Down
69 changes: 3 additions & 66 deletions src/main/java/me/coley/recaf/util/IllegalBytecodePatcherUtil.java
@@ -1,14 +1,8 @@
package me.coley.recaf.util;

import me.coley.cafedude.ClassFile;
import me.coley.cafedude.InvalidClassException;
import me.coley.cafedude.constant.ConstPoolEntry;
import me.coley.cafedude.constant.CpClass;
import me.coley.cafedude.constant.CpUtf8;
import me.coley.cafedude.io.ClassFileReader;
import me.coley.cafedude.io.ClassFileWriter;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.*;

import java.util.Map;

Expand All @@ -31,7 +25,6 @@ public class IllegalBytecodePatcherUtil {
*/
public static byte[] fix(Map<String, byte[]> classes, Map<String, byte[]> invalidClasses, byte[] value) {
try {
String str = new String(value).toLowerCase();
ClassFile cf = new ClassFileReader().read(value);
// Patch oak classes (pre-java)
// - CafeDude does this by default
Expand All @@ -41,15 +34,17 @@ public static byte[] fix(Map<String, byte[]> classes, Map<String, byte[]> invali
cf.setVersionMinor(3);
return new ClassFileWriter().write(cf);
}
/*
// TODO: A good automated system to detect the problem would be handy
// - Something better than this obviously since these are essentially swappable watermarks
String str = new String(value).toLowerCase();
else if (str.contains("binscure") || str.contains("binclub") || str.contains("java/yeet")) {
return patchBinscure(cf);
} else {
// TODO: Other obfuscators that create invalid classes, like Paramorphism, should be supported
// - Some code for this already exists in the discord group but its outdated...
Log.info("Unknown protection on class file");
}
}*/
return new ClassFileWriter().write(cf);
} catch (Throwable t) {
// Fallback, yield original value
Expand All @@ -58,64 +53,6 @@ else if (str.contains("binscure") || str.contains("binclub") || str.contains("ja
}
}

/**
* Patch Binscure obfuscation.
*
* @param cf
* Classfile obfuscated by Binscure.
*
* @return ASM-parsable bytecode.
*
* @throws InvalidClassException
* When the class could not be read or written back to.
*/
private static byte[] patchBinscure(ClassFile cf) throws InvalidClassException {
// Swap illegal class names like "give up" to something legal
int bad = 1;
for (ConstPoolEntry entry : cf.getPool()) {
if (entry instanceof CpClass) {
CpUtf8 name = ((CpUtf8) cf.getPool().get(((CpClass) entry).getIndex()));
if (isIllegalName(name.getText())) {
name.setText("patched/binclub/FakeType" + (bad++));
}
}
}
// Write class-file back
byte[] out = new ClassFileWriter().write(cf);
// Attempt to pass-through asm to remove some extra junk,
// which assists some decompilers in not totally shitting themselves.
// The output is still trash, but at least there is output.
if (ClassUtil.isValidClass(out)) {
try {
ClassNode node = ClassUtil.getNode(new org.objectweb.asm.ClassReader(out),
org.objectweb.asm.ClassReader.EXPAND_FRAMES);
for (MethodNode mn : node.methods) {
for (AbstractInsnNode insn : mn.instructions) {
// These "ex-dee le may-may" named instructions are bogus.
// They're in code-blocks that get skipped over and only serve to include junk
// in the constant-pool that throws off decompilers.
if (insn instanceof InvokeDynamicInsnNode) {
InvokeDynamicInsnNode indy = (InvokeDynamicInsnNode) insn;
if (indy.bsm.getOwner().equals("java/yeet") ||
indy.name.equals("fuck") || indy.name.equals("yayeet")) {
mn.instructions.set(insn, new InsnNode(Opcodes.NOP));
}
}
}
// TODO: Find a nice way to remove bad catch blocks
}
return ClassUtil.toCode(node, 0);
} catch (Throwable t) {
Log.warn("Failed to remove junk INVOKEDYNAMIC instructions");
}
} else {
Log.error("Binscure process failed to fully patch class. New ASM crash method?");
}
// Fallback if second-asm pass fails.
// Classes should be valid at this point, but not entierly cleaned up.
return out;
}

private static boolean isIllegalName(String name) {
return name.matches(".*\\s+.*");
}
Expand Down

6 comments on commit b3ba422

@Crystallinqq
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

point of removing this, is?

@x4e
Copy link
Contributor

@x4e x4e commented on b3ba422 Mar 12, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Crystallinqq binscure won

@Crystallinqq
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$$

@Col-E
Copy link
Owner Author

@Col-E Col-E commented on b3ba422 Mar 12, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

binscure won

Uh huh, yeah you keep saying that πŸ˜‰

Instead of this trash Cafedood beats the crap outta binscure, nurses it back to health, only to give it one final curb-stomp.... ok that's a bit much, but this code is outdated so I removed it.

@Crystallinqq
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Downvoted.

@Col-E
Copy link
Owner Author

@Col-E Col-E commented on b3ba422 Mar 12, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anyways I'm gonna keep updating Cafedood to do the heavy lifting since ASM won't patch things. But when I have the time I'll put more work into countering obfuscation natively in Recaf.

Please sign in to comment.