이 난독 화 된 JavaScript는 어떻게 작동합니까?
다음 JavaScript는 어떻게 작동합니까?
나는 그것이 축소 된 코드라는 것을 이해합니다. 난독 해제를 조금 시도했지만이 효과를 얻는 방법에 대한 명확한 개념을 얻을 수 없습니다. 어떤 종류의 반복, Date 객체 사용, 이상한 문자열 조작, Math 함수에 문자열을 사용하고 있음을 알 수 있습니다. 그러면 코드가 자체적으로 인쇄됩니다.
최소한의 예제로 동일한 효과를 어떻게 다시 작성할 수 있습니까?
eval(z='p="<"+"pre>"/* ,.oq#+ ,._, */;for(y in n="zw24l6k\
4e3t4jnt4qj24xh2 x/* =<,m#F^ A W###q. */42kty24wrt413n243n\
9h243pdxt41csb yz/* #K q##H######Am */43iyb6k43pk7243nm\
r24".split(4)){/* dP cpq#q##########b, */for(a in t=pars\
eInt(n[y],36)+/* p##@###YG=[#######y */(e=x=r=[]))for\
(r=!r,i=0;t[a/* d#qg `*PWo##q#######D */]>i;i+=.05)wi\
th(Math)x-= /* aem1k.com Q###KWR#### W[ */.05,0>cos(o=\
new Date/1e3/* .Q#########Md#.###OP A@ , */+x/PI)&&(e[~\
~(32*sin(o)*/* , (W#####Xx######.P^ T % */sin(.5+y/7))\
+60] =-~ r);/* #y `^TqW####P###BP */for(x=0;122>\
x;)p+=" *#"/* b. OQ####x#K */[e[x++]+e[x++\
]]||(S=("eval"/* l `X#####D , */+"(z=\'"+z.spl\
it(B = "\\\\")./* G####B" # */join(B+B).split\
(Q="\'").join(B+Q/* VQBP` */)+Q+")//m1k")[x/2\
+61*y-1]).fontcolor/* TP */(/\\w/.test(S)&&"#\
03B");document.body.innerHTML=p+=B+"\\n"}setTimeout(z)')//
서문 : http://jsfiddle.net/WZXYr/2/ 에서 코드를 광범위하게 아름답게 수정하고 주석을 달았습니다.
가장 바깥 쪽 레이어를 고려하십시오.
eval(z = '...');
코드 문자열은 변수에 저장됩니다 z
. 할당 연산자는 할당 된 값을 반환하므로 코드 문자열도에 인수로 전달됩니다 eval
.
코드 문자열 z
은 eval
. 코드는 정리하더라도 매우 둔감하지만 다음과 같이 보입니다.
- 문자로 구분 된 base-36 숫자의 문자열을 구문 분석합니다
4
. - 글로벌 변수를 사용하여, 값의 맵을 채우고
e
,x
및y
홀드 상태에지도. 지도 상태는 부분적으로 벽시계 (new Date / 1e3
) 에서 현재 초의 함수입니다 . - 맵 값을 사용하여 코드는 출력 문자열을 생성합니다.
p
- 코드 사용은
p += " *#"[index]
공간, 별표 (*) 또는 해시 마크의 사용 여부를 결정하는index
사실이다e[x++] + e[x++]
(위에서 말했듯이,e
및x
지도 상태에 대한 책임이 있습니다) - 인덱스가의 길이보다 크면
" *#"
출력p
을의 문자로 채우는 대체 코드가 있습니다z
. 내부 캐릭터는 애니메이션 캐릭터로 채워지고 외부 캐릭터는에서 가져옵니다z
.
- 코드 사용은
코드 끝에는 setTimeout(z)
코드 문자열을 비동기 적으로 평가하는에 대한 호출이 z
있습니다. 이 반복 호출을 z
통해 코드가 반복됩니다.
간단한 예 :
다음은 매우 간단한 버전입니다 ( http://jsfiddle.net/5QXn8/ ) :
eval(z='p="<"+"pre>";for(i=0;i<172;++i)if(i > 62 && i < 67)p+="!---"[~~(new Date/1e2 + i)%4];else p += ("eval(z=\'" + z + "\')")[i];document.body.innerHTML = p;setTimeout(z)')
for
루프 출력 문자열의 각 문자를 추가한다p
(문자열 길이 172 개 문자이다)for(i=0;i<172;++i)
내부 조건은 애니메이션 캐릭터 인 62에서 67 사이의 캐릭터에 있는지 여부를 결정합니다.
if(i > 62 && i < 67)
그렇다면
!---
두 번째 벽시계 값의 10 분의 1을 기준으로 이동 하여를 출력 합니다. 이것은 애니메이션 효과를 제공합니다.p+="!---"[~~(new Date/1e2 + i)%4]
(
new Date
날짜 값을 0과 3 사이의 숫자로 변환하기 위해 주변의 모든 불쾌 함 이 실제로 존재합니다.)그렇지 않고 애니메이션 캐릭터가 아니라면 다음에
i
의해 정의 된 문자열에서 인덱스 문자 를 인쇄합니다."eval(z='" + z + "')"
즉, 및로
z
둘러싸인 코드 문자열 입니다.eval('
')
마지막으로 문자열을 출력하고을 사용
setTimeout
하여z
다음 실행을 대기열에 추가합니다 .document.body.innerHTML = p;setTimeout(z)
내 최종 출력이되지 않도록주의 확실히 내가 끝으로 갈수록 백 슬래시를 차지하지 - -하지만 여전히 당신에게 기술이 일반적으로 어떻게 작동하는지 꽤 좋은 아이디어를 제공해야 맞다.
다음은 주석이 달린 소스입니다. 추신 : 나는 저자 다;)
function z(){ // will be replaced with eval
p = "<" + "pre>"; // use <pre> tag for formatted output
for ( // loop though lines
y in n = ( // y - the line number
"zw24" + // n - the encoded data
"l6k4" + // every line holds encoded data
"e3t4" +
"jnt4" + // string will be concated in build process
"qj24" +
"xh2 4" + // data after spaces will be ignored but
"2kty24" + // … is used to not break block comments
"wrt4" + // … which will save some chars
"13n24" +
"3n9h24" +
"3pdxt4" +
"1csb 4" +
"3iyb6k4" +
"3pk724" +
"3nmr24"
).split(4) // data will be split by (unused) 4
){
for ( // loop throug every char in line
a in t = parseInt( // numbers are encoded as string
n[y], // … with a base of 36
36
) + ( // large number will be converted to string
e = // e - holds the rendered globe
x = // x - horizonal position
r = [] // r - bitmap flag if pixel is set
)
){
r = !r; // toggle binary flag
for ( // look though bitmap states
i = 0;
t[a] > i; // draw pixel t[a]-times
i += .05
)
with (Math) // refer to Math later
x -= .05,
0 > cos( // prevent backface visibility
o =
new Date / 1e3 + // get rotation based on current time
x / PI
) && (
e[ // access matrix
~~( // convert float to integer
sin(o) * // rotate around y axis
sin(.5 + y/7) *
32 // scale up the globe
) + 60 // move to center
] = -~r // store bitmap state in render matrix
)
}
for ( // loop through columns
x = 0;
122 > x; // break after char 122
) p += " *#"[ // add space, asterisk or hash
e[x++] + // … based pixel opacity
e[x++]
] || (S = ( // otherwise use the original code
"eval(z='" + // inception of missing "eval" statement
z
.split(B = "\\") // escape \ with \\
.join(B + B)
.split(Q = "'") // escape ' with \'
.join(B + Q) +
Q + // add missing ')
")////////" // add extra chars to fill mapping
)[
x / 2 + // get character at current position
61 * y-1
]
).fontcolor( // colorize outpu
/\w/.test(S) && // test for [0-9A-Z]
"#03B" // render blue
// otherwise pink (default)
);
document.body.innerHTML = // render output
p += // append new line
B + // add backspace
"\n"; // add new line
}
setTimeout(z) // render animation on next frame
}
z()
다음은 수동으로 난독 해제 된 또 다른 버전으로, 모든 초기화를 표현에서 벗어나 자신의 명령문으로 이동합니다.
z='p="<"+"pre>"/* ,.oq#+ ,._, */;for(y in n="zw24l6k\
4e3t4jnt4qj24xh2 x/* =<,m#F^ A W###q. */42kty24wrt413n243n\
9h243pdxt41csb yz/* #K q##H######Am */43iyb6k43pk7243nm\
r24".split(4)){/* dP cpq#q##########b, */for(a in t=pars\
eInt(n[y],36)+/* p##@###YG=[#######y */(e=x=r=[]))for\
(r=!r,i=0;t[a/* d#qg `*PWo##q#######D */]>i;i+=.05)wi\
th(Math)x-= /* aem1k.com Q###KWR#### W[ */.05,0>cos(o=\
new Date/1e3/* .Q#########Md#.###OP A@ , */+x/PI)&&(e[~\
~(32*sin(o)*/* , (W#####Xx######.P^ T % */sin(.5+y/7))\
+60] =-~ r);/* #y `^TqW####P###BP */for(x=0;122>\
x;)p+=" *#"/* b. OQ####x#K */[e[x++]+e[x++\
]]||(S=("eval"/* l `X#####D , */+"(z=\'"+z.spl\
it(B = "\\\\")./* G####B" # */join(B+B).split\
(Q="\'").join(B+Q/* VQBP` */)+Q+")//m1k")[x/2\
+61*y-1]).fontcolor/* TP */(/\\w/.test(S)&&"#\
03B");document.body.innerHTML=p+=B+"\\n"}setTimeout(z)';
p = "<" + "pre>";
n = ["zw2", "l6k", "e3t", "jnt", "qj2", "xh2 x/* =<,m#F^ A W###q. */", "2kty2", "wrt", "13n2", "3n9h2", "3pdxt", "1csb yz/* #K q##H######Am */", "3iyb6k", "3pk72", "3nmr2", ""]
for (y in n) {
e = [];
x = 0;
r = true;
t = parseInt(n[y], 36) + "";
for (a in t) {
r = !r
for (i = 0; i < t[a]; i += 0.05) {
x -= 0.05;
o = new Date / 1e3 + x / Math.PI
if (Math.cos(o) < 0)
e[~~(32 * Math.sin(o) * Math.sin(0.5 + y / 7)) + 60] = -~r;
}
for (x = 0; x < 122;) {
S = "eval" + "(z='" + z.split(B = "\\").join(B + B).split(Q = "'").join(B + Q) + Q + ")//m1k"
p += " *#"[e[x++] + e[x++]] || S[x/2+61*y-1]).fontcolor(/\w/.test(S[x/2+61*y-1]) && "#03B");
}
p += B + "\n";
document.body.innerHTML = p;
}
setTimeout(z)
다음은 발생합니다.
z
모든 코드를 포함하는 여러 줄 문자열입니다. 그것은됩니다eval
에드.- 코드 끝에서는
z
에 전달됩니다setTimeout
. 그것은 같이requestAnimationFrame
그리고eval
함께 작동 하여 가능한 한 가장 높은 속도로 간격을두고 평가합니다. - 코드 자체
p
는 HTML이 추가 될 문자열 버퍼 및n
기본 36으로 인코딩 된 숫자의 배열을 초기화 합니다 (에서 문자열에 조인되고"4"
주석은에서 고려되지 않는 관련없는 쓰레기parseInt
임). - 의 각 숫자는
n
한 줄 (n.length == 16
)을 인코딩 합니다. 이제 열거 됩니다. - A bunch of variables is initialised, some disguised as the
e
array literal but they are then cast to numbers (x
) or booleans (r
) or strings (t
) when used. - Each digit in the number
t
is enumerated, inverting the booleanr
each turn. For different anglesx
, and depending on the current timenew Date / 1000
(so that it gives an animation), the arraye
is filled using some bitwise operators - with1
whenr
is false and2
s whenr
is true at that time. - Then a loop does iterate the 61 columns of the image, from
x=0
to 122 in double steps, appending single characters top
. B
being the backslash, the stringS
is built from the code stringz
by escaping backslashes and apostrophes, to get an accurate representation of what it looked in the source.- Every two consecutive numbers from
e
are added and used to access a character from" *#"
, to build up the animated image. If one of the indices is not defined, theNaN
index resolves to an undefined character and instead the respective character from theS
string is taken (check out the formulax/2+61*y-1
). If that character should be a word character, it is colored differently using thefontcolor
String method. - After each line, the trailing backspace and a linebreak are added to
p
, and the HTML string gets assigned to the document body.
How the same effect could be rewritten for a minimal example?
Here is an other example:
setInterval(z='s=("setInterval(z=\'"+\
z.replace(/[\\\\\']/g,"\\\\$&")+"\')"\
).match(/.{1,37}/g).join("\\\\\\n");d\
ocument.body.innerHTML=\"<\\pre>"+s.s\
lice(0, 175)+String( + new Date()).fo\
ntcolor("red")+s.slice(188)')
It has all the releveant things you need for this kind of animation:
setInterval
andDate
for the animationA reconstruction of its own code (quine-like), in here:
s = ( "setInterval(z='" // the outer invokation + z.replace(/[\\\']/g,"\\$&") // the escaped version + "\')" ) // the end of the assignment .match(/.{1,37}/g).join("\\\n"); // chunked into lines
The output via
document.body.innerHTML
and a<pre>
element- Replacing some parts of the code with the animated string
A string with the all the code is evaluated, and a timeout makes the loop; The string is stored in a variable named z
and in the middle of the code, between comments /*
and */
there is an "Earth ASCII Art". The code parses the comments and changes the document content, keeping the js and updating the art. Bellow is just the code sliced:
p="<pre>";
for(y in n="zw24l6k4e3t4jnt4qj24xh2 x42kty24wrt413n243n9h243pdxt41csb yz43iyb6k43pk7243nmr24".split(4)){
for(a in t = parseInt(n[y],36)+(e=x=r=[]))
for(r=!r,i=0;t[a]>i;i+=.05)
with(Math) x-= .05,0>cos(o=new Date/1e3+x/PI)&&(e[~~(32*sin(o)*sin(.5+y/7))+60] =-~ r);
for(x=0;122>x;) p += " *#"[e[x++]+e[x++\]] ||
(S=("eval"+"(z=\'"+z.split(B = "\\\\").join(B+B).split(Q="\'").join(B+Q)+Q+")//m1k")[x/2+61*y-1]).fontcolor(/\\w/.test(S)&&"#\03B");
p += B+"\\n"
document.body.innerHTML= p
}
참고URL : https://stackoverflow.com/questions/18834309/how-does-this-obfuscated-javascript-work
'Programing' 카테고리의 다른 글
읽기 전용 및 가져 오기 전용 속성을 사용해야하는 경우 (0) | 2020.08.30 |
---|---|
브라우저 호환성에 대해 걱정하지 않고 어떤 HTML5 태그를 사용할 수 있습니까? (0) | 2020.08.30 |
최고의 온라인 결제 처리 솔루션은 무엇입니까? (0) | 2020.08.30 |
ViewData와 TempData의 차이점은 무엇입니까? (0) | 2020.08.30 |
CSS 선택기에서 별표 (*)는 무엇을합니까? (0) | 2020.08.30 |