Skip to content

Commit

Permalink
Add exclude self support
Browse files Browse the repository at this point in the history
  • Loading branch information
Dr-TSNG committed Mar 29, 2021
1 parent 06326c8 commit ebc51c7
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 74 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ bin/
gen/
out/
# Uncomment the following line in case you need and you don't have the release build type files in your app
# release/
release/

# Gradle files
.gradle/
Expand Down
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ Attension: Xposed API version lower than 93 is NOT supported due to a permission
与此同时,部分“不安分”的app会使用各种漏洞绕过系统权限来获取你的应用列表,从而对你建立用户画像。(如陈叔叔将安装了V2Ray的用户分为一类)
该模块提供了一些检测方式用于测试您是否成功的隐藏了带有root印记的包名,如Magisk/Edxposed Manager。
同时可作为Xposed模块用于隐藏应用列表或特定应用,保护你的隐私。
注意:由于一个权限问题,XPosed API至少为93才能正常使用该模块
注意:由于一个权限问题,Xposed API至少为93才能正常使用该模块

## Update Log/更新日志
V1.1
Add exclude self support/增加了排除自身功能

## TODO
+ Add native detection
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ android {
applicationId "com.tsng.hidemyapplist"
minSdkVersion 26
targetSdkVersion 30
versionCode 6
versionName "1.0"
versionCode 7
versionName "1.1"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
Expand Down
113 changes: 43 additions & 70 deletions app/src/main/java/com/tsng/hidemyapplist/HookApplist.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
Expand Down Expand Up @@ -49,71 +50,56 @@ protected void afterHookedMethod(MethodHookParam param) {
final Set<String> enabled = pref.getStringSet("ApplyHooks", null);
//获取模板

if (enable_all_hooks || enabled.contains("method_pm")) pmHook(pref);
if (enable_all_hooks || enabled.contains("method_pm")) pmHook(lpp, pref);
if (enable_all_hooks || enabled.contains("method_api")) apiHook(lpp, pref);
if (enable_all_hooks || enabled.contains("method_intent")) intentHook(lpp, pref);
if (enable_all_hooks || enabled.contains("method_uid")) uidHook(lpp, pref);
if (enable_all_hooks || enabled.contains("method_datafile")) fileHook(lpp, pref);
//下钩子
}

void pmHook(final XSharedPreferences pref) {
if (pref.getBoolean("HideAllApps", false))
XposedHelpers.findAndHookMethod(Runtime.class, "exec", String.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) {
if (((String) param.args[0]).contains("pm list packages"))
param.args[0] = "echo Permission Denied";
}
});
else
XposedHelpers.findAndHookMethod(Runtime.class, "exec", String.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) {
try {
XposedHelpers.findAndHookMethod(param.getResult().getClass(), "getInputStream", new XC_MethodHook() {
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
BufferedReader br = new BufferedReader(new InputStreamReader((InputStream) param.getResult(), StandardCharsets.UTF_8));
String line;
StringBuilder sb = new StringBuilder();
while ((line = br.readLine()) != null) {
boolean flg = false;
for (String key : pref.getStringSet("HideApps", null))
if (line.contains(key)) {
flg = true;
break;
}
if (flg) continue;
boolean isToHide(final XSharedPreferences pref, String lppname, String pkgstr) {
if (pref.getBoolean("ExcludeSelf", false) && pkgstr.contains(lppname)) return false;
if (pref.getBoolean("HideAllApps", false)) return true;
Set<String> set = pref.getStringSet("HideApps", new HashSet<>());
for (String pkg : set)
if (pkgstr.contains(pkg))
return true;
return false;
}

void pmHook(final LoadPackageParam lpp, final XSharedPreferences pref) {
XposedHelpers.findAndHookMethod(Runtime.class, "exec", String.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) {
try {
XposedHelpers.findAndHookMethod(param.getResult().getClass(), "getInputStream", new XC_MethodHook() {
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
BufferedReader br = new BufferedReader(new InputStreamReader((InputStream) param.getResult(), StandardCharsets.UTF_8));
String line;
StringBuilder sb = new StringBuilder();
while ((line = br.readLine()) != null)
if (!isToHide(pref, lpp.packageName, line))
sb.append(line).append("\n");
}
InputStream result = new ByteArrayInputStream(sb.toString().getBytes(StandardCharsets.UTF_8));
param.setResult(result);
}
});
} catch (Throwable e) {
Log.e(LOG, "hooking Runtime.exec ERROR");
}
InputStream result = new ByteArrayInputStream(sb.toString().getBytes(StandardCharsets.UTF_8));
param.setResult(result);
}
});
} catch (Throwable e) {
Log.e(LOG, "hooking Runtime.exec ERROR");
}
});
}
});
}

