AI+ Smali 等于 破解插件

升级完idea 之后 发现插件不对劲了 .

重新下载mybatis类插件 就下载了 MybatisCodeHelperPro

免费功能够用 但是每次提示激活

于是 tg中搜了下 发现居然没有..

简单的试下破解

插件位置

由于我是mac 电脑 在jetbrains toolbox的帮助下找到了idea的日志

根据日志拿到了插件的目录.

激活方式

插件界面如下

简单分析了插件激活页面之后 目标离线激活

寻找机会

在此之前 利用 jadx 和 recaf-gui 进行反编译和编译工作

输入任意编码提示错误信息.

在jadx中查到定位类

第一次 找到了公钥 解密的地方 经过一顿研究 发现私钥加密了原始数据 base64编码了密文 .

第二次 找到了解密后的数据格式 (感谢52破解的一个帖子 构建了成功的载荷格式)
{ "paidKey": "88888888-8888-8888-8888-888888888888", "valid": true, "userMac": "唯一码", "validTo": 4100688000000 }

破解逻辑绕过解密动作

这个时候用jadx 定位到类 在recaf-gui 中 用Smali 编辑class .

复制代码
  .inner public static {
    name: Decoder,
    inner: java/util/Base64$Decoder,
    outer: java/util/Base64
}
.inner public static final {
    name: Lookup,
    inner: java/lang/invoke/MethodHandles$Lookup,
    outer: java/lang/invoke/MethodHandles
}
.sourcefile "SourceFile"
.super java/lang/Object
.class public super com/ccnode/codegenerator/ag/f/e {

    .field private static a Lcom/google/gson/Gson; 

    .method public <init> ()V {
        parameters: { this },
        code: {
        A: 
            line 11
            aload this
            invokespecial java/lang/Object.<init> ()V
            return 
        B: 
        }
    }

    .method public static a (Ljava/lang/String;)Lcom/ccnode/codegenerator/ag/d/f; {
        parameters: { v0 },
        exceptions: { 
            { B, C, D, Lcom/ccnode/codegenerator/ag/f/b; }, 
            { G, H, I, Ljava/io/UnsupportedEncodingException; }, 
            { K, L, M, Ljava/lang/Exception; }
         },
        code: {
        A: 
            line 15
            aconst_null 
            astore v1
        B: 
            // try-start:   range=[B-C] handler=D:com/ccnode/codegenerator/ag/f/b 
            line 17
            new java/lang/String
            dup 
            invokestatic java/util/Base64.getDecoder ()Ljava/util/Base64$Decoder;
            ldc "TUlHZk1BMEdDU3FHU0liM0RRRUJBUVVBQTRHTkFEQ0JpUUtCZ1FDZzUyUjExV0h1MysvNUV2WnhkS0l2a3ovekpnS2VNUUhNLytMVkxSZS9zWUpFQlUxbUUrODc3MmJJckk4UThscldqSHc5cmVjQ1RWVVhXUnhWYXBndk1HYTZ3KzU4STZwYXdSaFhwZDBrRkhUY2xxeUZGWFpoS3ZiQUtoblphRGNuZkJtSkhObTQwR0JFTGpCTmx5MXpha2FIblFmUzF0QlhaSGQwOUV0c2VRSURBUUFC"
            invokevirtual java/util/Base64$Decoder.decode (Ljava/lang/String;)[B
            getstatic kotlin/text/Charsets.UTF_8 Ljava/nio/charset/Charset;
            invokespecial java/lang/String.<init> ([BLjava/nio/charset/Charset;)V
            invokestatic com/ccnode/codegenerator/ag/f/d.a (Ljava/lang/String;)Ljava/security/interfaces/RSAPublicKey;
            invokestatic java/util/Base64.getDecoder ()Ljava/util/Base64$Decoder;
            aload v0
            invokevirtual java/util/Base64$Decoder.decode (Ljava/lang/String;)[B
            invokestatic com/ccnode/codegenerator/ag/f/d.b (Ljava/security/interfaces/RSAPublicKey;[B)[B
            astore v1
        C: 
            // try-end:     range=[B-C] handler=D:com/ccnode/codegenerator/ag/f/b 
            line 20
            goto F
        D: 
            // try-handler: range=[B-C] handler=D:com/ccnode/codegenerator/ag/f/b 
            line 18
            astore v2
        E: 
            line 19
            new com/ccnode/codegenerator/ag/f/c
            dup 
            invokespecial com/ccnode/codegenerator/ag/f/c.<init> ()V
            invokestatic java/util/Base64.getDecoder ()Ljava/util/Base64$Decoder;
            aload v0
            invokevirtual java/util/Base64$Decoder.decode (Ljava/lang/String;)[B
            invokestatic com/ccnode/codegenerator/ag/f/d.b (Ljava/security/interfaces/RSAPublicKey;[B)[B
            astore v1
        F: 
            line 21
            aconst_null 
            astore v2
        G: 
            // try-start:   range=[G-H] handler=I:java/io/UnsupportedEncodingException 
            line 24
            new java/lang/String
            dup 
            aload v1
            ldc "UTF-8"
            invokespecial java/lang/String.<init> ([BLjava/lang/String;)V
            astore v3
        H: 
            // try-end:     range=[G-H] handler=I:java/io/UnsupportedEncodingException 
            line 27
            goto K
        I: 
            // try-handler: range=[G-H] handler=I:java/io/UnsupportedEncodingException 
            line 25
            astore v4
        J: 
            line 26
            new java/lang/RuntimeException
            dup 
            aload v4
            invokespecial java/lang/RuntimeException.<init> (Ljava/lang/Throwable;)V
            athrow 
        K: 
            // try-start:   range=[K-L] handler=M:java/lang/Exception 
            line 29
            getstatic com/ccnode/codegenerator/ag/f/e.a Lcom/google/gson/Gson;
            aload v3
            ldc Lcom/ccnode/codegenerator/ag/d/f;
            invokevirtual com/google/gson/Gson.fromJson (Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;
            checkcast com/ccnode/codegenerator/ag/d/f
            astore v2
        L: 
            // try-end:     range=[K-L] handler=M:java/lang/Exception 
            line 32
            goto O
        M: 
            // try-handler: range=[K-L] handler=M:java/lang/Exception 
            line 30
            astore v4
        N: 
            line 31
            new java/lang/RuntimeException
            dup 
            aload v3
            invokedynamic makeConcatWithConstants (Ljava/lang/String;)Ljava/lang/String; { invokestatic, java/lang/invoke/StringConcatFactory.makeConcatWithConstants, (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite; } { "gson catch exception, the json string is\u0001" }
            aload v4
            invokespecial java/lang/RuntimeException.<init> (Ljava/lang/String;Ljava/lang/Throwable;)V
            athrow 
        O: 
            line 33
            aload v2
            areturn 
        P: 
        }
    }

    .method static <clinit> ()V {
        code: {
        A: 
            line 12
            new com/google/gson/Gson
            dup 
            invokespecial com/google/gson/Gson.<init> ()V
            putstatic com/ccnode/codegenerator/ag/f/e.a Lcom/google/gson/Gson;
            return 
        B: 
        }
    }

}

直接将输入的字符串作为json传递给gson 反序列化

复制代码
  .inner public static {
    name: Decoder,
    inner: java/util/Base64$Decoder,
    outer: java/util/Base64
}
.inner public static final {
    name: Lookup,
    inner: java/lang/invoke/MethodHandles$Lookup,
    outer: java/lang/invoke/MethodHandles
}
.sourcefile "SourceFile"
.super java/lang/Object
.class public super com/ccnode/codegenerator/ag/f/e {

    .field private static a Lcom/google/gson/Gson; 

    .method public <init> ()V {
        parameters: { this },
        code: {
        A: 
            line 11
            aload this
            invokespecial java/lang/Object.<init> ()V
            return 
        B: 
        }
    }

    .method public static a (Ljava/lang/String;)Lcom/ccnode/codegenerator/ag/d/f; {
        parameters: { v0 },
        exceptions: { 
            { A, B, C, Ljava/lang/Exception; }
         },
        code: {
        A: 
            // try-start:   range=[A-B] handler=C:java/lang/Exception 
            line 29
            getstatic com/ccnode/codegenerator/ag/f/e.a Lcom/google/gson/Gson;
            aload v0
            ldc Lcom/ccnode/codegenerator/ag/d/f;
            invokevirtual com/google/gson/Gson.fromJson (Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;
            checkcast com/ccnode/codegenerator/ag/d/f
            astore v2
        B: 
            // try-end:     range=[A-B] handler=C:java/lang/Exception 
            line 32
            goto E
        C: 
            // try-handler: range=[A-B] handler=C:java/lang/Exception 
            line 30
            astore v4
        D: 
            line 31
            new java/lang/RuntimeException
            dup 
            aload v0
            invokedynamic makeConcatWithConstants (Ljava/lang/String;)Ljava/lang/String; { invokestatic, java/lang/invoke/StringConcatFactory.makeConcatWithConstants, (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite; } { "gson catch exception, the json string is\u0001" }
            aload v4
            invokespecial java/lang/RuntimeException.<init> (Ljava/lang/String;Ljava/lang/Throwable;)V
            athrow 
        E: 
            line 33
            aload v2
            areturn 
        F: 
        }
    }

    .method static <clinit> ()V {
        code: {
        A: 
            line 12
            new com/google/gson/Gson
            dup 
            invokespecial com/google/gson/Gson.<init> ()V
            putstatic com/ccnode/codegenerator/ag/f/e.a Lcom/google/gson/Gson;
            return 
        B: 
        }
    }

}

重复N+1次询问ai 语法

编译成功 导出工程

替换之后 重启idea 显示激活成功

唯一码计算代码

复制代码
    package com.free.api.oshitest;

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

public class Mac {
    private static final byte[][] VIRTUAL_MAC_PREFIXES = {{0, 5, 105}, {0, 28, 20}, {0, 12, 41}, {0, 80, 86}, {8, 0, 39}, {10, 0, 39}, {0, 3, -1}, {0, 21, 93}};

    public static void main(String[] args) {
        final String mac = getNetworkInfo("mac").getFirst();
        System.out.println(mac);
    }

    public static String mac() {
        return getNetworkInfo("mac").getFirst();
    }

    public static List<String> getNetworkInfo(String type) {
        List<String> result = new ArrayList<>();
        try {
            Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
            while (networkInterfaces.hasMoreElements()) {
                NetworkInterface networkInterface = networkInterfaces.nextElement();
                if (!isValidNetworkInterface(networkInterface)) {
                    continue;
                }

                Enumeration<InetAddress> inetAddresses = networkInterface.getInetAddresses();
                while (inetAddresses.hasMoreElements()) {
                    InetAddress inetAddress = inetAddresses.nextElement();
                    if (isLocalIPv4Address(inetAddress)) {
                        processNetworkAddress(inetAddress, type, result);
                    }
                }
            }
        } catch (SocketException e) {
            System.err.println("Error getting network interfaces: " + e.getMessage());
        } catch (UnknownHostException e) {
            System.err.println("Error resolving host: " + e.getMessage());
        }
        return result;
    }

    private static boolean isValidNetworkInterface(NetworkInterface networkInterface) throws SocketException {
        byte[] hardwareAddress = networkInterface.getHardwareAddress();
        return hardwareAddress != null && hardwareAddress.length > 0 && !isVirtualMacAddress(hardwareAddress);
    }

    private static boolean isLocalIPv4Address(InetAddress inetAddress) {
        return inetAddress instanceof Inet4Address && inetAddress.isSiteLocalAddress();
    }

    private static void processNetworkAddress(InetAddress inetAddress, String type, List<String> result) throws UnknownHostException {
        InetAddress address = InetAddress.getByName(inetAddress.getHostAddress());
        if (address == null) {
            return;
        }

        if ("ip".equals(type)) {
            String ip = address.toString().replaceAll("^/+", "");
            result.add(ip);
        } else if ("mac".equals(type)) {
            String mac = formatMacAddress(address);
            if (mac != null) {
                result.add(mac);
            }
        }
    }

    private static String formatMacAddress(InetAddress inetAddress) {
        try {
            byte[] hardwareAddress = NetworkInterface.getByInetAddress(inetAddress).getHardwareAddress();
            if (hardwareAddress == null) {
                return null;
            }

            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < hardwareAddress.length; i++) {
                sb.append(String.format("%02X", hardwareAddress[i]));
                if (i < hardwareAddress.length - 1) {
                    sb.append("-");
                }
            }
            return sb.toString();
        } catch (SocketException e) {
            System.err.println("Error getting MAC address: " + e.getMessage());
            return null;
        }
    }

    private static boolean isVirtualMacAddress(byte[] macAddress) {
        if (macAddress == null || macAddress.length < 3) {
            return false;
        }

        for (byte[] prefix : VIRTUAL_MAC_PREFIXES) {
            if (macAddress[0] == prefix[0] && macAddress[1] == prefix[1] && macAddress[2] == prefix[2]) {
                return true;
            }
        }
        return false;
    }
}

激活码构建程序

复制代码
package com.free.api.oshitest;

import com.google.gson.annotations.SerializedName;

public class f {
    @SerializedName(value = "paidKey")
    private String a;
    @SerializedName(value = "valid")
    private Boolean a2;
    @SerializedName(value = "userMac")
    private String b3;
    @SerializedName(value = "validTo")
    private Long a4;

    public String getA() {
        return a;
    }

    public void setA(String a) {
        this.a = a;
    }

    public Boolean getA2() {
        return a2;
    }

    public void setA2(Boolean a2) {
        this.a2 = a2;
    }

    public String getB3() {
        return b3;
    }

    public void setB3(String b3) {
        this.b3 = b3;
    }

    public Long getA4() {
        return a4;
    }

    public void setA4(Long a4) {
        this.a4 = a4;
    }

    @Override
    public String toString() {
        final StringBuffer sb = new StringBuffer("f{");
        sb.append("a='").append(a).append('\'');
        sb.append(", a2=").append(a2);
        sb.append(", b3='").append(b3).append('\'');
        sb.append(", a4=").append(a4);
        sb.append('}');
        return sb.toString();
    }
}
package com.free.api.oshitest;

import com.google.gson.Gson;

import java.util.Base64;

/**
 * @author: Yh
 * @date: 2025-10月-30 17:35:00 17:35
 */
public class GetKey {
    public static void main(String[] args) {
        f f = new f();
        f.setA("88888888-8888-8888-8888-888888888888");
        f.setA2(true);
        f.setA4(4100688000000L);
        f.setB3(Mac.mac());
        Gson gson = new Gson();
        final String json = gson.toJson(f);
        System.out.println(json);
        final String s = Base64.getEncoder().encodeToString(json.getBytes());
        System.out.println(s);
    }
}

kimi的协和之旅