Skip to content
This repository has been archived by the owner on Nov 13, 2024. It is now read-only.

Commit

Permalink
update seia-soto/asdefuser (#56)
Browse files Browse the repository at this point in the history
* update seia-soto/asdefuser

Co-authored-by: HoJeong Go <[email protected]>

* chore: add ad-shield domains

* build: update user.js

* chore: add thephoblographer.com

https://www.thephoblographer.com/2023/12/31/last-chance-to-win-this-great-lens/
https://github.com/ghostery/ghostery-extension/issues/1430

* chore: remove m.inven.co.kr in exclusions list

---------

Co-authored-by: HoJeong Go <[email protected]>
  • Loading branch information
piquark6046 and seia-soto authored Jan 2, 2024
1 parent 4bccb2f commit 80390fd
Show file tree
Hide file tree
Showing 16 changed files with 302 additions and 304 deletions.
12 changes: 7 additions & 5 deletions microShield.user.js

Large diffs are not rendered by default.

23 changes: 11 additions & 12 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
{
"name": "microshield",
"version": "3.11.13",
"version": "3.12.0",
"description": "",
"type": "module",
"scripts": {
"build": "pnpm bundle",
"shortwave:cache": "OUTPUT=$(readlink -f ./sources/src/__generated__/shortwave.cache.ts) node sources/scripts/generateShortwaveCache.mjs",
"ztinywave:cache": "OUTPUT=$(readlink -f ./sources/src/__generated__/ztinywave.cache.ts) node sources/scripts/generateTinywaveCache.mjs",
"bundle": "esbuild sources/src/index.ts --bundle --minify --define:global=window --inject:./sources/esbuild.inject.ts --banner:js=\"$(cat ./sources/banner.txt)\" --target=es2022,chrome109,safari16,firefox115 --outfile=./microShield.user.js",
"debug": "esbuild sources/src/index.ts --bundle --define:global=window --inject:./sources/esbuild.inject.ts --banner:js=\"$(cat ./sources/banner.txt)\" --target=es2022,chrome109,safari16,firefox115 --outfile=./microShield-debug.user.js"
},
Expand All @@ -26,20 +27,18 @@
],
"license": "Apache-2.0",
"dependencies": {
"acorn": "^8.11.2",
"acorn-walk": "^8.3.1",
"buffer": "^6.0.3",
"playwright": "^1.40.1",
"protobufjs": "^7.2.5"
"@types/node": "^20.10.6",
"buffer": "^6.0.3"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^6.7.2",
"@typescript-eslint/parser": "^6.7.2",
"esbuild": "^0.19.3",
"eslint": "^8.49.0",
"@typescript-eslint/eslint-plugin": "^6.12.0",
"@typescript-eslint/parser": "^6.12.0",
"acorn-walk": "^8.3.0",
"esbuild": "^0.19.11",
"eslint": "^8.54.0",
"eslint-config-xo": "^0.43.1",
"eslint-config-xo-typescript": "^1.0.1",
"terser": "^5.19.4",
"ts-node": "^10.9.1"
"playwright": "^1.40.0",
"typescript": "^5.3.2"
}
}
5 changes: 3 additions & 2 deletions sources/banner.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// @downloadURL https://cdn.jsdelivr.net/gh/List-KR/microShield@latest/microShield.user.js
// @license Apache-2.0
//
// @version 3.11.13
// @version 3.12.0
// @author PiQuark6046 and contributors
//
// @match *://algumon.com/*
Expand Down Expand Up @@ -92,7 +92,8 @@
// @match *://*.fmkorea.com/*
// @match *://forexlive.com/*
// @match *://*.forexlive.com/*
// @exclude *://m.inven.co.kr/imart/imarble/*
// @match *://thephoblographer.com/*
// @match *://*.thephoblographer.com/*
//
// @description microShield allows the adblock community to resist against Ad-Shield widely.
// @description:ko microShield는 애드블록 커뮤니티가 애드쉴드에 널리 저항할 수 있도록 합니다.
Expand Down
52 changes: 52 additions & 0 deletions sources/src/call-validators/analyzers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
type Analyzer = (line: string) => boolean;

class MemoizedCallAnalyzer {
private readonly cache: Map<string, boolean>;
private readonly analyzer: Analyzer;

constructor(analyzer: Analyzer) {
this.cache = new Map();
this.analyzer = analyzer;
}

analyze(line: string) {
if (this.cache.has(line)) {
return this.cache.get(line)!;
}

const result = this.analyzer(line);

this.cache.set(line, result);

return result;
}
}

export const annoymousCallAnalyzer = new MemoizedCallAnalyzer(line => line.startsWith('[') || line.startsWith('<'));

export const extensionCallAnalyzer = new MemoizedCallAnalyzer(line => line.startsWith('chrome') || line.startsWith('webkit') || line.startsWith('moz'));

const knownAdShieldOrigins = [
'https://07c225f3.online',
'https://css-load.com',
'https://html-load',
'https://content-loader.com',
];

export const adShieldCallAnalyzer = new MemoizedCallAnalyzer(line => {
if (line.endsWith('/script.min.js') || line.endsWith('/loader.min.js')) {
return true;
}

if (!location.origin.endsWith('.online') && line.includes('.online')) {
return true;
}

for (const origin of knownAdShieldOrigins) {
if (line.startsWith(origin)) {
return true;
}
}

return false;
});
30 changes: 30 additions & 0 deletions sources/src/call-validators/suites.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import {type getCallStack} from '../utils';
import {adShieldCallAnalyzer} from './analyzers';

export type ValidatorFunction = (callStack: ReturnType<typeof getCallStack>) => boolean;

export const hasOriginOfAdShield: ValidatorFunction = ({trace}) => adShieldCallAnalyzer.analyze(trace[trace.length - 1]);

export const hasAdShield: ValidatorFunction = ({trace}) => {
for (const line of trace) {
if (adShieldCallAnalyzer.analyze(line)) {
return true;
}
}

return false;
};

export const createValidationSuite = (validators: ValidatorFunction[]) => (callStack: ReturnType<typeof getCallStack>) => {
for (const validator of validators) {
if (validator(callStack)) {
return true;
}
}

return false;
};

export const adShieldOriginCheck = createValidationSuite([hasOriginOfAdShield]);

export const adShieldStrictCheck = createValidationSuite([hasAdShield]);
113 changes: 94 additions & 19 deletions sources/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,100 @@
import {useNetworkInterceptor} from './interceptors/network.js';
import {interceptEval} from './interceptors/eval.js';
import {tinywave} from './loaders/ztinywave.js';
import {useDisableMethod, useIsSubframe} from './utils.js';
import {basedrop} from './loaders/basedrop.js';
import {tinywave} from './loaders/ztinywave.js';
import {documentReady, getCallStack, makeProxy} from './utils.js';
import {adShieldOriginCheck, adShieldStrictCheck} from './call-validators/suites.js';
import {isAdShieldObj} from './obj-validators/index.js';

