抖音算法逆向分析-仅供学习使用

抖音 as, cp, mas,xlog 压缩签名算法逆向-仅供学习使用
此版本为低版本的解密,因为xlog01开头为低版本,02开头为高版本所用

  1. /***********************************************************************
  2.  
  3. ************************************************************************/
  4.  
  5. #include <stdio.h>
  6. #include "stdinc.h"
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include "yemd5.h"
  10.  
  11. #define CHECK_FLAGS 0x0000
  12. //#define CHECK_FLAGS 0x0040
  13. //#define CHECK_FLAGS 0x0240
  14.  
  15. typedef struct {
  16. char *str1;
  17. char *str2;
  18. char *str3;
  19. char ch;
  20. } user_info;
  21.  
  22. // 抖音
  23. LOCAL user_info g_douyin = {
  24. "efc84c17",
  25. "57218436",
  26. "15387264",
  27. '1'
  28. };
  29.  
  30. // 多闪
  31. LOCAL user_info g_duosan = {
  32. "3ea57347",
  33. "57218436",
  34. "15387264",
  35. '2'
  36. };
  37.  
  38. //////////////////////////////////////////////////////////
  39. // for douyin
  40. LOCAL uchar byte_71214[256] = {
  41. 0x21, 0x4C, 0x74, 0x1B, 0x66, 0xCD, 0xB0, 0xD3, 0x33, 0x31, 0x4B, 0x77, 0x11, 0x45, 0xBE, 0x5E,
  42. 0x99, 0x28, 0x78, 0x5A, 0xBB, 0x3D, 0xF8, 0xB5, 0xAC, 0x62, 0x67, 0xEA, 0x26, 0xA6, 0x0F, 0x87,
  43. 0xA5, 0x1E, 0x9B, 0xD9, 0x12, 0x07, 0x41, 0xD6, 0xDC, 0x3A, 0x6C, 0x17, 0x9F, 0x56, 0x49, 0xC5,
  44. 0x22, 0xCB, 0x3B, 0xAD, 0x6A, 0xCC, 0xE6, 0x48, 0x76, 0x73, 0x24, 0x35, 0xE9, 0x7E, 0x8C, 0x05,
  45. 0x9A, 0x13, 0xC2, 0x30, 0xD2, 0xF6, 0x92, 0xEB, 0xE3, 0xB1, 0xAB, 0x14, 0x53, 0xBF, 0x47, 0x15,
  46. 0x82, 0xB2, 0x69, 0x27, 0xA1, 0x0E, 0x6E, 0xFB, 0x20, 0x0D, 0x50, 0xE8, 0x9E, 0x55, 0x7C, 0x46,
  47. 0x95, 0xA3, 0x52, 0x8E, 0x89, 0x3E, 0x9C, 0xD8, 0x90, 0xE2, 0x84, 0xEE, 0xD5, 0x4F, 0x29, 0x7B,
  48. 0x2D, 0x8A, 0xE7, 0xB4, 0xB3, 0xDF, 0xD4, 0x06, 0xDE, 0x6D, 0xAA, 0x23, 0x40, 0xA4, 0x5B, 0x4E,
  49. 0x38, 0x6F, 0x96, 0x91, 0xA8, 0x86, 0x00, 0x85, 0x98, 0x51, 0xA9, 0xA7, 0x57, 0xFC, 0x5D, 0x65,
  50. 0xC9, 0x72, 0xDB, 0x93, 0x03, 0x59, 0xF4, 0x4D, 0x71, 0xF3, 0xB8, 0x0A, 0x16, 0x2A, 0x44, 0x6B,
  51. 0x36, 0xC8, 0x0C, 0xF7, 0x8D, 0x4A, 0xF0, 0xFA, 0x25, 0x39, 0x97, 0x10, 0xE1, 0xD7, 0xC7, 0x58,
  52. 0x8B, 0x75, 0xCA, 0x60, 0x32, 0x2E, 0x2B, 0xB6, 0xBD, 0x1C, 0x79, 0xC1, 0x01, 0x34, 0x3C, 0x68,
  53. 0x9D, 0x5F, 0xA2, 0xE0, 0x08, 0xCF, 0xED, 0x64, 0x61, 0x04, 0xEC, 0x5C, 0xBC, 0xD0, 0xF9, 0xDD,
  54. 0x70, 0xDA, 0x0B, 0xFF, 0xF5, 0xF2, 0xB7, 0x7F, 0xB9, 0xCE, 0xC6, 0xA0, 0x88, 0x43, 0xC0, 0xD1,
  55. 0x83, 0x2F, 0xFD, 0x19, 0xE5, 0x1A, 0x80, 0x54, 0x18, 0x09, 0x3F, 0x7D, 0x1D, 0x42, 0x94, 0xFE,
  56. 0x8F, 0xAE, 0xEF, 0xE4, 0xC3, 0xBA, 0x7A, 0xF1, 0x63, 0x2C, 0xC4, 0xAF, 0x1F, 0x02, 0x81, 0x37
  57. };
  58.  
  59. // byte_73308_r
  60. LOCAL uchar byte_73308[256] = {
  61. 0x86, 0xBC, 0xFD, 0x94, 0xC9, 0x3F, 0x77, 0x25, 0xC4, 0xE9, 0x9B, 0xD2, 0xA2, 0x59, 0x55, 0x1E,
  62. 0xAB, 0x0C, 0x24, 0x41, 0x4B, 0x4F, 0x9C, 0x2B, 0xE8, 0xE3, 0xE5, 0x03, 0xB9, 0xEC, 0x21, 0xFC,
  63. 0x58, 0x00, 0x30, 0x7B, 0x3A, 0xA8, 0x1C, 0x53, 0x11, 0x6E, 0x9D, 0xB6, 0xF9, 0x70, 0xB5, 0xE1,
  64. 0x43, 0x09, 0xB4, 0x08, 0xBD, 0x3B, 0xA0, 0xFF, 0x80, 0xA9, 0x29, 0x32, 0xBE, 0x15, 0x65, 0xEA,
  65. 0x7C, 0x26, 0xED, 0xDD, 0x9E, 0x0D, 0x5F, 0x4E, 0x37, 0x2E, 0xA5, 0x0A, 0x01, 0x97, 0x7F, 0x6D,
  66. 0x5A, 0x89, 0x62, 0x4C, 0xE7, 0x5D, 0x2D, 0x8C, 0xAF, 0x95, 0x13, 0x7E, 0xCB, 0x8E, 0x0F, 0xC1,
  67. 0xB3, 0xC8, 0x19, 0xF8, 0xC7, 0x8F, 0x04, 0x1A, 0xBF, 0x52, 0x34, 0x9F, 0x2A, 0x79, 0x56, 0x81,
  68. 0xD0, 0x98, 0x91, 0x39, 0x02, 0xB1, 0x38, 0x0B, 0x12, 0xBA, 0xF6, 0x6F, 0x5E, 0xEB, 0x3D, 0xD7,
  69. 0xE6, 0xFE, 0x50, 0xE0, 0x6A, 0x87, 0x85, 0x1F, 0xDC, 0x64, 0x71, 0xB0, 0x3E, 0xA4, 0x63, 0xF0,
  70. 0x68, 0x83, 0x46, 0x93, 0xEE, 0x60, 0x82, 0xAA, 0x88, 0x10, 0x40, 0x22, 0x66, 0xC0, 0x5C, 0x2C,
  71. 0xDB, 0x54, 0xC2, 0x61, 0x7D, 0x20, 0x1D, 0x8B, 0x84, 0x8A, 0x7A, 0x4A, 0x18, 0x33, 0xF1, 0xFB,
  72. 0x06, 0x49, 0x51, 0x74, 0x73, 0x17, 0xB7, 0xD6, 0x9A, 0xD8, 0xF5, 0x14, 0xCC, 0xB8, 0x0E, 0x4D,
  73. 0xDE, 0xBB, 0x42, 0xF4, 0xFA, 0x2F, 0xDA, 0xAE, 0xA1, 0x90, 0xB2, 0x31, 0x35, 0x05, 0xD9, 0xC5,
  74. 0xCD, 0xDF, 0x44, 0x07, 0x76, 0x6C, 0x27, 0xAD, 0x67, 0x23, 0xD1, 0x92, 0x28, 0xCF, 0x78, 0x75,
  75. 0xC3, 0xAC, 0x69, 0x48, 0xF3, 0xE4, 0x36, 0x72, 0x5B, 0x3C, 0x1B, 0x47, 0xCA, 0xC6, 0x6B, 0xF2,
  76. 0xA6, 0xF7, 0xD5, 0x99, 0x96, 0xD4, 0x45, 0xA3, 0x16, 0xCE, 0xA7, 0x57, 0x8D, 0xE2, 0xEF, 0xD3
  77. };
  78.  
  79. LOCAL uint dword_73418[] = {
  80. 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
  81. 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
  82. 0x9216d5d9, 0x8979fb1b, 0xd1310ba6, 0x98dfb5ac,
  83. 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96,
  84. 0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7,
  85. 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69,
  86. 0xa458fea3, 0xf4933d7e, 0x0d95748f, 0x728eb658,
  87. 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5
  88. };
  89. LOCAL uint dword_73408[] = {
  90. 0x9c30d539, 0x2af26013, 0xc5d1b023, 0x286085f0
  91. };
  92.  
  93. LOCAL uchar g_initKey[16] = {
  94. 0x72, 0x71, 0x67, 0xa2, 0xd1, 0xe4, 0x03, 0x3c, 0x47, 0xd4, 0x04, 0x4b, 0xfd, 0x85, 0x0d, 0xd2
  95. };
  96.  
  97. LOCAL char * RAND_STR = "_ZYXWVUTSRQPONMLKJIH";
  98. int global_rand = 0;
  99.  
  100. /////////////////////////////////////////////////////////////
  101. LOCAL uchar hc2i(char ch)
  102. {
  103. if(ch >= '0' && ch <= '9') return ch - '0';
  104. if(ch >= 'a' && ch <= 'f') return ch - 'a' + 10;
  105. if(ch >= 'A' && ch <= 'F') return ch - 'A' + 10;
  106. return 0xff;
  107. }
  108.  
  109. LOCAL int hexstr2hex(char *str, size_t len, uchar *hex)
  110. {
  111. int i, j;
  112. uchar ch;
  113.  
  114. len &= 0xfffffffe;
  115.  
  116. for(i = 0, j = 0; i < len; i += 2, j ++) {
  117. ch = hc2i(str[i]);
  118. if(ch == 0xff) break;
  119. hex[j] = ch << 4;
  120.  
  121. ch = hc2i(str[i + 1]);
  122. if(ch == 0xff) break;
  123. hex[j] |= ch;
  124. }
  125. return j;
  126. }
  127.  
  128. LOCAL char i2hc(uchar ch)
  129. {
  130. if(ch >= 0x10) return '\0';
  131. if(ch < 10) return ch + '0';
  132. return 'a' + (ch - 10);
  133. }
  134.  
  135. LOCAL int hex2hexstr(uchar *hex, size_t len, char *str)
  136. {
  137. int i, j;
  138. char ch;
  139.  
  140. for(i = 0, j = 0; i < len; i ++) {
  141. ch = i2hc(hex[i] >> 4);
  142. if(ch == '\0') break;
  143. str[j ++] = ch;
  144.  
  145. ch = i2hc(hex[i] & 0xf);
  146. if(ch == '\0') break;
  147. str[j ++] = ch;
  148. }
  149. return j;
  150. }
  151.  
  152. LOCAL uint bit_swap(uint v0)
  153. {
  154. uint v1, v2;
  155.  
  156. v1 = ((v0 & 0xAAAAAAAA) >> 1) ^ ((v0 & 0x55555555) << 1);
  157. v2 = ((v1 & 0xCCCCCCCC) >> 2) ^ ((v1 & 0x33333333) << 2);
  158. return ((v2 & 0xF0F0F0F0) >> 4) ^ ((v2 & 0x0F0F0F0F) << 4);
  159. }
  160.  
  161. LOCAL uchar __rbit_byte(uchar ch)
  162. {
  163. uchar c1, c2;
  164.  
  165. c1 = ((ch & 0xAA) >> 1) ^ ((ch & 0x55) << 1);
  166. c2 = ((c1 & 0xCC) >> 2) ^ ((c1 & 0x33) << 2);
  167. c1 = ((c2 & 0xF0) >> 4) ^ ((c2 & 0x0F) << 4);
  168.  
  169. return c1;
  170. }
  171.  
  172. LOCAL void calc_md5(uchar *data, int size, char *md5)
  173. {
  174. int i;
  175. md5_ctx_s md5ctx;
  176. uchar md5hex[16];
  177.  
  178. yemd5_init(&md5ctx);
  179. yemd5_update(&md5ctx, data, size);
  180. yemd5_final(&md5ctx, md5hex);
  181.  
  182. for(i = 0; i < 16; i ++) {
  183. snprintf(md5 + i * 2, 3, "%.2x", md5hex[i]);
  184. }
  185. }
  186.  
  187. #define PARAM_NUM_MAX 512
  188. typedef struct{
  189. char *position;
  190. int keylen;
  191. int valuelen;
  192. } string_pos;
  193.  
  194. LOCAL int string_cmp(char *str1, int len1, char *str2, int len2)
  195. {
  196. int i;
  197.  
  198. for(i = 0; i < len1 && i < len2; i ++) {
  199. if(str1[i] > str2[i]) return 1;
  200. if(str1[i] < str2[i]) return -1;
  201. }
  202. if((i == len1) && (i == len2)) return 0;
  203. if(i == len1) return -1;
  204. return 1;
  205. }
  206.  
  207. LOCAL int string_pos_add2list(string_pos *slist, int count, char *position, int klen, int vlen)
  208. {
  209. int i, ret;
  210.  
  211. for(i = 0; i < count; i ++) {
  212. ret = string_cmp(slist[i].position, slist[i].keylen, position, klen);
  213. if(ret == 0) return -1; // 表示已经存在,不再添加
  214. if(ret > 0) {
  215. memmove(&slist[i + 1], &slist[i], (count - i) * sizeof(string_pos));
  216. break;
  217. }
  218. }
  219. slist[i].position = position;
  220. slist[i].keylen = klen;
  221. slist[i].valuelen = vlen;
  222. return 0;
  223. }
  224.  
  225. LOCAL void copy_param(uchar *dst, uchar *src, int len)
  226. {
  227. int i;
  228.  
  229. for(i = 0; i < len; i ++) {
  230. if(src[i] == '+' || src[i] == ' ') {
  231. dst[i] = 'a';
  232. } else {
  233. dst[i] = src[i];
  234. }
  235. }
  236. }
  237.  
  238. LOCAL int calc_params_md5(user_info *puinfo, char *params, ulong ts, char *devid, char *hex)
  239. {
  240. char *p1, *p2, *p3;
  241. int i, count, size = 0;
  242. string_pos *sposlist;
  243. char temp[128], *buf;
  244.  
  245. // 用 纯c 写字符串操作就是比较操蛋~~
  246. sposlist = (string_pos *)malloc(PARAM_NUM_MAX * sizeof(string_pos));
  247. if(sposlist == NULL) {
  248. return -1;
  249. }
  250. p1 = temp;
  251. snprintf(p1, 128, "device_id=%s", devid);
  252. sposlist[0].position = p1;
  253. sposlist[0].keylen = 9;
  254. sposlist[0].valuelen = strlen(devid);
  255. size = sposlist[0].valuelen;
  256.  
  257. p1 += sposlist[0].keylen + 1 + sposlist[0].valuelen;
  258. snprintf(p1, 100, "rstr=%s", puinfo->str1);
  259. sposlist[1].position = p1;
  260. sposlist[1].keylen = 4;
  261. sposlist[1].valuelen = strlen(puinfo->str1);
  262. size += sposlist[1].valuelen;
  263.  
  264. p1 += sposlist[1].keylen + 1 + sposlist[1].valuelen;
  265. snprintf(p1, 80, "ts=%u", ts);
  266. sposlist[2].position = p1;
  267. sposlist[2].keylen = 2;
  268. sposlist[2].valuelen = strlen(p1) - 3;
  269. size += sposlist[2].valuelen;
  270.  
  271. count = 3;
  272.  
  273. size += strlen(devid) + 3;
  274.  
  275. // 先提取参数对
  276. p1 = params;
  277. while(*p1 != '\0' && count < PARAM_NUM_MAX) {
  278. p2 = strchr(p1, '&');
  279. if(p2 == NULL) p2 = p1 + strlen(p1);
  280. p3 = strchr(p1, '=');
  281. if(p3 && (p3 > p1) && (p3 < p2)) {
  282. p3 ++;
  283. if(p3 != p2) {
  284. // 按升序添加
  285. if(string_pos_add2list(sposlist, count, p1, p3 - p1 - 1, p2 - p3) == 0) {
  286. size += p2 - p3;
  287. count ++;
  288. }
  289. }
  290. }
  291.  
  292. if(*p2 == '\0') break;
  293. p1 = p2 + 1;
  294. }
  295.  
  296. buf = (char *)malloc(size);
  297. if(buf == NULL) {
  298. free(sposlist);
  299. return -1;
  300. }
  301. p1 = buf;
  302. for(i = 0; i < count; i ++) {
  303. //memcpy(p1, sposlist[i].position + sposlist[i].keylen + 1, sposlist[i].valuelen);
  304. copy_param(p1, sposlist[i].position + sposlist[i].keylen + 1, sposlist[i].valuelen);
  305. p1 += sposlist[i].valuelen;
  306. }
  307. free(sposlist);
  308. strcpy_s(p1, strlen(devid) + 1, devid);
  309. p1 += strlen(p1);
  310. *p1 ++ = '4';
  311. *p1 ++ = '3';
  312. *p1 ++ = '5';
  313.  
  314. calc_md5(buf, size, hex);
  315. free(buf);
  316. return 0;
  317. }
  318.  
  319. LOCAL int calc_params_md5_with_rand(user_info *puinfo, char *params, ulong ts, char *devid, char *hex, char *rand)
  320. {
  321. char *p1, *p2, *p3;
  322. int i, count, size = 0;
  323. string_pos *sposlist;
  324. char temp[128], *buf;
  325.  
  326. // 用 纯c 写字符串操作就是比较操蛋~~
  327. sposlist = (string_pos *)malloc(PARAM_NUM_MAX * sizeof(string_pos));
  328. if (sposlist == NULL) {
  329. return -1;
  330. }
  331. p1 = temp;
  332. snprintf(p1, 128, "device_id=%s", devid);
  333. sposlist[0].position = p1;
  334. sposlist[0].keylen = 9;
  335. sposlist[0].valuelen = strlen(devid);
  336. size = sposlist[0].valuelen;
  337.  
  338. p1 += sposlist[0].keylen + 1 + sposlist[0].valuelen;
  339. snprintf(p1, 100, "rstr=%s", puinfo->str1);
  340. sposlist[1].position = p1;
  341. sposlist[1].keylen = 4;
  342. sposlist[1].valuelen = strlen(puinfo->str1);
  343. size += sposlist[1].valuelen;
  344.  
  345. p1 += sposlist[1].keylen + 1 + sposlist[1].valuelen;
  346. snprintf(p1, 80, "ts=%u", ts);
  347. sposlist[2].position = p1;
  348. sposlist[2].keylen = 2;
  349. sposlist[2].valuelen = strlen(p1) - 3;
  350. size += sposlist[2].valuelen;
  351.  
  352. count = 3;
  353.  
  354. size += strlen(devid) + 3;
  355.  
  356. // 先提取参数对
  357. p1 = params;
  358. while (*p1 != '\0' && count < PARAM_NUM_MAX) {
  359. p2 = strchr(p1, '&');
  360. if (p2 == NULL) p2 = p1 + strlen(p1);
  361. p3 = strchr(p1, '=');
  362. if (p3 && (p3 > p1) && (p3 < p2)) {
  363. p3++;
  364. if (p3 != p2) {
  365. // 按升序添加
  366. if (string_pos_add2list(sposlist, count, p1, p3 - p1 - 1, p2 - p3) == 0) {
  367. size += p2 - p3;
  368. count++;
  369. }
  370. }
  371. }
  372.  
  373. if (*p2 == '\0') break;
  374. p1 = p2 + 1;
  375. }
  376.  
  377. buf = (char *)malloc(size);
  378. if (buf == NULL) {
  379. free(sposlist);
  380. return -1;
  381. }
  382. p1 = buf;
  383. for (i = 0; i < count; i++) {
  384. //memcpy(p1, sposlist[i].position + sposlist[i].keylen + 1, sposlist[i].valuelen);
  385. copy_param(p1, sposlist[i].position + sposlist[i].keylen + 1, sposlist[i].valuelen);
  386. p1 += sposlist[i].valuelen;
  387. }
  388. free(sposlist);
  389. strcpy_s(p1, strlen(devid) + 1, devid);
  390. p1 += strlen(p1);
  391. //strcpy_s(buf-3, 3, rand);
  392. *p1++ = rand[0];
  393. *p1++ = rand[1];
  394. *p1++ = rand[2];
  395. //printf("buf:%s\n", buf);
  396. calc_md5(buf, size, hex);
  397. free(buf);
  398. return 0;
  399. }
  400.  
  401. /*
  402. 计算 ascp
  403.   输入:
  404. ts: 10 位时间戳
  405. params: 计算参数, 每个参数用 & 分割
  406. deviceId: 设备ID
  407.   输出:
  408. ascp: 返回 44 字节的ascp值, 空间由上层申请(>44字节)
  409.   返回:
  410. 成功返回 0, 失败返回 -1
  411. */
  412. int __stdcall GetASCP(ulong ts, char *params, char *deviceId, char *ascp)
  413. {
  414. int i;
  415. char hex[33], *p;
  416. user_info *puinfo = NULL;
  417.  
  418. if(params == NULL || deviceId == NULL || ascp == NULL) {
  419. return -1;
  420. }
  421.  
  422. puinfo = &g_douyin;
  423.  
  424. p = strchr(params, '?');
  425. if(p) params = p + 1;
  426.  
  427. // 解析参数
  428. if(calc_params_md5(puinfo, params, ts, deviceId, hex) != 0) {
  429. return -1;
  430. }
  431.  
  432. if(((~ts) & 1) == 0) {
  433. calc_md5(hex, 32, hex);
  434. }
  435.  
  436. //// 先初始化固定值
  437. //ascp[0] = 'a';
  438. //ascp[1] = puinfo->ch;
  439. //ascp[18] = '4';
  440. //ascp[19] = '3';
  441. //ascp[20] = '5';
  442. //ascp[21] = '5';
  443. //ascp[38] = 'e';
  444. //ascp[39] = puinfo->ch;
  445.  
  446. // 先初始化固定值
  447. ascp[0] = 'a';
  448. ascp[1] = puinfo->ch;
  449. ascp[18] = '4';
  450. ascp[19] = '3';
  451. ascp[20] = '5';
  452. ascp[21] = '5';
  453.  
  454. ascp[38] = 'e';
  455. ascp[39] = puinfo->ch;
  456.  
  457. // 下面的4个用变量地址进行运算出来的,有点随机的味道,可以写死
  458. ascp[40] = 'Y';
  459. ascp[41] = 'c';
  460. ascp[42] = 'a';
  461. ascp[43] = 'g';
  462. ascp[44] = '\0';
  463.  
  464. for(i = 0; i < 8; i ++) {
  465. ascp[2 + i * 2] = hex[i];
  466. }
  467. for(i = 24; i < 32; i ++) {
  468. ascp[23 + (i - 24) * 2] = hex[i];
  469. }
  470.  
  471. snprintf(hex, 10, "%08x", ts);
  472. for(i = 0; i < 8; i ++) {
  473. ascp[22 + i * 2] = hex[puinfo->str2[i] - '1'];
  474. ascp[ 3 + i * 2] = hex[puinfo->str3[i] - '1'];
  475. }
  476.  
  477. return 0;
  478. }
  479.  
  480. int __stdcall GetASCP1(ulong ts, char *params, char *deviceId, char *ascp, char *rand_str) {
  481. int i;
  482. char hex[33], *p;
  483. user_info *puinfo = NULL;
  484.  
  485. if (params == NULL || deviceId == NULL || ascp == NULL) {
  486. return -1;
  487. }
  488.  
  489. puinfo = &g_douyin;
  490.  
  491. p = strchr(params, '?');
  492. if (p) params = p + 1;
  493.  
  494. // 解析参数
  495. if (calc_params_md5_with_rand(puinfo, params, ts, deviceId, hex, rand_str) != 0) {
  496. return -1;
  497. }
  498. if (((~ts) & 1) == 0) {
  499. calc_md5(hex, 32, hex);
  500. }
  501.  
  502.  
  503. ascp[0] = 'a';
  504. ascp[1] = puinfo->ch;
  505. memcpy(ascp + 18, rand_str, 4);
  506. ascp[38] = 'e';
  507. ascp[39] = puinfo->ch;
  508.  
  509. if (!global_rand) {
  510. srand(time(NULL));
  511. }
  512.  
  513. ascp[40] = RAND_STR[rand() % 20];
  514. ascp[41] = 's';
  515. ascp[42] = RAND_STR[rand() % 20];
  516. ascp[43] = 'a';
  517. ascp[44] = '\0';
  518.  
  519. for (i = 0; i < 8; i++) {
  520. ascp[2 + i * 2] = hex[i];
  521. }
  522. for (i = 24; i < 32; i++) {
  523. ascp[23 + (i - 24) * 2] = hex[i];
  524. }
  525.  
  526. snprintf(hex, 10, "%08x", ts);
  527. for (i = 0; i < 8; i++) {
  528. ascp[22 + i * 2] = hex[puinfo->str2[i] - '1'];
  529. ascp[3 + i * 2] = hex[puinfo->str3[i] - '1'];
  530. }
  531.  
  532. return 0;
  533.  
  534.  
  535.  
  536. }
  537.  
  538. int __stdcall GetASCPDuosan(ulong ts, char *params, char *deviceId, char *ascp, char *rand_str) {
  539. int i;
  540. char hex[33], *p;
  541. user_info *puinfo = NULL;
  542.  
  543. if (params == NULL || deviceId == NULL || ascp == NULL) {
  544. return -1;
  545. }
  546.  
  547. puinfo = &g_duosan;
  548.  
  549. p = strchr(params, '?');
  550. if (p) params = p + 1;
  551.  
  552. // 解析参数
  553. if (calc_params_md5_with_rand(puinfo, params, ts, deviceId, hex, rand_str) != 0) {
  554. return -1;
  555. }
  556. if (((~ts) & 1) == 0) {
  557. calc_md5(hex, 32, hex);
  558. }
  559.  
  560.  
  561. ascp[0] = 'a';
  562. ascp[1] = puinfo->ch;
  563. memcpy(ascp + 18, rand_str, 4);
  564. ascp[38] = 'e';
  565. ascp[39] = puinfo->ch;
  566.  
  567. if (!global_rand) {
  568. srand(time(NULL));
  569. }
  570.  
  571. ascp[40] = RAND_STR[rand() % 20];
  572. ascp[41] = 's';
  573. ascp[42] = RAND_STR[rand() % 20];
  574. ascp[43] = 'a';
  575. ascp[44] = '\0';
  576.  
  577. for (i = 0; i < 8; i++) {
  578. ascp[2 + i * 2] = hex[i];
  579. }
  580. for (i = 24; i < 32; i++) {
  581. ascp[23 + (i - 24) * 2] = hex[i];
  582. }
  583.  
  584. snprintf(hex, 10, "%08x", ts);
  585. for (i = 0; i < 8; i++) {
  586. ascp[22 + i * 2] = hex[puinfo->str2[i] - '1'];
  587. ascp[3 + i * 2] = hex[puinfo->str3[i] - '1'];
  588. }
  589.  
  590. return 0;
  591.  
  592.  
  593.  
  594. }
  595.  
  596. LOCAL uint sub_20224(uint a1)
  597. {
  598. uint a;
  599. uchar c1, c2, c3, c4;
  600.  
  601. c1 = (a1 >> 24) & 0xFF;
  602. c2 = (a1 >> 16) & 0xFF;
  603. c3 = (a1 >> 8) & 0xFF;
  604. c4 = (a1 ) & 0xFF;
  605.  
  606. a = (byte_73308[c1] << 24) | (byte_73308[c2] << 16) | (byte_73308[c3] << 8) | byte_73308[c4];
  607. return ((a << 10) | (a >> 22)) ^ ((a >> 8) | (a << 24)) ^ a ^ ((a << 2) | (a >> 30)) ^ ((a << 18) | (a >> 14));
  608. }
  609.  
  610. LOCAL uint sub_1F6B0(uint a1)
  611. {
  612. int i;
  613. uchar *p = (uchar *)&a1;
  614. uint s = 0;
  615.  
  616. for(i = 0; i < 4; i ++) {
  617. s = (s << 4) + p[i];
  618. if(s & 0xF0000000) break;
  619. }
  620. return s & 0x7fffffff;
  621. }
  622.  
  623. LOCAL uint sub_1F2E4(uint a1)
  624. {
  625. int i;
  626. uchar *p = (uchar *)&a1;
  627. uint s = 0x4e67c6a7;
  628.  
  629. for(i = 0; i < 4; i ++) {
  630. s ^= (s << 5) + (s >> 2) + p[i];
  631. }
  632. return s & 0x7fffffff;
  633. }
  634.  
  635. LOCAL uint sub_1F4D0(uint a1)
  636. {
  637. int i;
  638. uchar *p = (uchar *)&a1;
  639. uint s = 0;
  640.  
  641. for(i = 0; i < 4; i ++) {
  642. if(i & 0x1) {
  643. s ^= (s << 11) ^ (s >> 5) ^ p[i] ^ 0xFFFFFFFF;
  644. } else {
  645. s ^= (s << 7) ^ (s >> 3) ^ p[i];
  646. }
  647. }
  648. return s & 0x7fffffff;
  649. }
  650.  
  651. LOCAL void sub_1EB64(uint *idata, uchar *key, uchar *odata)
  652. {
  653. int i;
  654. uint val[36];
  655.  
  656. memset(val, 0, sizeof(val));
  657. val[0] = (key[ 0] << 0x18) | (key[ 1] << 0x10) | (key[ 2] << 0x08) | key[ 3];
  658. val[1] = (key[ 4] << 0x18) | (key[ 5] << 0x10) | (key[ 6] << 0x08) | key[ 7];
  659. val[2] = (key[ 8] << 0x18) | (key[ 9] << 0x10) | (key[10] << 0x08) | key[11];
  660. val[3] = (key[12] << 0x18) | (key[13] << 0x10) | (key[14] << 0x08) | key[15];
  661.  
  662. for(i = 0; i < 32; i ++) {
  663. val[i + 4] = sub_20224(val[i + 1] ^ val[i + 2] ^ val[i + 3] ^ idata[i]) ^ val[i];
  664. }
  665.  
  666. odata[ 0] = val[35] >> 0x18; odata[ 1] = val[35] >> 0x10; odata[ 2] = val[35] >> 0x08; odata[ 3] = val[35];
  667. odata[ 4] = val[34] >> 0x18; odata[ 5] = val[34] >> 0x10; odata[ 6] = val[34] >> 0x08; odata[ 7] = val[34];
  668. odata[ 8] = val[33] >> 0x18; odata[ 9] = val[33] >> 0x10; odata[10] = val[33] >> 0x08; odata[11] = val[33];
  669. odata[12] = val[32] >> 0x18; odata[13] = val[32] >> 0x10; odata[14] = val[32] >> 0x08; odata[15] = val[32];
  670. }
  671.  
  672. LOCAL void douyin_my_encrypt(uchar *a1, int size, uint *a3, uchar *a4)
  673. {
  674. int i, r;
  675. uchar ch1, ch2;
  676. uint *p;
  677.  
  678. for(i = 0; i < size / 2; i ++) {
  679. ch1 = *(uchar *)(byte_73308 + byte_71214[__rbit_byte(a1[i])]);
  680. ch2 = *(uchar *)(byte_73308 + byte_71214[__rbit_byte(a1[size - i - 1])]);
  681.  
  682. a1[i] = ch2;
  683. a1[size - i - 1] = ch1;
  684. }
  685.  
  686. if((size % 16) == 0) {
  687. memcpy(a4, a1, 16);
  688. sub_1EB64(a3, a1, a1);
  689.  
  690. r = size / 4;
  691. p = (uint *)a1;
  692. for(i = 0; i < r; i ++) {
  693. p[i] = bit_swap(p[i]) ^ bit_swap(sub_1F6B0(p[(i + 1) % r])) ^ bit_swap(sub_1F4D0(p[(i + 2) % r])) ^ bit_swap(sub_1F2E4(p[(i + 3) % r]));
  694. }
  695. }
  696. }
  697.  
  698. LOCAL void douyin_my_decrypt(uchar *a1, int size, uint *a3, uchar *a4)
  699. {
  700. int i, r;
  701. uchar ch1, ch2;
  702. uint *p;
  703.  
  704. if((size % 16) == 0) {
  705. p = (uint *)a1;
  706.  
  707. r = size / 4;
  708. for(i = r - 1; i >= 0; i --) {
  709. p[i] = p[i] ^ bit_swap(sub_1F6B0(p[(i + 1) % r])) ^ bit_swap(sub_1F4D0(p[(i + 2) % r])) ^ bit_swap(sub_1F2E4(p[(i + 3) % r]));
  710. p[i] = bit_swap(p[i]);
  711. }
  712.  
  713. sub_1EB64(a3, a1, a1);
  714. memcpy(a4, a1, 16);
  715. }
  716.  
  717. for(i = 0; i < size / 2; i ++) {
  718. ch1 = *(uchar *)(byte_73308 + *(uchar *)(byte_71214 + __rbit_byte(a1[i])));
  719. ch2 = *(uchar *)(byte_73308 + *(uchar *)(byte_71214 + __rbit_byte(a1[size - i - 1])));
  720. a1[i] = ch2;
  721. a1[size - i - 1] = ch1;
  722. }
  723. }
  724.  
  725. LOCAL uint sub_1F0D0(uint a1)
  726. {
  727. uint r1, r2;
  728. uint a, b, c, d;
  729.  
  730. a = *(uchar *)(byte_73308 + (uchar)(a1 >> 0x18));
  731. b = *(uchar *)(byte_73308 + (uchar)(a1 >> 0x10));
  732. c = *(uchar *)(byte_73308 + (uchar)(a1 >> 0x08));
  733. d = *(uchar *)(byte_73308 + (uchar)(a1 ));
  734.  
  735. r1 = (a << 0x18) | (b << 0x10) | (c << 0x08) | d;
  736.  
  737. r2 = r1 ^ ((r1 << 0x0d) | (r1 >> 0x13)) ^ ((r1 >> 0x09) | (r1 << 0x17));
  738.  
  739. return r2;
  740. }
  741.  
  742. LOCAL void douyin_my_setencryptkey(uint odata[32], uchar idata[16])
  743. {
  744. int i;
  745. uint temp, val[40];
  746.  
  747. memset(val, 0, sizeof(val));
  748.  
  749. val[0] = ((idata[ 0] << 0x18) | (idata[ 1] << 0x10) | (idata[ 2] << 0x08) | idata[ 3]) ^ dword_73408[0];
  750. val[1] = ((idata[ 4] << 0x18) | (idata[ 5] << 0x10) | (idata[ 6] << 0x08) | idata[ 7]) ^ dword_73408[1];
  751. val[2] = ((idata[ 8] << 0x18) | (idata[ 9] << 0x10) | (idata[10] << 0x08) | idata[11]) ^ dword_73408[2];
  752. val[3] = ((idata[12] << 0x18) | (idata[13] << 0x10) | (idata[14] << 0x08) | idata[15]) ^ dword_73408[3];
  753.  
  754. for(i = 0; i < 32; i ++) {
  755. temp = dword_73418[i] ^ val[i + 0] ^ val[i + 1] ^ val[i + 2] ^ val[i + 3];
  756. val[i + 4] = sub_1F0D0(temp);
  757. odata[i] = val[i + 4];
  758. }
  759. }
  760.  
  761. LOCAL void douyin_my_setdecryptkey(uint odata[32], uchar idata[16])
  762. {
  763. int i;
  764. douyin_my_setencryptkey(odata, idata);
  765.  
  766. // swap
  767. for(i = 0; i < 16; i ++) {
  768. odata[i] ^= odata[31 - i];
  769. odata[31 - i] ^= odata[i];
  770. odata[i] ^= odata[31 - i];
  771. }
  772. }
  773.  
  774. int __stdcall GetMAS(char *as, char *mas)
  775. {
  776. int i, offset;
  777. uchar *pos;
  778. uint ui1, ui2, ui3;
  779. uchar ch1, ch2;
  780. uchar data[27];
  781. uint yeKey[32];
  782. uchar key[16];
  783.  
  784. // 参数非空判断
  785. if(as == NULL || mas == NULL) {
  786. return -1;
  787. }
  788. // 判断输入的 as 长度是否为22
  789. if(strlen(as) != 22) {
  790. return -1;
  791. }
  792.  
  793. data[0] = 0x01;
  794. pos = data + 1;
  795. *pos = (uchar)data;
  796. *(pos + 1) = (ushort)data >> 8;
  797. //*pos = 0x80;
  798. //*(pos + 1) = 0x36;
  799.  
  800. *(ushort *)(pos + 2) = CHECK_FLAGS;
  801. memcpy(pos + 4, as, 22);
  802.  
  803. memset(yeKey, 0, sizeof(yeKey));
  804. memcpy(key, g_initKey, 16);
  805.  
  806. douyin_my_setencryptkey(yeKey, key);
  807. douyin_my_encrypt(pos, 16, yeKey, key);
  808. douyin_my_setencryptkey(yeKey, key);
  809. douyin_my_encrypt(pos + 16, 10, yeKey, key);
  810.  
  811. for(i = 0; i < 27; i ++) {
  812. //sprintf(mas + i * 2, "%.2x", data[i]);
  813. sprintf_s(mas + i * 2, 3, "%.2x", data[i]);
  814. }
  815. return 0;
  816. }
  817.  
  818. int __stdcall GetMAS1(char *as, char *mas, ushort rand) {
  819.  
  820. int i, offset;
  821. uchar *pos;
  822. uint ui1, ui2, ui3;
  823. uchar ch1, ch2;
  824. uchar data[27];
  825. uint yeKey[32];
  826. uchar key[16];
  827.  
  828. // 参数非空判断
  829. if (as == NULL || mas == NULL) {
  830. return -1;
  831. }
  832. // 判断输入的 as 长度是否为22
  833. if (strlen(as) != 22) {
  834. return -1;
  835. }
  836.  
  837. data[0] = 0x01;
  838. pos = data + 1;
  839. *(ushort *)(pos) = rand;
  840.  
  841. *(ushort *)(pos + 2) = CHECK_FLAGS;
  842. memcpy(pos + 4, as, 22);
  843.  
  844. memset(yeKey, 0, sizeof(yeKey));
  845. memcpy(key, g_initKey, 16);
  846.  
  847. douyin_my_setencryptkey(yeKey, key);
  848. douyin_my_encrypt(pos, 16, yeKey, key);
  849. douyin_my_setencryptkey(yeKey, key);
  850. douyin_my_encrypt(pos + 16, 10, yeKey, key);
  851.  
  852. for (i = 0; i < 27; i++) {
  853. //sprintf(mas + i * 2, "%.2x", data[i]);
  854. sprintf_s(mas + i * 2, 3, "%.2x", data[i]);
  855. }
  856. return 0;
  857.  
  858. }
  859.  
  860. void __stdcall MemFree(void *ptr)
  861. {
  862. if(ptr) free(ptr);
  863. }
  864.  
  865. uchar *__stdcall XlogEncrypt(uchar *data, int *psize)
  866. {
  867. int encsize, leftlen;
  868. uint yeKey[32];
  869. uchar key[16];
  870. uchar *buffer = NULL, *pos;
  871.  
  872. if(data == NULL || psize == NULL) {
  873. return NULL;
  874. }
  875.  
  876. leftlen = *psize + 4;
  877. buffer = (uchar *)malloc(leftlen + 1);
  878. if(buffer == NULL) {
  879. return NULL;
  880. }
  881. buffer[0] = 0x01;
  882. pos = buffer + 1;
  883. *pos = (uchar)buffer;
  884. *(pos + 1) = (ushort)buffer >> 8;
  885. *(ushort *)(pos + 2) = CHECK_FLAGS;
  886. memcpy(pos + 4, data, *psize);
  887.  
  888. memset(yeKey, 0, sizeof(yeKey));
  889. memcpy(key, g_initKey, 16);
  890.  
  891. while(leftlen > 0) {
  892. douyin_my_setencryptkey(yeKey, key);
  893. encsize = (leftlen >= 16) ? 16 : leftlen;
  894. douyin_my_encrypt(pos, encsize, yeKey, key);
  895.  
  896. pos += encsize;
  897. leftlen -= encsize;
  898. }
  899. *psize += 5;
  900. return buffer;
  901. }
  902.  
  903. uchar *__stdcall XlogDecrypt(uchar *data, int *psize)
  904. {
  905. int encsize, leftlen;
  906. uint yeKey[32];
  907. uchar key[16];
  908. uchar *buffer = NULL, *pos;
  909.  
  910. if(data == NULL || psize == NULL || *psize < 3) {
  911. return NULL;
  912. }
  913. if((data[0] != 1) || (*psize == 27)) {
  914. return NULL;
  915. }
  916. leftlen = *psize - 1;
  917.  
  918. buffer = (uchar *)malloc(leftlen);
  919. if(buffer == NULL) {
  920. return NULL;
  921. }
  922.  
  923. memset(yeKey, 0, sizeof(yeKey));
  924. memcpy(key, g_initKey, 16);
  925.  
  926. memcpy(buffer, data + 1, leftlen);
  927. pos = buffer;
  928. while(leftlen > 0) {
  929. douyin_my_setdecryptkey(yeKey, key);
  930. encsize = (leftlen >= 16) ? 16 : leftlen;
  931. douyin_my_decrypt(pos, encsize, yeKey, key);
  932.  
  933. pos += encsize;
  934. leftlen -= encsize;
  935. }
  936.  
  937. *psize -= 5;
  938. memmove(buffer, buffer + 4, *psize);
  939. return buffer;
  940. }

原文转自:https://gitee.com/ming369/Tiktok/blob/master/douyin.c#

发表评论

邮箱地址不会被公开。 必填项已用*标注