Estoy publicando aquí como FYI: las clases cifradas en JSL no son seguras.Recomiendo usar solo funciones y no clases, ya que las funciones no son vulnerables a esto.
El problema radica en el hecho de que las clases JMP son introspectivas, mientras que las funciones compiladas no lo son.Considere la siguiente clase que contiene un método que realmente me gustaría mantener en secreto:
Define Class(
"complex",
real = 0;
imag = 0;
_init_ = Method( {a, b},
real = a;
imag = b;
);
secret method = Method( {secret input 1, secret input 2 = "foo"},
{Default Local},
my secret password = "password123";
my secret connection database = "database=UML_4x7z;source=axml1131;pwd=my_great_password";
Eval( Eval Expr(
my ultra secret program = Run Program(
Executable( "secret_exe.exe" ),
Options( Expr( "-o " || my secret connection database ) )
)
) );
);
Add = Method( {y},
New Object( complex( real + y:real, imag + y:imag ) )
);
Sub = Method( {y},
New Object( complex( real - y:real, imag - y:imag ) )
);
Mul = Method( {y},
New Object( complex( real * y:real - imag * y:imag, imag * y:real + real * y:imag ) )
);
Div = Method( {y},
t = New Object( complex( 0, 0 ) );
mag2 = y:Magsq();
t:real = real * y:real + imag * y:imag;
t:imag = imag * y:real + real * y:imag;
t:real = t:real / mag2;
t:imag = t:imag / mag2;
t;
);
Magsq = Method( {},
real * real + imag * imag
);
Mag = Method( {},
Sqrt( real * real + imag * imag )
);
_to string_ = Method( {},
Char( real ) || " + " || Char( imag ) || "i"
);
_show_ = _to string_;
);Si toma este script y lo encripta (usando Edit->Encrypt Script...), lo ideal es que el código interno no sea fácilmente visible para ningún usuario final al que pueda distribuirlo.Esto, sin embargo, no es el caso.En realidad, es ridículamente fácil de deconstruir y reconstruir.
Aquí hay un par de funciones que pueden deconstruir los métodos encriptados (este es el problema) y luego reconstruirlos por conveniencia:
clref = New Object( complex( 1, 2 ) );
introspect = Function( {obj},
{Default Local},
i = 1;
obj part = Arg( obj, 1 );
ret = Eval List( {Head Name( obj part )} );
While( !Is Empty( Arg( obj part, i ) ),
moil = Eval List({Arg( obj part, i)} );
ret[N Items( ret ) + 1] = If( N Arg( Arg( moil, 1 ) ) > 0, Recurse( moil ), Head Name( Arg( moil, 1 ) ) );
i++
);
ret
);
Clear Log();
deconstructed = introspect( Eval List( {Name Expr( clref:secret method )} ) );
Show( deconstructed );
reconstruct = Function( {input},
{Default Local},
init = Parse( input[1] || "()" );
If( Is List( input ) & N Items( input ) > 1,
For( i = 2, i <= N Items( input ), i++,
If( Is List( input[i] ),
Insert Into( init, Try( ( s = Recurse( input[i] ); s )[1], Char( s ) ) )
,
Insert Into( init, Parse( input[i] ) )
)
);
);
Eval List( {Name Expr( init ) } );
);
Show( reconstruct( v ) );Tenga en cuenta que hay dos advertencias con esto: no puede distinguir fácilmente entre cadenas y nombres (pero usted, como ser humano, probablemente pueda), y no tendrá visibilidad de los argumentos centrales de una construcción como clase:método( arg1, arg2 ):returned_class_method( arg ); , donde el primer método devuelve una clase a la que llamas método.Incluso con estas limitaciones, puede ser muy rápido encontrar detalles de implementación incluso para contraseñas/información confidencial.
Una vez más, mi recomendación es que si está cifrando un script o varios scripts por motivos de seguridad, no confíe en las clases.