不想无限使用,直接破解到正版:

输入邮箱 名字之后 还有licence信息之后,处理函数是:

this.text.getText() 很明显是你输入的licence.   然后交给父类okPress处理了.      licence字符串存放的变量是 this.r.   获取这个变量的方法是 am()

查看调用licence信息的地方:

t3.common.lic.a.d.bb(). :   把用户输入用this.aT.a()进行处理.   aT对象的类名是:t3.utils.a

展示licence信息的地方: t3.common.lic.j.a():

licence信息存储组织方法 t3.common.lic.a.j.a():。    猜测xVar应该是服务器传过来的.

核心类: 对用户输入的licence进行处理

分析:

String x = RegisteredLicenseDocumentFormatter.m886x(str);

License f = this.f711aX.mo903f(x);

if (!f.getStatus().isActive()) {
this.f710aW.mo720O(f.getStatus().getDescription());
return;
}

随便输入licence信息得到如下信息.  .f710aW.mo720O 是显示错误的对话框.

Your license key seems to be corrupted. Make sure you have copied all text between and including the --- markers at the start and end of the license key.

这个信息的显示意味着走了异常的代码, 这个异常处有一个打印具体的信息. 等会看这个异常原因.   因为不知道是哪一步异常的.

先找到输出日志的文件:

错误详细:

从错误信息中可以看到 是  执行License f = this.f711aX.mo903f(x); 这个语句就异常了.   [ at t3.common.lic.a.i.a(ManagerController.java:61)]

