清楚缓存,重新打开app, 点击同意按钮,会触发设备注册;
很明显是一个post包,device_register
可以看到请求体加密了 那么 请求体是什么呢?
很老版本思路:都是直接明文注册
较老版本思路:在反编译后请求体通过一个bool来判断,是否走,ttencrypt;
这个地方可以hook明文也可以直接修改bool值,让抓包直接抓到明文;正常情况下,是将请求体压缩后,走ttencrypt,进行密文注册;
我们接着往下走,看新版是否有变化;
看下params参数:
cdid:
只找到个从SharedPreferences xml拿,没有就uuid;
openudid:
x_ss_stub:
这个值就很普通了,java层,post包的时候会把data转成字符串进行md5的一个值;
搜出来个这玩意,兄弟们想想这是干啥,注册,激活。。
ttencrypt:
搜一下:/service/2/device_register/
private boolean LIZ(String str, JSONObject jSONObject) {String[] strArr;boolean z;Throwable th;ChangeQuickRedirect changeQuickRedirect;String str2;ChangeQuickRedirect changeQuickRedirect2;ChangeQuickRedirect changeQuickRedirect3;l4Z l4z;String C;boolean z2;ChangeQuickRedirect changeQuickRedirect4 = LIZ;if (PatchProxy.isEnable(changeQuickRedirect4)) {PatchProxyResult proxy = PatchProxy.proxy(new Object[]{str, jSONObject}, this, changeQuickRedirect4, false, 5);if (proxy.isSupported) {return ((Boolean) proxy.result).booleanValue();}}try {byte[] bytes = str.getBytes("UTF-8");System.currentTimeMillis();ChangeQuickRedirect changeQuickRedirect5 = l5V.LIZ;if (PatchProxy.isEnable(changeQuickRedirect5)) {PatchProxyResult proxy2 = PatchProxy.proxy(PatchProxy.getEmptyArgs(), null, changeQuickRedirect5, true, 1);if (proxy2.isSupported) {strArr = (String[]) proxy2.result;if (strArr == null) {for (String str3 : strArr) {byte[] bArr = (byte[]) bytes.clone();if (!StringUtils.isEmpty(str3)) {Logger.debug();if (TextUtils.isEmpty(jSONObject.optString("device_id")) || TextUtils.isEmpty(jSONObject.optString("install_id"))) {z = true;} else {z = false;}try {ChangeQuickRedirect changeQuickRedirect6 = LIZ;if (PatchProxy.isEnable(changeQuickRedirect6)) {PatchProxyResult proxy3 = PatchProxy.proxy(PatchProxy.getEmptyArgs(), this, changeQuickRedirect6, false, 7);if (proxy3.isSupported) {z2 = ((Boolean) proxy3.result).booleanValue();}}ChangeQuickRedirect changeQuickRedirect7 = l5V.LIZ;if (PatchProxy.isEnable(changeQuickRedirect7)) {PatchProxyResult proxy4 = PatchProxy.proxy(PatchProxy.getEmptyArgs(), null, changeQuickRedirect7, true, 4);if (proxy4.isSupported) {z2 = ((Boolean) proxy4.result).booleanValue();}}if (l5V.LIZJ != null) {z2 = l5V.LIZJ.LIZ();}try {if (str3.indexOf(63) < 0) {new StringBuilder();C = O.C(str3, "?");} else {new StringBuilder();C = O.C(str3, "&");}str2 = NetUtil.sendEncryptLog(C, bArr, this.LIZJ.LJIILL, false, (String[]) null, (Map) null, (String) null, z, false);} catch (RuntimeException unused) {l4Q.LIZ(Monitor.Key.register, Monitor.State.f_to_bytes);try {str2 = NetUtil.doPost(str3, bytes, true, "application/json; charset=utf-8", false, (Map) null, z, false);String C2 = O.C("device_register response: ", str2);changeQuickRedirect2 = l4T.LIZ;if (PatchProxy.isEnable(changeQuickRedirect2)) {}changeQuickRedirect3 = l4T.LIZ;if (PatchProxy.isEnable(changeQuickRedirect3)) {}l4z = l4T.LIZIZ;if (l4z != null) {}if (str2 != null) {}l4Q.LIZ(Monitor.Key.register, Monitor.State.f_resp_error);} catch (Throwable th2) {th = th2;l4Q.LIZ(Monitor.Key.register, Monitor.State.f_net);l5O l5o = this.LIZJ;changeQuickRedirect = l5O.LIZIZ;if (PatchProxy.isEnable(changeQuickRedirect)) {}if (th instanceof CommonHttpException) {}}}String C22 = O.C("device_register response: ", str2);changeQuickRedirect2 = l4T.LIZ;if (PatchProxy.isEnable(changeQuickRedirect2) || !PatchProxy.proxy(new Object[]{C22}, null, changeQuickRedirect2, true, 1).isSupported) {changeQuickRedirect3 = l4T.LIZ;if (PatchProxy.isEnable(changeQuickRedirect3)) {try {} catch (Throwable th3) {th = th3;l4Q.LIZ(Monitor.Key.register, Monitor.State.f_net);l5O l5o2 = this.LIZJ;changeQuickRedirect = l5O.LIZIZ;if (PatchProxy.isEnable(changeQuickRedirect)) {PatchProxyResult proxy5 = PatchProxy.proxy(new Object[]{th}, l5o2, changeQuickRedirect, false, 21);if (proxy5.isSupported) {if (!((Boolean) proxy5.result).booleanValue()) {throw th;}}}if (th instanceof CommonHttpException) {int responseCode = ((CommonHttpException) th).getResponseCode();if (l5o2.LJJIIJ) {continue;} else if (responseCode < 200) {continue;} else if (responseCode == 301) {continue;} else if (responseCode != 302) {throw th;}} else {continue;}}}l4z = l4T.LIZIZ;if (l4z != null) {l4z.LIZ(C22, null);}}if (str2 != null || str2.length() == 0) {l4Q.LIZ(Monitor.Key.register, Monitor.State.f_resp_error);} else if (LIZ(new JSONObject(str2))) {return true;}} catch (Throwable th4) {th = th4;l4Q.LIZ(Monitor.Key.register, Monitor.State.f_net);l5O l5o22 = this.LIZJ;changeQuickRedirect = l5O.LIZIZ;if (PatchProxy.isEnable(changeQuickRedirect)) {}if (th instanceof CommonHttpException) {}}}}return false;}throw new IllegalArgumentException("url is null");}}strArr = (l5V.LIZIZ == null || l5V.LIZIZ.length <= 0 || StringUtils.isEmpty(l5V.LIZIZ[0])) ? new String[]{O.C("https://", l5V.LIZLLL, "/service/2/device_register/"), O.C("https://", l5V.LIZLLL, "/service/2/device_register/")} : l5V.LIZIZ;if (strArr == null) {}} catch (Throwable unused2) {l4Q.LIZ(Monitor.Key.register, Monitor.State.f_exception);return false;}}
可以看到整个注册这个接口的流程;
这一段代码是核心,看到是发请求去了;
import com.ss.android.common.applog.NetUtil;
str2 = NetUtil.sendEncryptLog(C, bArr, this.LIZJ.LJIILL, false, (String[]) null, (Map) null, (String) null, z, false);str2 = NetUtil.doPost(str3, bytes, true, "application/json; charset=utf-8", false, (Map) null, z, false);
这个时候,我们看出来已经和老版本有区别了,没有一个bool值来控制是否请求加密,而是直接去加密,若报错才会进行明文注册; 这是一点不同的地方;
doPost: 确实没啥东西;
sendEncryptLog:
如果包含str.contains(“/service/2/app_log/”)就去走ttEncrypt 加密,目前走else
else: 也是压缩 ttEncrypt 加密
ttEncrypt 该加密方式so层,libEncryptor.so
我们在看下,整体接口:
看到确实是发了很多接口,注册,激活,日志包等等;而且必须是六神注册,密文注册,这样设备才可用;
很明显的,device_register,app_alert ,app_log等等
为了权重更好,甚至注册完之后还需要发一些日志包,过一些验证码,提高设备权重;