void apiHook(final LoadPackageParam lpp, final XSharedPreferences pref) {
XposedHelpers.findAndHookMethod("android.app.ApplicationPackageManager", lpp.classLoader, "getInstalledPackages", int.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) {
if (pref.getBoolean("HideAllApps", false)) {
param.setResult(null);
return;
}
List<PackageInfo> packageInfos = (List) param.getResult();
for (Iterator<PackageInfo> iterator = packageInfos.iterator(); iterator.hasNext(); ) {
String name = iterator.next().packageName;
for (String pkg : pref.getStringSet("HideApps", null))
if (name.equals(pkg)) {
iterator.remove();
break;
}
}
for (Iterator<PackageInfo> iterator = packageInfos.iterator(); iterator.hasNext(); )
if (isToHide(pref, lpp.packageName, iterator.next().packageName))
iterator.remove();
param.setResult(packageInfos);
}
});
Expand All @@ -123,19 +109,10 @@ void intentHook(final LoadPackageParam lpp, final XSharedPreferences pref) {
XposedHelpers.findAndHookMethod("android.app.ApplicationPackageManager", lpp.classLoader, "queryIntentActivities", Intent.class, int.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) {
if (pref.getBoolean("HideAllApps", false)) {
param.setResult(null);
return;
}
List<ResolveInfo> infos = (List) param.getResult();
for (Iterator<ResolveInfo> iterator = infos.iterator(); iterator.hasNext(); ) {
String name = iterator.next().activityInfo.packageName;
for (String pkg : pref.getStringSet("HideApps", null))
if (name.equals(pkg)) {
iterator.remove();
break;
}
}
for (Iterator<ResolveInfo> iterator = infos.iterator(); iterator.hasNext(); )
if (isToHide(pref, lpp.packageName, iterator.next().activityInfo.packageName))
iterator.remove();
param.setResult(infos);
}
});
Expand All @@ -145,14 +122,10 @@ void uidHook(final LoadPackageParam lpp, final XSharedPreferences pref) {
XposedHelpers.findAndHookMethod("android.app.ApplicationPackageManager", lpp.classLoader, "getPackagesForUid", int.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) {
if (pref.getBoolean("HideAllApps", false)) {
param.setResult(null);
return;
}
String[] list = (String[]) param.getResult();
if (list != null)
for (String pkg : list)
if (pref.getStringSet("HideApps", null).contains(pkg)) {
if (isToHide(pref, lpp.packageName, pkg)) {
param.setResult(null);
break;
}
Expand All @@ -164,14 +137,14 @@ void fileHook(final LoadPackageParam lpp, final XSharedPreferences pref) {
XposedHelpers.findAndHookConstructor(File.class, String.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) {
if (pref.getBoolean("HideAllApps", false) &&
((String) param.args[0]).contains("Android/data/") &&
!((String) param.args[0]).contains(lpp.packageName)) {
String path = (String) param.args[0];
if (path.contains(lpp.packageName)) return;
if (pref.getBoolean("HideAllApps", false) && path.contains("Android/data/")) {
param.args[0] = "fuck/there/is/no/file";
return;
}
for (String pkg : pref.getStringSet("HideApps", null))
if (((String) param.args[0]).contains(pkg)) {
if (path.contains(pkg)) {
param.args[0] = "fuck/there/is/no/file";
break;
}
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/res/values-zh-rCN/strings_xposed.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
<string name="xposed_template_hide_apps">隐藏应用</string>
<string name="xposed_template_hide_all_apps">禁止读取应用列表</string>
<string name="xposed_template_hide_all_apps_summary">这会使目标应用无法获取到任何安装信息</string>
<string name="xposed_template_exclude_self">排除自身</string>
<string name="xposed_template_exclude_self_summary">这会避免应用无法检测到自己</string>
<string name="xposed_template_choose_apps_to_hide">选择要隐藏的应用</string>
<string name="xposed_teplate_select">选择一个模板</string>
</resources>
2 changes: 2 additions & 0 deletions app/src/main/res/values/strings_xposed.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
<string name="xposed_template_hide_apps">Hide apps</string>
<string name="xposed_template_hide_all_apps">Reject applist requests</string>
<string name="xposed_template_hide_all_apps_summary">This will prevent target apps to find any app installed</string>
<string name="xposed_template_exclude_self">Exclude self</string>
<string name="xposed_template_exclude_self_summary">This will prevent that a app cannot detect itself</string>
<string name="xposed_template_choose_apps_to_hide">Choose apps to hide</string>
<string name="xposed_teplate_select">Select a template</string>
</resources>
5 changes: 5 additions & 0 deletions app/src/main/res/xml/template_preferences.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,14 @@
android:summary="@string/xposed_template_hide_all_apps_summary"
android:title="@string/xposed_template_hide_all_apps" />
</PreferenceCategory>
<SwitchPreferenceCompat
android:key="ExcludeSelf"
android:summary="@string/xposed_template_exclude_self_summary"
android:title="@string/xposed_template_exclude_self" />
<Preference
android:dependency="HideAllApps"
android:fragment="com.tsng.hidemyapplist.TemplateSettingsActivity$HideAppsFragment"
android:title="@string/xposed_template_choose_apps_to_hide" />


</PreferenceScreen>

0 comments on commit ebc51c7

Please sign in to comment.