【转载】JetBrains 全家桶系列 2024 破解思路....

转载声明:来源作者信息

关于(JetBrains 2024)

JetBrains 是一家全球性软件公司,专门为软件开发者和团队打造可以提升工作效率的智能工具。总部位于捷克共和国布拉格,在多个国家/地区设有研发实验室和销售办事处。

环境

  • IDEA
  • JDK 17
  • jadx

逆向分析

这块过程,直接省略吧;
代码各种混淆 跟 加密; 着实看不下去;
就在一筹莫展之际, 突然发现一个可行的破解方案;

这里以 GoLand 为例, 当 系统检测到未授权时,会弹出一个 license 框;
并且这个框在你输入license 之前退不了;

此刻, 我就想, 我们能不能 注入一些代码, 开启一个线程来检测 该 license 窗口, 并且来修改窗口属性呢??

一开始我自己写了一个 class, 代码如下:

class WindowWatcher {
    static {
System.out.println(">>>>>>>   WindowWatcher");
    }
}

然后把编译后的 WindowWatcher.class 随便找了一个 JetBrains 依赖的 JAR 塞进去了;

然后用命令后启动 GoLand;
发现打印的日志并没有我的 WindowWatcher;

不愧是 JetBrains, 想必 是用了自己写的类加载器, classLoader, 而且并不会加载 jar 包里所有的 class;

所有我们之前找 依赖里的 class 来反编译然后, 添加我们的 static 静态代码

     System.out.println(">>>>>>>   WindowWatcher");
     Thread watcherThread = new Thread(() -> {
        while (watcherFlag) {
            try {
               // 每隔5秒执行一次遍历
               Thread.sleep(5000);
               Window[] windows = Window.getWindows();
               for (Window window : windows) {
                   if (window instanceof JDialog dialog) {

                       List<JButton> buttons = getButtons(dialog);
                       for (JButton button : buttons) {
                           String text = button.getText();
                           // System.out.println("Button Text: " + text);
                           dialog.setTitle("K'ed by: marlkiller");
                           if (text != null && (text.contains("Quit") || text.contains("Close"))) {
                               // dialog.setTitle(dialog.getTitle() + " 请点击["+text+"] 按钮");
                               button.removeActionListener(button.getActionListeners()[0]);
                               button.setText("<Close>");
                               button.addActionListener(new ActionListener() {
                                   @Override
                                   public void actionPerformed(ActionEvent e) {
                                       watcherFlag = false;
                                       dialog.setVisible(false);
                                   }
                               });
                           }
                       }
                   }
               }
            } catch (InterruptedException e) {
               e.printStackTrace();
            }
        }
     });
     // 将线程设置为守护线程,随着主线程结束而结束
     watcherThread.setDaemon(true);
     watcherThread.start();

代码逻辑如下:
定时监测所有的窗口,
检测到 Licenses 窗口时 ,清除原始 Quit 按钮按钮的事件,
并且添加一个 close 当前 Dialog 的事件…

之后将class 覆盖, 然后重启app

之后会看到一个效果:

当弹出未授权窗口时, 点几 Quit 按钮, 该窗口就被隐藏了…
之后我们正常打开项目即可…

大概是考虑到社区版,以及不同产品的兼容性;
所以除了启动窗口的时候, 没看到有别的地方有什么限制;

除此之外, 还有一个破解思路;
用 Agent 来动态修改 字节码文件,
但是目前的 class混淆加密严重,着实不知道 agent 改给哪些clz 挂钩哦

搞了个 shell 脚本,一键替换打包资源

target_app="/Users/voidm/Applications/GoLand.app"
rewrite_file="$(pwd)/../out/production/java_dev/com/jetbrains/ls/responses/License.class"  
rewrite_file2="$(pwd)/../out/production/java_dev/com/jetbrains/ls/responses/License\$1.class"

echo "Changing directory to ${target_app}/Contents/lib" 
cd "${target_app}/Contents/lib"

# 查找包含目标 Class 的 jar 包
check_jar_for_class() {
    local directory="$1"
    local class_file="$2"
    local found=false

    for jar_file in "$directory"/*.jar; do
       if jar tf "$jar_file" | grep -q "$class_file"; then
           # 返回包含指定类文件的jar包名称
           echo "$(basename "$jar_file")"
           found=true
           return
       fi
    done

    # 如果未找到指定文件,则输出日志并退出
    if ! $found; then
       echo "target class_file not found" >&2
       exit 1
    fi
}

jar_name=$(check_jar_for_class "${target_app}/Contents/lib" "com/jetbrains/ls/responses/License.class")
echo "target_jar is : $jar_name"

jar_file="${target_app}/Contents/lib/${jar_name}"
jar_file_back="${jar_file}_Backup"

# 备份文件
if [ ! -f "$jar_file_back" ];
then
    echo "Backing up $jar_file to $jar_file_back"
    cp "$jar_file" "$jar_file_back"
fi

# 解压缩 Jar  
echo "Extracting ${jar_name}"
jar -xvf ${jar_name} com/jetbrains/ls/responses/License.class

# 替换文件
cp -f ${rewrite_file} "./com/jetbrains/ls/responses/License.class"  
cp -f ${rewrite_file2} "./com/jetbrains/ls/responses/License\$1.class"

# 重新打包
echo "Compressing ${jar_name}"
jar -uvf ${jar_name} "com/jetbrains/ls/responses/License.class"
jar -uvf ${jar_name} "com/jetbrains/ls/responses/License\$1.class"

# 清理临时文件
rm -rf ./com

后记

人啊, 不能太闲; 太闲的时候就会胡闹,比如这个胡闹出来的破解思路…
找工作真tm难…

仅供研究学习使用,请勿用于非法用途
注:若转载请注明来源(本贴地址)作者信息

34 个赞

软件开发软件分享

2 个赞

厉害了

2 个赞

有点东西

2 个赞

以为有现成的破解补丁就进来了

受教了

我选择继续用ja-netfilter :star_struck:

1 个赞

2024 试了下 ,按照之前的ja思路可以继续破解用吧。

不过还是欢迎新思路。 @jetbrains 快来修bug

求个成品,感谢

厉害了

@takatorury 完成下任务

666

厉害,mark

可以的,思路打开

1 个赞

学习下,谢谢分享

大佬,牛掰啊

MARK