[color=]【修复所写代码已开源,见 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 (86.15 KB, 下载次数: 0)
下载附件
2022-10-31 19:05 上传
可以看出它在无条件调用
[color=] 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(@Nullable 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 = 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] 纯文本查看 复制代码
image.png (170.8 KB, 下载次数: 0)
下载附件
Android Studio开发示意图
2022-10-31 19:08 上传
代码写完后,直接构建apk,找到其中的dex文件,将 AppInstaller.smail放到飞哥传输中对应的位置(保证包名和路径一致),将 e.smail 中的 b方法覆盖飞哥传输原有的。
(注:此步建议把dex传输到手机上操作,否则需要用apktool手动拆包封包,没有mt会员可以用np代替)
接下来就是修改飞哥传输的清单文件,在里面新增对AppInstaller的声明:
[XML] 纯文本查看 复制代码
同时加入允许安装未知应用的权限:
[XML] 纯文本查看 复制代码
image.png (200 KB, 下载次数: 0)
下载附件
注入代码后反编译的示意图
2022-10-31 19:12 上传
然后重新编译生成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/