Skip to content

Commit 6826bca

Browse files
committed
Support multiple platforms for command obfuscate, build, runtime
1 parent 6c7828f commit 6826bca

File tree

3 files changed

+195
-122
lines changed

3 files changed

+195
-122
lines changed

src/protect_code.pt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def protect_pytransform():
4343
buf = f.read(size)
4444
fmt = 'I' * n
4545
checksum = sum(pytransform.struct.unpack(fmt, buf)) & 0xFFFFFFFF
46-
if not checksum == {checksum}:
46+
if checksum not in {checksum}:
4747
raise RuntimeError('unexpected %s' % filename)
4848
try:
4949
check_obfuscated_script()

src/pyarmor.py

Lines changed: 52 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -198,10 +198,10 @@ def _build(args):
198198
if args.output is None else os.path.normpath(args.output)
199199
logging.info('Output path is: %s', output)
200200

201-
platform = args.platform if args.platform else project.get('platform')
202-
if platform:
203-
logging.info('Taget platform is: %s', platform)
204-
check_cross_platform(platform)
201+
platforms = args.platforms if args.platforms else project.get('platform')
202+
if platforms:
203+
logging.info('Taget platforms: %s', platforms)
204+
check_cross_platform(platforms)
205205

206206
restrict = project.get('restrict_mode',
207207
0 if project.get('disable_restrict_mode') else 1)
@@ -258,11 +258,6 @@ def v(t):
258258
for s in project.entry.split(',')] if project.entry else []
259259
protection = project.cross_protection \
260260
if hasattr(project, 'cross_protection') else 1
261-
if platform:
262-
if protection == 1:
263-
protection = platform
264-
elif not isinstance(protection, int):
265-
protection = ','.join([protection, platform])
266261

267262
for x in sorted(files):
268263
a, b = os.path.join(src, x), os.path.join(soutput, x)
@@ -272,20 +267,23 @@ def v(t):
272267
if not os.path.exists(d):
273268
os.makedirs(d)
274269

270+
if hasattr(project, 'plugins'):
271+
plugins = search_plugins(project.plugins)
272+
else:
273+
plugins = None
274+
275275
if entries and (os.path.abspath(a) in entries):
276276
vmode = adv_mode | 8
277277
pcode = protection
278-
if hasattr(project, 'plugins'):
279-
plugins = search_plugins(project.plugins)
280278
else:
281279
vmode = adv_mode
282280
pcode = 0
283-
plugins = None
284281

285282
encrypt_script(prokey, a, b, obf_code=obf_code, obf_mod=obf_mod,
286283
wrap_mode=wrap_mode, adv_mode=vmode,
287284
rest_mode=restrict, protection=pcode,
288-
plugins=plugins, rpath=project.runtime_path)
285+
platforms=platforms, plugins=plugins,
286+
rpath=project.runtime_path)
289287

290288
logging.info('%d scripts has been obfuscated', len(files))
291289
project['build_time'] = time.time()
@@ -310,7 +308,7 @@ def v(t):
310308

311309
package = project.get('package_runtime', 0) \
312310
if args.package_runtime is None else args.package_runtime
313-
make_runtime(capsule, routput, platform=platform, package=package)
311+
make_runtime(capsule, routput, platforms=platforms, package=package)
314312

315313
if not restrict:
316314
licode = '*FLAGS:%c*CODE:PyArmor-Project' % chr(1)
@@ -453,7 +451,7 @@ def _obfuscate(args):
453451
raise RuntimeError('Only one path is allowed')
454452
args.scripts = []
455453
else:
456-
for s in args.scrips:
454+
for s in args.scripts:
457455
if not s.lower().endswith('.py'):
458456
raise RuntimeError('Only one path is allowed')
459457
path = os.path.abspath(args.src)
@@ -513,12 +511,8 @@ def _obfuscate(args):
513511
logging.info('Obfuscate scripts with default mode')
514512
cross_protection = 0 if args.no_cross_protection else \
515513
1 if args.cross_protection is None else args.cross_protection
516-
if args.platform:
517-
logging.info('Target platform is %s', args.platform)
518-
if cross_protection == 1:
519-
cross_protection = args.platform
520-
elif isinstance(cross_protection, str):
521-
cross_protection = ','.join([cross_protection, args.platform])
514+
if args.platforms:
515+
logging.info('Target platforms: %s', args.platforms)
522516

523517
advanced = 1 if args.advanced else 0
524518
logging.info('Advanced mode is %d', advanced)
@@ -534,15 +528,16 @@ def _obfuscate(args):
534528
logging.info('\t%s -> %s', x, b)
535529
is_entry = entry and (os.path.abspath(a) == os.path.abspath(entry))
536530
protection = is_entry and cross_protection
537-
plugins = protection and search_plugins(args.plugins)
531+
plugins = search_plugins(args.plugins)
538532

539533
d = os.path.dirname(b)
540534
if not os.path.exists(d):
541535
os.makedirs(d)
542536

543537
vmode = advanced | (8 if is_entry else 0)
544538
encrypt_script(prokey, a, b, adv_mode=vmode, rest_mode=restrict,
545-
protection=protection, plugins=plugins)
539+
protection=protection, platforms=args.platforms,
540+
plugins=plugins)
546541
logging.info('%d scripts have been obfuscated', len(files))
547542

548543
if (not args.no_bootstrap) and entry and os.path.exists(entry):
@@ -558,7 +553,7 @@ def _obfuscate(args):
558553
logging.info('Obfuscate %d scripts OK.', len(files))
559554
return
560555

