吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 4277|回复: 49
收起左侧

[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] 纯文本查看 复制代码
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] 纯文本查看 复制代码
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] 纯文本查看 复制代码
<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] 纯文本查看 复制代码
<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] 纯文本查看 复制代码
 
<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, 2024-4-29 21:33

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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