JavaScript (ECMAScript6), 한 줄에 2 바이트
'\
'[
'\
b\
i\
g'
][
'\
c\
o\
n\
s\
t\
r\
u\
c\
t\
o\
r'
][
'\
c\
a\
l\
l'
](
0,
`\
n\
=\
p\
r\
o\
m\
p\
t\
(\
'\
'\
)\
;\
i\
=\
0\
;\
f\
o\
r\
(\
;\
+\
+\
i\
<\
=\
n\
;\
c\
o\
n\
s\
o\
l\
e\
.\
l\
o\
g\
(\
i\
%\
5\
?\
f\
|\
|\
i\
:\
f\
+\
'\
P\
i\
e\
'\
)\
)\
f\
=\
i\
%\
3\
?\
'\
'\
:\
'\
A\
p\
p\
l\
e\
'\
`)
()
긴 설명
줄을 짧게 만들 수있는 방법은 코드를 문자열로 변환하고 줄 끝을 피하는 것입니다. 이렇게하면 줄당 2 바이트가 제한됩니다.
그래서 alert(1)
이된다
"\
a\
l\
e\
r\
(\
1\
)"
그러나 이제 코드는 문자열이므로 문자열을 코드로 실행해야합니다. 문자열을 코드로 실행할 수있는 적어도 4 가지 방법을 알고 있습니다.
- eval (code) . 호출하는 데 5 바이트 이상 필요
eval(
- setTimeout (코드, 타임 아웃) . 함수를 비동기 적으로 실행하지만 선택적으로 문자열을 전달하면 내부적으로 eval을 호출합니다.
- DOM을 활용하여 코드를
onclick=""
속성 는 있지만 요소 생성 부분을 짧게 만들 수는 없었습니다.
- 함수 생성자를 호출하면 new Function () 은 나중에 호출 할 수있는 익명 함수로 코드를 구문 분석합니다 (이것을 사용했습니다).
내부의 모든 기본 기능의 삶 창 객체와 사용자가 사용하는 객체 속성에 액세스 할 수 있습니다 자바 스크립트에서 점 표기법은 이렇게 eval()
하게 window.eval()
하거나 사용하여 속성에 액세스 할 수 있습니다 브래킷 표기법을 window['eval']()
. eval
앞에서 설명한 방법을 사용하여 여러 줄 을 나누기 위해이를 활용할 수 있습니다 . 하지만 여전히 창 을 입력해야합니다 . 한 가지 트릭은 프레임 안에 있지 않으면 top 변수도 window이므로 window.eval은 top.eval (3 바이트 미만)이됩니다.
w=top
w['eval']
You can shorten the assignment using parenthesis
w=(
top
)
w[
'e\
av\
al'
](
/*string*/
)
따라서 코드가 최소 3 바이트가됩니다. 코드를 2 바이트로 만들려면 new Function(/*string*/);
생성자를 사용했지만 입력하지 않고도 액세스 할 수있는 독창적이어야했습니다.
먼저 함수 생성자를 사용하면 새 키워드를 생략하는 함수로 호출 할 수 있습니다. 이렇게하면 4 바이트가 줄어들지 만 다른 이유로도 중요합니다. 함수는 여전히 우리가 회전 할 수있는 인스턴스를 반환으로 생성자를 호출 new Function(code)
하는 방법에 대해 Function(code)
. 또 다른 중요한 점은 Function 생성자가 함수 call
를 호출하지만이 참조를 재정의 하는 메소드를 가지고 있으며 Function 생성자 자체는 자체적으로 메소드를 호출 할 수있는 함수라는 것입니다Function.call(null, code)
입니다.
모든 기본 함수는 함수 생성자의 인스턴스이며, 자바 스크립트의 모든 객체에는 생성자 속성이 있습니다. 따라서와 같은 기본 함수 alert.constructor
에서 호출을 사용하여 함수 생성자를 액세스 할 수 있습니다 메소드를 하여 생성자를 함수로 실행할 수 있습니다. 이제 alert.constructor.call (null, code) 함수를 반환합니다.
이전의 테크닉을 결합하여 alert['constructor']['call'](null, code)
이제 짧은 이름의 함수 또는 메소드를 찾아야하므로 String 생성자 에서 big () 메소드를 선택합니다 . 빈 문자열에서 직접 액세스 할 수 있습니다."".big
"".big.constructor.call(null, "code")();
''['big']['constructor']['call'](0,'/* code */')()
그런 다음 방금 2 바이트로 모든 것을 끊었습니다.
짧은 어 설명 (TLDR)
eval (code) 대신 문자열을 구문 분석 하기 위해 새로운 Function (code) 생성자에 액세스하고 있습니다. 이 생성자는 anyFunction을 수행하여 모든 기본 함수에서 사용할 수 있습니다. 같은 생성자 . String.prototype.big 내부에서 함수 / 메서드를 사용하고
있지만 문자열 리터럴에서 직접 액세스 하여 대괄호 표기법으로 설정했습니다 . 를 사용하여 중단 할 수 있습니다 .alert.constructor===Function
String.prototype.big.constructor.call(null, /*string*/)
"".big
""['big']['constructor']['call'](0, CODE)
\