simplify
simplify copied to clipboard
[Bug] [SmaliVM] visitClassAnnotations() fail on parsing obfuscated member class names
Some obfuscators tend to rename member classes to short random strings like "Ab" or "Bc".
.class public final Lde/fipso/test/container/ui/ContainerActivity;
.super Landroidx/appcompat/app/AppCompatActivity;
.source "ContainerActivity.kt"
# annotations
.annotation system Ldalvik/annotation/MemberClasses;
value = {
Lde/fipso/test/rL;
}
.end annotation
visitInnerClasses() then fails to parse the inner and outer class name, because we are not using the default class name format with the $ as the separator. (java.lang.ArrayIndexOutOfBoundsException: 1 -> ClassBuilder.java:150);
EDIT: This could be a baksmali issue.
Thanks for the report. I'm also leaning towards this being a dexlib issue. If you can't reproduce with just baksmali, can you share a Dex file which causes the issue?
Seems like this is a feature of the Axan Obfuscator, but again this could be a misbehaviour in the smali class name generation by baksmali or dexlib.
I was able to come up with a dirty fix for this problem. Basically, I am just passing the parents Class name as the outer class name and using the full member class name as the inner class name.
private void visitInnerClasses(String parentClassName, BuilderEncodedValues.BuilderTypeEncodedValue value,
ClassWriter classWriter) {
// String name, String outerName, String innerName, int access
String internalName = value.getValue();
String fullName = stripName(value.getValue());
String[] parts = fullName.split("\\$", 2);
String outerName;
String innerName;
if (parts.length == 2){
outerName = parts[0];
innerName = parts[1];
}else{
outerName = parentClassName;
innerName = fullName;
}
System.out.println("visitInnerClasses(): " + outerName + "$" + innerName);
boolean isAnonymous = innerName.equals("1") || Ints.tryParse(innerName) != null;
if (isAnonymous) {
innerName = null;
}
int innerAccess = classManager.getVirtualClass(internalName).getClassDef().getAccessFlags();
classWriter.visitInnerClass(fullName, outerName, innerName, innerAccess);
}
Thanks for the extra detail and the fix. I'll have to read the java specs to see what's technically allowed and see if I can improve what you have here.
Also: I added smali syntax highlighting to github a while back so I changed your original comment to use it. :D