冰凌汇编

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 181|回复: 2
收起左侧

[分享] FR10.0 另一揭破思路

[复制链接]
bingling 发表于 2022-3-10 22:00:41
请问一下论坛里面研究FR的大神,有没有发现这款软件有什么暗装呢?发出来一起交流一下呗。
前些天看了论坛一位大神的帖子https://www.52pojie.cn/thread-1012601-1-1.html,试着弄了一下,真的被FR10的加密给弄崩溃了
于是想到了一个新思路,是否可以在它加载完关键类之后,从jvm里面取出字节码修改后再替换回去呢?

分享一下我的思路吧

启动FR,使用HSDB工具拿到三个类:
1、com.fr.license.selector.EncryptedLicenseSelector
2、com.fr.license.security.LicFileRegistry
3、com.fr.license.entity.FineLicense

FR10.0 另一揭破思路 - bingling_冰凌汇编

需要修改以下几个关键的地方:
1、com.fr.license.selector.EncryptedLicenseSelector的decrypt方法:

[Java] 纯文本查看 复制代码
public abstract class EncryptedLicenseSelector extends AbstractLicenseSelector {
    byte[] getBytes() {
        byte[] var1 = this.readRawBytes();
        return this.decrypt(var1);
    }
 
    private byte[] decrypt(byte[] var1) {   // 修改为 return var1;
        try {
            System.getProperties().setProperty("com.ibm.crypto.provider.DoRSATypeChecking", "false");
            return (new CommonDecryptChain()).decrypt(var1);
        } catch (Throwable var3) {
            this.decryptFailed(var3);
            return new byte[0];
        }
    }
 
    protected void decryptFailed(Throwable var1) {
        FineLoggerFactory.getLogger().error("Read license failed." + var1.getMessage(), var1);
    }
 
    abstract byte[] readRawBytes();
}


其实修改这一个地方就够了,另外两处修改可用于方便懒人。

2、com.fr.license.security.LicFileRegistry的check方法:
[Java] 纯文本查看 复制代码
public class LicFileRegistry {
    private static Map<Integer, LicFileChecker> _2c75dfba_fdee_47fa_8cf4_74897f6d7e9a = new ConcurrentHashMap(5);
 
    private LicFileRegistry() {
    }
 
    static {
        register(new LicFileCheckerImpl());
    }
 
    public static void register(LicFileChecker var0) {
        _2c75dfba_fdee_47fa_8cf4_74897f6d7e9a.put(var0.getTypeCode(), var0);
    }
 
    public static boolean check(InputStream var0, Integer var1) {   // 修改为 return true;
        LicFileChecker var2 = _2c75dfba_fdee_47fa_8cf4_74897f6d7e9a.get(var1);
        return var2 != null && var2.check(var0);
    }
}


修改这里主要是破解lic上传注册。

3、com.fr.license.entity.FineLicense的两个support方法:
[Java] 纯文本查看 复制代码
public class FineLicense extends AbstractLicense {
    public FineLicense(JSONObject var1) {
        super(var1);
    }
 
    public String getString(String var1, String var2) {
        return super.getInnerString(var1, var2);
    }
 
    public boolean support(PluginMarker var1) { // 修改为 return true;
        if (var1 == null) {
            return false;
        } else {
            try {
                JSONObject var2 = this.getJSONObject();
                if (var2.has(LicenseItem.Plugin.getKey())) {
                    JSONArray var3 = var2.getJSONArray(LicenseItem.Plugin.getKey());
 
                    for(int var5 = 0; var5 < var3.length(); ++var5) {
                        String[] var4 = var3.getString(var5).split(",");
                        if (var4.length >= 2 && var1.getPluginID().equals(var4[0])) {
                            return true;
                        }
                    }
                }
            } catch (Exception var6) {
                FineLoggerFactory.getLogger().error(var6.getMessage(), var6);
            }
 
            return false;
        }
    }
 
