é difícil resumir esta pergunta no título de uma pergunta
ATUALIZAÇÃO Criei um JSFiddle que constrói uma string ofuscada a partir de sua entrada com base nas letras extraídas desta pergunta: Você pode acessá-la aqui ou uma essência seria mais fácil?
Recentemente, deparei com um pouco de JavaScript ofuscado neste perfil que se parece com isso:
javascript:[[]+1/!1][1^1][1>>1]+({}+[])[1<<1^11>>1]+([]+!!-
[])[1<<1]+[/~/+{}][+!1][-~1<<1]+([]+/-/[(!!1+[])[1>>1]+(!!1
+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^11<<1]+([,][
~1]+[])[1-~1]+[[]+{}][!1.1%1][11111.1%11.1*111e11|!1]+(/1/+
1/[1<1][1%1])[1^11]+[[],[]+{}][1][+1]+(/<</[1]+[])[1/1.1&1]
Desculpe estragar a surpresa, mas quando isso é avaliado, ele retorna isso:
"I love you" in Chrome
"I lone you" In Firefox
"I lo[e you" in IE10
A maneira como isso funciona, quando dividido, é gerar uma série de mensagens e extrair delas as letras (usando o "I" como exemplo):
[]+1/!1
returns
"Infinity"
then
[[]+1/!1]
creates this array:
["Infinity"]
then
[[]+1/!1][1^1]
Takes the first (1^1 == 0) element of that array
"Infinity"
finally
[[]+1/!1][1^1][1>>1]
Takes the first (1>>1 == 0) char of that string
"I"
Outras cadeias geradas incluem:
({}+[]) -> "[object Object]" (where the space comes from)
([]+!!-[]) -> "false" (used for it's "l")
[/~/+{}][+!1] -> "/~/[object Object]" (this is used for an "o")
(/<</[1]+[]) -> "undefined"
Eu estava interessado em encontrar um substituto para o "n" e "[" e criei o seguinte:
String.fromCharCode(('1'.charCodeAt(0)<<1)+(10<<1))
O que sinto no espírito de usar zeros e zeros, mas viola um dos aspectos mais elegantes do código original, que é a aparência de não ter nada a ver com strings. Alguém mais tem uma idéia de como gerar um "v" que esteja de acordo com o código ofuscado original?
Aqui estão algumas informações extras encontradas depois que muitos programadores talentosos de JavaScript analisaram mais detalhadamente
O Firefox retorna "Eu solto você" Por causa desta linha:
([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^11<<1]+
[1^11<<1]
apara um caractere específico disso:
([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])
O que avalia isso:
"function test() {
[native code]
}"
Parece que podemos ter o nosso "V" !!!
O Chrome retorna "eu te amo", porque o mesmo código retorna isso:
"function test() { [native code] }"
Antes que a pergunta fosse encerrada para conexão questionável com "um problema de programação real", pensei em adicionar uma solução resumida baseada em @ Supr , @ Cory e @ alpha123 , eis que:
alert([[]+1/!1][1^1][1>>1]+({}+[])[1<<1^11>>1]+(
[]+!!-[])[1<<1]+[/~/+{}][+!1][-~1<<1]+[([]+/-/[(
!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(
!!1+[])[1^1]])[1+(1^(11+1+1)<<1)],([]+/-/[(!!1+[
])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[
])[1^1]])[1^11<<1],([]+/-/[(!!1+[])[1>>1]+(!!1+[
])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^(11
+1+1)<<1]][((([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<
1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[(1<<1<<1<<1
)+1<<1]==({}+[])[1^1])*1)+((([]+/-/[(!!1+[])[1>>
1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1
]])[(1^11<<1)-1]==({}+[])[1^1])<<1)]+([,][~1]+[]
)[1-~1]+[[]+{}][!1.1%1][11111.1%11.1*111e11|!1]+
(/1/+1/[1<1][1%1])[1^11]+[[],[]+{}][1][+1]+(/<</
[1]+[])[1/1.1&1])
Dada a complexidade do código e a mensagem que ele produz, é quase como se o mecanismo JavaScript estivesse dizendo o quão especial você se sente :)
fonte
function test() { [native code] }
, então você pode normalizá-lo e extrair a letra desejadaRespostas:
Antes de tudo, gostaria de agradecer a Jason e a todos os colaboradores por brincar com esse trecho engraçado. Escrevi esse código apenas por diversão , a fim de enviá-lo para minha esposa em 14 de fevereiro :) Tendo apenas o Chrome instalado no laptop, não tive opções para verificar como ele funciona no Firefox e no IE. Além disso, eu realmente não esperava que a
toString()
representação dos métodos internos pudesse parecer diferente em outros navegadores.Agora, passando para o problema real , vamos dar uma olhada precisa no código. Sim,
"v"
foi o verdadeiro "problema" aqui. Não encontrei outras maneiras de obter essa carta, exceto a análise de[native code]
string, que pode ser obtida a partir de qualquer método interno. Como me limitava a não ter seqüências de caracteres e números, exceto o1
usado, eu precisava explorar algum método que tivesse apenas caracteres disponíveis em seu nome.Caracteres disponíveis podem ser obtidas a partir de palavras-chave existentes e representações de seqüência, ou seja, desde o início, tivemos
NaN
,null
,undefined
,Infinity
,true
,false
, e"[object Object]"
. Alguns deles podem ser facilmente convertidos em strings, por exemplo,1/!1+[]
give"Infinity"
.Analisei diferentes métodos internos para matrizes
[]
, objetos{}
, expressões regulares/(?:)/
, números1.1
, seqüências de caracteres"1"
e descobri um belo método deRegExp
objeto chamadotest()
. Seu nome pode ser montado a partir de todos os caracteres disponíveis, por exemplo,"t"
e"e"
a partir detrue
, e"s"
defalse
. Eu criei uma string"test"
e resolvi esse método usando a notação de colchetes para regex literal/-/
, corretamente identificada nesta linha:Como já foi discutido, esse trecho de código é avaliado no Chrome como:
no Firefox como:
e no IE como:
(neste último, preste atenção especial ao espaço antes da
function
palavra-chave)Então, como você vê claramente, meu código estava obtendo o 24º caractere da string apresentada, que era no Chrome
"v"
(como foi planejado), mas infelizmente no Firefox e IE -"n"
e"["
respectivamente.Para obter a mesma saída em todos os navegadores, usei uma abordagem diferente da ilustrada nas outras respostas. Agora a versão modificada se parece com isso:
No entanto, para intrigar os leitores, não fornecerei uma solução para isso. Sinceramente, acredito que você entenderá facilmente como funciona ... e alguns podem até surpreender sua amada no modo entre navegadores;)
PS ainda outro ofuscador
Inspirado na idéia de Jason de criar uma ferramenta ofuscante universal, escrevi mais uma. Você pode encontrá-lo em JSBin: http://jsbin.com/amecoq/2 . Ele pode ofuscar qualquer texto que contenha números
[0-9]
, pequenas letras latinas[a-z]
e espaços. O comprimento da string é limitado principalmente pela sua RAM (pelo menos o corpo da minha resposta foi ofuscado com sucesso). A saída é suportada pelo Chrome, Firefox e IE.Dica: a ferramenta usa uma abordagem de ofuscação diferente da apresentada acima.
fonte
Por que o
native code
trecho da pergunta não está sendo usado? Este fornece um'v'
no Chrome e Firefox:Edite para oferecer suporte ao IE e faça-o sem o operador ternário: Este funciona no Chrome, IE e FF. Constrói uma matriz e usa
==
para determinar o navegador.Legível:
fonte
n
ev
e apenas escolher o que for maior:str[23]>str[27]?str[23]:str[27]
. Em outras palavras, o operador terciário é o truque. Poderia ser estendido para oferecer suporte ao IE também:([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1+(1^(11+1+1)<<1)]
Isso é o mais próximo que pude, infelizmente, viola a convenção da ofuscação original ao fazer uma chamada para
unescape()
:Destruir:
Outras idéias:
unescape("\x76")
118
sem chamarString.fromCharCode()
Atualizações:
Comecei a jogar código de golfe e o reduzi, substituindo peças por mais
1
s, etc.fonte
'%'
com a(/%/+[[]+1/!1])[1]
remoção de quaisquer aspas. Também adicioneil=unescape;
usando letras minúsculasL
para ocultar a referênciaunescape
. Este tem sido divertido :)(/%/+[])[1]
$1
;Aqui está a parte que gera o n / v:
No Firefox,
([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])
avalia comoenquanto no Chrome é
1^11<<1
é igual a 23. Portanto, devido ao espaço em branco extra do Firefox, isso não é suficiente para chegar ao 'v' e, em vez disso, é 'n'.E é por isso que você não deve confiar no comportamento da função # toString. ;)
EDIT: Finalmente, encontrei uma versão entre navegadores razoavelmente ofuscada:
Isso substitui a seção n / v por:
que explora diferenças no parseInt (aparentemente o Firefox analisa números começando com 0 como octal, enquanto o Chrome não) para adicionar 4 no caso do Firefox, obtendo assim 'v' de 'native' nos dois casos (não consigo encontrar outro 'v ': P).
O parseInt parece um pouco fora do lugar, mas é o melhor que posso fazer por enquanto.
fonte
Does anyone else have an idea of how to generate a "v" that is in keeping with the original obfuscated code?
Para o caso de uso geral , se o uso de caracteres não for uma grande preocupação, posso estar inclinado a trapacear um pouco.
Crie a função "c" que transforma um número 0 .. 25 em um caractere.
Por motivos de desempenho, pré-armazene em cache as letras, se desejar.
No console do Chrome, a matriz resultante é assim:
Então ... seu v pode ser
l[10+10+1]
.Como alternativa, uma solução geral como esta:
Ou, para esse problema específico , talvez apenas:
fonte
Isso fornece av no Chrome:
E isso acontece no Firefox:
Os dois o extraem
Object.prototype.preventExtensions()
, então você provavelmente poderia encontrar uma maneira entre navegadores para fazer referência a esse método. (É o único nome de 17 caracteres em Object.Prototype para iniciantes.)Sinta-se livre para criar uma versão mais ofuscada disso e levar todo o crédito para si mesmo, estou sem tempo;)
fonte
No chrome, a expressão é
([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])
avaliada como"function test() { [native code] }"
, e é[1^11<<1]
avaliada como 23 (operadores bit a bit fazem com que a variável seja truncada em 32 bits)fonte
Does anyone else have an idea of how to generate a "v" that is in keeping with the original obfuscated code?