对抖音进行反编译发现,其检测注入框架1.是通过进程抓取进程中包含的包。2.是检测堆栈中是否包含注入框架的包
所用 抖音版本 1.85
反编译找到检测类
搜索“xposed”关键字找到类com.ss.sys.ces.b.a
其包含四个字符串常量
private static String b = "XposedBridge.jar";
private static String c = "de.robv.android.xposed.XposedBridge";
private static String d = "com.saurik.substrate";
private static String e = "com.saurik.substrate.MS$2";
传值分析
if (a())
{
((JSONObject)localObject).put("xposed", 1);
if (b())
{
((JSONObject)localObject).put("cydia", 1);
if (!com.ss.sys.ces.a.f()) {
break label174;
}
((JSONObject)localObject).put("frida", 1);
((JSONObject)localObject).put("vapp", com.ss.sys.ces.a.v(paramContext.getFilesDir().getAbsolutePath(), paramContext.getPackageName()));
paramContext = System.getProperty("java.vm.version");
if ((paramContext == null) || (!paramContext.startsWith("2"))) {
break label624;
}
i = 1;
if (i == 0) {
break label185;
}
((JSONObject)localObject).put("api", new JSONArray(b.a().b()));
return (JSONObject)localObject;
localThrowable = localThrowable;
localThrowable.printStackTrace();
localJSONObject1 = null;
}
}
else
{
localJSONObject1.put("xposed", 0);
continue;
}
localJSONObject1.put("cydia", 0);
}
其是通过a()函数判断是否有注入框架
//由a函数的内容分析出 需同时 a(String param)返回true 和 d()函数返回true,才会被发现
public static boolean a()
{
return (a(b)) && (d());
}
函数a(String param)
其通过FileReader("/proc/" + Process.myPid() + "/maps")
获得所需包数据
通过循环与 看是否包含”XposedBridge.jar”,若有说明包含注入框架
private static boolean a(String paramString)
{
try
{
Object localObject = new HashSet();
BufferedReader localBufferedReader = new BufferedReader(new FileReader("/proc/" + Process.myPid() + "/maps"));
for (;;)
{
String str = localBufferedReader.readLine();
if (str == null) {
break;
}
if ((str.endsWith(".so")) || (str.endsWith(".jar"))) {
((Set)localObject).add(str.substring(str.lastIndexOf(" ") + 1));
}
}
localBufferedReader.close();
localObject = ((Set)localObject).iterator();
while (((Iterator)localObject).hasNext())
{
boolean bool = ((String)((Iterator)localObject).next()).contains(paramString);
if (bool) {
return true;
}
}
}
catch (Throwable paramString) {}
return false;
}
d函数通过抛出异常,来检测异常栈,若异常栈中有”de.robv.android.xposed.XposedBridge”字符串说明注入框架使用过,从而跑出了该异常。
private static boolean d()
{
boolean bool2 = false;
StackTraceElement[] arrayOfStackTraceElement;
int j;
int i;
try
{
throw new Exception("");
}
catch (Exception localException)
{
arrayOfStackTraceElement = localException.getStackTrace();
j = arrayOfStackTraceElement.length;
i = 0;
}
for (;;)
{
boolean bool1 = bool2;
if (i < j)
{
if (arrayOfStackTraceElement[i].getClassName().equals(c)) {
bool1 = true;
}
}
else {
return bool1;
}
i += 1;
}
}
总结
public static boolean a()
{
return (a(b)) && (d());
}
因此a()函数是先判断是否有注入框架xposed,再判断是否使用了该框架。