吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 5809|回复: 57
收起左侧

[Android 原创] 解决飞鸽传输2.3.6在安卓11/13上无法调用apk安装器的问题

[复制链接]
侃遍天下无二人 发表于 2022-10-31 16:36
本帖最后由 侃遍天下无二人 于 2023-8-26 15:25 编辑

【修复所写代码已开源,见 https://gitee.com/kbtxwer/feige-fix/
上回书说到:我们通过修改返回值去掉了飞鸽传输的广告,但飞鸽传输毕竟是很古老的软件了,在安卓11上虽然还基本能正常运行,但无法通过它直接安装收到的apk,这会给我的使用带来些许不便
原本还可以利用ES文件中转站解决,但我最近破解的旧版ES文件浏览器没这个功能,于是只好上网找找安卓11上安装软件的新方法,尝试融进飞鸽传输中:
根据 Android Apk安装(兼容Android11 Api30)中的描述,安卓11废弃了 Intent.ACTION_INSTALL_PACKAGE 字段,使以前的安装方法不再可用
文中还给了示例代码,不过引入kt会让安装包体积大增,因此要转换为java的实现。

用jadx打开上回修改好的飞鸽传输,定位到 com.tj.feige.app.a.e 的577行附近,发现一个静态无返回值的b(Context context, String str)方法,这就是我们要改的方法了:
image.png

可以看出它在无条件调用 android.intent.action.VIEW而我们要让这个方法在传入的文件后缀为apk,且安卓版本不小于11(sdk 30)时,走我们新增的逻辑(代码不能在jadx里直接修改,手动改smail也不现实,所以我在这里用Android Studio重新建立简化的开发环境写代码)
[Java] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package com.tj.feige.app.a;
 
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
 
import com.kbtx.AppInstaller;
 
import java.io.File;
import java.io.IOException;
 
public class e {
    private static String a(File file){
        return "";
    };
    private static void a(Context context, String str){}
 
    @SuppressLint("WrongConstant")
    public static void b(Context context, String str){
        File file = new File(str);
        Intent intent = new Intent();
        intent.addFlags(268435456);
        if(file.getName().endsWith(".apk") && Build.VERSION.SDK_INT >= 30){
            intent.setClass(context, AppInstaller.class);
        }else {
            intent.setAction("android.intent.action.VIEW");
        }
        intent.setDataAndType(Uri.fromFile(file),a(file));
        context.startActivity(intent);
    }
}

我们在Android Studio里新建的类路径应当和飞鸽传输里原有的完全一致,这样就可以直接从编译出来的dex中提取对应的smail汇编直接覆盖,如果这个方法调用了dex里的其他函数,只要建一个空壳,然后假装调用就行,确保编译过程不出错。

注意到代码里调用了 AppInstaller.class,这是我仿照文章用Java实现的安装器,代码如下:
[Java] 纯文本查看 复制代码
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
package com.kbtx;
 
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.IntentSender;
import android.content.pm.PackageInstaller;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
 
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
 
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
 
public class AppInstaller extends Activity implements View.OnClickListener {
    private static final String action = "com.kbtx.Install_APK";
    private boolean should_kill = false;
    @Override
    protected void onCreate([url=home.php?mod=space&uid=1043391]@nullable[/url] Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Uri uri = getIntent().getData();
        should_kill = false;
        if (uri != null && uri.getScheme().equals("file")) {
            File file = new File(uri.getPath());
            try {
                Install(file);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
 
    @Override
    protected void onResume() {
        super.onResume();
        if(should_kill) finish();
        should_kill = true;
    }
 
    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        if(intent==null || !intent.getAction().equals(action)) return;
        int status = intent.getExtras().getInt(PackageInstaller.EXTRA_STATUS);
        switch (status){
            case PackageInstaller.STATUS_PENDING_USER_ACTION:{
                startActivity((Intent) intent.getExtras().get(Intent.EXTRA_INTENT));
                break;
            }
            case PackageInstaller.STATUS_SUCCESS:{
                Log.i("FeiGe","应用安装成功");
                break;
            }
            case PackageInstaller.STATUS_FAILURE:{
                Log.i("FeiGe","应用安装失败");
                break;
            }
        }
    }
 
    public void Install(File apk) throws IOException {
        if(Build.VERSION.SDK_INT < 30) return;
        PackageInstaller packageInstaller = getPackageManager().getPackageInstaller();
        PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL);
        int sessionId = packageInstaller.createSession(params);
        PackageInstaller.Session session = packageInstaller.openSession(sessionId);
        addApkToInstallSession(apk,session);
        Intent intent = new Intent(this,AppInstaller.class);
        intent.setAction(action);
        PendingIntent pendingIntent = PendingIntent.getActivity(this,0,intent,0);
        IntentSender statRecv = pendingIntent.getIntentSender();
        session.commit(statRecv);
    }
 
    private void addApkToInstallSession(File apk, PackageInstaller.Session session){
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
            Log.e("feige","准备为新版安卓设备安装apk...");
            Log.e("feige","安装包路径: " + apk.getAbsolutePath());
            try(OutputStream packageInSession = session.openWrite("package",0,-1);
                InputStream is = new FileInputStream(apk)
            ){
                byte[] buffer = new byte[16384];
                int n;
                while((n = is.read(buffer)) >= 0){
                    packageInSession.write(buffer,0,n);
                }
            }catch (IOException e){
                e.printStackTrace();
                Log.e("feige","传输进程出错!");
                return;
            }
            Log.e("feige","数据传输完毕");
        }
    }
 
