def _obfuscate(args): '''Obfuscate scripts without project''' if args.src is None and args.entry is None and not args.scripts: raise RuntimeError('No entry script') entry = args.entry or (args.scripts and args.scripts[0]) path = os.path.abspath( os.path.dirname(entry) if args.src is None else args.src) logging.info('Obfuscate scripts in path "%s"', path) capsule = args.capsule if args.capsule else DEFAULT_CAPSULE if os.path.exists(capsule) and check_capsule(capsule): logging.info('Use cached capsule %s', capsule) else: logging.info('Generate capsule %s', capsule) make_capsule(capsule) output = args.output if os.path.abspath(output) == path: raise RuntimeError('Output path can not be same as src') if args.recursive: pats = ['global-include *.py', 'prune build', 'prune dist'] if os.path.abspath(output).startswith(path): x = os.path.abspath(output)[len(path):].strip('/\\') pats.append('prune %s' % x) if hasattr('', 'decode'): pats = [p.decode() for p in pats] files = Project.build_manifest(pats, path) else: files = Project.build_globfiles(['*.py'], path) logging.info('Save obfuscated scripts to "%s"', output) if not os.path.exists(output): os.makedirs(output) logging.info('Read public key from capsule') prokey = get_product_key(capsule) logging.info('Obfuscate scripts with default mode') for x in files: a, b = os.path.join(path, x), os.path.join(output, x) logging.info('\t%s -> %s', x, b) protection = args.cross_protection and entry \ and (os.path.abspath(a) == os.path.abspath(entry)) d = os.path.dirname(b) if not os.path.exists(d): os.makedirs(d) encrypt_script(prokey, a, b, protection=protection) logging.info('%d scripts have been obfuscated', len(files)) make_runtime(capsule, output) if entry and entry.endswith('__init__.py') and args.restrict is None: logging.info('Disable restrict mode for package by default') restrict = 0 else: restrict = 1 if args.restrict is None else args.restrict logging.info('Obfuscate scripts with restrict mode %s', 'on' if restrict else 'off') if not restrict: licode = '*FLAGS:%c*CODE:PyArmor-Project' % chr(1) licfile = os.path.join(output, license_filename) logging.info('Generate no restrict mode license file: %s', licfile) make_project_license(capsule, licode, licfile) if entry: make_entry(os.path.basename(entry), path, output) for script in args.scripts[1:]: make_entry(os.path.basename(script), path, output) logging.info('Obfuscate %d scripts OK.', len(files))
def _build(args): '''Build project, obfuscate all scripts in the project.''' project = Project() project.open(args.project) logging.info('Build project %s ...', args.project) capsule = build_path(project.capsule, args.project) logging.info('Use capsule: %s', capsule) output = build_path(project.output, args.project) \ if args.output is None else args.output logging.info('Output path is: %s', output) if not args.only_runtime: mode = project.get_obfuscate_mode() files = project.get_build_files(args.force) src = project.src soutput = os.path.join(output, os.path.basename(src)) \ if project.get('is_package') else output filepairs = [(os.path.join(src, x), os.path.join(soutput, x)) for x in files] logging.info('%s increment build', 'Disable' if args.force else 'Enable') logging.info('Search scripts from %s', src) logging.info('Obfuscate %d scripts with mode %s', len(files), mode) for x in files: logging.info('\t%s', x) logging.info('Save obfuscated scripts to %s', soutput) obfuscate_scripts(filepairs, mode, capsule, soutput) # for x in targets: # output = os.path.join(project.output, x) # pairs = [(os.path.join(src, x), os.path.join(output, x)) # for x in files] # for src, dst in pairs: # try: # shutil.copy2(src, dst) # except Exception: # os.makedirs(os.path.dirname(dst)) # shutil.copy2(src, dst) project['build_time'] = time.time() project.save(args.project) if not args.no_runtime: if project.runtime_path is None or args.output is not None: routput = output else: routput = os.path.join(args.project, 'runtimes') if not os.path.exists(routput): logging.info('Make path: %s', routput) os.mkdir(routput) logging.info('Make runtime files to %s', routput) make_runtime(capsule, routput) if project.get('disable_restrict_mode'): licode = '*FLAGS:%c*CODE:Pyarmor-Project' % chr(1) licfile = os.path.join(routput, license_filename) logging.info('Generate no restrict mode license file: %s', licfile) make_project_license(capsule, licode, licfile) if project.entry: make_entry(project.entry, project.src, output, rpath=project.runtime_path, ispackage=project.get('is_package')) else: logging.info('\tIn order to import obfuscated scripts, insert ') logging.info('\t2 lines in entry script:') logging.info('\t\tfrom pytransfrom import pyarmor_runtime') logging.info('\t\tpyarmor_runtime()') logging.info('Build project OK.')
def _build(args): '''Build project, obfuscate all scripts in the project.''' project = Project() project.open(args.project) logging.info('Build project %s ...', args.project) capsule = build_path(project.capsule, args.project) logging.info('Use capsule: %s', capsule) output = build_path(project.output, args.project) \ if args.output is None else args.output logging.info('Output path is: %s', output) if not args.only_runtime: files = project.get_build_files(args.force) src = project.src soutput = os.path.join(output, os.path.basename(src)) \ if project.get('is_package') else output logging.info('Save obfuscated scripts to "%s"', soutput) if not os.path.exists(soutput): os.makedirs(soutput) logging.info('Read public key from capsule') prokey = get_product_key(capsule) logging.info('%s increment build', 'Disable' if args.force else 'Enable') logging.info('Search scripts from %s', src) logging.info('Obfuscate scripts with mode:') if hasattr(project, 'obf_mod'): obf_mod = project.obf_mod else: obf_mod = project.obf_module_mode == 'des' if hasattr(project, 'wrap_mode'): wrap_mode = project.wrap_mode obf_code = project.obf_code elif project.obf_code_mode == 'wrap': wrap_mode = 1 obf_code = 1 else: wrap_mode = 0 obf_code = 0 if project.obf_code_mode == 'none' else 1 def v(t): return 'on' if t else 'off' logging.info('Obfuscating the whole module is %s', v(obf_mod)) logging.info('Obfuscating each function is %s', v(obf_code)) logging.info('Autowrap each code object mode is %s', v(wrap_mode)) entry = os.path.abspath(project.entry) if project.entry else None protection = project.cross_protection \ if hasattr(project, 'cross_protection') else 1 for x in files: a, b = os.path.join(src, x), os.path.join(soutput, x) logging.info('\t%s -> %s', x, b) d = os.path.dirname(b) if not os.path.exists(d): os.makedirs(d) pcode = entry and (os.path.abspath(a) == entry) and protection encrypt_script(prokey, a, b, obf_code=obf_code, obf_mod=obf_mod, wrap_mode=wrap_mode, protection=pcode, rpath=project.runtime_path) logging.info('%d scripts has been obfuscated', len(files)) project['build_time'] = time.time() project.save(args.project) if project.entry: make_entry(project.entry, project.src, output, rpath=project.runtime_path, ispackage=project.get('is_package')) if not args.no_runtime: routput = os.path.join(output, os.path.basename(project.src)) \ if project.get('is_package') else output if not os.path.exists(routput): logging.info('Make path: %s', routput) os.mkdir(routput) logging.info('Make runtime files to %s', routput) make_runtime(capsule, routput) if project.get('disable_restrict_mode'): licode = '*FLAGS:%c*CODE:PyArmor-Project' % chr(1) licfile = os.path.join(routput, license_filename) logging.info('Generate no restrict mode license file: %s', licfile) make_project_license(capsule, licode, licfile) else: logging.info('\tIn order to import obfuscated scripts, insert ') logging.info('\t2 lines in entry script:') logging.info('\t\tfrom pytransform import pyarmor_runtime') logging.info('\t\tpyarmor_runtime()') logging.info('Build project OK.')
def _licenses(args): '''Generate licenses for obfuscated scripts. Examples, * Expired license for global capsule pyarmor licenses --expired=2018-05-12 Customer-Jordan * Bind license to fixed harddisk and expired someday for project cd projects/myproject ./pyarmor licenses -e 2018-05-12 \\ --bind-disk '100304PBN2081SF3NJ5T' Customer-Tom ''' if os.path.exists(os.path.join(args.project, config_filename)): logging.info('Generate licenses for project %s ...', args.project) project = Project() project.open(args.project) capsule = build_path(project.capsule, args.project) \ if args.capsule is None else args.capsule else: if args.project != '': logging.warning('Ignore option --project, no project in %s', args.project) capsule = DEFAULT_CAPSULE if args.capsule is None else args.capsule if not (os.path.exists(capsule) and check_capsule(capsule)): logging.info('Generate capsule %s', capsule) make_capsule(capsule) logging.info('Generate licenses with capsule %s ...', capsule) project = { 'disable_restrict_mode': 0 if args.restrict else 1, } licpath = os.path.join( args.project if args.output is None else args.output, 'licenses') if os.path.exists(licpath): logging.info('Output path of licenses: %s', licpath) else: logging.info('Make output path of licenses: %s', licpath) os.mkdir(licpath) if args.expired is None: fmt = '' else: fmt = '*TIME:%.0f\n' % \ time.mktime(time.strptime(args.expired, '%Y-%m-%d')) if project.get('disable_restrict_mode'): logging.info('The license files generated is in disable restrict mode') fmt = '%s*FLAGS:%c' % (fmt, 1) else: logging.info('The license files generated is in restrict mode') if args.bind_disk: fmt = '%s*HARDDISK:%s' % (fmt, args.bind_disk) if args.bind_mac: fmt = '%s*IFMAC:%s' % (fmt, args.bind_mac) if args.bind_ipv4: fmt = '%s*IFIPV4:%s' % (fmt, args.bind_ipv4) # if args.bind_ipv6: # fmt = '%s*IFIPV6:%s' % (fmt, args.bind_ipv6) if args.bind_domain: fmt = '%s*DOMAIN:%s' % (fmt, args.bind_domain) if args.bind_file: bind_file, bind_key = args.bind_file.split(';', 2) if os.path.exists(bind_file): f = open(bind_file, 'rb') s = f.read() f.close() if sys.version_info[0] == 3: fmt = '%s*FIXKEY:%s;%s' % (fmt, bind_key, s.decode()) else: fmt = '%s*FIXKEY:%s;%s' % (fmt, bind_key, s) else: raise RuntimeError('Bind file %s not found' % bind_file) # Prefix of registration code fmt = fmt + '*CODE:' for rcode in args.codes: output = os.path.join(licpath, rcode) if not os.path.exists(output): logging.info('Make path: %s', output) os.mkdir(output) licfile = os.path.join(output, license_filename) licode = fmt + rcode txtinfo = licode.replace('\n', r'\n') if args.expired: txtinfo = '"Expired:%s%s"' % (args.expired, txtinfo[txtinfo.find(r'\n') + 2:]) logging.info('Generate license: %s', txtinfo) make_project_license(capsule, licode, licfile) logging.info('Write license file: %s', licfile) logging.info('Write information to %s.txt', licfile) with open(os.path.join(licfile + '.txt'), 'w') as f: f.write(txtinfo) logging.info('Generate %d licenses OK.', len(args.codes))
def _obfuscate(args): '''Obfuscate scripts without project.''' for x in ('src', 'entry', 'cross-protection'): if getattr(args, x.replace('-', '_')) is not None: logging.warning('Option --%s has been deprecated', x) if args.src is None and not args.scripts: raise RuntimeError('No scripts specified') path = os.path.abspath( os.path.dirname(args.scripts[0]) if args.src is None else args.src) logging.info('Source path is "%s"', path) entry = args.entry or (args.scripts and args.scripts[0]) logging.info('Entry script is %s', entry) capsule = args.capsule if args.capsule else DEFAULT_CAPSULE if os.path.exists(capsule) and check_capsule(capsule): logging.info('Use cached capsule %s', capsule) else: logging.info('Generate capsule %s', capsule) make_capsule(capsule) output = args.output if os.path.abspath(output) == path: raise RuntimeError('Output path can not be same as src') if args.recursive: logging.info('Recursive mode is on') pats = ['global-include *.py'] if args.exclude: for x in args.exclude.split(','): logging.info('Exclude path "%s"', x) pats.append('prune %s' % x) if os.path.abspath(output).startswith(path): x = os.path.abspath(output)[len(path):].strip('/\\') pats.append('prune %s' % x) logging.info('Auto exclude output path "%s"', x) if hasattr('', 'decode'): pats = [p.decode() for p in pats] files = Project.build_manifest(pats, path) elif args.exact: logging.info('Exact mode is on') files = [os.path.abspath(x) for x in args.scripts] else: logging.info('Normal mode is on') files = Project.build_globfiles(['*.py'], path) logging.info('Save obfuscated scripts to "%s"', output) if not os.path.exists(output): os.makedirs(output) logging.info('Read public key from capsule') prokey = get_product_key(capsule) logging.info('Obfuscate scripts with default mode') cross_protection = 0 if args.no_cross_protection else \ 1 if args.cross_protection is None else args.cross_protection if args.platform: logging.info('Target platform is %s', args.platform) if cross_protection == 1: cross_protection = args.platform elif isinstance(cross_protection, str): cross_protection = ','.join([cross_protection, args.platform]) for x in files: if os.path.isabs(x): a, b = x, os.path.join(output, os.path.basename(x)) else: a, b = os.path.join(path, x), os.path.join(output, x) logging.info('\t%s -> %s', x, b) protection = entry and (os.path.abspath(a) == os.path.abspath(entry)) \ and cross_protection plugins = protection and args.plugins d = os.path.dirname(b) if not os.path.exists(d): os.makedirs(d) encrypt_script(prokey, a, b, protection=protection, plugins=plugins) logging.info('%d scripts have been obfuscated', len(files)) make_runtime(capsule, output, platform=args.platform) logging.info('Obfuscate scripts with restrict mode %s', 'on' if args.restrict else 'off') if not args.restrict: licode = '*FLAGS:%c*CODE:PyArmor-Project' % chr(1) licfile = os.path.join(output, license_filename) logging.info('Generate no restrict mode license file: %s', licfile) make_project_license(capsule, licode, licfile) if (not args.no_bootstrap) and entry and os.path.exists(entry): entryname = entry if args.src else os.path.basename(entry) if os.path.exists(os.path.join(output, entryname)): make_entry(entryname, path, output) else: logging.info('Use outer entry script "%s"', entry) make_entry(entry, path, output) logging.info('Obfuscate %d scripts OK.', len(files))
def _licenses(args): '''Generate licenses for this project. Use command hdinfo to get hardware information. ''' logging.info('Generate licenses for project %s ...', args.project) project = Project() project.open(args.project) licpath = os.path.join(args.project, 'licenses') if not os.path.exists(licpath): logging.info('Make output path of licenses: %s', licpath) os.mkdir(licpath) if args.expired is None: fmt = '' else: fmt = '*TIME:%.0f\n' % \ time.mktime(time.strptime(args.expired, '%Y-%m-%d')) if project.get('disable_restrict_moce'): fmt = '%s*FLAGS:%c' % (fmt, 1) if args.bind_disk: fmt = '%s*HARDDISK:%s' % (fmt, args.bind_disk) if args.bind_mac: fmt = '%s*IFMAC:%s' % (fmt, args.bind_mac) if args.bind_ipv4: fmt = '%s*IFIPV4:%s' % (fmt, args.bind_ipv4) # if args.bind_ipv6: # fmt = '%s*IFIPV6:%s' % (fmt, args.bind_ipv6) if args.bind_domain: fmt = '%s*DOMAIN:%s' % (fmt, args.bind_domain) # if args.bind_file: # if os.path.exists(args.bind_file): # f = open(args.bind_file, 'rb') # s = f.read() # f.close() # if sys.version_info[0] == 3: # fmt = '%s*FIXKEY:%s;%s' % (fmt, key, s.decode()) # else: # fmt = '%s*FIXKEY:%s;%s' % (fmt, key, s) # else: # raise RuntimeError('Bind file %s not found' % bindfile) # Prefix of registration code fmt = fmt + '*CODE:' capsule = build_path(project.capsule, args.project) for rcode in args.codes: output = os.path.join(licpath, rcode) if not os.path.exists(output): logging.info('Make path: %s', output) os.mkdir(output) licfile = os.path.join(output, license_filename) licode = fmt + rcode txtinfo = licode.replace('\n', r'\n') if args.expired: txtinfo = '"Expired:%s%s"' % (args.expired, txtinfo[txtinfo.find(r'\n') + 2:]) logging.info('Generate license: %s', txtinfo) make_project_license(capsule, licode, licfile) logging.info('Write license file: %s', licfile) logging.info('Write information to %s.txt', licfile) with open(os.path.join(licfile + '.txt'), 'w') as f: f.write(txtinfo) logging.info('Generate %d licenses OK.', len(args.codes))
def _licenses(args): '''Generate licenses for obfuscated scripts.''' for x in ('bind-file', ): if getattr(args, x.replace('-', '_')) is not None: logging.warning('Option --%s has been deprecated', x) if os.path.exists(os.path.join(args.project, config_filename)): logging.info('Generate licenses for project %s ...', args.project) project = Project() project.open(args.project) capsule = build_path(project.capsule, args.project) \ if args.capsule is None else args.capsule else: if args.project != '': logging.warning('Ignore option --project, there is no project') capsule = DEFAULT_CAPSULE if args.capsule is None else args.capsule if not (os.path.exists(capsule) and check_capsule(capsule)): logging.info('Generate capsule %s', capsule) make_capsule(capsule) logging.info('Generate licenses with capsule %s ...', capsule) project = dict(disable_restrict_mode=0 if args.restrict else 1) licpath = os.path.join( args.project if args.output is None else args.output, 'licenses') if os.path.exists(licpath): logging.info('Output path of licenses: %s', licpath) else: logging.info('Make output path of licenses: %s', licpath) os.mkdir(licpath) if args.expired is None: fmt = '' else: fmt = '*TIME:%.0f\n' % \ time.mktime(time.strptime(args.expired, '%Y-%m-%d')) if project.get('disable_restrict_mode'): logging.info('The license file generated is in disable restrict mode') fmt = '%s*FLAGS:%c' % (fmt, 1) else: logging.info('The license file generated is in restrict mode') if args.bind_disk: fmt = '%s*HARDDISK:%s' % (fmt, args.bind_disk) if args.bind_mac: fmt = '%s*IFMAC:%s' % (fmt, args.bind_mac) if args.bind_ipv4: fmt = '%s*IFIPV4:%s' % (fmt, args.bind_ipv4) # if args.bind_ipv6: # fmt = '%s*IFIPV6:%s' % (fmt, args.bind_ipv6) if args.bind_domain: fmt = '%s*DOMAIN:%s' % (fmt, args.bind_domain) if args.bind_file: bind_file, bind_key = args.bind_file.split(';', 2) if os.path.exists(bind_file): f = open(bind_file, 'rb') s = f.read() f.close() if sys.version_info[0] == 3: fmt = '%s*FIXKEY:%s;%s' % (fmt, bind_key, s.decode()) else: fmt = '%s*FIXKEY:%s;%s' % (fmt, bind_key, s) else: raise RuntimeError('Bind file %s not found' % bind_file) # Prefix of registration code fmt = fmt + '*CODE:' for rcode in args.codes: output = os.path.join(licpath, rcode) if not os.path.exists(output): logging.info('Make path: %s', output) os.mkdir(output) licfile = os.path.join(output, license_filename) licode = fmt + rcode txtinfo = licode.replace('\n', r'\n') if args.expired: txtinfo = '"Expired:%s%s"' % (args.expired, txtinfo[txtinfo.find(r'\n') + 2:]) logging.info('Generate license: %s', txtinfo) make_project_license(capsule, licode, licfile) logging.info('Write license file: %s', licfile) logging.info('Write information to %s.txt', licfile) with open(os.path.join(licfile + '.txt'), 'w') as f: f.write(txtinfo) logging.info('Generate %d licenses OK.', len(args.codes))
def _build(args): '''Build project, obfuscate all scripts in the project.''' project = Project() project.open(args.project) logging.info('Build project %s ...', args.project) logging.info('Check project') project._check(args.project) pro_path = args.project \ if args.project == '' or os.path.exists(args.project) \ else os.path.dirname(args.project) capsule = build_path(project.capsule, pro_path) logging.info('Use capsule: %s', capsule) output = build_path(project.output, pro_path) \ if args.output is None else os.path.normpath(args.output) logging.info('Output path is: %s', output) platform = args.platform if args.platform else project.get('platform') if platform: logging.info('Taget platform is: %s', platform) if not args.only_runtime: src = project.src if os.path.abspath(output).startswith(src): excludes = ['prune %s' % os.path.abspath(output)[len(src) + 1:]] else: excludes = [] files = project.get_build_files(args.force, excludes=excludes) soutput = os.path.join(output, os.path.basename(src)) \ if project.get('is_package') else output logging.info('Save obfuscated scripts to "%s"', soutput) if not os.path.exists(soutput): os.makedirs(soutput) logging.info('Read public key from capsule') prokey = get_product_key(capsule) logging.info('%s increment build', 'Disable' if args.force else 'Enable') logging.info('Search scripts from %s', src) logging.info('Obfuscate scripts with mode:') if hasattr(project, 'obf_mod'): obf_mod = project.obf_mod else: obf_mod = project.obf_module_mode == 'des' if hasattr(project, 'wrap_mode'): wrap_mode = project.wrap_mode obf_code = project.obf_code elif project.obf_code_mode == 'wrap': wrap_mode = 1 obf_code = 1 else: wrap_mode = 0 obf_code = 0 if project.obf_code_mode == 'none' else 1 def v(t): return 'on' if t else 'off' logging.info('Obfuscating the whole module is %s', v(obf_mod)) logging.info('Obfuscating each function is %s', v(obf_code)) logging.info('Autowrap each code object mode is %s', v(wrap_mode)) entries = [ build_path(s.strip(), project.src) for s in project.entry.split(',') ] if project.entry else [] protection = project.cross_protection \ if hasattr(project, 'cross_protection') else 1 if platform: if protection == 1: protection = platform elif not isinstance(protection, int): protection = ','.join([protection, platform]) for x in files: a, b = os.path.join(src, x), os.path.join(soutput, x) logging.info('\t%s -> %s', x, b) d = os.path.dirname(b) if not os.path.exists(d): os.makedirs(d) if entries and (os.path.abspath(a) in entries): pcode = protection if hasattr(project, 'plugins'): plugins = project.plugins else: pcode = 0 plugins = None encrypt_script(prokey, a, b, obf_code=obf_code, obf_mod=obf_mod, wrap_mode=wrap_mode, protection=pcode, plugins=plugins, rpath=project.runtime_path) logging.info('%d scripts has been obfuscated', len(files)) project['build_time'] = time.time() project.save(args.project) if project.entry: make_entry(project.entry, project.src, output, rpath=project.runtime_path, runtime=not args.no_runtime, ispackage=project.get('is_package')) if not args.no_runtime: routput = output if args.output is not None and args.only_runtime \ else os.path.join(output, os.path.basename(project.src)) \ if project.get('is_package') else output if not os.path.exists(routput): logging.info('Make path: %s', routput) os.mkdir(routput) logging.info('Make runtime files to %s', routput) make_runtime(capsule, routput, platform=platform) if project.get('disable_restrict_mode'): licode = '*FLAGS:%c*CODE:PyArmor-Project' % chr(1) licfile = os.path.join(routput, license_filename) logging.info('Generate no restrict mode license file: %s', licfile) make_project_license(capsule, licode, licfile) else: logging.info('\tIn order to import obfuscated scripts, insert ') logging.info('\t2 lines in entry script:') logging.info('\t\tfrom pytransform import pyarmor_runtime') logging.info('\t\tpyarmor_runtime()') logging.info('Build project OK.')
def _obfuscate(args): '''Obfuscate scripts without project.''' platforms = compatible_platform_names(args.platforms) if platforms: logging.info('Target platforms: %s', platforms) check_cross_platform(platforms) for x in ('entry', 'cross-protection'): if getattr(args, x.replace('-', '_')) is not None: logging.warning('Option --%s has been deprecated', x) if args.src is None: if args.scripts[0].lower().endswith('.py'): path = os.path.abspath(os.path.dirname(args.scripts[0])) else: path = os.path.abspath(args.scripts[0]) args.src = path if len(args.scripts) > 1: raise RuntimeError('Only one path is allowed') args.scripts = [] else: for s in args.scripts: if not s.lower().endswith('.py'): raise RuntimeError('Only one path is allowed') path = os.path.abspath(args.src) if not os.path.exists(path): raise RuntimeError('Not found source path: %s' % path) logging.info('Source path is "%s"', path) entry = args.entry or (args.scripts and args.scripts[0]) logging.info('Entry script is %s', entry) capsule = args.capsule if args.capsule else DEFAULT_CAPSULE if os.path.exists(capsule): logging.info('Use cached capsule %s', capsule) else: logging.info('Generate capsule %s', capsule) make_capsule(capsule) output = args.output if os.path.abspath(output) == path: raise RuntimeError('Output path can not be same as src') suffix = get_name_suffix() if args.enable_suffix else '' if args.recursive: logging.info('Recursive mode is on') pats = ['global-include *.py'] if args.exclude: for item in args.exclude: for x in item.split(','): if x.endswith('.py'): logging.info('Exclude pattern "%s"', x) pats.append('exclude %s' % x) else: logging.info('Exclude path "%s"', x) pats.append('prune %s' % x) if os.path.abspath(output).startswith(path): x = os.path.abspath(output)[len(path):].strip('/\\') pats.append('prune %s' % x) logging.info('Auto exclude output path "%s"', x) if hasattr('', 'decode'): pats = [p.decode() for p in pats] files = Project.build_manifest(pats, path) elif args.exact: logging.info('Exact mode is on') files = [os.path.abspath(x) for x in args.scripts] else: logging.info('Normal mode is on') files = Project.build_globfiles(['*.py'], path) logging.info('Save obfuscated scripts to "%s"', output) if not os.path.exists(output): os.makedirs(output) logging.info('Read public key from capsule') prokey = get_product_key(capsule) logging.info('Obfuscate scripts with default mode') cross_protection = 0 if args.no_cross_protection else \ 1 if args.cross_protection is None else args.cross_protection advanced = 1 if args.advanced else 0 logging.info('Advanced mode is %d', advanced) restrict = args.restrict logging.info('Restrict mode is %d', restrict) for x in sorted(files): if os.path.isabs(x): a, b = x, os.path.join(output, os.path.basename(x)) else: a, b = os.path.join(path, x), os.path.join(output, x) logging.info('\t%s -> %s', x, b) is_entry = entry and (os.path.abspath(a) == os.path.abspath(entry)) protection = is_entry and cross_protection plugins = search_plugins(args.plugins) d = os.path.dirname(b) if not os.path.exists(d): os.makedirs(d) vmode = advanced | (8 if is_entry else 0) encrypt_script(prokey, a, b, adv_mode=vmode, rest_mode=restrict, protection=protection, platforms=platforms, plugins=plugins, suffix=suffix) logging.info('%d scripts have been obfuscated', len(files)) if (not args.no_bootstrap) and entry and os.path.exists(entry): x = args.package_runtime relative = True if x == 3 else False if x == 2 else None entryname = entry if args.src else os.path.basename(entry) if os.path.exists(os.path.join(output, entryname)): make_entry(entryname, path, output, relative=relative, suffix=suffix) else: logging.info('Use outer entry script "%s"', entry) make_entry(entry, path, output, relative=relative, suffix=suffix) if args.no_runtime: logging.info('Obfuscate %d scripts OK.', len(files)) return make_runtime(capsule, output, platforms=platforms, package=args.package_runtime, suffix=suffix) logging.info('Obfuscate scripts with restrict mode %s', 'on' if args.restrict else 'off') if not args.restrict: licode = '*FLAGS:%c*CODE:PyArmor-Project' % chr(1) licpath = os.path.join(output, 'pytransform') if args.package_runtime \ else output licfile = os.path.join(licpath, license_filename) logging.info('Generate no restrict mode license file: %s', licfile) make_project_license(capsule, licode, licfile) logging.info('Obfuscate %d scripts OK.', len(files))
def _build(args): '''Build project, obfuscate all scripts in the project.''' project = Project() project.open(args.project) logging.info('Build project %s ...', args.project) logging.info('Check project') project._check(args.project) pro_path = args.project \ if args.project == '' or os.path.exists(args.project) \ else os.path.dirname(args.project) capsule = build_path(project.capsule, pro_path) logging.info('Use capsule: %s', capsule) suffix = get_name_suffix() if project.get('enable_suffix') else '' output = build_path(project.output, pro_path) \ if args.output is None else os.path.normpath(args.output) logging.info('Output path is: %s', output) platforms = args.platforms if args.platforms else project.get('platform') platforms = compatible_platform_names(platforms) if platforms: logging.info('Taget platforms: %s', platforms) check_cross_platform(platforms) restrict = project.get('restrict_mode', 0 if project.get('disable_restrict_mode') else 1) if not args.only_runtime: src = project.src if os.path.abspath(output).startswith(src): excludes = ['prune %s' % os.path.abspath(output)[len(src) + 1:]] else: excludes = [] files = project.get_build_files(args.force, excludes=excludes) soutput = os.path.join(output, os.path.basename(src)) \ if project.get('is_package') else output logging.info('Save obfuscated scripts to "%s"', soutput) if not os.path.exists(soutput): os.makedirs(soutput) logging.info('Read public key from capsule') prokey = get_product_key(capsule) logging.info('%s increment build', 'Disable' if args.force else 'Enable') logging.info('Search scripts from %s', src) logging.info('Obfuscate scripts with mode:') if hasattr(project, 'obf_mod'): obf_mod = project.obf_mod else: obf_mod = project.obf_module_mode == 'des' if hasattr(project, 'wrap_mode'): wrap_mode = project.wrap_mode obf_code = project.obf_code elif project.obf_code_mode == 'wrap': wrap_mode = 1 obf_code = 1 else: wrap_mode = 0 obf_code = 0 if project.obf_code_mode == 'none' else 1 adv_mode = (1 if project.advanced_mode else 0) \ if hasattr(project, 'advanced_mode') else 0 def v(t): return 'on' if t else 'off' logging.info('Obfuscating the whole module is %s', v(obf_mod)) logging.info('Obfuscating each function is %s', v(obf_code)) logging.info('Autowrap each code object mode is %s', v(wrap_mode)) logging.info('Advanced mode is %s', v(adv_mode)) logging.info('Restrict mode is %s', restrict) entries = [ build_path(s.strip(), project.src) for s in project.entry.split(',') ] if project.entry else [] protection = project.cross_protection \ if hasattr(project, 'cross_protection') else 1 for x in sorted(files): a, b = os.path.join(src, x), os.path.join(soutput, x) logging.info('\t%s -> %s', x, b) d = os.path.dirname(b) if not os.path.exists(d): os.makedirs(d) if hasattr(project, 'plugins'): plugins = search_plugins(project.plugins) else: plugins = None if entries and (os.path.abspath(a) in entries): vmode = adv_mode | 8 pcode = protection else: vmode = adv_mode pcode = 0 encrypt_script(prokey, a, b, obf_code=obf_code, obf_mod=obf_mod, wrap_mode=wrap_mode, adv_mode=vmode, rest_mode=restrict, protection=pcode, platforms=platforms, plugins=plugins, rpath=project.runtime_path, suffix=suffix) logging.info('%d scripts has been obfuscated', len(files)) project['build_time'] = time.time() project.save(args.project) if project.entry: soutput = os.path.join(output, os.path.basename(project.src)) \ if project.get('is_package') else output x = project.get('package_runtime', 0) \ if args.package_runtime is None else args.package_runtime relative = True if x == 3 else \ False if (x == 2 or args.no_runtime) else None make_entry(project.entry, project.src, soutput, rpath=project.runtime_path, relative=relative, suffix=suffix) if not args.no_runtime: routput = output if args.output is not None and args.only_runtime \ else os.path.join(output, os.path.basename(project.src)) \ if project.get('is_package') else output if not os.path.exists(routput): logging.info('Make path: %s', routput) os.mkdir(routput) package = project.get('package_runtime', 0) \ if args.package_runtime is None else args.package_runtime make_runtime(capsule, routput, platforms=platforms, package=package, suffix=suffix) if not restrict: licode = '*FLAGS:%c*CODE:PyArmor-Project' % chr(1) licpath = os.path.join(routput, 'pytransform') if package \ else routput licfile = os.path.join(licpath, license_filename) logging.info('Generate no restrict mode license file: %s', licfile) make_project_license(capsule, licode, licfile) logging.info('Build project OK.')
def _licenses(args): '''Generate licenses for this project. In order to bind licenses to fixed machine, use command hdinfo to get all available hardware information: python pyarmor.py hdinfo Examples, * Expired license python pyarmor.py licenses --project=projects/myproject \ --expired=2018-05-12 Customer-Jordan * Bind license to fixed harddisk and expired someday cd projects/myproject ./pyarmor licenses -e 2018-05-12 \ --bind-disk '100304PBN2081SF3NJ5T' Customer-Tom * Batch expired licenses for many customers cd projects/myproject ./pyarmor licenses -e 2018-05-12 Customer-A Customer-B Customer-C ''' logging.info('Generate licenses for project %s ...', args.project) project = Project() project.open(args.project) licpath = os.path.join(args.project, 'licenses') if not os.path.exists(licpath): logging.info('Make output path of licenses: %s', licpath) os.mkdir(licpath) if args.expired is None: fmt = '' else: fmt = '*TIME:%.0f\n' % \ time.mktime(time.strptime(args.expired, '%Y-%m-%d')) if project.get('disable_restrict_mode'): fmt = '%s*FLAGS:%c' % (fmt, 1) if args.bind_disk: fmt = '%s*HARDDISK:%s' % (fmt, args.bind_disk) if args.bind_mac: fmt = '%s*IFMAC:%s' % (fmt, args.bind_mac) if args.bind_ipv4: fmt = '%s*IFIPV4:%s' % (fmt, args.bind_ipv4) # if args.bind_ipv6: # fmt = '%s*IFIPV6:%s' % (fmt, args.bind_ipv6) if args.bind_domain: fmt = '%s*DOMAIN:%s' % (fmt, args.bind_domain) # if args.bind_file: # if os.path.exists(args.bind_file): # f = open(args.bind_file, 'rb') # s = f.read() # f.close() # if sys.version_info[0] == 3: # fmt = '%s*FIXKEY:%s;%s' % (fmt, key, s.decode()) # else: # fmt = '%s*FIXKEY:%s;%s' % (fmt, key, s) # else: # raise RuntimeError('Bind file %s not found' % bindfile) # Prefix of registration code fmt = fmt + '*CODE:' capsule = build_path(project.capsule, args.project) for rcode in args.codes: output = os.path.join(licpath, rcode) if not os.path.exists(output): logging.info('Make path: %s', output) os.mkdir(output) licfile = os.path.join(output, license_filename) licode = fmt + rcode txtinfo = licode.replace('\n', r'\n') if args.expired: txtinfo = '"Expired:%s%s"' % (args.expired, txtinfo[txtinfo.find(r'\n') + 2:]) logging.info('Generate license: %s', txtinfo) make_project_license(capsule, licode, licfile) logging.info('Write license file: %s', licfile) logging.info('Write information to %s.txt', licfile) with open(os.path.join(licfile + '.txt'), 'w') as f: f.write(txtinfo) logging.info('Generate %d licenses OK.', len(args.codes))