.method private z(Ljava/lang/String;)Lt3/common/lic/h;
.registers 9 .prologue
const/4 v1, 0x0 const/4 v3, 0x1 const/4 v4, 0x0 .line 154
.line 156
:try_start_3
const-string v0, "X.509" invoke-static {v0}, Ljava/security/cert/CertificateFactory;->getInstance(Ljava/lang/String;)Ljava/security/cert/CertificateFactory; move-result-object v0 .line 157
const-class v2, Lt3/common/lic/ae; const-string v5, "/t3/common/lic/licensing_public.cer" invoke-virtual {v2, v5}, Ljava/lang/Class;->getResourceAsStream(Ljava/lang/String;)Ljava/io/InputStream;
:try_end_10
.catch Ljava/security/cert/CertificateException; {:try_start_3 .. :try_end_10} :catch_49 move-result-object v2 .line 160
if-eqz v2, :cond_aa .line 163
:try_start_13
invoke-virtual {v0, v2}, Ljava/security/cert/CertificateFactory;->generateCertificate(Ljava/io/InputStream;)Ljava/security/cert/Certificate; move-result-object v0 check-cast v0, Ljava/security/cert/X509Certificate;
:try_end_19
.catchall {:try_start_13 .. :try_end_19} :catchall_63 .line 167
:try_start_19
invoke-virtual {v2}, Ljava/io/InputStream;->close()V
:try_end_1c
.catch Ljava/io/IOException; {:try_start_19 .. :try_end_1c} :catch_59
.catch Ljava/security/cert/CertificateException; {:try_start_19 .. :try_end_1c} :catch_49 .line 177
:goto_1c
:try_start_1c
const-string v2, "SHA-1" invoke-static {v2}, Ljava/security/MessageDigest;->getInstance(Ljava/lang/String;)Ljava/security/MessageDigest; move-result-object v2 .line 178
invoke-virtual {v0}, Ljava/security/cert/X509Certificate;->getEncoded()[B move-result-object v5 invoke-virtual {v2, v5}, Ljava/security/MessageDigest;->update([B)V .line 179
invoke-virtual {v2}, Ljava/security/MessageDigest;->digest()[B
:try_end_2c
.catch Ljava/security/cert/CertificateEncodingException; {:try_start_1c .. :try_end_2c} :catch_72
.catch Ljava/security/NoSuchAlgorithmException; {:try_start_1c .. :try_end_2c} :catch_a8
.catch Ljava/security/cert/CertificateException; {:try_start_1c .. :try_end_2c} :catch_49 move-result-object v1 .line 185
:goto_2d
if-nez v1, :cond_7c move v2, v3 :goto_30
:try_start_30
sget-object v5, Lt3/common/lic/ae;->am:[B invoke-static {v1, v5}, Ljava/util/Arrays;->equals([B[B)Z move-result v1 if-nez v1, :cond_7e move v1, v3 :goto_39
or-int/2addr v1, v2 if-eqz v1, :cond_80 .line 186
const-string v0, "Failed to verify the integrity of the certificate." invoke-static {v0}, Lorg/pmw/tinylog/Logger;->error(Ljava/lang/String;)V .line 187
new-instance v0, Ljava/lang/SecurityException; const-string v1, "License verification has failed." invoke-direct {v0, v1}, Ljava/lang/SecurityException;-><init>(Ljava/lang/String;)V throw v0
:try_end_49
.catch Ljava/security/cert/CertificateException; {:try_start_30 .. :try_end_49} :catch_49 .line 193
:catch_49
move-exception v0 .line 194
const-string v1, "Failed to access the 3t certificate." new-array v2, v4, [Ljava/lang/Object; invoke-static {v0, v1, v2}, Lorg/pmw/tinylog/Logger;->error(Ljava/lang/Throwable;Ljava/lang/String;[Ljava/lang/Object;)V .line 195
new-instance v0, Ljava/lang/SecurityException; const-string v1, "License verification has failed." invoke-direct {v0, v1}, Ljava/lang/SecurityException;-><init>(Ljava/lang/String;)V throw v0 .line 169
:catch_59
move-exception v2 .line 170
:try_start_5a
const-string v5, "Failed to find or load 3t certificate." const/4 v6, 0x0 new-array v6, v6, [Ljava/lang/Object; invoke-static {v2, v5, v6}, Lorg/pmw/tinylog/Logger;->error(Ljava/lang/Throwable;Ljava/lang/String;[Ljava/lang/Object;)V
:try_end_62
.catch Ljava/security/cert/CertificateException; {:try_start_5a .. :try_end_62} :catch_49 goto :goto_1c .line 166
:catchall_63
move-exception v0 .line 167
:try_start_64
invoke-virtual {v2}, Ljava/io/InputStream;->close()V
:try_end_67
.catch Ljava/io/IOException; {:try_start_64 .. :try_end_67} :catch_68
.catch Ljava/security/cert/CertificateException; {:try_start_64 .. :try_end_67} :catch_49 .line 172
:goto_67
:try_start_67
throw v0 .line 169
:catch_68
move-exception v1 .line 170
const-string v2, "Failed to find or load 3t certificate." const/4 v3, 0x0 new-array v3, v3, [Ljava/lang/Object; invoke-static {v1, v2, v3}, Lorg/pmw/tinylog/Logger;->error(Ljava/lang/Throwable;Ljava/lang/String;[Ljava/lang/Object;)V goto :goto_67 .line 181
:catch_72
move-exception v2 .line 182
:goto_73
const-string v5, "Failed to hash the certificate." const/4 v6, 0x0 new-array v6, v6, [Ljava/lang/Object; invoke-static {v2, v5, v6}, Lorg/pmw/tinylog/Logger;->error(Ljava/lang/Throwable;Ljava/lang/String;[Ljava/lang/Object;)V goto :goto_2d :cond_7c
move v2, v4 .line 185
goto :goto_30 :cond_7e
move v1, v4 goto :goto_39 .line 190
:cond_80
invoke-virtual {v0}, Ljava/security/cert/X509Certificate;->getPublicKey()Ljava/security/PublicKey;
:try_end_83
.catch Ljava/security/cert/CertificateException; {:try_start_67 .. :try_end_83} :catch_49 move-result-object v0 .line 198
:goto_84
if-nez v0, :cond_8e .line 199
new-instance v0, Ljava/lang/SecurityException; const-string v1, "Failed to load the 3T certificate." invoke-direct {v0, v1}, Ljava/lang/SecurityException;-><init>(Ljava/lang/String;)V throw v0 .line 203
:cond_8e
new-instance v1, Lt3/common/lic/h; invoke-direct {v1}, Lt3/common/lic/h;-><init>()V .line 204
invoke-virtual {v1, p1}, Lt3/common/lic/h;->d(Ljava/lang/String;)V .line 205
invoke-virtual {v1, v0}, Lt3/common/lic/h;->verify(Ljava/security/PublicKey;)Z .line 208
invoke-virtual {v1}, Lt3/common/lic/h;->E()Z move-result v0 if-nez v0, :cond_a7 .line 209
new-instance v0, Ljava/lang/SecurityException; const-string v1, "License verification failed." invoke-direct {v0, v1}, Ljava/lang/SecurityException;-><init>(Ljava/lang/String;)V throw v0 .line 211
:cond_a7
return-object v1 .line 181
:catch_a8
move-exception v2 goto :goto_73 :cond_aa
move-object v0, v1 goto :goto_84
.end method

贴出来的代码就是校验用户输入的licence关键代码, 可以这个方法反编译失败了,有时间再大力研究这段代码吧.

把这个jar包放在android studio中 居然完全可以看到源码, 不可思议

看了一下这个方法,  他的思路是:

获取licensing_public.cer文件, 然后用sha-1算法验证这个文件对不对, 如果不对就跑异常.   这样可以防止有人修改cer文件.

之后创建 t3.common.lic.h 对象,  然后把这个返回.      var1 是用户输入.   他是用#在分割.    用户完全完全可以输入  xxx#xxxx 这样的格式数据.

破解思路方法就可多了:

方案一:

自己生成X.509 公私密钥key.    计算公有key的sha-1

用自己生成的公钥替换licensing_public.cer。 然后替换代码中 sha-1的值.     就OK了.

然后用注册机:

调用 public static af a(String var0, PrivateKey var1)这个方法生成lincese就可以.
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
// package t3.common.lic; import com.google.common.io.BaseEncoding;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import org.pmw.tinylog.Logger; public class af {
private String aq = null;
private String content = null;
private boolean ar = false; public String aL() {
return this.aq;
} public String getContent() {
return this.content;
} public boolean E() {
return this.ar;
} private af() {
} public static af a(String var0, PublicKey var1) throws IllegalArgumentException {
af var2 = new af();
var2.aq = var0;
var2.ar = false;
if (null != var0 && null != var1) {
String[] var3 = w(var0).split("\\\\");
if (var3.length != 3) {
throw new IllegalArgumentException("signedString is not readable.");
} else {
byte[] var4;
byte[] var5;
byte[] var6;
BaseEncoding var7;
IllegalArgumentException var8;
try {
var7 = BaseEncoding.base64();
var4 = var7.decode(var3[0]);
if (var4.length == 0) {
return var2;
} var5 = var7.decode(var3[1]);
var6 = var7.decode(var3[2]);
} catch (IllegalArgumentException var10) {
var8 = new IllegalArgumentException("signedString is not readable.");
var8.initCause(var10);
throw var8;
} if (var4[0] != 3) {
throw new IllegalArgumentException("signedString is not readable (version mismatch).");
} else {
try {
var7 = null;
Signature var11 = Signature.getInstance("SHA256withRSA");
var11.initVerify(var1);
var11.update(var5);
if (var11.verify(var6)) {
var2.content = new String(var5, "UTF-8");
var2.ar = true;
return var2;
} else {
return var2;
}
} catch (InvalidKeyException | SignatureException | UnsupportedEncodingException | NoSuchAlgorithmException var9) {
var8 = new IllegalArgumentException("signedString is not readable.");
var8.initCause(var9);
throw var8;
}
}
}
} else {
throw new IllegalArgumentException("One of the arguments is null.");
}
} public static af a(String var0, PrivateKey var1) {
af var2 = new af();
var2.content = var0;
var2.ar = false;
byte[] var3 = new byte[]{3}; byte[] var4;
try {
var4 = var0.getBytes("UTF-8");
} catch (UnsupportedEncodingException var12) {
var12.printStackTrace();
Logger.error(var12, "Encoding failure", new Object[0]);
return null;
} Object var5 = null; byte[] var13;
try {
Signature var6 = Signature.getInstance("SHA256withRSA");
var6.initSign(var1);
var6.update(var4);
var13 = var6.sign();
} catch (InvalidKeyException | SignatureException | NoSuchAlgorithmException var11) {
Logger.error(var11, "Encryption failure", new Object[0]);
return var2;
} BaseEncoding var14 = BaseEncoding.base64(); try {
var14.encode(var3);
var14.encode(var4);
var14.encode(var13);
} catch (IllegalArgumentException var10) {
Logger.error(var10, "Encryption failure", new Object[0]);
return var2;
} String var7 = String.format("%s\\%s\\%s", var14.encode(var3), var14.encode(var4), var14.encode(var13));
var2.aq = w(var7);
var2.ar = true;
return var2;
} private static String B(String var0) {
String[] var1 = var0.split("#");
String var2 = var0;
if (var1.length > 2) {
var2 = var1[var1.length - 2];
} else if (var1.length == 2) {
var2 = var1[1];
} return var2;
} private static String w(String var0) {
return var0.replaceAll("[^0-9a-zA-Z/=+\\\\]", "");
}
}

方案二:

直接修改代码此处代码, 然后随便输入:

=========

开始动态调试之旅:

查看安装时间:

var1 是记录了安装时间.  看是什么赋值的?

var1和var2记录是在本地:  ~/.3T/studio-3t/soduz3vqhnnja46uvu3szq--

调试得知: ~/.3T/studio-3t/soduz3vqhnnja46uvu3szq--/settings.dat 文件里的内容就是记录安装时间的.     只不过加密了.

理论上删除这个文件,就可以无限试用了, 但是实际情况不是:

本人删除这个文件之后,  又重新生成了一个一摸一样的数据, 这个setting.data不是最终源头.  继续调试之旅,

开始从加密的地方断点调试.

t3.common.lic.b.j 类中是数据源头, 因为是这个类的 this.bj.get("soduz3vqhnnja46uvu3szq--") 之后得到了数据.

继续追踪,发现安装时间的数据存放在5个类中:

是一个List 这个 list类的信息分别是:

如果把这5个地方的安装数据都删除,  那就达到无限试用了. 接下来找到5个地方.

第一个地方: t3.common.lic.b.j

this.bj = Preferences.userRoot().node("/3t/mongochef/" + var2);  var2 = "enterprise"

// Preferences.userRoot() 目录在: ~/Library/Preferences/com.apple.java.util.prefs.plist

第二到五地方分别是:

/Users/dengzhongqiang/.3T/studio-3t/Lwm3TdTxgYJkXBgVk4s3/settings.dat

/Users/dengzhongqiang/.cache/ftuwWNWoJl-STeZhVGHKkQ--/5rpyYIZGkVBXle1pseFY2g

/var/folders/x4/xwpchqcd1m9539py__22l0ww0000gn/T/t3/dataman/mongodb/app/AppRunner/soduz3vqhnnja46uvu3szq--

/var/folders/x4/xwpchqcd1m9539py__22l0ww0000gn/T/ftuwWNWoJl-STeZhVGHKkQ--/5rpyYIZGkVBXle1pseFY2g--.log

说明:

第一个地方比较特别 com.apple.java.util.prefs.plist。  这个是所有Java软件共享的,  直接删除可能会影响其他应用.

其他第二到五地方随意删.

写了一个脚本:

rm -f ~/Library/Preferences/3t.*
rm -rf ~/.3T
rm -rf ~/.cache/ftuwWNWoJl-STeZhVGHKkQ--
rm -rf /var/folders/x4/xwpchqcd1m9539py__22l0ww0000gn/T/t3
rm -rf /var/folders/x4/xwpchqcd1m9539py__22l0ww0000gn/T/ftuwWNWoJl-STeZhVGHKkQ--

发现了一个奇怪现象,执行了之后并没有效果, 时间没有重置.  不得不佩服这个软件安全措施做的很到位.

没办法,继续挖掘.

查找到原因了: t3.common.lic.b.j 没有存放在com.apple.java.util.prefs.plist文件中.  在跟踪就到JVM虚拟机了.  osx库在处理这个数据, 具体怎么处理的就不清楚了.

只能写代码删除了.

package com.company.dzqCrack;

import java.util.prefs.Preferences;

public class Main {

    public static void main(String[] args) {
// write your code here
Preferences bt = Preferences.userRoot().node("/3t/mongochef/enterprise");
bt.remove("soduz3vqhnnja46uvu3szq--");
}
}

到此之际,破解完成.  又有30天了

关于动态调试别人的jar包总结:

修改info.plist文件: 圈出来的就是新增的

<string>-Xdebug</string>
<string>-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=50064</string>

然后在 idea编辑器中创建一个remote debug

=======================

虽然可以无限试用了,  但是心里有一个结,就是

为什么删了com.apple.java.util.prefs.plist  3t.mongochef.enterprise.plist 等plist文件,为什么还有存有安装信息.  跟踪的时候 发现它是加载了 osx库.

一定打破砂锅探到底

进入jre.bundle目录。

将osx库拖入hopper

可以看到Java层面的东西,最终调用是这些方法.

发现 _getStringsForNode调用了两次 _toCF:

查了一下苹果开发文档:

也就是这个_toCF核心是把 c语言的字符串 转换为 CFString .

转换之后,有一个方法被调用了:

(*(*r15 + 0x530))(r15, r14, rax);  // r15 = arg0.   其实这个就是JNIEnv *env      查看jni.h 中的定义 是struct JNINativeInterface类型

0x530是这个结构体的偏移,  暂且放一放.

通过跟踪发现: 一切数据来源都是调用 CFPreferencesCopyValue,

上面英文的大概意思。

CFPreferences 不能直接转 NSUserDefault.      是线程安全的.  和应用程序还有用户ID,host有关.    没有发现特别之处.  之所以删除plist文件不生效是因为数据已经加载到内存中了.

至此大完结,   删除~/Library/Preferences 目录下 t3* 3t*文件是有用的,  删除plist文件之后重启电脑就好了, 也就是上面的shell脚本是OK的.

如果不想重启电脑, 就执行一段Java代码, 用Java代码操作删除,立马生效.

======

截止到2020年04月30日,我发现之前的shell脚本对所有studio3T的版本都是有效的,studio3t可以随意升级版本。

但是之前的shell脚本不具有普适性,只对本人的电脑有效。  鉴于此,为了让所有人都可以无限试用,我改造了一下之前的脚本。   如果发现以下脚本无法使用,请留言。

#!/bin/sh 

rm -f ~/Library/Preferences/3t.*
rm -rf ~/.3T
rm -rf ~/.cache/ftuwWNWoJl-STeZhVGHKkQ-- ftPath=`find /var/folders -name "ftuwWNWoJl-STeZhVGHKkQ--" -print 2>&1 | fgrep -v "Permission denied" | fgrep -v "Operation not permitted"`
t3Path=`dirname ${ftPath}`/t3 if [ -e ${ftPath} ];then
rm -rf ${ftPath}
fi if [ -e ${t3Path} ];then
rm -rf ${t3Path}
fi echo "删除文件成功,请立即重启电脑生效"
echo "如果不想立刻重启,那么请在重启电脑前,都不要重新运行studio3T, 否则执行脚本将不起作用"

mac App 破解之路六 studio 3t的更多相关文章

  1. Mac app 破解之路

    6年之前一直做过一些内存挂,脚本挂.都是比较低级的技术. 这几年期间,断断续续利用业余时间学了一些汇编的知识,当时只是想着破解游戏. 所有的黑技术都是业余自学的,没有老师可以问,只能百度和自己领悟,比 ...

  2. Mac App破解之路九 vscode插件破解

    破解对象: luaide 破解目的:学习如何破解vscode插件 破解背景: vsscode用了这么多年,安装了很多插件,其中luaide插件是收费的.  说实话,100块并不贵, 我本来准备买的. ...

  3. MAC App破解之路十 Particle Design

    这个软件破解非常简单: 修改: [PaddleStatic Yz6nrtNwF4].直接返回1 效果:

  4. Mac App 破解之路八 病毒程序分析

    本人使用MacBooster 7 扫出了几个未知程序. JMJ56 这个程序. 在finder中打开发现是一个shell脚本 调用了python 9NKb0 就是python脚本使用.    只不过是 ...

  5. Ios App破解之路二 JJ斗地主

    前提条件: 越狱手机里, 安装了 <JJ斗地主> 使用砸壳工具clutch 下载地址: https://github.com/KJCracks/Clutch/releases dzq:~/ ...

  6. IOS App破解之路一 拿到appstore上的ipa

    1,  在Mac电脑上的app store里搜索Apple Configurator2 并安装 2, iPhone手机连接Mac电脑 3, 登录Apple Configurator2 菜单栏,  账号 ...

  7. 【APP设计利器】Sketch 41 Mac中文破解版(含汉化插件)

    Sketch是一款拥有美观界面和强大功能适用于所有设计师的专业矢量绘图工具.它旨在为美术设计师创造出一款更优秀的作品,不是复制品,而是提升品.Sketch简约的设计是基于无限的规模和层次的绘图空间,免 ...

  8. mongodb studio 3t 破解无限使用脚本

    @echo off ECHO 重置Studio 3T的使用日期...... FOR /f "tokens=1,2,* " %%i IN ('reg query "HKEY ...

  9. 破解studio 3T

    方法一: 打开注册表:regedit 计算机\HKEY_CURRENT_USER\Software\JavaSoft\Prefs\3t\mongochef\enterprise 将里面得数据清零,又是 ...

随机推荐

  1. DQN(Deep Q-learning)入门教程(三)之蒙特卡罗法算法与Q-learning算法

    蒙特卡罗法 在介绍Q-learing算法之前,我们还是对蒙特卡罗法(MC)进行一些介绍.MC方法是一种无模型(model-free)的强化学习方法,目标是得到最优的行为价值函数\(q_*\).在前面一 ...

  2. template标签介绍和使用

    template标签介绍和使用 1.介绍:template标签是html5新出来的标签,具有3个特点,(1)随意性:可以写在页面中的任何地方.(2)不可见性:它里面的元素都是不可见的.(3)页面也不会 ...

  3. [SD.TEAM语录]AC语录

    决定做了就要马上去做,不要有任何犹豫     本站文章为宝宝巴士 SD.Team原创,转载务必在明显处注明:(作者官方网站:宝宝巴士) 转载自[宝宝巴士SuperDo团队] 原文链接: http:// ...

  4. [工具推荐]005.Axure RP Pro 7.0模拟C#TAB控件

    有一次,主管安排我写一个项目的原型,但是项目中涉及到了Tab控件,在Axure中的控件中找了一番,没有找着Tab控件.那么我们只能换种法子来实现它了,我们用到了Dynamic Panel来模拟. 1. ...

  5. 利用Python网络爬虫采集天气网的实时信息—BeautifulSoup选择器

    相信小伙伴们都知道今冬以来范围最广.持续时间最长.影响最重的一场低温雨雪冰冻天气过程正在进行中.预计,今天安徽.江苏.浙江.湖北.湖南等地有暴雪,局地大暴雪,新增积雪深度4-8厘米,局地可达10-20 ...

  6. Sublime Text3 注册码(Windows/Build 3176版本)| 开发工具

    转自:dushusir.com 1.修改hosts文件(路径:C:\Windows\System32\drivers\etc): 0.0.0.0 www.sublimetext.com 0.0.0.0 ...

  7. 使用Mac的Remote Desktop Manager连接ubuntu16.04 & Win10的远程桌面

    疫情严重,公司实行远程办公.自己只有mac电脑,苦于3个系统间跨平台建立远程桌面. 今天,终于尝试成功!特来记录,以防别人踩坑! Mac远程软件安装 Remote Desktop Manager软件非 ...

  8. Java实现 蓝桥杯 算法训练 2的次幂表示

    算法训练 2的次幂表示 时间限制:1.0s 内存限制:512.0MB 问题描述 任何一个正整数都可以用2进制表示,例如:137的2进制表示为10001001. 将这种2进制表示写成2的次幂的和的形式, ...

  9. SQK Server实现 LeetCode 175 组合两个表

    175. 组合两个表 SQL架构 表1: Person +-------------+---------+ | 列名 | 类型 | +-------------+---------+ | Person ...

  10. java实现第四届蓝桥杯世纪末星期

    世纪末星期 题目描述 曾有邪教称1999年12月31日是世界末日.当然该谣言已经不攻自破. 还有人称今后的某个世纪末的12月31日,如果是星期一则会- 有趣的是,任何一个世纪末的年份的12月31日都不 ...