Estoy publicando aquí para su información: las clases cifradas en JSL no son seguras.Recomiendo usar sólo 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 cifra (usando Editar->Encriptar 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 deconstruir y reconstruir.
Aquí hay un par de funciones que pueden deconstruir los métodos cifrados (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 humano, probablemente pueda hacerlo) y no tendrá visibilidad de los argumentos centrales de una construcción como clase: método (arg1, arg2): método_clase_devuelto (arg); , donde el primer método devuelve una clase a la que luego llamas como método.Incluso con estas limitaciones, puede resultar muy rápido encontrar detalles de implementación incluso para contraseñas/información confidencial.
Nuevamente, mi recomendación es que si está cifrando un script o varios scripts por motivos de seguridad, no confíe en las clases.
Bueno saber.Sugiero enviar esto a soporte@jmp.com también si aún no lo has hecho.