ASM и Minecraft обфускация

Версия Minecraft
1.7.10
API
Forge
236
4
22
Всем привет. Есть такой вопрос, который я всё время решал раньше костылём и, в принципе, было прекрасно. Но вот что-то сегодня этот костыль не прокатил. Вообщем вот есть кусок кода, комментарием помечен мой костыль:

Java:
public class MyASMHook implements IClassTransformer {

    @Override
    public byte[] transform(String name, String transformedName, byte[] basicClass) {
        if(!transformedName.equals("net.minecraft.util.MessageDeserializer")) return basicClass;
        var obf = !name.equals(transformedName); //Вот тот самый костыль
        var classNode = new ClassNode();
        var classReader = new ClassReader(basicClass);
        classReader.accept(classNode, 0);
        //Тут мои модификации методов, не относится к теме
        var writer = new ClassWriter(0);
        classNode.accept(writer);
        return writer.toByteArray();
    }

}
Дело в том, чтобы полноценно использовать ASM нужно точно знать обфусцирована ли игра. Если, допустим, при поиске методов я и могу написать if(method.name.equals("a") || method.name.equals("func_103191a") || method.name.equals("normalName")), то при вставке опкодов на уровне INVOKE... уже требуется чёткое имя класса, метода и его дескриптор (а значит точные имена классов аргументов метода), ибо в противном случае будет краш из-за несуществующего метода. В transformedName, как я понял, всегда находится "нормальное" имя класса через '.', будь оно из майнкрафта или же из модов. А name - текущее имя класса ("в рантайме"). Логично, что по идеи, чтобы определить, обфусцирована ли игра - нужно проверить неравенство этих 2 строк, что я всегда и делал. Но на этот раз не повезло. Я думал ошибку сделал в логике хука, но нет. Для отладки я добавил принт неравенства строки и принт всех опкодов и (если они instanceof MethodInsNode) их owner, name и desc. В результате я получил необфусцированные (нормальные) имена классов и нормальные (для майнкрафта) имена методов (тобишь func_1121a и т.п.), а вот строки эти были не равны. В итоге obf = true, но судя по опкодам - должна быть false. Как же гарантировано узнать, требуется использование обфусцированного или обычного имени класса/метода при поиске/инвоке?
 
236
4
22
ObfuscationReflectionHelper
Это совершенно не поможет. Такое только в рантайме годится ибо под капотом идёт просто подбор "правильного" названия филды (если ты про геттеры полей) + ещё будет ранняя попытка обратиться к классу (из этого хелпера), который ещё на этапе ASM модификации и не загрузился в JVM - краш.
FMLLaunchHandler.isDeobfuscatedEnvironment()
Такого метода нет.

Нашёл филду deobfuscatedEnvironment. Как я понял, ты про неё говоришь. Но она запривачена - нужно стучаться рефлексией ибо явно AT не снимет приват ачесс. Ну видимо это единственный способ...
 
1,038
57
229
попробуй добавить ignoreCase или toLowerCase.
С трансформерами не работал, поэтому тяжело что-то советовать в асбтрактном мышлении.
Если всё работало раньше, наверняка ошибка где то на поверхности, банальщина какая нить, которую упустил из виду.
 
236
4
22
FMLLaunchHandler.isDeobfuscatedEnvironment() до неё и стучится напрямую без рефлексии. Посмотри, мб у тебя там что-то схожее есть
Нету, но по сурсам игры нашёл другое решение. Главный класс, где мы регистрируем ASM трансформеры (и путь к которому пишем в манифесте мода) имеет метод injectData и передаёт Map. В этой мапе по опред. ключу есть булева deobfuscatedEnvironment. Ключ можно в сурсах посмотреть. Правда пока на ту затею, где мне нужен был ASM я забил, но дела нет.
 
1,074
72
372
Вариант 1: Использовать значение параметра из blackboard
Java:
boolean deobf = (boolean)Launch.blackboard.get("fml.deobfuscatedEnvironment");

Вариант 2: Универсальный. Проверяем существование файла (на них трансформеры не распространяются).
Java:
URL url = LoadingPlugin.class.getResource("/net/minecraft/world/World.class"); // Можно любой класс ванили, меняющий имя
boolean isObfuscated = url == null;
 
Сверху