    @Override
    public void onClick(View view) {
        finish();
    }
}

此部分代码在清单文件中对应的声明如下:
[XML] 纯文本查看 复制代码
1
2
3
4
5
6
<activity android:name=".AppInstaller" android:launchMode="singleTop"
            android:exported="false">
            <intent-filter>
                <action android:name="com.kbtx.Install_APK" android:exported="true"/>
            </intent-filter>
        </activity>


Android Studio开发示意图

Android Studio开发示意图

代码写完后,直接构建apk,找到其中的dex文件,将 AppInstaller.smail放到飞哥传输中对应的位置(保证包名和路径一致),将 e.smail  中的 b方法覆盖飞鸽传输原有的。
(注:此步建议把dex传输到手机上操作,否则需要用apktool手动拆包封包,没有mt会员可以用np代替)
接下来就是修改飞鸽传输的清单文件,在里面新增对AppInstaller的声明:
[XML] 纯文本查看 复制代码
1
2
3
4
5
6
<activity android:name="com.kbtx.AppInstaller" android:launchMode="singleTop"
            android:exported="false">
            <intent-filter>
                <action android:name="com.kbtx.Install_APK" android:exported="true"/>
            </intent-filter>
        </activity>

同时加入允许安装未知应用的权限:
[XML] 纯文本查看 复制代码
1
2
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
    <uses-permission android:name="android.permission.REPLACE_EXISTING_PACKAGE" />

注入代码后反编译的示意图

注入代码后反编译的示意图

然后重新编译生成apk,得到的飞鸽传输就能在安卓11下直接安装接收到的apk文件了

原版:https://wwd.lanzoue.com/ipchmuqmqaj
上次的去广告成品:https://wwd.lanzoue.com/iWKLcuqmqba
修复安装功能的成品:https://wwd.lanzoue.com/ixoJ10ewts2b
修复安装功能(用了另一套代码)+底部菜单的成品:https://wwd.lanzoue.com/i4PzS0g88tcj
修复所写代码已开源,见 https://gitee.com/kbtxwer/feige-fix/



免费评分

参与人数 7吾爱币 +11 热心值 +7 收起 理由
hekygogo + 1 + 1 谢谢@Thanks!
coolcool2199 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
tail88 + 1 + 1 飞鸽安卓版太古老了,功能太少不方便
RobinMaas + 2 + 1 用心讨论,共获提升!
sifeng + 1 + 1 谢谢@Thanks!
笙若 + 1 + 1 谢谢@Thanks!
冥界3大法王 + 4 + 1 此贴最大的败笔是没有配图,俗不知红花儿配绿叶?

查看全部评分

本帖被以下淘专辑推荐:

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

 楼主| 侃遍天下无二人 发表于 2023-8-26 15:22
hekygogo 发表于 2023-8-26 15:08
谢谢楼主,一直用的飞鸽2007,可惜安卓的不行,找了很多跨平台互传软件feem landrop都不顺手,这个修改版ap ...

这两天升级到安卓13了,发现照样能正常运行
 楼主| 侃遍天下无二人 发表于 2022-11-1 18:43
zoomyou 发表于 2022-11-1 09:53
飞鸽传输,有PC版吗,是不是这个手机软件和PC可以互通联系的?

Windows上有ipmsg或者飞秋,Linux上有iptux,都是可以互通的
ouzhzh 发表于 2022-10-31 16:47
本帖最后由 ouzhzh 于 2022-10-31 16:48 编辑

飞鸽传输在手机上效果如何?使用过的说一下。
coolheat 发表于 2022-10-31 17:08
楼主的技术不错,佩服,下载来试试
冥界3大法王 发表于 2022-10-31 17:18
此贴最大的败笔是没有配图,殊不知红花儿配绿叶?
qqxiazhitmac 发表于 2022-10-31 17:22
感谢分享
weixu 发表于 2022-10-31 17:28
谢谢分享
qqxiazhitmac 发表于 2022-10-31 17:30
感谢分享
 楼主| 侃遍天下无二人 发表于 2022-10-31 19:14
冥界3大法王 发表于 2022-10-31 17:18
此贴最大的败笔是没有配图,殊不知红花儿配绿叶?

补上了,看看还有哪些细节需要补充的
冥界3大法王 发表于 2022-10-31 19:41
侃遍天下无二人 发表于 2022-10-31 19:14
补上了,看看还有哪些细节需要补充的

飞鸽传书的界面最好来一张,这样才承托主人公。@侃遍天下无二人 不然总觉得没有主角。。。
cccyyyccc1 发表于 2022-10-31 20:29
楼主厉害,老物件焕发新活力
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2025-4-22 02:41

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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