Class Remapper
Objectweb ASM Classnodes as input and output them without having
to go through an intermediary store-to-file mode.
Additionally, this is a no-bullshit remapper. It will only remap, not change your Access flags,
LVT entries or anything like that. If you want a deobfuscator,
use Oaktree after remapping.-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionvoidaddTarget(org.objectweb.asm.tree.ClassNode node) Adds a single class node to remapvoidaddTargets(Collection<org.objectweb.asm.tree.ClassNode> nodes) Adds multiple class nodes to remapvoidfixICNNames(StringBuilder sharedBuilder) Fixes remappedInnerClassNodeby remapping any child classes alongside their parent class, even if only the parent class was remapped.List<org.objectweb.asm.tree.ClassNode>Note: due to the circumstances of how the remapper works, this method call may be not required as the remapper remaps the input ClassNodes without cloning them in any capacity.@NotNull StringgetRemappedClassName(@NotNull String name) Remaps a class name.@NotNull StringgetRemappedFieldDescriptor(@NotNull String fieldDesc, @NotNull StringBuilder sharedBuilder) Remaps a field descriptor.@NotNull StringgetRemappedFieldName(@NotNull String owner, @NotNull String name, @NotNull String desc) Remaps a field name.@NotNull StringgetRemappedMethodDescriptor(@NotNull String methodDesc, @NotNull StringBuilder sharedBuilder) Remaps a method descriptor.@NotNull StringgetRemappedMethodName(@NotNull String owner, @NotNull String name, @NotNull String desc) Remaps a method name.voidprocess()Processes all remap orders and clears the remap orders afterwards.voidremapClassName(String oldName, String newName) Remaps the name of all target class nodes onceprocess()is called.voidremapClassNames(Map<String, String> mappings) Remaps the name of all target class nodes onceprocess()is called.voidremapField(String owner, String desc, String oldName, String newName) Inserts a field renaming entry to the remapping list.voidremapMethod(String owner, String desc, String oldName, String newName) Inserts a method renaming entry to the remapping list.voidremoveMethodRemap(String owner, String desc, String name) Removes a method remapping entry from the method remapping list.
-
Constructor Details
-
Remapper
public Remapper()
-
-
Method Details
-
addTarget
public void addTarget(org.objectweb.asm.tree.ClassNode node) Adds a single class node to remap- Parameters:
node- The class node
-
addTargets
Adds multiple class nodes to remap- Parameters:
nodes- The class nodes
-
clearTargets
public void clearTargets() -
fixICNNames
Fixes remappedInnerClassNodeby remapping any child classes alongside their parent class, even if only the parent class was remapped. Due to the potentially destructive properties of this action, this method must be explicitly invoked for it to do anything.More specifically if the class "OuterClass" is remapped to "RootClass", but "OuterClass$Inner" is not remapped, then after
process()the classes "RootClass" and "OuterClass$Inner" will exist. As the names contradict the relation given by theirInnerClassNode, most decompilers will discard theInnerClassNode.To fix this issue, this method will look for such changes and renames the inner classes accordingly.
This method will only do anything if it is called before
process()and will modify the internal collection of remapped classes.The more
ClassNodesthere are, the more efficient this method is at doing what it should do.This method can be destructive as it will not check for collisions.
- Parameters:
sharedBuilder- A sharedStringBuilderto reduce memory consumption created by string operations- Returns:
- A map that contains ALL additional mappings where as the key is the old name and the value the new name.
-
getOutput
Note: due to the circumstances of how the remapper works, this method call may be not required as the remapper remaps the input ClassNodes without cloning them in any capacity.- Returns:
- Returns the targets
-
getRemappedClassName
Remaps a class name.- Parameters:
name- The old (unmapped) class name- Returns:
- The new (remapped) class name
-
getRemappedFieldDescriptor
@NotNull public @NotNull String getRemappedFieldDescriptor(@NotNull @NotNull String fieldDesc, @NotNull @NotNull StringBuilder sharedBuilder) Remaps a field descriptor.- Parameters:
fieldDesc- The old (unmapped) field descriptorsharedBuilder- A shared cached string builder. The contents of the string builder are wiped and after the invocation the contents are undefined- Returns:
- The new (remapped) field descriptor. It can be identity identical to the "fieldDesc" if it didn't need to be altered
-
getRemappedFieldName
@NotNull public @NotNull String getRemappedFieldName(@NotNull @NotNull String owner, @NotNull @NotNull String name, @NotNull @NotNull String desc) Remaps a field name.- Parameters:
owner- The old (unmapped) class namename- The old (unmapped) field namedesc- The old (unmapped) field descriptor- Returns:
- The new (remapped) field name
- Since:
- 0.1.0
-
getRemappedMethodDescriptor
@NotNull public @NotNull String getRemappedMethodDescriptor(@NotNull @NotNull String methodDesc, @NotNull @NotNull StringBuilder sharedBuilder) Remaps a method descriptor.- Parameters:
methodDesc- The old (unmapped) method descriptorsharedBuilder- A shared cached string builder. The contents of the string builder are wiped and after the invocation the contents are undefined- Returns:
- The new (remapped) method descriptor. It can be identity identical to the "methodDesc" if it didn't need to be altered
-
getRemappedMethodName
@NotNull public @NotNull String getRemappedMethodName(@NotNull @NotNull String owner, @NotNull @NotNull String name, @NotNull @NotNull String desc) Remaps a method name.- Parameters:
owner- The old (unmapped) class namename- The old (unmapped) method namedesc- The old (unmapped) method descriptor- Returns:
- The new (remapped) method name
- Since:
- 0.1.0
-
process
public void process()Processes all remap orders and clears the remap orders afterwards. The classes that need to be processed remain in the targets list untilclearTargets()is invoked. This allows for reusability of the same remapper instance. Class names are remapped last. -
remapClassName
Remaps the name of all target class nodes onceprocess()is called. Class names are remapped alongside method / fields however technically they are remapped last.- Parameters:
oldName- The old internal class name of the class to remapnewName- The new internal class name of the class to remap
-
remapClassNames
Remaps the name of all target class nodes onceprocess()is called. Class names are remapped alongside method / fields however technically they are remapped last. This is a bulk method. And is similar to callingremapClassName(String, String).- Parameters:
mappings- A map that represents all the class remaps. Keys are old names, values are new names.
-
remapField
Inserts a field renaming entry to the remapping list. The owner and desc strings must be valid for the current class names, i. e. withoutremapClassName(String, String)andprocess()applied. The fields are not actually renamed untilprocess()is invoked. These tasks are however removed as soon asprocess()is invoked. UnlikeremapMethod(String, String, String, String), this method will do it's best to propagate field renames to child classes. However it may miss a few if not all classes are declared as targets. However one would still be able to explicitly add a remap via this method.- Parameters:
owner- The internal name of the current owner of the fielddesc- The descriptor string of the field entryoldName- The old name of the fieldnewName- The new name of the field- See Also:
-
Type.getInternalName()
-
remapMethod
public void remapMethod(String owner, String desc, String oldName, String newName) throws ConflicitingMappingException Inserts a method renaming entry to the remapping list. The owner and desc strings must be valid for the current class names, i. e. withoutremapClassName(String, String)andprocess()applied. The method are not actually renamed untilprocess()is invoked.WARNING: if the method is non-static and non-private and the owning class non-final then it is recommended that the change is propagated through the entire tree. Renaming a method will only affect one class, not multiple - which may void overrides or other similar behaviours.
- Parameters:
owner- The internal name of the current owner of the methoddesc- The descriptor string of the method entryoldName- The old name of the methodnewName- The new name of the method- Throws:
ConflicitingMappingException- If a mapping error occurs.- See Also:
-
Type.getInternalName()
-
removeMethodRemap
Removes a method remapping entry from the method remapping list. This method practically undoesremapMethod(String, String, String, String). Like it it only affects a SINGLE method in a SINGLE class and it's references. Note that implicitly declared/inherited methods must also be added to the remap list.- Parameters:
owner- The class of the method that should not be remappeddesc- The descriptor of the method to not remapname- The name of the method that should not be remapped
-