    public boolean support(FunctionPoint var1) {    // 修改为 return true;
        String var2 = this.getString(LicenseItem.Function.getKey(), "");
        if (StringUtils.isNotBlank(var2)) {
            BigInteger var3 = new BigInteger(String.valueOf(var2));
            return var3.and(BigInteger.ONE.shiftLeft(var1.getMarker())).compareTo(BigInteger.ZERO) == 1;
        } else {
            return true;
        }
    }


主要用于破解收费插件。

修改之后的代码可自行编译为class字节码,使用javaagent替换,不过不推荐。因为每次小更新部分类的成员变量名都会随机变化,使得破解失效,
因此建议拿到加载后的字节码自行进行修改并使用javaagent替换,以第一个关键类为例,代码如下:

[Java] 纯文本查看 复制代码
public class FxxxAgent {
    public static void agentmain(String args, Instrumentation inst) throws Exception {
        Class<?>[] classes = inst.getAllLoadedClasses();
        for (Class<?> clazz : classes) {
            if (clazz.getName().equals("com.fr.license.selector.EncryptedLicenseSelector")) {
                inst.addTransformer((loader, className, classBeingRedefined, protectionDomain, classfileBuffer) -> {
                    if (className.equals("com/fr/license/selector/EncryptedLicenseSelector")) {
                        try {
                            DataInputStream inputStream = new DataInputStream(new ByteArrayInputStream(classfileBuffer));
                            ClassFile classFile = new ClassFile(inputStream);
                            inputStream.close();
                            ConstPool constPool = classFile.getConstPool();
                            MethodInfo methodInfo = classFile.getMethod("decrypt");
                            CodeAttribute codeAttribute = new CodeAttribute(constPool, 1, 2, new byte[]{43, -80},
                                    new ExceptionTable(constPool));
                            methodInfo.setCodeAttribute(codeAttribute);
                            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                            DataOutputStream outputStream = new DataOutputStream(byteArrayOutputStream);
                            classFile.write(outputStream);
                            outputStream.close();
                            byte[] result = byteArrayOutputStream.toByteArray();
                            byteArrayOutputStream.close();
                            return result;
                        } catch (Exception e) {
                            e.printStackTrace();
                            return classfileBuffer;
                        }
                    } else {
                        return classfileBuffer;
                    }
                });
                inst.retransformClasses(clazz);
            }
        }
    }
}


在manifest.sf文件中加上一行:Agent-Class: 刚刚编辑的类名,打包成jar文件备用。

为了使这些代码可以运行起来,需要找个地方写上一些自己的代码,我找的是fine-core-10.0.jar下的com.fr.runtime.FineRuntime这个类,
在initEncryptedBridge方法的最下面加上了自己的代码:

[Java] 纯文本查看 复制代码
private static void initEncryptedBridge() throws Exception {
    ClassLoader var0 = (ClassLoader) Class.forName(START_LOADER_FACTORY_NAME).newInstance();
    Class.forName("com.fr.plugin.bridge.FinePluginBridge", true, var0);
    String name = ManagementFactory.getRuntimeMXBean().getName();
    String pid = name.substring(0, name.indexOf('@'));
    VirtualMachine virtualMachine = VirtualMachine.attach(pid);
    virtualMachine.loadAgent("D:/agent.jar", null); // 这里的路径即为刚刚打的jar包路径
    virtualMachine.detach();
}


用winrar打开fr-core-10.0.jar,将编译好的FineRuntime.class替换,或者单独打成jar包,保证文件名能排在fr-core-10.0.jar的前面,放在WEB-INF\lib目录里

用如下内容的注册文件注册即可

[XML] 纯文本查看 复制代码
{"VERSION":"10.0","DEADLINE":"253402271999000","CONCURRENCY":"0"}


最后把自己的代码分享给大家吧。
https://github.com/2316361/FineCrack
冰凌汇编免责声明
以上内容均来自网友转发或原创,如存在侵权请发送到站方邮件9003554@qq.com处理。
Sebastian 发表于 2022-3-13 13:35:02
 - Sebastian_冰凌汇编 - Sebastian_冰凌汇编 - Sebastian_冰凌汇编
3366470538 发表于 2022-3-13 13:41:55
good - 3366470538_冰凌汇编
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|站点统计|Archiver|小黑屋|RSS|冰凌汇编 ( 滇ICP备2022002049号 滇公网安备 53032102000029号)|网站地图

GMT+8, 2022-9-25 06:31 , Processed in 0.139729 second(s), 8 queries , Redis On.

冰凌汇编 - 建立于2021年12月20日

Powered by Discuz! © 2001-2022 Comsenz Inc.

快速回复 返回顶部 返回列表