美团优选风控分析
作者:互联网
某团优选app的部分代码.(可以看得出来,检测机器是否root,也检测了是否安装了xp环境),并且在libmtguard.so这个文件内读取了机型的很多信息,java层也获取了很多信息(某团系的so层获取机型信息都在这个so内做的)
public final class DeviceUtil {
private static int a;
private static long b;
private static long c;
private static long d;
private static long e;
private static long f;
private static LEVEL g;
private static final String[] h = {"/data/local/su", "/data/local/bin/su", "/data/local/xbin/su", "/system/xbin/su", "/system/bin/su", "/system/bin/.ext/su", "/system/bin/failsafe/su", "/system/sd/xbin/su", "/system/usr/we-need-root/su", "/sbin/su", "/su/bin/su"};
private static final FileFilter i = new FileFilter() {
/* class com.meituan.metrics.util.DeviceUtil.AnonymousClass1 */
public final boolean accept(File file) {
return Pattern.matches("cpu[0-9]", file.getName());
}
};
public enum LEVEL {
BEST(4),
HIGH(3),
MIDDLE(2),
LOW(1),
BAD(-1),
UN_KNOW(0);
int value;
private LEVEL(int i) {
this.value = i;
}
public final int getValue() {
return this.value;
}
}
public static LEVEL a(Context context) {
if (g != null) {
return g;
}
long d2 = d(context);
int a2 = a();
if (d2 <= 0) {
g = LEVEL.UN_KNOW;
} else if (d2 > 6442450944L) {
g = LEVEL.BEST;
} else if (d2 > IjkMediaMeta.AV_CH_WIDE_RIGHT) {
g = LEVEL.HIGH;
} else if (a2 <= 0) {
g = LEVEL.UN_KNOW;
} else if (d2 > IjkMediaMeta.AV_CH_WIDE_LEFT && a2 > 4) {
g = LEVEL.MIDDLE;
} else if (d2 <= IjkMediaMeta.AV_CH_STEREO_RIGHT || a2 <= 2) {
g = LEVEL.BAD;
} else {
g = LEVEL.LOW;
}
return g;
}
/* JADX WARNING: Removed duplicated region for block: B:17:0x002c */
/* Code decompiled incorrectly, please refer to instructions dump. */
public static int a() {
/*
int r0 = com.meituan.metrics.util.DeviceUtil.a
if (r0 <= 0) goto L_0x0007
int r0 = com.meituan.metrics.util.DeviceUtil.a
return r0
L_0x0007:
r0 = 0
java.lang.String r1 = "/sys/devices/system/cpu/possible"
int r1 = a(r1) // Catch:{ Exception -> 0x002a }
if (r1 != 0) goto L_0x0016
java.lang.String r1 = "/sys/devices/system/cpu/present"
int r1 = a(r1) // Catch:{ Exception -> 0x002a }
L_0x0016:
if (r1 != 0) goto L_0x0029
java.lang.String r1 = "/sys/devices/system/cpu/"
java.io.File r2 = new java.io.File // Catch:{ Exception -> 0x002a }
r2.<init>(r1) // Catch:{ Exception -> 0x002a }
java.io.FileFilter r1 = com.meituan.metrics.util.DeviceUtil.i // Catch:{ Exception -> 0x002a }
java.io.File[] r1 = r2.listFiles(r1) // Catch:{ Exception -> 0x002a }
if (r1 != 0) goto L_0x0028
goto L_0x002a
L_0x0028:
int r1 = r1.length // Catch:{ Exception -> 0x002a }
L_0x0029:
r0 = r1
L_0x002a:
if (r0 != 0) goto L_0x002d
r0 = 1
L_0x002d:
com.meituan.metrics.util.DeviceUtil.a = r0
return r0
*/
throw new UnsupportedOperationException("Method not decompiled: com.meituan.metrics.util.DeviceUtil.a():int");
}
public static boolean b() {
try {
for (String str : h) {
if (new File(str).exists()) {
return true;
}
}
} catch (Exception unused) {
}
return false;
}
public static String c() {
if (Build.VERSION.SDK_INT >= 21) {
return TextUtils.join(",", Build.SUPPORTED_ABIS);
}
String str = Build.CPU_ABI;
String str2 = Build.CPU_ABI2;
if (TextUtils.isEmpty(str2)) {
return str;
}
return str + "," + str2;
}
private static int a(String str) {
Throwable th;
FileInputStream fileInputStream;
FileInputStream fileInputStream2 = null;
try {
fileInputStream = new FileInputStream(str);
try {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fileInputStream, "UTF-8"));
String readLine = bufferedReader.readLine();
bufferedReader.close();
if (readLine != null) {
if (readLine.matches("0-[\\d]+$")) {
int parseInt = Integer.parseInt(readLine.substring(2)) + 1;
f.a(fileInputStream);
return parseInt;
}
}
f.a(fileInputStream);
return 0;
} catch (IOException unused) {
fileInputStream2 = fileInputStream;
f.a(fileInputStream2);
return 0;
} catch (Throwable th2) {
th = th2;
f.a(fileInputStream);
throw th;
}
} catch (IOException unused2) {
f.a(fileInputStream2);
return 0;
} catch (Throwable th3) {
th = th3;
fileInputStream = null;
f.a(fileInputStream);
throw th;
}
}
public static String c(Context context) {
long d2 = d(context);
return d2 > 0 ? String.valueOf(d2) : "N/A";
}
private static long d(Context context) {
if (d > 0) {
return d;
}
if (Build.VERSION.SDK_INT < 16 || context == null) {
return b("MemTotal:");
}
ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
ActivityManager activityManager = (ActivityManager) context.getSystemService(PushConstants.INTENT_ACTIVITY_NAME);
activityManager.getMemoryInfo(memoryInfo);
d = memoryInfo.totalMem;
e = memoryInfo.threshold;
long maxMemory = Runtime.getRuntime().maxMemory();
if (maxMemory == Long.MAX_VALUE) {
f = (long) activityManager.getMemoryClass();
} else {
f = maxMemory;
}
return d;
}
private static long b(String str) {
Throwable th;
long j = 0;
if (TextUtils.isEmpty(str)) {
return 0;
}
BufferedReader bufferedReader = null;
try {
BufferedReader bufferedReader2 = new BufferedReader(new InputStreamReader(new FileInputStream("/proc/meminfo"), "UTF-8"));
try {
String readLine = bufferedReader2.readLine();
while (true) {
if (readLine == null) {
break;
}
Object[] split = readLine.split("\\s+");
if (str.equals(split[0])) {
j = ((long) Integer.parseInt(split[1])) * 1024;
break;
}
readLine = bufferedReader2.readLine();
}
f.a(bufferedReader2);
} catch (Exception unused) {
bufferedReader = bufferedReader2;
f.a(bufferedReader);
return j;
} catch (Throwable th2) {
th = th2;
bufferedReader = bufferedReader2;
f.a(bufferedReader);
throw th;
}
} catch (Exception unused2) {
f.a(bufferedReader);
return j;
} catch (Throwable th3) {
th = th3;
f.a(bufferedReader);
throw th;
}
return j;
}
@SuppressLint({"DefaultLocale"})
public static JSONObject a(JSONObject jSONObject, Context context) {
long j;
try {
jSONObject.put("deviceLevel", a(context));
jSONObject.put("MemoryTotal", String.format("%.2f MB", Float.valueOf((((float) d(context)) * 1.0f) / 1048576.0f)));
Object[] objArr = new Object[1];
if (Build.VERSION.SDK_INT < 16 || context == null) {
j = b("MemAvailable:");
} else {
ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
((ActivityManager) context.getSystemService(PushConstants.INTENT_ACTIVITY_NAME)).getMemoryInfo(memoryInfo);
j = memoryInfo.availMem;
}
objArr[0] = Float.valueOf((1.0f * ((float) j)) / 1048576.0f);
jSONObject.put("MemoryAvailable", String.format("%.2f MB", objArr));
} catch (Exception unused) {
}
return jSONObject;
}
public static String d() {
long j;
if (b > 0) {
j = b;
} else {
long j2 = 0;
for (int i2 = 0; i2 < a(); i2++) {
long a2 = m.a(e.a("/sys/devices/system/cpu/cpu" + i2 + "/cpufreq/cpuinfo_max_freq"), 0L);
if (a2 > j2) {
j2 = a2;
}
}
b = j2;
j = j2;
}
return j > 0 ? String.valueOf(j) : "N/A";
}
public static String e() {
long j;
if (c > 0) {
j = c;
} else {
long j2 = Long.MAX_VALUE;
for (int i2 = 0; i2 < a(); i2++) {
long a2 = m.a(e.a("/sys/devices/system/cpu/cpu" + i2 + "/cpufreq/cpuinfo_min_freq"), 0L);
if (a2 < j2 && a2 > 0) {
j2 = a2;
}
}
if (j2 == Long.MAX_VALUE) {
j = 0;
} else {
c = j2;
j = j2;
}
}
return j > 0 ? String.valueOf(j) : "N/A";
}
public static String b(Context context) {
long j;
if (f > 0) {
j = f;
} else {
d(context);
j = f;
}
return j > 0 ? String.valueOf(j) : "N/A";
}
}
解决设备指纹
由于安卓系统的开源开放策略导致在安卓内获取机型信息可以获取到非常多,所以这里想要解决设备指纹,可以有两套方案,那就是详细的分析app, 都在哪里读取的系统信息,通过hook的手段修改这些参数,当然也可以在网络发送数据前,未加密的数据进行替换,加密的数据在加密前进行参数替换也是可以的.第二种方案就是通过rom的定制可以实现未root的情况下实现一键改机。本文中采用的是第二种方案,定制rom + 长连接+ 尽可能的模拟真实用户访问 直到不封账号,不封设备,不封IP 为止.
标签:优选,return,String,美团,long,风控,static,context,r1 来源: https://blog.csdn.net/acy007/article/details/120669091