共计 12453 个字符,预计需要花费 32 分钟才能阅读完成。
先看看设施注册的包:
POST https://log-lq.snssdk.com/service/2/device_register/?device_id=56581003169&
is_activated=1&aid=1128&tt_data=a&version_code=12.4.0&app_name=aweme&app_version=12.4.0&vid=84185501-88C0-4E38-BA3D-F3656A073020&device_id=56581003169&channel=App%20Store&mcc_mnc=46001&aid=1128&screen_width=1125&openudid=690af6a89ae78c69306c8a07bca241b840sd156&cdid=AD072FE4-41B7-4890-BEBC-2D57A4F3F253&os_api=18&ac=4G&os_version=12.4&build_number=123011&device_platform=android&iid=3125112636576938&device_type=Huawei%C8600&is_vcd=1 HTTP/1.1
Host: log-lq.snssdk.com
Connection: keep-alive
Content-Length: 856
Accept: application/json
Cookie: odin_tt=458f8eb0d95b7b9adb4b6fc6591918bfb996096967a7aa4305bd81b5150a8199d2e29ed21883cdd7709c5beaa2be3baa; sessionid=66e5128a179ef5f03f5187bae265bf9c; sessionid_ss=ff5128a179ef5f03f5187baecss22; sid_guard=d2da128a179ef5f03f5187bae265bf9c%7C1598662639%7C5183349%7CWed%2C+28-Oct-2020+00%3A46%3A28+GMT; sid_tt=66e5128a179ef5f03f5187bae265bf9c; uid_tt=fsffdc1fa00bb0ddddd400f58d5795df3; uid_tt_ss=232ec1fa00bb0ddddd400f58d5795321; install_id=3125112636576938; ttreq=1$432133fb80de2e267dd1a8478e5394cdd0cd23d1
Content-Type: application/octet-stream;tt-data=a
X-SS-Cookie: install_id=3125112636576938; ttreq=432133fb80de2e267dd1a8478e5394cdd0cd23d1; sessionid=ff5128a179ef5f03f5187baecss22; sessionid_ss=ff5128a179ef5f03f5187baecss22; sid_guard=ff5128a179ef5f03f5187baecss22%7C1598662639%7C5183349%7CWed%2C+28-Oct-2020+00%3A46%3A28+GMT; sid_tt=ff5128a179ef5f03f5187baecss22; uid_tt=d36ec1fa00bb0ddddd400f58d5795df3; uid_tt_ss=d36ec1fa00bb0ddddd400f58d5795df3; odin_tt=a09d8eb0d95b7b9adb4b6fc6591918bfb996096967a7aa4305bd81b5150a8199d2e29ed21883cdd7709c5beaa2be3baa
tt-request-time: 15994653422123
User-Agent: Aweme 12.3.0 rv:123015 (iPhone; iOS 12.2; zh_CN) Cronet
aid: 1128
x-Tt-Token: 00632e5128a179ef5f03f5187bae265bf9cdded28ab77be5f36e4259d59aa924b6c7f5284cdd07bf788188bb5185d61c32145
sdk-version: 2
passport-sdk-version: 5.12.1
X-SS-STUB: 34C32EDE4A3C45F55403E5EBD44A321B
X-SS-DP: 1128
x-tt-trace-id: 00-6123a32f7a09f80897b9fe6e7cc5490468-62a08f7a09f32457-01
Accept-Encoding: gzip, deflate, br
X-Khronos: 1599465342
X-Gorgon: 040802f0000e09020319e1d6be6194bfbd32024c25831c86bce
在新版设施注册的 url 中你会发现多了一部分参数,然而有一个参数比拟夺目那就是 is_activated=1。明白人一眼就能看进去是什么含意,对于设施注册外面的参数在这里不不便剖析,须要具体理解的能够分割我!评论区有联系方式!
首先咱们要晓得抖音封禁设施靠判断什么
而后咱们就能够针对它来解。
抖音判断一台设施无非就是依据手机的 IMEI,IMSI,MAC, 零碎版本
型号之类的来判断时候同一台设施
咱们利用 JADX 来逆向,要害函数在 ttEncrypt 办法
func IIDEncrypt(plainStr []byte) []byte {CplainStr := C.CString(string(plainStr))
defer C.free(unsafe.Pointer(CplainStr))
plainlength := len(plainStr)
libPathC := C.CString(EXTENSION_DIR + OIDB_API)
defer C.free(unsafe.Pointer(libPathC))
encryptedLength := plainlength + 4 + (16 - plainlength%16)
CKeyStr := C.CString("!*ss!_defaul%t54K&EY")
defer C.free(unsafe.Pointer(CKeyStr))
CEncryptedStr := C.encode(libPathC, CplainStr, C.int(encryptedLength), CKeyStr, C.int(20))
defer C.free(unsafe.Pointer(CEncryptedStr))
encryptedStr := C.GoBytes(unsafe.Pointer(CEncryptedStr), C.int(encryptedLength))
//encryptedHexStr := hex.EncodeToString(encryptedStr)
return encryptedStr
}
char* Encode(char* plain, int plainlength, char* key, int keylength)
{//string plain = hexToStr(hexplain);
char *xkey;
char *xplain;
//int keylength = key.length();
//int plainlength = plain.length();
xkey = (char*) malloc(keylength);
xplain = (char*) malloc(plainlength);
memcpy(xkey, key, keylength);
memcpy(xplain, plain, plainlength);
unsigned char *out = (unsigned char*) malloc(plainlength + 100);
aweme_aes((__int64)xplain, plainlength, (__int64)xkey, keylength, (__int64)out);
free(xkey);
free(xplain);
xkey = NULL;
xplain = NULL;
// int cryptedStr_length = plainlength + 4 + (16 - plainlength%16);
// std::string hexStr = charsToHex(out, cryptedStr_length);
// free(out);
//out = NULL;
return (char*)out;
}
#include "subs.h"
uint32 bswap32(uint32 x)
{return ((x << 24) & 0xff000000) |
((x << 8) & 0x00ff0000) |
((x >> 8) & 0x0000ff00) |
((x >> 24) & 0x000000ff);
}
unsigned char InvSbox[256] = { // inverse s-box
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d };
unsigned char Sbox[256] = { // forward s-box
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 };
__int64 aweme_aes(__int64 plainStr, __int64 plainStr_length, __int64 key, __int64 key_length, __int64 strOut)
{return sub_1005D099C((const void *)plainStr, plainStr_length, (void *)key, key_length, (_BYTE *)strOut, 2);
}
signed __int64 sub_1005D099C(const void *plainStr, signed int plainStr_length, void *keyStr, signed int keyStr_Length, _BYTE *strOut, char value_2)
{
char v6; // w21
_BYTE *strOut2; // x19
signed int v8; // w20
const void *v9; // x22
signed __int64 result; // x0
int v11; // w8
unsigned int v12; // w8
int v13; // w9
int v14; // w8
unsigned int v15; // w24
int v16; // w25
_BYTE *v17; // x23
signed __int64 v18; // x8
signed __int64 v19; // x8
int v20; // w10
int w11; // w11
int w12; // w12
int w14; // w14
unsigned int *v24; // x13
unsigned int v25; // w16
unsigned int *v26; // [xsp+8h] [xbp-58h]
int v27; // [xsp+Ch] [xbp-54h]
int v28; // [xsp+10h] [xbp-50h]
int v29; // [xsp+14h] [xbp-4Ch]
v26 = (unsigned int*) malloc(1000);
v6 = value_2;
strOut2 = strOut;
v8 = plainStr_length;
v9 = plainStr;
result = 0xFFFFFFFFLL;
if (keyStr_Length >= 1 && keyStr && plainStr_length >= 1 && strOut)
{sub_1005D0B50(keyStr, keyStr_Length, (unsigned int *)v26);
//sub_1005D0B50(a3, a4, (unsigned int *)&v26);
v11 = v8 + 15;
if (v8 >= 0)
v11 = v8;
v12 = v8 - (v11 & 0xFFFFFFF0);
v13 = 16 - v12;
v14 = 31 - v12;
if (v13 >= 0)
v14 = v13;
v15 = v13 - (v14 & 0xFFFFFFF0);
v16 = v8 + v15 + 4;
v17 = strOut2 + 4;
memmove(strOut2 + 4, v9, v8);
*strOut2 = 116;
strOut2[1] = 99;
strOut2[2] = v6;
strOut2[3] = v15;
if (v16 >= 5) //plainStr_length
{v18 = (unsigned int)v16 - 4LL;
do
{*v17 = Sbox[(unsigned __int8)*v17];
++v17;
--v18;
} while (v18);
}
if ((signed int)(v15 + v8) >= 16)
{
v19 = 0LL;
// v20 = v26; //0x25
//
// w11 = (int)((&v26)[1]);
// w12 = (int)((&v26)[2]);
// w14 = (int)((&v26)[3]);
v20 = *v26; //0x25
//int * tmp1 = (int*)v20;
w11 = v26[1];
// int * tmp2 = (int*)w11;
w12 = v26[2];
//int * tmp3 = (int*)w12;
w14 = v26[3];
//int * tmp4 = (int*)w14;
v24 = (unsigned int *)(strOut2 + 16);
do
{v25 = *(v24 - 2);
*(v24 - 3) = bswap32(bswap32(*(v24 - 3)) ^ v20);
*(v24 - 2) = bswap32(w11 ^ __ROR4__(bswap32(v25), 24));
*(v24 - 1) = bswap32(w12 ^ __ROR4__(bswap32(*(v24 - 1)), 16));
*v24 = bswap32(w14 ^ __ROR4__(bswap32(*v24), 8));
v24 += 4;
++v19;
} while (v19 < (v15 + v8) >> 4);
}
result = 0LL;
}
free(v26);
v26 = NULL;
return result;
}
void * sub_1005D0B50(void *keyStr, signed int keyStr_length, unsigned int *out)
{
unsigned int *out2; // x19
signed int keyStr_length2; // w20
signed int v5; // w21
void *result; // x0
__int64 v7; // x8
bool v8; // nf
unsigned __int8 v9; // vf
__int64 v10; // x8
unsigned int v11; // w9
unsigned int v12; // w9
out2 = out;
keyStr_length2 = keyStr_length;
if (keyStr_length >= 16)
v5 = 16;
else
v5 = keyStr_length;
result = memcpy(out, keyStr, v5);
if (keyStr_length2 <= 15)
{
v7 = v5 + 1;
do
{*((_BYTE *)out2 + v7 - 1) = InvSbox[*((unsigned __int8 *)out2 + v7 - 2)];
v9 = __OFSUB__(v7, 16LL);
v8 = v7++ - 16 < 0;
} while (v8 ^ v9);
}
v10 = 0LL;
do
{*((_BYTE *)out2 + v10) = Sbox[*((unsigned __int8 *)out2 + v10)];
++v10;
} while (v10 != 16);
v11 = out2[1];
*out2 = bswap32(*out2); //w10
out2[1] = bswap32(v11); //w11
v12 = out2[3];
out2[2] = bswap32(out2[2]); //w12
out2[3] = bswap32(v12); //w14
//printf("");
return result;
}
通过下面 device_register 的 url 咱们能够晓得,设施注册其实是向抖音提交以后设施的一些信息,例如 MAC、SSID、UUID、IMEI、IMSI、WIFIMAC、device_brand、device_model、device_board、device_type、openudid、clientudid、build_serial 等等来注册失去 device_id 和 install_id。
其实抖音的验签机制很野,即便你的 x -gorgon 算法生成略微和它 APP 自身计算的有些出入(说白了就是抖音检测到你是独立计算到),它照样会凋谢一些性能给你,比方获取 feed 接口(热门视频),然而你会发现没法点赞,评论,私信。起初通过 frida 进行一个 hook 验证,发现确有此事,很多 x -gorgon 算法都是应用 hook 或者间接调用 so 到形式实现到,基本没去真正解刨它外面到运算过程。再一次测试到过程中,我把 url 以及 x -khrons 和 cookie,xttsub 固定起来,应用 hook 或者调用 so 的形式去计算 x -gorgon 后果,发现不论你执行多少次,后果都是一样的。然而,我应用 frida 来拦挡抖音它本人的签名过程,并把参数改成和下面的一样,那么它每次计算的后果都不一样。由此可见,抖音在计算过程中必定获取了某些全局参数,比方它签名后会把一些值存入到
一个全局变量,下次计算到时候读取,也或者它在某些性能动作到时候,会记录一些值,影响签名到计算算法。这个事件到的确失去屡次证实,用 hook 或者 so 调用形式其实抖音是晓得的
如果是间接把 SO 拿进去调用,失去的跟 APP 外面得出的是不统一的。
进一步验证,我把 cms 的接口都 HOOK 住。而后看程序。
输入后果如下
decode:0404001000018b386ff8b154ff4fc10cf79d74bca55d75398ee0
decode:5dfc13b6e9b1a8131ec9fe3546ce6e4900000000000000000000000000000000435be92aa3259d3fdbed7d341f16d2da00000000000000000000000000000000
decode:040400100001d956086cf8e14b01c10cf79d74bca55d75394ea6
decode:153a6e2fbe986c0472603ddb349fd95d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
decode:0404001000019bde7af5f8e14bc33736dad874bca55d75395665
decode:f3e0258d2bb713f718dd8a335109228a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
decode:040400100001b6b912a1f8e14bc33736dad874bca55d753956d1
decode:00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
decode:0404001000014d6de9baf8e14bc33736dad874bca55d7539560e
decode:153a6e2fbe986c0472603ddb349fd95d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
decode:0404001000019bde7af5f8e14bc33736dad874bca55d7539d66d
decode:153a6e2fbe986c0472603ddb349fd95d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
decode:0404001000019bde7af5f8e14bc33736dad874bca55d7539d66d
decode:18cb57ab5a5e6c4e281a59e850958c6614e1e5f771c631bc1195c3725673279c435be92aa3259d3fdbed7d341f16d2da00000000000000000000000000000000
调用了 META 接口之后,XG 有显著的变动。在通过 234 编号后就无显著变动。
XG 的计算不单纯是简略的几个参数串在一起调用 SO 就完事的。
我为了谨严再次确认,从软件启动的时候每隔 3 秒调用一次。输入如下。
‘*“0404d07100019a0e1440e23f320ce4a518a2316455f6681c77ff|1595258812”‘*“0404d07100019a0e1440e23f320ce4a518a2316455f6681cb7f3|1595258815”‘*“0404d07100019a0e1440e23f320ce4a518a2316455f6681c0918|1595258818”‘*“0404f871000116414c1cb5ff90d058381eac0ff8b86f5b6cf841|1595258821”‘*“0404c0fa0001b283c4aa6d8371ce4786276f68d39bbfbe3ff76b|1595258824”‘*“04047847000199e497dc87cc722beb6b04bec1dc480ba39ce3b6|1595258827”‘*“04040000000116faf9c9565f3c17c9e2a8d723bfb55edbb34c29|1595258830”‘*“04040000000116faf9c9565f3c17c9e2a8d723bfb55edbb3b4a6|1595258833”‘*“04040000000116faf9c9565f3c17c9e2a8d723bfb55edbb314ac|1595258836”‘*“04040000000116faf9c9565f3c17c9e2a8d723bfb55edbb324af|1595258840”‘*“04040000000116faf9c9565f3c17c9e2a8d723bfb55edbb3e4a3|1595258843”‘*“04040000000116faf9c9565f3c17c9e2a8d723bfb55edbb344a9|1595258846”‘*“04040000000116faf9c9565f3c17c9e2a8d723bfb55edbb3b866|1595258849”‘*“04040000000116faf9c9565f3c17c9e2a8d723bfb55edbb3186c|1595258852”‘*“04040000000116faf9c9565f3c17c9e2a8d723bfb55edbb3d860|1595258855”‘*“04040000000116faf9c9565f3c17c9e2a8d723bfb55edbb3686b|1595258858”
能够晓得,设施注册进去不可用,跟很多因素都有关系,环境信息,设施信息 曾经后面的 xg,以及 xlog 风控算法的反对等等。
TiToData:业余的短视频、直播数据接口服务平台。
更多信息请分割:TiToData
笼罩支流平台:抖音,快手,小红书,TikTok,YouTube