5252 get_product_key , register_keyfile , query_keyinfo , \
5353 get_platform_list , download_pytransform , update_pytransform ,\
5454 check_cross_platform , compatible_platform_names , \
55- get_name_suffix , get_bind_key , make_super_bootstrap
55+ get_name_suffix , get_bind_key , make_super_bootstrap , \
56+ make_protection_code
5657
5758import packer
5859
@@ -227,6 +228,41 @@ def _build(args):
227228 if hasattr (project , 'advanced_mode' ) else 0
228229 supermode = adv_mode > 1
229230
231+ protection = project .cross_protection \
232+ if hasattr (project , 'cross_protection' ) else 1
233+
234+ bootstrap_code = project .get ('bootstrap_code' , 1 )
235+ relative = True if bootstrap_code == 3 else \
236+ False if (bootstrap_code == 2 or
237+ (args .no_runtime and bootstrap_code == 1 )) else None
238+
239+ if args .no_runtime :
240+ if protection == 1 :
241+ logging .warning ('No cross protection because no runtime generated' )
242+ protection = 0
243+ else :
244+ routput = output if args .output is not None and args .only_runtime \
245+ else os .path .join (output , os .path .basename (project .src )) \
246+ if project .get ('is_package' ) else output
247+ if not os .path .exists (routput ):
248+ logging .info ('Make path: %s' , routput )
249+ os .mkdir (routput )
250+
251+ package = project .get ('package_runtime' , 0 ) \
252+ if args .package_runtime is None else args .package_runtime
253+
254+ licfile = project .license_file
255+ if not restrict and not licfile :
256+ licfile = 'no-restrict'
257+
258+ checklist = make_runtime (capsule , routput , licfile = licfile ,
259+ platforms = platforms , package = package ,
260+ suffix = suffix , supermode = supermode )
261+ if protection == 1 :
262+ protection = make_protection_code ((relative , checklist , suffix ),
263+ multiple = bool (platforms ),
264+ supermode = supermode )
265+
230266 if not args .only_runtime :
231267 src = project .src
232268 if os .path .abspath (output ).startswith (src ):
@@ -264,11 +300,6 @@ def _build(args):
264300 wrap_mode = 0
265301 obf_code = 0 if project .obf_code_mode == 'none' else 1
266302
267- bootstrap_code = project .get ('bootstrap_code' , 1 )
268- relative = True if bootstrap_code == 3 else \
269- False if (bootstrap_code == 2 or
270- (args .no_runtime and bootstrap_code == 1 )) else None
271-
272303 def v (t ):
273304 return 'on' if t else 'off'
274305 logging .info ('Obfuscating the whole module is %s' , v (obf_mod ))
@@ -279,8 +310,6 @@ def v(t):
279310
280311 entries = [build_path (s .strip (), project .src )
281312 for s in project .entry .split (',' )] if project .entry else []
282- protection = project .cross_protection \
283- if hasattr (project , 'cross_protection' ) else 1
284313
285314 for x in sorted (files ):
286315 a , b = os .path .join (src , x ), os .path .join (soutput , x )
@@ -315,41 +344,13 @@ def v(t):
315344 project ['build_time' ] = time .time ()
316345 project .save (args .project )
317346
318- if adv_mode < 2 and project .entry and bootstrap_code :
347+ if ( not supermode ) and project .entry and bootstrap_code :
319348 soutput = os .path .join (output , os .path .basename (project .src )) \
320349 if project .get ('is_package' ) else output
321350 make_entry (project .entry , project .src , soutput ,
322351 rpath = project .runtime_path , relative = relative ,
323352 suffix = suffix )
324353
325- if not args .no_runtime :
326- routput = output if args .output is not None and args .only_runtime \
327- else os .path .join (output , os .path .basename (project .src )) \
328- if project .get ('is_package' ) else output
329- if not os .path .exists (routput ):
330- logging .info ('Make path: %s' , routput )
331- os .mkdir (routput )
332-
333- package = project .get ('package_runtime' , 0 ) \
334- if args .package_runtime is None else args .package_runtime
335- make_runtime (capsule , routput , platforms = platforms , package = package ,
336- suffix = suffix , supermode = supermode )
337-
338- licfile = project .license_file
339- if licfile :
340- logging .info ('Project has customized license file: %s' , licfile )
341- licpath = os .path .join (routput , 'pytransform' + suffix ) \
342- if package else routput
343- logging .info ('Copy project license file to %s' , licpath )
344- shutil .copy (licfile , licpath )
345- elif not restrict :
346- licode = '*FLAGS:%c*CODE:PyArmor-Project' % chr (1 )
347- licpath = os .path .join (routput , 'pytransform' + suffix ) \
348- if package else routput
349- licfile = os .path .join (licpath , license_filename )
350- logging .info ('Generate no restrict mode license file: %s' , licfile )
351- make_license_key (capsule , licode , licfile )
352-
353354 logging .info ('Build project OK.' )
354355
355356
@@ -518,7 +519,7 @@ def _obfuscate(args):
518519 if check_cross_platform (platforms ) is not False :
519520 return
520521
521- for x in ('entry' , 'cross-protection' ):
522+ for x in ('entry' ,):
522523 if getattr (args , x .replace ('-' , '_' )) is not None :
523524 logging .warning ('Option --%s has been deprecated' , x )
524525
@@ -606,6 +607,7 @@ def _obfuscate(args):
606607
607608 advanced = args .advanced if args .advanced else 0
608609 logging .info ('Advanced mode is %d' , advanced )
610+ supermode = advanced > 1
609611
610612 restrict = args .restrict
611613 logging .info ('Restrict mode is %d' , restrict )
@@ -614,6 +616,25 @@ def _obfuscate(args):
614616 relative = True if n == 3 else False if n == 2 else None
615617 bootstrap = (not args .no_bootstrap ) and n
616618 elist = [os .path .abspath (x ) for x in entries ]
619+
620+ if args .no_runtime :
621+ if cross_protection == 1 :
622+ logging .warning ('No cross protection because no runtime generated' )
623+ cross_protection = 0
624+ else :
625+ package = args .package_runtime
626+ licfile = args .license_file
627+ if (not restrict ) and (licfile is not None ):
628+ licfile = 'no-restrict'
629+ checklist = make_runtime (capsule , output , platforms = platforms ,
630+ licfile = licfile , package = package ,
631+ suffix = suffix , supermode = supermode )
632+ if cross_protection == 1 :
633+ cross_protection = make_protection_code (
634+ (relative , checklist , suffix ),
635+ multiple = bool (platforms ),
636+ supermode = supermode )
637+
617638 for x in sorted (files ):
618639 if os .path .isabs (x ):
619640 a , b = x , os .path .join (output , os .path .basename (x ))
@@ -634,30 +655,12 @@ def _obfuscate(args):
634655 plugins = plugins , suffix = suffix , obf_code = args .obf_code ,
635656 obf_mod = args .obf_mod , wrap_mode = args .wrap_mode )
636657
637- if advanced > 1 :
658+ if supermode :
638659 make_super_bootstrap (a , b , relative = relative , suffix = suffix )
639660 elif is_entry and bootstrap :
640661 name = os .path .abspath (a )[len (path )+ 1 :]
641662 make_entry (name , path , output , relative = relative , suffix = suffix )
642663
643- logging .info ('%d scripts have been obfuscated' , len (files ))
644-
645- if args .no_runtime :
646- logging .info ('Obfuscate %d scripts OK.' , len (files ))
647- return
648-
649- package = args .package_runtime
650- make_runtime (capsule , output , platforms = platforms ,
651- package = package , suffix = suffix , supermode = advanced > 1 )
652-
653- if not args .restrict :
654- licode = '*FLAGS:%c*CODE:PyArmor-Project' % chr (1 )
655- licpath = (os .path .join (output , 'pytransform' + suffix ) if package
656- else output )
657- licfile = os .path .join (licpath , license_filename )
658- logging .info ('Generate no restrict mode license file: %s' , licfile )
659- make_license_key (capsule , licode , licfile )
660-
661664 logging .info ('Obfuscate %d scripts OK.' , len (files ))
662665
663666
@@ -795,15 +798,26 @@ def _runtime(args):
795798 package = not args .no_package
796799 platforms = compatible_platform_names (args .platforms )
797800 suffix = get_name_suffix () if args .enable_suffix else ''
798- make_runtime (capsule , output , licfile = args .with_license ,
799- platforms = platforms , package = package , suffix = suffix ,
800- restrict = False , supermode = args .super_mode )
801-
802- filename = os .path .join (output , '__init__.py' ) if args .inside else \
803- os .path .join (args .output , name + '.py' )
804- logging .info ('Generating bootstrap script ...' )
805- make_bootstrap_script (filename , capsule = capsule , suffix = suffix )
806- logging .info ('Generating bootstrap script %s OK' , filename )
801+ licfile = 'no' if args .no_license else args .license_file
802+ checklist = make_runtime (capsule , output , licfile = licfile ,
803+ platforms = platforms , package = package ,
804+ suffix = suffix , restrict = False ,
805+ supermode = args .super_mode )
806+
807+ logging .info ('Generating protection script ...' )
808+ filename = os .path .join (output , 'pytransform_protection.py' )
809+ data = make_protection_code ((args .inside , checklist , suffix ),
810+ multiple = bool (platforms ),
811+ supermode = args .super_mode )
812+ with open (filename , 'r' ) as f :
813+ f .write (data )
814+
815+ if not args .super_mode :
816+ filename = os .path .join (output , '__init__.py' ) if args .inside else \
817+ os .path .join (args .output , name + '.py' )
818+ logging .info ('Generating bootstrap script ...' )
819+ make_bootstrap_script (filename , capsule = capsule , suffix = suffix )
820+ logging .info ('Generating bootstrap script %s OK' , filename )
807821
808822
809823def _version_action ():
@@ -876,9 +890,6 @@ def _parser():
876890 dest = 'bootstrap_code' ,
877891 type = int , default = 1 , choices = (0 , 1 , 2 , 3 ),
878892 help = 'How to insert bootstrap code to entry script' )
879- cparser .add_argument ('--no-cross-protection' , action = 'store_true' ,
880- help = 'Do not insert cross protection code to entry '
881- 'script' )
882893 cparser .add_argument ('scripts' , metavar = 'SCRIPT' , nargs = '+' ,
883894 help = 'List scripts to obfuscated, the first script '
884895 'is entry script' )
@@ -887,8 +898,6 @@ def _parser():
887898 'in the top most path' )
888899 cparser .add_argument ('-e' , '--entry' , metavar = 'SCRIPT' ,
889900 help = argparse .SUPPRESS )
890- cparser .add_argument ('--cross-protection' , choices = (0 , 1 ),
891- help = argparse .SUPPRESS )
892901 cparser .add_argument ('--plugin' , dest = 'plugins' , metavar = 'NAME' ,
893902 action = 'append' ,
894903 help = 'Insert extra code to entry script, '
@@ -912,6 +921,14 @@ def _parser():
912921 help = 'DO NOT generate runtime files' )
913922 cparser .add_argument ('--enable-suffix' , action = 'store_true' ,
914923 help = 'Make unique runtime files and bootstrap code' )
924+ cparser .add_argument ('--with-license' , dest = 'license_file' ,
925+ help = 'Use this license file other than default' )
926+ group = cparser .add_mutually_exclusive_group ()
927+ group .add_argument ('--no-cross-protection' , action = 'store_true' ,
928+ help = 'Do not insert protection code to entry script' )
929+ group .add_argument ('--cross-protection' , metavar = 'SCRIPT' ,
930+ help = 'Specify cross protection script' )
931+
915932 cparser .set_defaults (func = _obfuscate )
916933
917934 #
@@ -1214,7 +1231,10 @@ def _parser():
12141231 help = 'Generate bootstrap script which is used '
12151232 'inside one package' )
12161233 cparser .add_argument ('-L' , '--with-license' , metavar = 'FILE' ,
1234+ dest = 'license_file' ,
12171235 help = 'Replace default license with this file' )
1236+ cparser .add_argument ('without-license' , dest = 'no_license' ,
1237+ action = 'store_true' , help = argparse .SUPPRESS )
12181238 cparser .add_argument ('--platform' , dest = 'platforms' , metavar = 'NAME' ,
12191239 action = 'append' ,
12201240 help = 'Generate runtime package for this platform, '
0 commit comments