吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 43972|回复: 152
上一主题 下一主题
收起左侧

[原创] FinalShell 3.0.10 逆向破解

    [复制链接]
跳转到指定楼层
楼主
Ax王者 发表于 2020-1-13 20:40 回帖奖励
本帖最后由 Ax王者 于 2021-10-3 18:57 编辑

[Plain Text] 纯文本查看 复制代码
高级版功能(不断增加中) 
1. 网络监控可选择接口,同时监控多个网络接口速度. 
2. 打包传输,自动压缩解压,适合传输大量文件,文件夹和文本文件.
3. 高级网络监控,监控每个进程监听的端口,以及网络 
4. 高级进程管理,详细显示进程信息.连接状态. 
5. 无限制的终端命令历史,路径历史,可快速输入命令,切换路径.


这是 FinalShell 高级版的功能。

我打算直接静态破解,毕竟这款软件的静态混淆没有那么的强。

首先进行命名反混淆。
(反混淆后启动软件发现是秒启动,原生版本都需要很长时间去加载,难不成是直接跳过了证书验证?)

然后我们用 JbyteMod-Reborn 加载这个反混淆后的文件。




直接搜索“高级版”看看会有些什么?
结果显而易见,升级高级版对应的是免费版本,“高级版”字符串则对应的是付费版本了。

我们直接跳转到 “MainPanel” 对主页面进行分析。




这里会有两个对字符串字段的定义,我们直接搜索“高级版”所对应的字段的调用记录。



发现这里会有三个对这个字段的调用,我们随便进去一个,来查询一下它的具体条件是怎么样?

[Java] 纯文本查看 复制代码
private void OO00O0OOOO0O00O0OO0O0OOO0OOO0OOOO0OOO0OO0OO0O00O0O000O0O0OO0OO0OO0O0O0O0OOO0OO0O00000OOOOO0OO0OO0OOO() {
    boolean pro = myssh.App.OO0OO0000OOO0OO0O0O0000O000OO00O0O0OO00OO00O0O000OOO00O0O00O00OOO0O0O000O0O0O0OOO000OO000OOOOO0O0O().O0000OOO0000O0OO0OO0O0O0OO00O000O0OO0O0OO0OOO0OOOOOO0000OOO00O00O0O0OOOOOO0OO0000OO0OOO00OOOOOOO0().O00OOOO00O00OO0OOOO00O00000OOOO0OOOO0000000O0OOOO00OO0000O00O00OO0OOOOOO0O0OO0O00OOOOOOO0O0O0O0000OO();
    if (pro) {
        this.O000O0O0OOO0O0O000000OO0OOO00OO000OO00O0OOO0OOOOOOOO0OOOOOOO000O0OOO0OO00O0O000OO00OOOO00O000O.setText(this.O0OOOOOO000OO0O0O0OOOO000O0O000OO0OOOOOO0OO00OOO00OOO0O0000OO000OOO0O00OO00O0O0OO00O00O00000OO0OOOO);
    } else {
        this.O000O0O0OOO0O0O000000OO0OOO00OO000OO00O0OOO0OOOOOOOO0OOOOOOO000O0OOO0OO00O0O000OO00OOOO00O000O.setText(this.OOOO00O0OOO00OOOO0OO0OOO0OOO0O000OOOO0000O0000OO00OOO00O0OO0OO0OO0O0OO0OO0O0OOOOO0O00OOOOOOOO000O0);
    }
    this.O0OOO0000OO00O0OOOOO0OO0OO00O0OO0O00O00OOOO000OOOO0OO0O00O00OOOO0000O0O000OOOO0O00000O00O0OOO0O.O00OOOO00O00OO0OOOO00O00000OOOO0OOOO0000000O0OOOO00OO0000O00O00OO0OOOOOO0O0OO0O00OOOOOOO0O0O0O0000OO(pro);
    OO0O00OO000O0O0OO00OO00OOOOO0OOOOO0OO000O0OOOO0OOO0000O000O0OOO0OOOO0O00000OOOOO0OO0000O0O0OO000OO.OO0O00OO00OOOOOO0000O0O000O0O0000OOOO00OO000OO0000OO000000O00O0O000OO00O0O000O00O0O00OOOOOO0OOO0().O00OOOO00O00OO0OOOO00O00000OOOO0OOOO0000000O0OOOO00OO0000O00O00OO0OOOOOO0O0OO0O00OOOOOOO0O0O0O0000OO(pro);
    OO0O00OO00OOOOOO0000O0O000O0O0000OOOO00OO000OO0000OO000000O00O0O000OO00O0O000O00O0O00OOOOOO0OOO0.OOOO000O00OO0O0000O0000OO0O0O00OOOO00OO00OOO000000O0OOO0OOOOOOOOOOOOO000OO0OOOO000O00OO000OOOOOOO000().O00OOOO00O00OO0OOOO00O00000OOOO0OOOO0000000O0OOOO00OO0000O00O00OO0OOOOOO0O0OO0O00OOOOOOO0O0O0O0000OO(pro);
}


