diff options
author | zaaarf <zaaarf@proton.me> | 2023-06-11 14:48:24 +0200 |
---|---|---|
committer | zaaarf <zaaarf@proton.me> | 2023-06-11 14:48:24 +0200 |
commit | 7c427316a675cbe7e81a04294781c59f2606239d (patch) | |
tree | 3a4efc720f44205db6c518ee854f03eebf215e7c /src/main/java/ftbsc/lll/mapper/tools |
feat: initial implementation, created interface and moved stuff from processor
Diffstat (limited to 'src/main/java/ftbsc/lll/mapper/tools')
-rw-r--r-- | src/main/java/ftbsc/lll/mapper/tools/ClassData.java | 100 | ||||
-rw-r--r-- | src/main/java/ftbsc/lll/mapper/tools/MappingUtils.java | 56 |
2 files changed, 156 insertions, 0 deletions
diff --git a/src/main/java/ftbsc/lll/mapper/tools/ClassData.java b/src/main/java/ftbsc/lll/mapper/tools/ClassData.java new file mode 100644 index 0000000..a9fbcec --- /dev/null +++ b/src/main/java/ftbsc/lll/mapper/tools/ClassData.java @@ -0,0 +1,100 @@ +package ftbsc.lll.mapper.tools; + +import ftbsc.lll.exceptions.AmbiguousMappingException; +import ftbsc.lll.exceptions.MappingNotFoundException; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * Container class used to store information about classes. + */ +public class ClassData { + /** + * The unobfuscated name (FQN with '/' instad of '.') of the class. + */ + public final String unobf; + + /** + * The obfuscated internal name (FQN with '/' instad of '.') of the class. + */ + public final String obf; + + /** + * A {@link Map} tying each member's name or signature to its + * obfuscated counterpart. + */ + public final Map<String, String> members; + + /** + * The constructor. It takes in the names (obfuscated and non-obfuscated) + * of a class. + * @param unobf the unobfuscated name + * @param obf the obfuscated name + */ + public ClassData(String unobf, String obf) { + this.unobf = unobf; + this.obf = obf; + this.members = new HashMap<>(); + } + + /** + * Adds a member to the target class. + * For fields only the names are required; for methods, + * this takes in the full signature ({@code name + " " + space}). + * @param s the String representing the declaration line + */ + public void addMember(String s) { + String[] split = s.trim().split(" "); + if(split.length == 2) //field + members.put(split[0], split[1]); + else if (split.length == 3) //method + members.put(split[0] + " " + split[1], split[2]); + } + + /** + * Gets an obfuscated member given the method name and a method descriptor, + * which may be partial (i.e. not include return type) or null if the member + * is not a method. + * @param memberName member name + * @param methodDescriptor the method descriptor, or null if it's not a method + * @return the requested obfuscated name, or null if nothing was found + * @throws AmbiguousMappingException if not enough data was given to uniquely identify a mapping + */ + public String get(String memberName, String methodDescriptor) { + + //find all keys that start with the name + List<String> candidates = members.keySet().stream().filter( + m -> m.split(" ")[0].equals(memberName) + ).collect(Collectors.toList()); + + if(methodDescriptor != null) { + String signature = String.format("%s %s", memberName, methodDescriptor); + candidates = candidates.stream().filter( + m -> m.equals(signature) + ).collect(Collectors.toList()); + } + + switch(candidates.size()) { + case 0: + throw new MappingNotFoundException(String.format( + "%s.%s%s", + this.unobf, + memberName, + methodDescriptor == null ? "" : "()" + )); + case 1: + return members.get(candidates.get(0)); + default: + throw new AmbiguousMappingException(String.format( + "Mapper could not uniquely identify member %s.%s%s, found %d!", + this.unobf, + memberName, + methodDescriptor == null ? "" : "()", + candidates.size() + )); + } + } +}
\ No newline at end of file diff --git a/src/main/java/ftbsc/lll/mapper/tools/MappingUtils.java b/src/main/java/ftbsc/lll/mapper/tools/MappingUtils.java new file mode 100644 index 0000000..918052a --- /dev/null +++ b/src/main/java/ftbsc/lll/mapper/tools/MappingUtils.java @@ -0,0 +1,56 @@ +package ftbsc.lll.mapper.tools; + +import ftbsc.lll.exceptions.MappingNotFoundException; +import ftbsc.lll.mapper.IMapper; +import ftbsc.lll.tools.DescriptorBuilder; +import org.objectweb.asm.Type; + +public class MappingUtils { + /** + * Obfuscates a method descriptor, replacing its class references + * with their obfuscated counterparts. + * @param descriptor a {@link String} containing the descriptor + * @return the obfuscated descriptor + */ + public static String obfuscateMethodDescriptor(String descriptor, IMapper mapper) { + Type method = Type.getMethodType(descriptor); + Type[] arguments = method.getArgumentTypes(); + Type returnType = method.getReturnType(); + + Type[] obfArguments = new Type[arguments.length]; + for(int i = 0; i < obfArguments.length; i++) + obfArguments[i] = obfuscateType(arguments[i], mapper); + + return Type.getMethodDescriptor(obfuscateType(returnType, mapper), obfArguments); + } + + /** + * Given a {@link Type} and a valid {@link IMapper} it returns its obfuscated + * counterpart. + * @param type the type in question + * @return the obfuscated type + */ + public static Type obfuscateType(Type type, IMapper mapper) { + //unwrap arrays + Type unwrapped = type; + int arrayLevel = 0; + while(unwrapped.getSort() == Type.ARRAY) { + unwrapped = unwrapped.getElementType(); + arrayLevel++; + } + + //if it's a primitive no operation is needed + if(type.getSort() < Type.ARRAY) + return type; + + String internalName = type.getInternalName(); + + String internalNameObf; + try { + internalNameObf = mapper.obfuscateClass(internalName); + return Type.getType(DescriptorBuilder.nameToDescriptor(internalNameObf, arrayLevel)); + } catch(MappingNotFoundException e) { + return type; + } + } +} |