Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import os
- import re
- import sys
- class Format(object):
- hpp = '''\
- #ifndef {0}
- #define {0}
- {1}
- {2}
- {3}
- #endif'''
- @classmethod
- def hpp_beutifier(cls, source):
- out = ''
- n_blank = 0
- for line in source.split('\n'):
- if line == '' or line.isspace():
- n_blank += 1
- else:
- if n_blank > 2:
- n_blank = 2
- out += '\n' * n_blank
- n_blank = 0
- out += line + '\n'
- return out
- class ReSupport(object):
- r_guard = re.compile(r'(#ifndef|#endif)')
- r_include_dep = re.compile(r'#include "(.+?)"')
- r_include = re.compile(r'#include <(.+?)>')
- r_define = re.compile(r'#define (.+)')
- @classmethod
- def guard(cls, inp):
- return cls.r_guard.findall(inp)
- @classmethod
- def include_dep(cls, inp):
- return cls.r_include_dep.findall(inp)
- @classmethod
- def include(cls, inp):
- return cls.r_include.findall(inp)
- @classmethod
- def define(cls, inp):
- return cls.r_define.findall(inp)
- class SourceInfo(object):
- def __init__(self):
- self.out = ''
- self.deps = []
- self.includes = []
- self.defines = []
- @classmethod
- def set_with(cls, out, deps, includes, defines):
- obj = cls()
- obj.out = out
- obj.deps = deps
- obj.includes = includes
- obj.defines = defines
- return obj
- @classmethod
- def read_file(cls, path):
- obj = cls()
- with open(path) as f:
- for line in f.readlines():
- if len(ReSupport.guard(line)) > 0:
- continue
- include_name = ReSupport.include_dep(line)
- if len(include_name) > 0:
- obj.deps.append(include_name[0])
- continue
- include_name = ReSupport.include(line)
- if len(include_name) > 0:
- obj.includes.append(include_name[0])
- continue
- define_name = ReSupport.define(line)
- if len(define_name) > 0:
- obj.defines.append(define_name[0])
- continue
- obj.out += line
- return obj
- def __add__(self, other):
- out = self.out + other.out
- deps = self.deps + other.deps
- includes = self.includes + other.includes
- defines = self.defines + other.defines
- return SourceInfo.set_with(out, deps, includes, defines)
- def file_list(dirname, ban_dir=[]):
- files = []
- if isinstance(ban_dir, str):
- ban_dir = [ban_dir]
- for name in os.listdir(dirname):
- full_path = os.path.join(dirname, name)
- if os.path.isfile(full_path):
- files.append(full_path)
- elif os.path.isdir(full_path) and name not in ban_dir:
- files += file_list(full_path)
- return files
- def in_endswith(name, files):
- for f in files:
- if f.endswith(name):
- return f
- return None
- def order_dep(deps, files, done):
- info = SourceInfo()
- for dep in deps:
- if in_endswith(dep, done) is None:
- path = in_endswith(dep.split('/')[-1], files)
- if path is not None:
- new = SourceInfo.read_file(path)
- dep_new = order_dep(new.deps, files, done)
- info += dep_new + new
- done.append(path)
- return info
- def none_preproc(dirname):
- if not os.path.exists(dirname):
- return [], ''
- dep = []
- out = ''
- includes = ''
- for files in os.listdir(dirname):
- with open(os.path.join(dirname, files)) as f:
- lines = f.readlines()
- if lines[0].startswith('#ifndef') \
- and lines[1].startswith('#define') \
- and lines[-1].startswith('#endif'):
- lines = lines[2:-1]
- data = ''.join(lines)
- include_idx = data.find('// merge:np_include')
- if include_idx != -1:
- start_idx = include_idx + len('// merge:np_include')
- end_idx = data.find('// merge:end', include_idx)
- includes += data[start_idx:end_idx]
- data = data[end_idx + len('// merge:end'):]
- include_idx = data.find('// merge:include')
- if include_idx != -1:
- start_idx = include_idx + len('// merge:include')
- end_idx = data.find('// merge:end', include_idx)
- for line in data[start_idx:end_idx].split('\n'):
- res = ReSupport.include(line)
- if len(res) > 0:
- dep += res
- includes += line + '\n'
- data = data[end_idx + len('// merge:end'):]
- dep.append(files)
- out += data
- return dep, includes + out
- def merge(dirname):
- done = []
- info = SourceInfo()
- files = file_list(dirname, 'platform')
- preproc_dep, info.out = \
- none_preproc(os.path.join(dirname, 'platform'))
- for full_path in files:
- if full_path not in done:
- source = SourceInfo.read_file(full_path)
- dep = order_dep(source.deps, files, done)
- info += dep + source
- done.append(full_path)
- return info, preproc_dep
- def write_hpp(outfile, merged):
- info, preproc_dep = merged
- dep_check = lambda file: not any(file.endswith(dep) for dep in preproc_dep)
- idx = outfile.rfind('/')
- if idx > -1:
- outfile = outfile[idx+1:]
- guard_name = outfile.upper().replace('.', '_')
- unique_include = []
- for include in info.includes:
- if include not in unique_include and dep_check(include):
- unique_include.append(include)
- includes = '\n'.join(
- '#include <{}>'.format(x) for x in sorted(unique_include)) + '\n'
- defines = '\n'.join(
- '#define {}'.format(x) for x in info.defines) + '\n'
- out = Format.hpp.format(guard_name, includes, defines, info.out)
- out = Format.hpp_beutifier(out)
- with open(outfile, 'w') as f:
- f.write(out)
- if __name__ == "__main__":
- if len(sys.argv) > 1:
- outfile = sys.argv[1]
- else:
- outfile = './obfuscator.hpp'
- if len(sys.argv) > 2:
- dirname = sys.argv[2]
- else:
- dirname = './obfuscator/obfs'
- merged = merge(dirname)
- write_hpp(outfile, merged)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement