Se você usa bloqueadores de anúncios, pode encontrar o BlockAdBlock . Este script detecta seu bloqueador e não permite o acesso até o site. Mas eu me perguntava como isso funciona. Como o anti-bloqueador detecta os bloqueadores? E como os bloqueadores reagem a isso e como eles bloqueiam os anti-bloqueadores?História da engenharia reversa
A primeira coisa que fiz foi olhar para o site deles . O BlockAdBlock oferece um configurador com configurações: o intervalo de espera e a aparência do aviso, gerando diferentes versões do script.Isso me fez pensar em versões. E se ele não podia ver uma versão, e tudo de uma vez? Então eu fiz. Voltei no tempo usando a Wayback Machine . Depois disso, baixei todas as versões do BlockAdBlock e as misturei.Lista de todas as versões do BlockAdBlock, com sha1sum
6d5eafab2ca816ccd049ad8f796358c0a7a43cf3 20151007203811.js
065b4aa813b219abbce76ad20a3216b3481b11bb 20151113115955.js
d5dec97a775b2e563f3e4359e4f8f1c3645ba0e5 20160121132336.js
8add06cbb79bc25114bd7a2083067ceea9fbb354 20160318193101.js
8add06cbb79bc25114bd7a2083067ceea9fbb354 20160319042810.js
8add06cbb79bc25114bd7a2083067ceea9fbb354 20160331051645.js
8add06cbb79bc25114bd7a2083067ceea9fbb354 20160406061855.js
8add06cbb79bc25114bd7a2083067ceea9fbb354 20160408025028.js
555637904dc9e4bfc6f08bdcae92f0ba0f443ebf 20160415083215.js
d8986247cad3bbc2dd92c3a2a06ac1540da6b286 20161120215354.js
d8986247cad3bbc2dd92c3a2a06ac1540da6b286 20170525201720.js
d8986247cad3bbc2dd92c3a2a06ac1540da6b286 20170606090847.js
d8986247cad3bbc2dd92c3a2a06ac1540da6b286 20170703211338.js
d8986247cad3bbc2dd92c3a2a06ac1540da6b286 20170707211652.js
d8986247cad3bbc2dd92c3a2a06ac1540da6b286 20170813090718.js
d8986247cad3bbc2dd92c3a2a06ac1540da6b286 20170915094808.js
d8986247cad3bbc2dd92c3a2a06ac1540da6b286 20171005180631.js
d8986247cad3bbc2dd92c3a2a06ac1540da6b286 20171019162109.js
d8986247cad3bbc2dd92c3a2a06ac1540da6b286 20171109101135.js
d8986247cad3bbc2dd92c3a2a06ac1540da6b286 20171127113945.js
d8986247cad3bbc2dd92c3a2a06ac1540da6b286 20171211042454.js
d8986247cad3bbc2dd92c3a2a06ac1540da6b286 20171227031408.js
d8986247cad3bbc2dd92c3a2a06ac1540da6b286 20180202000800.js
d8986247cad3bbc2dd92c3a2a06ac1540da6b286 20180412213253.js
d8986247cad3bbc2dd92c3a2a06ac1540da6b286 20180419060636.js
d8986247cad3bbc2dd92c3a2a06ac1540da6b286 20180530223228.js
d8986247cad3bbc2dd92c3a2a06ac1540da6b286 20180815042610.js
d8986247cad3bbc2dd92c3a2a06ac1540da6b286 20181029233809.js
d8986247cad3bbc2dd92c3a2a06ac1540da6b286 20181122190948.js
d8986247cad3bbc2dd92c3a2a06ac1540da6b286 20181122205748.js
d8986247cad3bbc2dd92c3a2a06ac1540da6b286 20190324081812.js
d8986247cad3bbc2dd92c3a2a06ac1540da6b286 20190420155244.js
d8986247cad3bbc2dd92c3a2a06ac1540da6b286 20190424200651.js
d8986247cad3bbc2dd92c3a2a06ac1540da6b286 20190903121933.js
d8986247cad3bbc2dd92c3a2a06ac1540da6b286 20200112084838.js
Apenas seis versões diferem entre si, e a última delas se refere a 2016, embora alguns sites ainda usem o BlockAdBlock. Isso é ótimo, porque será o suficiente para fazermos engenharia reversa da única versão e depois inverter as diferenças. Spoiler: veremos o desenvolvimento de idéias e até os remanescentes do código de depuração. Publiqueitodas as versões no GitHub . Se você deseja examinar as diferenças, neste repositório cada confirmação é uma nova versão.Desembalar
O código do script não é minificado, mas compactado por um JS-packer de Dean Edwards com alterações cosméticas e sem nenhuma modificação da lógica 1.eval(function(p, a, c, k, e, d) {
e = function(c) {
return (c < a ? '' : e(parseInt(c / a))) + ((c = c % a) > 35 ? String.fromCharCode(c + 29) : c.toString(36))
};
if (!''.replace(/^/, String)) {
while (c--) {
d[e(c)] = k[c] || e(c)
}
k = [function(e) {
return d[e]
}];
e = function() {
return '\\w+'
};
c = 1
};
while (c--) {
if (k[c]) {
p = p.replace(new RegExp('\\b' + e(c) + '\\b', 'g'), k[c])
}
}
return p
}('0.1("2 3 4 5 6 7 8\'d. 9, h? a b c d e f g");i j=\'a\'+\'k\'+\'e\'+\'l\'+\'n\'+\'m\'+\'e\';',24,24,
'console|log|This|code|will|get|unpacked|then|eval|Cool||||||||huh|let|you|w|s||o'.split('|'),0,{}))
Felizmente, isso não é um problema para nós. O ponto fraco do empacotador é que todo o código durante a descompactação é passado para eval()
. Se substituirmos eval()
por algo parecido console.log()
, obteremos repentinamente todo o código-fonte e o empacotador será derrotado ..Feito isso para cada versão, podemos examinar cada uma delas e ver quais funções foram adicionadas ao longo do tempo.v1 :? - novembro de 2015: roteiro inicial
Código-fonteVamos começar com um estudo 20151007203811.js
publicado em novembro de 2015 3. Embora essa primeira versão não bloqueie muito bem os bloqueadores, ela permite avaliar a arquitetura BlockAdBlock sem o lixo acumulado ao longo dos anos.Arquitetura
Em três frases:- BlockAdBlock é um fechamento que retorna um objeto com três funções:
bab()
define a isca e chama um cheque check
check()
verifica se o bloqueador bloqueou a isca, causando arm
arm()
sobreposição
- O ponto de entrada é
bab()
iniciado após um período de tempo especificado.
- Três funções são geradas com argumentos definidos no configurador BlockAdBlock .
O código é criado em torno de um fechamento atribuído a um objeto global com um nome aleatório.var randomID = '',
e = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
for (var i = 0; i < 12; i++) randomID +=
e.charAt(Math.floor(Math.random() * e.length));
var setTimeoutDelay = 7;
window['' + randomID + ''] = ...
O autor forneceu uma randomização completa para contornar o bloqueio estático.Em seguida, retorna um objeto com três funções: bab
, check
e arm
.window['' + randomID + ''] = (function() {
var eid = ...
return {
bab: function(check, passed_eid) {},
check: function(checkPredicate, unused) {},
arm: function() {}
}
})();
Estes são meus próprios nomes. Todas as variáveis são minificadas e algumas são ofuscadas.O ponto de entrada é bab()
chamado setTimeout()
.setTimeout('window[\'\' + randomID + \'\'] \
.bab(window[\'\' + randomID + \'\'].check, \
window[\'\' + randomID + \'\'].bab_elementid)', setTimeoutDelay * 1000)
bab_elementid
não usado em nenhuma versão do código. setTimeout
passado como uma string.Um fechamento possui variáveis externas. Dois deles são usados para salvar o estado em um script:adblockDetected
igual a 1 se um bloqueador de anúncios for detectado.
nagMode
- Esta é uma opção de configuração. Se estiver instalado, o script não bloqueia o acesso à página, mas apenas o ativa uma vez.
Outras variáveis para controlar a aparência e o comportamento são definidas no configurador .var eid = ' ad_box',
__u1 = 1,
overlayColor = '#EEEEEE',
textColor = '#777777',
buttonBackgroundColor = '#adb8ff',
buttonColor = '#FFFFFF',
__u2 = '',
welcomeText = 'Sorry for the interruption...',
primaryText = 'It looks like you\'re using an ad blocker. That\'s okay. Who doesn\'t?',
subtextText = 'But without advertising-income, we can\'t keep making this site awesome.',
buttonText = 'I understand, I have disabled my ad blocker. Let me in!',
adblockDetected = 0,
nagMode = 0,
bab_domain = 'moc.kcolbdakcolb';
bab_domain
definido aqui na tentativa de ofuscar o domínio BlockAdBlock.bab: crie um banner de chamariz
O principal método de trabalho com o BlockAdBlock é criar "isca" ou "isca" a partir de elementos de publicidade que parecem banners reais. Ele então verifica se o bloqueador está bloqueado.Isso cria um engodo: uma div falsa que finge ser um anúncio, mas está oculta.bab: function(check, passed_eid) {
if (typeof document.body == 'undefined') {
return
};
var delay = '0.1',
passed_eid = eid ? eid : 'banner_ad',
bait = document.createElement('DIV');
bait.id = passed_eid;
bait.style.position = 'absolute';
bait.style.left = '-999px';
bait.appendChild(document.createTextNode(' '));
document.body.appendChild(bait);
...
Aparentemente, passed_eid
pretende-se configurar o identificador da isca, mas não é usado.Depois disso, é verificado se a isca foi removida pelo bloco de anúncios. ...
setTimeout(function() {
if (bait) {
check((bait.clientHeight == 0), delay);
check((bait.clientWidth == 0), delay);
check((bait.display == 'hidden'), delay);
check((bait.visibility == 'none'), delay);
check((bait.opacity == 0), delay);
check((bait.left < 1000), delay);
check((bait.top < 1000), delay)
} else {
check(true, delay)
}
}, 125)
}
Se a isca não existir mais, o elemento será excluído (e iniciaremos a sobreposição).A função check
funcionará se Predicate
retornar um valor true
e iniciar arm
.check: function(checkPredicate, unused) {
if ((checkPredicate) && (adblockDetected == 0)) {
adblockDetected = 1;
window['' + randomID + ''].arm()
} else {}
}
Como o teste é check
acionado várias vezes, como mostrado acima, é adblockDetected
definido como o primeiro teste correto para evitar disparos repetidos arm
.Modo Grunhido
O script possui uma função chamada "modo nag": nesse modo, o BlockAdBlock diz apenas uma vez para desativar o bloqueador de anúncios, mas não o bloqueia toda vez que você o visita. Isso é feito configurando o item localStorage
na primeira visita.Se pudéssemos instalar esse elemento, poderíamos desativar o bloqueio para sempre? Infelizmente, o BlockAdBlock verifica antecipadamente se o script foi configurado para o modo nag; portanto, esse método não funcionará quando funcionar no modo padrão, ou seja, com bloqueio de acesso.arm: function() {
if (nagMode == 1) {
var babNag = sessionStorage.getItem('babn');
if (babNag > 0) {
return true
} else {
sessionStorage.setItem('babn', (Math.random() + 1) * 1000)
}
};
...
Infelizmente, ele está nagMode
instalado no configurador e, por padrão, é igual 0
.BlockAdBlock versão 1
Os bloqueadores de anúncios usam os chamados filtros: linhas de código que podem bloquear solicitações de rede e ocultar elementos na página. Ao criar elementos de isca, o BlockAdBlock inicia especificamente esses filtros.Com essa defesa simples, o BlockAdBlock é eficaz contra todos os principais bloqueadores de anúncios, como uBlock Origin, AdBlock Plus e Ghostery. Para combater isso, precisamos escrever nosso próprio filtro, que é ativado apenas em sites que executam o BlockAdBlock.Escrever filtros para um bloqueador é um pouco complicado. Precisamos de um filtro de conteúdo que bloqueie elementos na página gerada após o carregamento. Como a isca tem um identificador banner_ad
, criamos uma exceção para ocultar elementosmarcado #@#
para todos os elementos #
com um identificador banner_ad
e coloque-o na lista de filtros de usuários do nosso bloqueador.O resultado é o seguinte:localhost#@# #banner_ad
Eu tenho o host local aqui para demonstração. Você pode substituí-lo pelo seu URL.Isso desativa com sucesso o BlockAdBlock. A solução pode parecer simples, mas há muito tempo trabalha com êxito na lista de filtros Anti-AdBlock-Killer .Versão 2 (novembro de 2015 - janeiro de 2016): várias melhorias
Diferença do código fontev1 / v2Criação de iscas: menos bugs
Há um erro sutil na primeira versão da criação da isca: a div criada não tem conteúdo; portanto, uma div é gerada com uma altura de 0 e uma largura de 0. Mais tarde, o código verifica se a div foi excluída, verificando sua altura e largura. Mas como tinha altura zero, o BlockAdBlock sempre funcionou 4.O erro de uma div vazia foi corrigido.bab: function(...) {
bait = document.createElement('DIV');
...
bait.appendChild(document.createTextNode('Â '));
Uma div filho é criada com algum conteúdo.Detecção de bloqueadores através de banners gráficos falsos
Nesse método, criamos uma imagem falsa com um nome aleatório ativado doubleclick.net
. Bloqueadores de anúncios bloquearão a imagem, pensando que é um banner de anúncio. Mas isso não requer nenhuma alteração no nosso filtro.bab: function(...) {
bait = document.createElement('DIV');
bait.innerHTML = '<img src="http://doubleclick.net/' + randomStr() + '.jpg">';
...
randomStr()
gera uma cadeia de comprimento arbitrário.Outra diferença notável foi o uso de um temporizador, em setInterval
vez de uma simples verificação única para ver se um gatilho está instalado. Ele verifica novamente se o banner gráfico é exibido e se seu atributo não foi alterado src
, verificando o conteúdo da isca.Novo setInterval
e verifique a disponibilidade da imagem: ...
checkCallback = setInterval(function() {
if (bait) {
check((bait.clientHeight == 0), delay);
check((bait.clientWidth == 0), delay);
check((bait.display == 'hidden'), delay);
check((bait.visibility == 'none'), delay);
check((bait.opacity == 0), delay);
try {
check((document.getElementById('banner_ad').innerHTML.indexOf('click') == -1), delay)
} catch (e) {}
} else {
check(true, delay)
}
}, 1000
Por que indexof ('click')
? Porque a fonte da imagem src="doubleclick.net/abcdefg.jpg"
e verificamos se o fragmento da string é preservado click
.Versão 3 (novembro de 2015 - março de 2016): isca generalizada
Diferença do código fontev2 / v3Criação de Iscas: Identificadores Aleatórios
A única alteração nesta versão, embora significativa, é a aparência de identificadores aleatórios para a isca. O novo identificador é retirado da lista de identificadores ao carregar a página e é usado para a isca, que agora é colocada no meio da página.Uma longa lista de identificadores aleatórios demonstra um bom conhecimento da área de assunto.var baitIDs = [
"ad-left",
"adBannerWrap",
"ad-frame",
"ad-header",
"ad-img",
"ad-inner",
"ad-label",
"ad-lb",
"ad-footer",
"ad-container",
"ad-container-1",
"ad-container-2",
"Ad300x145",
"Ad300x250",
"Ad728x90",
"AdArea",
"AdFrame1",
"AdFrame2",
"AdFrame3",
"AdFrame4",
"AdLayer1",
"AdLayer2",
"Ads_google_01",
"Ads_google_02",
"Ads_google_03",
"Ads_google_04",
"DivAd",
"DivAd1",
"DivAd2",
"DivAd3",
"DivAdA",
"DivAdB",
"DivAdC",
"AdImage",
"AdDiv",
"AdBox160",
"AdContainer",
"glinkswrapper",
"adTeaser",
"banner_ad",
"adBanner",
"adbanner",
"adAd",
"bannerad",
" ad_box",
" ad_channel",
" adserver",
" bannerid",
"adslot",
"popupad",
"adsense",
"google_ad",
"outbrain-paid",
"sponsored_link"
];
Geração aleatória de ID
randomBaitID = baitIDs[ Math.floor(Math.random() * baitIDs.length) ],
...
var passed_eid = randomBaitID;
bait = document.createElement('DIV');
bait.id = passed_eid;
Como isso funciona em cada inicialização, o identificador será diferente a cada vez.BlockAdBlock, terceira a última versão
O BlockAdBlock explora o ponto cego dos bloqueadores de anúncios: se um filtro ignorar todos os identificadores acima, ele também ignorará os anúncios reais. Assim, o BlockAdBlock força o bloqueador de anúncios a se tornar inútil .Nos bloqueadores, podemos executar scripts arbitrários antes de carregar a página. Você pode tentar remover o objeto BlockAdBlock antecipadamente. Mas, para isso, precisamos do nome do objeto BlockAdBlock, que é randomizado cada vez que é iniciado.O uBlock Origin adotou uma abordagem diferente. Como o código é executado por uma função eval
, podemos definir nossa própria função eval
que bloqueará a execução se encontrarmos o BlockAdBlock. Em JS, um objeto é capaz disso Proxy
: você pode substituir qualquer propriedade e método em qualquer objeto.Isso pode ser contornado, não passando a carga útil inicial do BlockAdBlock eval
, mas usando-a diretamente, portanto, também procuramos o ponto de entrada: a chamada setTimeout
. Como é setTimeout
passado por uma string, não por uma função, verificamos essa string.Implementação no uBlock Origin ( origem ):const signatures = [
[ 'blockadblock' ],
[ 'babasbm' ],
[ /getItem\('babn'\)/ ],
[
'getElementById',
'String.fromCharCode',
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',
'charAt',
'DOMContentLoaded',
'AdBlock',
'addEventListener',
'doScroll',
'fromCharCode',
'<<2|r>>4',
'sessionStorage',
'clientWidth',
'localStorage',
'Math',
'random'
],
];
const check = function(s) {
};
Lista de assinaturas: definindo modelos de código. A função check
verifica a sequência após eval
a conformidade com esses padrões.Em seguida, proxy as funções eval
e setTimeout
.window.eval = new Proxy(window.eval, {
apply: function(target, thisArg, args) {
const a = args[0];
if ( typeof a !== 'string' || !check(a) ) {
return target.apply(thisArg, args);
}
if ( document.body ) {
document.body.style.removeProperty('visibility');
}
let el = document.getElementById('babasbmsgx');
if ( el ) {
el.parentNode.removeChild(el);
}
}
});
window.setTimeout = new Proxy(window.setTimeout, {
apply: function(target, thisArg, args) {
const a = args[0];
if (
typeof a !== 'string' ||
/\.bab_elementid.$/.test(a) === false
) {
return target.apply(thisArg, args);
}
}
});
Como agora estamos usando um scriptlet , um fragmento de código personalizado especial executado pelo bloqueador, o filtro muda um pouco:localhost## +js(nobab)
Por não iniciar por padrão em todos os sites por motivos de desempenho, você deve atribuí-lo a cada site usando um script.Versão 4 (janeiro de 2016 - abril de 2016): funções experimentais
Diferença do código-fonte v3 / v4O método descrito para bloquear anti-bloqueadores foi desenvolvido em janeiro de 2016, de acordo com o histórico de confirmações do uBlock Origin , e não mudou conceitualmente desde o início. O BlockAdBlock nunca tentou contornar esse filtro alterando sua arquitetura. Em vez disso, ele continuou a desenvolver novos recursos. E quando vamos para a página BlockAdBlock, vemos uma guia interessante: "Você precisa de mais poder anti-bloqueio?"
Embora esses métodos de proteção estejam disponíveis apenas através de uma guia especial, eles estão incluídos em todos os scripts e são executados através de variáveis com os nomes correspondentes. A quarta versão implementa dois métodos:aDefOne
, "Proteção específica para sites do adsense"
aDefTwo
, "Recurso especial de segurança"
Comentários de depuração aleatórios
Antes de me despedir de você, devo mencionar mais uma coisa. No processo de engenharia reversa, uma função chamou minha atenção:Depurando console.log()
diretamente no código!function consolelog(e) {
if (window.consolelog == 1) {
console.log(e)
}
};
Isso é feito apenas se global consolelog
, por exemplo, estiver definido window.consolelog = 1
.Os comentários de depuração estão disponíveis apenas nesta versão. Se eu não tivesse revertido todas as versões, nunca as teria notado. Eles fornecem informações valiosas sobre como o código funciona.Segurança avançada: AdSense
Todos esses métodos especiais de proteção são codificados check
, não arm
como, como sugere a arquitetura. Talvez um novo desenvolvedor que não esteja familiarizado com a base de código tenha começado a trabalhar no produto.Se o AdSense estiver ativo na página, procuraremos anúncios. Se eles desaparecerem devido a um bloqueador, o BlockAdBlock será ativado.function check() {
...
var q = 'ins.adsbygoogle',
adsbygoogleQuery = document.querySelector(q);
if ((adsbygoogleQuery) && (adblockDetected == 0)) {
if (aDefOne == 'yes') {
consolelog('case2: standard bait says ads are NOT blocked.');
var adsbygoogle = '//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js';
if (scriptExists(adsbygoogle)) {
consolelog('case2: And Adsense pre-exists.');
if (adsbygoogleQuery.innerHTML.replace(/\s/g, '').length == 0) {
consolelog('case2: Ads are blocked.');
window['' + randomID + ''].arm()
}
}
};
adblockDetected = 1
}
...
scriptExists
verifica a página inteira em busca de um script com um determinado URL. Nesse caso, o script do AdSense 5.A URL do script é comparada com todos os scripts da página. Por algum motivo, o URL é truncado para 15 caracteres.function scriptExists(href) {
if (href) href = href.substr(href.length - 15);
var scripts = document.getElementsByTagName('script');
for (var i = scripts.length; i--;) {
var src = String(scripts[i].src);
if (src) src = src.substr(src.length - 15);
if (src === href) return true
};
return false
};
Proteção Avançada: Elemento Especial
Diferentemente do primeiro, esse método é acompanhado por um aviso: "Teste após a instalação para garantir a compatibilidade com o site".Essa proteção especial funciona apenas se um bloqueador não for encontrado e não houver script do AdSense na página. Aqui está o trecho de código relevante check
:check: function(checkPredicate, unused) {
if ((checkPredicate) && (adblockDetected == 0)) {
} else {
var q = 'ins.adsbygoogle',
adsbygoogleQuery = document.querySelector(q);
if ((adsbygoogleQuery) && (adblockDetected == 0)) {
if (aDefOne == 'yes') {
};
} else {
if (adblockDetected == 0) {
if (aDefTwo == 'yes') {
}
}
}
}
O método pressupõe que os proprietários do site usem apenas o AdSense: se um script do AdSense não existir, algo estará errado.Por que houve um aviso? Este método tenta ativar o script do AdSense. Se não carregar, provavelmente o bloqueador bloqueou a solicitação de rede, portanto, o BlockAdBlock é acionado. Mas isso pode arruinar alguns sites, daí o aviso.Se o AdSense não tiver sido carregado, a sobreposição será iniciada.if (aDefTwo == 'yes') {
var googleAdCode = '//static.doubleclick.net/instream/ad_status.js';
consolelog('case3: standard bait says ads are NOT blocked. Maybe ???\
No Adsense is found. Attempting to add Google ad code to head...');
var script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
script.setAttribute('src', googleAdCode);
script.onerror = function() {
window['' + randomID + ''].arm()
};
adblockDetected = 1;
if (!scriptExists(googleAdCode)) {
document.getElementsByTagName('head')[0].appendChild(script)
};
adsbygoogleQuery = 0;
window['' + randomID + ''].check = function() {
return
}
}
Quando ocorre uma falha no nível da rede, ela funciona onerror
como se um bloqueador de anúncios estivesse funcionando.De fato, a maioria dos bloqueadores de anúncios responde a isso e bloqueia a solicitação. Mas há um bloqueador que eu não mencionei ainda. Fale sobre o navegador Brave .Admirável Resposta do Navegador
Até agora, estudamos como o anti-bloqueio é detectado no uBlock Origin. E funciona, apenas um filtro específico é necessário para cada site em que o BlockAdBlock está instalado. O navegador Brave é impressionante, pois detecta e ignora o BlockAdBlock de todas as versões sem nenhuma ação necessária por parte do usuário. Para fazer isso, ele falsifica a solicitação diretamente na camada de rede 6.Em vez de bloquear a solicitação, ad_status.js
ela a ignora, mas carrega o tamanho de 0 bytes de anúncios do Google Ads . Esse truque engana o BlockAdBlock, porque onerror
funciona apenas se a solicitação de rede falhar.Versão 5 (março de 2016 - novembro de 2016)
Diferença do código fontev4 / v5Proteção avançada: favoritos de spam
A única alteração nesta versão é que a segunda proteção estendida foi reescrita, embora ainda siga o mesmo princípio básico: verificar as solicitações de rede que serão bloqueadas pelo bloqueador. Mas agora os favoritos estão sendo carregados, em vez do AdSense.Brave evita esse ataque da mesma maneira. Ele não bloqueia solicitações, mas cria imagens 1 × 1 falsas.if (aDefTwo == 'yes') {
if (! window['' + randomID + ''].ranAlready) {/
var favicons = [
"//www.google.com/adsense/start/images/favicon.ico",
"//www.gstatic.com/adx/doubleclick.ico",
"//advertising.yahoo.com/favicon.ico",
"//ads.twitter.com/favicon.ico",
"//www.doubleclickbygoogle.com/favicon.ico"
],
len = favicons.length,
img = favicons[Math.floor(Math.random() * len)],
...
baitImages(Math.floor(Math.random() * 2) + 1);
var m = new Image();
m.onerror = function() {
baitImages(Math.floor(Math.random() * 2) + 1);
c.src = imgCopy;
baitImages(Math.floor(Math.random() * 2) + 1)
};
c.onerror = function() {
adblockDetected = 1;
baitImages(Math.floor(Math.random() * 3) + 1);
window['' + randomID + ''].arm()
};
m.src = img;
baitImages(Math.floor(Math.random() * 3) + 1);
window['' + randomID + ''].ranAlready = true
};
}
A função baitImages
pode ser chamada com freqüência, com um número aleatório de imagens, para ignorar bloqueadores estáticos.Versão 6 (abril de 2016 - novembro de 2016): bloqueio corajoso
Diferença de código-fonte v5 / v6Os métodos BlockAdBlock, embora simples à primeira vista, gradualmente se tornaram mais complexos e mais eficientes. Mas o último inimigo invicto permaneceu: o navegador Brave.Proteção Avançada: Definindo um Favoricon Falsificado
Por que o BlockAdBlock mudou de tentativa de carregar um script para carregar imagens (favicons)? A resposta está no código adicionado à proteção por meio de favoritos de spam e ativado contra a proteção do Brave.Verificando a resposta para uma imagem falsa:if (aDefTwo == 'yes') {
baitImages(Math.floor(Math.random() * 3) + 1);
var m = new Image();
if ((aDefThree % 3) == 0) {
m.onload = function() {
if ((m.width < 8) && (m.width > 0)) {
window['' + randomID + ''].arm()
}
}
};
}
Se o tamanho do favicon for menor que 8 × 8, provavelmente isso é falso no navegador Brave.Com esse truque, o BlockAdBlock ignora o disfarce de Brave e outros bloqueadores que executam esse código (a maioria, como o uBlock Origin, bloqueia-o primeiro).Após essa atualização, no final de novembro de 2016, o BlockAdBlock desapareceu da Internet. Embora seus “métodos avançados de segurança” funcionem, eles nunca foram ativados para a maioria dos usuários. Esta foi a última atualização. A última postagem no Twitter e no site foi publicada em algum lugar no final de 2017.No entanto, o legado do BlockAdBlock continua vivo. Embora seja trivial bloqueá-lo atualmente, esse script ainda é usado por alguns sites modernos.Conclusão
Quem vencerá a corrida armamentista entre bloqueadores de anúncios e anti-bloqueadores que bloqueiam anúncios? Só o tempo irá dizer. À medida que a corrida armamentista se desenvolve, os anti-bloqueadores terão que usar métodos mais sofisticados e códigos especiais, como mostra a evolução do BlockAdBlock.Por outro lado, os bloqueadores têm a vantagem de sistemas estáveis e poderosas ferramentas de filtragem por meio de listas de filtros, além de acesso ao JavaScript. Com esse sistema, basta uma pessoa entender como derrotar o inimigo - e atualizar a lista de filtros com novos sites.Ao analisar a evolução do BlockAdBlock, bem como as várias respostas dos bloqueadores de anúncios, pudemos desenhar uma imagem de uma pequena guerra entre o BlockAdBlock e os bloqueadores. No processo, aprendemos quais métodos são usados nas hostilidades.Meu código de engenharia reversa é publicado no GitHub . Obrigado pela leitura.
1. Se você quiser ter uma idéia de como isso funciona, tente colar o exemplo abaixo no console JS e, em seguida, observe o código. Se você está interessado em seu funcionamento interno, aqui está o código fonte . Return [voltar]2. Não acredita? Tente mudar eval
para console.log
na primeira linha.[para retornar]3. O registro de data e hora diz 201510
, então talvez outubro. Mas não sabemos quando o script mudou. Todos nós sabemos:- 2015-10, uma versão foi salva:
20151007203811.js
- 2015-11, há uma nova versão:
20151113115955.js
Tanto quanto sabemos, o script pode ser alterado no dia anterior ao segundo registro de data e hora. Assim, eu abordo de forma conservadora o namoro. Return [voltar]4. Durante a correção desse erro, foram desenvolvidos testes para a v1. Return [voltar]5. Obrigado a McStroyer no Reddit, que chamou a atenção para isso. Return [voltar]6. O componente Brave bloqueador de anúncios está aberto, para que possamos examinar o código-fonte para ter uma idéia de como ele funciona.Agradecemos a François Marie por indicar o código fonte do Brave. Return [voltar]