某音最新X-Gorgon 注册设备 xlog ascp mas等参数算法分析 2020-04-03逆向记录

小编自恋一下,逆向大神 属于逆向爱好者,如需要交流技术请在评论区留下邮箱,或者联系我邮箱[email protected]

某音版本里面加了好几个算法,有as,cp(早期就这两个),后面又加了mas,X-Gorgon,X-SS-STUB,X-Khronos算法,很多关键key之间有相互关联,只要有一个环节算错了,包括设备频繁使用被封,就会请求不到数据。目前版本的抖音加了很多的验证,及代码混淆,难度偏大。

某音的签名算法在libcms.so中,在JNI_Onload中动态注册jni函数。

算法用ollvm混淆了,主要是流程平坦化,流程混淆和运算替换

主要用到一些逆向工具IDA,Xposed框架

本人经过了几个通宵,逆向出了04版本的X-Gorgon,现在说说抖音各个参数的作用吧!

X-Gorgon

生成方式:对cookie,请求的url 截取参数,拼接成字符串,然后经过下列方法进行加密

 

某音最新X-Gorgon 注册设备 xlog ascp mas等参数算法分析 2020-04-03逆向记录_第1张图片

拿到加密的str以后转成byte数组,获取当前时间戳进行加密(中间有3个方法是核心这里就不公开了)最后计算出X-Gorgon

 

某音最新X-Gorgon 注册设备 xlog ascp mas等参数算法分析 2020-04-03逆向记录_第2张图片

X-SS-STUB是post请求时body部分的md5值,但是在为空的情况下,有时候不参与加密,有时候参与加密,具体接口需要具体分析。

X-Khronos比较简单就是一个unix时间戳

 

如下是请求抖音的视频详情接口demo

 

某音最新X-Gorgon 注册设备 xlog ascp mas等参数算法分析 2020-04-03逆向记录_第3张图片

截图

关于抖音注册设备算法 以及xlog算法等等会在下次讲解

 

某音最新X-Gorgon 注册设备 xlog ascp mas等参数算法分析 2020-04-03逆向记录_第4张图片

xlog的做法

GET https://xlog.snssdk.com/v2/s?os=0&ver=0.6.10.25.17-IH-Do&m=2&app_ver=9.9.0®ion=zh_CN&aid=1128&did=19671560880 HTTP/1.1
Host: xlog.snssdk.com
Connection: keep-alive
Cookie: sessionid=
X-SS-REQ-TICKET: 1582898273153
sdk-version: 1
x-tt-trace-id: 00-8c16dd31094948432b05140591f60468-8c16dd3109494843-01
User-Agent: com.ss.android.ugc.aweme/990 (Linux; U; Android 5.1.1; zh_CN; YQ601; Build/LMY47V; Cronet/77.0.3844.0)
Accept-Encoding: gzip, deflate
X-Gorgon: 0401d012000449c94d909ca41fa968eb6a8ab9ea7528d54eadae
X-Khronos: 1582898273

首先调用解密方法,将02开头的 byte[]数组进行解密,解密后是一个json字符串,然后再调用xlog加密接口进行加密,然后提交,返回的依然是一个02开头的,然后再进行解密,就可以看到结果了,
再次之前还有一个 sdfp包,也是需要用到这个加密解密的 可以参考文档


import android.text.TextUtils;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public final class ByteUtil {

  private static final String NULL_MD5_STRING = "00000000000000000000000000000000";

  public static byte[] b(String paramString) {
    int i = paramString.length();
    byte[] arrayOfByte = new byte[i / 2];
    for (byte b = 0; b < i; b += 2)
      arrayOfByte[b / 2] = (byte)((Character.digit(paramString.charAt(b), 16) << 4) + Character
          .digit(paramString.charAt(b + 1), 16));
    return arrayOfByte;
  }

  public static String ByteToStr(byte[] bArr) {

    int i = 0;

    char[] toCharArray = "0123456789abcdef".toCharArray();
    char[] cArr = new char[(bArr.length * 2)];
    while (i < bArr.length) {
      int i2 = bArr[i] & 255;
      int i3 = i * 2;
      cArr[i3] = toCharArray[i2 >>> 4];
      cArr[i3 + 1] = toCharArray[i2 & 15];
      i++;
    }
    return new String(cArr);
  }

  public static String getXGon(String url, String stub, String ck, String sessionid){
    StringBuilder sb=new StringBuilder();
    if (TextUtils.isEmpty(url)){
      sb.append(NULL_MD5_STRING);
    }else {
      sb.append(encryption(url).toLowerCase());
    }

    if (TextUtils.isEmpty(stub)){
      sb.append(NULL_MD5_STRING);
    }else {
      sb.append(stub);
    }

    if (TextUtils.isEmpty(ck)){
      sb.append(NULL_MD5_STRING);
    }else {
      sb.append(encryption(ck).toLowerCase());
    }

    if (TextUtils.isEmpty(sessionid)){
      sb.append(NULL_MD5_STRING);
    }else {
      sb.append(encryption(sessionid).toLowerCase());
    }
    return sb.toString();
  }

  public static String encryption(String str) {
    String re_md5=null;
    try {
      MessageDigest md = MessageDigest.getInstance("MD5");
      md.update(str.getBytes());
      byte b[] = md.digest();

      int i;

      StringBuffer buf = new StringBuffer("");
      for (int offset = 0; offset < b.length; offset++) {
        i = b[offset];
        if (i < 0)
          i += 256;
        if (i < 16)
          buf.append("0");
        buf.append(Integer.toHexString(i));
      }

      re_md5 = buf.toString();

    } catch (NoSuchAlgorithmException e) {
      e.printStackTrace();
    }
    return re_md5.toUpperCase();
  }

  public static byte[] StrToByte(String str) {
    String str2 = str;
    Object[] objArr = new Object[1];
    int i = 0;
    objArr[0] = str2;

    int length = str.length();
    byte[] bArr = new byte[(length / 2)];
    while (i < length) {
      bArr[i / 2] = (byte) ((Character.digit(str2.charAt(i), 16) << 4) + Character
          .digit(str2.charAt(i + 1), 16));
      i += 2;
    }
    return bArr;
  }
}

免责声明

  1. 请勿使用本服务于商用
  2. 请勿使用本服务大量抓取
  3. 若因使用本服务与抖音官方造成不必要的纠纷,本人盖不负责
  4. 本人纯粹技术爱好,若侵犯抖音贵公司的权益,请告知

你可能感兴趣的:(抖音)