561-
make_runtime(capsule, output, platform=args.platform,
556+
make_runtime(capsule, output, platforms=args.platforms,
562557
package=args.package_runtime)
563558

564559
logging.info('Obfuscate scripts with restrict mode %s',
@@ -642,10 +637,10 @@ def _register(args):
642637
@arcommand
643638
def _download(args):
644639
'''List and download platform-dependent dynamic libraries.'''
645-
if args.platid:
646-
for platid in args.platid:
647-
logging.info('Downloading dynamic library: %s', platid)
648-
download_pytransform(platid, output=args.output, url=args.url)
640+
if args.platnames:
641+
for name in args.platnames:
642+
logging.info('Downloading dynamic library: %s', name)
643+
download_pytransform(name, args.output, url=args.url)
649644

650645
else:
651646
lines = []
@@ -655,8 +650,9 @@ def _download(args):
655650
logging.info('Search the available libraries for %s:', patterns)
656651
else:
657652
logging.info('All the available libraries:')
658-
if not args.verbose:
659-
logging.info('Use -v to display information in details')
653+
if args.help_platform:
654+
# logging.info('Current platform name: %s')
655+
logging.info('All available standard platform names:')
660656

661657
def match_platform(item):
662658
for pat in patterns:
@@ -668,13 +664,17 @@ def match_platform(item):
668664
return True
669665

670666
for p in plist:
667+
if args.help_platform:
668+
pname = p['id'].rsplit('.', 1)[0]
669+
if pname not in lines:
670+
lines.append(pname)
671+
continue
672+
671673
if not match_platform(p):
672674
continue
673675
lines.append('')
674676
lines.append('%16s: %s' % ('id', p['id']))
675677
lines.append('%16s: %s' % ('platform', ', '.join(p['platform'])))
676-
if not args.verbose:
677-
continue
678678
lines.append('%16s: %s' % ('machines', ', '.join(p['machines'])))
679679
lines.append('%16s: %s' % ('features', ', '.join(p['features'])))
680680
lines.append('%16s: %s' % ('remark', p['remark']))
@@ -687,9 +687,9 @@ def _runtime(args):
687687
capsule = DEFAULT_CAPSULE
688688
output = args.output
689689
package = not args.no_package
690-
platform = args.platform
691-
make_runtime(capsule, output, licfile=args.with_license, platform=platform,
692-
package=package)
690+
platforms = args.platforms
691+
make_runtime(capsule, output, licfile=args.with_license,
692+
platforms=platforms, package=package)
693693

694694

695695
def _version_action():
@@ -778,8 +778,10 @@ def _parser():
778778
cparser.add_argument('--restrict', type=int, choices=range(5),
779779
default=1, help='Set restrict mode')
780780
cparser.add_argument('--capsule', help=argparse.SUPPRESS)
781-
cparser.add_argument('--platform', metavar='PLAT-ID',
782-
help='Target platform to run obfuscated scripts')
781+
cparser.add_argument('--platform', dest='platforms', metavar='NAME',
782+
action='append',
783+
help='Target platform to run obfuscated scripts, '
784+
'use this option multiple times for more platforms')
783785
cparser.add_argument('--advanced', nargs='?', const=1, type=int,
784786
default=0, choices=(0, 1),
785787
help='Enable advanced mode')
@@ -937,8 +939,10 @@ def _parser():
937939
help='DO NOT generate runtime files')
938940
cparser.add_argument('-O', '--output',
939941
help='Output path, override project configuration')
940-
cparser.add_argument('--platform', metavar='PLAT-ID',
941-
help='Target platform to run obfuscated scripts')
942+
cparser.add_argument('--platform', dest='platforms', metavar='NAME',
943+
action='append',
944+
help='Target platform to run obfuscated scripts, '
945+
'use this option multiple times for more platforms')
942946
cparser.add_argument('--package-runtime', choices=(0, 1, 2), type=int,
943947
help='Save runtime files as a package or not')
944948
cparser.set_defaults(func=_build)
@@ -1034,17 +1038,17 @@ def _parser():
10341038
epilog=_download.__doc__,
10351039
formatter_class=argparse.RawDescriptionHelpFormatter,
10361040
help='Download platform-dependent dynamic libraries')
1037-
cparser.add_argument('-v', '--verbose', action='store_true',
1038-
help='Display dynamic library information in details')
10391041
cparser.add_argument('-O', '--output', metavar='PATH',
10401042
help='Save downloaded library to this path, default '
10411043
'is `~/.pyarmor/platforms`')
10421044
cparser.add_argument('--url', help='Download from this mirror site')
10431045
group = cparser.add_mutually_exclusive_group()
1046+
group.add_argument('--help-platform', action='store_true',
1047+
help='Display all available platform names')
10441048
group.add_argument('-L', '--list', nargs='?', const='', dest='pattern',
10451049
help='List available dynamic libraries')
1046-
group.add_argument('platid', nargs=1, metavar='PLAT-ID',
1047-
help='Download dynamic library by plat-id')
1050+
group.add_argument('platnames', nargs='+', metavar='NAME',
1051+
help='Download dynamic library for this platform')
10481052
cparser.set_defaults(func=_download)
10491053

10501054
#
@@ -1061,8 +1065,11 @@ def _parser():
10611065
help='Generate runtime files without package')
10621066
cparser.add_argument('-L', '--with-license', metavar='FILE',
10631067
help='Replace default license with this file')
1064-
cparser.add_argument('--platform', help='Generate runtime package '
1065-
'for specified platform')
1068+
cparser.add_argument('--platform', dest='platforms', metavar='NAME',
1069+
action='append',
1070+
help='Generate runtime package for this platform, '
1071+
'use this option multiple times for more platforms')
1072+
cparser.add_argument('--platform', help='')
10661073
cparser.add_argument('pkgname', nargs='?', default='pytransform',
10671074
help=argparse.SUPPRESS)
10681075
cparser.set_defaults(func=_runtime)

0 commit comments

Comments
 (0)