Advertisement
Guest User

Untitled

a guest
Aug 21st, 2019
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.24 KB | None | 0 0
  1. import os
  2. import re
  3. import sys
  4.  
  5.  
  6. class Format(object):
  7. hpp = '''\
  8. #ifndef {0}
  9. #define {0}
  10. {1}
  11. {2}
  12. {3}
  13. #endif'''
  14.  
  15. @classmethod
  16. def hpp_beutifier(cls, source):
  17. out = ''
  18. n_blank = 0
  19. for line in source.split('\n'):
  20. if line == '' or line.isspace():
  21. n_blank += 1
  22. else:
  23. if n_blank > 2:
  24. n_blank = 2
  25.  
  26. out += '\n' * n_blank
  27. n_blank = 0
  28.  
  29. out += line + '\n'
  30. return out
  31.  
  32.  
  33. class ReSupport(object):
  34. r_guard = re.compile(r'(#ifndef|#endif)')
  35. r_include_dep = re.compile(r'#include "(.+?)"')
  36. r_include = re.compile(r'#include <(.+?)>')
  37. r_define = re.compile(r'#define (.+)')
  38.  
  39. @classmethod
  40. def guard(cls, inp):
  41. return cls.r_guard.findall(inp)
  42.  
  43. @classmethod
  44. def include_dep(cls, inp):
  45. return cls.r_include_dep.findall(inp)
  46.  
  47. @classmethod
  48. def include(cls, inp):
  49. return cls.r_include.findall(inp)
  50.  
  51. @classmethod
  52. def define(cls, inp):
  53. return cls.r_define.findall(inp)
  54.  
  55.  
  56. class SourceInfo(object):
  57. def __init__(self):
  58. self.out = ''
  59. self.deps = []
  60. self.includes = []
  61. self.defines = []
  62.  
  63. @classmethod
  64. def set_with(cls, out, deps, includes, defines):
  65. obj = cls()
  66. obj.out = out
  67. obj.deps = deps
  68. obj.includes = includes
  69. obj.defines = defines
  70. return obj
  71.  
  72. @classmethod
  73. def read_file(cls, path):
  74. obj = cls()
  75. with open(path) as f:
  76. for line in f.readlines():
  77. if len(ReSupport.guard(line)) > 0:
  78. continue
  79.  
  80. include_name = ReSupport.include_dep(line)
  81. if len(include_name) > 0:
  82. obj.deps.append(include_name[0])
  83. continue
  84.  
  85. include_name = ReSupport.include(line)
  86. if len(include_name) > 0:
  87. obj.includes.append(include_name[0])
  88. continue
  89.  
  90. define_name = ReSupport.define(line)
  91. if len(define_name) > 0:
  92. obj.defines.append(define_name[0])
  93. continue
  94.  
  95. obj.out += line
  96. return obj
  97.  
  98. def __add__(self, other):
  99. out = self.out + other.out
  100. deps = self.deps + other.deps
  101. includes = self.includes + other.includes
  102. defines = self.defines + other.defines
  103. return SourceInfo.set_with(out, deps, includes, defines)
  104.  
  105.  
  106. def file_list(dirname, ban_dir=[]):
  107. files = []
  108. if isinstance(ban_dir, str):
  109. ban_dir = [ban_dir]
  110.  
  111. for name in os.listdir(dirname):
  112. full_path = os.path.join(dirname, name)
  113. if os.path.isfile(full_path):
  114. files.append(full_path)
  115. elif os.path.isdir(full_path) and name not in ban_dir:
  116. files += file_list(full_path)
  117. return files
  118.  
  119.  
  120. def in_endswith(name, files):
  121. for f in files:
  122. if f.endswith(name):
  123. return f
  124. return None
  125.  
  126.  
  127. def order_dep(deps, files, done):
  128. info = SourceInfo()
  129. for dep in deps:
  130. if in_endswith(dep, done) is None:
  131. path = in_endswith(dep.split('/')[-1], files)
  132.  
  133. if path is not None:
  134. new = SourceInfo.read_file(path)
  135. dep_new = order_dep(new.deps, files, done)
  136.  
  137. info += dep_new + new
  138. done.append(path)
  139.  
  140. return info
  141.  
  142.  
  143. def none_preproc(dirname):
  144. if not os.path.exists(dirname):
  145. return [], ''
  146.  
  147. dep = []
  148. out = ''
  149. includes = ''
  150. for files in os.listdir(dirname):
  151. with open(os.path.join(dirname, files)) as f:
  152. lines = f.readlines()
  153.  
  154. if lines[0].startswith('#ifndef') \
  155. and lines[1].startswith('#define') \
  156. and lines[-1].startswith('#endif'):
  157. lines = lines[2:-1]
  158.  
  159. data = ''.join(lines)
  160.  
  161. include_idx = data.find('// merge:np_include')
  162. if include_idx != -1:
  163. start_idx = include_idx + len('// merge:np_include')
  164. end_idx = data.find('// merge:end', include_idx)
  165.  
  166. includes += data[start_idx:end_idx]
  167. data = data[end_idx + len('// merge:end'):]
  168.  
  169. include_idx = data.find('// merge:include')
  170. if include_idx != -1:
  171. start_idx = include_idx + len('// merge:include')
  172. end_idx = data.find('// merge:end', include_idx)
  173.  
  174. for line in data[start_idx:end_idx].split('\n'):
  175. res = ReSupport.include(line)
  176. if len(res) > 0:
  177. dep += res
  178. includes += line + '\n'
  179.  
  180. data = data[end_idx + len('// merge:end'):]
  181.  
  182. dep.append(files)
  183. out += data
  184.  
  185. return dep, includes + out
  186.  
  187.  
  188. def merge(dirname):
  189. done = []
  190. info = SourceInfo()
  191. files = file_list(dirname, 'platform')
  192.  
  193. preproc_dep, info.out = \
  194. none_preproc(os.path.join(dirname, 'platform'))
  195.  
  196. for full_path in files:
  197. if full_path not in done:
  198. source = SourceInfo.read_file(full_path)
  199. dep = order_dep(source.deps, files, done)
  200.  
  201. info += dep + source
  202. done.append(full_path)
  203.  
  204. return info, preproc_dep
  205.  
  206.  
  207. def write_hpp(outfile, merged):
  208. info, preproc_dep = merged
  209. dep_check = lambda file: not any(file.endswith(dep) for dep in preproc_dep)
  210.  
  211. idx = outfile.rfind('/')
  212. if idx > -1:
  213. outfile = outfile[idx+1:]
  214. guard_name = outfile.upper().replace('.', '_')
  215.  
  216. unique_include = []
  217.  
  218. for include in info.includes:
  219. if include not in unique_include and dep_check(include):
  220. unique_include.append(include)
  221.  
  222. includes = '\n'.join(
  223. '#include <{}>'.format(x) for x in sorted(unique_include)) + '\n'
  224. defines = '\n'.join(
  225. '#define {}'.format(x) for x in info.defines) + '\n'
  226.  
  227. out = Format.hpp.format(guard_name, includes, defines, info.out)
  228. out = Format.hpp_beutifier(out)
  229.  
  230. with open(outfile, 'w') as f:
  231. f.write(out)
  232.  
  233. if __name__ == "__main__":
  234. if len(sys.argv) > 1:
  235. outfile = sys.argv[1]
  236. else:
  237. outfile = './obfuscator.hpp'
  238.  
  239. if len(sys.argv) > 2:
  240. dirname = sys.argv[2]
  241. else:
  242. dirname = './obfuscator/obfs'
  243.  
  244. merged = merge(dirname)
  245. write_hpp(outfile, merged)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement