├── .gitattributes ├── translating.py ├── argus.py └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /translating.py: -------------------------------------------------------------------------------- 1 | # translating from .c to .py 2 | 3 | # note that *(a2+ 16) is equal to a2[16] 4 | # -> *(x + y) = x[y] 5 | 6 | # uLL = 0 so 0x18uLL = 0x180 in .py 7 | 8 | # undefined .c functions (some not implemented yet, some unique .c) 9 | 10 | def __readfsqword(): return 11 | def malloc(): return 12 | def smh_malloc(): return 13 | def calc_checks(): return 14 | def free(): return 15 | def do_some_mutex4(): return 16 | 17 | # .c types in python 18 | # None = undefined type 19 | _QWORD = None 20 | __int64: int 21 | __fastcall: None 22 | _BYTE: bytearray = [] 23 | void: None 24 | 25 | # .c vars in python 26 | byte_165A0: _BYTE = [65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47] # weak 27 | 28 | 29 | #----- (000000000007F846) ---------------------------------------------------- 30 | def does_something_b64(a1: _QWORD, a2: __int64) -> _QWORD *__fastcall: 31 | 32 | # undefined yet 33 | v7: list = [] 34 | 35 | # define vars 36 | v2: __int64 # r15 37 | v3: _BYTE # r12 38 | v4: void # rbx 39 | v5: __int64 # rsi 40 | v7[7]: __int64 # [rsp+0h] [rbp-38h] BYREF 41 | 42 | v7[1] = __readfsqword(0x28) 43 | v7[0] = 0 # 0LL = 0 44 | 45 | v7[1] = __readfsqword(0x28) 46 | v7[0] = 0 47 | base64_encode(0, 0, v7, a2[16] , a2[12] ) 48 | v2 = v7[0] 49 | 50 | if v7[0]: 51 | v3 = malloc(v7[0]) 52 | base64_encode(v3, v2, v7, a2[16] , a2[12]) 53 | # v4 = smh_malloc(0x18uLL) uLL = 0 so 0x18uLL = 0x180 in .py 54 | v4 = smh_malloc(0x180) 55 | calc_checks(v4, v3, v7[0]) 56 | free(v3) 57 | v5 = v4 58 | 59 | else: 60 | v5 = 0 61 | 62 | do_some_mutex4(a1, v5) 63 | return a1 64 | 65 | # implementing base64_encode in .py 66 | # ----- (00000000000736D2) ---------------------------------------------------- 67 | def base64_encode(a1: _BYTE, a2: __int64, a3: __int64, a4: __int64 , a5: __int64) -> _QWORD *__fastcall: 68 | if a5: 69 | if (a5 / 3 - ((a5 % 3 == 0) - 1)) >> 62: 70 | a3 = -1 71 | return 4294967254 72 | v6 = 4 * (a5 / 3 - ((a5 % 3 == 0) - 1)) + 1 73 | if not a1 or v6 > a2: 74 | a3 = v6 75 | return 4294967254 76 | v7 = 1 77 | v8 = a1 78 | while v7 - 1 < 3 * (a5 / 3): 79 | v9 = a4 + v7 - 1 80 | v10 = a4 + v7 81 | v11 = a4 + v7 + 1 82 | v8 = byte_165A0[v9 >> 2] 83 | v8[1] = byte_165A0[(v10 >> 4) | (16 * v9) & 0x30] 84 | v8[2] = byte_165A0[4 * (v10 & 0xF) + (v11 >> 6)] 85 | v8[3] = byte_165A0[v11 & 0x3F] 86 | v8 += 4 87 | v7 += 3 88 | if v7 - 1 < a5: 89 | v13 = a4 + v7 - 1 90 | v14 = 0 91 | if v7 < a5: 92 | v14 = a4 + v7 93 | v8 = byte_165A0[v13 >> 2] 94 | v8[1] = byte_165A0[(v14 >> 4) | (16 * v13) & 0x30] 95 | v15 = 61 96 | if v7 < a5: 97 | v15 = byte_165A0[4 * (v14 & 0xF)] 98 | v8[2] = v15 99 | v8[3] = 61 100 | v8 += 4 101 | a3 = v8 - a1 102 | v8 = 0 103 | else: 104 | a3 = 0 105 | return 0 106 | 107 | # .c code 108 | 109 | 110 | # //----- (00000000000736D2) ---------------------------------------------------- 111 | # __int64 __fastcall base64_encode(_BYTE *a1, unsigned __int64 a2, unsigned __int64 *a3, __int64 a4, unsigned __int64 a5) 112 | # { 113 | # unsigned __int64 v6; // rdx 114 | # unsigned __int64 v7; // r15 115 | # _BYTE *v8; // r14 116 | # unsigned __int8 v9; // si 117 | # unsigned __int64 v10; // rax 118 | # unsigned __int64 v11; // rdx 119 | # unsigned __int64 v13; // rdx 120 | # unsigned int v14; // er10 121 | # char v15; // cl 122 | 123 | # if ( a5 ) 124 | # { 125 | # if ( (a5 / 3 - ((a5 % 3 == 0) - 1LL)) >> 62 ) 126 | # { 127 | # *a3 = -1LL; 128 | # return 4294967254LL; 129 | # } 130 | # v6 = 4 * (a5 / 3 - ((a5 % 3 == 0) - 1LL)) + 1; 131 | # if ( !a1 || v6 > a2 ) 132 | # { 133 | # *a3 = v6; 134 | # return 4294967254LL; 135 | # } 136 | # v7 = 1LL; 137 | # v8 = a1; 138 | # while ( v7 - 1 < 3 * (a5 / 3) ) 139 | # { 140 | # v9 = *(a4 + v7 - 1); 141 | # v10 = *(a4 + v7); 142 | # v11 = *(a4 + v7 + 1); 143 | # *v8 = byte_165A0[v9 >> 2]; 144 | # v8[1] = byte_165A0[(v10 >> 4) | (16 * v9) & 0x30]; 145 | # v8[2] = byte_165A0[4 * (v10 & 0xF) + (v11 >> 6)]; 146 | # v8[3] = byte_165A0[v11 & 0x3F]; 147 | # v8 += 4; 148 | # v7 += 3LL; 149 | # } 150 | # if ( v7 - 1 < a5 ) 151 | # { 152 | # v13 = *(a4 + v7 - 1); 153 | # v14 = 0; 154 | # if ( v7 < a5 ) 155 | # v14 = *(a4 + v7); 156 | # *v8 = byte_165A0[v13 >> 2]; 157 | # v8[1] = byte_165A0[(v14 >> 4) | (16 * v13) & 0x30]; 158 | # v15 = 61; 159 | # if ( v7 < a5 ) 160 | # v15 = byte_165A0[4 * (v14 & 0xF)]; 161 | # v8[2] = v15; 162 | # v8[3] = 61; 163 | # v8 += 4; 164 | # } 165 | # *a3 = v8 - a1; 166 | # *v8 = 0; 167 | # } 168 | # else 169 | # { 170 | # *a3 = 0LL; 171 | # } 172 | # return 0LL; 173 | # } 174 | 175 | 176 | 177 | # _QWORD *__fastcall does_something_b64(_QWORD *a1, __int64 a2) 178 | # { 179 | # unsigned __int64 v2; // r15 180 | # _BYTE *v3; // r12 181 | # void *v4; // rbx 182 | # __int64 v5; // rsi 183 | # unsigned __int64 v7[7]; // [rsp+0h] [rbp-38h] BYREF 184 | 185 | # v7[1] = __readfsqword(0x28u); 186 | # v7[0] = 0LL; 187 | # base64_encode(0LL, 0LL, v7, a2[16] , a2[16] ); 188 | # v2 = v7[0]; 189 | # if ( v7[0] ) 190 | # { 191 | # v3 = malloc(v7[0]); 192 | # base64_encode(v3, v2, v7, a2[16] , a2[16] ); 193 | # v4 = smh_malloc(0x18uLL); 194 | # calc_checks(v4, v3, v7[0]); 195 | # free(v3); 196 | # v5 = v4; 197 | # } 198 | # else 199 | # { 200 | # v5 = 0LL; 201 | # } 202 | # do_some_mutex4(a1, v5); 203 | # return a1; 204 | # } 205 | -------------------------------------------------------------------------------- /argus.py: -------------------------------------------------------------------------------- 1 | # Argus main function 2 | 3 | class Argus: 4 | def __init__(self) -> None: 5 | return 6 | 7 | double = None 8 | __int64 = int 9 | __m128 = int 10 | 11 | def generate_xargus( 12 | self, 13 | a1: __int64, 14 | a2: __m128, 15 | a3: __m128, 16 | a4: __m128, 17 | a5: __m128, 18 | a6: double, 19 | a7: double, 20 | a8: __m128, 21 | a9: __m128, 22 | ) -> int: 23 | 24 | dest: int 25 | off_A3F30: int 26 | v18: int 27 | v19: int 28 | v20: int 29 | v21: int 30 | 31 | v45: int 32 | v47: int 33 | v48: int 34 | v49: int 35 | v50: int 36 | v51: int 37 | v52: int 38 | v53: int 39 | v54: int 40 | v55: int 41 | v57: int 42 | v58: int 43 | v59: int 44 | v60: int 45 | v61: int 46 | v62: int 47 | v63: int 48 | v64: int 49 | v65: int 50 | v66: int 51 | v68: int 52 | v69: int 53 | v70: int 54 | v71: int 55 | v72: int 56 | v73: int 57 | v74: int 58 | v75: int 59 | v78: int 60 | v79: int 61 | v80: int 62 | v81: int 63 | v82: int 64 | v83: int 65 | v84: int 66 | v85: int 67 | v86: int 68 | v87: int 69 | v88: int 70 | v89: int 71 | v91: int 72 | v92: int 73 | v93: int 74 | v94: int 75 | v95: int 76 | v96: int 77 | v97: int 78 | v98: int 79 | v99: int 80 | v100: int 81 | v103: int 82 | v104: int 83 | v105: int 84 | v106: int 85 | v107: int 86 | v108: int 87 | v109: int 88 | v110: int 89 | v111: int 90 | 91 | v139: int 92 | v140: int 93 | v141: int 94 | v142: int 95 | v143: int 96 | v144: int 97 | v144: int 98 | v145: int 99 | v146: int 100 | v147: int 101 | v148: int 102 | v149: int 103 | v150: int 104 | v151: int 105 | 106 | v104: int 107 | dword_0: int 108 | xmmword_A4020: int 109 | off_A4010: int 110 | 111 | v152 = _readfsqword(0x28) 112 | v9 = a1 113 | v10 = a1 + 8 114 | v70 = a1 + 16 115 | v68 = a1 + 24 116 | v73 = a1 + 32 117 | v74 = a1 + 40 118 | v75 = a1 + 48 119 | v72 = a1 + 56 120 | ptr = a1 + 72 121 | v77 = a1 + 80 122 | 123 | memcpy(dest, off_A3F30, 0xE0) 124 | v113 = 538970409 125 | self.more_mutex2(v100, v10) 126 | v116 = self.do_some_mutex3(v100.m128i_i64) + 16 127 | self.do_some_mutex(v100) 128 | v114 = 1 129 | v115 = rand_from_time() 130 | self.mutex_rwlock(v111, v10) 131 | 132 | if self.mutex_and_calc4(v111.m128i_i64): 133 | 134 | v11 = v109 135 | self.mutex_rwlock2(v109, v10) 136 | v12 = 1 137 | v13 = 0 138 | else: 139 | v11 = v110 140 | self.mutex_rwlock(v110, v10) 141 | v13 = 1 142 | v12 = 0 143 | v117 = self.do_some_mutex(v11.m128i_i64) + 16 144 | 145 | if v12: 146 | self.do_some_mutex(v109) 147 | if v13: 148 | self.do_some_mutex(v110) 149 | 150 | v14 = self.sub_43094(v10) 151 | v15 = 0 152 | 153 | if not v14: 154 | v15 = v9 155 | 156 | v132 = v15 157 | v16 = v10 + 10 158 | self.mutex_unlock_lock(v100, v16) 159 | v17 = self.mutex_unlock_lock2(v100.m128i_i64) 160 | self.mult1(v108, v17) 161 | self.mult2(v100) 162 | 163 | v118 = self.do_some_mutex3(v108) + 16 164 | self.mult3(v107, a2.m128_u64, a3, a4, a5, v18, v19, a8, a9) 165 | v119 = self.do_some_mutex3(v107.m128i_i64) + 16 166 | version_string = self.get_version_string() 167 | v120 = self.str_sig(a2, a3, a4, a5, v20, v21, a8, a9, v107, v17) 168 | v22 = v73 + 16 169 | v122 = v73 + 12 170 | v123 = v22 171 | v124 = 0 172 | v125 = v9 173 | self.sm3_hash(v105, v70) 174 | 175 | v126 = 6 176 | v127 = v106 177 | self.sm3_hash(v103, v68) 178 | v128 = 6 179 | v129 = v104 180 | v102 = dword_0 181 | v101 = xmmword_A4020 182 | v100 = off_A4010 183 | v23 = self.UND_pthread2(v103, v68) 184 | v24 = self.sub_45AF4(v23) 185 | 186 | self.malloc_shit(v150, "sign") 187 | # DWORD2(v101) = UND_pthread3(v24, v150) 188 | self.calc_smh3(v150) 189 | v25 = self.UND_pthread2(v150, v150) 190 | v26 = self.sub_45AF4(v25) 191 | self.malloc_shit(v150, "setting") 192 | # LODWORD(v102) = UND_pthread3(v26, v150) 193 | self.calc_smh3(v150) 194 | v27 = self.UND_pthread2(v150, v150) 195 | v28 = self.sub_45AF4(v27) 196 | self.malloc_shit(v150, "report") 197 | # HIDWORD(v101) = UND_pthread3(v28, v150) 198 | self.calc_smh3(v150) 199 | v130 = v100 200 | v131 = v74 + 16 201 | v138 = a1 + 64 202 | self.maybe_malloc_check(v97) 203 | self.maybe_malloc_check(v94) 204 | if self.calc7(v75) or self.calc7(v72): 205 | 206 | v137 = "none" 207 | 208 | else: 209 | 210 | v137 = v72 + 16 211 | self.calc_and_mutex(v150, v75, 0) 212 | v29 = self.do_some_mutex2(v150) 213 | self.calc_cool3_0(v97, v29) 214 | self.do_some_mutex(v150) 215 | v133 = v98 216 | v134 = v99 217 | self.call_more_calc1(v147, v68, v70) 218 | self.call_more_calc1(v150, v147, v72) 219 | self.calc_smh3(v147) 220 | self.sm3_hash(v147, v150) 221 | self.calc_cool3_0(v94, v147) 222 | self.calc_smh3(v147) 223 | v135 = v95 224 | v136 = v96 225 | self.calc_smh3(v150) 226 | 227 | v30 = self.j_UND_calc_smh6(dest) 228 | self.calc_checks2(v91, 0, v30) 229 | self.j_UND_calc_smh7(dest, v93) 230 | v31 = rand_from_time() 231 | v71 = HIWORD(v31) 232 | v90 = HIWORD(v31) 233 | self.mutex_unlock_lock(v144, v16) 234 | v32 = self.mutex_unlock_lock2(v144.m128i_i64) 235 | self.malloc_shit(v150, "sign_key") 236 | self.sub_8334E(v146, v32, v150) 237 | v33 = self.do_some_mutex2(v146) 238 | self.sub_7F908(v147, v33) 239 | v34 = self.do_some_mutex2(v147) 240 | self.calc_smh1(v87, v34) 241 | self.do_some_mutex(v147) 242 | self.do_some_mutex(v146) 243 | self.calc_smh3(v150) 244 | self.mult2(v144) 245 | self.calc_checks(v150, v89, 16) 246 | self.calc_and_mutex(v147, v150, 0) 247 | v35 = self.do_some_mutex2(v147) 248 | self.calc_smh1(v86, v35) 249 | self.do_some_mutex(v147) 250 | self.calc_smh3(v150) 251 | self.calc_checks(v150, v89 + 16, 16) 252 | self.calc_and_mutex(v147, v150, 0) 253 | v36 = self.do_some_mutex2(v147) 254 | self.calc_smh1(v85, v36) 255 | self.do_some_mutex(v147) 256 | self.calc_smh3(v150) 257 | v69 = v31 258 | # LODWORD(v150) = v31 259 | self.calc_checks(v146, v150, 4) 260 | self.call_more_calc1(v147, v87, v146) 261 | self.call_more_calc1(v150, v147, v87) 262 | self.sm3_hash(v83, v150) 263 | self.calc_smh3(v150) 264 | self.calc_smh3(v147) 265 | self.calc_smh3(v146) 266 | v82 = self.calc_tyhon(v89, v88) 267 | self.maybe_malloc_check(v81) 268 | self.calc_smh1(v139, v83) 269 | if v84 <= 31: 270 | self.calc_checks2(v150, 0, 32 - v84) 271 | self.calc_1_caller(v139, v150) 272 | self.calc_smh3(v150) 273 | 274 | v37 = v93 275 | v38 = v92 276 | v39 = v140 277 | v40 = 0 278 | self.calc_checks2(v147, 0, 576) 279 | self.calc_checks(v146, v39, 32) 280 | self.calc_checks(v144, v37, v38) 281 | v41 = v146[2] 282 | v42 = v148 283 | v151 = 0 284 | v150 = 0 285 | 286 | while v40 != 4: 287 | v150[v40] = v41[8 * v40] 288 | v40 += 1 289 | 290 | v42 = v150 # list()?? 291 | v150 = 0 292 | v151 = 0 293 | for i in range(0, 71): 294 | v44 = v151[1] 295 | v45 = v150 296 | for j in range(1, 4): 297 | v149[j] = v150[j] 298 | v47 = v45[1] ^ v44 << 61 299 | # v151 = v47 ^ ((0x3DC94C3A046D678B >> (i % 0x3E)) & 1 | 0xFFFFFFFFFFFFFFFC) ^ v45 ^ v47 >> 1 300 | # .c -> *(&v151 + 1) = v47 ^ ((0x3DC94C3A046D678BuLL >> (i % 0x3Eu)) & 1 | 0xFFFFFFFFFFFFFFFCLL) ^ v45 ^ __ROR8__(v47, 1) 301 | # v151[1] = v47 ^ ((0x3DC94C3A046D678BuLL >> (i % 0x3Eu)) & 1 | 0xFFFFFFFFFFFFFFFCLL) ^ v45 ^ __ROR8__(v47, 1) 302 | 303 | v151[1] = ( 304 | v47 305 | ^ ((0x3DC94C3A046D678B >> (i % 0x3E)) & 1 | 0xFFFFFFFFFFFFFFFC) 306 | ^ v45 307 | ^ __ROR8__(v47, 1) 308 | ) 309 | v42[i + 1] = v150 310 | 311 | v48 = 16 * ((v144.m128i_i32[3] + 16) / 16) 312 | v49 = v48 - v144.m128i_i8[12] 313 | 314 | self.maybe_malloc_check(v150) 315 | self.calc_smh2(v150, v49, v49) 316 | self.calc_1_caller(v144, v150) 317 | v50 = 0 318 | self.calc_checks2(v141, 0, v48) 319 | v51 = v148 320 | v52 = v145 321 | v53 = v143 322 | 323 | while v50 < v48: 324 | v54 = v52[v50] 325 | v55 = v52[v50 + 8] 326 | for k in range(0, 72): 327 | v57 = v55 328 | v55 = ( 329 | v51[8 * k] 330 | ^ ((v55 << 1) | (v55 >> 7)) & ((v55 << 8) | (v55 >> 8)) 331 | ^ v54 332 | ^ ((v55 << 2) | (v55 >> 6)) 333 | ) 334 | v54 = v57 335 | v53[v50] = v54 336 | v53[v50 + 8] = v55 337 | v50 += 16 338 | 339 | v58 = malloc(v48) 340 | v59 = v142 341 | v60 = v142 342 | memcpy(v58, v53, v142) 343 | self.calc_smh3(v141) 344 | self.calc_smh3(v150) 345 | self.calc_smh3(v144) 346 | self.calc_smh3(v146) 347 | self.calc_smh3(v147) 348 | 349 | if v58 and v59 > 0: 350 | self.calc_smh2(v81, v59, 0x20) 351 | memcpy(v81[2], v58, v60) 352 | # elif not v58: 353 | # goto LABEL_36 354 | # free(v58) 355 | # LABEL_36: 356 | 357 | if v58: 358 | free(v58) 359 | 360 | self.calc_smh3(v139) 361 | self.call_more_calc1(v150, v73, v81) 362 | # HIDWORD(v149) = _byteswap_ulong(calc_tyhon(v90, 2)) 363 | 364 | v61 = 0 365 | self.calc_checks2(v147, 0, v150 >> 32) 366 | v62 = v150 >> 32 367 | v63 = 0 368 | 369 | if v150 >= 0: 370 | v63 = v150 >> 32 371 | while True: 372 | v62 -= 1 373 | if v63 == v61: 374 | break 375 | v148[v61] = v151[v62] ^ v149[v61 & 3 + 4] 376 | v61 += 1 377 | 378 | v80 = 0x1800000000000000 379 | v64 = (((v104 & 0x3F) | 0x6000) << 46) | ((v106 & 0x3F) << 40) 380 | v80 = v64 | rand_from_time() 381 | 382 | self.calc_checks(v139, v82, 1) 383 | self.calc_checks(v79, v80, 8) 384 | self.call_more_calc1(v141, v139, v79) 385 | self.call_more_calc1(v144, v141, v147) 386 | self.sub_53A5C(v78, v71) 387 | self.call_more_calc1(v146, v144, v78) 388 | self.calc_smh3(v78) 389 | self.calc_smh3(v144) 390 | self.calc_smh3(v141) 391 | self.calc_smh3(v79) 392 | self.calc_smh3(v139) 393 | 394 | v139 = [1] 395 | self.sub_7FA8C(v141, v146, v86, v85, v139) 396 | v65 = self.do_some_mutex2(v141) 397 | self.calc_smh1(v144, v65) 398 | self.do_some_mutex(v141) 399 | self.sub_53A5C(v79, v69) 400 | self.call_more_calc1(v139, v79, v144) 401 | self.does_something_b64(v78, v139) 402 | v66 = self.do_some_mutex2(v78) 403 | self.calc_smh1(v141, v66) 404 | self.do_some_mutex(v78) 405 | self.calc_smh3(v139) 406 | self.calc_smh3(v79) 407 | 408 | # import ctypes 409 | 410 | # libc = ctypes.CDLL('libc.so.6') 411 | 412 | # buffer = ctypes.c_char_p() 413 | # r = libc.asprintf(ctypes.byref(buffer), b"The total is %d\n", 5+8) 414 | 415 | # libc.puts(buffer) 416 | # libc.printf(b"%d characters generated\n", r) 417 | 418 | ptr = "%s" % "X-Argus" 419 | v77 = "%s" % v143 420 | 421 | self.calc_smh3(v141) 422 | self.calc_smh3(v144) 423 | self.calc_smh3(v146) 424 | self.calc_smh3(v147) 425 | self.calc_smh3(v150) 426 | self.calc_smh3(v81) 427 | self.calc_smh3(v83) 428 | self.calc_smh3(v85) 429 | self.calc_smh3(v86) 430 | self.calc_smh3(v87) 431 | self.calc_smh3(v91) 432 | self.calc_smh3(v94) 433 | self.calc_smh3(v97) 434 | self.calc_smh3(v103) 435 | self.calc_smh3(v105) 436 | self.do_some_mutex(v107) 437 | self.do_some_mutex(v108) 438 | 439 | return _readfsqword(0x28) 440 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## TikTok X-Argus 2 | ## Reversing the Argus Algorithm 3 | 4 | X-Argus Api (also includes Mssdk) 5 | - https://rapidapi.com/tiktok-api-development-tiktok-api-development-default/api/tiktok-services1 6 | 7 | ```js 8 | 9 | X-Argus 10 | R0fy5TvUEH0E6kFiGAQFnDJhAZRtBWVjFXygipEnVBxrRsmOfPV+BxlZqR8/QvHfQ34cw8zKhLtUf+zJo/Sc3/CEICpL3DRdtx2+au1li5h9Rhs6jPopy2zq1d1qVxE6W1QhzL1YdKiPX9IumXadNtxo7XXLL+/cIYQqFTNfobF2DFzWT2I1MuMNwXoB+nPYdnf852vOkKYpXwm4SzwOMN4Q 47 47 f2 e5 3b d4 10 7 d 04 ea 41 62 18 04 05 9 c 32 61 01 94 6 d 05 65 63 15 7 c a0 8 a 91 27 54 1 c 6b 46 c9 11 | 12 | 8 e 7 c f5 13 | 7 e 07 19 59 14 | a9 1f 3f 42 15 | f1 df 43 7 e 16 | 1 c c3 cc ca 17 | 84 bb 54 7f 18 | ec c9 a3 f4 19 | 9 c df f0 84 20 | 20 2 a 4b dc 21 | 34 5 d b7 1 d 22 | be 6 a ed 65 23 | 8b 98 7 d 46 24 | 1b 3 a 8 c fa 25 | 29 cb 6c ea 26 | d5 dd 6 a 57 27 | 11 3 a 5b 54 28 | 21 cc bd 58 29 | 74 a8 8f 5f 30 | d2 2 e 99 76 31 | 9 d 36 dc 68 32 | ed 75 cb 2f 33 | ef dc 21 84 34 | 2 a 15 33 5f 35 | a1 b1 76 0 c 36 | 5 c d6 4f 62 37 | 35 32 e3 0 d 38 | c1 7 a01 fa 39 | 73 d8 76 77 40 | fc e7 6b ce 41 | 90 a6 29 5f 42 | 09 b8 4b 3 c 43 | 0 e 30 de 10 44 | 45 | ``` 46 | 47 | aes encryption point 48 | final result place; 49 | search: `0xc253c` eor `w9`,` w11`,` w9` ; 50 | 51 | ```js 52 | 0x70ef40853c 0xc253c eor w9, w11, w9 ; x9= 0x564fafa4 -> 0xfce76bce , x11= 0xaaa8c46a -> 0xaaa8c46a ;xa-debug 0xfce76bce 53 | 0x70ef408540 0xc2540 eor w11, w12, w0 ; x0= 0xedef6a38 -> 0xedef6a38 , x11= 0xaaa8c46a -> 0x90a6295f , x12= 0x7d494367 -> 0x7d494367 ; xa-debug 0x90a6295f 54 | 0x70ef408544 0xc2544 eor w12, w13, w1 ; x1= 0x24ee9fad -> 0x24ee9fad , x12= 0x7d494367-> 0x9b84b3c , x13= 0x2d56d491 -> 0x2d56d491 ;xa-debug 0x09b84b3c 55 | 0x70ef408548 0xc2548 eor w8, w10, w8 ; x8= 0x8ac41b06 -> 0xe30de10 , x10= 0x84f4c516 -> 0x84f4c516 ;xa-debug 0x0e30de10 56 | ``` 57 | 58 | eor w9, w11, w9 ; 59 | 0x564fafa4 ^ 0xa4aa9470 = 0xf2e53bd4 Trace 60 | down: 0x564fafa4 has always existed 0xa4aa9470 This value is changed. 61 | Analyze 0x564fafa4 62 | ```js 63 | 0x70ef407eac 0xc1eac eor w9, w9, w1 ; x1= 0x6200 -> 0x6200 , x9= 0x604fcd40 -> 0x604faf40 64 | 0x70ef407eb0 0xc1eb0 eor w9, w9, w3 ; x3= 0xe4 -> 0xe4 , x9= 0x604faf40 -> 0x604fafa4 65 | 0x70ef407eb4 0xc1eb4 eor w9, w9 , w18 ; x9= 0x604fafa4 -> 0x564fafa4 , x18= 0x36000000 -> 0x36000000 66 | ``` 67 | 0x36000000 This value is familiar, like aes' RCON. 68 | static const uint8_t Rcon[11] = {0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 }; 69 | 70 | Go back up to see if aes is used, findcrypt in ida can recognize it. 71 | In fact, the positioning is very simple, the offset here is 0xc1eb4. Take it to ida for static analysis. 72 | ```js 73 | .text: 00000000000 C1EA8 LDR W3, [X15,W3,UXTW# 2 ] 74 | .text: 00000000000 C1EAC EOR W9, W9, W1 75 | .text: 00000000000 C1EB0 EOR W9, W9, W3 76 | .text: 00000000000 C1EB4 EOR W9, W9 77 | .text: 00000000000 C1EB8 EOR W18, W4, W9 78 | .text: 00000000000 C1EBC STP W9, W18, [X11] 79 | ``` 80 | Exactly, this function is the aes algorithm. 81 | 82 | ```js 83 | __int64 __fastcall sub_C1DE8 (__int64 a1, unsigned int *a2, unsigned int a3) 84 | .text: 00000000000 C1DE8 ; __unwind { 85 | .text: 00000000000 C1DE8 LSR W8, W2, # 2 86 | .text: 00000000000 87 | C1DEC AND W8, W8, W8, # 0 : 00000000000 C1DF0 ADD W8, W8, # 6 88 | .text: 00000000000 C1DF4 STR X8, [X0,# 0x1E0 ] 89 | .text: 00000000000C1DF8 LDR W9, [X1] 90 | .text: 00000000000 C1DFC CMP W2, # 0x20 91 | .text: 00000000000 C1E00 REV W9, W9 92 | .text: 00000000000 C1E04 STR W9, [X0] 93 | .text: 00000000000 C1E08 LDR W10 ] 94 | .text: 00000000000 C1E0C REV W10, W10 95 | .text: 00000000000 C1E10 STR W10, [X0,# 4 ] 96 | .text: 00000000000 C1E14 LDR W10, [X1,#8 ] 97 | .text: 00000000000 C1E18 REV W10, W10 98 | .text: 00000000000 C1E1C STR W10, [X0,# 8 ] 99 | .text: 00000000000 C1E20 REV W10 , [X1,# 0xC ] 100 | .text: 00000000000 101 | .text : 00000000000 C1E28 STR W10, [X0,# 0xC ] 102 | ``` 103 | This function has 3 parameters, what is it to chase in 010. For 64-bit instructions, the first three functions are generally x0, x1, and x2; 104 | 105 | ```js 106 | 0x70ef407df4 0xc1df4 str x8, [x0, # 0x1e0 ] ; x0= 0x714f36da30 -> 0x714f36da30 , x8= 0xa -> 0xa 107 | 0x70ef407df8 0xc1df8 ldr w9, [x1] ; x1= 0x70e8016c40 -> 0x70e8016c40 , x9= 0x714f36e5e8 -> 0x763359f1 108 | 0x70ef407dfc 0xc1dfc cmp w2, # 0x20 ; x2= 0x10 -> 0x10 109 | ``` 110 | The read length is only 0x10, which is like the length of the key, x2 16 bits, and the assumption is that it is set as the key. 111 | x0: 0x714f36da30 112 | x1: 0x70e8016c40 113 | x2: 0x10 114 | 115 | ```js 116 | 0x70ef407e00 0xc1e00 rev w9, w9 ; x9= 0x763359f1 -> 0xf1593376 117 | 0x70ef407e04 0xc1e04 str w9, [x0] ; x0= 0x714f36da30 -> 0x714f36da30 , x9= 0xf1593376 -> 0xf1593376 118 | 0x70ef407e08 0xc1e08 ldr w10, [x1, # 4 ] ; x1= 0x70e8016c40 -> 0x70e8016c40 , x10= 0x714f36e5c0 -> 0x8da96e76 119 | 0x70ef407e0c 0xc1e0c rev w10, w10 ; x10= 0x8da96e76 -> 0x766ea98d 120 | 0x70ef407e10 0x ,4 # str w10, [x, 4 # str w10] ; x0= 0x714f36da30 -> 0x714f36da30 , x10= 0x766ea98d -> 0x766ea98d 121 | 0x70ef407e14 0xc1e14 ldr w10, [x1, # 8 ] ; x1= 0x70e8016c40 -> 0x70e8016c40 , x10= 0x766ea98d -> 0x51bf334 122 | 0x70ef407e18 0xc1e18 rev w10, w10 ; x10= 0x51bf334 -> 0x34f31b05 123 | 0x70ef407e1c 0xc1e1c str w10, [x0, # 8 ] ; x0= 0x714f36da30 -> 0x714f36da30 , x10= 0x34f31b05 -> 0x34f31b05 124 | 0x70ef407e20 0xc1e20 ldr w10, [x1, # 0xc ] ; x1= 0x70e8016c40 -> 0x70e8016c40 , x10= 0x34f31b05 - > 0xe45b9d7a 125 | 0x70ef407e24 0xc1e24 rev w10, w10 ; 126 | ``` 127 | 128 | key: f1 59 33 76 76 6e a9 8d 34 f3 1b 05 7a 9d 5b e4 129 | 130 | As mentioned in the previous article on general algorithm, the key length of aes is related to the number of rounds. Pseudocode here can also be determined. 131 | 132 | ```js 133 | switch ( a3 ) 134 | { 135 | case 0x20u: 136 | case 0x18u: 137 | case 0x10u: 138 | a3=x2=16. Basically determine the key16 bit, and 128 mode. 139 | 140 | v9 = *(_DWORD *)((char *)&unk_1094F8 + v5); 141 | v4 ^= dword_1084F8[(v8 >> 16) & 0xFF] ^ dword_1088F8[(unsigned __int16)v8 >> 8] ^ dword_108CF8[(unsigned __int8) v8] ^ dword_1090F8[v8 >> 24] ^ v9; 142 | } 143 | ``` 144 | 145 | Looking at the source code of aes, rcon will be used when the key is expanded. 146 | http://git.bwing.com.cn/zhanghua/freeswitch/blob/728d960017c510c8108ce6c62cfbdd691a0c8831/libs/srtp/crypto/cipher/aes.c 147 | 148 | ```js 149 | expanded_key->round[i].v8[ 0 ] = aes_sbox[expanded_key->round[i ​​-1 ].v8[ 13 ]] ^ rc; 150 | .rodata: 00000000001094F 8 unk_1094F8 DCB 0 ; DATA XREF: sub_C1DE8+ 68 ↑o 151 | . rodata: 00000000001094F 8 ; sub_C1DE8+ 84 ↑o ... 152 | .rodata: 00000000001094F 9 DCB 0 153 | .rodata: 00000000001094F A DCB 0 154 | .rodata: 00000000001094F B DCB 1 155 | .rodata0: 000199C DCB 0 156 | .rodata: 00000000001094F D DCB 0 157 | .rodata: 00000000001094F E DCB 0 158 | .rodata: 00000000001094F F DCB 2 159 | .rodata: 0000000000109500 DCB 0 160 | .rodata: 0000000000109501 DCB 0 161 | .rodata: 0000000000109502 DCB 0 162 | .rodata: 0000000000109503 DCB 4 163 | .rodata : 0000000000109504 DCB 0 164 | .rodata: 0000000000109505 DCB 0 165 | .rodata: 0000000000109506 DCB 0 166 | .rodata: 0000000000109507 DCB 8 167 | .rodata: 0000000000109508 DCB 0 168 | .rodata: 0000000000109509 DCB 0 169 | .rodata: 000000000010950 A DCB 0 170 | .rodata: 000000000010950B DCB 0x10 171 | .rodata: 000000000010950 C DCB 0 172 | .rodata: 000000000010950D DCB 0 173 | .rodata: 000000000010950 E DCB 0 174 | .rodata: 000000000010950F DCB 0x20 175 | .rodata: 0000000000109510 DCB 0 176 | .rodata: 0000000000109511 DCB 0 177 | .rodata: 0000000000109512 DCB 0 178 | .rodata: 0000000000109513 DCB 0x40 ; @ 179 | .rodata: 0000000000109514 DCB 0 180 | .rodata : 0000000000109515 DCB 0 181 | .rodata: 0000000000109516 DCB 0 182 | .rodata: 0000000000109517 DCB 0x80 183 | .rodata: 0000000000109518 DCB 0 184 | .rodata: 0000000000109519 DCB 0 185 | .rodata: 000000000010951 A DCB 0 186 | .rodata: 000000000010951B DCB 0x1B 187 | .rodata: 000000000010951 C DCB 0 188 | .rodata: 000000000010951 D DCB 0 189 | .rodata: 000000000010951 E DCB 0 190 | .rodata: 000000000010951F DCB 0x36 ; 6 191 | ``` 192 | The case1 branch is also taken here. 193 | 194 | ```c 195 | void AES_init_ctx_iv ( struct AES_ctx* ctx, const uint8_t * key, const uint8_t * iv) 196 | { KeyExpansion (ctx->RoundKey, key); memcpy (ctx->Iv, iv, AES_BLOCKLEN); } 197 | ``` 198 | 199 | The key is found, then find the offset iv (determine whether it is cbc or ecb mode.) 200 | It can be known that it is called by sub_C2978. Continue this line of thinking to push upwards. 201 | 202 | ```c 203 | .text:00000000000C6B14 ; DATA XREF: .rodata:000000000010C97C↓o 204 | .text:00000000000C6B14 LDP X9, X10, [X0,#8] ; jumptable 00000000000C6AF8 case 1 205 | .text:00000000000C6B18 MOV X0, X8 206 | .text:00000000000C6B1C LDR X1, [ X9,#0x10] 207 | .text:00000000000C6B20 LDR W2, [X9,#0xC] 208 | .text:00000000000C6B24 LDR X3, [X10,#0x10] 209 | .text:00000000000C6B28 B sub_C2978 210 | ``` 211 | 212 | Been chasing here: kind of like a complete aes. 213 | a1 = 1 214 | 215 | ```c 216 | signed __int64 __fastcall sub_C6B5C(int ** a1, __int64 a2, char * a3, _BYTE * a4, unsigned int a5) { 217 | _BYTE * v5; // x19 char *v6; // x20 __int64 v7; // x21 __int64 v8; // x23 int v9; // w24 unsigned int v10; // w25 _OWORD *v11; // x22 __int64 i; // x8 _BYTE *v13; // x19 char *v14; // x20 __int64 v15; // x21 int v16; // w8 unsigned __int64 v17; // x22 unsigned __int64 v18; // x23 signed __int64 result; // x0 218 | 219 | v13 = a4; 220 | v14 = a3; 221 | v15 = a2; 222 | v16 = ** a1; 223 | if (v16 == 1) // go here { v5 = a4; v6 = a3; v7 = a2; if ( a5 & 0xF ) { result = 0xFFFFFFFF LL; } else { v8 = 0LL ; v9 = 0 ; v10 = a5 >> 4 ; v11 = (_OWORD *)(a2 + 488 ); while ( v9 != v10 ) { for ( i = 0LL ; i ! = 224 | 225 | 16; 226 | ++i) * 227 | ((_BYTE * ) v11 + i) ^= v6[i]; 228 | sub_C2970(v7, (unsigned int * )(v7 + 488)); 229 | ++v9; 230 | v6 += 16;*(_OWORD * ) & v5[v8] = * v11; 231 | v8 += 16 LL; 232 | } 233 | result = 0 LL; 234 | } 235 | } 236 | else { 237 | if (v16 == 2) { 238 | sub_C2CA0(a2, a3, a4, a5); 239 | } else if (v16 = = 3) { 240 | sub_C2F24(a2, a3, a4, a5); 241 | 242 | } else { 243 | v17 = 0 LL; 244 | v18 = a5; 245 | while (v17 < v18) { 246 | sub_C224C(v15, (unsigned int * ) & v14[v17], & v13[v17]); 247 | v17 += 16 LL; 248 | } 249 | } 250 | result = 0 LL; 251 | } 252 | return result; 253 | } 254 | ``` 255 | ```c 256 | static void XorWithIv(uint8_t * buf, 257 | const uint8_t * Iv) { 258 | uint8_t i; 259 | for (i = 0; i < AES_BLOCKLEN; ++i) // The block in AES is always 128bit no matter the key size { buf[i] ^= Iv[i]; } } 260 | ``` 261 | aes - cbc has the processing of plaintext buf and iv XOR, which is very suspicious here, look at the data for: 262 | 263 | ```c 264 | (i = 0 LL; i != 16; ++i) * ((_BYTE * ) v11 + i) ^= v6[i]; 265 | ``` 266 | 267 | ```c 268 | .text: 00000000000 C2A4C loc_C2A4C ; CODE XREF: sub_C6B5C -40F 8↓j 269 | .text: 00000000000 C2A4C LDRB W9, [X20,X8] 270 | .text: 271 | 000000000000 C2A50 LDRB W10, [X22, X80 ] 002000 W10, W9 ; eor iv 272 | .text: 00000000000 C2A58 STRB W9, [X22,X8] 273 | .text: 00000000000 C2A5C ADD X8, X8, # 1 274 | 275 | 0x70ef408a54 0xc2a54 eor w9, w10, w9 ; x9= 0x35 -> 0x2a , x10= 0x1f -> 0x1f ; xa-debug aes_iv 276 | 0x70ef408a58 0xc2a58 strb w9 , [x22, x8] ; x8= 0x0 - > 0x0 , x9 0x2a , x22= 0x714f36de90 -> 0x714f36de90 277 | 0x70ef408a5c 0xc2a5c add x8, x8, # 1 ; x8= 0x0 -> 0x1 278 | 0x70ef408a60 0xc2a60 cmp x8, # 0x10 ; x8= 0x1-> 0x1 279 | 0x70ef408a4c 0xc2a4c ldrb w9, [x20, x8] ; x8= 0x1 -> 0x1 , x9= 0x2a -> 0x47 , x20= 0x70e803bb20 -> 0x70e803bb20 280 | 0x70ef408a50 0xc2a50 ldrb w10, [x22, x8] ; x8= 0x1 -> 0x1 , x10= 0x1f -> 0xe1 , x22= 0x714f36de90 -> 0x714f36de90 281 | 0x70ef408a54 0xc2a54 eor w9, w10, w9 ; x9= 0x47 -> 0xa6 , x10= 0xe1 -> 0xe1 282 | 0c2584 strb w9, [x22, x8] ; x8= 0x1 -> 0x1 , x9= 0xa6 -> 0xa6 , x22= 0x714f36de90 -> 0x714f36de90 283 | 0x70ef408a5c 0xc2a5c add x8, x8 , # 1 ; x8= 0x1 -> cmp 0x408 284 | 0xc2 # 0x10 ; x8= 0x2 -> 0x2 285 | 0x70ef408a4c 0xc2a4c ldrb w9, [x20, x8] ; x8= 0x2 -> 0x2 , x9= 0xa6 -> 0x47 , x20= 0x70e803bb20 -> 0x70e803bb20 286 | 0x70ef4 0xc2a50 ldrb w10, [x22, x8] ; x8= 0x2 -> 0x2 , x10= 0xe1 - > 0x9 , x22= 0x714f36de90 - > 0x714f36de90 287 | 0x70ef408a54 0xc2a54 eor w9, w10, w9 x0 - > 0x9 = 0x47 > 0x9 288 | 0x70ef408a58 0xc2a58 strb w9, [x22, x8] ; x8= 0x2 -> 0x2 , x9= 0x4e -> 0x4e , x22= 0x714f36de90 -> 0x714f36de90 289 | 0x70ef408a5c 0xc2 a5c add x8, x8, # 1 ;0x2 -> 0x3 290 | 0x70ef408a60 0xc2a60 cmp x8, # 0x10 ; x8= 0x3 -> 0x3 291 | 0x70ef408a4c 0xc2a4c ldrb w9, [x20, x8] ; x8= 0x3 -> 0x3 , x9= 0x4e -> 0x47 , x20= 0x70e803bb20 -> 0x70e803bb20 292 | 0x70ef408a50 0xc2a50 ldrb w10, [x22, x8] ; x8= 0x3 -> 0x3 , x10= 0x9 -> 0xa4 , x22= 0x714f36de90 -> 0x714f36de90 293 | 0x70ef408a54 0xc2a54 eor w9, w10, w9 ; x9=0x47 -> 0xe3 , x10= 0xa4 -> 0xa4 294 | 0x70ef408a58 0xc2a58 strb w9, [x22, x8] ; x8= 0x3 -> 0x3 , x9= 0xe3 -> 0xe3 , x22= 0x714f36de90 -> 0x714f36de90 295 | 0x70ef408a5c 0xc2a5c add x8, x8, # 1 ; x8= 0x3 -> 0x4 296 | 0x70ef408a60 0xc2a60 cmp x8, # 0x10 ; x8= 0x4 -> 0x4 297 | 0x70ef408a4c 0xc2a4c ldrb w9, [x20, x8] ; x8= 0x4 -> 0x4, x9= 0xe3 -> 0x47 , x20= 0x70e803bb20 -> 0x70e803bb20 298 | 0x70ef408a50 0xc2a50 ldrb w10, [x22, x8] ; x8= 0x4 -> 0x4 , x10= 0xa4 -> 0x12 , x22= 0x714f36de90 -> 0x714f36de90 299 | 0x70ef408a54 0xc2a54 eor w9, w10, w9 ; x9= 0x47 -> 0x55 , x10= 0x12 -> 0x12 300 | 0x70ef408a58 0xc2a58 strb w9, [x22, x8] ; x8= 0x4 -> 0x4 , x9= 0x55 -> 0x55 , x22=0x714f36de90 -> 0x714f36de90 301 | 0x70ef408a5c 0xc2a5c add x8, x8, # 1 ; x8= 0x4 -> 0x5 302 | 0x70ef408a60 0xc2a60 cmp x8, # 0x10 ; x8= 0x5 -> 0x5 303 | 0x70ef408a4c 0xc2a4c ldrb w9, [x20, x8] ; x8= 0x5 -> 0x5 , x9= 0x55 -> 0x1 , x20= 0x70e803bb20 -> 0x70e803bb20 304 | 0x70ef408a50 0xc2a50 ldrb w10, [x22, x8] ; x8= 0x5 -> 0x5 , x10= 0x12 -> 0x52, x22= 0x714f36de90 -> 0x714f36de90 305 | 0x70ef408a54 0xc2a54 eor w9, w10, w9 ; x9= 0x1 -> 0x53 , x10= 0x52 -> 0x52 306 | 0x70ef408a58 0xc2a58 strb w9, [x22, x8] ; x8= 0x5 -> 0x5 , x9= 0x53 -> 0x53 , x22= 0x714f36de90 -> 0x714f36de90 307 | 0x70ef408a5c 0xc2a5c add x8, x8, # 1 ; x8= 0x5 -> 0x6 308 | 0x70ef408a60 0xc2a60 cmp x8, # 0x10 ; x8= 0x6 ->0x6 309 | 0x70ef408a4c 0xc2a4c ldrb w9, [x20, x8] ; x8= 0x6 -> 0x6 , x9= 0x53 -> 0x90 , x20= 0x70e803bb20 -> 0x70e803bb20 310 | 0x70ef408a50 0xc2a50 ldrb w10, [x22, x8] ; x8= 0x6 -> 0x6 , x10= 0x52 -> 0x83 , x22= 0x714f36de90 -> 0x714f36de90 311 | 0x70ef408a54 0xc2a54 eor w9, w10, w9 ; x9= 0x90 -> 0x13 , x10= 0x83 -> 0x83 312 | 0x70ef408a58 strb w9, [x22, x8] ; x8= 0x6 - > 0x6 , x9 = 0x13 -> 0x13 , x22= 0x714f36de90 -> 0x714f36de90 313 | 0x70ef408a5c 0xc2a5c add 314 | x8 , x8 , # 1 ; # 0x10 ; x8= 0x7 -> 0x7 315 | 0x70ef408a4c 0xc2a4c ldrb w9, [x20, x8] ; x8= 0x7 -> 0x7 , x9= 0x13 -> 0xe , x20= 0x70e803bb20 -> 0x70e803bb20 316 | 0x70ef40 0xc2a50 ldrb w10, [x22, x8] ; x8= 0x7 -> 0x7 , x10= 0x83 -> 0xf4 , x22= 0x714f36de90 -> 0x714f36de90 317 | 0x70ef408a54 0xc2a54 eor w9, w10, wxfxe - > 0x9 = 0 > 0xf4 318 | 0x70ef408a58 0xc2a58 strb w9, [x22, x8] ; x8= 0x7 -> 0x7 , x9= 0xfa -> 0xfa , x22= 0x714f36de90 -> 0x714f36de90 319 | 0x70ef408a5c 0xc2 ; x8, # 1a5c add x8, x0x7 -> 0x8 320 | 0x70ef408a60 0xc2a60 cmp x8, # 0x10 ; x8= 0x8 -> 0x8 321 | 0x70ef408a4c 0xc2a4c ldrb w9, [x20, x8] ; x8= 0x8 -> 0x8 , x9= 0xfa -> 0x18 , x20= 0x70e803bb20 -> 0x70e803bb20 322 | 0x70ef408a50 0xc2a50 ldrb w10, [x22, x8] ; x8= 0x8 -> 0x8 , x10= 0xf4 -> 0x18 , x22= 0x714f36de90 -> 0x714f36de90 323 | 0x70ef408a54 0xc2a54 eor w9, w10, w9 ; x9=0x18 -> 0x0 , x10= 0x18 -> 0x18 324 | 0x70ef408a58 0xc2a58 strb w9, [x22, x8] ; x8= 0x8 -> 0x8 , x9= 0x0 -> 0x0 , x22= 0x714f36de90 -> 0x714f36de90 325 | 0x70ef408a5c 0xc2a5c add x8, x8, # 1 ; x8= 0x8 -> 0x9 326 | 0x70ef408a60 0xc2a60 cmp x8, # 0x10 ; x8= 0x9 -> 0x9 327 | 0x70ef408a4c 0xc2a4c ldrb w9, [x20, x8] ; x8= 0x9 -> 0x9 , x9=0x0 -> 0xf6 , x20= 0x70e803bb20 -> 0x70e803bb20 328 | 0x70ef408a50 0xc2a50 ldrb w10, [x22, x8] ; x8= 0x9 - > 0x9 , x10= 0x18 -> 0xde , x22= 0x714f36de90 -> 0x714f36de90 329 | 0x70ef408a54 0xc2a54 eor w9, w10, w9 ; x9= 0xf6 -> 0x28 , x10= 0xde -> 0xde 330 | 0x70ef408a58 0xc2a58 strb w9, [x22, x8] ; x8= 0x9 - > 0x9 , x9= 0x28 -> 0x28 , x22=0x714f36de90 -> 0x714f36de90 331 | 0x70ef408a5c 0xc2a5c add x8, x8, # 1 ; x8= 0x9 -> 0xa 332 | 0x70ef408a60 0xc2a60 cmp x8, # 0x10 ; x8= 0xa -> 0xa 333 | 0x70ef408a4c 0xc2a4c ldrb w9, [x20, x8] ; x8= 0xa -> 0xa , x9= 0x28 -> 0x3d , x20= 0x70e803bb20 -> 0x70e803bb20 334 | 0x70ef408a50 0xc2a50 ldrb w10, [x22, x8] ; x8= 0xa -> 0xa , x10= 0xde -> 0x9e, x22= 0x714f36de90 -> 0x714f36de90 335 | 0x70ef408a54 0xc2a54 eor w9, w10, w9 ; x9= 0x3d -> 0xa3 , x10= 0x9e -> 0x9e 336 | 0x70ef408a58 0xc2a58 strb w9, [x22, x8] ; x8= 0xa -> 0xa , x9= 0xa3 -> 0xa3 , x22= 0x714f36de90 -> 0x714f36de90 337 | 0x70ef408a5c 0xc2a5c add x8, x8, # 1 ; x8= 0xa -> 0xb 338 | 0x70ef408a60 0xc2a60 cmp x8, # 0x10 ; x8= 0xb-> 0xb 339 | 0x70ef408a4c 0xc2a4c ldrb w9, [x20, x8] ; x8= 0xb - > 0xb , x9= 0xa3 -> 0x44 , x20= 0x70e803bb20 -> 0x70e803bb20 340 | 0x70ef408a50 0xc2a50 ldrb w10, [x22, x8] ; x8= 0xb -> 0xb , x10= 0x9e -> 0x5 , x22= 0x714f36de90 -> 0x714f36de90 341 | 0x70ef408a54 0xc2a54 eor w9, w10, w9 ; x9= 0x44 -> 0x41 , x10= 0x5 -> 0x5 342 | 0x2a588008 strb w9, [x22, x8] ; x8= 0xb - > 0xb , x9 = 0x41 -> 0x41 , x22= 0x714f36de90 - > 0x714f36de90 343 | 0x70ef408a5c 0xc2a5c add x8 , x8, # 1 ; # 0x10 ; x8= 0xc -> 0xc 0x70ef408a4c 0xc2a4c ldrb w9, [x20, x8] ; x8= 0xc -> 0xc , x9= 0x41 -> 0x9 , x20= 0x70e803bb20 -> 0x70e803bb20 0x70ef40 344 | 345 | 346 | 0xc2a50 ldrb w10, [x22, x8] ; x8= 0xc - > 0xc , x10= 0x5 -> 0x1a , x22= 0x714f36de90 - > 0x714f36de90 347 | 0x70ef408a54 0xc2a54 eor w9 , w10, w9 x1 , x9= 0x = 9 > 0x1a 348 | 0x70ef408a58 0xc2a58 strb w9, [x22, x8] ; x8= 0xc -> 0xc , x9= 0x13 -> 0x13 , x22= 0x714f36de90 -> 0x714f36de90 349 | 0x70ef408a5c 0xc2a5c add x8, x8, # 1 ;0xc -> 0xd 350 | 0x70ef408a60 0xc2a60 cmp x8, # 0x10 ; x8= 0xd -> 0xd 351 | 0x70ef408a4c 0xc2a4c ldrb w9, [x20, x8] ; x8= 0xd -> 0xd , x9= 0x13 -> 0x47 , x20= 0x70e803bb20 -> 0x70e803bb20 352 | 0x70ef408a50 0xc2a50 ldrb w10, [x22, x8] ; x8= 0xd -> 0xd , x10= 0x1a -> 0x96 , x22= 0x714f36de90 -> 0x714f36de90 353 | 0x70ef408a54 0xc2a54 eor w9, w10, w9 ; x9=0x47 -> 0xd1 , x10= 0x96 -> 0x96 354 | 0x70ef408a58 0xc2a58 strb w9, [x22, x8] ; x8= 0xd -> 0xd , x9= 0xd1 -> 0xd1 , x22= 0x714f36de90 -> 0x714f36de90 355 | 0x70ef408a5c 0xc2a5c add x8, x8, # 1 ; x8= 0xd -> 0xe 356 | 0x70ef408a60 0xc2a60 cmp x8, # 0x10 ; x8= 0xe -> 0xe 357 | 0x70ef408a4c 0xc2a4c ldrb w9, [x20, x8] ; x8= 0xe -> 0xe, x9= 0xd1 -> 0xb8 , x20= 0x70e803bb20 -> 0x70e803bb20 358 | 0x70ef408a50 0xc2a50 ldrb w10, [x22, x8] ; x8= 0xe -> 0xe , x10= 0x96 -> 0x9e , x22= 0x714f36de90 -> 0x714f36de90 359 | 0x70ef408a54 0xc2a54 eor w9, w10, w9 ; x9= 0xb8 -> 0x26 , x10= 0x9e -> 0x9e 360 | 0x70ef408a58 0xc2a58 strb w9, [x22, x8] ; x8= 0xe -> 0xe , x9= 0x26 -> 0x26 , x22=0x714f36de90 -> 0x714f36de90 361 | 0x70ef408a5c 0xc2a5c add x8, x8, # 1 ; x8= 0xe -> 0xf 362 | 0x70ef408a60 0xc2a60 cmp x8, # 0x10 ; x8= 0xf -> 0xf 363 | 0x70ef408a4c 0xc2a4c ldrb w9, [x20, x8] ; x8= 0xf -> 0xf , x9= 0x26 -> 0x44 , x20= 0x70e803bb20 -> 0x70e803bb20 364 | 0x70ef408a50 0xc2a50 ldrb w10, [x22, x8] ; x8= 0xf -> 0xf , x10= 0x9e -> 0x12, x22= 0x714f36de90 -> 0x714f36de90 365 | 0x70ef408a54 0xc2a54 eor w9, w10, w9 ; x9= 0x44 -> 0x56 , x10= 0x12 -> 0x12 366 | 0x70ef408a58 0xc2a58 strb w9, [x22, x8] ; x8= 0xf -> 0xf , x9= 0x56 -> 0x56 , x22= 0x714f36de90 -> 0x714f36de90 367 | ``` 368 | Just get `iv = 1FE109A4125283F418DE9E051A969E12` 369 | 370 | Here is exactly 16 times, and in aes; 371 | ```c 372 | static void XorWithIv(uint8_t * buf, 373 | const uint8_t * Iv) { 374 | uint8_t i; 375 | for (i = 0; i < AES_BLOCKLEN; ++i) // The block in AES is always 128bit no matter the key size 376 | { 377 | buf[i] ^= Iv[i]; 378 | } 379 | } 380 | ``` 381 | ```c 382 | void AES_CBC_encrypt_buffer(struct AES_ctx * ctx, uint8_t * buf, size_t length) { 383 | size_t i; 384 | uint8_t * Iv = ctx -> Iv; 385 | for (i = 0; i < length; i += AES_BLOCKLEN) { 386 | XorWithIv(buf, Iv); 387 | Cipher((state_t * ) buf, ctx -> RoundKey); 388 | Iv = buf; 389 | buf += AES_BLOCKLEN; 390 | } /* store Iv in ctx for next call */ 391 | memcpy(ctx -> Iv, Iv, AES_BLOCKLEN); 392 | } 393 | 394 | // See how many groups there are here; 395 | ``` 396 | 397 | search: 0xc2a54. A total of 160 groups of 160/16=10. Exactly 10 rounds. 398 | See if aes can decrypt 399 | and solve it. 400 | 401 | 402 | ```txt 403 | 35 47 47 47 47 01 90 0e 18 f6 3d 44 09 47 b8 44 48 f3 cb 74 b0 84 a6 5a eb eb 76 62 3c ca 64 31 ab 50 4a 9e d0 e1 ee 87 5a 27 66 6 ab 6a e0 c4 e1 f5 3d 30 7c 49 c5 c3 6c 9a 15 f0 d3 05 50 82 3d 22 ac ef 49 d1 9e f0 87 8f 62 13 54 3e 1d 11 c7 0e 5a 8b a6 25 e8 6d 2f 4c b5 b7 72 9 04 69 8b 80 81 82 e7 71 54 0a bd fb dd 09 a2 0c c6 a0 aa 5f 82 46 70 1c 4d 18 c6 f3 60 a8 dc a8 b3 6c bb 37 33 ff fd c7 fd ff fd 47 fd 47 47 404 | ``` 405 | 406 | It just matches the previous buf plaintext. 407 | 3547474747 35 is a fixed value, and 47474747 is the random value of the previous frida script hook. 408 | 409 | Continue to push back up to see how these data are generated, look for in the trace file 410 | 411 | #### aes operation before encryption 412 | ``` 413 | 0x70ef3baf44 0x74f44 orr x8, x8, x9 ; x8=0x100000000->0x180e900100000000, x9=0x180e900000000000->0x180e900000000000 414 | ``` 415 | 01 90 0e 18 happens to be little endian. 0x180e900100000000. 416 | 417 | ``` 418 | 0x70ef3baf3c 0x74f3c ldr x9, [x11, w9, uxtw # 3 ] ; x9= 0x2 -> 0xe800000000000 , x11= 0x714f36f580 -> 0x714f36f580 419 | 0x70ef3baf40 0x74f40 ldr x8, [x11, w8, uxtw # 3 ] ; x8= 0x1 -> 0x1800000000000000 , x11= 0x714f36f580 -> 0x714f36f580 420 | 0x70ef3baf44 0x74f44 orr x8, x8, x9 ; x8= 0x1800000000000000 -> 0x180e800000000000 , x9= 0xe800000000000 -> 0xe800000000000 0x70ef3bb6bc 0x756bc lsl x8, x8, x11 ; x8= 421 | 422 | 0x3 -> 0x1800000000000000 , x11= 0x3b -> 0x3b 423 | 424 | ``` 425 | There is an lsl command here. translate to python 426 | 427 | ```py 428 | def lsl ( data, lsr_offset ): 429 | result = (data >> ( 64 - lsr_offset)) | (data << lsr_offset) return result & 0xffffffffffffffff res = lsl( 0x3 , 0x3b ) print ( hex (res)) # 0x180000000000000 lsl x8 , x8, x11 ; x8= 0x3a -> 0xe800000000000 , x11= 0x2e -> 0x2e The summary is: ((lsl( 0x3 , 0x3b ) ^ lsl ( 0x3a , 0x2e )) ^ 0x100000000000 ) ^ 0x100000 430 | ``` 431 | 432 | It seems that there are several constants, and we will see different results in the trace. 433 | Move on to the next result. f6 3d 44 09 434 | 435 | Looking alone can find some strings. 436 | 437 | ![pasted-19](https://user-images.githubusercontent.com/113767969/190852198-5e643f1d-03d8-489a-88ce-6172e0ece5a5.png) 438 | 439 | These results are all XORed with a key. This key: 0xfffdc7fd 440 | 441 | pasted-20 442 | 443 | 0xfffdc7fd: The generation rules are not detailed here. 444 | After a little bit, you can find them in the trace file. 445 | 446 | In fact, there is a set of algorithms. 447 | 448 | ```js 449 | 0x70ef3bb6a4 0x756a4 lsl w8, w8, w11 ; x8= 0x47 -> 0x23800 , x11= 0xb - > 0xb ;xa-xorkey 450 | 0x70ef3bb714 0x75714 sxtw x8, w8 ; x8= 0x23800 -> 0x23800 0x70ef3baf3c 0x74f3c ldr x9, [x11, w9, uxtw # 3 ] ; x9= 0x7 -> 0x23800 , x11= 0x714f36ddc0 -> 0x714f36ddc0 0x70ef3baf40 0x74f40 ldr x8, [x11, w8, uxtw # 3 ] ; x8= 0x1 -> 0x47 , x11= 451 | 452 | 453 | 0x714f36ddc0 -> 0x714f36ddc0 454 | 0x70ef3baf44 0x74f44 orr x8, x8, x9 ; x8= 0x47 -> 0x23847 , x9= 0x23800 -> 0x23800 0x70ef3bb640 0x75640 ldr x9, [x11, w9, uxtw # 3 ] ; x9= 0x1 -> 0x23847 , x11= 0x714f36ddc0 -> 0x714f36ddc0 0x70ef3bb644 0x75644 ldr x8, [x11, w8, uxtw # 3 ] ; x8= 0x7 -> 0x2 , x11= 0x714f36ddc0 -> 0x714f36ddc0 0x70ef36ddc0 0x70 ; 455 | 456 | 457 | 458 | 0x2 -> 0x23845 , x9= 0x23847 -> 0x23847 0x70ef3bb648 0x75648 eor x8, x8, x9 ; x8= 0x23845 -> 0x23802 , x9= 0x47 -> 0x47 0x70ef3bb658 0x75658 ldr x9, [x11, w9, uxtw # 3 ] ; x9= 0x1 -> 0x23802 , x11= 0x714f36ddc0 -> 0x714f36ddc0 0x70ef3bb65c 0x7565c ldr x8, [x11, w8, uxtw # 3 ] ; x8= 0x0 - > 0x0 , x11 = 0x714f36dddc0460x70701 459 | 460 | 461 | 462 | 463 | 464 | 0x75660 orr x8, x8, x9 ; x8= 0x0 -> 0x23802 , x9= 0x23802 -> 0x23802 465 | 0x70ef3bb664 0x75664 mvn x8, x8 ; x8= 0x23802 -> 0xffffffffffffdc7fd 466 | and perform the sum of the first random number byte in ramdom, lsl operation orr operation. The final mvn operation. 467 | ``` 468 | 469 | code above. 470 | 471 | ```py 472 | def get_aes_xor_key ( random_hex ): 473 | split_key = int (random_hex[: 2 ], 16 ) 474 | random_key = lsl(split_key, 0xb ) random_key 475 | = split_key | random_key 476 | num_key = lsr(split_key, 0x5 ) 477 | random_key = random_key ^ num_key 478 | random_key = random_key ^ split_key 479 | random_key = 0x0 | random_key 480 | xor_key = int ( hex ((~random_key) & 0xffffffffffffffff )[- 8 :], 16 ) return xor_key 481 | ``` 482 | Data after decryption: 483 | 484 | **09 c0 83 f4 b8 45 83 b5 0c 36 b3 4d 7b 5b 9d 16 14 8b a5 c1 35 99 f6 56 af b7 59 2d 1e 13 40 a7 d8 9b ac 97 1f c7 58 55 5d 39 26 3e c2 a cd bb4 ab 67 ea 0d 14 f8 af 7f fa df 53 12 8e 2c 61 0d 40 72 9d ee 93 c3 e2 ec 00 f3 a5 76 61 d8 17 90 e8 b1 4a 4a b5 67 16 f3 90 f9 96 76 47 a9 7c 7d f5 40 3c 20 f6 5f cb 3b 5f 57 98 7f b9 8d db b0 e7 3b 34 9d 57 21 6f 4e 93 46 f0 ce 00 00 00 00 00 00 80 00 b8 ba** 485 | 486 | ```àsm 487 | 0x70ef3bb648 0x75648 eor x8, x8, x9 ; x8= 0x73b562f3d0204222 -> 0x9c083f4b84583b5 , x9= 0x7a75e1076865c197 -> 0x7a75e1076865c197 488 | 0x70ef3bb64c 0x7564c str x8, [x11, w10, uxtw # 3 ] ; x8= 0x9c083f4b84583b5 -> 0x9c083f4b84583b5 , x10= 0x7 -> 0x7 , x11= 0x714f36dbb0 -> 0x714f36dbb0 489 | 0x70ef3bb06c 0x7506c ldr x9, [x19] ; x9= 0x7a75e1076865c197 -> 0x70ef4486b8 , x19= 0x714f36dba8 -> 0x7814 490 | 0x70ef3bb070 0x75070 ldur x8, [x22, # -0x20 ] ; x8= 0x9c083f4b84583b5 -> 0x0 , x22= 0x714f36dce0 - > 0x714f36dce0 Since the length is 16 bits, divide it by 8 bytes 09 c0 83 f4 b8 45 36 b3 4 d 7b 5b 9 d 16 14 8b a5 c1 35 99 f6 56 af b7 59 2 d 1 e 13 40 491 | 492 | 493 | 494 | 495 | 496 | a7 497 | d8 9b ac 97 1f c7 58 55 498 | 5 d 39 26 08 c2 cd bb b4 499 | 3 a 3 e ab 67 ea 0 d 14 f8 500 | af 7f fa df 53 12 8 e 2 c 501 | 61 0 d 40 72 9 d ee 93 c3 502 | e2 ec 00 f3 a5 76 61 d8 503 | 17 90 e8 b1 4 a4 a b5 67 504 | 16 f3 90 f9 96 76 47 7 c 505 | 7 d 1 a b6 a9 f5 40 3 c 20 506 | f6 5f cb 3b 5f 57 98 7f 507 | b9 8 d db b0 e7 3b 34 9 d 508 | 57 21 6f 4 e 93 46 f0 ce 509 | 00 00 00 00 00 00 80 00 510 | Excluding the last group of complements, there are exactly 16 groups.16 * 8 = 128 lengths. 511 | It's a bit like a symmetric algorithm, but it's actually symmetric, otherwise how to decrypt it. It may be tt's own self-defined symmetric algorithm. 512 | ``` 513 | ```asm 514 | 0x70ef3bb648 0x75648 eor x8, x8, x9 ; x8= 0x28b2874f9c4f259a -> 0x57216f4e9346f0ce , x9= 0x7f93e8010f09d554 -> 0x7f93e8010f09d554 ;xa-eor-res 0x57216f4e9346f0ce 515 | 0x70ef3bb64c 0x7564c str x8, [x11, w10, uxtw # 3 ] ; x8= 0x57216f4e9346f0ce -> 0x57216f4e9346f0ce , x10= 0x7 -> 0x7 , x11= 0x714f36dbb0 -> 0x714f36dbb0 516 | 0x70ef3bb06c 0x7506c ldr x9, [x19] ; x9= 0x7f93e8010f09d554 -> 0x70ef4486b8 , x19= 0x7-> 0x714f36dba8 517 | 0x70ef3bb070 0x75070 ldur x8, [x22, # -0x20 ] ; x8= 0x57216f4e9346f0ce -> 0x0 , x22= 0x714f36dce0 -> 0x714f36dce0 518 | ``` 519 | Here is the reverse order: 520 | 521 | ```js 522 | 0x70ef42abb4 0xe4bb4 ldrb w9, [x21, x8] ; x8= 0x0 -> 0x0 , x9= 0xda778b58e2a2834b -> 0xce , x21= 0x7146b9c7e0 -> 0x7146b9c7e0 523 | 0x70ef42abb8 0xe4bb8 strb w9, [x20, x8] ; x8= 0x0 -> 0x0 , x9 = 0xce -> 0xce , x20= 0x70e80ce900 -> 0x70e80ce900 524 | 0x70ef42abbc 0xe4bbc add x8, x8, # 1 ; x8= 0x0 -> 0x1 525 | 0x70ef42abc0 0xe4bc0 cmp x19, x8 ; x8= 0x1 ->0x1 , x19= 0x80 -> 0x80 526 | 0x70ef42abb4 0xe4bb4 ldrb w9, [x21, x8] ; x8= 0x1 -> 0x1 , x9= 0xce -> 0xf0 , x21= 0x7146b9c7e0 -> 0x7146b9c7e0 527 | 0x70ef42abb8 0xe4bb8 strb w9, [x20, x8] ; x8= 0x1 -> 0x1 , x9= 0xf0 -> 0xf0 , x20= 0x70e80ce900 -> 0x70e80ce900 528 | 0x70ef42abc 0xe4bbc add x8, x8, # 1 ; x8= 0x1 -> 0x2 529 | 0x70ef42abc0 0xe4bc0 cmp x19, x8 ; x8= 0x2 -> 0x2 , x19= 0x80 -> 0x80 530 | 0x70ef42abb4 0xe4bb4 ldrb w9, [x21, x8] ; x8= 0x2 -> 0x2 , x9= 0xf0 -> 0x46 , x21= 0x7146b9c7e0 -> 0x7146b9c7e0 531 | 0x70ef42abb8 0xe4bb8 strb w9, [x20, x8] ; x8= 0x2 -> 0x2 , x9= 0x46 -> 0x46 , x20= 0x70e80ce900 -> 0x70e80ce900 532 | 0x70ef42abbc 0xe4bbc add x8, x8, # 1 ; x8= 0x2 ->0x3 533 | 0x70ef42abc0 0xe4bc0 cmp x19 , x8 ; x8= 0x3 - > 0x3 , x19= 0x80 - > 0x80 0x70ef42abb4 534 | 0xe4bb4 ldrb w9 , [x21, x8 ] ; > 0x7146b9c7e0 535 | 0x70ef42abb8 0xe4bb8 strb w9, [x20, x8] ; x8= 0x3 -> 0x3 , x9= 0x93 -> 0x93 , x20= 0x70e80ce900 -> 0x70e80ce900 536 | 0x70ef8 , xe4bbc # add x x 0x3 -> 0xe4bbc1 ; x8= 0x3 -> 0x4 537 | 0x70ef42abc0 0xe4bc0 cmp x19, x8 ; x8= 0x4 -> 0x4 , x19= 0x80 -> 0x80 538 | 0x70ef42abb4 0xe4bb4 ldrb w9 , [x21, x8] ; x8= 0x4 - > 0x4 , x9 > 0x4e , x21= 0x7146b9c7e0 -> 0x7146b9c7e0 539 | 0x70ef42abb8 0xe4bb8 strb w9, [x20, x8] ; x8= 0x4 -> 0x4 , x9= 0x4e -> 0x4e , x20= 0x70e80ce900 -> 0x70e80ce909 540 | [ _ _ _ _ _ _ _ 541 | _ _ _ _ _ _ _ _ _ _ 542 | _ _ _ _ -> 0x5 , x9= 0x4e -> 0x6f , x21= 0x7146b9c7e0 -> 0x7146b9c7e0 543 | 0x70ef42abb8 0xe4bb8 strb w9, [x20, x8] ; x8= 0x5 -> 0x5 , x9= 0x6f -> 0x6f , x20=0x70e80ce900 -> 0x70e80ce900 544 | ``` 545 | 546 | So reverse the result: 547 | 548 | ```js 549 | 57 21 6f 4 e 93 46 f0 ce 550 | b9 8 d db b0 e7 3b 34 9 d 551 | f6 5f cb 3b 5f 57 98 7f 552 | 7 d 1 a b6 a9 f5 40 3 c 20 553 | 16 f3 90 f9 96 76 47 7 c 554 | 17 90 e8 b1 4 a 4 a b5 67 555 | e2 ec 00 f3 a5 76 61 d8 556 | 61 0 d 40 72 9 d ee 93 c3 557 | af 7f fa df 53 12 8 e 2 c 558 | 3 a 3 e ab 67 ea 0 d 14 f8 559 | 5 d 39 26 08 c2 cd bb b4 560 | d8 9b ac 97 1f c7 58 55 561 | af b7 59 2 d 1 e 13 40 a7 562 | 14 8b a5 c1 35 99 f6 56 563 | 0 c 36 b3 4 d 7b 5b 9 d 16 564 | 09 c0 83 f4 b8 45 83 b5 565 | ``` 566 | These results are obtained through many rounds of XOR, and it is too troublesome to write them all down, so just follow them yourself. 567 | 568 | There are 8 big rounds in total, and there are 72 small rounds in the big round. 569 | Really cruel. 570 | 571 | After decryption is such a byte 572 | ```py 573 | b'\x08\xd2\xa4\x80\x82\x04\x10\x02\x18\x8e\x9d\xba\xf4\x08"\x0411282\n1588093228B\x14v04.03.04-ml-androidH\x80\x90\x98@ R\x08\x00\x80\x00\x00\x00\x00\x00\x00`\xee\xdb\xc6\xae\x0cj\x06\x10n4\xa2\xb8\xc7r\x06z+ \xda6tz\n\x08\x06 \x10\xbe\xe1T\x18\xbe\xe1T\x88\x01\xee\xdb\xc6\xae\x0c\xa2\x01\x04none\xa8\x01\xe2\x05' 574 | 575 | 08d2a48082041002188e9dbaf408220431313238320a3135383830393332323842147630342e30332e30342d6d6c2d616e64726f696448809098405208008000000000000060eedbc6ae0c6a06106e34a2b8c772067a2b20da36747a0a080610bee15418bee1548801eedbc6ae0ca201046e6f6e65a801e205 576 | ``` 577 | This looks like a protobuf. 578 | 579 | https://protobuf-decoder.netlify.app/ lets use this site to solve the protobuf str 580 | pasted-22 581 | 582 | For the specific functions of these fields, you can find them on Baidu or trace them. 583 | There is a process of sm3 calculation in it. 584 | 585 | Anyway, it can be reversed in the end. 586 | 587 | ```c 588 | syntax = "proto3"; 589 | 590 | message Argus { 591 | uint32 magic = 1; // 0x20200929 << 1 592 | uint32 version = 2; // 2 593 | uint64 rand = 3; // rand() << 1 594 | string msAppID = 4; // "1233" 595 | optional string deviceID = 5; // "7196299929824265734" comes from the registered device function 596 | string licenseID = 6; // "2142840551" 597 | optional string appVersion = 7; 598 | string sdkVersionStr = 8; // "v04.04.05-ov-android" 599 | uint32 sdkVersion = 9; // 0x4040520 << 1 600 | bytes envCode = 10; // 8 zeros are enough 601 | uint32 platform = 11; 602 | uint64 createTime = 12; // x_khronos << 1 603 | optional bytes bodyHash = 13; // sm3(x-ss-stub)[:6] 604 | optional bytes queryHash = 14; // sm3(query_string)[:6] 605 | optional ActionRecord actionRecord = 15; 606 | optional string secDeviceToken = 16;// From /sdi/get_token request 607 | optional uint64 isAppLicense = 17; // equal to createTime 608 | optional bytes pskHash = 18; // hash 609 | optional bytes pskCalHash = 19; // hash 610 | string pskVersion = 20; // Before logging in, it is "none", and after logging in, it is x-bd-kmsv 611 | uint32 callType = 21; // 738 612 | optional ChannelInfo channelInfo = 23; 613 | optional string seed = 24; // from /ms/get_seed 614 | optional uint32 extType = 25; // 2, 6, 8, 10 are all possible 615 | optional ExtraInfo extraInfo = 26; 616 | } 617 | 618 | message ExtraInfo { 619 | uint32 algorithm = 1; // 2, 4, 6, 8, 10, 12, 14, 16 correspond to different algorithms, this number comes from /ms/get_seed 620 | bytes algorithmData = 2; // Use query, ss-stub, 00000001 for calculation 621 | } 622 | 623 | message ChannelInfo { 624 | string phoneInfo = 1; // Mi 10 Pro 625 | uint32 metasecConstant = 2; // Fixed value 16, get 8 from the address in so, and become 0x10 after shifting and XOR 626 | string channel = 3; // googleplay 627 | uint32 appVersionConstant = 4; // 0x14607000 << 1, each version is different, the same version is the same. 628 | } 629 | 630 | message ActionRecord { 631 | optional uint32 signCount = 1; // Number of times the algorithm is called, count << 1 632 | optional uint32 reportCount = 2; // /ri/report number of reports << 1, risk control: There is verification here. The default value of 1388734 is not acceptable when searching for products. Sometimes it is. If you use the default value, a block verification will pop up. 633 | optional uint32 settingCount = 3; // /mscc/common_setting reporting times << 1, default value 1388734 634 | optional uint32 reportFailCount = 4; 635 | optional uint32 reportSuccessCount = 5; 636 | optional uint32 actionIncremental = 6; // always remains 1 << 1 637 | optional uint32 appLaunchTime = 7; // app launch time << 1 638 | } 639 | ``` 640 | --------------------------------------------------------------------------------