-
-
[原创]逆向中的GL与着色器逆向
-
发表于: 2024-7-25 15:10 6300
-
着色器是一种运行在图形处理单元(GPU)上的小程序,用于对图形渲染管线的特定部分进行处理。着色器的主要作用是将输入数据(如顶点位置、颜色等)转化为输出数据(如像素颜色),从而实现对图像的渲染和处理。
从着色器代码到GPU可以理解的着色器程序,一般需要经过编译。
针对较低版本的OpenGL,这一般意味着从文件或者data段读取源代码直接编译。这给了我们修改shader以控制最终渲染表现的机会。例如笔者在VNCTF2024中的题目LearnOpenGL,就可以通过直接修改着色器的方法得到flag。
更为细致的,这里的”编译“其实包含了编译与链接两步。
一般而言,如果最后需要着色器生成一个图像,那么顶点着色器与片段着色器是不可缺的。因为图形的渲染必然涉及到以下两步:第一步把3D坐标转换为2D坐标,第二步是把2D坐标转变为实际的有颜色的像素。
可以大致理解成顶点着色器负责第一步,片段着色器负责第二步。那么两步加在一起才是一个完整的过程。反映到代码层面,就是在编译好顶点与片段着色器后,需要把两者链接起来,变成一个program,后续调用会直接调用这个program进行渲染。
而对于OpenGL之外的其它环境,着色器代码可能会被预编译为中间表示,如Vulkan平台通常使用SPIR-V作为中间表示,而DirectX平台则使用DXBC。
根据题目名,以及调用的动态链接库,我们初步怀疑是Vulkan平台的shader逆向。运行程序,发现没有图形界面,那么看来它调用vulkan不是用来绘图的。直接猜测一手,核心的加密逻辑在vulkan调用的着色器里。
ida分析main_0函数,很容易发现dword_140021000里存的是加密后的密文。往前翻哪里读入了着色器,因为着色器读入后需要平台进行加载,所以在vkCreateShaderModule函数之前的sub_14001135C函数中
分析代码,着色器在程序的resource里,可以使用resource hacker等工具提取出来。发现是二进制格式的,需要反编译。根据我们前置介绍里讲的,Vulkan平台通常使用SPIR-V作为中间表示,那么现在我们需要找一个SPIR-V的反编译器。经过一番搜索,发现百度只能找到spirv-dis,是反编译成字节码,逆向难度仍然较大。GitHub能找到spirv-cross,直接把我们提取出来的中间表示还原成GLSL:
到了这步,xtea加密的特征就很明显了,我们写出对应的解密代码:
头尾有些问题。头可以确定是DubheCTF,根据flag规则与tea加密原理,尾部只有一位未知,即^^*},在本地用python的subprocess爆破一下
js先上下面这个网站去一点混淆:https://deobfuscate.relative.im/
flag解密部分的代码如下,记该函数为get_flag:
现在我们要求的变成了这个函数的parm
与检查flag相关的顶点着色器代码如下,传入vec3(三个数构成的数组),前两个被用来确定顶点的位置,第三个作为一个可以在着色器间传递的变量,进入了片段着色器:
片段着色器代码如下:
稍微去一下名称混淆如下:
后面就是根据功能恢复一下代码里的函数与变量名:
本来的打算是使用z3,对输入进行规约,但是存在两个难点:
赛后参考其它队伍的做法,发现能通过重放爆破的方式,把输入逐渐爆破出来,感觉这题有点过于偏技巧了
以下均来自r3kapig的wp
只涉及到输入里的5个变量(input[0xb], input[0x3], input[0x1], input[0x15], input[0x8]),可以考虑爆破出来
后续进行结果的组装
input = [19, 9, 8, 15, 3, 18, 17, 10, 23, 5, 0, 6, 24, 14, 12, 11, 2, 13, 16, 4, 7, 1, 21, 22, 20];
手动执行check,即可拿到flag
参考链接
#version 450
layout(local_size_x
=
1
, local_size_y
=
1
, local_size_z
=
1
)
in
;
const uint _80[
5
]
=
uint[](
1214346853u
,
558265710u
,
559376756u
,
1747010677u
,
1651008801u
);
layout(binding
=
0
, std430)
buffer
V
{
uint v[];
} _23;
void main()
{
uint cnt
=
gl_GlobalInvocationID.x
*
2u
;
uint
sum
=
0u
;
uint l
=
_23.v[cnt];
uint r
=
_23.v[cnt
+
1u
];
for
(
int
i
=
1
; i <
=
40
; i
+
+
)
{
l
+
=
((((((~(r << uint(
3
))) & (r >> uint(
5
))) | ((r << uint(
3
)) & (~(r >> uint(
5
))))) ^ (~r)) & ((r << uint(
3
)) ^ (r >> uint(
5
)))) ^ ((~((~(
sum
+
_80[
sum
&
4u
])) | (~((r >> uint(
3
)) & (r << uint(
2
))))))));
sum
+
=
1932555628u
;
r
+
=
((((((~(l << uint(
3
))) & (l >> uint(
5
))) | ((l << uint(
3
)) & (~(l >> uint(
5
))))) ^ (~l)) & ((l << uint(
3
)) ^ (l >> uint(
5
)))) ^ ((~((~(
sum
+
_80[(
sum
>> uint(
11
)) &
4u
])) | (~((l >> uint(
3
)) & (l << uint(
2
))))))));
}
_23.v[cnt]
=
l;
_23.v[cnt
+
1u
]
=
r;
}
#version 450
layout(local_size_x
=
1
, local_size_y
=
1
, local_size_z
=
1
)
in
;
const uint _80[
5
]
=
uint[](
1214346853u
,
558265710u
,
559376756u
,
1747010677u
,
1651008801u
);
layout(binding
=
0
, std430)
buffer
V
{
uint v[];
} _23;
void main()
{
uint cnt
=
gl_GlobalInvocationID.x
*
2u
;
uint
sum
=
0u
;
uint l
=
_23.v[cnt];
uint r
=
_23.v[cnt
+
1u
];
for
(
int
i
=
1
; i <
=
40
; i
+
+
)
{
l
+
=
((((((~(r << uint(
3
))) & (r >> uint(
5
))) | ((r << uint(
3
)) & (~(r >> uint(
5
))))) ^ (~r)) & ((r << uint(
3
)) ^ (r >> uint(
5
)))) ^ ((~((~(
sum
+
_80[
sum
&
4u
])) | (~((r >> uint(
3
)) & (r << uint(
2
))))))));
sum
+
=
1932555628u
;
r
+
=
((((((~(l << uint(
3
))) & (l >> uint(
5
))) | ((l << uint(
3
)) & (~(l >> uint(
5
))))) ^ (~l)) & ((l << uint(
3
)) ^ (l >> uint(
5
)))) ^ ((~((~(
sum
+
_80[(
sum
>> uint(
11
)) &
4u
])) | (~((l >> uint(
3
)) & (l << uint(
2
))))))));
}
_23.v[cnt]
=
l;
_23.v[cnt
+
1u
]
=
r;
}
#include <stdint.h>
#include <stdio.h>
// 解密函数
void
decrypt(uint32_t *v, uint32_t *k) {
uint32_t v0 = v[0], v1 = v[1], sum = 0, i;
/* set up */
uint32_t delta = 1932555628u;
/* a key schedule constant */
for
(i = 0; i < 40; i++) {
sum += delta;
}
for
(i = 0; i < 40; i++) {
/* basic cycle start */
v1 -=
((((((~(v0 << 3u)) & (v0 >> 5u)) | ((v0 << 3u) & (~(v0 >> 5u)))) ^
(~v0)) &
((v0 << 3u) ^ (v0 >> 5u))) ^
((~((~(sum + k[(sum >> 11u) & 4u])) | (~((v0 >> 3u) & (v0 << 2u)))))));
sum -= delta;
v0 -= ((((((~(v1 << 3u)) & (v1 >> 5u)) | ((v1 << 3u) & (~(v1 >> 5u)))) ^
(~v1)) &
((v1 << 3u) ^ (v1 >> 5u))) ^
((~((~(sum + k[sum & 4u])) | (~((v1 >> 3u) & (v1 << 2u)))))));
}
/* end cycle */
v[0] = v0;
v[1] = v1;
}
int
main() {
uint32_t ida_chars[] = {0x185B72AF, 0X631D2C6, 0XDE8B33CC, 0X31EBCD9F,
0X5DB8B33, 0XA8D77D0, 0X865C6111, 0XBF032335,
0X722228A5, 0XAD833A57, 0XB7C3456F};
uint32_t key[] = {1214346853u, 558265710u, 559376756u, 1747010677u,
1651008801u};
decrypt(ida_chars, key);
decrypt(ida_chars + 2, key);
decrypt(ida_chars + 4, key);
decrypt(ida_chars + 6, key);
decrypt(ida_chars + 8, key);
decrypt(ida_chars + 10, key);
decrypt(ida_chars + 12, key);
decrypt(ida_chars + 14, key);
printf
(
"%s"
, ida_chars);
return
0;
}
// :8�eCTF{Go0Od!!!You_4re_Vu1k@N_Mast3r^^ݙ�
#include <stdint.h>
#include <stdio.h>
// 解密函数
void
decrypt(uint32_t *v, uint32_t *k) {
uint32_t v0 = v[0], v1 = v[1], sum = 0, i;
/* set up */
uint32_t delta = 1932555628u;
/* a key schedule constant */
for
(i = 0; i < 40; i++) {
sum += delta;
}
for
(i = 0; i < 40; i++) {
/* basic cycle start */
v1 -=
((((((~(v0 << 3u)) & (v0 >> 5u)) | ((v0 << 3u) & (~(v0 >> 5u)))) ^
(~v0)) &
((v0 << 3u) ^ (v0 >> 5u))) ^
((~((~(sum + k[(sum >> 11u) & 4u])) | (~((v0 >> 3u) & (v0 << 2u)))))));
sum -= delta;
v0 -= ((((((~(v1 << 3u)) & (v1 >> 5u)) | ((v1 << 3u) & (~(v1 >> 5u)))) ^
(~v1)) &
((v1 << 3u) ^ (v1 >> 5u))) ^
((~((~(sum + k[sum & 4u])) | (~((v1 >> 3u) & (v1 << 2u)))))));
}
/* end cycle */
v[0] = v0;
v[1] = v1;
}
int
main() {
uint32_t ida_chars[] = {0x185B72AF, 0X631D2C6, 0XDE8B33CC, 0X31EBCD9F,
0X5DB8B33, 0XA8D77D0, 0X865C6111, 0XBF032335,
0X722228A5, 0XAD833A57, 0XB7C3456F};
uint32_t key[] = {1214346853u, 558265710u, 559376756u, 1747010677u,
1651008801u};
decrypt(ida_chars, key);
decrypt(ida_chars + 2, key);
decrypt(ida_chars + 4, key);
decrypt(ida_chars + 6, key);
decrypt(ida_chars + 8, key);
decrypt(ida_chars + 10, key);
decrypt(ida_chars + 12, key);
decrypt(ida_chars + 14, key);
printf
(
"%s"
, ida_chars);
return
0;
}
// :8�eCTF{Go0Od!!!You_4re_Vu1k@N_Mast3r^^ݙ�
import
string
import
subprocess
known_chars
=
"DubheCTF{Go0Od!!!You_4re_Vu1k@N_Mast3r^^"
# 已知的40位字符
for
ch
in
string.printable:
flag
=
known_chars
+
ch
+
"}"
with subprocess.Popen(
[
"./ezVK.exe"
], stdin
=
subprocess.PIPE, stdout
=
subprocess.PIPE
) as p:
stdout, _
=
p.communicate(
input
=
flag.encode())
if
"You Are GENIUS!!!"
in
stdout.decode():
print
(
"flag found:"
, flag)
exit(
0
)
# flag found: DubheCTF{Go0Od!!!You_4re_Vu1k@N_Mast3r^^_}
import
string
import
subprocess
known_chars
=
"DubheCTF{Go0Od!!!You_4re_Vu1k@N_Mast3r^^"
# 已知的40位字符
for
ch
in
string.printable:
flag
=
known_chars
+
ch
+
"}"
with subprocess.Popen(
[
"./ezVK.exe"
], stdin
=
subprocess.PIPE, stdout
=
subprocess.PIPE
) as p:
stdout, _
=
p.communicate(
input
=
flag.encode())
if
"You Are GENIUS!!!"
in
stdout.decode():
print
(
"flag found:"
, flag)
exit(
0
)
# flag found: DubheCTF{Go0Od!!!You_4re_Vu1k@N_Mast3r^^_}
function
_0x52fd86(parm) {
let salt = CryptoJS.enc.Hex.parse(
CryptoJS.SHA256(parm).toString(CryptoJS.enc.Hex)
),
iv_ = CryptoJS.enc.Hex.parse(
'fd3cb6c1be89457ba82919a33f02707c'
),
enc = CryptoJS.enc.Hex.parse(
'4f6b9161b29e59e2d94fa90529d745601473cb4203c02d9549eea6e322908d71e0472241d86f3821b3c96dd82937b04dcef80b9f68b23dd2371d2a56ef873ce857563eefc6f9057aa0cc5b41ff87477256f6b56ef342da815099d1217d301d03b76e4fae675d27bf95ca43154015b964'
),
flag = CryptoJS.AES.decrypt({ ciphertext: enc }, salt, {
iv: iv_,
padding: CryptoJS.pad.Pkcs7,
mode: CryptoJS.mode.CBC,
hasher: CryptoJS.algo.SHA256,
})
return
flag.toString(CryptoJS.enc.Utf8)
}
function
_0x52fd86(parm) {
let salt = CryptoJS.enc.Hex.parse(
CryptoJS.SHA256(parm).toString(CryptoJS.enc.Hex)
),
iv_ = CryptoJS.enc.Hex.parse(
'fd3cb6c1be89457ba82919a33f02707c'
),
enc = CryptoJS.enc.Hex.parse(
'4f6b9161b29e59e2d94fa90529d745601473cb4203c02d9549eea6e322908d71e0472241d86f3821b3c96dd82937b04dcef80b9f68b23dd2371d2a56ef873ce857563eefc6f9057aa0cc5b41ff87477256f6b56ef342da815099d1217d301d03b76e4fae675d27bf95ca43154015b964'
),
flag = CryptoJS.AES.decrypt({ ciphertext: enc }, salt, {
iv: iv_,
padding: CryptoJS.pad.Pkcs7,
mode: CryptoJS.mode.CBC,
hasher: CryptoJS.algo.SHA256,
})
return
flag.toString(CryptoJS.enc.Utf8)
}
attribute vec3 position;
varying
float
owO;
void main(void){
gl_Position
=
vec4(position.xy,
0.0
,
1.0
);
owO
=
position.z;
}
attribute vec3 position;
varying
float
owO;
void main(void){
gl_Position
=
vec4(position.xy,
0.0
,
1.0
);
owO
=
position.z;
}
#ifdef GL_ES
precision highp
float
;
/
/
设置为高精度浮点数
#endif
varying
float
owO;
/
/
顶点着色器传入
#define OvO 255.0
#define Ovo 128.0
#define OVO 23.0
float
OwO (
float
Owo,
float
OWO,
float
owO) {
OWO
=
floor(OWO
+
0.5
);
owO
=
floor(owO
+
0.5
);
return
mod(floor((floor(Owo)
+
0.5
)
/
exp2(OWO)), floor(
1.0
*
exp2(owO
-
OWO)
+
0.5
));
}
vec4 oWo (
float
Ow0) {
if
(Ow0
=
=
0.0
)
return
vec4(
0.0
);
float
Owo
=
Ow0 >
0.0
?
0.0
:
1.0
;
Ow0
=
abs
(Ow0);
float
OWO
=
floor(log2(Ow0));
float
oWo
=
OWO
+
OvO
-
Ovo;
OWO
=
((Ow0
/
exp2(OWO))
-
1.0
)
*
pow
(
2.0
, OVO);
float
owO
=
oWo
/
2.0
;
oWo
=
fract(owO)
+
fract(owO);
float
oWO
=
floor(owO);
owO
=
OwO(OWO,
0.0
,
8.0
)
/
OvO;
Ow0
=
OwO(OWO,
8.0
,
16.0
)
/
OvO;
OWO
=
(oWo
*
Ovo
+
OwO(OWO,
16.0
, OVO))
/
OvO;
Owo
=
(Owo
*
Ovo
+
oWO)
/
OvO;
return
vec4(owO, Ow0, OWO, Owo);
}
void main(){
gl_FragColor
=
oWo(owO);
/
/
RGBA
}
#ifdef GL_ES
precision highp
float
;
/
/
设置为高精度浮点数
#endif
varying
float
owO;
/
/
顶点着色器传入
#define OvO 255.0
#define Ovo 128.0
#define OVO 23.0
float
OwO (
float
Owo,
float
OWO,
float
owO) {
OWO
=
floor(OWO
+
0.5
);
owO
=
floor(owO
+
0.5
);
return
mod(floor((floor(Owo)
+
0.5
)
/
exp2(OWO)), floor(
1.0
*
exp2(owO
-
OWO)
+
0.5
));
}
vec4 oWo (
float
Ow0) {
if
(Ow0
=
=
0.0
)
return
vec4(
0.0
);
float
Owo
=
Ow0 >
0.0
?
0.0
:
1.0
;
Ow0
=
abs
(Ow0);
float
OWO
=
floor(log2(Ow0));
float
oWo
=
OWO
+
OvO
-
Ovo;
OWO
=
((Ow0
/
exp2(OWO))
-
1.0
)
*
pow
(
2.0
, OVO);
float
owO
=
oWo
/
2.0
;
oWo
=
fract(owO)
+
fract(owO);
float
oWO
=
floor(owO);
owO
=
OwO(OWO,
0.0
,
8.0
)
/
OvO;
Ow0
=
OwO(OWO,
8.0
,
16.0
)
/
OvO;
OWO
=
(oWo
*
Ovo
+
OwO(OWO,
16.0
, OVO))
/
OvO;
Owo
=
(Owo
*
Ovo
+
oWO)
/
OvO;
return
vec4(owO, Ow0, OWO, Owo);
}
void main(){
gl_FragColor
=
oWo(owO);
/
/
RGBA
}
#ifdef GL_ES
precision highp
float
;
/
/
设置为高精度浮点数
#endif
varying
float
vert_in;
/
/
顶点着色器传入,即owO
#define val_255 255.0
#define val_128 128.0
#define val_23 23.0
float
func1 (
float
parm1,
float
parm2,
float
vert_in) {
parm2
=
floor(parm2
+
0.5
);
vert_in
=
floor(vert_in
+
0.5
);
return
mod(floor((floor(parm1)
+
0.5
)
/
exp2(parm2)), floor(
1.0
*
exp2(vert_in
-
parm2)
+
0.5
));
}
vec4 func2 (
float
parm1) {
if
(parm1
=
=
0.0
)
return
vec4(
0.0
);
float
temp1
=
parm1 >
0.0
?
0.0
:
1.0
;
parm1
=
abs
(parm1);
float
temp2
=
floor(log2(parm1));
float
temp3
=
temp2
+
val_255
-
val_128;
temp2
=
((parm1
/
exp2(temp2))
-
1.0
)
*
pow
(
2.0
, val_23);
float
vert_in
=
temp3
/
2.0
;
temp3
=
fract(vert_in)
+
fract(vert_in);
float
temp4
=
floor(vert_in);
vert_in
=
func1(temp2,
0.0
,
8.0
)
/
val_255;
parm1
=
func1(temp2,
8.0
,
16.0
)
/
val_255;
temp2
=
(temp3
*
val_128
+
func1(temp2,
16.0
, val_23))
/
val_255;
temp1
=
(temp1
*
val_128
+
temp4)
/
val_255;
return
vec4(vert_in, parm1, temp2, temp1);
}
void main(){
gl_FragColor
=
func2(vert_in);
/
/
RGBA
}
#ifdef GL_ES
precision highp
float
;
/
/
设置为高精度浮点数
#endif
varying
float
vert_in;
/
/
顶点着色器传入,即owO
#define val_255 255.0
#define val_128 128.0
#define val_23 23.0
float
func1 (
float
parm1,
float
parm2,
float
vert_in) {
parm2
=
floor(parm2
+
0.5
);
vert_in
=
floor(vert_in
+
0.5
);
return
mod(floor((floor(parm1)
+
0.5
)
/
exp2(parm2)), floor(
1.0
*
exp2(vert_in
-
parm2)
+
0.5
));
}
vec4 func2 (
float
parm1) {
if
(parm1
=
=
0.0
)
return
vec4(
0.0
);
float
temp1
=
parm1 >
0.0
?
0.0
:
1.0
;
parm1
=
abs
(parm1);
float
temp2
=
floor(log2(parm1));
float
temp3
=
temp2
+
val_255
-
val_128;
temp2
=
((parm1
/
exp2(temp2))
-
1.0
)
*
pow
(
2.0
, val_23);
float
vert_in
=
temp3
/
2.0
;
temp3
=
fract(vert_in)
+
fract(vert_in);
float
temp4
=
floor(vert_in);
vert_in
=
func1(temp2,
0.0
,
8.0
)
/
val_255;
parm1
=
func1(temp2,
8.0
,
16.0
)
/
val_255;
temp2
=
(temp3
*
val_128
+
func1(temp2,
16.0
, val_23))
/
val_255;
temp1
=
(temp1
*
val_128
+
temp4)
/
val_255;
return
vec4(vert_in, parm1, temp2, temp1);
}
void main(){
gl_FragColor
=
func2(vert_in);
/
/
RGBA
}
const _0x464c09 = (
function
() {
let _0x451913 =
true
return
function
(_0x258426, _0x4b7b8d) {
const _0x1bb18e = _0x451913
?
function
() {
if
(_0x4b7b8d) {
const _0x2d8886 = _0x4b7b8d.apply(_0x258426, arguments)
return
(_0x4b7b8d =
null
), _0x2d8886
}
}
:
function
() { }
return
(_0x451913 =
false
), _0x1bb18e
}
})(),
_0x4c494b = _0x464c09(
this
,
function
() {
return
_0x4c494b
.toString()
.search(_0x9bd70f.dnYkL)
.toString()
.constructor(_0x4c494b)
.search(_0x9bd70f.dnYkL)
})
_0x4c494b()
window.addEventListener(
'load'
, load)
var
draw_canvas, calc_canvas
function
load() {
let draw_canvas_vert =
'\n attribute vec3 position;\n uniform mat4 mvpMatrix;\n varying vec2 vPosition;\n\n void main(void){\n gl_Position = mvpMatrix * vec4(position, 1.0);\n vPosition = position.xy;\n }\n '
,
draw_canvas_frag =
'\n#ifdef GL_ES\nprecision mediump float;\n#endif \n\nuniform float u_time;\nuniform vec2 u_resolution;\nvarying vec2 vPosition;\n\nvec3 hash(vec2 seed){\n vec3 p3 = fract(float(seed.x + seed.y*86.) * vec3(.1051, .1020, .0983));\n\tp3 += dot(p3, p3.yzx + 33.33);\n return fract(p3);\n}\n\nvec3 layer(float scale, vec2 uv, float time){\n // uv coord in cell\n vec2 scaled_uv = uv * scale - 0.5;\n vec2 uv0 = fract( scaled_uv ) - 0.5;\n // cell id\n vec2 cell_id = scaled_uv - fract(scaled_uv);\n \n \n vec3 col = vec3(0);\n float speed = 1.5;\n // distance to a spinning random point in the cell (also surrounding cells)\n vec3 seed = hash(cell_id);\n\n float radiance = seed.x + time * seed.y;\n vec2 center_of_star = vec2(sin(radiance), cos(radiance))*0.3;\n\n // radial distort effect for star shine\n vec2 v_to_star = uv0 - center_of_star;\n float star_radiance = atan(v_to_star.x/v_to_star.y);\n float star_spark_1 = sin(star_radiance*14.+radiance*6.);\n float star_spark_2 = sin(star_radiance*8.-radiance*2.);\n float stars = length(v_to_star) * (5.+star_spark_1+star_spark_2) * 0.03;\n col += smoothstep(length(seed) * 0.01, 0., stars);\n return col;\n}\nvoid main()\n{ // center global uv from -1 to 1\n vec2 virtual_resolution = vec2(2.0, 2.0);\n vec2 uv = (vPosition * 2. - virtual_resolution.xy) / virtual_resolution.y;\n vec3 col = vec3(0.);//vColor.xyz;\n \n const float layer_count = 6.5;\n for(float i = 0.0; i < layer_count; i+=1.){\n float rotate_speed = u_time*0.4;\n float scale = mod(i - rotate_speed, layer_count)*1.5;\n vec2 offseted_uv = uv + vec2(sin(rotate_speed), cos(rotate_speed));\n vec3 layer_col = layer(scale, offseted_uv, u_time + i*1.5);\n \n // we want the star to smoothly show up\n float max_scale = layer_count * 1.5;\n float color_amp = smoothstep(0., 1., smoothstep(max_scale, 0., scale));\n col += layer_col * color_amp;\n }\n // blue background\n col += vec3(0., 0., -0.15) * (uv.y - 0.7) * pow(length(uv), 0.5);\n gl_FragColor = vec4(col, 1.);\n}\n '
,
calc_canvas_vert =
`\nattribute vec3 position;
varying float owO;\n \n
void main(void){\n
gl_Position = vec4(position.xy, 0.0, 1.0);\n
owO = position.z;\n }\n `,
calc_canvas_frag =
`\n
#ifdef GL_ES\n
precision highp float;\n
#endif \n
varying float owO;\n
#define OvO 255.0\n
#define Ovo 128.0\n
#define OVO 23.0\n\n
float OwO (float Owo, float OWO, float owO) {
\n OWO = floor(OWO + 0.5);
owO = floor(owO + 0.5);
\n
return
mod(floor((floor(Owo) + 0.5) / exp2(OWO)), floor(1.0*exp2(owO - OWO) + 0.5));
\n}\n
vec4 oWo (float Ow0) {
\n
if
(Ow0 == 0.0)
return
vec4(0.0); \n
float Owo = Ow0 > 0.0 ? 0.0 : 1.0; \n
Ow0 = abs(Ow0); \n
float OWO = floor(log2(Ow0)); \n
float oWo = OWO + OvO - Ovo; \n
OWO = ((Ow0 / exp2(OWO)) - 1.0) * pow(2.0, OVO);\n
float owO = oWo / 2.0; \n
oWo = fract(owO) + fract(owO); \n
float oWO = floor(owO); \n
owO = OwO(OWO, 0.0, 8.0) / OvO; \n
Ow0 = OwO(OWO, 8.0, 16.0) / OvO; \n
OWO = (oWo * Ovo + OwO(OWO, 16.0, OVO)) / OvO; \n
Owo = (Owo * Ovo + oWO) / OvO; \n
return
vec4(owO, Ow0, OWO, Owo); \n
}\n\nvoid main()\n{
\n gl_FragColor = oWo(owO);\n
}\n `
draw_canvas =
new
ShaderManager(
'canvas'
, 0, 0, draw_canvas_vert, draw_canvas_frag,
true
)
draw_canvas.render()
calc_canvas =
new
ShaderManager(
'canvas-calc'
,
650,
650,
calc_canvas_vert,
calc_canvas_frag,
false
)
calc_canvas.render()
let pattern_container = document.getElementById(
'pattern-container'
),
lines = document.getElementById(
'lines'
),
latest_selected_dot =
null
,
line =
null
,
selected =
false
,
selected_dot = []
pattern_container.childNodes.forEach((dot) => {
if
(!dot.classList) {
return
}
if
(!dot.classList.contains(
'dot'
)) {
return
}
dot.addEventListener(
'mousedown'
, (_0x5be741) => {
selected_dot.forEach((dot) => {
dot.classList.remove(
'selected'
)
dot.classList.remove(
'select'
)
dot.classList.remove(
'lose'
)
dot.classList.remove(
'win'
)
})
lines.innerHTML =
''
selected_dot = []
selected =
true
dot.classList.add(
'select'
)
line = document.createElementNS(
'http://www.w3.org/2000/svg'
,
'line'
)
line.setAttribute(
'x1'
,
dot.offsetLeft + dot.offsetWidth / 2
)
line.setAttribute(
'y1'
,
dot.offsetTop + dot.offsetHeight / 2
)
line.setAttribute(
'x2'
,
dot.offsetLeft + dot.offsetWidth / 2
)
line.setAttribute(
'y2'
,
dot.offsetTop + dot.offsetHeight / 2
)
line.setAttribute(
'stroke'
,
'white'
)
line.setAttribute(
'stroke-width'
,
'5'
)
lines.appendChild(line)
//画线,但是头尾是同一个点
selected_dot.push(dot)
latest_selected_dot = dot
})
dot.addEventListener(
'mouseover'
, (_0x1cae46) => {
//鼠标移入
if
(!selected) {
return
}
if
(dot.classList.contains(
'selected'
)) {
return
}
if
(dot.classList.contains(
'select'
)) {
return
}
line &&
(line.setAttribute(
'x2'
,
dot.offsetLeft + dot.offsetWidth / 2
),
line.setAttribute(
'y2'
,
dot.offsetTop + dot.offsetHeight / 2
),
latest_selected_dot.classList.add(
'selected'
),
latest_selected_dot.classList.remove(
'select'
))
// 把线从上一个点连到当前点
dot.classList.add(
'select'
)
line = document.createElementNS(
'http://www.w3.org/2000/svg'
,
'line'
)
line.setAttribute(
'x1'
,
dot.offsetLeft + dot.offsetWidth / 2
)
line.setAttribute(
'y1'
,
dot.offsetTop + dot.offsetHeight / 2
)
line.setAttribute(
'x2'
,
dot.offsetLeft + dot.offsetWidth / 2
)
line.setAttribute(
'y2'
,
dot.offsetTop + dot.offsetHeight / 2
)
line.setAttribute(
'stroke'
,
'white'
)
line.setAttribute(
'stroke-width'
,
'5'
)
lines.appendChild(line)
selected_dot.push(dot)
latest_selected_dot = dot
})
})
pattern_container.addEventListener(
'mousemove'
, (pos) => {
if
(!selected) {
return
}
latest_selected_dot &&
line &&
(line.setAttribute(
'x2'
,
pos.clientX - pattern_container.getBoundingClientRect().left
),
line.setAttribute(
'y2'
,
pos.clientY - pattern_container.getBoundingClientRect().top
))
})
// 连线跟随鼠标
pattern_container.addEventListener(
'mouseup'
, (_0x3584c1) => {
//鼠标松开
if
(latest_selected_dot && line) {
line.setAttribute(
'x2'
,
latest_selected_dot.offsetLeft + latest_selected_dot.offsetWidth / 2
)
line.setAttribute(
'y2'
,
latest_selected_dot.offsetTop + latest_selected_dot.offsetHeight / 2
)
latest_selected_dot.classList.add(
'selected'
)
latest_selected_dot =
null
let flag = check_flag(
selected_dot.map((dot) => parseInt(dot.dataset.number))
// 传入选中的点的顺序
)
if
(flag !==
null
) {
selected_dot.forEach((dot) => {
dot.classList.add(
'win'
)
})
let flag_p = document.getElementById(
'flag'
)
flag_p.innerText = flag
}
else
{
selected_dot.forEach((dot) => {
dot.classList.add(
'lose'
)
})
}
}
selected =
false
})
}
function
abs(num) {
return
Math.abs(num)
}
const _0xdf21a4 = async (_0x5c1638) => {
const _0x4f0cab =
new
TextEncoder().encode(_0x5c1638),
_0x336245 = await window.crypto.subtle.digest(_0x37cc4d.tNPCS, _0x4f0cab),
_0x587059 = Array.from(
new
Uint8Array(_0x336245)),
_0x49519a = _0x587059
.map((_0x29f99c) => _0x29f99c.toString(16).padStart(2,
'0'
))
.join(
''
)
return
_0x49519a
}
function
check_flag(index_list) {
let _0x526465 = calc_canvas.wtf(index_list[19], index_list[3], index_list[5]) * 25,
_0x27d483 = calc_canvas.wtf(index_list[7], index_list[20], index_list[18]) * 25,
_0x47edd7 = calc_canvas.wtf(index_list[11], index_list[22], index_list[18]) * 25,
_0x3c8060 = calc_canvas.wtf(index_list[5], index_list[17], index_list[2]) * 25,
_0x315313 = calc_canvas.wtf(index_list[20], index_list[13], index_list[5]) * 25,
_0x3cef24 = calc_canvas.wtf(index_list[11], index_list[1], index_list[21]) * 25,
_0x2ee445 = calc_canvas.wtf(index_list[8], index_list[11], index_list[1]) * 25,
_0x5e280a = calc_canvas.wtf(index_list[9], index_list[5], index_list[4]) * 25,
_0x5f6c26 = calc_canvas.wtf(index_list[17], index_list[9], index_list[21]) * 25,
_0x13e7aa = calc_canvas.wtf(index_list[23], index_list[9], index_list[20]) * 25,
_0x9d682e = calc_canvas.wtf(index_list[16], index_list[5], index_list[4]) * 25,
_0x277f3c = calc_canvas.wtf(index_list[16], index_list[14], index_list[13]) * 25,
_0x2f58be = calc_canvas.wtf(index_list[5], index_list[6], index_list[10]) * 25,
_0x5a6698 = calc_canvas.wtf(index_list[2], index_list[11], index_list[5]) * 25,
_0x52d3ed = calc_canvas.wtf(index_list[11], index_list[3], index_list[1]) * 25,
_0x4320e6 = calc_canvas.wtf(index_list[12], index_list[3], index_list[10]) * 25,
_0xf9ef4b = calc_canvas.wtf(index_list[14], index_list[1], index_list[9]) * 25,
_0x429aaf = calc_canvas.wtf(index_list[18], index_list[11], index_list[17]) * 25,
_0x1a4487 = calc_canvas.wtf(index_list[12], index_list[15], index_list[2]) * 25,
_0x4c135d = calc_canvas.wtf(index_list[22], index_list[0], index_list[19]) * 25,
_0x5c13fb = 0
_0x5c13fb += abs(
0.3837876686390533 - calc_canvas.gtfo(_0x3cef24, _0xf9ef4b, _0x5f6c26, 16, 21)
)
_0x5c13fb += abs(
0.21054889940828397 - calc_canvas.gtfo(_0x52d3ed, _0x3cef24, _0x2ee445, 8, 2)
)
_0x5c13fb += abs(
0.475323349112426 - calc_canvas.gtfo(_0x3cef24, _0x429aaf, _0x2f58be, 0, 20)
)
_0x5c13fb += abs(
0.6338370887573964 - calc_canvas.gtfo(_0x3c8060, _0x27d483, _0x2f58be, 8, 4)
)
_0x5c13fb += abs(
0.4111607928994082 - calc_canvas.gtfo(_0x47edd7, _0x52d3ed, _0x4320e6, 23, 1)
)
_0x5c13fb += abs(
0.7707577751479291 - calc_canvas.gtfo(_0x429aaf, _0x3c8060, _0x277f3c, 20, 6)
)
_0x5c13fb += abs(
0.7743081420118344 - calc_canvas.gtfo(_0x13e7aa, _0x5a6698, _0x3c8060, 9, 10)
)
_0x5c13fb += abs(
0.36471487573964495 - calc_canvas.gtfo(_0x5f6c26, _0x526465, _0x315313, 18, 8)
)
_0x5c13fb += abs(
0.312678449704142 - calc_canvas.gtfo(_0x4320e6, _0x13e7aa, _0x429aaf, 0, 17)
)
_0x5c13fb += abs(
0.9502808165680473 - calc_canvas.gtfo(_0x1a4487, _0x13e7aa, _0x3c8060, 22, 10)
)
_0x5c13fb += abs(
0.5869052899408282 - calc_canvas.gtfo(_0x2f58be, _0x5e280a, _0x47edd7, 14, 10)
)
_0x5c13fb += abs(
0.9323389467455623 - calc_canvas.gtfo(_0x429aaf, _0x47edd7, _0x2f58be, 12, 7)
)
_0x5c13fb += abs(
0.4587118106508875 - calc_canvas.gtfo(_0x2ee445, _0x5a6698, _0x47edd7, 4, 21)
)
_0x5c13fb += abs(
0.14484472189349107 - calc_canvas.gtfo(_0x4320e6, _0x13e7aa, _0x52d3ed, 7, 15)
)
_0x5c13fb += abs(
0.7255550059171598 - calc_canvas.gtfo(_0x3cef24, _0x429aaf, _0x1a4487, 9, 23)
)
_0x5c13fb += abs(
0.5031261301775147 - calc_canvas.gtfo(_0x3c8060, _0x47edd7, _0x52d3ed, 7, 1)
)
_0x5c13fb += abs(
0.1417352189349112 - calc_canvas.gtfo(_0x2ee445, _0x52d3ed, _0x5f6c26, 16, 14)
)
_0x5c13fb += abs(
0.5579334437869822 - calc_canvas.gtfo(_0x52d3ed, _0x47edd7, _0x1a4487, 19, 11)
)
_0x5c13fb += abs(
0.48502262721893485 -
calc_canvas.gtfo(_0x9d682e, _0x315313, _0x5e280a, 23, 18)
)
_0x5c13fb += abs(
0.5920916568047336 - calc_canvas.gtfo(_0x5e280a, _0x5f6c26, _0x27d483, 19, 6)
)
_0x5c13fb += abs(
0.7222713017751479 - calc_canvas.gtfo(_0xf9ef4b, _0x47edd7, _0x315313, 8, 16)
)
_0x5c13fb += abs(
0.12367382248520711 - calc_canvas.gtfo(_0x9d682e, _0x4320e6, _0x2f58be, 9, 5)
)
_0x5c13fb += abs(
0.4558028402366864 - calc_canvas.gtfo(_0x277f3c, _0x9d682e, _0x47edd7, 10, 2)
)
_0x5c13fb += abs(
0.8537692426035504 - calc_canvas.gtfo(_0x429aaf, _0x13e7aa, _0x5a6698, 4, 11)
)
_0x5c13fb += abs(
0.9618170650887574 - calc_canvas.gtfo(_0x2f58be, _0x1a4487, _0x429aaf, 15, 2)
)
_0x5c13fb += abs(
0.22088933727810647 - calc_canvas.gtfo(_0x526465, _0x5e280a, _0xf9ef4b, 10, 5)
)
_0x5c13fb += abs(
0.4302783550295858 - calc_canvas.gtfo(_0xf9ef4b, _0x277f3c, _0x3cef24, 14, 2)
)
_0x5c13fb += abs(
0.6262803313609467 - calc_canvas.gtfo(_0x4c135d, _0x52d3ed, _0x47edd7, 17, 22)
)
if
(_0x5c13fb > 0.00001) {
return
null
}
s =
''
s += Math.round(
calc_canvas.wtf(index_list[4], index_list[2], index_list[22]) * 100000
).toString()
s += Math.round(
calc_canvas.wtf(index_list[17], index_list[9], index_list[14]) * 100000
).toString()
s += Math.round(
calc_canvas.wtf(index_list[4], index_list[13], index_list[7]) * 100000
).toString()
s += Math.round(
calc_canvas.wtf(index_list[4], index_list[20], index_list[23]) * 100000
).toString()
s += Math.round(
calc_canvas.wtf(index_list[5], index_list[7], index_list[12]) * 100000
).toString()
s += Math.round(
calc_canvas.wtf(index_list[20], index_list[19], index_list[4]) * 100000
).toString()
s += Math.round(
calc_canvas.wtf(index_list[17], index_list[6], index_list[19]) * 100000
).toString()
s += Math.round(
calc_canvas.wtf(index_list[6], index_list[21], index_list[18]) * 100000
).toString()
s += Math.round(
calc_canvas.wtf(index_list[4], index_list[3], index_list[8]) * 100000
).toString()
s += Math.round(
calc_canvas.wtf(index_list[11], index_list[7], index_list[14]) * 100000
).toString()
s += Math.round(
calc_canvas.wtf(index_list[9], index_list[2], index_list[13]) * 100000
).toString()
s += Math.round(
calc_canvas.wtf(index_list[22], index_list[10], index_list[3]) * 100000
).toString()
s += Math.round(
calc_canvas.wtf(index_list[15], index_list[22], index_list[13]) * 100000
).toString()
s += Math.round(
calc_canvas.wtf(index_list[16], index_list[12], index_list[9]) * 100000
).toString()
s += Math.round(
calc_canvas.wtf(index_list[14], index_list[8], index_list[17]) * 100000
).toString()
s += Math.round(
calc_canvas.wtf(index_list[1], index_list[18], index_list[6]) * 100000
).toString()
s += Math.round(
calc_canvas.wtf(index_list[10], index_list[11], index_list[3]) * 100000
).toString()
s += Math.round(
calc_canvas.wtf(index_list[8], index_list[12], index_list[5]) * 100000
).toString()
s += Math.round(
calc_canvas.wtf(index_list[1], index_list[3], index_list[12]) * 100000
).toString()
s += Math.round(
calc_canvas.wtf(index_list[9], index_list[13], index_list[7]) * 100000
).toString()
s += Math.round(
calc_canvas.gtfo(
index_list[22],
index_list[13],
index_list[5],
index_list[4],
index_list[7]
) * 100000
).toString()
s += Math.round(
calc_canvas.gtfo(
index_list[10],
index_list[14],
index_list[17],
index_list[23],
index_list[11]
) * 100000
).toString()
s += Math.round(
calc_canvas.gtfo(
index_list[23],
index_list[20],
index_list[6],
index_list[1],
index_list[3]
) * 100000
).toString()
s += Math.round(
calc_canvas.gtfo(
index_list[15],
index_list[12],
index_list[2],
index_list[13],
index_list[9]
) * 100000
).toString()
s += Math.round(
calc_canvas.gtfo(
index_list[16],
index_list[20],
index_list[6],
index_list[5],
index_list[18]
) * 100000
).toString()
s += Math.round(
calc_canvas.gtfo(
index_list[3],
index_list[6],
index_list[7],
index_list[8],
index_list[23]
) * 100000
).toString()
s += Math.round(
calc_canvas.gtfo(
index_list[21],
index_list[9],
index_list[10],
index_list[3],
index_list[22]
) * 100000
).toString()
s += Math.round(
calc_canvas.gtfo(
index_list[14],
index_list[6],
index_list[15],
index_list[12],
index_list[19]
) * 100000
).toString()
s += Math.round(
calc_canvas.gtfo(
index_list[13],
index_list[19],
index_list[22],
index_list[23],
index_list[1]
) * 100000
).toString()
s += Math.round(
calc_canvas.gtfo(
index_list[21],
index_list[2],
index_list[9],
index_list[0],
index_list[19]
) * 100000
).toString()
s += Math.round(
calc_canvas.gtfo(
index_list[5],
index_list[19],
index_list[21],
index_list[14],
index_list[6]
) * 100000
).toString()
s += Math.round(
calc_canvas.gtfo(
index_list[16],
index_list[15],
index_list[20],
index_list[13],
index_list[3]
) * 100000
).toString()
s += Math.round(
calc_canvas.gtfo(
index_list[20],
index_list[15],
index_list[10],
index_list[21],
index_list[6]
) * 100000
).toString()
s += Math.round(
calc_canvas.gtfo(
index_list[7],
index_list[1],
index_list[21],
index_list[20],
index_list[3]
) * 100000
).toString()
s += Math.round(
calc_canvas.gtfo(
index_list[9],
index_list[20],
index_list[1],
index_list[10],
index_list[6]
) * 100000
).toString()
s += Math.round(
calc_canvas.gtfo(
index_list[10],
index_list[2],
index_list[1],
index_list[16],
index_list[4]
) * 100000
).toString()
s += Math.round(
calc_canvas.gtfo(
index_list[15],
index_list[5],
index_list[20],
index_list[19],
index_list[8]
) * 100000
).toString()
s += Math.round(
calc_canvas.gtfo(
index_list[20],
index_list[8],
index_list[21],
index_list[10],
index_list[12]
) * 100000
).toString()
s += Math.round(
calc_canvas.gtfo(
index_list[19],
index_list[5],
index_list[4],
index_list[2],
index_list[22]
) * 100000
).toString()
s += Math.round(
calc_canvas.gtfo(
index_list[10],
index_list[20],
index_list[14],
index_list[9],
index_list[7]
) * 100000
).toString()
let flag = get_flag(s)
return
(
(s += Math.round(
calc_canvas.gtfo(
index_list[5],
index_list[15],
index_list[9],
index_list[13],
index_list[16]
) * 100000
).toString()),
(s += Math.round(
calc_canvas.gtfo(
index_list[20],
index_list[8],
index_list[11],
index_list[22],
index_list[23]
) * 100000
).toString()),
(s += Math.round(
calc_canvas.gtfo(
index_list[22],
index_list[3],
index_list[1],
index_list[17],
index_list[15]
) * 100000
).toString()),
(s += Math.round(
calc_canvas.gtfo(
index_list[4],
index_list[8],
index_list[14],
index_list[3],
index_list[17]
) * 100000
).toString()),
(s += Math.round(
calc_canvas.gtfo(
index_list[12],
index_list[6],
index_list[11],
index_list[10],
index_list[15]
) * 100000
).toString()),
(s += Math.round(
calc_canvas.gtfo(
index_list[13],
index_list[5],
index_list[2],
index_list[4],
index_list[9]
) * 100000
).toString()),
(s += Math.round(
calc_canvas.gtfo(
index_list[21],
index_list[12],
index_list[19],
index_list[11],
index_list[20]
) * 100000
).toString()),
(s += Math.round(
calc_canvas.gtfo(
index_list[13],
index_list[11],
index_list[18],
index_list[12],
index_list[20]
) * 100000
).toString()),
(s += Math.round(
calc_canvas.gtfo(
index_list[11],
index_list[2],
index_list[8],
index_list[3],
index_list[16]
) * 100000
).toString()),
(s += Math.round(
calc_canvas.gtfo(
index_list[16],
index_list[1],
index_list[5],
index_list[4],
index_list[22]
) * 100000
).toString()),
(s += Math.round(
calc_canvas.gtfo(
index_list[0],
index_list[3],
index_list[12],
index_list[10],
index_list[1]
) * 100000
).toString()),
(s += Math.round(
calc_canvas.gtfo(
index_list[19],
index_list[22],
index_list[17],
index_list[14],
index_list[13]
) * 100000
).toString()),
(s += Math.round(
calc_canvas.gtfo(
index_list[14],
index_list[2],
index_list[10],
index_list[18],
index_list[16]
) * 100000
).toString()),
(s += Math.round(
calc_canvas.gtfo(
index_list[21],
index_list[0],
index_list[18],
index_list[19],
index_list[4]
) * 100000
).toString()),
(s += Math.round(
calc_canvas.gtfo(
index_list[22],
index_list[12],
index_list[9],
index_list[16],
index_list[17]
) * 100000
).toString()),
(s += Math.round(
calc_canvas.gtfo(
index_list[4],
index_list[18],
index_list[15],
index_list[0],
index_list[14]
) * 100000
).toString()),
(s += Math.round(
calc_canvas.gtfo(
index_list[9],
index_list[5],
index_list[19],
index_list[20],
index_list[12]
) * 100000
).toString()),
(s += Math.round(
calc_canvas.gtfo(
index_list[10],
index_list[6],
index_list[20],
index_list[11],
index_list[5]
) * 100000
).toString()),
(s += Math.round(
calc_canvas.gtfo(
index_list[1],
index_list[11],
index_list[22],
index_list[13],
index_list[9]
) * 100000
).toString()),
(s += Math.round(
calc_canvas.gtfo(
index_list[1],
index_list[19],
index_list[10],
index_list[0],
index_list[18]
) * 100000
).toString()),
flag
)
}
function
get_flag(parm) {
let salt = CryptoJS.enc.Hex.parse(
CryptoJS.SHA256(parm).toString(CryptoJS.enc.Hex)
),
iv_ = CryptoJS.enc.Hex.parse(
'fd3cb6c1be89457ba82919a33f02707c'
),
enc = CryptoJS.enc.Hex.parse(
'4f6b9161b29e59e2d94fa90529d745601473cb4203c02d9549eea6e322908d71e0472241d86f3821b3c96dd82937b04dcef80b9f68b23dd2371d2a56ef873ce857563eefc6f9057aa0cc5b41ff87477256f6b56ef342da815099d1217d301d03b76e4fae675d27bf95ca43154015b964'
),
flag = CryptoJS.AES.decrypt({ ciphertext: enc }, salt, {
iv: iv_,
padding: CryptoJS.pad.Pkcs7,
mode: CryptoJS.mode.CBC,
hasher: CryptoJS.algo.SHA256,
})
return
flag.toString(CryptoJS.enc.Utf8)
}
class ShaderManager {
constructor(
canvas_id,
_width,
_height,
vert,
frag,
render_now
) {
this
.canvas = document.getElementById(canvas_id)
_width != 0 && _height != 0
? ((
this
.canvas.width = _width), (
this
.canvas.height = _height))
: ((
this
.canvas.width = window.innerWidth),
(
this
.canvas.height = window.innerHeight))
this
.w =
this
.canvas.width
this
.h =
this
.canvas.height
this
.d = [
4, 20, 23, 13, 11, 0, 15, 1, 14, 21, 9, 19, 8, 3, 17, 24, 16, 6, 22, 10,
7, 18, 2, 5, 12,
]
this
.timeLoad = performance.now()
this
.gl =
this
.canvas.getContext(
'webgl2'
)
this
.gl.getExtension(
'EXT_color_buffer_float'
)
this
.v_shader =
this
.create_shader(vert,
'OuO'
)
this
.f_shader =
this
.create_shader(frag,
'>w<'
)
this
.prg =
this
.create_program(
this
.v_shader,
this
.f_shader)
let _this =
this
function
_0x52ad9c() {
_this.render()
_this.animationFrameRequest = window.requestAnimationFrame(_0x52ad9c)
}
return
render_now && _0x52ad9c(),
this
}
[
'wtf'
](parm1, parm2, parm3) {
this
.gl.clearColor(0, 0, 0, 1)
this
.gl.clearDepth(1)
this
.gl.clear(
this
.gl.COLOR_BUFFER_BIT |
this
.gl.DEPTH_BUFFER_BIT)
const _0x4b856b =
this
.gl.getAttribLocation(
this
.prg,
'position'
),
position_array = [
-1,
-1,
((parm1 % 1) +
this
.d[~~parm1]) / 25,
-1,
1,
((parm2 % 1) +
this
.d[~~parm2]) / 25,
1,
1,
((parm2 % 1) +
this
.d[~~parm2]) / 25,
-1,
-1,
((parm1 % 1) +
this
.d[~~parm1]) / 25,
1,
1,
((parm2 % 1) +
this
.d[~~parm2]) / 25,
1,
-1,
((parm1 % 1) +
this
.d[~~parm1]) / 25,
],
_0x3e2e26 =
this
.create_vbo(position_array)
this
.gl.bindBuffer(
this
.gl.ARRAY_BUFFER, _0x3e2e26)
this
.gl.enableVertexAttribArray(_0x4b856b)
this
.gl.vertexAttribPointer(_0x4b856b, 3,
this
.gl.FLOAT,
false
, 0, 0)
this
.gl.useProgram(
this
.prg)
this
.gl.drawArrays(
this
.gl.TRIANGLES, 0, 6)
this
.gl.flush()
const _0x2fa9a7 =
new
Uint8Array(4)
this
.gl.readPixels(
this
.w / 2,
(((parm3 % 1) +
this
.d[~~parm3]) *
this
.h) / 25,
1,
1,
this
.gl.RGBA,
this
.gl.UNSIGNED_BYTE,
_0x2fa9a7
)
let _0x511406 =
new
Float32Array(_0x2fa9a7.buffer)
return
_0x511406[0].toFixed(15)
}
[
'gtfo'
](parm1, parm2, parm3, parm4, parm5) {
this
.gl.clearColor(0, 0, 0, 1)
this
.gl.clearDepth(1)
this
.gl.clear(
this
.gl.COLOR_BUFFER_BIT |
this
.gl.DEPTH_BUFFER_BIT)
const _0x16760a =
this
.gl.getAttribLocation(
this
.prg,
'position'
),
_0x13e5e0 = [
-1,
-1,
((parm1 % 1) +
this
.d[~~parm1]) / 25,
3,
-1,
((parm2 % 1) +
this
.d[~~parm2]) / 25,
-1,
3,
((parm3 % 1) +
this
.d[~~parm3]) / 25,
],
_0x49be08 =
this
.create_vbo(_0x13e5e0)
this
.gl.bindBuffer(
this
.gl.ARRAY_BUFFER, _0x49be08)
this
.gl.enableVertexAttribArray(_0x16760a)
this
.gl.vertexAttribPointer(_0x16760a, 3,
this
.gl.FLOAT,
false
, 0, 0)
this
.gl.useProgram(
this
.prg)
this
.gl.drawArrays(
this
.gl.TRIANGLES, 0, 3)
this
.gl.flush()
const _0x3da8ae =
new
Uint8Array(4)
this
.gl.readPixels(
(((parm4 % 1) +
this
.d[~~parm4]) *
this
.w) / 25,
(((parm5 % 1) +
this
.d[~~parm5]) *
this
.h) / 25,
1,
1,
this
.gl.RGBA,
this
.gl.UNSIGNED_BYTE,
_0x3da8ae
)
let _0x2e76ac =
new
Float32Array(_0x3da8ae.buffer)
return
_0x2e76ac[0].toFixed(15)
}
[
'render'
]() {
this
.gl.clearColor(0, 0, 0, 1)
this
.gl.clearDepth(1)
this
.gl.clear(
this
.gl.COLOR_BUFFER_BIT |
this
.gl.DEPTH_BUFFER_BIT)
let _0x39f658 = performance.now()
this
.timeDelta = (_0x39f658 -
this
.timePrev) / 1000
this
.timePrev = _0x39f658
const _0x18111e =
new
Array(2)
_0x18111e[0] =
this
.gl.getAttribLocation(
this
.prg,
'position'
)
const _0x15ddf2 =
new
Array(2)
_0x15ddf2[0] = 3
_0x15ddf2[1] = 4
const _0x2626af = [
3, 8, 0, 7, -3, 5, 3, -8, 0, 3, 8, 0, 7, -3, 5, 7, 3, 5, 3, 8, 0, -3,
-8, 0, 3, -8, 0, 3, 8, 0, -3, -8, 0, -3, 8, 0, -3, 8, 0, -7, -3, 5, -3,
-8, 0, -3, 8, 0, -7, -3, 5, -7, 3, 5,
],
_0x1ebfe3 =
this
.create_vbo(_0x2626af)
this
.gl.bindBuffer(
this
.gl.ARRAY_BUFFER, _0x1ebfe3)
this
.gl.enableVertexAttribArray(_0x18111e[0])
this
.gl.vertexAttribPointer(
_0x18111e[0],
_0x15ddf2[0],
this
.gl.FLOAT,
false
,
0,
0
)
const _0x570653 =
new
matIV(),
_0x5a4b24 = _0x570653.identity(_0x570653.create()),
_0x5f594b = _0x570653.identity(_0x570653.create()),
_0x15df66 = _0x570653.identity(_0x570653.create()),
_0x28d80f = _0x570653.identity(_0x570653.create()),
_0xf54bc7 = (_0x39f658 -
this
.timeLoad) / 1000,
_0x404188 = [
Math.sin(Math.sin(_0xf54bc7) / 3),
Math.cos(Math.sin(_0xf54bc7) / 3),
0,
]
_0x570653.lookAt([0, 0, 5], [0, 0, 0], _0x404188, _0x5f594b)
_0x570653.perspective(
90,
this
.canvas.width /
this
.canvas.height,
0.1,
100,
_0x15df66
)
_0x570653.multiply(_0x15df66, _0x5f594b, _0x28d80f)
_0x570653.multiply(_0x28d80f, _0x5a4b24, _0x28d80f)
const _0x4d0a27 =
this
.gl.getUniformLocation(
this
.prg,
'mvpMatrix'
)
this
.gl.uniformMatrix4fv(_0x4d0a27,
false
, _0x28d80f)
const _0x504e76 =
this
.gl.getUniformLocation(
this
.prg,
'u_time'
)
this
.gl.uniform1f(_0x504e76, _0xf54bc7)
const _0x15e050 =
this
.gl.getUniformLocation(
this
.prg,
'u_resolution'
)
this
.gl.uniform2f(_0x15e050,
this
.canvas.width,
this
.canvas.height)
this
.gl.useProgram(
this
.prg)
this
.gl.drawArrays(
this
.gl.TRIANGLES, 0, 18)
this
.gl.flush()
}
[
'create_shader'
](_0x217f95, _0x50b1bf) {
let _0x333f8e
switch
(_0x50b1bf) {
case
'OuO'
:
_0x333f8e =
this
.gl.createShader(
this
.gl.VERTEX_SHADER)
break
case
'>w<'
:
_0x333f8e =
this
.gl.createShader(
this
.gl.FRAGMENT_SHADER)
break
default
:
return
}
this
.gl.shaderSource(_0x333f8e, _0x217f95)
this
.gl.compileShader(_0x333f8e)
if
(
this
.gl.getShaderParameter(_0x333f8e,
this
.gl.COMPILE_STATUS)) {
return
_0x333f8e
}
else
{
alert(
this
.gl.getShaderInfoLog(_0x333f8e))
}
}
[
'create_program'
](_0x4d159e, _0x135a44) {
const _0x171a80 =
this
.gl.createProgram()
this
.gl.attachShader(_0x171a80, _0x4d159e)
this
.gl.attachShader(_0x171a80, _0x135a44)
this
.gl.linkProgram(_0x171a80)
if
(
this
.gl.getProgramParameter(_0x171a80,
this
.gl.LINK_STATUS)) {
return
this
.gl.useProgram(_0x171a80), _0x171a80
}
else
{
alert(
this
.gl.getProgramInfoLog(_0x171a80))
}
}
[
'create_vbo'
](_0xbcae1c) {
const _0x9500e2 =
this
.gl.createBuffer()
return
(
this
.gl.bindBuffer(
this
.gl.ARRAY_BUFFER, _0x9500e2),
this
.gl.bufferData(
this
.gl.ARRAY_BUFFER,
new
Float32Array(_0xbcae1c),
this
.gl.STATIC_DRAW
),
this
.gl.bindBuffer(
this
.gl.ARRAY_BUFFER,
null
),
_0x9500e2
)
}
}
const _0x464c09 = (
function
() {
let _0x451913 =
true
return
function
(_0x258426, _0x4b7b8d) {
const _0x1bb18e = _0x451913
?
function
() {
if
(_0x4b7b8d) {
const _0x2d8886 = _0x4b7b8d.apply(_0x258426, arguments)
return
(_0x4b7b8d =
null
), _0x2d8886
}
}
:
function
() { }
return
(_0x451913 =
false
), _0x1bb18e
}
})(),
_0x4c494b = _0x464c09(
this
,
function
() {
return
_0x4c494b
.toString()
.search(_0x9bd70f.dnYkL)
.toString()
.constructor(_0x4c494b)
.search(_0x9bd70f.dnYkL)
})
_0x4c494b()
window.addEventListener(
'load'
, load)
var
draw_canvas, calc_canvas
function
load() {
let draw_canvas_vert =
'\n attribute vec3 position;\n uniform mat4 mvpMatrix;\n varying vec2 vPosition;\n\n void main(void){\n gl_Position = mvpMatrix * vec4(position, 1.0);\n vPosition = position.xy;\n }\n '
,
draw_canvas_frag =
'\n#ifdef GL_ES\nprecision mediump float;\n#endif \n\nuniform float u_time;\nuniform vec2 u_resolution;\nvarying vec2 vPosition;\n\nvec3 hash(vec2 seed){\n vec3 p3 = fract(float(seed.x + seed.y*86.) * vec3(.1051, .1020, .0983));\n\tp3 += dot(p3, p3.yzx + 33.33);\n return fract(p3);\n}\n\nvec3 layer(float scale, vec2 uv, float time){\n // uv coord in cell\n vec2 scaled_uv = uv * scale - 0.5;\n vec2 uv0 = fract( scaled_uv ) - 0.5;\n // cell id\n vec2 cell_id = scaled_uv - fract(scaled_uv);\n \n \n vec3 col = vec3(0);\n float speed = 1.5;\n // distance to a spinning random point in the cell (also surrounding cells)\n vec3 seed = hash(cell_id);\n\n float radiance = seed.x + time * seed.y;\n vec2 center_of_star = vec2(sin(radiance), cos(radiance))*0.3;\n\n // radial distort effect for star shine\n vec2 v_to_star = uv0 - center_of_star;\n float star_radiance = atan(v_to_star.x/v_to_star.y);\n float star_spark_1 = sin(star_radiance*14.+radiance*6.);\n float star_spark_2 = sin(star_radiance*8.-radiance*2.);\n float stars = length(v_to_star) * (5.+star_spark_1+star_spark_2) * 0.03;\n col += smoothstep(length(seed) * 0.01, 0., stars);\n return col;\n}\nvoid main()\n{ // center global uv from -1 to 1\n vec2 virtual_resolution = vec2(2.0, 2.0);\n vec2 uv = (vPosition * 2. - virtual_resolution.xy) / virtual_resolution.y;\n vec3 col = vec3(0.);//vColor.xyz;\n \n const float layer_count = 6.5;\n for(float i = 0.0; i < layer_count; i+=1.){\n float rotate_speed = u_time*0.4;\n float scale = mod(i - rotate_speed, layer_count)*1.5;\n vec2 offseted_uv = uv + vec2(sin(rotate_speed), cos(rotate_speed));\n vec3 layer_col = layer(scale, offseted_uv, u_time + i*1.5);\n \n // we want the star to smoothly show up\n float max_scale = layer_count * 1.5;\n float color_amp = smoothstep(0., 1., smoothstep(max_scale, 0., scale));\n col += layer_col * color_amp;\n }\n // blue background\n col += vec3(0., 0., -0.15) * (uv.y - 0.7) * pow(length(uv), 0.5);\n gl_FragColor = vec4(col, 1.);\n}\n '
,
calc_canvas_vert =
`\nattribute vec3 position;
varying float owO;\n \n
void main(void){\n
gl_Position = vec4(position.xy, 0.0, 1.0);\n
owO = position.z;\n }\n `,
calc_canvas_frag =
`\n
#ifdef GL_ES\n
precision highp float;\n
#endif \n
varying float owO;\n
#define OvO 255.0\n
#define Ovo 128.0\n
#define OVO 23.0\n\n
float OwO (float Owo, float OWO, float owO) {
\n OWO = floor(OWO + 0.5);
owO = floor(owO + 0.5);
\n
return
mod(floor((floor(Owo) + 0.5) / exp2(OWO)), floor(1.0*exp2(owO - OWO) + 0.5));
\n}\n
vec4 oWo (float Ow0) {
\n
if
(Ow0 == 0.0)
return
vec4(0.0); \n
float Owo = Ow0 > 0.0 ? 0.0 : 1.0; \n
Ow0 = abs(Ow0); \n
float OWO = floor(log2(Ow0)); \n
float oWo = OWO + OvO - Ovo; \n
OWO = ((Ow0 / exp2(OWO)) - 1.0) * pow(2.0, OVO);\n
float owO = oWo / 2.0; \n
oWo = fract(owO) + fract(owO); \n
float oWO = floor(owO); \n
owO = OwO(OWO, 0.0, 8.0) / OvO; \n
Ow0 = OwO(OWO, 8.0, 16.0) / OvO; \n
OWO = (oWo * Ovo + OwO(OWO, 16.0, OVO)) / OvO; \n
Owo = (Owo * Ovo + oWO) / OvO; \n
return
vec4(owO, Ow0, OWO, Owo); \n
}\n\nvoid main()\n{
\n gl_FragColor = oWo(owO);\n
}\n `
draw_canvas =
new
ShaderManager(
'canvas'
, 0, 0, draw_canvas_vert, draw_canvas_frag,
true
)
draw_canvas.render()
calc_canvas =
new
ShaderManager(
'canvas-calc'
,
650,
650,
calc_canvas_vert,
calc_canvas_frag,
false
)
calc_canvas.render()
let pattern_container = document.getElementById(
'pattern-container'
),
lines = document.getElementById(
'lines'
),
latest_selected_dot =
null
,
line =
null
,
selected =
false
,
selected_dot = []
pattern_container.childNodes.forEach((dot) => {
if
(!dot.classList) {
return
}
if
(!dot.classList.contains(
'dot'
)) {
return
}
dot.addEventListener(
'mousedown'
, (_0x5be741) => {
selected_dot.forEach((dot) => {
dot.classList.remove(
'selected'
)
dot.classList.remove(
'select'
)
dot.classList.remove(
'lose'
)
dot.classList.remove(
'win'
)
})
lines.innerHTML =
''
selected_dot = []
selected =
true
dot.classList.add(
'select'
)
line = document.createElementNS(
'http://www.w3.org/2000/svg'
,
'line'
)
line.setAttribute(
'x1'
,
dot.offsetLeft + dot.offsetWidth / 2
)
line.setAttribute(
'y1'
,
dot.offsetTop + dot.offsetHeight / 2
)
line.setAttribute(
'x2'
,
dot.offsetLeft + dot.offsetWidth / 2
)
line.setAttribute(
'y2'
,
dot.offsetTop + dot.offsetHeight / 2
)
line.setAttribute(
'stroke'
,
'white'
)
line.setAttribute(
'stroke-width'
,
'5'
)
lines.appendChild(line)
//画线,但是头尾是同一个点
selected_dot.push(dot)
latest_selected_dot = dot
})
dot.addEventListener(
'mouseover'
, (_0x1cae46) => {
//鼠标移入
if
(!selected) {
return
}
if
(dot.classList.contains(
'selected'
)) {
return
}
if
(dot.classList.contains(
'select'
)) {
return
}
line &&
(line.setAttribute(
'x2'
,
dot.offsetLeft + dot.offsetWidth / 2
),
line.setAttribute(
'y2'
,
dot.offsetTop + dot.offsetHeight / 2
),
latest_selected_dot.classList.add(
'selected'
),
latest_selected_dot.classList.remove(
'select'
))
// 把线从上一个点连到当前点
dot.classList.add(
'select'
)
line = document.createElementNS(
'http://www.w3.org/2000/svg'
,
'line'
)
line.setAttribute(
'x1'
,
dot.offsetLeft + dot.offsetWidth / 2
)
line.setAttribute(
'y1'
,
dot.offsetTop + dot.offsetHeight / 2
)
line.setAttribute(
'x2'
,
dot.offsetLeft + dot.offsetWidth / 2
)
line.setAttribute(
'y2'
,
dot.offsetTop + dot.offsetHeight / 2
)
line.setAttribute(
'stroke'
,
'white'
)
line.setAttribute(
'stroke-width'
,
'5'
)
lines.appendChild(line)
selected_dot.push(dot)
latest_selected_dot = dot
})
})
pattern_container.addEventListener(
'mousemove'
, (pos) => {
if
(!selected) {
return
}
latest_selected_dot &&
line &&
(line.setAttribute(
'x2'
,
pos.clientX - pattern_container.getBoundingClientRect().left
),
line.setAttribute(
'y2'
,
pos.clientY - pattern_container.getBoundingClientRect().top
))
})
// 连线跟随鼠标
pattern_container.addEventListener(
'mouseup'
, (_0x3584c1) => {
//鼠标松开
if
(latest_selected_dot && line) {
line.setAttribute(
'x2'
,
latest_selected_dot.offsetLeft + latest_selected_dot.offsetWidth / 2
)
line.setAttribute(
'y2'
,
latest_selected_dot.offsetTop + latest_selected_dot.offsetHeight / 2
)
latest_selected_dot.classList.add(
'selected'
)
latest_selected_dot =
null
let flag = check_flag(
selected_dot.map((dot) => parseInt(dot.dataset.number))
// 传入选中的点的顺序
)
if
(flag !==
null
) {
selected_dot.forEach((dot) => {
dot.classList.add(
'win'
)
})
let flag_p = document.getElementById(
'flag'
)
flag_p.innerText = flag
}
else
{
selected_dot.forEach((dot) => {
dot.classList.add(
'lose'
)
})
}
}
selected =
false
})
}
function
abs(num) {
return
Math.abs(num)
}
const _0xdf21a4 = async (_0x5c1638) => {
const _0x4f0cab =
new
TextEncoder().encode(_0x5c1638),
_0x336245 = await window.crypto.subtle.digest(_0x37cc4d.tNPCS, _0x4f0cab),
_0x587059 = Array.from(
new
Uint8Array(_0x336245)),
_0x49519a = _0x587059
.map((_0x29f99c) => _0x29f99c.toString(16).padStart(2,
'0'
))
.join(
''
)
return
_0x49519a
}
function
check_flag(index_list) {
let _0x526465 = calc_canvas.wtf(index_list[19], index_list[3], index_list[5]) * 25,
_0x27d483 = calc_canvas.wtf(index_list[7], index_list[20], index_list[18]) * 25,
_0x47edd7 = calc_canvas.wtf(index_list[11], index_list[22], index_list[18]) * 25,
_0x3c8060 = calc_canvas.wtf(index_list[5], index_list[17], index_list[2]) * 25,
_0x315313 = calc_canvas.wtf(index_list[20], index_list[13], index_list[5]) * 25,
_0x3cef24 = calc_canvas.wtf(index_list[11], index_list[1], index_list[21]) * 25,
_0x2ee445 = calc_canvas.wtf(index_list[8], index_list[11], index_list[1]) * 25,
_0x5e280a = calc_canvas.wtf(index_list[9], index_list[5], index_list[4]) * 25,
_0x5f6c26 = calc_canvas.wtf(index_list[17], index_list[9], index_list[21]) * 25,
_0x13e7aa = calc_canvas.wtf(index_list[23], index_list[9], index_list[20]) * 25,
_0x9d682e = calc_canvas.wtf(index_list[16], index_list[5], index_list[4]) * 25,
_0x277f3c = calc_canvas.wtf(index_list[16], index_list[14], index_list[13]) * 25,
_0x2f58be = calc_canvas.wtf(index_list[5], index_list[6], index_list[10]) * 25,
_0x5a6698 = calc_canvas.wtf(index_list[2], index_list[11], index_list[5]) * 25,
_0x52d3ed = calc_canvas.wtf(index_list[11], index_list[3], index_list[1]) * 25,
_0x4320e6 = calc_canvas.wtf(index_list[12], index_list[3], index_list[10]) * 25,
_0xf9ef4b = calc_canvas.wtf(index_list[14], index_list[1], index_list[9]) * 25,
_0x429aaf = calc_canvas.wtf(index_list[18], index_list[11], index_list[17]) * 25,
_0x1a4487 = calc_canvas.wtf(index_list[12], index_list[15], index_list[2]) * 25,
_0x4c135d = calc_canvas.wtf(index_list[22], index_list[0], index_list[19]) * 25,
_0x5c13fb = 0
_0x5c13fb += abs(
0.3837876686390533 - calc_canvas.gtfo(_0x3cef24, _0xf9ef4b, _0x5f6c26, 16, 21)
)
_0x5c13fb += abs(
0.21054889940828397 - calc_canvas.gtfo(_0x52d3ed, _0x3cef24, _0x2ee445, 8, 2)
)
_0x5c13fb += abs(
0.475323349112426 - calc_canvas.gtfo(_0x3cef24, _0x429aaf, _0x2f58be, 0, 20)
)
_0x5c13fb += abs(
0.6338370887573964 - calc_canvas.gtfo(_0x3c8060, _0x27d483, _0x2f58be, 8, 4)
)
_0x5c13fb += abs(
0.4111607928994082 - calc_canvas.gtfo(_0x47edd7, _0x52d3ed, _0x4320e6, 23, 1)
)
_0x5c13fb += abs(
0.7707577751479291 - calc_canvas.gtfo(_0x429aaf, _0x3c8060, _0x277f3c, 20, 6)
)
_0x5c13fb += abs(
0.7743081420118344 - calc_canvas.gtfo(_0x13e7aa, _0x5a6698, _0x3c8060, 9, 10)
)
_0x5c13fb += abs(
0.36471487573964495 - calc_canvas.gtfo(_0x5f6c26, _0x526465, _0x315313, 18, 8)
)
_0x5c13fb += abs(
0.312678449704142 - calc_canvas.gtfo(_0x4320e6, _0x13e7aa, _0x429aaf, 0, 17)
)
_0x5c13fb += abs(
0.9502808165680473 - calc_canvas.gtfo(_0x1a4487, _0x13e7aa, _0x3c8060, 22, 10)
)
_0x5c13fb += abs(
0.5869052899408282 - calc_canvas.gtfo(_0x2f58be, _0x5e280a, _0x47edd7, 14, 10)
)
_0x5c13fb += abs(
0.9323389467455623 - calc_canvas.gtfo(_0x429aaf, _0x47edd7, _0x2f58be, 12, 7)
)
_0x5c13fb += abs(
0.4587118106508875 - calc_canvas.gtfo(_0x2ee445, _0x5a6698, _0x47edd7, 4, 21)
)
_0x5c13fb += abs(
0.14484472189349107 - calc_canvas.gtfo(_0x4320e6, _0x13e7aa, _0x52d3ed, 7, 15)
)
_0x5c13fb += abs(
0.7255550059171598 - calc_canvas.gtfo(_0x3cef24, _0x429aaf, _0x1a4487, 9, 23)
)
_0x5c13fb += abs(
0.5031261301775147 - calc_canvas.gtfo(_0x3c8060, _0x47edd7, _0x52d3ed, 7, 1)
)
_0x5c13fb += abs(
0.1417352189349112 - calc_canvas.gtfo(_0x2ee445, _0x52d3ed, _0x5f6c26, 16, 14)
)
_0x5c13fb += abs(
0.5579334437869822 - calc_canvas.gtfo(_0x52d3ed, _0x47edd7, _0x1a4487, 19, 11)
)
_0x5c13fb += abs(
0.48502262721893485 -
calc_canvas.gtfo(_0x9d682e, _0x315313, _0x5e280a, 23, 18)
)
_0x5c13fb += abs(
0.5920916568047336 - calc_canvas.gtfo(_0x5e280a, _0x5f6c26, _0x27d483, 19, 6)
)
_0x5c13fb += abs(
0.7222713017751479 - calc_canvas.gtfo(_0xf9ef4b, _0x47edd7, _0x315313, 8, 16)
)
_0x5c13fb += abs(
0.12367382248520711 - calc_canvas.gtfo(_0x9d682e, _0x4320e6, _0x2f58be, 9, 5)
)
_0x5c13fb += abs(
0.4558028402366864 - calc_canvas.gtfo(_0x277f3c, _0x9d682e, _0x47edd7, 10, 2)
)
_0x5c13fb += abs(
0.8537692426035504 - calc_canvas.gtfo(_0x429aaf, _0x13e7aa, _0x5a6698, 4, 11)
)
_0x5c13fb += abs(
0.9618170650887574 - calc_canvas.gtfo(_0x2f58be, _0x1a4487, _0x429aaf, 15, 2)
)
_0x5c13fb += abs(
0.22088933727810647 - calc_canvas.gtfo(_0x526465, _0x5e280a, _0xf9ef4b, 10, 5)
)
_0x5c13fb += abs(
0.4302783550295858 - calc_canvas.gtfo(_0xf9ef4b, _0x277f3c, _0x3cef24, 14, 2)
)
_0x5c13fb += abs(
0.6262803313609467 - calc_canvas.gtfo(_0x4c135d, _0x52d3ed, _0x47edd7, 17, 22)
)
if
(_0x5c13fb > 0.00001) {
return
null
}
s =
''
s += Math.round(
calc_canvas.wtf(index_list[4], index_list[2], index_list[22]) * 100000
).toString()
s += Math.round(
calc_canvas.wtf(index_list[17], index_list[9], index_list[14]) * 100000
).toString()
s += Math.round(
calc_canvas.wtf(index_list[4], index_list[13], index_list[7]) * 100000
).toString()
s += Math.round(
calc_canvas.wtf(index_list[4], index_list[20], index_list[23]) * 100000
).toString()
s += Math.round(
calc_canvas.wtf(index_list[5], index_list[7], index_list[12]) * 100000
).toString()
s += Math.round(
calc_canvas.wtf(index_list[20], index_list[19], index_list[4]) * 100000
).toString()
s += Math.round(
calc_canvas.wtf(index_list[17], index_list[6], index_list[19]) * 100000
).toString()
s += Math.round(
calc_canvas.wtf(index_list[6], index_list[21], index_list[18]) * 100000
).toString()
s += Math.round(
calc_canvas.wtf(index_list[4], index_list[3], index_list[8]) * 100000
).toString()
s += Math.round(
calc_canvas.wtf(index_list[11], index_list[7], index_list[14]) * 100000
).toString()
s += Math.round(
calc_canvas.wtf(index_list[9], index_list[2], index_list[13]) * 100000
).toString()
s += Math.round(
calc_canvas.wtf(index_list[22], index_list[10], index_list[3]) * 100000
).toString()
s += Math.round(
calc_canvas.wtf(index_list[15], index_list[22], index_list[13]) * 100000
).toString()
s += Math.round(
calc_canvas.wtf(index_list[16], index_list[12], index_list[9]) * 100000
).toString()
s += Math.round(
calc_canvas.wtf(index_list[14], index_list[8], index_list[17]) * 100000
).toString()
s += Math.round(
calc_canvas.wtf(index_list[1], index_list[18], index_list[6]) * 100000
).toString()
s += Math.round(
calc_canvas.wtf(index_list[10], index_list[11], index_list[3]) * 100000
).toString()
s += Math.round(
calc_canvas.wtf(index_list[8], index_list[12], index_list[5]) * 100000
).toString()
s += Math.round(
calc_canvas.wtf(index_list[1], index_list[3], index_list[12]) * 100000
).toString()
s += Math.round(
calc_canvas.wtf(index_list[9], index_list[13], index_list[7]) * 100000
).toString()
s += Math.round(
calc_canvas.gtfo(
index_list[22],
index_list[13],
index_list[5],
index_list[4],
index_list[7]
) * 100000
).toString()
s += Math.round(
calc_canvas.gtfo(
index_list[10],
index_list[14],
index_list[17],
index_list[23],
index_list[11]
) * 100000
).toString()
s += Math.round(
calc_canvas.gtfo(
index_list[23],
index_list[20],
index_list[6],
index_list[1],
index_list[3]
) * 100000
).toString()
s += Math.round(
calc_canvas.gtfo(
index_list[15],
index_list[12],
index_list[2],
index_list[13],
index_list[9]
) * 100000
).toString()
s += Math.round(
calc_canvas.gtfo(
index_list[16],
index_list[20],
index_list[6],
index_list[5],
index_list[18]
) * 100000
).toString()
s += Math.round(
calc_canvas.gtfo(
index_list[3],
index_list[6],
index_list[7],
index_list[8],
index_list[23]
) * 100000
).toString()
s += Math.round(
calc_canvas.gtfo(
index_list[21],
index_list[9],
index_list[10],
index_list[3],
index_list[22]
) * 100000
).toString()
s += Math.round(
calc_canvas.gtfo(
index_list[14],
index_list[6],
index_list[15],
index_list[12],
index_list[19]
) * 100000
).toString()
s += Math.round(
calc_canvas.gtfo(
index_list[13],
index_list[19],
index_list[22],
index_list[23],
index_list[1]
) * 100000
).toString()
s += Math.round(
calc_canvas.gtfo(
index_list[21],
index_list[2],
index_list[9],
index_list[0],
index_list[19]
) * 100000
).toString()
s += Math.round(
calc_canvas.gtfo(
index_list[5],
index_list[19],
index_list[21],
index_list[14],
index_list[6]
) * 100000
).toString()
s += Math.round(
calc_canvas.gtfo(
index_list[16],
index_list[15],
index_list[20],
index_list[13],
index_list[3]
) * 100000
).toString()
s += Math.round(
calc_canvas.gtfo(
index_list[20],
index_list[15],
index_list[10],
index_list[21],
index_list[6]
) * 100000
).toString()
s += Math.round(
calc_canvas.gtfo(
index_list[7],
index_list[1],
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课