通过CFR反编译器反编译出来的代码,我们可以轻松的知道他是如何判断用户是否为“Pro”用户了。

我们直接跳转到它赋值 布尔值 “pro” 所调用的方法。

我们直接进入了类“ControlClient”,看来这就是主要的验证类了。
我们要开始动手了?

首先我注意到的是这两个方法:

[Asm] 纯文本查看 复制代码
    private boolean method1() {
        boolean success = false;
        this.code= 0;
        this.O000OOOO00OO0O0O0O0OO0OO0OO000O0O00000OOO0O0OO0O00O00OOOOO00O00OOOO0O000OO00OOO00OO0OOOOO0O0O0000O = false;
        this.O000000000O0000OOOO0O0O000O0000OOOO0OO0O0O00OOO00OO00O000O0OO0OOO0000000OO000O0OOO00OOOO00000OO0OOOO = false;
        JSONObject requestMeaaage = new JSONObject();
        requestMeaaage.put("username", (Object)App.OO0OO0000OOO0OO0O0O0000O000OO00O0O0OO00OO00O0O000OOO00O0O00O00OOO0O0O000O0O0O0OOO000OO000OOOOO0O0O().O000OOOO00OO0O0O0O0OO0OO0OO000O0O00000OOO0O0OO0O00O00OOOOO00O00OOOO0O000OO00OOO00OO0OOOOO0O0O0000O().O00OOO00O00OOOOO0OO0OOOO00O00OO0OO00OOOOO0O000OO00O0OO000O000O0OOO0OOOO000OOO0000OO000OOOOOOOOOOO00());
        requestMeaaage.put("password", (Object)App.OO0OO0000OOO0OO0O0O0000O000OO00O0O0OO00OO00O0O000OOO00O0O00O00OOO0O0O000O0O0O0OOO000OO000OOOOO0O0O().O000OOOO00OO0O0O0O0OO0OO0OO000O0O00000OOO0O0OO0O00O00OOOOO00O00OOOO0O000OO00OOO00OO0OOOOO0O0O0000O().OOO00OO00OOOO00OO0O00O0O00OOO0OOO000O00OOOO00OOOOOO000O0OO0O0OO0OO000O00O0OOOOOO00OO00OO00OOOO0OO000());
        requestMeaaage.put("fix", (Object)Tools.OO0O00OO00OOOOOO0000O0O000O0O0000OOOO00OO000OO0000OO000000O00O0O000OO00O0O000O00O0O00OOOOOO0OOO0((int)this.O000O0OOOOO00O0O00O0OO00O000O00O00000O0OO00000OOOO0O0OOOOO0O0O0OOOOO00OOO000OOO0000O0O0OOO0O0OO00OO0.nextInt(1024)));
        try {
            String msg;
            JSONObject responJson = this.O00OOOO00O00OO0OOOO00O00000OOOO0OOOO0000000O0OOOO00OO0000O00O00OO0OOOOOO0O0OO0O00OOOOOOO0O0O0O0000OO(requestMeaaage, "http://www.hostbuf.com/fs.c", this.OOO00O00OO00O0O000000O0OOOOOO0OOOO0O000OO000OO0OO0O0O00O0O0O00OO000O00OO000OOO00OO0O0O00O0O00OO0000);
            this.code = responJson.getIntValue("code");
            LoginDialog.OO0O000000O0OO000000O0O0000O0OO0O00OOO000OOOOOOO00OO0O00O0OO000O00OO00OOO000O00OOOOO0O0OOO0O0O0O0 = msg = responJson.getString("msg");
            this.O000OOOO00OO0O0O0O0OO0OO0OO000O0O00000OOO0O0OO0O00O00OOOOO00O00OOOO0O000OO00OOO00OO0OOOOO0O0O0000O = true;
            while (this.O000OOOO00OO0O0O0O0OO0OO0OO000O0O00000OOO0O0OO0O00O00OOOOO00O00OOOO0O000OO00OOO00OO0OOOOO0O0O0000O) {
                Thread.sleep((long)100L);
            }
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return success;
    }

    public boolean OOO0OOOOO00O0OO00O000OOOO0OO00OOO00000OO0000000OOOOOO00O0OOO00O0O00O0OOOOOO0OOO0O000OOOO0000OO0O000O() {
        return this.O000OOOO00OO0O0O0O0OO0OO0OO000O0O00000OOO0O0OO0O00O00OOOOO00O00OOOO0O000OO00OOO00OO0OOOOO0O0O0000O;
    }

    void method2() {
        if (this.code== 1) {
            if (this.O0O0O0000OO00O0O0000OO0OOO00O0OO00OO0OO0OOO0000OO00O00O0OOOO00OOOO00OO00O00O000OO00OOOO0000O000O != null) {
                this.O0O0O0000OO00O0O0000OO0OOO00O0OO00OO0OO0OOO0000OO00O00O0OOOO00OOOO00OO00O00O000OO00OOOO0000O000O.O00OOOO00O00OO0OOOO00O00000OOOO0OOOO0000000O0OOOO00OO0000O00O00OO0OOOOOO0O0OO0O00OOOOOOO0O0O0O0000OO(true);
            }
        } else {
            this.O0O0O0000OO00O0O0000OO0OOO00O0OO00OO0OO0OOO0000OO00O00O0OOOO00OOOO00OO00O00O000OO00OOOO0000O000O.O00OOOO00O00OO0OOOO00O00000OOOO0OOOO0000000O0OOOO00OO0000O00O00OO0OOOOOO0O0OO0O00OOOOOOO0O0O0O0000OO(false);
        }
        this.O000000000O0000OOOO0O0O000O0000OOOO0OO0O0O00OOO00OO00O000O0OO0OOO0000000OO000O0OOO00OOOO00000OO0OOOO = true;
        this.O000OOOO00OO0O0O0O0OO0OO0OO000O0O00000OOO0O0OO0O00O00OOOOO00O00OOOO0O000OO00OOO00OO0OOOOO0O0O0000O = false;
    }


第二个方法会首先判断第一个方法所取得的 code,如果为1,那么就继续。
然后会判断一个interface是否为null。
随后就会把

第一个方法会获取responJson作为信息返回,是在登陆窗口弹出的以及显示出的信息。


具体思路已经理顺,我们直接对其进行修改!

首先patch掉它这个类中用来获取请求的方法。

[Java] 纯文本查看 复制代码
public com.alibaba.fastjson.JSONObject O00OOOO00O00OO0OOOO00O00000OOOO0OOOO0000000O0OOOO00OO0000O00O00OO0OOOOOO0O0OO0O00OOOOOOO0O0O0O0000OO(com.alibaba.fastjson.JSONObject requestMeaaage, java.lang.String url, org.apache.http.client.HttpClient httpclient) throws java.lang.Exception {
    com.alibaba.fastjson.JSONObject responeMessage = null;
    boolean success = false;
    for (int n = 0;
     n < this.O0O000OOOOO0000O0000O000O00O000O0O0OO0O00OO0000OO00OO0OOO0O0O0OO00OO00O0OOO0OOOOOO0OOO0O00000OO0OO; ++n) {
        org.apache.http.client.methods.HttpPost post = new org.apache.http.client.methods.HttpPost(url);
        java.io.DataInputStream dis = null;
        try {
            byte[] requestData = requestMeaaage.toString().getBytes("utf-8");
            requestData = myssh.OOO00O00OO00O0O000000O0OOOOOO0OOOO0O000OO000OO0OO0O0O00O0O0O00OO000O00OO000OOO00OO0O0O00O0O00OO0000.DesUtilPro.O00OOOO00O00OO0OOOO00O00000OOOO0OOOO0000000O0OOOO00OO0000O00O00OO0OOOOOO0O0OO0O00OOOOOOO0O0O0O0000OO((byte[])requestData);
            org.apache.http.entity.ByteArrayEntity entity = new org.apache.http.entity.ByteArrayEntity(requestData);
            post.setEntity((org.apache.http.HttpEntity)entity);
            org.apache.http.HttpResponse respone = httpclient.execute((org.apache.http.client.methods.HttpUriRequest)post);
            org.apache.http.HttpEntity responeEntity = respone.getEntity();
            int responeLength = (int)responeEntity.getContentLength();
            java.io.InputStream is = responeEntity.getContent();
            dis = new java.io.DataInputStream(is);
            byte[] responeData = new byte[responeLength];
            dis.readFully(responeData);
            responeData = myssh.OOO00O00OO00O0O000000O0OOOOOO0OOOO0O000OO000OO0OO0O0O00O0O0O00OO000O00OO000OOO00OO0O0O00O0O00OO0000.DesUtilPro.OO0O00OO00OOOOOO0000O0O000O0O0000OOOO00OO000OO0000OO000000O00O0O000OO00O0O000O00O0O00OOOOOO0OOO0((byte[])responeData);
            java.lang.String string = new java.lang.String(responeData, "utf-8");
            responeMessage = com.alibaba.fastjson.JSONObject.parseObject((java.lang.String)string);
            success = true;
            break;
        }
        catch (java.lang.Exception e) {
            e.printStackTrace();
            try {
                java.lang.Thread.sleep((long)100L);
            }
            catch (java.lang.InterruptedException e1) {
                e1.printStackTrace();
            }
            continue;
        }
        finally {
            if (dis != null) {
                try {
                    dis.close();
                }
                catch (java.io.IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    if (!success) {
        throw new java.lang.Exception("request failed!");
    }
    return responeMessage;
}


直接return null;

然后开始patch上面所说的“method1”

1.Patch 方法返回的布尔值,直接return true;
2.Patch Code检测和返回的Message


3.Patch “method2” 内的一切条件判断


好了,我们现在启动一下试试看。


出现了JVM虚拟机字节码校验错误,我们上面修改的代码是不存在的问题的
所以不知道哪里出现了问题,直接注入代码反射修改虚拟机,强制跳过验证。

启动。



看来是启动成功了,接下来测试一下破解是否成功。




看来是成功了?
投入实际应用测试一下。




成功了!


总结一下,
这个软件的验证没有我认为的那么困难,可能主要是因为这个软件本来我感觉就挺良心的,没有要商业化的意思。

破解副本仅供学习参考,请勿用于商业用途。
若您喜欢这个软件,请支持正版,也就35块钱,资助一下人家。


另外,给点分?


新版
FinalShell 3.9.2.2 离线激活 key-gen - 『原创发布区』 - 吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn
https://www.aliyundrive.com/s/cFew9qVL8pQ


文中所用的静态修改工具可以在Github内搜索到,是一个Fork版本,由于自己没能力更新多少,就不在这里放出连接了。

免费评分

参与人数 31威望 +1 吾爱币 +37 热心值 +27 收起 理由
四万万的高度 + 1 + 1 谢谢@Thanks!
yanjingtu + 1 谢谢@Thanks!
灵影 + 1 + 1 谢谢@Thanks!
CoderDream + 1 想用mac高级版,支付宝付款35给作者了,竟然不能登陆
TCDT + 1 + 1 热心回复!
lwj888888 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
柠檬味小可爱 + 1 + 1 用心讨论,共获提升!
jokin1999 + 2 + 1 鼓励转贴优秀软件安全工具和文档!
李莹莹 + 2 用心讨论,共获提升!
LoTai + 1 + 1 用心讨论,共获提升!
Asd1984 + 1 + 1 谢谢@Thanks!
cnmcwma + 1 + 1 我很赞同!
bakabakaba + 1 + 1 谢谢@Thanks!
wsjxy + 1 + 1 我很赞同!
Lucky1_25 + 1 + 1 我很赞同!
飞仙003 + 1 我很赞同!
Hmily + 1 + 7 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
凉米饭 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
814182193 + 1 + 1 谢谢@Thanks!
某些人 + 1 + 1 谢谢@Thanks!
1062807258wang + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
霸气侧漏m2 + 1 + 1 热心回复!
wz36125 + 1 谢谢@Thanks!
Enterl + 1 + 1 谢谢@Thanks!
foxmail395 + 1 + 1 用心讨论,共获提升!
青面兽老杨 + 1 + 1 谢谢@Thanks!
egaokiss + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
lene + 1 + 1 用心讨论,共获提升!
2Burhero + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
呓语丶 + 1 这个软件挺良心的 要用还是赞助一下吧 也不贵 破解技术就交流学习一.
yntcxlong + 1 + 1 用心讨论,共获提升!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

推荐
zhh 发表于 2020-1-13 22:40
支持技术上的学习,有条件支持正版软件也是极好的!
推荐
羽未 发表于 2020-7-3 15:07
ecareyu 发表于 2020-5-29 10:59
无脑问下,在逆向过程中,是否发现有挖矿木马的存在?我觉得如果没有的话,最好替作者澄清一下。

我用了一年多了,确实遇到过一次CPU爆满的情况,java占用99%。当时作者很久没更新,现在作者重新拾起,不知道修复没有,具体的忘了。结论就是多开不要长期挂起,每天重启一次软件,到现在没遇到第二次。
3#
huming899 发表于 2020-1-13 21:32
有用免费版,唉~!不经常使用,想着用到就支持一下开发者!开发不易!!!
4#
fnycwfj 发表于 2020-1-13 22:23
感谢,非常好!
5#
chenjingyes 发表于 2020-1-13 22:32
感谢楼主分享技术
6#
zy1234 发表于 2020-1-13 23:58
挺好的一个软件,免费也很好用的
7#
XCIX 发表于 2020-1-14 02:15
谢谢楼主,学习中
8#
2Burhero 发表于 2020-1-14 02:33
评分路过
9#
egaokiss 发表于 2020-1-14 08:21
感谢您的分享,非常有用,谢谢。
10#
gblw 发表于 2020-1-14 08:38
值得学习,谢谢分享~
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-24 01:13

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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