• 【逆向怎么玩】 动态调试一款牛逼C++ IDE实录


    声明

    • 本篇只从逆向兴趣出发,研究其程序运行原理。
    • CLion程序版权为jetBrains所有.
    • 注册码授权为jetBrains及其付费用户所有.
    • 不会释出任何完整的源代码.
    • 涉及能直接推算出注册码的地方打码.
    • 网上查了下,已有注册机,所以想要key的同学不要找我.

    CLion是什么?

    CLion是著名的jetBrains公司出的一款C/C++智能IDE。
    什么,你不知道jetBrains?
    我只提两点:

    • Visual Studio ReSharper (for C#)
    • IntelliJ IDEA (for java)

    你还是不知道?好吧,我确定你是emacs/vim党.

    CLion如下:


    背景

    在上篇:CLion注册码算法逆向分析实录

    我们通过结合jdb、jd-gui等工具,静态分析被混淆的clion.jar中的class信息,顺利拿到了CLion的注册码算法.

    但是,如果能在动态调试中分析代码路径,拿注册码算法或者改改功能啥的不是更酸爽么?

    本篇将从动态调试的角度展开逆向之旅,作为对上篇的一个补充。

    本篇用到的关键技术和工具:

    • java -verbose
    • HotSpot™ Serviceability Agent
    • jetBrains intellij IDEA 14.3
    • jetBrains CLion 1.0.4
    • jd-gui 1.2
    • jinfo
    • dump运行时的class信息
    • 带混淆调试
    • ClassPath和vm options修复

    动态调试的困难

    对于CLion这种产品级程序,我们面临以下困难:

    • 无源码
    • 字节码混淆
    • 运行时生成class和hotswap

    获取入口函数所在的类名

    办法总比困难多,让我们开始准备动态调试吧!

    通过上一篇博文的分析,我们已经熟悉了CLion程序启动的一些代码路径,首先要找到程序的入口函数main,并重建它。怎么找呢?

    • 方法1:通过启动脚本来找

    可以通过查看$CLION_HOME/bin下的clion.sh来看启动参数:

    133 MAIN_CLASS_NAME="$CL_MAIN_CLASS_NAME"
    134 if [ -z "$MAIN_CLASS_NAME" ]; then
    	  #注意这里
    135   MAIN_CLASS_NAME="com.intellij.idea.Main"
    136 fi
    ...
    176 LD_LIBRARY_PATH="$IDE_BIN_HOME:$LD_LIBRARY_PATH" "$JDK/bin/java" 
    177   $AGENT 
    178   "-Xbootclasspath/a:$IDE_HOME/lib/boot.jar" 
    179   -classpath "$CLASSPATH" 
    180   $VM_OPTIONS "-Djb.vmOptionsFile=$VM_OPTIONS_FILES_USED" 
    181   "-XX:ErrorFile=$HOME/java_error_in_CL_%p.log" 
    182   -Djb.restart.code=88 -Didea.paths.selector=clion10 
    183   $IDE_PROPERTIES_PROPERTY 
    184   $IDE_JVM_ARGS 
    185   $REQUIRED_JVM_ARGS 
          #以及这里
    186   $MAIN_CLASS_NAME 
    187   "$@"
    188 EC=$?
    
    
    • 方法2:通过jinfo来获取

    也可以让CLion先跑起来,通过jinfo来获取,首先通过jpsps -ef | grep clion来确认CLion的pid

    [haoran@localhost Tools]$ jps
    27120 Jps
    4001 Main
    26953 Main
    16911 Launcher
    

    接着输入jinfo pid,这里是jinfo 26953

    [haoran@localhost Tools]$ jinfo 26953
    Attaching to process ID 26953, please wait...
    Error attaching to process: sun.jvm.hotspot.runtime.VMVersionMismatchException: Supported versions are 25.45-b02. Target VM is 25.40-b25
    sun.jvm.hotspot.debugger.DebuggerException: sun.jvm.hotspot.runtime.VMVersionMismatchException: Supported versions are 25.45-b02. Target VM is 25.40-b25
    	at sun.jvm.hotspot.HotSpotAgent.setupVM(HotSpotAgent.java:435)
    	at sun.jvm.hotspot.HotSpotAgent.go(HotSpotAgent.java:305)
    	at sun.jvm.hotspot.HotSpotAgent.attach(HotSpotAgent.java:140)
    	at sun.jvm.hotspot.tools.Tool.start(Tool.java:185)
    	at sun.jvm.hotspot.tools.Tool.execute(Tool.java:118)
    	at sun.jvm.hotspot.tools.JInfo.main(JInfo.java:138)
    
    

    发现因为jre/jvm的版本不匹配,出现了异常,怎么解决呢?
    clion.sh入手,看看它如何指定jvm

    这里写图片描述

    可以发现,$IDE_HOME意即CLion安装的路径比$JAVA_HOME搜索的顺序更靠前,我们调整这个顺序即可避免jre/jvm版本不匹配的问题。

    调整后,再次利用jinfo pid来查看,得到如下信息:

    这里写图片描述

    之所以列举jre/jvm版本不匹配的异常问题,以及通过jinfo来获取程序入口函数所在类的方式,是为后续我们通过SA来dump运行时的class及修复java文件扫清障碍、奠定基础。


    新建入口类##

    我们已经得到main函数所在的类名为com.intellij.idea.Main,但是通过分析,发现其不在clion.jar中,那么它在哪里?

    我们通过在CLion启动参数中加入-verbose,并将结果重定向到文件中,来分析这个类所在的jar。

    如下所示:

    这里写图片描述

    接下来,通过jd-gui来反编译bootstrap.jar/com/intellij/idea/Main.class,并将其java代码导入到我们新建的同名java文件中:

    这里写图片描述


    修复入口类##

    这样的java代码是无法通过编译的,而且因为很多缺失的类都是很重要的依赖,所以无法通过简单的屏蔽来让代码跑起来。

    那我们开始修复这些缺失的类,怎么修复呢?

    我们可以使用HotSpot™ Serviceability Agent (SA)提供的能力,获取运行时的class。当然,获取运行时的class不只这一种方式。

    说干就干,classFilter:

    这里写图片描述


    编译好这个classFilter,按下面的步骤来运行:

    1. 运行CLion.
    2. 找到CLion的pid.
    3. 启动如下命令:

    java -cp $JAVA_HOME/lib/sa-jdi.jar:. 
    	 -Dsun.jvm.hotspot.tools.jcore.filter=$filterName 
    	 -Dsun.jvm.hotspot.tools.jcore.outputDir=$dumpedClassOutputDir 
    	 sun.jvm.hotspot.tools.jcore.ClassDump $clion_pid
    
    # $filterName  :我们自定义的classFilter
    # $dumpedClassOutputDir : 存放dump出的class文件的目录
    # $clion_pid :CLion进程pid.
    

    看下我们dump出的classes:

    这里写图片描述

    到这一步,已经成功了一大半,接下来,按照你喜欢的方式将这些classes加入classPath吧!


    修复ClassPath

    还在等什么,赶紧点run吧:

    这里写图片描述

    嗯,果不其然,很多类还是缺失,对于运行中生成的类,按上面的方法来找,对于已经在jar中的类,赶紧找找classPath还有什么吧。

    还记得上面的jinfo吧,祭出:

    这里写图片描述

    将这些加入ClassPath中。


    修复资源、运行时参数、及JVM的options##

    程序已经越来越接近跑起来的状态,还有一些细碎,奔跑吧骚年!

    Q. 此刻有没有一种,买来风扇,涂上硅胶,扣定开关的感觉?
    A. 要的就是这种能够DIY的工程师感觉嘛~^^

    你会发现,后续的运行中,还会出现许多异常,没有关系,通过分析,就知道还有一些东西没有修复,包括:

    • 资源/Resources
    • 运行时参数
    • vm options

    其中CLion的vm options我们依然通过jinfo方式获取:

    -Xss2m -Xms256m -Xmx768m -XX:MaxPermSize=250m
    -XX:ReservedCodeCacheSize=96m -XX:+UseConcMarkSweepGC
    ...
    -XX:ErrorFile=/home/haoran/java_error_in_CL_%p.log
    -Djb.restart.code=88 -Didea.paths.selector=clion10
    -Didea.platform.prefix=CLion
    -Didea.no.jre.check=true


    让程序动起来!##

    做完了上面细碎的功夫,来看看我们的成果:

    • 华丽丽的Stack Frames!

    这里写图片描述


    • 华丽丽的Locals!

    这里写图片描述


    • 华丽丽的注册码算法!
      这里写图片描述

    这里写图片描述


    结语##

    什么?没有动态调试过程?

    有意研究注册码算法的同学,请参考上篇博文:CLion注册码算法逆向分析实录.但是不要做坏事哦 :]

    我觉得上面的几个华丽丽的东西已经足够你

    • step in/over/out (单步 步入/步过/跳出)
    • evaluate expressions (表达式计算)
    • stack frame in/out (栈帧切换)
    • break point (断点啊亲)

    有了这些还追不出注册码算法么?
    骚年,那你该反思了 :]

    这里写图片描述


    撰文不易,若觉得本文对你有帮助或者博你一笑的,留个言、点个推荐吧 :]

  • 相关阅读:
    HTML5 与 CSS3 jQuery部分知识总结【转】
    JS中检测数据类型的几种方式及优缺点【转】
    PHP 小数点保留两位【转】
    ES6中的const命令【转】
    bootstrap学习笔记【转】
    让一个元素垂直水平居中的三种方法【转】
    JavaScript笔试必备语句【转】
    网站优化——前端部分【转】
    移动App服务端架构设计
    IE6浏览器常见的bug及其修复方法
  • 原文地址:https://www.cnblogs.com/foreach-break/p/crack_clion_jar_and_debug_with_Serviceability_Agent.html
Copyright © 2020-2023  润新知