常用破解教程仅供参考,仅供学习用途

news/2024/10/30 15:23:11/

 

破解过程大致如下// 反编译插件
// 修改注册逻辑代码
// 字节码写入
// 重新打包
// 替换jar包

破解方法

  1. 下载官方插件
  2. 将安装好的插件jar拷贝到桌面
  • Mac插件保存目录:/Users/username/Library/Application Support/WebStorm2017.2/Iedis/lib/
  1. 通过反射和javassist将混淆的字符串还原。
  2. 最终找到注册相关的类,通过javassist修改字节码文件并更新到原jar中,替换jar即可

工具准备

  • 反编译工具
  1. cfr
  2. procyon
  3. Luyten
  4. Fernfolower
  5. BytecodeViewer
  6. JD-gui
  • 查找文本中的相应字符串工具(Linux可以用自带的grep)
  • javassist(字节码修改工具)

示例:Iedis破解思路 

Iedis是IDEA上的一个收费redis插件,java编写的,既然是java写的,收费这些自然是很容易绕过的。由于Java太容易被反编译,作者还是做了些代码混淆和字符串加密。

利用JD-GUI反编译出来的代码片段

可以看出类名和字符串都被混淆和加密了,从代码上很难去定位和分析他的注册流程。

package com.seventh7.widget.iedis.config;import com.intellij.icons.AllIcons.General;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.ui.Messages;class iextends e
{private static final String[] ib;private static final String[] jb;i(n paramn){super(a(20539, 52876), a(20539, 52876), AllIcons.General.Remove, a(20537, 55341), paramn);}void a(AnActionEvent paramAnActionEvent, P paramP){String str1 = String.format(a(20538, 25199), new Object[] { paramP.f() });String str2 = a(20536, 20012);try{if (Messages.showOkCancelDialog(a(), str1, str2, Messages.getQuestionIcon()) == 0) {com.seventh7.widget.iedis.d.e.a().a(a(), paramP.b());}}catch (RuntimeException localRuntimeException){throw d(localRuntimeException);}}

破解的2个思路

  • 还原代码中的所有加密字符串,根据字符串的内定位到相关的代码,利用javassist修改class文件,将文件替换掉原来的文件
  • 逆向出他的认证算法,然后做个注册机之类的。iedis是采用服务器认证的,每次启动都要去服务器查询激活,所以注册机不适合。但是我们可以本地架设一个认证服务。

架设认证服务器还是比较简单的,下面还是主要研究一下第一种思路。

还原字符串

从那些混淆的代码去定位软件的运行逻辑很难下手,但是我们可以换个思路,将软件运行过程中字符串都打印出来,这样我们基本上就可以得到一份软件的运行日志,对java程序进行运行时插入语句看似很麻烦,其实JVM默认就支持javaagent,写个javaagent即可达到效果,javaagent的使用可以参考《javaagent-的使用》

  1. 编写javaagent程序
/*** 给iedis的加密字符串函数 插入打印代码*/
public class IedisTransformer implements ClassFileTransformer {private final static String IDEA_LIB="/Applications/IntelliJ IDEA.app/Contents/lib/*";private final static String IDEIS_LIB="/Users/liaojiacan/Library/Application Support/IntelliJIdea2017.2/Iedis/lib/*";public IedisTransformer() {try {ClassPool.getDefault().appendClassPath(IDEA_LIB);ClassPool.getDefault().appendClassPath(IDEIS_LIB);} catch (NotFoundException e) {e.printStackTrace();}}@Overridepublic byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {if(className.startsWith("com/seventh7/widget/iedis")){try {CtClass clazz = ClassPool.getDefault().makeClass(new ByteArrayInputStream(classfileBuffer));CtMethod[] methods = clazz.getDeclaredMethods();CtClass string = ClassPool.getDefault().getCtClass(String.class.getName());for(CtMethod method :methods){if(method.getLongName().startsWith("com.seventh7.widget.iedis.a.p.f")){System.out.println("Inject :: SUCCESS!");method.insertBefore("if(true){return true;} ");continue;}if(method.getReturnType().equals(string)){String name = method.getLongName();System.out.println("transform the iedis method:"+name);method.insertAfter("System.out.println(\"--------------------\");" +" System.out.println(\""+name+"\"); " +" System.out.println(java.util.Arrays.toString($args)); " +" System.out.println(\"return:\"+$_);");}}return clazz.toBytecode();} catch (IOException e) {e.printStackTrace();} catch (NotFoundException e) {e.printStackTrace();} catch (CannotCompileException e) {e.printStackTrace();}}return null;}
}
  1. 修改System.out,把所有的print打印到我们指定的文件中 /tmp/system.out
  2. public class Main {public static void premain(String agentOps, Instrumentation inst) {PrintStream out = null;try {out = new PrintStream("/tmp/system.out");} catch (FileNotFoundException e) {e.printStackTrace();}System.setOut(out);System.setErr(out);if ("iedis".equals(agentOps)){inst.addTransformer(new IedisTransformer());}else if("injectPrint".equals(agentOps)) {inst.addTransformer(new InjectPrintTransformer());}else {inst.addTransformer(new SimpleTransformer());}}public static void main(String[] args) {System.out.println(helloWorld());}public static String helloWorld(){return "This is a javaagent!";}
    }

     

  3. 配置idea启动配置,加入我们的javaagent
#修改idea.vmoptions文件加入下面一行配置
-javaagent:/Users/liaojiacan/Workspace/tools/decomplie/javaagent/javaagent-1.0-SNAPSHOT.jar=iedis
-Xms128m
-Xmx750m
-XX:ReservedCodeCacheSize=240m
-XX:+UseCompressedOops
-Dfile.encoding=UTF-8
-XX:+UseConcMarkSweepGC
-XX:SoftRefLRUPolicyMSPerMB=50
-ea
-Dsun.io.useCanonCaches=false
-Djava.net.preferIPv4Stack=true
-XX:+HeapDumpOnOutOfMemoryError
-XX:-OmitStackTraceInFastThrow
-Xverify:none-XX:ErrorFile=$USER_HOME/java_error_in_idea_%p.log
-XX:HeapDumpPath=$USER_HOME/java_error_in_idea.hprof
-Xbootclasspath/a:../lib/boot.jar

启动Idea 后我们可以在/tmp/system.out中可以看到这些关键的日志

--------------------
com.seventh7.widget.iedis.L.a(java.lang.String)
return:{"trailing":true,"daysLeft":9,"popup":true,"activated":false}
--------------------
com.seventh7.widget.iedis.B.a()
return:186b474e0ffffffb70ffffff96680ffffffc0240ffffff89456b0fffffffa320ffffffa70ffffff92
--------------------
com.seventh7.widget.iedis.x.a(byte[])
return:MTg2YjQ3NGUwZmZmZmZmYjcwZmZmZmZmOTY2ODBmZmZmZmZjMDI0MGZmZmZmZjg5NDU2YjBmZmZm
ZmZmYTMyMGZmZmZmZmE3MGZmZmZmZjkyOjI=
--------------------
com.seventh7.widget.iedis.L.a(java.lang.String)
return:{"trailing":true,"daysLeft":9,"popup":true,"activated":false}
--------------------com.seventh7.widget.iedis.L.a(java.lang.String)
[https://www.codesmagic.com/q2?t=MTg2YjQ3NGUwZmZmZmZmYjcwZmZmZmZmOTY2ODBmZmZmZmZjMDI0MGZmZmZmZjg5NDU2YjBmZmZmZmZmYTMyMGZmZmZmZmE3MGZmZmZmZjkyOjI=]
return:{"trailing":true,"daysLeft":9,"popup":true,"activated":false}
--------------------
com.seventh7.widget.iedis.a.p.b(int,int)
[-13938, -6118]
return:trailing
--------------------
com.seventh7.widget.iedis.a.p.b(int,int)
[-13937, -25088]
return:daysLeft
--------------------
com.seventh7.widget.iedis.a.p.b(int,int)
[-13939, 7216]
return:popup

从上面的日志可以看出一些关键点:

  • https://www.codesmagic.com/q2?t= 是注册的服务器

  • com.seventh7.widget.iedis.a.o 这个类是很关键的类

  • 认证服务器返回的认证结果为
    {“trailing”:true,“daysLeft”:9,“popup”:true,“activated”:false}

查看反编译的代码,可以看出这个类是一个抽象类,他的唯一子类是com.seventh7.widget.iedis.a.p,根据外面获取到的运行日志,大概可以推断出 f这个方法是认证的方法。

package com.seventh7.widget.iedis.a;import com.seventh7.widget.iedis.b.d.a;
import java.util.Map;
import java.io.IOException;
import com.seventh7.widget.iedis.L;class p extends o
{private static final String[] kb;private static final String[] lb;//基本上可以推断出 这个就是认证的方法,最直接的方法就是直接return true@Overrideprotected boolean f() throws IOException {//this.d() 是调用https://www.codesmagic.com/q2去注册的//Map的返回值{"trailing":true,"daysLeft":9,"popup":true,"activated":false}final Map d = this.d();//trailingfinal boolean booleanValue = L.a(d, b(-13938, -6118));//this.d()执行后的异常信息。final a[] b = av.b();//daysLeftfinal int b2 = L.b(d, b(-13937, -25088));//popupfinal boolean booleanValue2 = L.a(d, b(-13939, 7216));boolean booleanValue3 = false;Label_0104: {Label_0074: {boolean b3;try {b3 = (booleanValue3 = booleanValue);if (b != null) {break Label_0104;}if (b3) {break Label_0074;}break Label_0074;}catch (IOException ex) {throw b(ex);}try {if (b3) {this.a(b2, booleanValue2);return false;}}catch (IOException ex2) {throw b(ex2);}}//activedbooleanValue3 = L.a(d, b(-13940, 8507));}final boolean b4 = booleanValue3;//如果已经过了试用,就检测激活Label_0122: {boolean b5;try {final boolean b6;b5 = (b6 = b4);// b = av.b()if (b != null) {return b6;}if (!b5) {break Label_0122;}return true;}catch (IOException ex3) {throw b(ex3);}try {if (!b5) {this.c();return false;}}catch (IOException ex4) {throw b(ex4);}}return true;}private static IOException b(final IOException ex) {return ex;}}

从上面的分享结果可以看出,有两种破解思路

  • 方法一 修改 com.seventh7.widget.iedis.a.p.f 永远return true

  • 方法二 搭建一个认证服务器,本地替换host,认证服务器返回的结果为

{ "trailing": false, "popup": true, "activated": true, "daysLeft": 0 }

方法一的实现

public class IedisCracker {private final static String IDEA_LIB="/Applications/IntelliJ IDEA.app/Contents/lib/*";private final static String IDEIS_LIB="/Users/liaojiacan/Library/Application Support/IntelliJIdea2017.2/Iedis/lib/*";public static void main(String[] args) {try {ClassPool.getDefault().appendClassPath(IDEA_LIB);ClassPool.getDefault().appendClassPath(IDEIS_LIB);CtClass clazz = ClassPool.getDefault().getCtClass("com.seventh7.widget.iedis.a.p");CtMethod[] mds = clazz.getDeclaredMethods();for(CtMethod method : mds){if(method.getLongName().startsWith("com.seventh7.widget.iedis.a.p.f")){System.out.println("Inject :: SUCCESS!");try {method.insertBefore("if(true){return true;} ");} catch (CannotCompileException e) {e.printStackTrace();}continue;}}clazz.writeFile("/tmp/p.class");} catch (NotFoundException e) {e.printStackTrace();} catch (CannotCompileException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}
}

示例二:

 Javassist实现的破解IDEA MybatisPlugin修改字节码工具,仅供学习用途。

https://github.com/An0nymous0/MybatisPlugin-Crack-Javassist 

 

ps:

javaagent 的使用:

javaagent 是类似一个JVM的插件,利用JVM提供的Instrumentation API实现获取或者修改加载到JVM中的类字节码。

编写一个javagent的jar的方式如下:

1.实现一个ClassFileTransformer

public class SimpleTransformer implements ClassFileTransformer {@Overridepublic byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {System.out.println(className);System.out.println(protectionDomain.toString());return new byte[0];}
}
 

2.实现一个Premain-Class

public class Main {public static void premain(String agentOps, Instrumentation inst) {inst.addTransformer(new SimpleTransformer());}public static void main(String[] args) {System.out.println("This is a javaagent!");}
}

3.MANIFEST.MF配置

Manifest-Version: 1.0
Premain-Class: com.github.liaojiacan.Main
Can-Redefine-Classes: true
Can-Retransform-Classes: true
Can-Set-Native-Method-Prefix: true

4.运行命令

java -javaagent:agent.jar -jar app.jar

代码和assembly的打包配置可以参考

github

 

参考:https://www.awei.org/2017/11/19/idea-iedis-plugin-2-41-po-jie-fang-fa/


http://www.ppmy.cn/news/230782.html

相关文章

搭建ubuntu容器内C/C++开发调试环境

一、创建容器 为了让容器内的调试器&#xff08;gdb、lldb&#xff09;能够正常调试&#xff0c;在创建容器时需要添加参数&#xff1a; podman添加参数&#xff1a;--cap-addSYS_PTRACE&#xff0c;docker添加参数--cap-addSYS_PTRACE --security-opt seccompunconfined 否…

unity游戏框架学习-资源管理

概述:https://www.cnblogs.com/wang-jin-fu/p/10975660.html 这篇只涉及基础原理,下篇会讲如何实现一个简单的资源管理框架。 一、Assets和Objects 资源(Asset)是存储在Unity项目的 Assets 文件夹中的磁盘文件。有些资源的数据格式是Unity原声支持的,有些资源则需要转换为源…

Centos 7安装python3

Centos 7安装python3 Centos 7安装python3安装依赖包2.7版本备份下载&#xff0c;编译&#xff0c;安装创建软链接修复yum测试使用django安装 Centos 7安装python3 安装依赖包 yum -y groupinstall "Development tools"yum -y install zlib-devel bzip2-devel open…

用 Python 硬核从头实现一个神经网络

编者荐语 有个事情可能会让初学者惊讶&#xff1a;神经网络并不复杂&#xff01;『神经网络』这个词让人觉得很高大上&#xff0c;但实际上神经网络算法要比人们想象的简单。 链接丨https://victorzhou.com/blog/intro-to-neural-networks/ 这篇文章完全是为新手准备的。我们会…

saas产品私有化(一) 缓存中间件适配

一.背景 名词解释:私有化一般指的是在对客交付过程中,客户由于自身数据敏感,成本控制等原因要求交付乙方将售卖的服务利用现有甲方的硬件设备或者云服务进行服务的部署. 面向场景:一般特制的是saas化的云服务软件提供商的对特殊客群的场景.其中saas行业中比较起步和规模比较大的…

爱奇艺主界面

HTML <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>爱奇艺</title><link href"爱奇艺.css" type"text/css" rel"stylesheet"/> </head> <body…

音频播放卡顿优化

背景 音乐播放过程中,进行高CPU操作时,后台音乐播放出现卡滞。 分析 1、日志分析 日志中audioserver出现“AudioFlinger: underrun”的打印 05-27 15:35:00.186 396 777 W AudioFlinger: underrun, framesReady(0) < framesDesired(289), state: 6 05-27 15:35:0…

Android的UI卡顿

这篇文章我们主要从3个方面分析&#xff1a; 1.UI卡顿的原理 2.UI卡顿的原因分析 3.卡顿的总结 来看第一部分&#xff0c;UI卡顿的原理&#xff1a; 先来看下这样一个数字; 60fps -> 16ms 其实用户所感受到的卡顿的问题主要是来源于安卓的渲染性的问题。 我们的UI设…