Sto postando qui come FYI: le classi crittografate in JSL non sono sicure.Raccomando di utilizzare solo funzioni e non classi, poiché le funzioni non sono vulnerabili a questo.
Il problema sta nel fatto che le classi JMP sono introspettive, mentre le funzioni compilate no.Considera la seguente classe che contiene un metodo che mi piacerebbe davvero mantenere segreto:
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_;
);Se si prende questo script e lo si crittografa (utilizzando Modifica->Crittografa script...), idealmente il codice interno non dovrebbe essere facilmente visibile a nessun utente finale a cui lo si potrebbe distribuire.Questo, tuttavia, non è il caso.In realtà è ridicolmente facile da decostruire e ricostruire.
Ecco un paio di funzioni che possono decostruire i metodi crittografati (questo è il problema) quindi ricostruirlo per comodità:
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 ) );Nota che ci sono due avvertimenti con questo: non può facilmente distinguere tra stringhe e nomi (ma tu come umano probabilmente puoi), e non avrà visibilità sugli argomenti centrali di un costrutto come class:method( arg1, arg2 ):returned_class_method( arg ); , dove il primo metodo restituisce una classe di cui chiami ulteriormente un metodo.Anche con queste limitazioni può essere molto veloce trovare i dettagli di implementazione anche per password/informazioni sensibili.
Ancora una volta, la mia raccomandazione è che se stai crittografando uno script / più script per motivi di sicurezza, non fare affidamento sulle classi.
Buono a sapersi.Suggerisco di inviare questo a support@jmp.com anche se non l'hai già fatto.