Sample details: b6cd0ce980109c8ff2b8d1be63df0e7c --

Hashes
MD5: b6cd0ce980109c8ff2b8d1be63df0e7c
SHA1: e8ede8a56fe2feabc438d3517e5a61cf0e44b02e
SHA256: f674dd56a3bf571a862633451f09e3ce219d321f3980c3e1fd452466cf4b79fe
SSDEEP: 768:z7Sf2DjoHg4eNA4ft6UPcuy98kEefOK0px6:VmzfO3U
Details
File Type: UTF-8
Yara Hits
CuckooSandbox/embedded_pe | YRP/domain | YRP/IP | YRP/url | YRP/contentis_base64 |
Parent Files
eae8b84e9121563341a0e4a268df0094
Strings
		*********************************/
// https://github.com/gorhill/uBlock/issues/1395
//   Added `firstparty` argument: to avoid discarding cosmetic filters when
//   applying 1st-party filters.
Block.applyCompiledFilters = function(rawText, firstparty) {
    if ( rawText === '' ) { return; }
    let reader = new this.CompiledLineIO.Reader(rawText);
    this.staticNetFilteringEngine.fromCompiledContent(reader);
    this.staticExtFilteringEngine.fromCompiledContent(reader, {
        skipGenericCosmetic: this.userSettings.ignoreGenericCosmeticFilters,
        skipCosmetic: !firstparty && !this.userSettings.parseAllABPHideFilters
    });
/******************************************************************************/
// https://github.com/AdguardTeam/AdguardBrowserExtension/issues/917
Block.processDirectives = function(content) {
    const reIf = /^!#(if|endif)\b([^\n]*)/gm;
    const stack = [];
    const shouldDiscard = ( ) => stack.some(v => v);
    const parts = [];
    let  beg = 0, discard = false;
    while ( beg < content.length ) {
        const match = reIf.exec(content);
        if ( match === null ) { break; }
        switch ( match[1] ) {
        case 'if':
            let expr = match[2].trim();
            const target = expr.charCodeAt(0) === 0x21 /* '!' */;
            if ( target ) { expr = expr.slice(1); }
            const token = this.processDirectives.tokens.get(expr);
            const startDiscard =
                token === 'false' &&
                    target === false ||
                token !== undefined &&
                    vAPI.webextFlavor.soup.has(token) === target;
            if ( discard === false && startDiscard ) {
                parts.push(content.slice(beg, match.index));
                discard = true;
            }
            stack.push(startDiscard);
            break;
        case 'endif':
            stack.pop();
            const stopDiscard = shouldDiscard() === false;
            if ( discard && stopDiscard ) {
                beg = match.index + match[0].length + 1;
                discard = false;
            }
            break;
        default:
            break;
        }
    if ( stack.length === 0 && parts.length !== 0 ) {
        parts.push(content.slice(beg));
        content = parts.join('\n');
    return content.trim();
Block.processDirectives.tokens = new Map([
    [ 'ext_ublock', 'ublock' ],
    [ 'env_chromium', 'chromium' ],
    [ 'env_edge', 'edge' ],
    [ 'env_firefox', 'firefox' ],
    [ 'env_mobile', 'mobile' ],
    [ 'env_safari', 'safari' ],
    [ 'cap_html_filtering', 'html_filtering' ],
    [ 'cap_user_stylesheet', 'user_stylesheet' ],
    [ 'false', 'false' ],
/******************************************************************************/
Block.loadRedirectResources = function() {
    return this.redirectEngine.resourcesFromSelfie().then(success => {
        if ( success === true ) { return true; }
        const fetchPromises = [
            this.redirectEngine.loadBuiltinResources()
        ];
        const userResourcesLocation = this.hiddenSettings.userResourcesLocation;
        if ( userResourcesLocation !== 'unset' ) {
            for ( const url of userResourcesLocation.split(/\s+/) ) {
                fetchPromises.push(this.assets.fetchText(url));
            }
        }
        return Promise.all(fetchPromises);
    }).then(results => {
        if ( Array.isArray(results) === false ) { return results; }
        let content = '';
        for ( let i = 1; i < results.length; i++ ) {
            const result = results[i];
            if (
                result instanceof Object === false ||
                typeof result.content !== 'string' ||
                result.content === ''
            ) {
                continue;
            }
            content += '\n\n' + result.content;
        }
        this.redirectEngine.resourcesFromString(content);
        this.redirectEngine.selfieFromResources();
        return true;
    }).catch(reason => {
        log.info(reason);
        return false;
    });
/******************************************************************************/
Block.loadPublicSuffixList = function() {
    if ( this.hiddenSettings.disableWebAssembly === false ) {
        publicSuffixList.enableWASM();
    return this.assets.get(
        'compiled/' + this.pslAssetKey
    ).then(details =>
        publicSuffixList.fromSelfie(details.content, 
Block.base64)
    ).catch(reason => {
        console.info(reason);
        return false;
    }).then(success => {
        if ( success ) { return; }
        return this.assets.get(this.pslAssetKey, details => {
            if ( details.content !== '' ) {
                this.compilePublicSuffixList(details.content);
            }
        });
    });
Block.compilePublicSuffixList = function(content) {
    publicSuffixList.parse(content, punycode.toASCII);
    this.assets.put(
        'compiled/' + this.pslAssetKey,
        publicSuffixList.toSelfie(
Block.base64)
    );
/******************************************************************************/
// This is to be sure the selfie is generated in a sane manner: the selfie will
// be generated if the user doesn't change his filter lists selection for
// some set time.
Block.selfieManager = (function() {
    const 
Block;
    let timer;
    // As of 2018-05-31:
    //   JSON.stringify-ing ourselves results in a better baseline
    //   memory usage at selfie-load time. For some reasons.
    const create = function() {
        Promise.all([
            
b.assets.put(
                'selfie/main',
                JSON.stringify({
                    magic: 
b.systemSettings.selfieMagic,
                    availableFilterLists: 
b.availableFilterLists,
                })
            ),
            
b.redirectEngine.toSelfie('selfie/redirectEngine'),
            
b.staticExtFilteringEngine.toSelfie('selfie/staticExtFilteringEngine'),
            
b.staticNetFilteringEngine.toSelfie('selfie/staticNetFilteringEngine'),
        ]).then(( ) => {
            
b.lz4Codec.relinquish();
        });
    };
    const load = function() {
        return Promise.all([
            
b.assets.get('selfie/main').then(details => {
                if (
                    details instanceof Object === false ||
                    typeof details.content !== 'string' ||
                    details.content === ''
                ) {
                    return false;
                }
                let selfie;
                try {
                    selfie = JSON.parse(details.content);
                } catch(ex) {
                }
                if (
                    selfie instanceof Object === false ||
                    selfie.magic !== 
b.systemSettings.selfieMagic
                ) {
                    return false;
                }
                
b.availableFilterLists = selfie.availableFilterLists;
                return true;
            }),
            
b.redirectEngine.fromSelfie('selfie/redirectEngine'),
            
b.staticExtFilteringEngine.fromSelfie('selfie/staticExtFilteringEngine'),
            
b.staticNetFilteringEngine.fromSelfie('selfie/staticNetFilteringEngine'),
        ]).then(results => {
            if ( results.reduce((acc, v) => acc && v, true) ) {
                return 
b.loadRedirectResources();
            }
            return false;
        }).catch(reason => {
            log.info(reason);
            return false;
        });
    };
    const destroy = function() {
        if ( timer !== undefined ) {
            clearTimeout(timer);
            timer = undefined;
        }
        
b.cacheStorage.remove('selfie'); // TODO: obsolete, remove eventually.
        
b.assets.remove(/^selfie\//);
        timer = vAPI.setTimeout(( ) => {
            timer = undefined;
            create();
        }, 
b.hiddenSettings.selfieAfter * 60000);
    };
    return {
        load: load,
        destroy: destroy
    };
/******************************************************************************/
// https://github.com/gorhill/uBlock/issues/531
// Overwrite user settings with admin settings if present.
// Admin settings match layout of a uBlock backup. Not all data is
// necessarily present, i.e. administrators may removed entries which
// values are left to the user's choice.
Block.restoreAdminSettings = function() {
    return new Promise(resolve => {
    // >>>> start of executor
    if ( vAPI.adminStorage instanceof Object === false ) {
        return resolve();
    vAPI.adminStorage.getItem('adminSettings', json => {
        let data;
        if ( typeof json === 'string' && json !== '' ) {
            try {
                data = JSON.parse(json);
            } catch (ex) {
                console.error(ex);
            }
        }
        if ( data instanceof Object === false ) {
            return resolve();
        }
        const bin = {};
        let binNotEmpty = false;
        // https://github.com/uBlockOrigin/uBlock-issues/issues/666
        //   Allows an admin to set their own 'assets.json' file, with their
        //   own set of stock assets.
        if (
            typeof data.assetsBootstrapLocation === 'string' &&
            data.assetsBootstrapLocation !== ''
        ) {
            
Block.assetsBootstrapLocation = data.assetsBootstrapLocation;
        }
        if ( typeof data.userSettings === 'object' ) {
            for ( const name in this.userSettings ) {
                if ( this.userSettings.hasOwnProperty(name) === false ) {
                    continue;
                }
                if ( data.userSettings.hasOwnProperty(name) === false ) {
                    continue;
                }
                bin[name] = data.userSettings[name];
                binNotEmpty = true;
            }
        }
        // 'selectedFilterLists' is an array of filter list tokens. Each token
        // is a reference to an asset in 'assets.json'.
        if ( Array.isArray(data.selectedFilterLists) ) {
            bin.selectedFilterLists = data.selectedFilterLists;
            binNotEmpty = true;
        }
        if ( Array.isArray(data.whitelist) ) {
            bin.netWhitelist = data.whitelist;
            binNotEmpty = true;
        } else if ( typeof data.netWhitelist === 'string' ) {
            bin.netWhitelist = data.netWhitelist.split('\n');
            binNotEmpty = true;
        }
        if ( typeof data.dynamicFilteringString === 'string' ) {
            bin.dynamicFilteringString = data.dynamicFilteringString;
            binNotEmpty = true;
        }
        if ( typeof data.urlFilteringString === 'string' ) {
            bin.urlFilteringString = data.urlFilteringString;
            binNotEmpty = true;
        }
        if ( typeof data.hostnameSwitchesString === 'string' ) {
            bin.hostnameSwitchesString = data.hostnameSwitchesString;
            binNotEmpty = true;
        }
        if ( binNotEmpty ) {
            vAPI.storage.set(bin);
        }
        if ( typeof data.userFilters === 'string' ) {
            this.assets.put(this.userFiltersPath, data.userFilters);
        }
        resolve();
    });
    // <<<< end of executor
    });
/******************************************************************************/
// https://github.com/gorhill/uBlock/issues/2344
//   Support mutliple locales per filter list.
// https://github.com/gorhill/uBlock/issues/3210
//   Support ability to auto-enable a filter list based on user agent.
Block.listMatchesEnvironment = function(details) {
    // Matches language?
    if ( typeof details.lang === 'string' ) {
        let re = this.listMatchesEnvironment.reLang;
        if ( re === undefined ) {
            const match = /^[a-z]+/.exec(self.navigator.language);
            if ( match !== null ) {
                re = new RegExp('\\b' + match[0] + '\\b');
                this.listMatchesEnvironment.reLang = re;
            }
        }
        if ( re !== undefined && re.test(details.lang) ) { return true; }
    // Matches user agent?
    if ( typeof details.ua === 'string' ) {
        let re = new RegExp('\\b' + this.escapeRegex(details.ua) + '\\b', 'i');
        if ( re.test(self.navigator.userAgent) ) { return true; }
    return false;
/******************************************************************************/
Block.scheduleAssetUpdater = (function() {
    let timer, next = 0;
    return function(updateDelay) {
        if ( timer ) {
            clearTimeout(timer);
            timer = undefined;
        }
        if ( updateDelay === 0 ) {
            next = 0;
            return;
        }
        const now = Date.now();
        // Use the new schedule if and only if it is earlier than the previous
        // one.
        if ( next !== 0 ) {
            updateDelay = Math.min(updateDelay, Math.max(next - now, 0));
        }
        next = now + updateDelay;
        timer = vAPI.setTimeout(( ) => {
            timer = undefined;
            next = 0;
            this.assets.updateStart({
                delay: this.hiddenSettings.autoUpdateAssetFetchPeriod * 1000 ||
                       120000
            });
        }, updateDelay);
    };
/******************************************************************************/
Block.assetObserver = function(topic, details) {
    // Do not update filter list if not in use.
    if ( topic === 'before-asset-updated' ) {
        if ( details.type === 'filters' ) {
            if (
                this.availableFilterLists.hasOwnProperty(details.assetKey) === false ||
                this.selectedFilterLists.indexOf(details.assetKey) === -1
            ) {
                return;
            }
        }
        return true;
    // Compile the list while we have the raw version in memory
    if ( topic === 'after-asset-updated' ) {
        // Skip selfie-related content.
        if ( details.assetKey.startsWith('selfie/') ) { return; }
        const cached = typeof details.content === 'string' &&
                       details.content !== '';
        if ( this.availableFilterLists.hasOwnProperty(details.assetKey) ) {
            if ( cached ) {
                if ( this.selectedFilterLists.indexOf(details.assetKey) !== -1 ) {
                    this.extractFilterListMetadata(
                        details.assetKey,
                        details.content
                    );
                    this.assets.put(
                        'compiled/' + details.assetKey,
                        this.compileFilters(
                            details.content,
                            { assetKey: details.assetKey }
                        )
                    );
                }
            } else {
                this.removeCompiledFilterList(details.assetKey);
            }
        } else if ( details.assetKey === this.pslAssetKey ) {
            if ( cached ) {
                this.compilePublicSuffixList(details.content);
            }
        }
        vAPI.messaging.broadcast({
            what: 'assetUpdated',
            key: details.assetKey,
            cached: cached
        });
        // https://github.com/gorhill/uBlock/issues/2585
        //   Whenever an asset is overwritten, the current selfie is quite
        //   likely no longer valid.
        this.selfieManager.destroy();
        return;
    // Update failed.
    if ( topic === 'asset-update-failed' ) {
        vAPI.messaging.broadcast({
            what: 'assetUpdated',
            key: details.assetKey,
            failed: true
        });
        return;
    // Reload all filter lists if needed.
    if ( topic === 'after-assets-updated' ) {
        if ( details.assetKeys.length !== 0 ) {
            // https://github.com/gorhill/uBlock/pull/2314#issuecomment-278716960
            if (
                this.hiddenSettings.userResourcesLocation !== 'unset' ||
                vAPI.webextFlavor.soup.has('devbuild')
            ) {
                this.redirectEngine.invalidateResourcesSelfie();
            }
            this.loadFilterLists();
        }
        if ( this.userSettings.autoUpdate ) {
            this.scheduleAssetUpdater(this.hiddenSettings.autoUpdatePeriod * 3600000 || 25200000);
        } else {
            this.scheduleAssetUpdater(0);
        }
        vAPI.messaging.broadcast({
            what: 'assetsUpdated',
            assetKeys: details.assetKeys
        });
        return;
    // New asset source became available, if it's a filter list, should we
    // auto-select it?
    if ( topic === 'builtin-asset-source-added' ) {
        if ( details.entry.content === 'filters' ) {
            if (
                details.entry.off !== true ||
                this.listMatchesEnvironment(details.entry)
            ) {
                this.saveSelectedFilterLists([ details.assetKey ], true);
            }
        }
        return;