Target website:aHR0cHM6Ly93d3cuaXFpeWkuY29tL3ZfMXIxb2JoanRpNTguaHRtbA==
Target parameters: & amp;vf=
1. Deduction code
Next xhr breakpoint
Go back to the stack and find that the core part is in mmc. Refresh the next breakpoint and follow it.
The incoming parameter is the link with the beginning and end removed, and the returned string is 32 characters in length.
Following along, it looks like a simple webpack
(window.iqiyiPlayerJSONPCallback = window.iqiyiPlayerJSONPCallback || []).push([[1], { 1089: function(module, exports, __webpack_require__) { ............. }, 576: function(x, a, e) { var i; i = function(x, a, i) { var r = e(1089) , c = null; i.exports = { setEngine: function(x) { c = x }, mmcd: r.mmcd, mmc: function() { var x = c & amp; & amp; c.sbtr; x & amp; & amp; x.authkeyInvoking(); var a = r.mmc.apply(r, arguments); return x & amp; & amp; x.authkeyInvoked(), a } } } } }]);
The key function is the mmc in 1089. Just download it directly because it does not depend on other files. Simply run it.
The result is different, which means that the environment is probably detected and the V God plug-in is directly used.
Plug-in address: https://github.com/cilame/v_jstools
Checked something simple
Click to generate a temporary environment and copy it to the beginning of the file
Modify the code according to the error report
The test results are completely consistent
Algorithm restoration
The first is a simple ob confusion, which can be restored by just finding an open source source.
Then delete the false branch. I used the Boss Cai plug-in.
Then delete the useless code and find the aunt
It can be vaguely seen from the restored code that it is wasm, but there is no wasm file. It is directly compiled into asm.js
Usually the simplest command is
emcc main.cpp -s WASM=1 -o main.js
If you want not to output wasm, but convert it to asm.js. Change WASM=1 to WASM=0
In addition, it also changes asynchronous loading to synchronous -s WASM_ASYNC_COMPILATION=0;
If it is loaded asynchronously, an error will be reported if run directly.
The most common error is
TypeError: Cannot read properties of undefined (reading ‘apply’)
The main reason is that asynchronous loading of asm does not assign a value, that is, the c exported function and js have not completed the interaction.
Since it is wasm, the environment detection is probably not in wasm, but in the import function. The detections encountered so far include directly importing the detection function, and importing eval. There are some detection codes in wasm. In addition, due to Go comes with the particularity of js, which gives people the feeling that the environment can be obtained directly. In fact, the interaction is through js.
The target website belongs to the first import function
I imported a lot of functions and analyzed them one by one and found that as long as au returns 6, it will be fine.
function aU() { return 6 }
The test is the same as the website, the basic preparations are completed
The return value is 32 bits and is probably md5. Search for the keyword.
Then there is no more
Restoration is impossible, not even in this life
I don’t see any magic changes from the initialized values. Find a standard md5, which has obvious characteristics. It loops for 16* rounds. Print out each case and simply draw a picture.
Print the ones that appear 16 times
import numpy as np from matplotlib import pyplot as plt from collections import Counter from t import data counts = Counter(data) valid_data_points = {key for key, value in counts.items() if value == 16} filtered_data = np.array([point for point in data if point in valid_data_points]) plt.plot(filtered_data) plt.show()
Obviously there are 4 cycles of 16
101,80,25,-117,-98,96,88,17,
These are the core parts of the first round
101
case 101: { v = $x & amp; ~Rx | Qx & amp; Rx, Ex = sa + -1 | 0, s = 80, Ex = Ex >> 2, f = v, ta = na, v = (v + (Ux & amp; -2) & amp; -2 | Ux & amp; 1) + (v & amp; 1) | 0, g = aa + ((ia | 0) % 16 | 0) | 0; break }
It corresponds to
(b & amp; c) | ((~b) & amp; d) and safe_add(a, q)
case 80: { s = sa + 32 | 0, s = (g | 0) > (s >> 2 | 0) ? 36 : 25; break } case 25: { s = (g | 0) > (Tx | 0) ? 136 : 139; break } case -117: { s = (g | 0) == (Tx | 0) ? 166 : 158; break } case -98: { s = (g | 0) > (Tx + 1 | 0) ? 83 : 96;} case 96: { s = 88, f = c[G + (g << 2) >> 2] | 0; break }
Looks useless
case 88: { Ex = ca + (ia << 3) | 0, g = f >> 1, g = _i64Add(c[Ex >> 2] | 0, c[Ex + 4 >> 2] | 0, _bitshift64Shl(g | 0, ((g | 0) < 0) << 31 >> 31 | 0, 1) | 0, w() | 0) | 0, w() | 0, g = (f & 1) + g | 0, Ex = (g + (v & amp; -2) & amp; -2 | v & amp; 1) + (g & amp; 1) | 0, f = ((ia | 0) % 4 | 0) * 5 | 0, ta = f + 7 | 0, f = 25 - f | 0, f = Ex << ta | (f ? Ex >>> f : Ex), s = 17, Vx = $x, Fx = (f + (Rx & amp; -2) & amp; -2 | Rx & amp; 1) + (f & amp; 1) | 0, _x = Rx, xa = Qx, ra = ia + 1 | 0, ma = ka; break }
88 is the core. It doesn’t matter if you don’t understand it. f is the encrypted data. Save it and run it.
Add a log point and save the data
from Crypto.Util.number import long_to_bytes d = [1935762479, 1819557736, '''] datas = b"" for i in d: datas + = long_to_bytes(i)[::-1] print(datas)
Remove the padding and convert it into a string. Try it on any online website. It shows that you just added salt, but the addition is a little outrageous.
Summary
In general, it is relatively not difficult. It is a little simpler than Xun’s vmp plus wasm. There is environmental monitoring, but not much. If there is confusion, it is equivalent to none (Boss Cai yyds). The main reason is that the control flow is annoying. I have taken a trick here. Guys, just restore it
In addition, the app and TV terminals should use the same set of codes to restore them basically the same. Trace code, find the location to add data, and take it out. However, the same src on the TV terminal may have two salts, mainly because qd_v is different. .