const bootstrap = () => {
interceptEval();
useNetworkInterceptor();
useDisableMethod(Element.prototype, 'remove');
useDisableMethod(Element.prototype, 'removeChild');
useDisableMethod(Element.prototype, 'append');
useDisableMethod(Element.prototype, 'appendChild');
useDisableMethod(Element.prototype, 'insertBefore');
useDisableMethod(Element.prototype, 'attachShadow');
useDisableMethod(document, 'createElement');
useDisableMethod(Object, 'defineProperty');
useDisableMethod(Object, 'defineProperties');
useDisableMethod(window, 'Promise');

if (useIsSubframe()) {
return;
Element.prototype.remove = makeProxy(Element.prototype.remove, 'Element.prototype.remove');
Element.prototype.removeChild = makeProxy(Element.prototype.removeChild, 'Element.prototype.removeChild');
Element.prototype.insertAdjacentHTML = makeProxy(Element.prototype.insertAdjacentHTML, 'Element.prototype.insertAdjacentHTML');
Element.prototype.setAttribute = makeProxy(Element.prototype.setAttribute, 'Element.prototype.setAttribute');
EventTarget.prototype.addEventListener = makeProxy(EventTarget.prototype.addEventListener, 'EventTarget.prototype.addEventListener');
// Prevent messaging to inline
MessagePort.prototype.postMessage = makeProxy(MessagePort.prototype.postMessage, 'MessagePort.prototype.postMessage');
document.createElement = makeProxy(document.createElement, 'document.createElement');
// Prevent useless timer apis for performance
window.setInterval = makeProxy(setInterval, 'setInterval');
window.setTimeout = makeProxy(setTimeout, 'setInterval');

// Local Storage
localStorage.removeItem('as_profile_cache');
localStorage.removeItem('adshield-analytics-uuid');

Storage.prototype.setItem = new Proxy(Storage.prototype.setItem, {
apply(target, thisArg, argArray) {
const [key] = argArray as [string, string];

if (adShieldStrictCheck(getCallStack()) || key.startsWith('as_') || key.startsWith('as-') || key.includes('adshield')) {
throw new DOMException('QuotaExceededError');
}

return Reflect.apply(target, thisArg, argArray) as unknown;
},
});

// Network/XHR
window.fetch = makeProxy(fetch, 'fetch');
window.XMLHttpRequest = new Proxy(XMLHttpRequest, {
construct(target, argArray, newTarget) {
if (adShieldStrictCheck(getCallStack())) {
return {};
}

return Reflect.construct(target, argArray, newTarget) as XMLHttpRequest;
},
});

// Error prototype
window.Error = new Proxy(Error, {
set() {
throw new Error('Overriding Error is not allowed!');
},
setPrototypeOf() {
throw new Error('Overriding prototype of Error is not allowed!');
},
});

if (navigator.vendor.includes('Apple')) {
// Deserialization
JSON.parse = new Proxy(JSON.parse, {
apply(target, thisArg, argArray) {
const obj = Reflect.apply(target, thisArg, argArray) as unknown;

if (adShieldOriginCheck(getCallStack()) || isAdShieldObj(obj)) {
return null;
}

return obj;
},
set() {
throw new Error('Overriding JSON.parse is not allowed!');
},
});

void documentReady(document).then(() => {
// Remove already created ad elements
for (const el of document.querySelectorAll('iframe[src="about:blank"]')) {
el.remove();
}

const observer = new MutationObserver(records => {
for (const record of records) {
for (const node of record.addedNodes) {
if (node instanceof HTMLIFrameElement && node.getAttribute('src') === 'about:blank') {
node.remove();
}
}
}
});

observer.observe(document.documentElement ?? document.body, {
childList: true,
subtree: true,
});

document.head.insertAdjacentHTML('afterbegin', '<style>iframe[src="about:blank"]{display:none!important}</style>');
});
}

void basedrop();
Expand Down
25 changes: 0 additions & 25 deletions sources/src/interceptors/eval.ts

This file was deleted.

28 changes: 0 additions & 28 deletions sources/src/interceptors/network.ts

This file was deleted.

22 changes: 0 additions & 22 deletions sources/src/interceptors/storage.ts

This file was deleted.

6 changes: 3 additions & 3 deletions sources/src/loaders/basedrop.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import {useDebug, useDocumentReady} from '../utils';
import {createDebug, documentReady} from '../utils';

const debug = useDebug('[microShield:basedrop]');
const debug = createDebug('[microShield:basedrop]');

export const basedrop = async () => {
await useDocumentReady(document);
await documentReady(document);

let appendant = '';

Expand Down
8 changes: 4 additions & 4 deletions sources/src/loaders/basera1n.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as asKit from '../adshield-defuser-libs/basera1n';
import {useDebug, useDocumentReady} from '../utils.js';
import {createDebug, documentReady} from '../utils.js';

const debug = useDebug('[microShield:basera1n]');
const debug = createDebug('[microShield:basera1n]');

const extract = async () => {
let data: string | undefined;
Expand All @@ -22,7 +22,7 @@ const extract = async () => {
useSelector();

if (!data) {
await useDocumentReady(document);
await documentReady(document);

debug('html:post');
useSelector();
Expand Down Expand Up @@ -103,7 +103,7 @@ export const basera1n = async () => {

debug('payload', payload);

await useDocumentReady(document);
await documentReady(document);

restore(payload);
};
Loading

0 comments on commit 80390fd

Please sign in to comment.