最近接到一个需求,很多的APP会检测当前联网类型,不是WIFI时会有一些限制。因此想开发一个APP,调用frida-inject实现HOOK。首先想法是HOOK APP的ConnectivityManager.getNetworkInfo,这样可以达到目的,但是每个APP都要Hook,实际操作中有很多的麻烦,那么有没用一个一劳永逸的方法呢?
答案是有的, 任何一个APP,ConnectivityManager对象的值是通过AIDL调用,从系统服务拿到的,系统服务在手机里只有一个实例,如果我直接修改系统服务,就可以实现所有APP都改变了网络类型。
ConnectivityManager connManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
frida-inject的标准用法,是将一个js文件做为参数传入,既然我的目的单一,JS是固定不变的,为了应用更简洁,同时也想稍微隐藏一下js的实现方式,我尝试将这个js直接编译到frida-inject里,这样就是单一文件运行了。
找到“frida-core\inject\inject.vala”文件,将main函数里读JS文件的部分注销掉。
private static int main (string[] args) {
#if !WINDOWS
Posix.setsid ();
#endif
Environment.init ();
/* 这部分注销掉,不再read_stdin
try {
var ctx = new OptionContext ();
ctx.set_help_enabled (true);
ctx.add_main_entries (options, null);
ctx.parse (ref args);
if (output_version) {
print ("%s\n", version_string ());
return 0;
}
} catch (OptionError e) {
printerr ("%s\n", e.message);
printerr ("Run '%s --help' to see a full list of available command line options.\n", args[0]);
return 1;
}
if (spawn_file == null && target_pid == -1 && target_name == null) {
printerr ("PID or name must be specified\n");
return 2;
}
if (script_path == null || script_path == "") {
printerr ("Path to JavaScript file must be specified\n");
return 3;
}
string? script_source = null;
if (script_path == "-") {
script_path = null;
script_source = read_stdin ();
}
*/
然后,在后面加上自己的JS注入代码,修改网络类型成WIFI
//开始添加JS代码
script_path = null;
eternalize=true;
target_name="system_server";
string script_source = """
Java.perform(function () {
const networkInfo = Java.use("android.net.NetworkInfo");
const netmanager = Java.use("com.android.server.ConnectivityService");
networkInfo.writeToParcel.implementation = function (dest,flags) {
var callUid=Java.use("android.os.Binder").getCallingUid();
if(callUid!=1000){
dest.writeInt(1);
dest.writeInt(0);
dest.writeString("WIFI");
dest.writeString("subWifi");
dest.writeString("CONNECTED");
dest.writeString("CONNECTED");
dest.writeInt( 0);
dest.writeInt(1 );
dest.writeInt( 0);
dest.writeString(null);
dest.writeString(null);
}else
return this.writeToParcel(dest,flags);
};
netmanager.getActiveNetworkInfo.implementation = function () {
var callUid=Java.use("android.os.Binder").getCallingUid();
if(callUid!=1000){
var netInfo = networkInfo.$new(1, 0, "WIFI", "subWifi");
return netInfo;
}else
return this.getActiveNetworkInfo();
};
netmanager.getActiveNetworkInfoForUid.implementation = function () {
var callUid=Java.use("android.os.Binder").getCallingUid();
if(callUid!=1000){
var netInfo = networkInfo.$new(1, 0, "WIFI", "subWifi");
return netInfo;
}
else
return this.getActiveNetworkInfoForUid();
};
netmanager.getNetworkInfo.overload("int").implementation = function (networkType) {
var callUid=Java.use("android.os.Binder").getCallingUid();
if(callUid!=1000){
var netInfo;
if (networkType == 0)
netInfo = networkInfo.$new(0, 0, "4G", "4g");
else
netInfo = networkInfo.$new(1, 0, "WIFI", "subWifi");
return netInfo;
}else
return this.getNetworkInfo(networkType);
};
netmanager.getAllNetworkInfo.implementation = function () {
var callUid=Java.use("android.os.Binder").getCallingUid();
if(callUid!=1000){
var netInfo = networkInfo.$new(1, 0, "WIFI", "subWifi");
var netInfos = [netInfo];
return netInfos;
}else
return this.getAllNetworkInfo();
};
var wifiMng = Java.use("com.android.server.wifi.WifiServiceImpl");
var wifiInfoClass = Java.use("android.net.wifi.WifiInfo");
wifiMng.getConnectionInfo.implementation = function () {
var callUid=Java.use("android.os.Binder").getCallingUid();
if(callUid!=1000){
var wifiInfo = wifiInfoClass.$new();
wifiInfo.mRssi.value = -36;
wifiInfo.mLinkSpeed.value = 866;
wifiInfo.mFrequency.value = 5785;
wifiInfo.mNetworkId.value = 0;
wifiInfo.score.value = 80;
return wifiInfo;
}else
return this.getConnectionInfo();
};
});""";
//结束添加JS代码
ScriptRuntime script_runtime = DEFAULT;
if (script_runtime_str != null) {
var klass = (EnumClass) typeof (ScriptRuntime).class_ref ();
var v = klass.get_value_by_nick (script_runtime_str);
if (v == null) {
printerr ("Invalid script runtime\n");
return 4;
}
script_runtime = (ScriptRuntime) v.value;
}
编译出自己的frida-inject,只需要通过shell调用它,就达到了改变网络类型,打开手机上常用的多个视频软件,都没有弹出移动网络的告警通知,目标达成。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)