From 047f49616fd922ffcb5c874604846c07a03d49db Mon Sep 17 00:00:00 2001 From: wiki-bot Date: Sat, 16 Aug 2025 04:25:56 +0000 Subject: [PATCH] docs: update doxygen site from 2645951 --- Doxygen.md | 5 + doxygen/README_8md.html | 106 + doxygen/annotated.html | 140 ++ doxygen/annotated_dup.js | 46 + doxygen/attribute__transformer_8py.html | 124 + doxygen/attribute__transformer_8py.js | 4 + .../attribute__transformer_8py_source.html | 193 ++ doxygen/bc_s.png | Bin 0 -> 676 bytes doxygen/bc_sd.png | Bin 0 -> 635 bytes doxygen/class__analyzer_8py.html | 134 ++ doxygen/class__analyzer_8py.js | 7 + doxygen/class__analyzer_8py_source.html | 385 ++++ doxygen/class__mapper_8py.html | 142 ++ doxygen/class__mapper_8py.js | 9 + doxygen/class__mapper_8py_source.html | 529 +++++ doxygen/classes.html | 129 ++ ...uscator_1_1AdvancedObfuscator-members.html | 127 + ...classobfuscator_1_1AdvancedObfuscator.html | 953 ++++++++ .../classobfuscator_1_1AdvancedObfuscator.js | 22 + ...ormer_1_1AttributeTransformer-members.html | 114 + ...__transformer_1_1AttributeTransformer.html | 368 +++ ...te__transformer_1_1AttributeTransformer.js | 9 + ...r_1_1AttributeTransformer__coll__graph.dot | 10 + ..._1AttributeTransformer__inherit__graph.dot | 10 + ...ss__analyzer_1_1ClassAnalyzer-members.html | 118 + ...s_1_1class__analyzer_1_1ClassAnalyzer.html | 624 +++++ ...ers_1_1class__analyzer_1_1ClassAnalyzer.js | 13 + ...analyzer_1_1ClassAnalyzer__coll__graph.dot | 10 + ...lyzer_1_1ClassAnalyzer__inherit__graph.dot | 10 + ...s__analyzer_1_1ClassMethodMap-members.html | 109 + ..._1_1class__analyzer_1_1ClassMethodMap.html | 159 ++ ...rs_1_1class__analyzer_1_1ClassMethodMap.js | 4 + ...s__mapper_1_1ClassMapAnalyzer-members.html | 121 + ..._1_1class__mapper_1_1ClassMapAnalyzer.html | 745 ++++++ ...rs_1_1class__mapper_1_1ClassMapAnalyzer.js | 16 + ...apper_1_1ClassMapAnalyzer__coll__graph.dot | 10 + ...er_1_1ClassMapAnalyzer__inherit__graph.dot | 10 + ...class__mapper_1_1ClassMapping-members.html | 110 + ...mers_1_1class__mapper_1_1ClassMapping.html | 207 ++ ...ormers_1_1class__mapper_1_1ClassMapping.js | 5 + ...s__mapper_1_1ClassTransformer-members.html | 114 + ..._1_1class__mapper_1_1ClassTransformer.html | 392 ++++ ...rs_1_1class__mapper_1_1ClassTransformer.js | 9 + ...apper_1_1ClassTransformer__coll__graph.dot | 10 + ...er_1_1ClassTransformer__inherit__graph.dot | 10 + ..._flow_1_1ControlFlowFlattener-members.html | 124 + ...control__flow_1_1ControlFlowFlattener.html | 1102 +++++++++ ..._1control__flow_1_1ControlFlowFlattener.js | 19 + ...w_1_1ControlFlowFlattener__coll__graph.dot | 10 + ..._1ControlFlowFlattener__inherit__graph.dot | 10 + ..._1rename_1_1RenameTransformer-members.html | 141 ++ ...ormers_1_1rename_1_1RenameTransformer.html | 1570 +++++++++++++ ...sformers_1_1rename_1_1RenameTransformer.js | 36 + ...name_1_1RenameTransformer__coll__graph.dot | 10 + ...e_1_1RenameTransformer__inherit__graph.dot | 10 + ...1_1symbol__tree_1_1ClassScope-members.html | 112 + ...formers_1_1symbol__tree_1_1ClassScope.html | 322 +++ ...nsformers_1_1symbol__tree_1_1ClassScope.js | 7 + ...ymbol__tree_1_1ClassScope__coll__graph.dot | 10 + ...ol__tree_1_1ClassScope__inherit__graph.dot | 10 + ..._1symbol__tree_1_1ModuleScope-members.html | 111 + ...ormers_1_1symbol__tree_1_1ModuleScope.html | 298 +++ ...sformers_1_1symbol__tree_1_1ModuleScope.js | 6 + ...mbol__tree_1_1ModuleScope__coll__graph.dot | 10 + ...l__tree_1_1ModuleScope__inherit__graph.dot | 10 + ...mers_1_1symbol__tree_1_1Scope-members.html | 117 + ...transformers_1_1symbol__tree_1_1Scope.html | 428 ++++ ...sstransformers_1_1symbol__tree_1_1Scope.js | 12 + ...1symbol__tree_1_1Scope__inherit__graph.dot | 12 + ...ers_1_1symbol__tree_1_1Symbol-members.html | 116 + ...ransformers_1_1symbol__tree_1_1Symbol.html | 337 +++ ...stransformers_1_1symbol__tree_1_1Symbol.js | 11 + ...1_1symbol__tree_1_1SymbolTree-members.html | 119 + ...formers_1_1symbol__tree_1_1SymbolTree.html | 666 ++++++ ...nsformers_1_1symbol__tree_1_1SymbolTree.js | 14 + ...ol__tree_1_1SymbolTreeBuilder-members.html | 125 + ..._1_1symbol__tree_1_1SymbolTreeBuilder.html | 827 +++++++ ...rs_1_1symbol__tree_1_1SymbolTreeBuilder.js | 20 + ...tree_1_1SymbolTreeBuilder__coll__graph.dot | 10 + ...e_1_1SymbolTreeBuilder__inherit__graph.dot | 10 + ...1_1symbol__tree_1_1SymbolType-members.html | 116 + ...formers_1_1symbol__tree_1_1SymbolType.html | 342 +++ ...nsformers_1_1symbol__tree_1_1SymbolType.js | 11 + ...ymbol__tree_1_1SymbolType__coll__graph.dot | 10 + ...ol__tree_1_1SymbolType__inherit__graph.dot | 10 + ...encryption_1_1StringEncryptor-members.html | 114 + ...tils_1_1encryption_1_1StringEncryptor.html | 396 ++++ ...sutils_1_1encryption_1_1StringEncryptor.js | 9 + ...1_1junk__gen_1_1JunkGenerator-members.html | 112 + ...ssutils_1_1junk__gen_1_1JunkGenerator.html | 289 +++ ...lassutils_1_1junk__gen_1_1JunkGenerator.js | 7 + ...1_1name__gen_1_1NameGenerator-members.html | 113 + ...ssutils_1_1name__gen_1_1NameGenerator.html | 293 +++ ...lassutils_1_1name__gen_1_1NameGenerator.js | 8 + doxygen/closed.png | Bin 0 -> 132 bytes doxygen/control__flow_8py.html | 132 ++ doxygen/control__flow_8py.js | 6 + doxygen/control__flow_8py_source.html | 646 ++++++ .../dir_33a1d53dde8f74081d79f81ccfb4e6df.html | 124 + .../dir_33a1d53dde8f74081d79f81ccfb4e6df.js | 10 + .../dir_cbdb8362360e11eafe2fa3bc74cf0ffd.html | 118 + .../dir_cbdb8362360e11eafe2fa3bc74cf0ffd.js | 7 + doxygen/doc.svg | 12 + doxygen/docd.svg | 12 + doxygen/doxygen.css | 2045 +++++++++++++++++ doxygen/doxygen.svg | 28 + doxygen/dynsections.js | 199 ++ doxygen/encryption_8py.html | 124 + doxygen/encryption_8py.js | 4 + doxygen/encryption_8py_source.html | 229 ++ doxygen/files.html | 124 + doxygen/files_dup.js | 7 + doxygen/folderclosed.svg | 11 + doxygen/folderclosedd.svg | 11 + doxygen/folderopen.svg | 17 + doxygen/folderopend.svg | 12 + doxygen/functions.html | 307 +++ doxygen/functions_func.html | 232 ++ doxygen/functions_vars.html | 221 ++ doxygen/graph_legend.dot | 24 + doxygen/graph_legend.html | 165 ++ doxygen/hierarchy.html | 133 ++ doxygen/hierarchy.js | 29 + doxygen/index.html | 218 ++ doxygen/inherit_graph_0.dot | 17 + doxygen/inherit_graph_1.dot | 15 + doxygen/inherit_graph_10.dot | 9 + doxygen/inherit_graph_11.dot | 9 + doxygen/inherit_graph_2.dot | 11 + doxygen/inherit_graph_3.dot | 9 + doxygen/inherit_graph_4.dot | 9 + doxygen/inherit_graph_5.dot | 9 + doxygen/inherit_graph_6.dot | 13 + doxygen/inherit_graph_7.dot | 9 + doxygen/inherit_graph_8.dot | 9 + doxygen/inherit_graph_9.dot | 9 + doxygen/inherits.html | 133 ++ doxygen/jquery.js | 34 + doxygen/junk__gen_8py.html | 124 + doxygen/junk__gen_8py.js | 4 + doxygen/junk__gen_8py_source.html | 195 ++ doxygen/main_8py.html | 122 + doxygen/main_8py.js | 4 + doxygen/main_8py_source.html | 212 ++ doxygen/menu.js | 136 ++ doxygen/menudata.js | 97 + doxygen/minus.svg | 8 + doxygen/minusd.svg | 8 + doxygen/name__gen_8py.html | 124 + doxygen/name__gen_8py.js | 4 + doxygen/name__gen_8py_source.html | 167 ++ doxygen/namespacemain.html | 228 ++ doxygen/namespacemembers.html | 110 + doxygen/namespacemembers_func.html | 108 + doxygen/namespacemembers_vars.html | 106 + doxygen/namespaceobfuscator.html | 120 + doxygen/namespaceobfuscator.js | 4 + doxygen/namespaces.html | 141 ++ doxygen/namespaces_dup.js | 9 + doxygen/namespacetransformers.html | 130 ++ doxygen/namespacetransformers.js | 9 + ...ransformers_1_1attribute__transformer.html | 119 + ...etransformers_1_1attribute__transformer.js | 4 + ...espacetransformers_1_1class__analyzer.html | 224 ++ ...amespacetransformers_1_1class__analyzer.js | 7 + ...amespacetransformers_1_1class__mapper.html | 221 ++ .../namespacetransformers_1_1class__mapper.js | 9 + ...amespacetransformers_1_1control__flow.html | 160 ++ .../namespacetransformers_1_1control__flow.js | 6 + doxygen/namespacetransformers_1_1rename.html | 160 ++ doxygen/namespacetransformers_1_1rename.js | 6 + ...namespacetransformers_1_1symbol__tree.html | 173 ++ .../namespacetransformers_1_1symbol__tree.js | 12 + doxygen/namespaceutils.html | 123 + doxygen/namespaceutils.js | 6 + doxygen/namespaceutils_1_1encryption.html | 120 + doxygen/namespaceutils_1_1encryption.js | 4 + doxygen/namespaceutils_1_1junk__gen.html | 118 + doxygen/namespaceutils_1_1junk__gen.js | 4 + doxygen/namespaceutils_1_1name__gen.html | 119 + doxygen/namespaceutils_1_1name__gen.js | 4 + doxygen/nav_f.png | Bin 0 -> 153 bytes doxygen/nav_fd.png | Bin 0 -> 169 bytes doxygen/nav_g.png | Bin 0 -> 95 bytes doxygen/nav_h.png | Bin 0 -> 98 bytes doxygen/nav_hd.png | Bin 0 -> 114 bytes doxygen/navtree.css | 149 ++ doxygen/navtree.js | 559 +++++ doxygen/navtreedata.js | 69 + doxygen/navtreeindex0.js | 253 ++ doxygen/navtreeindex1.js | 241 ++ doxygen/obfuscator_8py.html | 122 + doxygen/obfuscator_8py.js | 4 + doxygen/obfuscator_8py_source.html | 463 ++++ doxygen/open.png | Bin 0 -> 123 bytes doxygen/plus.svg | 9 + doxygen/plusd.svg | 9 + doxygen/rename_8py.html | 132 ++ doxygen/rename_8py.js | 6 + doxygen/rename_8py_source.html | 627 +++++ doxygen/resize.js | 155 ++ doxygen/search/all_0.js | 16 + doxygen/search/all_1.js | 22 + doxygen/search/all_10.js | 7 + doxygen/search/all_11.js | 9 + doxygen/search/all_12.js | 20 + doxygen/search/all_13.js | 12 + doxygen/search/all_14.js | 11 + doxygen/search/all_15.js | 32 + doxygen/search/all_2.js | 4 + doxygen/search/all_3.js | 25 + doxygen/search/all_4.js | 10 + doxygen/search/all_5.js | 6 + doxygen/search/all_6.js | 8 + doxygen/search/all_7.js | 10 + doxygen/search/all_8.js | 4 + doxygen/search/all_9.js | 10 + doxygen/search/all_a.js | 6 + doxygen/search/all_b.js | 4 + doxygen/search/all_c.js | 10 + doxygen/search/all_d.js | 10 + doxygen/search/all_e.js | 9 + doxygen/search/all_f.js | 7 + doxygen/search/classes_0.js | 5 + doxygen/search/classes_1.js | 10 + doxygen/search/classes_2.js | 4 + doxygen/search/classes_3.js | 4 + doxygen/search/classes_4.js | 4 + doxygen/search/classes_5.js | 4 + doxygen/search/classes_6.js | 9 + doxygen/search/close.svg | 18 + doxygen/search/files_0.js | 4 + doxygen/search/files_1.js | 6 + doxygen/search/files_2.js | 4 + doxygen/search/files_3.js | 4 + doxygen/search/files_4.js | 4 + doxygen/search/files_5.js | 4 + doxygen/search/files_6.js | 4 + doxygen/search/files_7.js | 5 + doxygen/search/files_8.js | 4 + doxygen/search/files_9.js | 4 + doxygen/search/files_a.js | 4 + doxygen/search/functions_0.js | 15 + doxygen/search/functions_1.js | 15 + doxygen/search/functions_10.js | 31 + doxygen/search/functions_2.js | 4 + doxygen/search/functions_3.js | 4 + doxygen/search/functions_4.js | 5 + doxygen/search/functions_5.js | 4 + doxygen/search/functions_6.js | 4 + doxygen/search/functions_7.js | 9 + doxygen/search/functions_8.js | 4 + doxygen/search/functions_9.js | 5 + doxygen/search/functions_a.js | 4 + doxygen/search/functions_b.js | 4 + doxygen/search/functions_c.js | 5 + doxygen/search/functions_d.js | 4 + doxygen/search/functions_e.js | 4 + doxygen/search/functions_f.js | 4 + doxygen/search/mag.svg | 24 + doxygen/search/mag_d.svg | 24 + doxygen/search/mag_sel.svg | 31 + doxygen/search/mag_seld.svg | 31 + doxygen/search/namespaces_0.js | 4 + doxygen/search/namespaces_1.js | 4 + doxygen/search/namespaces_2.js | 10 + doxygen/search/namespaces_3.js | 7 + doxygen/search/pages_0.js | 4 + doxygen/search/pages_1.js | 4 + doxygen/search/search.css | 291 +++ doxygen/search/search.js | 840 +++++++ doxygen/search/searchdata.js | 33 + doxygen/search/variables_0.js | 4 + doxygen/search/variables_1.js | 5 + doxygen/search/variables_10.js | 4 + doxygen/search/variables_11.js | 4 + doxygen/search/variables_12.js | 4 + doxygen/search/variables_2.js | 13 + doxygen/search/variables_3.js | 5 + doxygen/search/variables_4.js | 4 + doxygen/search/variables_5.js | 5 + doxygen/search/variables_6.js | 4 + doxygen/search/variables_7.js | 9 + doxygen/search/variables_8.js | 4 + doxygen/search/variables_9.js | 4 + doxygen/search/variables_a.js | 5 + doxygen/search/variables_b.js | 7 + doxygen/search/variables_c.js | 6 + doxygen/search/variables_d.js | 4 + doxygen/search/variables_e.js | 4 + doxygen/search/variables_f.js | 11 + doxygen/splitbar.png | Bin 0 -> 314 bytes doxygen/splitbard.png | Bin 0 -> 282 bytes doxygen/symbol__tree_8py.html | 144 ++ doxygen/symbol__tree_8py.js | 12 + doxygen/symbol__tree_8py_source.html | 816 +++++++ doxygen/sync_off.png | Bin 0 -> 853 bytes doxygen/sync_on.png | Bin 0 -> 845 bytes doxygen/tab_a.png | Bin 0 -> 142 bytes doxygen/tab_ad.png | Bin 0 -> 135 bytes doxygen/tab_b.png | Bin 0 -> 169 bytes doxygen/tab_bd.png | Bin 0 -> 173 bytes doxygen/tab_h.png | Bin 0 -> 177 bytes doxygen/tab_hd.png | Bin 0 -> 180 bytes doxygen/tab_s.png | Bin 0 -> 184 bytes doxygen/tab_sd.png | Bin 0 -> 188 bytes doxygen/tabs.css | 1 + doxygen/transformers_2____init_____8py.html | 116 + ...transformers_2____init_____8py_source.html | 118 + doxygen/utils_2____init_____8py.html | 116 + doxygen/utils_2____init_____8py_source.html | 117 + 311 files changed, 30358 insertions(+) create mode 100644 Doxygen.md create mode 100644 doxygen/README_8md.html create mode 100644 doxygen/annotated.html create mode 100644 doxygen/annotated_dup.js create mode 100644 doxygen/attribute__transformer_8py.html create mode 100644 doxygen/attribute__transformer_8py.js create mode 100644 doxygen/attribute__transformer_8py_source.html create mode 100644 doxygen/bc_s.png create mode 100644 doxygen/bc_sd.png create mode 100644 doxygen/class__analyzer_8py.html create mode 100644 doxygen/class__analyzer_8py.js create mode 100644 doxygen/class__analyzer_8py_source.html create mode 100644 doxygen/class__mapper_8py.html create mode 100644 doxygen/class__mapper_8py.js create mode 100644 doxygen/class__mapper_8py_source.html create mode 100644 doxygen/classes.html create mode 100644 doxygen/classobfuscator_1_1AdvancedObfuscator-members.html create mode 100644 doxygen/classobfuscator_1_1AdvancedObfuscator.html create mode 100644 doxygen/classobfuscator_1_1AdvancedObfuscator.js create mode 100644 doxygen/classtransformers_1_1attribute__transformer_1_1AttributeTransformer-members.html create mode 100644 doxygen/classtransformers_1_1attribute__transformer_1_1AttributeTransformer.html create mode 100644 doxygen/classtransformers_1_1attribute__transformer_1_1AttributeTransformer.js create mode 100644 doxygen/classtransformers_1_1attribute__transformer_1_1AttributeTransformer__coll__graph.dot create mode 100644 doxygen/classtransformers_1_1attribute__transformer_1_1AttributeTransformer__inherit__graph.dot create mode 100644 doxygen/classtransformers_1_1class__analyzer_1_1ClassAnalyzer-members.html create mode 100644 doxygen/classtransformers_1_1class__analyzer_1_1ClassAnalyzer.html create mode 100644 doxygen/classtransformers_1_1class__analyzer_1_1ClassAnalyzer.js create mode 100644 doxygen/classtransformers_1_1class__analyzer_1_1ClassAnalyzer__coll__graph.dot create mode 100644 doxygen/classtransformers_1_1class__analyzer_1_1ClassAnalyzer__inherit__graph.dot create mode 100644 doxygen/classtransformers_1_1class__analyzer_1_1ClassMethodMap-members.html create mode 100644 doxygen/classtransformers_1_1class__analyzer_1_1ClassMethodMap.html create mode 100644 doxygen/classtransformers_1_1class__analyzer_1_1ClassMethodMap.js create mode 100644 doxygen/classtransformers_1_1class__mapper_1_1ClassMapAnalyzer-members.html create mode 100644 doxygen/classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html create mode 100644 doxygen/classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.js create mode 100644 doxygen/classtransformers_1_1class__mapper_1_1ClassMapAnalyzer__coll__graph.dot create mode 100644 doxygen/classtransformers_1_1class__mapper_1_1ClassMapAnalyzer__inherit__graph.dot create mode 100644 doxygen/classtransformers_1_1class__mapper_1_1ClassMapping-members.html create mode 100644 doxygen/classtransformers_1_1class__mapper_1_1ClassMapping.html create mode 100644 doxygen/classtransformers_1_1class__mapper_1_1ClassMapping.js create mode 100644 doxygen/classtransformers_1_1class__mapper_1_1ClassTransformer-members.html create mode 100644 doxygen/classtransformers_1_1class__mapper_1_1ClassTransformer.html create mode 100644 doxygen/classtransformers_1_1class__mapper_1_1ClassTransformer.js create mode 100644 doxygen/classtransformers_1_1class__mapper_1_1ClassTransformer__coll__graph.dot create mode 100644 doxygen/classtransformers_1_1class__mapper_1_1ClassTransformer__inherit__graph.dot create mode 100644 doxygen/classtransformers_1_1control__flow_1_1ControlFlowFlattener-members.html create mode 100644 doxygen/classtransformers_1_1control__flow_1_1ControlFlowFlattener.html create mode 100644 doxygen/classtransformers_1_1control__flow_1_1ControlFlowFlattener.js create mode 100644 doxygen/classtransformers_1_1control__flow_1_1ControlFlowFlattener__coll__graph.dot create mode 100644 doxygen/classtransformers_1_1control__flow_1_1ControlFlowFlattener__inherit__graph.dot create mode 100644 doxygen/classtransformers_1_1rename_1_1RenameTransformer-members.html create mode 100644 doxygen/classtransformers_1_1rename_1_1RenameTransformer.html create mode 100644 doxygen/classtransformers_1_1rename_1_1RenameTransformer.js create mode 100644 doxygen/classtransformers_1_1rename_1_1RenameTransformer__coll__graph.dot create mode 100644 doxygen/classtransformers_1_1rename_1_1RenameTransformer__inherit__graph.dot create mode 100644 doxygen/classtransformers_1_1symbol__tree_1_1ClassScope-members.html create mode 100644 doxygen/classtransformers_1_1symbol__tree_1_1ClassScope.html create mode 100644 doxygen/classtransformers_1_1symbol__tree_1_1ClassScope.js create mode 100644 doxygen/classtransformers_1_1symbol__tree_1_1ClassScope__coll__graph.dot create mode 100644 doxygen/classtransformers_1_1symbol__tree_1_1ClassScope__inherit__graph.dot create mode 100644 doxygen/classtransformers_1_1symbol__tree_1_1ModuleScope-members.html create mode 100644 doxygen/classtransformers_1_1symbol__tree_1_1ModuleScope.html create mode 100644 doxygen/classtransformers_1_1symbol__tree_1_1ModuleScope.js create mode 100644 doxygen/classtransformers_1_1symbol__tree_1_1ModuleScope__coll__graph.dot create mode 100644 doxygen/classtransformers_1_1symbol__tree_1_1ModuleScope__inherit__graph.dot create mode 100644 doxygen/classtransformers_1_1symbol__tree_1_1Scope-members.html create mode 100644 doxygen/classtransformers_1_1symbol__tree_1_1Scope.html create mode 100644 doxygen/classtransformers_1_1symbol__tree_1_1Scope.js create mode 100644 doxygen/classtransformers_1_1symbol__tree_1_1Scope__inherit__graph.dot create mode 100644 doxygen/classtransformers_1_1symbol__tree_1_1Symbol-members.html create mode 100644 doxygen/classtransformers_1_1symbol__tree_1_1Symbol.html create mode 100644 doxygen/classtransformers_1_1symbol__tree_1_1Symbol.js create mode 100644 doxygen/classtransformers_1_1symbol__tree_1_1SymbolTree-members.html create mode 100644 doxygen/classtransformers_1_1symbol__tree_1_1SymbolTree.html create mode 100644 doxygen/classtransformers_1_1symbol__tree_1_1SymbolTree.js create mode 100644 doxygen/classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder-members.html create mode 100644 doxygen/classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html create mode 100644 doxygen/classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.js create mode 100644 doxygen/classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder__coll__graph.dot create mode 100644 doxygen/classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder__inherit__graph.dot create mode 100644 doxygen/classtransformers_1_1symbol__tree_1_1SymbolType-members.html create mode 100644 doxygen/classtransformers_1_1symbol__tree_1_1SymbolType.html create mode 100644 doxygen/classtransformers_1_1symbol__tree_1_1SymbolType.js create mode 100644 doxygen/classtransformers_1_1symbol__tree_1_1SymbolType__coll__graph.dot create mode 100644 doxygen/classtransformers_1_1symbol__tree_1_1SymbolType__inherit__graph.dot create mode 100644 doxygen/classutils_1_1encryption_1_1StringEncryptor-members.html create mode 100644 doxygen/classutils_1_1encryption_1_1StringEncryptor.html create mode 100644 doxygen/classutils_1_1encryption_1_1StringEncryptor.js create mode 100644 doxygen/classutils_1_1junk__gen_1_1JunkGenerator-members.html create mode 100644 doxygen/classutils_1_1junk__gen_1_1JunkGenerator.html create mode 100644 doxygen/classutils_1_1junk__gen_1_1JunkGenerator.js create mode 100644 doxygen/classutils_1_1name__gen_1_1NameGenerator-members.html create mode 100644 doxygen/classutils_1_1name__gen_1_1NameGenerator.html create mode 100644 doxygen/classutils_1_1name__gen_1_1NameGenerator.js create mode 100644 doxygen/closed.png create mode 100644 doxygen/control__flow_8py.html create mode 100644 doxygen/control__flow_8py.js create mode 100644 doxygen/control__flow_8py_source.html create mode 100644 doxygen/dir_33a1d53dde8f74081d79f81ccfb4e6df.html create mode 100644 doxygen/dir_33a1d53dde8f74081d79f81ccfb4e6df.js create mode 100644 doxygen/dir_cbdb8362360e11eafe2fa3bc74cf0ffd.html create mode 100644 doxygen/dir_cbdb8362360e11eafe2fa3bc74cf0ffd.js create mode 100644 doxygen/doc.svg create mode 100644 doxygen/docd.svg create mode 100644 doxygen/doxygen.css create mode 100644 doxygen/doxygen.svg create mode 100644 doxygen/dynsections.js create mode 100644 doxygen/encryption_8py.html create mode 100644 doxygen/encryption_8py.js create mode 100644 doxygen/encryption_8py_source.html create mode 100644 doxygen/files.html create mode 100644 doxygen/files_dup.js create mode 100644 doxygen/folderclosed.svg create mode 100644 doxygen/folderclosedd.svg create mode 100644 doxygen/folderopen.svg create mode 100644 doxygen/folderopend.svg create mode 100644 doxygen/functions.html create mode 100644 doxygen/functions_func.html create mode 100644 doxygen/functions_vars.html create mode 100644 doxygen/graph_legend.dot create mode 100644 doxygen/graph_legend.html create mode 100644 doxygen/hierarchy.html create mode 100644 doxygen/hierarchy.js create mode 100644 doxygen/index.html create mode 100644 doxygen/inherit_graph_0.dot create mode 100644 doxygen/inherit_graph_1.dot create mode 100644 doxygen/inherit_graph_10.dot create mode 100644 doxygen/inherit_graph_11.dot create mode 100644 doxygen/inherit_graph_2.dot create mode 100644 doxygen/inherit_graph_3.dot create mode 100644 doxygen/inherit_graph_4.dot create mode 100644 doxygen/inherit_graph_5.dot create mode 100644 doxygen/inherit_graph_6.dot create mode 100644 doxygen/inherit_graph_7.dot create mode 100644 doxygen/inherit_graph_8.dot create mode 100644 doxygen/inherit_graph_9.dot create mode 100644 doxygen/inherits.html create mode 100644 doxygen/jquery.js create mode 100644 doxygen/junk__gen_8py.html create mode 100644 doxygen/junk__gen_8py.js create mode 100644 doxygen/junk__gen_8py_source.html create mode 100644 doxygen/main_8py.html create mode 100644 doxygen/main_8py.js create mode 100644 doxygen/main_8py_source.html create mode 100644 doxygen/menu.js create mode 100644 doxygen/menudata.js create mode 100644 doxygen/minus.svg create mode 100644 doxygen/minusd.svg create mode 100644 doxygen/name__gen_8py.html create mode 100644 doxygen/name__gen_8py.js create mode 100644 doxygen/name__gen_8py_source.html create mode 100644 doxygen/namespacemain.html create mode 100644 doxygen/namespacemembers.html create mode 100644 doxygen/namespacemembers_func.html create mode 100644 doxygen/namespacemembers_vars.html create mode 100644 doxygen/namespaceobfuscator.html create mode 100644 doxygen/namespaceobfuscator.js create mode 100644 doxygen/namespaces.html create mode 100644 doxygen/namespaces_dup.js create mode 100644 doxygen/namespacetransformers.html create mode 100644 doxygen/namespacetransformers.js create mode 100644 doxygen/namespacetransformers_1_1attribute__transformer.html create mode 100644 doxygen/namespacetransformers_1_1attribute__transformer.js create mode 100644 doxygen/namespacetransformers_1_1class__analyzer.html create mode 100644 doxygen/namespacetransformers_1_1class__analyzer.js create mode 100644 doxygen/namespacetransformers_1_1class__mapper.html create mode 100644 doxygen/namespacetransformers_1_1class__mapper.js create mode 100644 doxygen/namespacetransformers_1_1control__flow.html create mode 100644 doxygen/namespacetransformers_1_1control__flow.js create mode 100644 doxygen/namespacetransformers_1_1rename.html create mode 100644 doxygen/namespacetransformers_1_1rename.js create mode 100644 doxygen/namespacetransformers_1_1symbol__tree.html create mode 100644 doxygen/namespacetransformers_1_1symbol__tree.js create mode 100644 doxygen/namespaceutils.html create mode 100644 doxygen/namespaceutils.js create mode 100644 doxygen/namespaceutils_1_1encryption.html create mode 100644 doxygen/namespaceutils_1_1encryption.js create mode 100644 doxygen/namespaceutils_1_1junk__gen.html create mode 100644 doxygen/namespaceutils_1_1junk__gen.js create mode 100644 doxygen/namespaceutils_1_1name__gen.html create mode 100644 doxygen/namespaceutils_1_1name__gen.js create mode 100644 doxygen/nav_f.png create mode 100644 doxygen/nav_fd.png create mode 100644 doxygen/nav_g.png create mode 100644 doxygen/nav_h.png create mode 100644 doxygen/nav_hd.png create mode 100644 doxygen/navtree.css create mode 100644 doxygen/navtree.js create mode 100644 doxygen/navtreedata.js create mode 100644 doxygen/navtreeindex0.js create mode 100644 doxygen/navtreeindex1.js create mode 100644 doxygen/obfuscator_8py.html create mode 100644 doxygen/obfuscator_8py.js create mode 100644 doxygen/obfuscator_8py_source.html create mode 100644 doxygen/open.png create mode 100644 doxygen/plus.svg create mode 100644 doxygen/plusd.svg create mode 100644 doxygen/rename_8py.html create mode 100644 doxygen/rename_8py.js create mode 100644 doxygen/rename_8py_source.html create mode 100644 doxygen/resize.js create mode 100644 doxygen/search/all_0.js create mode 100644 doxygen/search/all_1.js create mode 100644 doxygen/search/all_10.js create mode 100644 doxygen/search/all_11.js create mode 100644 doxygen/search/all_12.js create mode 100644 doxygen/search/all_13.js create mode 100644 doxygen/search/all_14.js create mode 100644 doxygen/search/all_15.js create mode 100644 doxygen/search/all_2.js create mode 100644 doxygen/search/all_3.js create mode 100644 doxygen/search/all_4.js create mode 100644 doxygen/search/all_5.js create mode 100644 doxygen/search/all_6.js create mode 100644 doxygen/search/all_7.js create mode 100644 doxygen/search/all_8.js create mode 100644 doxygen/search/all_9.js create mode 100644 doxygen/search/all_a.js create mode 100644 doxygen/search/all_b.js create mode 100644 doxygen/search/all_c.js create mode 100644 doxygen/search/all_d.js create mode 100644 doxygen/search/all_e.js create mode 100644 doxygen/search/all_f.js create mode 100644 doxygen/search/classes_0.js create mode 100644 doxygen/search/classes_1.js create mode 100644 doxygen/search/classes_2.js create mode 100644 doxygen/search/classes_3.js create mode 100644 doxygen/search/classes_4.js create mode 100644 doxygen/search/classes_5.js create mode 100644 doxygen/search/classes_6.js create mode 100644 doxygen/search/close.svg create mode 100644 doxygen/search/files_0.js create mode 100644 doxygen/search/files_1.js create mode 100644 doxygen/search/files_2.js create mode 100644 doxygen/search/files_3.js create mode 100644 doxygen/search/files_4.js create mode 100644 doxygen/search/files_5.js create mode 100644 doxygen/search/files_6.js create mode 100644 doxygen/search/files_7.js create mode 100644 doxygen/search/files_8.js create mode 100644 doxygen/search/files_9.js create mode 100644 doxygen/search/files_a.js create mode 100644 doxygen/search/functions_0.js create mode 100644 doxygen/search/functions_1.js create mode 100644 doxygen/search/functions_10.js create mode 100644 doxygen/search/functions_2.js create mode 100644 doxygen/search/functions_3.js create mode 100644 doxygen/search/functions_4.js create mode 100644 doxygen/search/functions_5.js create mode 100644 doxygen/search/functions_6.js create mode 100644 doxygen/search/functions_7.js create mode 100644 doxygen/search/functions_8.js create mode 100644 doxygen/search/functions_9.js create mode 100644 doxygen/search/functions_a.js create mode 100644 doxygen/search/functions_b.js create mode 100644 doxygen/search/functions_c.js create mode 100644 doxygen/search/functions_d.js create mode 100644 doxygen/search/functions_e.js create mode 100644 doxygen/search/functions_f.js create mode 100644 doxygen/search/mag.svg create mode 100644 doxygen/search/mag_d.svg create mode 100644 doxygen/search/mag_sel.svg create mode 100644 doxygen/search/mag_seld.svg create mode 100644 doxygen/search/namespaces_0.js create mode 100644 doxygen/search/namespaces_1.js create mode 100644 doxygen/search/namespaces_2.js create mode 100644 doxygen/search/namespaces_3.js create mode 100644 doxygen/search/pages_0.js create mode 100644 doxygen/search/pages_1.js create mode 100644 doxygen/search/search.css create mode 100644 doxygen/search/search.js create mode 100644 doxygen/search/searchdata.js create mode 100644 doxygen/search/variables_0.js create mode 100644 doxygen/search/variables_1.js create mode 100644 doxygen/search/variables_10.js create mode 100644 doxygen/search/variables_11.js create mode 100644 doxygen/search/variables_12.js create mode 100644 doxygen/search/variables_2.js create mode 100644 doxygen/search/variables_3.js create mode 100644 doxygen/search/variables_4.js create mode 100644 doxygen/search/variables_5.js create mode 100644 doxygen/search/variables_6.js create mode 100644 doxygen/search/variables_7.js create mode 100644 doxygen/search/variables_8.js create mode 100644 doxygen/search/variables_9.js create mode 100644 doxygen/search/variables_a.js create mode 100644 doxygen/search/variables_b.js create mode 100644 doxygen/search/variables_c.js create mode 100644 doxygen/search/variables_d.js create mode 100644 doxygen/search/variables_e.js create mode 100644 doxygen/search/variables_f.js create mode 100644 doxygen/splitbar.png create mode 100644 doxygen/splitbard.png create mode 100644 doxygen/symbol__tree_8py.html create mode 100644 doxygen/symbol__tree_8py.js create mode 100644 doxygen/symbol__tree_8py_source.html create mode 100644 doxygen/sync_off.png create mode 100644 doxygen/sync_on.png create mode 100644 doxygen/tab_a.png create mode 100644 doxygen/tab_ad.png create mode 100644 doxygen/tab_b.png create mode 100644 doxygen/tab_bd.png create mode 100644 doxygen/tab_h.png create mode 100644 doxygen/tab_hd.png create mode 100644 doxygen/tab_s.png create mode 100644 doxygen/tab_sd.png create mode 100644 doxygen/tabs.css create mode 100644 doxygen/transformers_2____init_____8py.html create mode 100644 doxygen/transformers_2____init_____8py_source.html create mode 100644 doxygen/utils_2____init_____8py.html create mode 100644 doxygen/utils_2____init_____8py_source.html diff --git a/Doxygen.md b/Doxygen.md new file mode 100644 index 0000000..07e546a --- /dev/null +++ b/Doxygen.md @@ -0,0 +1,5 @@ +# Doxygen Documentation + +The generated API reference is published in this wiki under the doxygen directory. + +- Open the HTML entry point: [doxygen/index.html](doxygen/index.html) diff --git a/doxygen/README_8md.html b/doxygen/README_8md.html new file mode 100644 index 0000000..8feb1bd --- /dev/null +++ b/doxygen/README_8md.html @@ -0,0 +1,106 @@ + + + + + + + +OMG-Fuscator: README.md File Reference + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
README.md File Reference
+
+
+
+
+ + + + diff --git a/doxygen/annotated.html b/doxygen/annotated.html new file mode 100644 index 0000000..96159d8 --- /dev/null +++ b/doxygen/annotated.html @@ -0,0 +1,140 @@ + + + + + + + +OMG-Fuscator: Class List + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Class List
+
+
+
Here are the classes, structs, unions and interfaces with brief descriptions:
+
+
+ + + + diff --git a/doxygen/annotated_dup.js b/doxygen/annotated_dup.js new file mode 100644 index 0000000..5d8dd75 --- /dev/null +++ b/doxygen/annotated_dup.js @@ -0,0 +1,46 @@ +var annotated_dup = +[ + [ "obfuscator", "namespaceobfuscator.html", [ + [ "AdvancedObfuscator", "classobfuscator_1_1AdvancedObfuscator.html", "classobfuscator_1_1AdvancedObfuscator" ] + ] ], + [ "transformers", "namespacetransformers.html", [ + [ "attribute_transformer", "namespacetransformers_1_1attribute__transformer.html", [ + [ "AttributeTransformer", "classtransformers_1_1attribute__transformer_1_1AttributeTransformer.html", "classtransformers_1_1attribute__transformer_1_1AttributeTransformer" ] + ] ], + [ "class_analyzer", "namespacetransformers_1_1class__analyzer.html", [ + [ "ClassAnalyzer", "classtransformers_1_1class__analyzer_1_1ClassAnalyzer.html", "classtransformers_1_1class__analyzer_1_1ClassAnalyzer" ], + [ "ClassMethodMap", "classtransformers_1_1class__analyzer_1_1ClassMethodMap.html", "classtransformers_1_1class__analyzer_1_1ClassMethodMap" ] + ] ], + [ "class_mapper", "namespacetransformers_1_1class__mapper.html", [ + [ "ClassMapAnalyzer", "classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html", "classtransformers_1_1class__mapper_1_1ClassMapAnalyzer" ], + [ "ClassMapping", "classtransformers_1_1class__mapper_1_1ClassMapping.html", "classtransformers_1_1class__mapper_1_1ClassMapping" ], + [ "ClassTransformer", "classtransformers_1_1class__mapper_1_1ClassTransformer.html", "classtransformers_1_1class__mapper_1_1ClassTransformer" ] + ] ], + [ "control_flow", "namespacetransformers_1_1control__flow.html", [ + [ "ControlFlowFlattener", "classtransformers_1_1control__flow_1_1ControlFlowFlattener.html", "classtransformers_1_1control__flow_1_1ControlFlowFlattener" ] + ] ], + [ "rename", "namespacetransformers_1_1rename.html", [ + [ "RenameTransformer", "classtransformers_1_1rename_1_1RenameTransformer.html", "classtransformers_1_1rename_1_1RenameTransformer" ] + ] ], + [ "symbol_tree", "namespacetransformers_1_1symbol__tree.html", [ + [ "ClassScope", "classtransformers_1_1symbol__tree_1_1ClassScope.html", "classtransformers_1_1symbol__tree_1_1ClassScope" ], + [ "ModuleScope", "classtransformers_1_1symbol__tree_1_1ModuleScope.html", "classtransformers_1_1symbol__tree_1_1ModuleScope" ], + [ "Scope", "classtransformers_1_1symbol__tree_1_1Scope.html", "classtransformers_1_1symbol__tree_1_1Scope" ], + [ "Symbol", "classtransformers_1_1symbol__tree_1_1Symbol.html", "classtransformers_1_1symbol__tree_1_1Symbol" ], + [ "SymbolTree", "classtransformers_1_1symbol__tree_1_1SymbolTree.html", "classtransformers_1_1symbol__tree_1_1SymbolTree" ], + [ "SymbolTreeBuilder", "classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html", "classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder" ], + [ "SymbolType", "classtransformers_1_1symbol__tree_1_1SymbolType.html", "classtransformers_1_1symbol__tree_1_1SymbolType" ] + ] ] + ] ], + [ "utils", "namespaceutils.html", [ + [ "encryption", "namespaceutils_1_1encryption.html", [ + [ "StringEncryptor", "classutils_1_1encryption_1_1StringEncryptor.html", "classutils_1_1encryption_1_1StringEncryptor" ] + ] ], + [ "junk_gen", "namespaceutils_1_1junk__gen.html", [ + [ "JunkGenerator", "classutils_1_1junk__gen_1_1JunkGenerator.html", "classutils_1_1junk__gen_1_1JunkGenerator" ] + ] ], + [ "name_gen", "namespaceutils_1_1name__gen.html", [ + [ "NameGenerator", "classutils_1_1name__gen_1_1NameGenerator.html", "classutils_1_1name__gen_1_1NameGenerator" ] + ] ] + ] ] +]; \ No newline at end of file diff --git a/doxygen/attribute__transformer_8py.html b/doxygen/attribute__transformer_8py.html new file mode 100644 index 0000000..5340278 --- /dev/null +++ b/doxygen/attribute__transformer_8py.html @@ -0,0 +1,124 @@ + + + + + + + +OMG-Fuscator: attribute_transformer.py File Reference + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
attribute_transformer.py File Reference
+
+ +
+ + + + diff --git a/doxygen/attribute__transformer_8py.js b/doxygen/attribute__transformer_8py.js new file mode 100644 index 0000000..6aaaf09 --- /dev/null +++ b/doxygen/attribute__transformer_8py.js @@ -0,0 +1,4 @@ +var attribute__transformer_8py = +[ + [ "transformers.attribute_transformer.AttributeTransformer", "classtransformers_1_1attribute__transformer_1_1AttributeTransformer.html", "classtransformers_1_1attribute__transformer_1_1AttributeTransformer" ] +]; \ No newline at end of file diff --git a/doxygen/attribute__transformer_8py_source.html b/doxygen/attribute__transformer_8py_source.html new file mode 100644 index 0000000..5dec3f0 --- /dev/null +++ b/doxygen/attribute__transformer_8py_source.html @@ -0,0 +1,193 @@ + + + + + + + +OMG-Fuscator: attribute_transformer.py Source File + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
attribute_transformer.py
+
+
+Go to the documentation of this file.
1"""
+
2@file transformers/attribute_transformer.py
+
3@brief Attribute access transformer for consistent class member renaming.
+
4@details Ensures references like self.method and self.attr are kept consistent
+
5 with class and attribute mappings produced by analysis.
+
6"""
+
7
+
8import ast
+
9from typing import Dict, Optional
+
10
+
+
11class AttributeTransformer(ast.NodeTransformer):
+
12 """
+
13 @brief Transform attribute access expressions for consistency.
+
14 @details Handles self.method and self.attr translations based on provided
+
15 mappings to keep calls and attributes aligned with obfuscated names.
+
16 """
+
17
+
+
18 def __init__(self, class_attr_mapping: Dict[str, Dict[str, str]], class_renames: Dict[str, str]):
+
19 """
+
20 @brief Initialize transformer with mapping dictionaries.
+
21 @param class_attr_mapping Maps class_name -> {attr_name -> obfuscated_attr_name}
+
22 @param class_renames Maps original_class_name -> obfuscated_class_name
+
23 """
+
24 self.class_attr_mapping = class_attr_mapping
+
25 self.class_renames = class_renames
+
26 self.current_class: Optional[str] = None
+
27
+
+
+
28 def visit_ClassDef(self, node):
+
29 """
+
30 @brief Track the current class and process its body.
+
31 @param node ast.ClassDef being visited.
+
32 @return ast.ClassDef Potentially modified node.
+
33 """
+
34 old_class = self.current_class
+
35
+
36 # Get the obfuscated name for this class
+
37 class_name = node.name
+
38 if class_name in self.class_renames:
+
39 self.current_class = self.class_renames[class_name]
+
40 else:
+
41 self.current_class = class_name
+
42
+
43 # Process the class body
+
44 node = self.generic_visit(node)
+
45
+
46 # Restore the previous class context
+
47 self.current_class = old_class
+
48 return node
+
49
+
+
+
50 def visit_Attribute(self, node):
+
51 """
+
52 @brief Transform attribute access for consistency within a class.
+
53 @param node ast.Attribute node to transform.
+
54 @return ast.AST Updated attribute node.
+
55 """
+
56 # First process any nested attributes
+
57 node = self.generic_visit(node)
+
58
+
59 # Handle self.attr references within a class
+
60 if isinstance(node.value, ast.Name) and node.value.id == 'self' and self.current_class:
+
61 if self.current_class in self.class_attr_mapping:
+
62 attr_map = self.class_attr_mapping[self.current_class]
+
63 # Only substitute if node.attr is still in its original form (a mapping key)
+
64 if node.attr in attr_map and node.attr != attr_map[node.attr]:
+
65 node.attr = attr_map[node.attr]
+
66
+
67 return node
+
+
+ + +
__init__(self, Dict[str, Dict[str, str]] class_attr_mapping, Dict[str, str] class_renames)
+ + + + +
+
+ + + + diff --git a/doxygen/bc_s.png b/doxygen/bc_s.png new file mode 100644 index 0000000000000000000000000000000000000000..224b29aa9847d5a4b3902efd602b7ddf7d33e6c2 GIT binary patch literal 676 zcmV;V0$crwP)y__>=_9%My z{n931IS})GlGUF8K#6VIbs%684A^L3@%PlP2>_sk`UWPq@f;rU*V%rPy_ekbhXT&s z(GN{DxFv}*vZp`F>S!r||M`I*nOwwKX+BC~3P5N3-)Y{65c;ywYiAh-1*hZcToLHK ztpl1xomJ+Yb}K(cfbJr2=GNOnT!UFA7Vy~fBz8?J>XHsbZoDad^8PxfSa0GDgENZS zuLCEqzb*xWX2CG*b&5IiO#NzrW*;`VC9455M`o1NBh+(k8~`XCEEoC1Ybwf;vr4K3 zg|EB<07?SOqHp9DhLpS&bzgo70I+ghB_#)K7H%AMU3v}xuyQq9&Bm~++VYhF09a+U zl7>n7Jjm$K#b*FONz~fj;I->Bf;ule1prFN9FovcDGBkpg>)O*-}eLnC{6oZHZ$o% zXKW$;0_{8hxHQ>l;_*HATI(`7t#^{$(zLe}h*mqwOc*nRY9=?Sx4OOeVIfI|0V(V2 zBrW#G7Ss9wvzr@>H*`r>zE z+e8bOBgqIgldUJlG(YUDviMB`9+DH8n-s9SXRLyJHO1!=wY^79WYZMTa(wiZ!zP66 zA~!21vmF3H2{ngD;+`6j#~6j;$*f*G_2ZD1E;9(yaw7d-QnSCpK(cR1zU3qU0000< KMNUMnLSTYoA~SLT literal 0 HcmV?d00001 diff --git a/doxygen/bc_sd.png b/doxygen/bc_sd.png new file mode 100644 index 0000000000000000000000000000000000000000..31ca888dc71049713b35c351933a8d0f36180bf1 GIT binary patch literal 635 zcmV->0)+jEP)Jwi0r1~gdSq#w{Bu1q z`craw(p2!hu$4C_$Oc3X(sI6e=9QSTwPt{G) z=htT&^~&c~L2~e{r5_5SYe7#Is-$ln>~Kd%$F#tC65?{LvQ}8O`A~RBB0N~`2M+waajO;5>3B&-viHGJeEK2TQOiPRa zfDKyqwMc4wfaEh4jt>H`nW_Zidwk@Bowp`}(VUaj-pSI(-1L>FJVsX}Yl9~JsqgsZ zUD9(rMwf23Gez6KPa|wwInZodP-2}9@fK0Ga_9{8SOjU&4l`pH4@qlQp83>>HT$xW zER^U>)MyV%t(Lu=`d=Y?{k1@}&r7ZGkFQ%z%N+sE9BtYjovzxyxCPxN6&@wLK{soQ zSmkj$aLI}miuE^p@~4}mg9OjDfGEkgY4~^XzLRUBB*O{+&vq<3v(E%+k_i%=`~j%{ Vj14gnt9}3g002ovPDHLkV1n!oC4m3{ literal 0 HcmV?d00001 diff --git a/doxygen/class__analyzer_8py.html b/doxygen/class__analyzer_8py.html new file mode 100644 index 0000000..92308dc --- /dev/null +++ b/doxygen/class__analyzer_8py.html @@ -0,0 +1,134 @@ + + + + + + + +OMG-Fuscator: class_analyzer.py File Reference + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
class_analyzer.py File Reference
+
+
+ +

Go to the source code of this file.

+ + + + + + +

+Classes

class  transformers.class_analyzer.ClassAnalyzer
 
class  transformers.class_analyzer.ClassMethodMap
 
+ + + + + +

+Namespaces

namespace  transformers
 
namespace  transformers.class_analyzer
 
+ + + + + +

+Functions

Tuple[bool, str] transformers.class_analyzer.get_method_name (ast.Attribute node)
 
 transformers.class_analyzer.update_obfuscator_with_class_mappings (obfuscator, ClassMethodMap class_map)
 
+
+
+ + + + diff --git a/doxygen/class__analyzer_8py.js b/doxygen/class__analyzer_8py.js new file mode 100644 index 0000000..ff130ae --- /dev/null +++ b/doxygen/class__analyzer_8py.js @@ -0,0 +1,7 @@ +var class__analyzer_8py = +[ + [ "transformers.class_analyzer.ClassAnalyzer", "classtransformers_1_1class__analyzer_1_1ClassAnalyzer.html", "classtransformers_1_1class__analyzer_1_1ClassAnalyzer" ], + [ "transformers.class_analyzer.ClassMethodMap", "classtransformers_1_1class__analyzer_1_1ClassMethodMap.html", "classtransformers_1_1class__analyzer_1_1ClassMethodMap" ], + [ "get_method_name", "class__analyzer_8py.html#a6b97dea989b6eb9d37b5d9b53fae3b6d", null ], + [ "update_obfuscator_with_class_mappings", "class__analyzer_8py.html#a33c650248422029fa53952d08e4da438", null ] +]; \ No newline at end of file diff --git a/doxygen/class__analyzer_8py_source.html b/doxygen/class__analyzer_8py_source.html new file mode 100644 index 0000000..d7c3bb6 --- /dev/null +++ b/doxygen/class__analyzer_8py_source.html @@ -0,0 +1,385 @@ + + + + + + + +OMG-Fuscator: class_analyzer.py Source File + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
class_analyzer.py
+
+
+Go to the documentation of this file.
1"""
+
2@file transformers/class_analyzer.py
+
3@brief Class analysis utilities for consistent renaming.
+
4@details Pre-analyzes classes, methods, attributes, and inheritance to build
+
5 consistent mappings used by obfuscation transformers.
+
6"""
+
7import ast
+
8from typing import Dict, Set, Tuple, List
+
9
+
+ +
11 """
+
12 @brief Stores method and attribute mappings for all classes.
+
13 """
+
+
14 def __init__(self):
+
15 # Maps: original_class_name -> {original_method_name -> obfuscated_method_name}
+
16 self.class_methods: Dict[str, Dict[str, str]] = {}
+
17
+
18 # Maps: original_class_name -> {original_attr_name -> obfuscated_attr_name}
+
19 self.class_attributes: Dict[str, Dict[str, str]] = {}
+
20
+
21 # Maps: original_class_name -> obfuscated_class_name
+
22 self.class_renames: Dict[str, str] = {}
+
23
+
24 # Track inheritance relationships: child_class -> [parent_classes]
+
25 self.inheritance: Dict[str, List[str]] = {}
+
26
+
27
+
+
+
+
28class ClassAnalyzer(ast.NodeVisitor):
+
29 """
+
30 @brief Analyze classes for consistent method/attribute renaming.
+
31 @details Ensures self.method() calls match def method() definitions and records inheritance.
+
32 """
+
+
33 def __init__(self, name_generator):
+
34 self.name_generator = name_generator
+ +
36 self.current_class = None
+
37
+
38 # To avoid duplicate scanning
+
39 self.scanned_classes: Set[str] = set()
+
40
+
41 # Track method calls within each class
+
42 self.method_calls: Dict[str, Set[str]] = {}
+
43
+
+
+
44 def analyze(self, tree: ast.AST) -> ClassMethodMap:
+
45 """
+
46 @brief Analyze the entire AST and produce mappings.
+
47 @param tree Parsed AST of the input module.
+
48 @return ClassMethodMap Populated mappings.
+
49 """
+
50 self.visit(tree)
+ + +
53 return self.method_map
+
54
+
+
+
55 def visit_ClassDef(self, node: ast.ClassDef):
+
56 """
+
57 @brief Process a class definition and map methods/attrs.
+
58 @param node ast.ClassDef node being visited.
+
59 """
+
60 prev_class = self.current_class
+
61 self.current_class = node.name
+
62
+
63 # Skip if already processed this class
+
64 if node.name in self.scanned_classes:
+
65 self.current_class = prev_class
+
66 return
+
67
+
68 # Initialize method calls tracking for this class
+
69 self.method_calls[node.name] = set()
+
70
+
71 # Record class inheritance
+
72 parent_classes = []
+
73 for base in node.bases:
+
74 if isinstance(base, ast.Name):
+
75 parent_classes.append(base.id)
+
76
+
77 if parent_classes:
+
78 self.method_map.inheritance[node.name] = parent_classes
+
79
+
80 # Initialize mappings for this class
+
81 if node.name not in self.method_map.class_methods:
+
82 self.method_map.class_methods[node.name] = {}
+
83
+
84 if node.name not in self.method_map.class_attributes:
+
85 self.method_map.class_attributes[node.name] = {}
+
86
+
87 # Create a consistent obfuscated name for this class
+
88 if node.name not in self.method_map.class_renames:
+
89 new_name = self.name_generator.generate_name()
+
90 self.method_map.class_renames[node.name] = new_name
+
91
+
92 # Process all method definitions in the class
+
93 for item in node.body:
+
94 # Methods
+
95 if isinstance(item, ast.FunctionDef):
+
96 # Skip dunder methods
+
97 if not (item.name.startswith('__') and item.name.endswith('__')):
+
98 # Generate a consistent obfuscated name for this method
+
99 new_name = self.name_generator.generate_name()
+
100 self.method_map.class_methods[node.name][item.name] = new_name
+
101
+
102 # Visit the method body to find self.method() calls
+
103 self.visit(item)
+
104
+
105 # Attributes in assignments
+
106 elif isinstance(item, ast.Assign):
+
107 self.visit_attribute_assign(item)
+
108 else:
+
109 # Visit other nodes (like if statements that might contain self.method calls)
+
110 self.visit(item)
+
111
+
112 self.scanned_classes.add(node.name)
+
113
+
114 # Visit any nested classes
+
115 for item in node.body:
+
116 if isinstance(item, ast.ClassDef):
+
117 self.visit(item)
+
118
+
119 self.current_class = prev_class
+
120
+
+
+
121 def visit_attribute_assign(self, node):
+
122 """
+
123 @brief Process self.attr assignments within a class.
+
124 @param node ast.Assign node of the assignment.
+
125 """
+
126 if not self.current_class:
+
127 return
+
128
+
129 for target in node.targets:
+
130 if isinstance(target, ast.Attribute) and isinstance(target.value, ast.Name):
+
131 if target.value.id == 'self':
+
132 # This is a self.attribute assignment
+
133 attr_name = target.attr
+
134 if attr_name not in self.method_map.class_attributes[self.current_class]:
+
135 new_name = self.name_generator.generate_name()
+
136 self.method_map.class_attributes[self.current_class][attr_name] = new_name
+
137
+
138 # Visit the value part of the assignment for nested self.method() calls
+
139 self.visit(node.value)
+
140
+
+
+
141 def visit_Attribute(self, node):
+
142 """
+
143 @brief Track self.method references for consistency checks.
+
144 @param node ast.Attribute being visited.
+
145 """
+
146 if self.current_class:
+
147 is_self_method, method_name = get_method_name(node)
+
148 if is_self_method:
+
149 # Record this method call for consistency checks later
+
150 self.method_calls[self.current_class].add(method_name)
+
151
+
152 # Continue traversing
+
153 self.generic_visit(node)
+
154
+
+
+ +
156 """
+
157 @brief Ensure all self.method() calls have mappings, even if undefined in class.
+
158 """
+
159 for class_name, method_calls in self.method_calls.items():
+
160 if class_name not in self.method_map.class_methods:
+
161 continue
+
162
+
163 class_methods = self.method_map.class_methods[class_name]
+
164 for method_name in method_calls:
+
165 if method_name not in class_methods:
+
166 # Skip dunder methods
+
167 if method_name.startswith('__') and method_name.endswith('__'):
+
168 continue
+
169 # Existing check: mapping is generated only once.
+
170 new_name = self.name_generator.generate_name()
+
171 class_methods[method_name] = new_name
+
172
+
+
+ +
174 """
+
175 @brief Propagate method mappings along inheritance hierarchies.
+
176 @details Ensures overridden methods reuse the same obfuscated name.
+
177 """
+
178 # Process inheritance depth-first to handle multi-level inheritance
+
179 def process_inheritance(class_name):
+
180 if class_name not in self.method_map.inheritance:
+
181 return
+
182
+
183 for parent in self.method_map.inheritance[class_name]:
+
184 # Process parent's inheritance first
+
185 process_inheritance(parent)
+
186
+
187 # Skip if parent isn't in our mappings (external class)
+
188 if parent not in self.method_map.class_methods:
+
189 continue
+
190
+
191 # Inherit parent's methods if not overridden
+
192 for method_name, obf_name in self.method_map.class_methods[parent].items():
+
193 if method_name not in self.method_map.class_methods[class_name]:
+
194 self.method_map.class_methods[class_name][method_name] = obf_name
+
195
+
196 # Process inheritance for each class
+
197 for class_name in list(self.method_map.class_methods.keys()):
+
198 process_inheritance(class_name)
+
199
+
200
+
+
+
+
201def get_method_name(node: ast.Attribute) -> Tuple[bool, str]:
+
202 """
+
203 @brief Determine if an attribute is a self.method() call.
+
204 @param node Attribute node to check.
+
205 @return Tuple[bool, str] (is_self_method, method_name)
+
206 """
+
207 if isinstance(node.value, ast.Name) and node.value.id == 'self':
+
208 return True, node.attr
+
209 return False, ""
+
210
+
211
+
+
+
212def update_obfuscator_with_class_mappings(obfuscator, class_map: ClassMethodMap):
+
213 """
+
214 @brief Update obfuscator with class/method/attribute mappings.
+
215 @param obfuscator AdvancedObfuscator instance to update.
+
216 @param class_map ClassMethodMap mappings produced by analysis.
+
217 """
+
218 # Update class name mappings in global_var_renames
+
219 for orig_name, obf_name in class_map.class_renames.items():
+
220 obfuscator.global_var_renames[orig_name] = obf_name
+
221
+
222 # Update class attr mapping with our analyzed data
+
223 for class_name, class_obf_name in class_map.class_renames.items():
+
224 # Initialize if needed
+
225 if class_obf_name not in obfuscator.class_attr_mapping:
+
226 obfuscator.class_attr_mapping[class_obf_name] = {}
+
227
+
228 # Copy method mappings
+
229 if class_name in class_map.class_methods:
+
230 for method, obf_method in class_map.class_methods[class_name].items():
+
231 obfuscator.class_attr_mapping[class_obf_name][method] = obf_method
+
232
+
233 # Copy attribute mappings
+
234 if class_name in class_map.class_attributes:
+
235 for attr, obf_attr in class_map.class_attributes[class_name].items():
+
236 obfuscator.class_attr_mapping[class_obf_name][attr] = obf_attr
+
+ + + + + + + + +
ClassMethodMap analyze(self, ast.AST tree)
+ + + + +
Tuple[bool, str] get_method_name(ast.Attribute node)
+
+
+ + + + diff --git a/doxygen/class__mapper_8py.html b/doxygen/class__mapper_8py.html new file mode 100644 index 0000000..117af7a --- /dev/null +++ b/doxygen/class__mapper_8py.html @@ -0,0 +1,142 @@ + + + + + + + +OMG-Fuscator: class_mapper.py File Reference + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
class_mapper.py File Reference
+
+
+ +

Go to the source code of this file.

+ + + + + + + + +

+Classes

class  transformers.class_mapper.ClassMapAnalyzer
 
class  transformers.class_mapper.ClassMapping
 
class  transformers.class_mapper.ClassTransformer
 
+ + + + + +

+Namespaces

namespace  transformers
 
namespace  transformers.class_mapper
 
+ + + +

+Functions

ast.AST transformers.class_mapper.apply_class_mapping (ast.AST tree, name_generator)
 
+ + + + + +

+Variables

 transformers.class_mapper.level
 
 transformers.class_mapper.logger = logging.getLogger("ClassMapper")
 
+
+
+ + + + diff --git a/doxygen/class__mapper_8py.js b/doxygen/class__mapper_8py.js new file mode 100644 index 0000000..de5d2e5 --- /dev/null +++ b/doxygen/class__mapper_8py.js @@ -0,0 +1,9 @@ +var class__mapper_8py = +[ + [ "transformers.class_mapper.ClassMapAnalyzer", "classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html", "classtransformers_1_1class__mapper_1_1ClassMapAnalyzer" ], + [ "transformers.class_mapper.ClassMapping", "classtransformers_1_1class__mapper_1_1ClassMapping.html", "classtransformers_1_1class__mapper_1_1ClassMapping" ], + [ "transformers.class_mapper.ClassTransformer", "classtransformers_1_1class__mapper_1_1ClassTransformer.html", "classtransformers_1_1class__mapper_1_1ClassTransformer" ], + [ "apply_class_mapping", "class__mapper_8py.html#a799073dc76d04c46febc20f3f88ff430", null ], + [ "level", "class__mapper_8py.html#a9ce72747d2040877bfa3d561bbcfb046", null ], + [ "logger", "class__mapper_8py.html#a77f334648be077cc4cf07b5862cc34f1", null ] +]; \ No newline at end of file diff --git a/doxygen/class__mapper_8py_source.html b/doxygen/class__mapper_8py_source.html new file mode 100644 index 0000000..cbc05d8 --- /dev/null +++ b/doxygen/class__mapper_8py_source.html @@ -0,0 +1,529 @@ + + + + + + + +OMG-Fuscator: class_mapper.py Source File + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
class_mapper.py
+
+
+Go to the documentation of this file.
1"""
+
2@file transformers/class_mapper.py
+
3@brief Class, method, and attribute mapping analyzer and transformer.
+
4@details Builds consistent rename mappings across classes, resolves inheritance,
+
5 and applies the mappings back to the AST for coherent obfuscation.
+
6"""
+
7
+
8import ast
+
9from typing import Dict, Set, List, Tuple, Optional
+
10import logging
+
11
+
12# Configure logging
+
13logging.basicConfig(level=logging.INFO)
+
14logger = logging.getLogger("ClassMapper")
+
15
+
+ +
17 """
+
18 @brief Stores all mappings related to classes in a centralized way.
+
19 @details Tracks class renames, method and attribute mappings, inheritance structure,
+
20 and seen method calls to ensure complete coverage.
+
21 """
+
22
+
+
23 def __init__(self):
+
24 # Original class name -> obfuscated class name
+
25 self.class_names: Dict[str, str] = {}
+
26
+
27 # Original class name -> {original method name -> obfuscated method name}
+
28 self.class_methods: Dict[str, Dict[str, str]] = {}
+
29
+
30 # Original class name -> {original attr name -> obfuscated attr name}
+
31 self.class_attributes: Dict[str, Dict[str, str]] = {}
+
32
+
33 # Child class -> list of parent classes (original names)
+
34 self.inheritance: Dict[str, List[str]] = {}
+
35
+
36 # Track all seen method calls to ensure complete coverage
+
37 self.seen_method_calls: Dict[str, Set[str]] = {}
+
38
+
+
+
39 def debug_info(self) -> str:
+
40 """Return debug information about mappings."""
+
41 info = []
+
42 info.append(f"Class mappings: {len(self.class_names)} classes")
+
43
+
44 for cls_name, obf_name in self.class_names.items():
+
45 info.append(f" {cls_name} -> {obf_name}")
+
46
+
47 if cls_name in self.class_methods:
+
48 methods = self.class_methods[cls_name]
+
49 info.append(f" Methods: {len(methods)}")
+
50 for method, obf_method in methods.items():
+
51 info.append(f" {method} -> {obf_method}")
+
52
+
53 if cls_name in self.class_attributes:
+
54 attrs = self.class_attributes[cls_name]
+
55 info.append(f" Attributes: {len(attrs)}")
+
56 for attr, obf_attr in attrs.items():
+
57 info.append(f" {attr} -> {obf_attr}")
+
58
+
59 return "\n".join(info)
+
60
+
61
+
+
+
+
62class ClassMapAnalyzer(ast.NodeVisitor):
+
63 """
+
64 @brief Analyze the AST to create a complete class mapping.
+
65 @details Performs multi-pass analysis to collect classes, methods, attributes,
+
66 inheritance, and method-call references and builds consistent mappings.
+
67 """
+
68
+
+
69 def __init__(self, name_generator):
+
70 self.name_generator = name_generator
+ +
72 self.current_class: Optional[str] = None
+
73 self.current_method: Optional[str] = None
+
74 self.processed_classes: Set[str] = set()
+
75
+
+
+
76 def analyze(self, tree: ast.AST) -> ClassMapping:
+
77 """
+
78 @brief Perform a complete analysis of the AST.
+
79 @param tree Parsed AST to analyze.
+
80 @return ClassMapping Aggregated mappings for class renaming and members.
+
81 """
+
82 # First pass: collect all class definitions, methods, and inheritance
+
83 self.visit(tree)
+
84
+
85 # Second pass: resolve inheritance and method mappings
+ + +
88
+
89 logger.info(f"Class analysis complete: {len(self.mapping.class_names)} classes processed")
+
90 logger.debug(self.mapping.debug_info())
+
91
+
92 return self.mapping
+
93
+
+
+
94 def visit_ClassDef(self, node: ast.ClassDef):
+
95 """
+
96 @brief Process a class definition.
+
97 @param node ast.ClassDef node.
+
98 """
+
99 prev_class = self.current_class
+
100 self.current_class = node.name
+
101
+
102 # Skip if already processed
+
103 if node.name in self.processed_classes:
+
104 self.current_class = prev_class
+
105 return
+
106
+
107 # Add class name mapping
+
108 if node.name not in self.mapping.class_names:
+
109 self.mapping.class_names[node.name] = self.name_generator.generate_name()
+
110
+
111 # Initialize dictionaries
+
112 if node.name not in self.mapping.class_methods:
+
113 self.mapping.class_methods[node.name] = {}
+
114
+
115 if node.name not in self.mapping.class_attributes:
+
116 self.mapping.class_attributes[node.name] = {}
+
117
+
118 if node.name not in self.mapping.seen_method_calls:
+
119 self.mapping.seen_method_calls[node.name] = set()
+
120
+
121 # Record inheritance
+
122 parent_classes = []
+
123 for base in node.bases:
+
124 if isinstance(base, ast.Name):
+
125 parent_classes.append(base.id)
+
126
+
127 if parent_classes:
+
128 self.mapping.inheritance[node.name] = parent_classes
+
129
+
130 # Process class body
+
131 for item in node.body:
+
132 if isinstance(item, ast.FunctionDef):
+
133 self.visit_method_def(item)
+
134 elif isinstance(item, ast.Assign):
+
135 self.visit_assign_in_class(item)
+
136 elif isinstance(item, ast.Expr):
+
137 # Could contain calls to self.methods
+
138 self.visit(item)
+
139 elif isinstance(item, ast.ClassDef):
+
140 # Nested class
+
141 self.visit(item)
+
142 else:
+
143 # Other nodes that might contain self.method calls
+
144 self.visit(item)
+
145
+
146 self.processed_classes.add(node.name)
+
147 self.current_class = prev_class
+
148
+
+
+
149 def visit_method_def(self, node: ast.FunctionDef):
+
150 """
+
151 @brief Process a method definition in a class.
+
152 @param node ast.FunctionDef node.
+
153 """
+
154 if not self.current_class:
+
155 return
+
156
+
157 prev_method = self.current_method
+
158 self.current_method = node.name
+
159
+
160 # Skip dunder methods from obfuscation
+
161 if not (node.name.startswith('__') and node.name.endswith('__')):
+
162 # Map method name if not already mapped
+
163 if node.name not in self.mapping.class_methods[self.current_class]:
+
164 obf_name = self.name_generator.generate_name()
+
165 self.mapping.class_methods[self.current_class][node.name] = obf_name
+
166 logger.debug(f"Mapped method {self.current_class}.{node.name} to {obf_name}")
+
167
+
168 # Visit method body to find self.method calls and self.attr assignments
+
169 for item in node.body:
+
170 self.visit(item)
+
171
+
172 self.current_method = prev_method
+
173
+
+
+
174 def visit_assign_in_class(self, node: ast.Assign):
+
175 """
+
176 @brief Process assignments in class body or methods.
+
177 @param node ast.Assign possibly containing self.attr writes.
+
178 """
+
179 if not self.current_class:
+
180 return
+
181
+
182 # Check for self.attribute assignments
+
183 for target in node.targets:
+
184 if isinstance(target, ast.Attribute) and isinstance(target.value, ast.Name) and target.value.id == 'self':
+
185 attr_name = target.attr
+
186
+
187 # Map attribute name if not already mapped
+
188 if attr_name not in self.mapping.class_attributes[self.current_class]:
+
189 obf_name = self.name_generator.generate_name()
+
190 self.mapping.class_attributes[self.current_class][attr_name] = obf_name
+
191 logger.debug(f"Mapped attribute {self.current_class}.{attr_name} to {obf_name}")
+
192
+
193 # Visit the value to find nested self.method calls
+
194 self.visit(node.value)
+
195
+
+
+
196 def visit_Attribute(self, node: ast.Attribute):
+
197 """
+
198 @brief Process attribute access like self.method or self.attr.
+
199 @param node ast.Attribute node.
+
200 """
+
201 if self.current_class and isinstance(node.value, ast.Name) and node.value.id == 'self':
+
202 # Record this access for later processing
+
203 method_name = node.attr
+
204 self.mapping.seen_method_calls[self.current_class].add(method_name)
+
205 logger.debug(f"Recorded method call: {self.current_class}.{method_name}")
+
206
+
207 # Continue traversal
+
208 self.generic_visit(node)
+
209
+
+
+
210 def visit_Assign(self, node: ast.Assign):
+
211 """
+
212 @brief Process assignments that might contain self.attr references.
+
213 @param node ast.Assign node.
+
214 """
+
215 # Visit both sides of the assignment
+
216 for target in node.targets:
+
217 self.visit(target)
+
218 self.visit(node.value)
+
219
+
+
+ +
221 """
+
222 @brief Ensure child classes inherit method mappings from parent classes.
+
223 @details Copies parent method mappings into children when not overridden.
+
224 """
+
225 def process_inheritance(class_name):
+
226 if class_name not in self.mapping.inheritance:
+
227 return
+
228
+
229 for parent in self.mapping.inheritance[class_name]:
+
230 # Process parent's inheritance first
+
231 process_inheritance(parent)
+
232
+
233 # Skip if parent isn't in our mappings
+
234 if parent not in self.mapping.class_methods:
+
235 continue
+
236
+
237 # Copy parent's method mappings to child if not overridden
+
238 for method_name, obf_name in self.mapping.class_methods[parent].items():
+
239 if method_name not in self.mapping.class_methods[class_name]:
+
240 self.mapping.class_methods[class_name][method_name] = obf_name
+
241 logger.debug(f"Inherited method {class_name}.{method_name} from {parent}")
+
242
+
243 # Process all classes
+
244 for class_name in list(self.mapping.class_methods.keys()):
+
245 process_inheritance(class_name)
+
246
+
+
+ +
248 """
+
249 @brief Ensure all method calls have corresponding mappings.
+
250 @details Handles methods called but not defined in the class.
+
251 """
+
252 for class_name, method_calls in self.mapping.seen_method_calls.items():
+
253 if class_name not in self.mapping.class_methods:
+
254 continue
+
255
+
256 for method_name in method_calls:
+
257 # Skip dunder methods
+
258 if method_name.startswith('__') and method_name.endswith('__'):
+
259 continue
+
260
+
261 # Add mapping if method was called but not defined
+
262 if method_name not in self.mapping.class_methods[class_name]:
+
263 obf_name = self.name_generator.generate_name()
+
264 self.mapping.class_methods[class_name][method_name] = obf_name
+
265 logger.debug(f"Added mapping for called method {class_name}.{method_name} -> {obf_name}")
+
266
+
267
+
+
+
+
268class ClassTransformer(ast.NodeTransformer):
+
269 """
+
270 @brief Transform class-related nodes using the mapping.
+
271 @details Renames class names, methods, and self.attr/self.method references
+
272 according to the analyzed mappings.
+
273 """
+
274
+
+
275 def __init__(self, mapping: ClassMapping):
+
276 self.mapping = mapping
+
277 self.current_class: Optional[str] = None
+
278
+
+
+
279 def visit_ClassDef(self, node: ast.ClassDef):
+
280 """
+
281 @brief Transform class name and process its body.
+
282 @param node ast.ClassDef node.
+
283 @return ast.ClassDef Transformed class node.
+
284 """
+
285 prev_class = self.current_class
+
286 orig_name = node.name
+
287 self.current_class = orig_name
+
288
+
289 # Rename class if it's in our mapping
+
290 if node.name in self.mapping.class_names:
+
291 node.name = self.mapping.class_names[node.name]
+
292 logger.debug(f"Transformed class {orig_name} -> {node.name}")
+
293
+
294 # Process class body
+
295 node.body = [self.visit(item) for item in node.body]
+
296
+
297 self.current_class = prev_class
+
298 return node
+
299
+
+
+
300 def visit_FunctionDef(self, node: ast.FunctionDef):
+
301 """
+
302 @brief Transform method name.
+
303 @param node ast.FunctionDef node.
+
304 @return ast.FunctionDef Transformed method node.
+
305 """
+
306 if self.current_class and node.name in self.mapping.class_methods.get(self.current_class, {}):
+
307 orig_name = node.name
+
308 node.name = self.mapping.class_methods[self.current_class][node.name]
+
309 logger.debug(f"Transformed method {self.current_class}.{orig_name} -> {node.name}")
+
310
+
311 # Visit the method body
+
312 node.body = [self.visit(item) for item in node.body]
+
313 return node
+
314
+
+
+
315 def visit_Attribute(self, node: ast.Attribute):
+
316 """
+
317 @brief Transform self.method and self.attr references.
+
318 @param node ast.Attribute node.
+
319 @return ast.Attribute Transformed attribute node.
+
320 """
+
321 # Process any child nodes first (for nested attributes)
+
322 node.value = self.visit(node.value)
+
323
+
324 # Check if this is a self.attr or self.method reference
+
325 if self.current_class and isinstance(node.value, ast.Name) and node.value.id == 'self':
+
326 orig_name = node.attr
+
327
+
328 # Check in method mappings first
+
329 if self.current_class in self.mapping.class_methods and node.attr in self.mapping.class_methods[self.current_class]:
+
330 node.attr = self.mapping.class_methods[self.current_class][node.attr]
+
331 logger.debug(f"Transformed self.method {self.current_class}.{orig_name} -> {node.attr}")
+
332
+
333 # Then check attribute mappings
+
334 elif self.current_class in self.mapping.class_attributes and node.attr in self.mapping.class_attributes[self.current_class]:
+
335 node.attr = self.mapping.class_attributes[self.current_class][node.attr]
+
336 logger.debug(f"Transformed self.attr {self.current_class}.{orig_name} -> {node.attr}")
+
337
+
338 return node
+
339
+
340# Helper function to apply the class mapping transformation
+
+
+
+
341def apply_class_mapping(tree: ast.AST, name_generator) -> ast.AST:
+
342 """
+
343 @brief Analyze and transform classes consistently.
+
344 @param tree Input AST.
+
345 @param name_generator Name generator used to create obfuscated identifiers.
+
346 @return Tuple[ast.AST, ClassMapping] Transformed AST and the mapping produced.
+
347 """
+
348 # First pass: analyze all classes
+
349 analyzer = ClassMapAnalyzer(name_generator)
+
350 mapping = analyzer.analyze(tree)
+
351
+
352 # Second pass: transform using the mapping
+
353 transformer = ClassTransformer(mapping)
+
354 transformed = transformer.visit(tree)
+
355
+
356 return transformed, mapping
+
+ +
ClassMapping analyze(self, ast.AST tree)
+ +
visit_Attribute(self, ast.Attribute node)
+
visit_method_def(self, ast.FunctionDef node)
+ + + + + +
visit_ClassDef(self, ast.ClassDef node)
+ + + + + + + + +
visit_FunctionDef(self, ast.FunctionDef node)
+
visit_Attribute(self, ast.Attribute node)
+ + +
__init__(self, ClassMapping mapping)
+
+
+ + + + diff --git a/doxygen/classes.html b/doxygen/classes.html new file mode 100644 index 0000000..203867d --- /dev/null +++ b/doxygen/classes.html @@ -0,0 +1,129 @@ + + + + + + + +OMG-Fuscator: Class Index + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ + + + + + diff --git a/doxygen/classobfuscator_1_1AdvancedObfuscator-members.html b/doxygen/classobfuscator_1_1AdvancedObfuscator-members.html new file mode 100644 index 0000000..bb2c04a --- /dev/null +++ b/doxygen/classobfuscator_1_1AdvancedObfuscator-members.html @@ -0,0 +1,127 @@ + + + + + + + +OMG-Fuscator: Member List + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ + + + + + diff --git a/doxygen/classobfuscator_1_1AdvancedObfuscator.html b/doxygen/classobfuscator_1_1AdvancedObfuscator.html new file mode 100644 index 0000000..ebcbac5 --- /dev/null +++ b/doxygen/classobfuscator_1_1AdvancedObfuscator.html @@ -0,0 +1,953 @@ + + + + + + + +OMG-Fuscator: obfuscator.AdvancedObfuscator Class Reference + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
obfuscator.AdvancedObfuscator Class Reference
+
+
+ + + + + + + + + + +

+Public Member Functions

 __init__ (self, debug_mode=False)
 
 detect_issues (self)
 
 log_debug (self, category, data)
 
str obfuscate (self, str code)
 
+ + + + + + + + + + + + + + + + + + + + + + + +

+Public Attributes

 class_attr_mapping
 
 debug_data
 
 debug_mode
 
 global_var_renames
 
 junk_gen
 
 name_generator
 
 primary_key
 
 salt
 
 secondary_key
 
 symbol_tree
 
 used_names
 
+ + + + + + + + + +

+Protected Member Functions

SymbolTree _build_symbol_tree (self, ast.AST tree)
 
ast.AST _flatten_control_flow (self, ast.AST tree)
 
str _generate_final_code (self, ast.AST tree)
 
ast.AST _rename_and_encrypt (self, ast.AST tree)
 
+

Detailed Description

+
@brief Core obfuscation engine orchestrating all transformations.
+@details Coordinates name generation, symbol tree construction, AST transformations
+         for renaming and string encryption, control-flow flattening, and final
+         code generation with junk injection. Optionally records detailed debug data.
+
+

Definition at line 25 of file obfuscator.py.

+

Constructor & Destructor Documentation

+ +

◆ __init__()

+ +
+
+ + + + + + + + + + + + + + + + + + +
obfuscator.AdvancedObfuscator.__init__ ( self,
 debug_mode = False 
)
+
+ +

Definition at line 32 of file obfuscator.py.

+
32 def __init__(self, debug_mode=False):
+
33 self.used_names = set()
+
34 self.name_generator = NameGenerator()
+
35
+
36 # Generate keys for string encryption
+
37 self.primary_key = bytes([random.randint(65, 90) for _ in range(16)])
+
38 self.secondary_key = bytes([random.randint(65, 90) for _ in range(8)])
+
39 self.salt = bytes([random.randint(65, 90) for _ in range(4)])
+
40
+
41 # Symbol tree for global tracking of all symbols
+
42 self.symbol_tree = None
+
43
+
44 # Legacy mappings for backward compatibility
+
45 self.class_attr_mapping = {}
+
46 self.global_var_renames = {}
+
47
+
48 # Initialize junk generator
+
49 self.junk_gen = JunkGenerator(self.name_generator)
+
50
+
51 # Debugging flags and data structures
+
52 self.debug_mode = debug_mode
+
53 self.debug_data = {
+
54 "timestamp": datetime.now().isoformat(),
+
55 "transformations": [],
+
56 "class_mappings": {},
+
57 "variable_mappings": {},
+
58 "method_mappings": {},
+
59 "string_encryption": [],
+
60 "issues_detected": [],
+
61 "control_flow_stats": {},
+
62 "junk_stats": {"count": 0, "snippets": []}
+
63 }
+
64
+
+
+
+

Member Function Documentation

+ +

◆ _build_symbol_tree()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
SymbolTree obfuscator.AdvancedObfuscator._build_symbol_tree ( self,
ast.AST tree 
)
+
+protected
+
+
@brief Build a global symbol tree from the parsed AST.
+@param tree Parsed AST of the input source.
+@return SymbolTree Populated symbol tree with rename mappings and metadata.
+
+

Definition at line 115 of file obfuscator.py.

+
115 def _build_symbol_tree(self, tree: ast.AST) -> SymbolTree:
+
116 """
+
117 @brief Build a global symbol tree from the parsed AST.
+
118 @param tree Parsed AST of the input source.
+
119 @return SymbolTree Populated symbol tree with rename mappings and metadata.
+
120 """
+
121 if self.debug_mode:
+
122 self.log_debug("symbol_tree_building", "Building global symbol tree")
+
123
+
124 builder = SymbolTreeBuilder()
+
125 symbol_tree = builder.build_tree(tree)
+
126
+
127 # Apply name generator to all symbols
+
128 symbol_tree.apply_name_generator(self.name_generator)
+
129
+
130 # Populate legacy mappings for backward compatibility
+
131 rename_mapping = symbol_tree.get_rename_mapping()
+
132
+
133 # Update class and method mappings
+
134 for class_name, class_obf_name in rename_mapping["classes"].items():
+
135 self.global_var_renames[class_name] = class_obf_name
+
136
+
137 # Initialize class_attr_mapping entry
+
138 if class_obf_name not in self.class_attr_mapping:
+
139 self.class_attr_mapping[class_obf_name] = {}
+
140
+
141 # Copy method mappings
+
142 if class_name in rename_mapping["methods"]:
+
143 for method_name, method_obf_name in rename_mapping["methods"][class_name].items():
+
144 self.class_attr_mapping[class_obf_name][method_name] = method_obf_name
+
145
+
146 # Copy attribute mappings
+
147 if class_name in rename_mapping["attributes"]:
+
148 for attr_name, attr_obf_name in rename_mapping["attributes"][class_name].items():
+
149 self.class_attr_mapping[class_obf_name][attr_name] = attr_obf_name
+
150
+
151 # Update function and variable mappings
+
152 self.global_var_renames.update(rename_mapping["functions"])
+
153 self.global_var_renames.update(rename_mapping["variables"])
+
154
+
155 if self.debug_mode:
+
156 self.log_debug("symbol_tree_stats", {
+
157 "classes": len(rename_mapping["classes"]),
+
158 "methods": sum(len(methods) for methods in rename_mapping["methods"].values()),
+
159 "attributes": sum(len(attrs) for attrs in rename_mapping["attributes"].values()),
+
160 "functions": len(rename_mapping["functions"]),
+
161 "variables": len(rename_mapping["variables"])
+
162 })
+
163
+
164 return symbol_tree
+
165
+
+

References obfuscator.AdvancedObfuscator.class_attr_mapping, transformers.attribute_transformer.AttributeTransformer.class_attr_mapping, transformers.rename.RenameTransformer.class_attr_mapping, obfuscator.AdvancedObfuscator.debug_mode, transformers.control_flow.ControlFlowFlattener.debug_mode, transformers.rename.RenameTransformer.debug_mode, obfuscator.AdvancedObfuscator.global_var_renames, transformers.rename.RenameTransformer.global_var_renames, obfuscator.AdvancedObfuscator.log_debug(), transformers.control_flow.ControlFlowFlattener.log_debug(), transformers.rename.RenameTransformer.log_debug(), obfuscator.AdvancedObfuscator.name_generator, transformers.class_analyzer.ClassAnalyzer.name_generator, transformers.class_mapper.ClassMapAnalyzer.name_generator, transformers.rename.RenameTransformer.name_generator, and utils.junk_gen.JunkGenerator.name_generator.

+ +

Referenced by obfuscator.AdvancedObfuscator._rename_and_encrypt().

+ +
+
+ +

◆ _flatten_control_flow()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
ast.AST obfuscator.AdvancedObfuscator._flatten_control_flow ( self,
ast.AST tree 
)
+
+protected
+
+
@brief Flatten control flow into a state-machine dispatch form.
+@param tree AST after renaming/encryption.
+@return ast.AST Transformed AST with flattened control flow.
+
+

Definition at line 196 of file obfuscator.py.

+
196 def _flatten_control_flow(self, tree: ast.AST) -> ast.AST:
+
197 """
+
198 @brief Flatten control flow into a state-machine dispatch form.
+
199 @param tree AST after renaming/encryption.
+
200 @return ast.AST Transformed AST with flattened control flow.
+
201 """
+
202 flattener = ControlFlowFlattener(debug_mode=self.debug_mode)
+
203 tree = flattener.visit(tree)
+
204
+
205 # Capture debug data from flattener if available
+
206 if self.debug_mode and hasattr(flattener, 'debug_data'):
+
207 self.debug_data["control_flow_stats"] = flattener.debug_data
+
208
+
209 ast.fix_missing_locations(tree)
+
210 return tree
+
211
+
+

References obfuscator.AdvancedObfuscator.debug_data, transformers.control_flow.ControlFlowFlattener.debug_data, transformers.rename.RenameTransformer.debug_data, obfuscator.AdvancedObfuscator.debug_mode, transformers.control_flow.ControlFlowFlattener.debug_mode, and transformers.rename.RenameTransformer.debug_mode.

+ +

Referenced by obfuscator.AdvancedObfuscator.obfuscate().

+ +
+
+ +

◆ _generate_final_code()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
str obfuscator.AdvancedObfuscator._generate_final_code ( self,
ast.AST tree 
)
+
+protected
+
+
@brief Generate final Python source from the AST and inject junk code.
+@param tree AST after all transformations.
+@return str Final obfuscated Python source code.
+
+

Definition at line 212 of file obfuscator.py.

+
212 def _generate_final_code(self, tree: ast.AST) -> str:
+
213 """
+
214 @brief Generate final Python source from the AST and inject junk code.
+
215 @param tree AST after all transformations.
+
216 @return str Final obfuscated Python source code.
+
217 """
+
218 lines = ast.unparse(tree).split('\n')
+
219 in_multiline = False
+
220 skip_for_n = 0
+
221 junk_count = 0
+
222 junk_snippets = []
+
223
+
224 def in_try_block(ls, ci):
+
225 c_line = ls[ci]
+
226 c_strip = c_line.lstrip()
+
227 c_indent = len(c_line) - len(c_strip)
+
228 saw_try = False
+
229 for idx in range(ci - 1, -1, -1):
+
230 l = ls[idx]
+
231 s = l.lstrip()
+
232 i_amount = len(l) - len(s)
+
233 if s.startswith(("except ", "finally:")) and i_amount <= c_indent:
+
234 break
+
235 if s.startswith("try:") and i_amount <= c_indent:
+
236 saw_try = True
+
237 break
+
238 return saw_try
+
239
+
240 # We add these two lines at the top to ensure random is imported
+
241 result = ["import random"]
+
242
+
243 for i, line in enumerate(lines):
+
244 strip = line.lstrip()
+
245 if '"""' in strip or "'''" in strip:
+
246 in_multiline = not in_multiline
+
247
+
248 # Conditions to inject junk
+
249 can_inject = (
+
250 not in_multiline
+
251 and not in_try_block(lines, i)
+
252 and skip_for_n == 0
+
253 and not strip.startswith(
+
254 (
+
255 "def ", "class ", "@", "try:", "except ", "finally:",
+
256 "import ", "from ", "elif ", "else:", "return", "raise",
+
257 "pass", "break", "continue"
+
258 )
+
259 )
+
260 )
+
261 if can_inject:
+
262 junk = self.junk_gen.generate_junk()
+
263 result.append(junk)
+
264 junk_snippets.append(junk)
+
265 junk_count += 1
+
266 skip_for_n = random.randint(5, 15)
+
267 else:
+
268 skip_for_n = max(0, skip_for_n - 1)
+
269
+
270 result.append(line)
+
271
+
272 if self.debug_mode:
+
273 self.debug_data["junk_stats"]["count"] = junk_count
+
274 self.debug_data["junk_stats"]["snippets"] = junk_snippets
+
275
+
276 return '\n'.join(result)
+
277
+
+

References obfuscator.AdvancedObfuscator.debug_data, transformers.control_flow.ControlFlowFlattener.debug_data, transformers.rename.RenameTransformer.debug_data, obfuscator.AdvancedObfuscator.debug_mode, transformers.control_flow.ControlFlowFlattener.debug_mode, transformers.rename.RenameTransformer.debug_mode, and obfuscator.AdvancedObfuscator.junk_gen.

+ +

Referenced by obfuscator.AdvancedObfuscator.obfuscate().

+ +
+
+ +

◆ _rename_and_encrypt()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
ast.AST obfuscator.AdvancedObfuscator._rename_and_encrypt ( self,
ast.AST tree 
)
+
+protected
+
+
@brief Rename identifiers and encrypt string literals in the AST.
+@param tree Input AST prior to control-flow transformations.
+@return ast.AST Transformed AST with consistent renames and encrypted strings.
+
+

Definition at line 166 of file obfuscator.py.

+
166 def _rename_and_encrypt(self, tree: ast.AST) -> ast.AST:
+
167 """
+
168 @brief Rename identifiers and encrypt string literals in the AST.
+
169 @param tree Input AST prior to control-flow transformations.
+
170 @return ast.AST Transformed AST with consistent renames and encrypted strings.
+
171 """
+
172 # First, build a comprehensive symbol tree
+
173 self.symbol_tree = self._build_symbol_tree(tree)
+
174
+
175 # Now perform the main transformation with consistent mappings
+
176 transformer = RenameTransformer(
+
177 self.name_generator,
+
178 self.global_var_renames,
+
179 self.class_attr_mapping,
+
180 self.primary_key,
+
181 self.secondary_key,
+
182 self.salt,
+
183 debug_mode=self.debug_mode
+
184 )
+
185
+
186 tree = transformer.visit(tree)
+
187
+
188 # Capture debug data from transformer if available
+
189 if self.debug_mode and hasattr(transformer, 'debug_data'):
+
190 self.debug_data["variable_mappings"] = transformer.debug_data.get("variable_mappings", {})
+
191 self.debug_data["string_encryption"] = transformer.debug_data.get("string_encryption", [])
+
192
+
193 ast.fix_missing_locations(tree)
+
194 return tree
+
195
+
+

References obfuscator.AdvancedObfuscator._build_symbol_tree(), obfuscator.AdvancedObfuscator.class_attr_mapping, transformers.attribute_transformer.AttributeTransformer.class_attr_mapping, transformers.rename.RenameTransformer.class_attr_mapping, obfuscator.AdvancedObfuscator.debug_data, transformers.control_flow.ControlFlowFlattener.debug_data, transformers.rename.RenameTransformer.debug_data, obfuscator.AdvancedObfuscator.debug_mode, transformers.control_flow.ControlFlowFlattener.debug_mode, transformers.rename.RenameTransformer.debug_mode, obfuscator.AdvancedObfuscator.global_var_renames, transformers.rename.RenameTransformer.global_var_renames, obfuscator.AdvancedObfuscator.name_generator, transformers.class_analyzer.ClassAnalyzer.name_generator, transformers.class_mapper.ClassMapAnalyzer.name_generator, transformers.rename.RenameTransformer.name_generator, utils.junk_gen.JunkGenerator.name_generator, obfuscator.AdvancedObfuscator.primary_key, utils.encryption.StringEncryptor.primary_key, obfuscator.AdvancedObfuscator.salt, utils.encryption.StringEncryptor.salt, obfuscator.AdvancedObfuscator.secondary_key, utils.encryption.StringEncryptor.secondary_key, and obfuscator.AdvancedObfuscator.symbol_tree.

+ +

Referenced by obfuscator.AdvancedObfuscator.obfuscate().

+ +
+
+ +

◆ detect_issues()

+ +
+
+ + + + + + + + +
obfuscator.AdvancedObfuscator.detect_issues ( self)
+
+
@brief Run integrity checks and record any issues to debug data.
+@details Aggregates issues from the symbol tree and legacy name-collision
+         checks to help diagnose transformation inconsistencies.
+
+

Definition at line 78 of file obfuscator.py.

+
78 def detect_issues(self):
+
79 """
+
80 @brief Run integrity checks and record any issues to debug data.
+
81 @details Aggregates issues from the symbol tree and legacy name-collision
+
82 checks to help diagnose transformation inconsistencies.
+
83 """
+
84 if not self.debug_mode:
+
85 return
+
86
+
87 # First check issues in the symbol tree
+
88 if self.symbol_tree:
+
89 symbol_tree_issues = self.symbol_tree.check_for_issues()
+
90 for issue in symbol_tree_issues:
+
91 self.debug_data["issues_detected"].append(issue)
+
92
+
93 # Legacy checks for backwards compatibility
+
94 used_renames = set()
+
95 duplicates = []
+
96
+
97 for orig, renamed in self.global_var_renames.items():
+
98 if renamed in used_renames:
+
99 duplicates.append(renamed)
+
100 used_renames.add(renamed)
+
101
+
102 # Check if our renamed values match any original names (could lead to conflicts)
+
103 if renamed in self.global_var_renames.keys():
+
104 self.debug_data["issues_detected"].append({
+
105 "type": "name_collision",
+
106 "info": f"Renamed value '{renamed}' matches an original name"
+
107 })
+
108
+
109 if duplicates:
+
110 self.debug_data["issues_detected"].append({
+
111 "type": "duplicate_names",
+
112 "names": duplicates
+
113 })
+
114
+
+

References obfuscator.AdvancedObfuscator.debug_data, transformers.control_flow.ControlFlowFlattener.debug_data, transformers.rename.RenameTransformer.debug_data, obfuscator.AdvancedObfuscator.debug_mode, transformers.control_flow.ControlFlowFlattener.debug_mode, transformers.rename.RenameTransformer.debug_mode, obfuscator.AdvancedObfuscator.global_var_renames, transformers.rename.RenameTransformer.global_var_renames, and obfuscator.AdvancedObfuscator.symbol_tree.

+ +
+
+ +

◆ log_debug()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
obfuscator.AdvancedObfuscator.log_debug ( self,
 category,
 data 
)
+
+
@brief Append a structured debug entry if debug mode is enabled.
+@param category Logical stage or component name.
+@param data Arbitrary JSON-serializable payload to record.
+
+

Definition at line 65 of file obfuscator.py.

+
65 def log_debug(self, category, data):
+
66 """
+
67 @brief Append a structured debug entry if debug mode is enabled.
+
68 @param category Logical stage or component name.
+
69 @param data Arbitrary JSON-serializable payload to record.
+
70 """
+
71 if self.debug_mode:
+
72 self.debug_data["transformations"].append({
+
73 "stage": category,
+
74 "data": data,
+
75 "timestamp": datetime.now().isoformat()
+
76 })
+
77
+
+

References obfuscator.AdvancedObfuscator.debug_data, transformers.control_flow.ControlFlowFlattener.debug_data, transformers.rename.RenameTransformer.debug_data, obfuscator.AdvancedObfuscator.debug_mode, transformers.control_flow.ControlFlowFlattener.debug_mode, and transformers.rename.RenameTransformer.debug_mode.

+ +

Referenced by obfuscator.AdvancedObfuscator._build_symbol_tree(), transformers.control_flow.ControlFlowFlattener.generate_junk_code(), transformers.control_flow.ControlFlowFlattener.visit_Break(), transformers.control_flow.ControlFlowFlattener.visit_Continue(), transformers.control_flow.ControlFlowFlattener.visit_For(), transformers.control_flow.ControlFlowFlattener.visit_FunctionDef(), transformers.control_flow.ControlFlowFlattener.visit_If(), transformers.control_flow.ControlFlowFlattener.visit_Return(), and transformers.control_flow.ControlFlowFlattener.visit_While().

+ +
+
+ +

◆ obfuscate()

+ +
+
+ + + + + + + + + + + + + + + + + + +
str obfuscator.AdvancedObfuscator.obfuscate ( self,
str code 
)
+
+
@brief End-to-end obfuscation entry point.
+@param code Original Python source code.
+@return str Obfuscated Python source code.
+
+

Definition at line 278 of file obfuscator.py.

+
278 def obfuscate(self, code: str) -> str:
+
279 """
+
280 @brief End-to-end obfuscation entry point.
+
281 @param code Original Python source code.
+
282 @return str Obfuscated Python source code.
+
283 """
+
284 tree = ast.parse(code)
+
285
+
286 # Step 1: Rename and encrypt
+
287 tree = self._rename_and_encrypt(tree)
+
288
+
289 # Step 2: Flatten control flow
+
290 tree = self._flatten_control_flow(tree)
+
291
+
292 # Step 3: Generate final obfuscated code
+
293 final_code = self._generate_final_code(tree)
+
294
+
295 if self.debug_mode:
+
296 debug_output_path = os.path.join("debug", f"debug_{self.debug_data['timestamp']}.json")
+
297 os.makedirs(os.path.dirname(debug_output_path), exist_ok=True)
+
298 with open(debug_output_path, "w") as debug_file:
+
299 json.dump(self.debug_data, debug_file, indent=4)
+
300
+
301 return final_code
+
+

References obfuscator.AdvancedObfuscator._flatten_control_flow(), obfuscator.AdvancedObfuscator._generate_final_code(), obfuscator.AdvancedObfuscator._rename_and_encrypt(), obfuscator.AdvancedObfuscator.debug_data, transformers.control_flow.ControlFlowFlattener.debug_data, transformers.rename.RenameTransformer.debug_data, obfuscator.AdvancedObfuscator.debug_mode, transformers.control_flow.ControlFlowFlattener.debug_mode, and transformers.rename.RenameTransformer.debug_mode.

+ +
+
+

Member Data Documentation

+ +

◆ class_attr_mapping

+ + + +

◆ debug_data

+ + + +

◆ debug_mode

+ + + +

◆ global_var_renames

+ + + +

◆ junk_gen

+ +
+
+ + + + +
obfuscator.AdvancedObfuscator.junk_gen
+
+ +

Definition at line 49 of file obfuscator.py.

+ +

Referenced by obfuscator.AdvancedObfuscator._generate_final_code().

+ +
+
+ +

◆ name_generator

+ + + +

◆ primary_key

+ +
+
+ + + + +
obfuscator.AdvancedObfuscator.primary_key
+
+
+ +

◆ salt

+ +
+
+ + + + +
obfuscator.AdvancedObfuscator.salt
+
+
+ +

◆ secondary_key

+ +
+
+ + + + +
obfuscator.AdvancedObfuscator.secondary_key
+
+
+ +

◆ symbol_tree

+ +
+
+ + + + +
obfuscator.AdvancedObfuscator.symbol_tree
+
+
+ +

◆ used_names

+ +
+
+ + + + +
obfuscator.AdvancedObfuscator.used_names
+
+ +

Definition at line 33 of file obfuscator.py.

+ +

Referenced by utils.name_gen.NameGenerator.generate_name().

+ +
+
+
The documentation for this class was generated from the following file: +
+
+ + + + diff --git a/doxygen/classobfuscator_1_1AdvancedObfuscator.js b/doxygen/classobfuscator_1_1AdvancedObfuscator.js new file mode 100644 index 0000000..6df2599 --- /dev/null +++ b/doxygen/classobfuscator_1_1AdvancedObfuscator.js @@ -0,0 +1,22 @@ +var classobfuscator_1_1AdvancedObfuscator = +[ + [ "__init__", "classobfuscator_1_1AdvancedObfuscator.html#aaffc65fd026066b5db7b28c767113b2b", null ], + [ "_build_symbol_tree", "classobfuscator_1_1AdvancedObfuscator.html#a424ba5de0c9a2ea94ffe39f58b6a04b8", null ], + [ "_flatten_control_flow", "classobfuscator_1_1AdvancedObfuscator.html#aab379b03fecc184395d84df866849bdb", null ], + [ "_generate_final_code", "classobfuscator_1_1AdvancedObfuscator.html#ac72c695b2382f94015e9133254c60ba8", null ], + [ "_rename_and_encrypt", "classobfuscator_1_1AdvancedObfuscator.html#ac5445e1980a8addc56b5e9e4b134f2a7", null ], + [ "detect_issues", "classobfuscator_1_1AdvancedObfuscator.html#aa5653d0e597359d527b772223acb9c54", null ], + [ "log_debug", "classobfuscator_1_1AdvancedObfuscator.html#add2f1a570ef241ad62e977d434973ddf", null ], + [ "obfuscate", "classobfuscator_1_1AdvancedObfuscator.html#a0bae5229abba4f829e01b84cb9c9ffd7", null ], + [ "class_attr_mapping", "classobfuscator_1_1AdvancedObfuscator.html#aef5016cadd430585e9e3bf6cd651766b", null ], + [ "debug_data", "classobfuscator_1_1AdvancedObfuscator.html#a4c05fe283ed840c34d9a4b1b8b90297b", null ], + [ "debug_mode", "classobfuscator_1_1AdvancedObfuscator.html#a755ab23358e464b4a4d8ea144d84c5db", null ], + [ "global_var_renames", "classobfuscator_1_1AdvancedObfuscator.html#a3ec1e13df931c1508ce87c1d43319d9e", null ], + [ "junk_gen", "classobfuscator_1_1AdvancedObfuscator.html#aaae69f3be557e46d9538d68caa5f2959", null ], + [ "name_generator", "classobfuscator_1_1AdvancedObfuscator.html#abaeb1135a6445bef98ac6574f827d6df", null ], + [ "primary_key", "classobfuscator_1_1AdvancedObfuscator.html#a6b389da576cc61f0404f71d31768ea80", null ], + [ "salt", "classobfuscator_1_1AdvancedObfuscator.html#aef1166ac92f95772a86271833cf0dc8d", null ], + [ "secondary_key", "classobfuscator_1_1AdvancedObfuscator.html#a5a777b8774460385c5640e6a7fd8abd3", null ], + [ "symbol_tree", "classobfuscator_1_1AdvancedObfuscator.html#a663f90581cbf805979af75ac48f400a3", null ], + [ "used_names", "classobfuscator_1_1AdvancedObfuscator.html#a9df466e5d1c16e8f5209573b5283fd2e", null ] +]; \ No newline at end of file diff --git a/doxygen/classtransformers_1_1attribute__transformer_1_1AttributeTransformer-members.html b/doxygen/classtransformers_1_1attribute__transformer_1_1AttributeTransformer-members.html new file mode 100644 index 0000000..06009d9 --- /dev/null +++ b/doxygen/classtransformers_1_1attribute__transformer_1_1AttributeTransformer-members.html @@ -0,0 +1,114 @@ + + + + + + + +OMG-Fuscator: Member List + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
transformers.attribute_transformer.AttributeTransformer Member List
+
+ +
+ + + + diff --git a/doxygen/classtransformers_1_1attribute__transformer_1_1AttributeTransformer.html b/doxygen/classtransformers_1_1attribute__transformer_1_1AttributeTransformer.html new file mode 100644 index 0000000..789c4ea --- /dev/null +++ b/doxygen/classtransformers_1_1attribute__transformer_1_1AttributeTransformer.html @@ -0,0 +1,368 @@ + + + + + + + +OMG-Fuscator: transformers.attribute_transformer.AttributeTransformer Class Reference + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
transformers.attribute_transformer.AttributeTransformer Class Reference
+
+
+
+ + Inheritance diagram for transformers.attribute_transformer.AttributeTransformer:
+
+
+ +
+ + Collaboration diagram for transformers.attribute_transformer.AttributeTransformer:
+
+
+ + + + + + + + + +

+Public Member Functions

 __init__ (self, Dict[str, Dict[str, str]] class_attr_mapping, Dict[str, str] class_renames)
 
 visit_Attribute (self, node)
 
 visit_ClassDef (self, node)
 
+ + + + + + + +

+Public Attributes

 class_attr_mapping
 
 class_renames
 
 current_class
 
+

Detailed Description

+
@brief Transform attribute access expressions for consistency.
+@details Handles self.method and self.attr translations based on provided
+         mappings to keep calls and attributes aligned with obfuscated names.
+
+

Definition at line 11 of file attribute_transformer.py.

+

Constructor & Destructor Documentation

+ +

◆ __init__()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
transformers.attribute_transformer.AttributeTransformer.__init__ ( self,
Dict[str, Dict[str, str]] class_attr_mapping,
Dict[str, str] class_renames 
)
+
+
@brief Initialize transformer with mapping dictionaries.
+@param class_attr_mapping Maps class_name -> {attr_name -> obfuscated_attr_name}
+@param class_renames Maps original_class_name -> obfuscated_class_name
+
+

Definition at line 18 of file attribute_transformer.py.

+
18 def __init__(self, class_attr_mapping: Dict[str, Dict[str, str]], class_renames: Dict[str, str]):
+
19 """
+
20 @brief Initialize transformer with mapping dictionaries.
+
21 @param class_attr_mapping Maps class_name -> {attr_name -> obfuscated_attr_name}
+
22 @param class_renames Maps original_class_name -> obfuscated_class_name
+
23 """
+
24 self.class_attr_mapping = class_attr_mapping
+
25 self.class_renames = class_renames
+
26 self.current_class: Optional[str] = None
+
27
+
+
+
+

Member Function Documentation

+ +

◆ visit_Attribute()

+ +
+
+ + + + + + + + + + + + + + + + + + +
transformers.attribute_transformer.AttributeTransformer.visit_Attribute ( self,
 node 
)
+
+
@brief Transform attribute access for consistency within a class.
+@param node ast.Attribute node to transform.
+@return ast.AST Updated attribute node.
+
+

Definition at line 50 of file attribute_transformer.py.

+
50 def visit_Attribute(self, node):
+
51 """
+
52 @brief Transform attribute access for consistency within a class.
+
53 @param node ast.Attribute node to transform.
+
54 @return ast.AST Updated attribute node.
+
55 """
+
56 # First process any nested attributes
+
57 node = self.generic_visit(node)
+
58
+
59 # Handle self.attr references within a class
+
60 if isinstance(node.value, ast.Name) and node.value.id == 'self' and self.current_class:
+
61 if self.current_class in self.class_attr_mapping:
+
62 attr_map = self.class_attr_mapping[self.current_class]
+
63 # Only substitute if node.attr is still in its original form (a mapping key)
+
64 if node.attr in attr_map and node.attr != attr_map[node.attr]:
+
65 node.attr = attr_map[node.attr]
+
66
+
67 return node
+
+

References obfuscator.AdvancedObfuscator.class_attr_mapping, transformers.attribute_transformer.AttributeTransformer.class_attr_mapping, transformers.rename.RenameTransformer.class_attr_mapping, transformers.attribute_transformer.AttributeTransformer.current_class, transformers.class_analyzer.ClassAnalyzer.current_class, transformers.class_mapper.ClassMapAnalyzer.current_class, transformers.class_mapper.ClassTransformer.current_class, and transformers.symbol_tree.SymbolTreeBuilder.current_class.

+ +
+
+ +

◆ visit_ClassDef()

+ +
+
+ + + + + + + + + + + + + + + + + + +
transformers.attribute_transformer.AttributeTransformer.visit_ClassDef ( self,
 node 
)
+
+
@brief Track the current class and process its body.
+@param node ast.ClassDef being visited.
+@return ast.ClassDef Potentially modified node.
+
+

Definition at line 28 of file attribute_transformer.py.

+
28 def visit_ClassDef(self, node):
+
29 """
+
30 @brief Track the current class and process its body.
+
31 @param node ast.ClassDef being visited.
+
32 @return ast.ClassDef Potentially modified node.
+
33 """
+
34 old_class = self.current_class
+
35
+
36 # Get the obfuscated name for this class
+
37 class_name = node.name
+
38 if class_name in self.class_renames:
+
39 self.current_class = self.class_renames[class_name]
+
40 else:
+
41 self.current_class = class_name
+
42
+
43 # Process the class body
+
44 node = self.generic_visit(node)
+
45
+
46 # Restore the previous class context
+
47 self.current_class = old_class
+
48 return node
+
49
+
+

References transformers.attribute_transformer.AttributeTransformer.class_renames, transformers.attribute_transformer.AttributeTransformer.current_class, transformers.class_analyzer.ClassAnalyzer.current_class, transformers.class_mapper.ClassMapAnalyzer.current_class, transformers.class_mapper.ClassTransformer.current_class, and transformers.symbol_tree.SymbolTreeBuilder.current_class.

+ +
+
+

Member Data Documentation

+ +

◆ class_attr_mapping

+ + + +

◆ class_renames

+ +
+
+ + + + +
transformers.attribute_transformer.AttributeTransformer.class_renames
+
+
+ +

◆ current_class

+ + +
The documentation for this class was generated from the following file: +
+
+ + + + diff --git a/doxygen/classtransformers_1_1attribute__transformer_1_1AttributeTransformer.js b/doxygen/classtransformers_1_1attribute__transformer_1_1AttributeTransformer.js new file mode 100644 index 0000000..0f3ac10 --- /dev/null +++ b/doxygen/classtransformers_1_1attribute__transformer_1_1AttributeTransformer.js @@ -0,0 +1,9 @@ +var classtransformers_1_1attribute__transformer_1_1AttributeTransformer = +[ + [ "__init__", "classtransformers_1_1attribute__transformer_1_1AttributeTransformer.html#a8bc2a45cb2e19075483d7b5b9c98ed50", null ], + [ "visit_Attribute", "classtransformers_1_1attribute__transformer_1_1AttributeTransformer.html#abe7e476c5bb7ecf22c0c5f7747cd1a9e", null ], + [ "visit_ClassDef", "classtransformers_1_1attribute__transformer_1_1AttributeTransformer.html#aa0bde339bf61f794e984dd890db8fd91", null ], + [ "class_attr_mapping", "classtransformers_1_1attribute__transformer_1_1AttributeTransformer.html#a2a45c1b9df1d719347a72d72cbb2891c", null ], + [ "class_renames", "classtransformers_1_1attribute__transformer_1_1AttributeTransformer.html#ade8fc4fc84a3bdddfd346bc95b711f13", null ], + [ "current_class", "classtransformers_1_1attribute__transformer_1_1AttributeTransformer.html#ad8426d8acb4d7fd20e18468414a15d5c", null ] +]; \ No newline at end of file diff --git a/doxygen/classtransformers_1_1attribute__transformer_1_1AttributeTransformer__coll__graph.dot b/doxygen/classtransformers_1_1attribute__transformer_1_1AttributeTransformer__coll__graph.dot new file mode 100644 index 0000000..30ba349 --- /dev/null +++ b/doxygen/classtransformers_1_1attribute__transformer_1_1AttributeTransformer__coll__graph.dot @@ -0,0 +1,10 @@ +digraph "transformers.attribute_transformer.AttributeTransformer" +{ + // LATEX_PDF_SIZE + bgcolor="transparent"; + edge [fontname=Helvetica,fontsize=10,labelfontname=Helvetica,labelfontsize=10]; + node [fontname=Helvetica,fontsize=10,shape=box,height=0.2,width=0.4]; + Node1 [id="Node000001",label="transformers.attribute\l_transformer.AttributeTransformer",height=0.2,width=0.4,color="gray40", fillcolor="grey60", style="filled", fontcolor="black",tooltip=" "]; + Node2 -> Node1 [id="edge1_Node000001_Node000002",dir="back",color="steelblue1",style="solid",tooltip=" "]; + Node2 [id="Node000002",label="ast::NodeTransformer",height=0.2,width=0.4,color="gray40", fillcolor="white", style="filled",tooltip=" "]; +} diff --git a/doxygen/classtransformers_1_1attribute__transformer_1_1AttributeTransformer__inherit__graph.dot b/doxygen/classtransformers_1_1attribute__transformer_1_1AttributeTransformer__inherit__graph.dot new file mode 100644 index 0000000..30ba349 --- /dev/null +++ b/doxygen/classtransformers_1_1attribute__transformer_1_1AttributeTransformer__inherit__graph.dot @@ -0,0 +1,10 @@ +digraph "transformers.attribute_transformer.AttributeTransformer" +{ + // LATEX_PDF_SIZE + bgcolor="transparent"; + edge [fontname=Helvetica,fontsize=10,labelfontname=Helvetica,labelfontsize=10]; + node [fontname=Helvetica,fontsize=10,shape=box,height=0.2,width=0.4]; + Node1 [id="Node000001",label="transformers.attribute\l_transformer.AttributeTransformer",height=0.2,width=0.4,color="gray40", fillcolor="grey60", style="filled", fontcolor="black",tooltip=" "]; + Node2 -> Node1 [id="edge1_Node000001_Node000002",dir="back",color="steelblue1",style="solid",tooltip=" "]; + Node2 [id="Node000002",label="ast::NodeTransformer",height=0.2,width=0.4,color="gray40", fillcolor="white", style="filled",tooltip=" "]; +} diff --git a/doxygen/classtransformers_1_1class__analyzer_1_1ClassAnalyzer-members.html b/doxygen/classtransformers_1_1class__analyzer_1_1ClassAnalyzer-members.html new file mode 100644 index 0000000..560b3a2 --- /dev/null +++ b/doxygen/classtransformers_1_1class__analyzer_1_1ClassAnalyzer-members.html @@ -0,0 +1,118 @@ + + + + + + + +OMG-Fuscator: Member List + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ + + + + + diff --git a/doxygen/classtransformers_1_1class__analyzer_1_1ClassAnalyzer.html b/doxygen/classtransformers_1_1class__analyzer_1_1ClassAnalyzer.html new file mode 100644 index 0000000..c6b7d16 --- /dev/null +++ b/doxygen/classtransformers_1_1class__analyzer_1_1ClassAnalyzer.html @@ -0,0 +1,624 @@ + + + + + + + +OMG-Fuscator: transformers.class_analyzer.ClassAnalyzer Class Reference + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
transformers.class_analyzer.ClassAnalyzer Class Reference
+
+
+
+ + Inheritance diagram for transformers.class_analyzer.ClassAnalyzer:
+
+
+ +
+ + Collaboration diagram for transformers.class_analyzer.ClassAnalyzer:
+
+
+ + + + + + + + + + + + + +

+Public Member Functions

 __init__ (self, name_generator)
 
ClassMethodMap analyze (self, ast.AST tree)
 
 visit_Attribute (self, node)
 
 visit_attribute_assign (self, node)
 
 visit_ClassDef (self, ast.ClassDef node)
 
+ + + + + + + +

+Public Attributes

 current_class
 
 method_map
 
 name_generator
 
+ + + + + +

+Protected Member Functions

 _ensure_consistent_method_mapping (self)
 
 _resolve_inheritance (self)
 
+

Detailed Description

+
@brief Analyze classes for consistent method/attribute renaming.
+@details Ensures self.method() calls match def method() definitions and records inheritance.
+
+

Definition at line 28 of file class_analyzer.py.

+

Constructor & Destructor Documentation

+ +

◆ __init__()

+ +
+
+ + + + + + + + + + + + + + + + + + +
transformers.class_analyzer.ClassAnalyzer.__init__ ( self,
 name_generator 
)
+
+ +

Definition at line 33 of file class_analyzer.py.

+
33 def __init__(self, name_generator):
+
34 self.name_generator = name_generator
+
35 self.method_map = ClassMethodMap()
+
36 self.current_class = None
+
37
+
38 # To avoid duplicate scanning
+
39 self.scanned_classes: Set[str] = set()
+
40
+
41 # Track method calls within each class
+
42 self.method_calls: Dict[str, Set[str]] = {}
+
43
+
+
+
+

Member Function Documentation

+ +

◆ _ensure_consistent_method_mapping()

+ +
+
+ + + + + +
+ + + + + + + + +
transformers.class_analyzer.ClassAnalyzer._ensure_consistent_method_mapping ( self)
+
+protected
+
+
@brief Ensure all self.method() calls have mappings, even if undefined in class.
+
+

Definition at line 155 of file class_analyzer.py.

+
155 def _ensure_consistent_method_mapping(self):
+
156 """
+
157 @brief Ensure all self.method() calls have mappings, even if undefined in class.
+
158 """
+
159 for class_name, method_calls in self.method_calls.items():
+
160 if class_name not in self.method_map.class_methods:
+
161 continue
+
162
+
163 class_methods = self.method_map.class_methods[class_name]
+
164 for method_name in method_calls:
+
165 if method_name not in class_methods:
+
166 # Skip dunder methods
+
167 if method_name.startswith('__') and method_name.endswith('__'):
+
168 continue
+
169 # Existing check: mapping is generated only once.
+
170 new_name = self.name_generator.generate_name()
+
171 class_methods[method_name] = new_name
+
172
+
+

References transformers.class_analyzer.ClassAnalyzer.method_map, obfuscator.AdvancedObfuscator.name_generator, transformers.class_analyzer.ClassAnalyzer.name_generator, transformers.class_mapper.ClassMapAnalyzer.name_generator, transformers.rename.RenameTransformer.name_generator, and utils.junk_gen.JunkGenerator.name_generator.

+ +

Referenced by transformers.class_analyzer.ClassAnalyzer.analyze().

+ +
+
+ +

◆ _resolve_inheritance()

+ +
+
+ + + + + +
+ + + + + + + + +
transformers.class_analyzer.ClassAnalyzer._resolve_inheritance ( self)
+
+protected
+
+
@brief Propagate method mappings along inheritance hierarchies.
+@details Ensures overridden methods reuse the same obfuscated name.
+
+

Definition at line 173 of file class_analyzer.py.

+
173 def _resolve_inheritance(self):
+
174 """
+
175 @brief Propagate method mappings along inheritance hierarchies.
+
176 @details Ensures overridden methods reuse the same obfuscated name.
+
177 """
+
178 # Process inheritance depth-first to handle multi-level inheritance
+
179 def process_inheritance(class_name):
+
180 if class_name not in self.method_map.inheritance:
+
181 return
+
182
+
183 for parent in self.method_map.inheritance[class_name]:
+
184 # Process parent's inheritance first
+
185 process_inheritance(parent)
+
186
+
187 # Skip if parent isn't in our mappings (external class)
+
188 if parent not in self.method_map.class_methods:
+
189 continue
+
190
+
191 # Inherit parent's methods if not overridden
+
192 for method_name, obf_name in self.method_map.class_methods[parent].items():
+
193 if method_name not in self.method_map.class_methods[class_name]:
+
194 self.method_map.class_methods[class_name][method_name] = obf_name
+
195
+
196 # Process inheritance for each class
+
197 for class_name in list(self.method_map.class_methods.keys()):
+
198 process_inheritance(class_name)
+
199
+
200
+
+

References transformers.class_analyzer.ClassAnalyzer.method_map.

+ +

Referenced by transformers.class_analyzer.ClassAnalyzer.analyze(), and transformers.class_mapper.ClassMapAnalyzer.analyze().

+ +
+
+ +

◆ analyze()

+ +
+
+ + + + + + + + + + + + + + + + + + +
ClassMethodMap transformers.class_analyzer.ClassAnalyzer.analyze ( self,
ast.AST tree 
)
+
+
@brief Analyze the entire AST and produce mappings.
+@param tree Parsed AST of the input module.
+@return ClassMethodMap Populated mappings.
+
+

Definition at line 44 of file class_analyzer.py.

+
44 def analyze(self, tree: ast.AST) -> ClassMethodMap:
+
45 """
+
46 @brief Analyze the entire AST and produce mappings.
+
47 @param tree Parsed AST of the input module.
+
48 @return ClassMethodMap Populated mappings.
+
49 """
+
50 self.visit(tree)
+
51 self._resolve_inheritance()
+
52 self._ensure_consistent_method_mapping()
+
53 return self.method_map
+
54
+
+

References transformers.class_analyzer.ClassAnalyzer._ensure_consistent_method_mapping(), transformers.class_analyzer.ClassAnalyzer._resolve_inheritance(), transformers.class_mapper.ClassMapAnalyzer._resolve_inheritance(), and transformers.class_analyzer.ClassAnalyzer.method_map.

+ +
+
+ +

◆ visit_Attribute()

+ +
+
+ + + + + + + + + + + + + + + + + + +
transformers.class_analyzer.ClassAnalyzer.visit_Attribute ( self,
 node 
)
+
+
@brief Track self.method references for consistency checks.
+@param node ast.Attribute being visited.
+
+

Definition at line 141 of file class_analyzer.py.

+
141 def visit_Attribute(self, node):
+
142 """
+
143 @brief Track self.method references for consistency checks.
+
144 @param node ast.Attribute being visited.
+
145 """
+
146 if self.current_class:
+
147 is_self_method, method_name = get_method_name(node)
+
148 if is_self_method:
+
149 # Record this method call for consistency checks later
+
150 self.method_calls[self.current_class].add(method_name)
+
151
+
152 # Continue traversing
+
153 self.generic_visit(node)
+
154
+
+

References transformers.attribute_transformer.AttributeTransformer.current_class, transformers.class_analyzer.ClassAnalyzer.current_class, transformers.class_mapper.ClassMapAnalyzer.current_class, transformers.class_mapper.ClassTransformer.current_class, transformers.symbol_tree.SymbolTreeBuilder.current_class, and transformers.class_analyzer.get_method_name().

+ +
+
+ +

◆ visit_attribute_assign()

+ +
+
+ + + + + + + + + + + + + + + + + + +
transformers.class_analyzer.ClassAnalyzer.visit_attribute_assign ( self,
 node 
)
+
+
@brief Process self.attr assignments within a class.
+@param node ast.Assign node of the assignment.
+
+

Definition at line 121 of file class_analyzer.py.

+
121 def visit_attribute_assign(self, node):
+
122 """
+
123 @brief Process self.attr assignments within a class.
+
124 @param node ast.Assign node of the assignment.
+
125 """
+
126 if not self.current_class:
+
127 return
+
128
+
129 for target in node.targets:
+
130 if isinstance(target, ast.Attribute) and isinstance(target.value, ast.Name):
+
131 if target.value.id == 'self':
+
132 # This is a self.attribute assignment
+
133 attr_name = target.attr
+
134 if attr_name not in self.method_map.class_attributes[self.current_class]:
+
135 new_name = self.name_generator.generate_name()
+
136 self.method_map.class_attributes[self.current_class][attr_name] = new_name
+
137
+
138 # Visit the value part of the assignment for nested self.method() calls
+
139 self.visit(node.value)
+
140
+
+

References transformers.attribute_transformer.AttributeTransformer.current_class, transformers.class_analyzer.ClassAnalyzer.current_class, transformers.class_mapper.ClassMapAnalyzer.current_class, transformers.class_mapper.ClassTransformer.current_class, transformers.symbol_tree.SymbolTreeBuilder.current_class, transformers.class_analyzer.ClassAnalyzer.method_map, obfuscator.AdvancedObfuscator.name_generator, transformers.class_analyzer.ClassAnalyzer.name_generator, transformers.class_mapper.ClassMapAnalyzer.name_generator, transformers.rename.RenameTransformer.name_generator, and utils.junk_gen.JunkGenerator.name_generator.

+ +

Referenced by transformers.class_analyzer.ClassAnalyzer.visit_ClassDef().

+ +
+
+ +

◆ visit_ClassDef()

+ +
+
+ + + + + + + + + + + + + + + + + + +
transformers.class_analyzer.ClassAnalyzer.visit_ClassDef ( self,
ast.ClassDef node 
)
+
+
@brief Process a class definition and map methods/attrs.
+@param node ast.ClassDef node being visited.
+
+

Definition at line 55 of file class_analyzer.py.

+
55 def visit_ClassDef(self, node: ast.ClassDef):
+
56 """
+
57 @brief Process a class definition and map methods/attrs.
+
58 @param node ast.ClassDef node being visited.
+
59 """
+
60 prev_class = self.current_class
+
61 self.current_class = node.name
+
62
+
63 # Skip if already processed this class
+
64 if node.name in self.scanned_classes:
+
65 self.current_class = prev_class
+
66 return
+
67
+
68 # Initialize method calls tracking for this class
+
69 self.method_calls[node.name] = set()
+
70
+
71 # Record class inheritance
+
72 parent_classes = []
+
73 for base in node.bases:
+
74 if isinstance(base, ast.Name):
+
75 parent_classes.append(base.id)
+
76
+
77 if parent_classes:
+
78 self.method_map.inheritance[node.name] = parent_classes
+
79
+
80 # Initialize mappings for this class
+
81 if node.name not in self.method_map.class_methods:
+
82 self.method_map.class_methods[node.name] = {}
+
83
+
84 if node.name not in self.method_map.class_attributes:
+
85 self.method_map.class_attributes[node.name] = {}
+
86
+
87 # Create a consistent obfuscated name for this class
+
88 if node.name not in self.method_map.class_renames:
+
89 new_name = self.name_generator.generate_name()
+
90 self.method_map.class_renames[node.name] = new_name
+
91
+
92 # Process all method definitions in the class
+
93 for item in node.body:
+
94 # Methods
+
95 if isinstance(item, ast.FunctionDef):
+
96 # Skip dunder methods
+
97 if not (item.name.startswith('__') and item.name.endswith('__')):
+
98 # Generate a consistent obfuscated name for this method
+
99 new_name = self.name_generator.generate_name()
+
100 self.method_map.class_methods[node.name][item.name] = new_name
+
101
+
102 # Visit the method body to find self.method() calls
+
103 self.visit(item)
+
104
+
105 # Attributes in assignments
+
106 elif isinstance(item, ast.Assign):
+
107 self.visit_attribute_assign(item)
+
108 else:
+
109 # Visit other nodes (like if statements that might contain self.method calls)
+
110 self.visit(item)
+
111
+
112 self.scanned_classes.add(node.name)
+
113
+
114 # Visit any nested classes
+
115 for item in node.body:
+
116 if isinstance(item, ast.ClassDef):
+
117 self.visit(item)
+
118
+
119 self.current_class = prev_class
+
120
+
+

References transformers.attribute_transformer.AttributeTransformer.current_class, transformers.class_analyzer.ClassAnalyzer.current_class, transformers.class_mapper.ClassMapAnalyzer.current_class, transformers.class_mapper.ClassTransformer.current_class, transformers.symbol_tree.SymbolTreeBuilder.current_class, transformers.class_analyzer.ClassAnalyzer.method_map, obfuscator.AdvancedObfuscator.name_generator, transformers.class_analyzer.ClassAnalyzer.name_generator, transformers.class_mapper.ClassMapAnalyzer.name_generator, transformers.rename.RenameTransformer.name_generator, utils.junk_gen.JunkGenerator.name_generator, and transformers.class_analyzer.ClassAnalyzer.visit_attribute_assign().

+ +
+
+

Member Data Documentation

+ +

◆ current_class

+ + + +

◆ method_map

+ + + +

◆ name_generator

+ + +
The documentation for this class was generated from the following file: +
+
+ + + + diff --git a/doxygen/classtransformers_1_1class__analyzer_1_1ClassAnalyzer.js b/doxygen/classtransformers_1_1class__analyzer_1_1ClassAnalyzer.js new file mode 100644 index 0000000..295bf7e --- /dev/null +++ b/doxygen/classtransformers_1_1class__analyzer_1_1ClassAnalyzer.js @@ -0,0 +1,13 @@ +var classtransformers_1_1class__analyzer_1_1ClassAnalyzer = +[ + [ "__init__", "classtransformers_1_1class__analyzer_1_1ClassAnalyzer.html#a4145a8d6f13f330351df501d2c2acbef", null ], + [ "_ensure_consistent_method_mapping", "classtransformers_1_1class__analyzer_1_1ClassAnalyzer.html#a525167f88e08ed9d456beb58698a5861", null ], + [ "_resolve_inheritance", "classtransformers_1_1class__analyzer_1_1ClassAnalyzer.html#a7bc086b8807e7b51c4237d0b20b35c88", null ], + [ "analyze", "classtransformers_1_1class__analyzer_1_1ClassAnalyzer.html#a8a4d1b9cb7d27cbe667e8317d482b5b6", null ], + [ "visit_Attribute", "classtransformers_1_1class__analyzer_1_1ClassAnalyzer.html#ab4fe116f7c092817a6cf585f965dd745", null ], + [ "visit_attribute_assign", "classtransformers_1_1class__analyzer_1_1ClassAnalyzer.html#a691ad5c2629a84762bf0f8ae82735021", null ], + [ "visit_ClassDef", "classtransformers_1_1class__analyzer_1_1ClassAnalyzer.html#a07cf975c27127718a00327be06695e5b", null ], + [ "current_class", "classtransformers_1_1class__analyzer_1_1ClassAnalyzer.html#a602830de65e4ef41bcb031062d9bb169", null ], + [ "method_map", "classtransformers_1_1class__analyzer_1_1ClassAnalyzer.html#a739a5193c309c36bd99184aba762a790", null ], + [ "name_generator", "classtransformers_1_1class__analyzer_1_1ClassAnalyzer.html#ae2b710d2e7aa346663d6086b95b0230d", null ] +]; \ No newline at end of file diff --git a/doxygen/classtransformers_1_1class__analyzer_1_1ClassAnalyzer__coll__graph.dot b/doxygen/classtransformers_1_1class__analyzer_1_1ClassAnalyzer__coll__graph.dot new file mode 100644 index 0000000..f22e8bf --- /dev/null +++ b/doxygen/classtransformers_1_1class__analyzer_1_1ClassAnalyzer__coll__graph.dot @@ -0,0 +1,10 @@ +digraph "transformers.class_analyzer.ClassAnalyzer" +{ + // LATEX_PDF_SIZE + bgcolor="transparent"; + edge [fontname=Helvetica,fontsize=10,labelfontname=Helvetica,labelfontsize=10]; + node [fontname=Helvetica,fontsize=10,shape=box,height=0.2,width=0.4]; + Node1 [id="Node000001",label="transformers.class\l_analyzer.ClassAnalyzer",height=0.2,width=0.4,color="gray40", fillcolor="grey60", style="filled", fontcolor="black",tooltip=" "]; + Node2 -> Node1 [id="edge1_Node000001_Node000002",dir="back",color="steelblue1",style="solid",tooltip=" "]; + Node2 [id="Node000002",label="ast::NodeVisitor",height=0.2,width=0.4,color="gray40", fillcolor="white", style="filled",tooltip=" "]; +} diff --git a/doxygen/classtransformers_1_1class__analyzer_1_1ClassAnalyzer__inherit__graph.dot b/doxygen/classtransformers_1_1class__analyzer_1_1ClassAnalyzer__inherit__graph.dot new file mode 100644 index 0000000..f22e8bf --- /dev/null +++ b/doxygen/classtransformers_1_1class__analyzer_1_1ClassAnalyzer__inherit__graph.dot @@ -0,0 +1,10 @@ +digraph "transformers.class_analyzer.ClassAnalyzer" +{ + // LATEX_PDF_SIZE + bgcolor="transparent"; + edge [fontname=Helvetica,fontsize=10,labelfontname=Helvetica,labelfontsize=10]; + node [fontname=Helvetica,fontsize=10,shape=box,height=0.2,width=0.4]; + Node1 [id="Node000001",label="transformers.class\l_analyzer.ClassAnalyzer",height=0.2,width=0.4,color="gray40", fillcolor="grey60", style="filled", fontcolor="black",tooltip=" "]; + Node2 -> Node1 [id="edge1_Node000001_Node000002",dir="back",color="steelblue1",style="solid",tooltip=" "]; + Node2 [id="Node000002",label="ast::NodeVisitor",height=0.2,width=0.4,color="gray40", fillcolor="white", style="filled",tooltip=" "]; +} diff --git a/doxygen/classtransformers_1_1class__analyzer_1_1ClassMethodMap-members.html b/doxygen/classtransformers_1_1class__analyzer_1_1ClassMethodMap-members.html new file mode 100644 index 0000000..9071399 --- /dev/null +++ b/doxygen/classtransformers_1_1class__analyzer_1_1ClassMethodMap-members.html @@ -0,0 +1,109 @@ + + + + + + + +OMG-Fuscator: Member List + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
transformers.class_analyzer.ClassMethodMap Member List
+
+
+ +

This is the complete list of members for transformers.class_analyzer.ClassMethodMap, including all inherited members.

+ + +
__init__(self)transformers.class_analyzer.ClassMethodMap
+
+ + + + diff --git a/doxygen/classtransformers_1_1class__analyzer_1_1ClassMethodMap.html b/doxygen/classtransformers_1_1class__analyzer_1_1ClassMethodMap.html new file mode 100644 index 0000000..13a0989 --- /dev/null +++ b/doxygen/classtransformers_1_1class__analyzer_1_1ClassMethodMap.html @@ -0,0 +1,159 @@ + + + + + + + +OMG-Fuscator: transformers.class_analyzer.ClassMethodMap Class Reference + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
transformers.class_analyzer.ClassMethodMap Class Reference
+
+
+ + + + +

+Public Member Functions

 __init__ (self)
 
+

Detailed Description

+
@brief Stores method and attribute mappings for all classes.
+
+

Definition at line 10 of file class_analyzer.py.

+

Constructor & Destructor Documentation

+ +

◆ __init__()

+ +
+
+ + + + + + + + +
transformers.class_analyzer.ClassMethodMap.__init__ ( self)
+
+ +

Definition at line 14 of file class_analyzer.py.

+
14 def __init__(self):
+
15 # Maps: original_class_name -> {original_method_name -> obfuscated_method_name}
+
16 self.class_methods: Dict[str, Dict[str, str]] = {}
+
17
+
18 # Maps: original_class_name -> {original_attr_name -> obfuscated_attr_name}
+
19 self.class_attributes: Dict[str, Dict[str, str]] = {}
+
20
+
21 # Maps: original_class_name -> obfuscated_class_name
+
22 self.class_renames: Dict[str, str] = {}
+
23
+
24 # Track inheritance relationships: child_class -> [parent_classes]
+
25 self.inheritance: Dict[str, List[str]] = {}
+
26
+
27
+
+

References transformers.attribute_transformer.AttributeTransformer.class_renames.

+ +
+
+
The documentation for this class was generated from the following file: +
+
+ + + + diff --git a/doxygen/classtransformers_1_1class__analyzer_1_1ClassMethodMap.js b/doxygen/classtransformers_1_1class__analyzer_1_1ClassMethodMap.js new file mode 100644 index 0000000..1ed2414 --- /dev/null +++ b/doxygen/classtransformers_1_1class__analyzer_1_1ClassMethodMap.js @@ -0,0 +1,4 @@ +var classtransformers_1_1class__analyzer_1_1ClassMethodMap = +[ + [ "__init__", "classtransformers_1_1class__analyzer_1_1ClassMethodMap.html#a26346b25523894f82d2e483b6da187fd", null ] +]; \ No newline at end of file diff --git a/doxygen/classtransformers_1_1class__mapper_1_1ClassMapAnalyzer-members.html b/doxygen/classtransformers_1_1class__mapper_1_1ClassMapAnalyzer-members.html new file mode 100644 index 0000000..1c8a5dd --- /dev/null +++ b/doxygen/classtransformers_1_1class__mapper_1_1ClassMapAnalyzer-members.html @@ -0,0 +1,121 @@ + + + + + + + +OMG-Fuscator: Member List + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ + + + + + diff --git a/doxygen/classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html b/doxygen/classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html new file mode 100644 index 0000000..be8b0aa --- /dev/null +++ b/doxygen/classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html @@ -0,0 +1,745 @@ + + + + + + + +OMG-Fuscator: transformers.class_mapper.ClassMapAnalyzer Class Reference + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
transformers.class_mapper.ClassMapAnalyzer Class Reference
+
+
+
+ + Inheritance diagram for transformers.class_mapper.ClassMapAnalyzer:
+
+
+ +
+ + Collaboration diagram for transformers.class_mapper.ClassMapAnalyzer:
+
+
+ + + + + + + + + + + + + + + + + +

+Public Member Functions

 __init__ (self, name_generator)
 
ClassMapping analyze (self, ast.AST tree)
 
 visit_Assign (self, ast.Assign node)
 
 visit_assign_in_class (self, ast.Assign node)
 
 visit_Attribute (self, ast.Attribute node)
 
 visit_ClassDef (self, ast.ClassDef node)
 
 visit_method_def (self, ast.FunctionDef node)
 
+ + + + + + + + + +

+Public Attributes

 current_class
 
 current_method
 
 mapping
 
 name_generator
 
+ + + + + +

+Protected Member Functions

 _ensure_complete_method_mapping (self)
 
 _resolve_inheritance (self)
 
+

Detailed Description

+
@brief Analyze the AST to create a complete class mapping.
+@details Performs multi-pass analysis to collect classes, methods, attributes,
+         inheritance, and method-call references and builds consistent mappings.
+
+

Definition at line 62 of file class_mapper.py.

+

Constructor & Destructor Documentation

+ +

◆ __init__()

+ +
+
+ + + + + + + + + + + + + + + + + + +
transformers.class_mapper.ClassMapAnalyzer.__init__ ( self,
 name_generator 
)
+
+ +

Definition at line 69 of file class_mapper.py.

+
69 def __init__(self, name_generator):
+
70 self.name_generator = name_generator
+
71 self.mapping = ClassMapping()
+
72 self.current_class: Optional[str] = None
+
73 self.current_method: Optional[str] = None
+
74 self.processed_classes: Set[str] = set()
+
75
+
+
+
+

Member Function Documentation

+ +

◆ _ensure_complete_method_mapping()

+ +
+
+ + + + + +
+ + + + + + + + +
transformers.class_mapper.ClassMapAnalyzer._ensure_complete_method_mapping ( self)
+
+protected
+
+
@brief Ensure all method calls have corresponding mappings.
+@details Handles methods called but not defined in the class.
+
+

Definition at line 247 of file class_mapper.py.

+
247 def _ensure_complete_method_mapping(self):
+
248 """
+
249 @brief Ensure all method calls have corresponding mappings.
+
250 @details Handles methods called but not defined in the class.
+
251 """
+
252 for class_name, method_calls in self.mapping.seen_method_calls.items():
+
253 if class_name not in self.mapping.class_methods:
+
254 continue
+
255
+
256 for method_name in method_calls:
+
257 # Skip dunder methods
+
258 if method_name.startswith('__') and method_name.endswith('__'):
+
259 continue
+
260
+
261 # Add mapping if method was called but not defined
+
262 if method_name not in self.mapping.class_methods[class_name]:
+
263 obf_name = self.name_generator.generate_name()
+
264 self.mapping.class_methods[class_name][method_name] = obf_name
+
265 logger.debug(f"Added mapping for called method {class_name}.{method_name} -> {obf_name}")
+
266
+
267
+
+

References transformers.class_mapper.ClassMapAnalyzer.mapping, transformers.class_mapper.ClassTransformer.mapping, obfuscator.AdvancedObfuscator.name_generator, transformers.class_analyzer.ClassAnalyzer.name_generator, transformers.class_mapper.ClassMapAnalyzer.name_generator, transformers.rename.RenameTransformer.name_generator, and utils.junk_gen.JunkGenerator.name_generator.

+ +

Referenced by transformers.class_mapper.ClassMapAnalyzer.analyze().

+ +
+
+ +

◆ _resolve_inheritance()

+ +
+
+ + + + + +
+ + + + + + + + +
transformers.class_mapper.ClassMapAnalyzer._resolve_inheritance ( self)
+
+protected
+
+
@brief Ensure child classes inherit method mappings from parent classes.
+@details Copies parent method mappings into children when not overridden.
+
+

Definition at line 220 of file class_mapper.py.

+
220 def _resolve_inheritance(self):
+
221 """
+
222 @brief Ensure child classes inherit method mappings from parent classes.
+
223 @details Copies parent method mappings into children when not overridden.
+
224 """
+
225 def process_inheritance(class_name):
+
226 if class_name not in self.mapping.inheritance:
+
227 return
+
228
+
229 for parent in self.mapping.inheritance[class_name]:
+
230 # Process parent's inheritance first
+
231 process_inheritance(parent)
+
232
+
233 # Skip if parent isn't in our mappings
+
234 if parent not in self.mapping.class_methods:
+
235 continue
+
236
+
237 # Copy parent's method mappings to child if not overridden
+
238 for method_name, obf_name in self.mapping.class_methods[parent].items():
+
239 if method_name not in self.mapping.class_methods[class_name]:
+
240 self.mapping.class_methods[class_name][method_name] = obf_name
+
241 logger.debug(f"Inherited method {class_name}.{method_name} from {parent}")
+
242
+
243 # Process all classes
+
244 for class_name in list(self.mapping.class_methods.keys()):
+
245 process_inheritance(class_name)
+
246
+
+

References transformers.class_mapper.ClassMapAnalyzer.mapping, and transformers.class_mapper.ClassTransformer.mapping.

+ +

Referenced by transformers.class_analyzer.ClassAnalyzer.analyze(), and transformers.class_mapper.ClassMapAnalyzer.analyze().

+ +
+
+ +

◆ analyze()

+ +
+
+ + + + + + + + + + + + + + + + + + +
ClassMapping transformers.class_mapper.ClassMapAnalyzer.analyze ( self,
ast.AST tree 
)
+
+
@brief Perform a complete analysis of the AST.
+@param tree Parsed AST to analyze.
+@return ClassMapping Aggregated mappings for class renaming and members.
+
+

Definition at line 76 of file class_mapper.py.

+
76 def analyze(self, tree: ast.AST) -> ClassMapping:
+
77 """
+
78 @brief Perform a complete analysis of the AST.
+
79 @param tree Parsed AST to analyze.
+
80 @return ClassMapping Aggregated mappings for class renaming and members.
+
81 """
+
82 # First pass: collect all class definitions, methods, and inheritance
+
83 self.visit(tree)
+
84
+
85 # Second pass: resolve inheritance and method mappings
+
86 self._resolve_inheritance()
+
87 self._ensure_complete_method_mapping()
+
88
+
89 logger.info(f"Class analysis complete: {len(self.mapping.class_names)} classes processed")
+
90 logger.debug(self.mapping.debug_info())
+
91
+
92 return self.mapping
+
93
+
+

References transformers.class_mapper.ClassMapAnalyzer._ensure_complete_method_mapping(), transformers.class_analyzer.ClassAnalyzer._resolve_inheritance(), transformers.class_mapper.ClassMapAnalyzer._resolve_inheritance(), transformers.class_mapper.ClassMapAnalyzer.mapping, and transformers.class_mapper.ClassTransformer.mapping.

+ +
+
+ +

◆ visit_Assign()

+ +
+
+ + + + + + + + + + + + + + + + + + +
transformers.class_mapper.ClassMapAnalyzer.visit_Assign ( self,
ast.Assign node 
)
+
+
@brief Process assignments that might contain self.attr references.
+@param node ast.Assign node.
+
+

Definition at line 210 of file class_mapper.py.

+
210 def visit_Assign(self, node: ast.Assign):
+
211 """
+
212 @brief Process assignments that might contain self.attr references.
+
213 @param node ast.Assign node.
+
214 """
+
215 # Visit both sides of the assignment
+
216 for target in node.targets:
+
217 self.visit(target)
+
218 self.visit(node.value)
+
219
+
+
+
+ +

◆ visit_assign_in_class()

+ +
+
+ + + + + + + + + + + + + + + + + + +
transformers.class_mapper.ClassMapAnalyzer.visit_assign_in_class ( self,
ast.Assign node 
)
+
+
@brief Process assignments in class body or methods.
+@param node ast.Assign possibly containing self.attr writes.
+
+

Definition at line 174 of file class_mapper.py.

+
174 def visit_assign_in_class(self, node: ast.Assign):
+
175 """
+
176 @brief Process assignments in class body or methods.
+
177 @param node ast.Assign possibly containing self.attr writes.
+
178 """
+
179 if not self.current_class:
+
180 return
+
181
+
182 # Check for self.attribute assignments
+
183 for target in node.targets:
+
184 if isinstance(target, ast.Attribute) and isinstance(target.value, ast.Name) and target.value.id == 'self':
+
185 attr_name = target.attr
+
186
+
187 # Map attribute name if not already mapped
+
188 if attr_name not in self.mapping.class_attributes[self.current_class]:
+
189 obf_name = self.name_generator.generate_name()
+
190 self.mapping.class_attributes[self.current_class][attr_name] = obf_name
+
191 logger.debug(f"Mapped attribute {self.current_class}.{attr_name} to {obf_name}")
+
192
+
193 # Visit the value to find nested self.method calls
+
194 self.visit(node.value)
+
195
+
+

References transformers.attribute_transformer.AttributeTransformer.current_class, transformers.class_analyzer.ClassAnalyzer.current_class, transformers.class_mapper.ClassMapAnalyzer.current_class, transformers.class_mapper.ClassTransformer.current_class, transformers.symbol_tree.SymbolTreeBuilder.current_class, transformers.class_mapper.ClassMapAnalyzer.mapping, transformers.class_mapper.ClassTransformer.mapping, obfuscator.AdvancedObfuscator.name_generator, transformers.class_analyzer.ClassAnalyzer.name_generator, transformers.class_mapper.ClassMapAnalyzer.name_generator, transformers.rename.RenameTransformer.name_generator, and utils.junk_gen.JunkGenerator.name_generator.

+ +
+
+ +

◆ visit_Attribute()

+ +
+
+ + + + + + + + + + + + + + + + + + +
transformers.class_mapper.ClassMapAnalyzer.visit_Attribute ( self,
ast.Attribute node 
)
+
+
@brief Process attribute access like self.method or self.attr.
+@param node ast.Attribute node.
+
+

Definition at line 196 of file class_mapper.py.

+
196 def visit_Attribute(self, node: ast.Attribute):
+
197 """
+
198 @brief Process attribute access like self.method or self.attr.
+
199 @param node ast.Attribute node.
+
200 """
+
201 if self.current_class and isinstance(node.value, ast.Name) and node.value.id == 'self':
+
202 # Record this access for later processing
+
203 method_name = node.attr
+
204 self.mapping.seen_method_calls[self.current_class].add(method_name)
+
205 logger.debug(f"Recorded method call: {self.current_class}.{method_name}")
+
206
+
207 # Continue traversal
+
208 self.generic_visit(node)
+
209
+
+

References transformers.attribute_transformer.AttributeTransformer.current_class, transformers.class_analyzer.ClassAnalyzer.current_class, transformers.class_mapper.ClassMapAnalyzer.current_class, transformers.class_mapper.ClassTransformer.current_class, transformers.symbol_tree.SymbolTreeBuilder.current_class, transformers.class_mapper.ClassMapAnalyzer.mapping, and transformers.class_mapper.ClassTransformer.mapping.

+ +
+
+ +

◆ visit_ClassDef()

+ +
+
+ + + + + + + + + + + + + + + + + + +
transformers.class_mapper.ClassMapAnalyzer.visit_ClassDef ( self,
ast.ClassDef node 
)
+
+
@brief Process a class definition.
+@param node ast.ClassDef node.
+
+

Definition at line 94 of file class_mapper.py.

+
94 def visit_ClassDef(self, node: ast.ClassDef):
+
95 """
+
96 @brief Process a class definition.
+
97 @param node ast.ClassDef node.
+
98 """
+
99 prev_class = self.current_class
+
100 self.current_class = node.name
+
101
+
102 # Skip if already processed
+
103 if node.name in self.processed_classes:
+
104 self.current_class = prev_class
+
105 return
+
106
+
107 # Add class name mapping
+
108 if node.name not in self.mapping.class_names:
+
109 self.mapping.class_names[node.name] = self.name_generator.generate_name()
+
110
+
111 # Initialize dictionaries
+
112 if node.name not in self.mapping.class_methods:
+
113 self.mapping.class_methods[node.name] = {}
+
114
+
115 if node.name not in self.mapping.class_attributes:
+
116 self.mapping.class_attributes[node.name] = {}
+
117
+
118 if node.name not in self.mapping.seen_method_calls:
+
119 self.mapping.seen_method_calls[node.name] = set()
+
120
+
121 # Record inheritance
+
122 parent_classes = []
+
123 for base in node.bases:
+
124 if isinstance(base, ast.Name):
+
125 parent_classes.append(base.id)
+
126
+
127 if parent_classes:
+
128 self.mapping.inheritance[node.name] = parent_classes
+
129
+
130 # Process class body
+
131 for item in node.body:
+
132 if isinstance(item, ast.FunctionDef):
+
133 self.visit_method_def(item)
+
134 elif isinstance(item, ast.Assign):
+
135 self.visit_assign_in_class(item)
+
136 elif isinstance(item, ast.Expr):
+
137 # Could contain calls to self.methods
+
138 self.visit(item)
+
139 elif isinstance(item, ast.ClassDef):
+
140 # Nested class
+
141 self.visit(item)
+
142 else:
+
143 # Other nodes that might contain self.method calls
+
144 self.visit(item)
+
145
+
146 self.processed_classes.add(node.name)
+
147 self.current_class = prev_class
+
148
+
+

References transformers.attribute_transformer.AttributeTransformer.current_class, transformers.class_analyzer.ClassAnalyzer.current_class, transformers.class_mapper.ClassMapAnalyzer.current_class, transformers.class_mapper.ClassTransformer.current_class, and transformers.symbol_tree.SymbolTreeBuilder.current_class.

+ +
+
+ +

◆ visit_method_def()

+ +
+
+ + + + + + + + + + + + + + + + + + +
transformers.class_mapper.ClassMapAnalyzer.visit_method_def ( self,
ast.FunctionDef node 
)
+
+
@brief Process a method definition in a class.
+@param node ast.FunctionDef node.
+
+

Definition at line 149 of file class_mapper.py.

+
149 def visit_method_def(self, node: ast.FunctionDef):
+
150 """
+
151 @brief Process a method definition in a class.
+
152 @param node ast.FunctionDef node.
+
153 """
+
154 if not self.current_class:
+
155 return
+
156
+
157 prev_method = self.current_method
+
158 self.current_method = node.name
+
159
+
160 # Skip dunder methods from obfuscation
+
161 if not (node.name.startswith('__') and node.name.endswith('__')):
+
162 # Map method name if not already mapped
+
163 if node.name not in self.mapping.class_methods[self.current_class]:
+
164 obf_name = self.name_generator.generate_name()
+
165 self.mapping.class_methods[self.current_class][node.name] = obf_name
+
166 logger.debug(f"Mapped method {self.current_class}.{node.name} to {obf_name}")
+
167
+
168 # Visit method body to find self.method calls and self.attr assignments
+
169 for item in node.body:
+
170 self.visit(item)
+
171
+
172 self.current_method = prev_method
+
173
+
+

References transformers.attribute_transformer.AttributeTransformer.current_class, transformers.class_analyzer.ClassAnalyzer.current_class, transformers.class_mapper.ClassMapAnalyzer.current_class, transformers.class_mapper.ClassTransformer.current_class, transformers.symbol_tree.SymbolTreeBuilder.current_class, and transformers.class_mapper.ClassMapAnalyzer.current_method.

+ +
+
+

Member Data Documentation

+ +

◆ current_class

+ + + +

◆ current_method

+ +
+
+ + + + +
transformers.class_mapper.ClassMapAnalyzer.current_method
+
+ +

Definition at line 158 of file class_mapper.py.

+ +

Referenced by transformers.class_mapper.ClassMapAnalyzer.visit_method_def().

+ +
+
+ +

◆ mapping

+ + + +

◆ name_generator

+ + +
The documentation for this class was generated from the following file: +
+
+ + + + diff --git a/doxygen/classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.js b/doxygen/classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.js new file mode 100644 index 0000000..31218cd --- /dev/null +++ b/doxygen/classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.js @@ -0,0 +1,16 @@ +var classtransformers_1_1class__mapper_1_1ClassMapAnalyzer = +[ + [ "__init__", "classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html#ad196ea0fd82543968f2514f4cebbba94", null ], + [ "_ensure_complete_method_mapping", "classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html#af584a55f0c308a55d109181485e1ae76", null ], + [ "_resolve_inheritance", "classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html#a34c03faa2fef07c3a5f0e56745b8e799", null ], + [ "analyze", "classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html#a13817b3df73643f9bb8b9601e3e040cb", null ], + [ "visit_Assign", "classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html#afdc5a0eb9fd40b5d0e9b70cea0de1f72", null ], + [ "visit_assign_in_class", "classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html#afd6498b69da44c6ec6e0b2afa725c67f", null ], + [ "visit_Attribute", "classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html#a6ba0759719762c8b373d3009b7caed98", null ], + [ "visit_ClassDef", "classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html#aeebda718232e13cd5a3e583db024da6f", null ], + [ "visit_method_def", "classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html#a6bcd45016a2ae5cb4be6a3cb942bdf9d", null ], + [ "current_class", "classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html#ac0d803c97db3802b92b824d036b14bcc", null ], + [ "current_method", "classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html#ad185e02d3dc16d55b1b6ad232203ef35", null ], + [ "mapping", "classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html#a93c02ece387c4611fa249e808f39bf10", null ], + [ "name_generator", "classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html#ad4df47c9f65fc7cc70ac7159b7116278", null ] +]; \ No newline at end of file diff --git a/doxygen/classtransformers_1_1class__mapper_1_1ClassMapAnalyzer__coll__graph.dot b/doxygen/classtransformers_1_1class__mapper_1_1ClassMapAnalyzer__coll__graph.dot new file mode 100644 index 0000000..c28a9e0 --- /dev/null +++ b/doxygen/classtransformers_1_1class__mapper_1_1ClassMapAnalyzer__coll__graph.dot @@ -0,0 +1,10 @@ +digraph "transformers.class_mapper.ClassMapAnalyzer" +{ + // LATEX_PDF_SIZE + bgcolor="transparent"; + edge [fontname=Helvetica,fontsize=10,labelfontname=Helvetica,labelfontsize=10]; + node [fontname=Helvetica,fontsize=10,shape=box,height=0.2,width=0.4]; + Node1 [id="Node000001",label="transformers.class\l_mapper.ClassMapAnalyzer",height=0.2,width=0.4,color="gray40", fillcolor="grey60", style="filled", fontcolor="black",tooltip=" "]; + Node2 -> Node1 [id="edge1_Node000001_Node000002",dir="back",color="steelblue1",style="solid",tooltip=" "]; + Node2 [id="Node000002",label="ast.NodeVisitor",height=0.2,width=0.4,color="gray40", fillcolor="white", style="filled",tooltip=" "]; +} diff --git a/doxygen/classtransformers_1_1class__mapper_1_1ClassMapAnalyzer__inherit__graph.dot b/doxygen/classtransformers_1_1class__mapper_1_1ClassMapAnalyzer__inherit__graph.dot new file mode 100644 index 0000000..c28a9e0 --- /dev/null +++ b/doxygen/classtransformers_1_1class__mapper_1_1ClassMapAnalyzer__inherit__graph.dot @@ -0,0 +1,10 @@ +digraph "transformers.class_mapper.ClassMapAnalyzer" +{ + // LATEX_PDF_SIZE + bgcolor="transparent"; + edge [fontname=Helvetica,fontsize=10,labelfontname=Helvetica,labelfontsize=10]; + node [fontname=Helvetica,fontsize=10,shape=box,height=0.2,width=0.4]; + Node1 [id="Node000001",label="transformers.class\l_mapper.ClassMapAnalyzer",height=0.2,width=0.4,color="gray40", fillcolor="grey60", style="filled", fontcolor="black",tooltip=" "]; + Node2 -> Node1 [id="edge1_Node000001_Node000002",dir="back",color="steelblue1",style="solid",tooltip=" "]; + Node2 [id="Node000002",label="ast.NodeVisitor",height=0.2,width=0.4,color="gray40", fillcolor="white", style="filled",tooltip=" "]; +} diff --git a/doxygen/classtransformers_1_1class__mapper_1_1ClassMapping-members.html b/doxygen/classtransformers_1_1class__mapper_1_1ClassMapping-members.html new file mode 100644 index 0000000..c789ad3 --- /dev/null +++ b/doxygen/classtransformers_1_1class__mapper_1_1ClassMapping-members.html @@ -0,0 +1,110 @@ + + + + + + + +OMG-Fuscator: Member List + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
transformers.class_mapper.ClassMapping Member List
+
+
+ +

This is the complete list of members for transformers.class_mapper.ClassMapping, including all inherited members.

+ + + +
__init__(self)transformers.class_mapper.ClassMapping
debug_info(self)transformers.class_mapper.ClassMapping
+
+ + + + diff --git a/doxygen/classtransformers_1_1class__mapper_1_1ClassMapping.html b/doxygen/classtransformers_1_1class__mapper_1_1ClassMapping.html new file mode 100644 index 0000000..518bb42 --- /dev/null +++ b/doxygen/classtransformers_1_1class__mapper_1_1ClassMapping.html @@ -0,0 +1,207 @@ + + + + + + + +OMG-Fuscator: transformers.class_mapper.ClassMapping Class Reference + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
transformers.class_mapper.ClassMapping Class Reference
+
+
+ + + + + + +

+Public Member Functions

 __init__ (self)
 
str debug_info (self)
 
+

Detailed Description

+
@brief Stores all mappings related to classes in a centralized way.
+@details Tracks class renames, method and attribute mappings, inheritance structure,
+         and seen method calls to ensure complete coverage.
+
+

Definition at line 16 of file class_mapper.py.

+

Constructor & Destructor Documentation

+ +

◆ __init__()

+ +
+
+ + + + + + + + +
transformers.class_mapper.ClassMapping.__init__ ( self)
+
+ +

Definition at line 23 of file class_mapper.py.

+
23 def __init__(self):
+
24 # Original class name -> obfuscated class name
+
25 self.class_names: Dict[str, str] = {}
+
26
+
27 # Original class name -> {original method name -> obfuscated method name}
+
28 self.class_methods: Dict[str, Dict[str, str]] = {}
+
29
+
30 # Original class name -> {original attr name -> obfuscated attr name}
+
31 self.class_attributes: Dict[str, Dict[str, str]] = {}
+
32
+
33 # Child class -> list of parent classes (original names)
+
34 self.inheritance: Dict[str, List[str]] = {}
+
35
+
36 # Track all seen method calls to ensure complete coverage
+
37 self.seen_method_calls: Dict[str, Set[str]] = {}
+
38
+
+
+
+

Member Function Documentation

+ +

◆ debug_info()

+ +
+
+ + + + + + + + +
str transformers.class_mapper.ClassMapping.debug_info ( self)
+
+
Return debug information about mappings.
+

Definition at line 39 of file class_mapper.py.

+
39 def debug_info(self) -> str:
+
40 """Return debug information about mappings."""
+
41 info = []
+
42 info.append(f"Class mappings: {len(self.class_names)} classes")
+
43
+
44 for cls_name, obf_name in self.class_names.items():
+
45 info.append(f" {cls_name} -> {obf_name}")
+
46
+
47 if cls_name in self.class_methods:
+
48 methods = self.class_methods[cls_name]
+
49 info.append(f" Methods: {len(methods)}")
+
50 for method, obf_method in methods.items():
+
51 info.append(f" {method} -> {obf_method}")
+
52
+
53 if cls_name in self.class_attributes:
+
54 attrs = self.class_attributes[cls_name]
+
55 info.append(f" Attributes: {len(attrs)}")
+
56 for attr, obf_attr in attrs.items():
+
57 info.append(f" {attr} -> {obf_attr}")
+
58
+
59 return "\n".join(info)
+
60
+
61
+
+
+
+
The documentation for this class was generated from the following file: +
+
+ + + + diff --git a/doxygen/classtransformers_1_1class__mapper_1_1ClassMapping.js b/doxygen/classtransformers_1_1class__mapper_1_1ClassMapping.js new file mode 100644 index 0000000..9f0ad97 --- /dev/null +++ b/doxygen/classtransformers_1_1class__mapper_1_1ClassMapping.js @@ -0,0 +1,5 @@ +var classtransformers_1_1class__mapper_1_1ClassMapping = +[ + [ "__init__", "classtransformers_1_1class__mapper_1_1ClassMapping.html#a9327faa5f8de53e9da48588245d332ba", null ], + [ "debug_info", "classtransformers_1_1class__mapper_1_1ClassMapping.html#a1fa5906a282c1ed833160badb1f674a2", null ] +]; \ No newline at end of file diff --git a/doxygen/classtransformers_1_1class__mapper_1_1ClassTransformer-members.html b/doxygen/classtransformers_1_1class__mapper_1_1ClassTransformer-members.html new file mode 100644 index 0000000..dce1bb7 --- /dev/null +++ b/doxygen/classtransformers_1_1class__mapper_1_1ClassTransformer-members.html @@ -0,0 +1,114 @@ + + + + + + + +OMG-Fuscator: Member List + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
transformers.class_mapper.ClassTransformer Member List
+
+ +
+ + + + diff --git a/doxygen/classtransformers_1_1class__mapper_1_1ClassTransformer.html b/doxygen/classtransformers_1_1class__mapper_1_1ClassTransformer.html new file mode 100644 index 0000000..b01e92c --- /dev/null +++ b/doxygen/classtransformers_1_1class__mapper_1_1ClassTransformer.html @@ -0,0 +1,392 @@ + + + + + + + +OMG-Fuscator: transformers.class_mapper.ClassTransformer Class Reference + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
transformers.class_mapper.ClassTransformer Class Reference
+
+
+
+ + Inheritance diagram for transformers.class_mapper.ClassTransformer:
+
+
+ +
+ + Collaboration diagram for transformers.class_mapper.ClassTransformer:
+
+
+ + + + + + + + + + + +

+Public Member Functions

 __init__ (self, ClassMapping mapping)
 
 visit_Attribute (self, ast.Attribute node)
 
 visit_ClassDef (self, ast.ClassDef node)
 
 visit_FunctionDef (self, ast.FunctionDef node)
 
+ + + + + +

+Public Attributes

 current_class
 
 mapping
 
+

Detailed Description

+
@brief Transform class-related nodes using the mapping.
+@details Renames class names, methods, and self.attr/self.method references
+         according to the analyzed mappings.
+
+

Definition at line 268 of file class_mapper.py.

+

Constructor & Destructor Documentation

+ +

◆ __init__()

+ +
+
+ + + + + + + + + + + + + + + + + + +
transformers.class_mapper.ClassTransformer.__init__ ( self,
ClassMapping mapping 
)
+
+ +

Definition at line 275 of file class_mapper.py.

+
275 def __init__(self, mapping: ClassMapping):
+
276 self.mapping = mapping
+
277 self.current_class: Optional[str] = None
+
278
+
+
+
+

Member Function Documentation

+ +

◆ visit_Attribute()

+ +
+
+ + + + + + + + + + + + + + + + + + +
transformers.class_mapper.ClassTransformer.visit_Attribute ( self,
ast.Attribute node 
)
+
+
@brief Transform self.method and self.attr references.
+@param node ast.Attribute node.
+@return ast.Attribute Transformed attribute node.
+
+

Definition at line 315 of file class_mapper.py.

+
315 def visit_Attribute(self, node: ast.Attribute):
+
316 """
+
317 @brief Transform self.method and self.attr references.
+
318 @param node ast.Attribute node.
+
319 @return ast.Attribute Transformed attribute node.
+
320 """
+
321 # Process any child nodes first (for nested attributes)
+
322 node.value = self.visit(node.value)
+
323
+
324 # Check if this is a self.attr or self.method reference
+
325 if self.current_class and isinstance(node.value, ast.Name) and node.value.id == 'self':
+
326 orig_name = node.attr
+
327
+
328 # Check in method mappings first
+
329 if self.current_class in self.mapping.class_methods and node.attr in self.mapping.class_methods[self.current_class]:
+
330 node.attr = self.mapping.class_methods[self.current_class][node.attr]
+
331 logger.debug(f"Transformed self.method {self.current_class}.{orig_name} -> {node.attr}")
+
332
+
333 # Then check attribute mappings
+
334 elif self.current_class in self.mapping.class_attributes and node.attr in self.mapping.class_attributes[self.current_class]:
+
335 node.attr = self.mapping.class_attributes[self.current_class][node.attr]
+
336 logger.debug(f"Transformed self.attr {self.current_class}.{orig_name} -> {node.attr}")
+
337
+
338 return node
+
339
+
340# Helper function to apply the class mapping transformation
+
+

References transformers.attribute_transformer.AttributeTransformer.current_class, transformers.class_analyzer.ClassAnalyzer.current_class, transformers.class_mapper.ClassMapAnalyzer.current_class, transformers.class_mapper.ClassTransformer.current_class, transformers.symbol_tree.SymbolTreeBuilder.current_class, transformers.class_mapper.ClassMapAnalyzer.mapping, and transformers.class_mapper.ClassTransformer.mapping.

+ +
+
+ +

◆ visit_ClassDef()

+ +
+
+ + + + + + + + + + + + + + + + + + +
transformers.class_mapper.ClassTransformer.visit_ClassDef ( self,
ast.ClassDef node 
)
+
+
@brief Transform class name and process its body.
+@param node ast.ClassDef node.
+@return ast.ClassDef Transformed class node.
+
+

Definition at line 279 of file class_mapper.py.

+
279 def visit_ClassDef(self, node: ast.ClassDef):
+
280 """
+
281 @brief Transform class name and process its body.
+
282 @param node ast.ClassDef node.
+
283 @return ast.ClassDef Transformed class node.
+
284 """
+
285 prev_class = self.current_class
+
286 orig_name = node.name
+
287 self.current_class = orig_name
+
288
+
289 # Rename class if it's in our mapping
+
290 if node.name in self.mapping.class_names:
+
291 node.name = self.mapping.class_names[node.name]
+
292 logger.debug(f"Transformed class {orig_name} -> {node.name}")
+
293
+
294 # Process class body
+
295 node.body = [self.visit(item) for item in node.body]
+
296
+
297 self.current_class = prev_class
+
298 return node
+
299
+
+

References transformers.attribute_transformer.AttributeTransformer.current_class, transformers.class_analyzer.ClassAnalyzer.current_class, transformers.class_mapper.ClassMapAnalyzer.current_class, transformers.class_mapper.ClassTransformer.current_class, and transformers.symbol_tree.SymbolTreeBuilder.current_class.

+ +
+
+ +

◆ visit_FunctionDef()

+ +
+
+ + + + + + + + + + + + + + + + + + +
transformers.class_mapper.ClassTransformer.visit_FunctionDef ( self,
ast.FunctionDef node 
)
+
+
@brief Transform method name.
+@param node ast.FunctionDef node.
+@return ast.FunctionDef Transformed method node.
+
+

Definition at line 300 of file class_mapper.py.

+
300 def visit_FunctionDef(self, node: ast.FunctionDef):
+
301 """
+
302 @brief Transform method name.
+
303 @param node ast.FunctionDef node.
+
304 @return ast.FunctionDef Transformed method node.
+
305 """
+
306 if self.current_class and node.name in self.mapping.class_methods.get(self.current_class, {}):
+
307 orig_name = node.name
+
308 node.name = self.mapping.class_methods[self.current_class][node.name]
+
309 logger.debug(f"Transformed method {self.current_class}.{orig_name} -> {node.name}")
+
310
+
311 # Visit the method body
+
312 node.body = [self.visit(item) for item in node.body]
+
313 return node
+
314
+
+

References transformers.attribute_transformer.AttributeTransformer.current_class, transformers.class_analyzer.ClassAnalyzer.current_class, transformers.class_mapper.ClassMapAnalyzer.current_class, transformers.class_mapper.ClassTransformer.current_class, transformers.symbol_tree.SymbolTreeBuilder.current_class, transformers.class_mapper.ClassMapAnalyzer.mapping, and transformers.class_mapper.ClassTransformer.mapping.

+ +
+
+

Member Data Documentation

+ +

◆ current_class

+ + + +

◆ mapping

+ + +
The documentation for this class was generated from the following file: +
+
+ + + + diff --git a/doxygen/classtransformers_1_1class__mapper_1_1ClassTransformer.js b/doxygen/classtransformers_1_1class__mapper_1_1ClassTransformer.js new file mode 100644 index 0000000..eda8947 --- /dev/null +++ b/doxygen/classtransformers_1_1class__mapper_1_1ClassTransformer.js @@ -0,0 +1,9 @@ +var classtransformers_1_1class__mapper_1_1ClassTransformer = +[ + [ "__init__", "classtransformers_1_1class__mapper_1_1ClassTransformer.html#af7356231305781d4b6287bde4fe38f9e", null ], + [ "visit_Attribute", "classtransformers_1_1class__mapper_1_1ClassTransformer.html#a18fb4582603ee59841361810858c680e", null ], + [ "visit_ClassDef", "classtransformers_1_1class__mapper_1_1ClassTransformer.html#a54db45ae6b1b4e8ffdf6c56ae4c67fd3", null ], + [ "visit_FunctionDef", "classtransformers_1_1class__mapper_1_1ClassTransformer.html#a0a61d0cd34072cb712df523d6fc504e3", null ], + [ "current_class", "classtransformers_1_1class__mapper_1_1ClassTransformer.html#a4cfb94377152b62a164976d6bd5e2fc5", null ], + [ "mapping", "classtransformers_1_1class__mapper_1_1ClassTransformer.html#a02e62f7a280ff5bfabb39f312c0f58fc", null ] +]; \ No newline at end of file diff --git a/doxygen/classtransformers_1_1class__mapper_1_1ClassTransformer__coll__graph.dot b/doxygen/classtransformers_1_1class__mapper_1_1ClassTransformer__coll__graph.dot new file mode 100644 index 0000000..5739342 --- /dev/null +++ b/doxygen/classtransformers_1_1class__mapper_1_1ClassTransformer__coll__graph.dot @@ -0,0 +1,10 @@ +digraph "transformers.class_mapper.ClassTransformer" +{ + // LATEX_PDF_SIZE + bgcolor="transparent"; + edge [fontname=Helvetica,fontsize=10,labelfontname=Helvetica,labelfontsize=10]; + node [fontname=Helvetica,fontsize=10,shape=box,height=0.2,width=0.4]; + Node1 [id="Node000001",label="transformers.class\l_mapper.ClassTransformer",height=0.2,width=0.4,color="gray40", fillcolor="grey60", style="filled", fontcolor="black",tooltip=" "]; + Node2 -> Node1 [id="edge1_Node000001_Node000002",dir="back",color="steelblue1",style="solid",tooltip=" "]; + Node2 [id="Node000002",label="ast.NodeTransformer",height=0.2,width=0.4,color="gray40", fillcolor="white", style="filled",tooltip=" "]; +} diff --git a/doxygen/classtransformers_1_1class__mapper_1_1ClassTransformer__inherit__graph.dot b/doxygen/classtransformers_1_1class__mapper_1_1ClassTransformer__inherit__graph.dot new file mode 100644 index 0000000..5739342 --- /dev/null +++ b/doxygen/classtransformers_1_1class__mapper_1_1ClassTransformer__inherit__graph.dot @@ -0,0 +1,10 @@ +digraph "transformers.class_mapper.ClassTransformer" +{ + // LATEX_PDF_SIZE + bgcolor="transparent"; + edge [fontname=Helvetica,fontsize=10,labelfontname=Helvetica,labelfontsize=10]; + node [fontname=Helvetica,fontsize=10,shape=box,height=0.2,width=0.4]; + Node1 [id="Node000001",label="transformers.class\l_mapper.ClassTransformer",height=0.2,width=0.4,color="gray40", fillcolor="grey60", style="filled", fontcolor="black",tooltip=" "]; + Node2 -> Node1 [id="edge1_Node000001_Node000002",dir="back",color="steelblue1",style="solid",tooltip=" "]; + Node2 [id="Node000002",label="ast.NodeTransformer",height=0.2,width=0.4,color="gray40", fillcolor="white", style="filled",tooltip=" "]; +} diff --git a/doxygen/classtransformers_1_1control__flow_1_1ControlFlowFlattener-members.html b/doxygen/classtransformers_1_1control__flow_1_1ControlFlowFlattener-members.html new file mode 100644 index 0000000..c7e4c99 --- /dev/null +++ b/doxygen/classtransformers_1_1control__flow_1_1ControlFlowFlattener-members.html @@ -0,0 +1,124 @@ + + + + + + + +OMG-Fuscator: Member List + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ + + + + + diff --git a/doxygen/classtransformers_1_1control__flow_1_1ControlFlowFlattener.html b/doxygen/classtransformers_1_1control__flow_1_1ControlFlowFlattener.html new file mode 100644 index 0000000..b313630 --- /dev/null +++ b/doxygen/classtransformers_1_1control__flow_1_1ControlFlowFlattener.html @@ -0,0 +1,1102 @@ + + + + + + + +OMG-Fuscator: transformers.control_flow.ControlFlowFlattener Class Reference + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
transformers.control_flow.ControlFlowFlattener Class Reference
+
+
+
+ + Inheritance diagram for transformers.control_flow.ControlFlowFlattener:
+
+
+ +
+ + Collaboration diagram for transformers.control_flow.ControlFlowFlattener:
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 __init__ (self, debug_mode=False)
 
List[ast.stmt] flatten_blocks (self)
 
List[ast.stmt] generate_junk_code (self)
 
 log_debug (self, str category, Any data)
 
ast.Assign visit_Break (self, ast.Break node)
 
ast.Assign visit_Continue (self, ast.Continue node)
 
List[ast.stmt] visit_For (self, ast.For node)
 
ast.FunctionDef visit_FunctionDef (self, ast.FunctionDef node)
 
ast.stmt visit_If (self, ast.If node)
 
List[ast.stmt] visit_Return (self, ast.Return node)
 
List[ast.stmt] visit_While (self, ast.While node)
 
+ + + + + + + + + + + +

+Public Attributes

 current_block_id
 
 debug_data
 
 debug_mode
 
 state_var_name
 
 states
 
+

Detailed Description

+
A transformer that flattens control flow by converting branching structures
+into a dispatch table with a while loop.
+
+

Definition at line 16 of file control_flow.py.

+

Constructor & Destructor Documentation

+ +

◆ __init__()

+ +
+
+ + + + + + + + + + + + + + + + + + +
transformers.control_flow.ControlFlowFlattener.__init__ ( self,
 debug_mode = False 
)
+
+ +

Definition at line 22 of file control_flow.py.

+
22 def __init__(self, debug_mode=False):
+
23 self.state_var_name = "_state"
+
24 self.states = {}
+
25 self.current_block_id = 0
+
26 self.debug_mode = debug_mode
+
27
+
28 # For tracking transformations when debug mode is enabled
+
29 if debug_mode:
+
30 self.debug_data = {
+
31 "flattened_functions": [],
+
32 "block_counts": {},
+
33 "transformations": []
+
34 }
+
35
+
+
+
+

Member Function Documentation

+ +

◆ flatten_blocks()

+ +
+
+ + + + + + + + +
List[ast.stmt] transformers.control_flow.ControlFlowFlattener.flatten_blocks ( self)
+
+
Create a flattened control flow structure using a while loop and switch-like
+dispatch based on a state variable.
+
+

Definition at line 84 of file control_flow.py.

+
84 def flatten_blocks(self) -> List[ast.stmt]:
+
85 """
+
86 Create a flattened control flow structure using a while loop and switch-like
+
87 dispatch based on a state variable.
+
88 """
+
89 # Create the state variable and initialize it
+
90 state_var = ast.Name(id=self.state_var_name, ctx=ast.Store())
+
91 init_state = ast.Assign(
+
92 targets=[state_var],
+
93 value=ast.Constant(value=0, kind=None)
+
94 )
+
95
+
96 # Create the while loop condition (state != -1)
+
97 loop_condition = ast.Compare(
+
98 left=ast.Name(id=self.state_var_name, ctx=ast.Load()),
+
99 ops=[ast.NotEq()],
+
100 comparators=[ast.Constant(value=-1, kind=None)]
+
101 )
+
102
+
103 # Create the dispatch table as a series of if/elif statements
+
104 dispatch_cases = []
+
105 for state_id, block in self.states.items():
+
106 # Create the condition (state == state_id)
+
107 condition = ast.Compare(
+
108 left=ast.Name(id=self.state_var_name, ctx=ast.Load()),
+
109 ops=[ast.Eq()],
+
110 comparators=[ast.Constant(value=state_id, kind=None)]
+
111 )
+
112
+
113 # Process the block statements
+
114 processed_block = []
+
115 for stmt in block:
+
116 processed_stmt = self.visit(stmt)
+
117 if isinstance(processed_stmt, list):
+
118 processed_block.extend(processed_stmt)
+
119 else:
+
120 processed_block.append(processed_stmt)
+
121
+
122 # If this block doesn't modify the state, add a transition to the next block
+
123 last_stmt = processed_block[-1] if processed_block else None
+
124 if not (isinstance(last_stmt, ast.Assign) and
+
125 isinstance(last_stmt.targets[0], ast.Name) and
+
126 last_stmt.targets[0].id == self.state_var_name):
+
127 # Add transition to next block
+
128 next_state = state_id + 1
+
129 if next_state not in self.states:
+
130 # If no next state, exit the loop
+
131 next_state = -1
+
132
+
133 processed_block.append(
+
134 ast.Assign(
+
135 targets=[ast.Name(id=self.state_var_name, ctx=ast.Store())],
+
136 value=ast.Constant(value=next_state, kind=None)
+
137 )
+
138 )
+
139
+
140 # Create the if/elif body
+
141 if_body = processed_block
+
142
+
143 # Add to dispatch cases
+
144 dispatch_cases.append((condition, if_body))
+
145
+
146 # Convert dispatch cases to if/elif/else structure
+
147 if_node = None
+
148 for i, (condition, body) in enumerate(reversed(dispatch_cases)):
+
149 if i == 0: # Last case (will be the 'else' clause)
+
150 if_node = ast.If(
+
151 test=condition,
+
152 body=body,
+
153 orelse=[]
+
154 )
+
155 else:
+
156 if_node = ast.If(
+
157 test=condition,
+
158 body=body,
+
159 orelse=[if_node] if if_node else []
+
160 )
+
161
+
162 # Create the while loop with the dispatch logic
+
163 while_body = [if_node] if if_node else []
+
164 while_loop = ast.While(
+
165 test=loop_condition,
+
166 body=while_body,
+
167 orelse=[]
+
168 )
+
169
+
170 # Add some junk code to obscure the control flow
+
171 junk = self.generate_junk_code()
+
172
+
173 # Assemble the flattened function body
+
174 flattened_body = [init_state] + junk + [while_loop]
+
175
+
176 return flattened_body
+
177
+
+

References transformers.control_flow.ControlFlowFlattener.generate_junk_code(), transformers.control_flow.ControlFlowFlattener.state_var_name, and transformers.control_flow.ControlFlowFlattener.states.

+ +

Referenced by transformers.control_flow.ControlFlowFlattener.visit_FunctionDef().

+ +
+
+ +

◆ generate_junk_code()

+ +
+
+ + + + + + + + +
List[ast.stmt] transformers.control_flow.ControlFlowFlattener.generate_junk_code ( self)
+
+
Generate meaningless code to obscure the control flow.
+

Definition at line 178 of file control_flow.py.

+
178 def generate_junk_code(self) -> List[ast.stmt]:
+
179 """Generate meaningless code to obscure the control flow."""
+
180 junk = []
+
181
+
182 # Add dummy variables that look like they're used for control flow
+
183 dummy_vars = [f"_cflow_{i}" for i in range(random.randint(2, 5))]
+
184 for var in dummy_vars:
+
185 # Initialize with random value
+
186 junk.append(
+
187 ast.Assign(
+
188 targets=[ast.Name(id=var, ctx=ast.Store())],
+
189 value=ast.Constant(value=random.randint(0, 100), kind=None)
+
190 )
+
191 )
+
192
+
193 # Add some conditional statements that don't do anything important
+
194 if dummy_vars:
+
195 cond = ast.Compare(
+
196 left=ast.Name(id=random.choice(dummy_vars), ctx=ast.Load()),
+
197 ops=[ast.Gt()],
+
198 comparators=[ast.Constant(value=50, kind=None)]
+
199 )
+
200
+
201 junk.append(
+
202 ast.If(
+
203 test=cond,
+
204 body=[
+
205 ast.Assign(
+
206 targets=[ast.Name(id=random.choice(dummy_vars), ctx=ast.Store())],
+
207 value=ast.Constant(value=random.randint(0, 100), kind=None)
+
208 )
+
209 ],
+
210 orelse=[]
+
211 )
+
212 )
+
213
+
214 if self.debug_mode:
+
215 self.log_debug("junk_code", {
+
216 "statements": len(junk),
+
217 "variables": dummy_vars
+
218 })
+
219
+
220 return junk
+
221
+
+

References obfuscator.AdvancedObfuscator.debug_mode, transformers.control_flow.ControlFlowFlattener.debug_mode, transformers.rename.RenameTransformer.debug_mode, obfuscator.AdvancedObfuscator.log_debug(), transformers.control_flow.ControlFlowFlattener.log_debug(), and transformers.rename.RenameTransformer.log_debug().

+ +

Referenced by transformers.control_flow.ControlFlowFlattener.flatten_blocks().

+ +
+
+ +

◆ log_debug()

+ + + +

◆ visit_Break()

+ +
+
+ + + + + + + + + + + + + + + + + + +
ast.Assign transformers.control_flow.ControlFlowFlattener.visit_Break ( self,
ast.Break node 
)
+
+
Transform break statements into a state change to exit the current loop.
+In a flattened control flow, this means finding the next state after the loop.
+
+For simplicity, we'll just set to -1 (terminate), but a more sophisticated
+approach would track enclosing loops and their exit states.
+
+

Definition at line 424 of file control_flow.py.

+
424 def visit_Break(self, node: ast.Break) -> ast.Assign:
+
425 """
+
426 Transform break statements into a state change to exit the current loop.
+
427 In a flattened control flow, this means finding the next state after the loop.
+
428
+
429 For simplicity, we'll just set to -1 (terminate), but a more sophisticated
+
430 approach would track enclosing loops and their exit states.
+
431 """
+
432 if self.debug_mode:
+
433 self.log_debug("break_transformation", {
+
434 "exit_state": -1
+
435 })
+
436
+
437 return ast.Assign(
+
438 targets=[ast.Name(id=self.state_var_name, ctx=ast.Store())],
+
439 value=ast.Constant(value=-1, kind=None)
+
440 )
+
441
+
+

References obfuscator.AdvancedObfuscator.debug_mode, transformers.control_flow.ControlFlowFlattener.debug_mode, transformers.rename.RenameTransformer.debug_mode, obfuscator.AdvancedObfuscator.log_debug(), transformers.control_flow.ControlFlowFlattener.log_debug(), transformers.rename.RenameTransformer.log_debug(), and transformers.control_flow.ControlFlowFlattener.state_var_name.

+ +
+
+ +

◆ visit_Continue()

+ +
+
+ + + + + + + + + + + + + + + + + + +
ast.Assign transformers.control_flow.ControlFlowFlattener.visit_Continue ( self,
ast.Continue node 
)
+
+
Transform continue statements to go back to the loop condition.
+In a flattened control flow, we need to know the loop condition state.
+
+For simplicity, we'll implement a jump to the current state, effectively
+rerunning the current block, but a more sophisticated approach would track
+enclosing loops and their condition states.
+
+

Definition at line 442 of file control_flow.py.

+
442 def visit_Continue(self, node: ast.Continue) -> ast.Assign:
+
443 """
+
444 Transform continue statements to go back to the loop condition.
+
445 In a flattened control flow, we need to know the loop condition state.
+
446
+
447 For simplicity, we'll implement a jump to the current state, effectively
+
448 rerunning the current block, but a more sophisticated approach would track
+
449 enclosing loops and their condition states.
+
450 """
+
451 if self.debug_mode:
+
452 self.log_debug("continue_transformation", {
+
453 "target_state": "current loop condition (simplified)"
+
454 })
+
455
+
456 # In this simplified model, we just loop back to the current state
+
457 # A more complete implementation would track the loop stack and jump to the loop start
+
458 return ast.Assign(
+
459 targets=[ast.Name(id=self.state_var_name, ctx=ast.Store())],
+
460 value=ast.Constant(value=0, kind=None)
+
461 )
+
462
+
+

References obfuscator.AdvancedObfuscator.debug_mode, transformers.control_flow.ControlFlowFlattener.debug_mode, transformers.rename.RenameTransformer.debug_mode, obfuscator.AdvancedObfuscator.log_debug(), transformers.control_flow.ControlFlowFlattener.log_debug(), transformers.rename.RenameTransformer.log_debug(), and transformers.control_flow.ControlFlowFlattener.state_var_name.

+ +
+
+ +

◆ visit_For()

+ +
+
+ + + + + + + + + + + + + + + + + + +
List[ast.stmt] transformers.control_flow.ControlFlowFlattener.visit_For ( self,
ast.For node 
)
+
+
Transform for loops into state transitions with loop body and else clause
+as separate states.
+
+

Definition at line 259 of file control_flow.py.

+
259 def visit_For(self, node: ast.For) -> List[ast.stmt]:
+
260 """
+
261 Transform for loops into state transitions with loop body and else clause
+
262 as separate states.
+
263 """
+
264 # Create unique variable names for this loop
+
265 iter_var = f"_iter_{self.current_block_id}"
+
266 index_var = f"_idx_{self.current_block_id}"
+
267
+
268 # Setup the iteration
+
269 setup_stmts = [
+
270 # Create iterator: _iter_X = iter(iterable)
+
271 ast.Assign(
+
272 targets=[ast.Name(id=iter_var, ctx=ast.Store())],
+
273 value=ast.Call(
+
274 func=ast.Name(id="iter", ctx=ast.Load()),
+
275 args=[self.visit(node.iter)],
+
276 keywords=[]
+
277 )
+
278 ),
+
279 # Initialize index: _idx_X = 0
+
280 ast.Assign(
+
281 targets=[ast.Name(id=index_var, ctx=ast.Store())],
+
282 value=ast.Constant(value=0, kind=None)
+
283 )
+
284 ]
+
285
+
286 # Create states for the loop body and else clause
+
287 loop_body_id = self.current_block_id
+
288 self.current_block_id += 1
+
289
+
290 # Loop body needs to get the next item and assign it to the target
+
291 loop_body = [
+
292 # try: target = next(_iter_X)
+
293 ast.Try(
+
294 body=[
+
295 ast.Assign(
+
296 targets=[self.visit(node.target)],
+
297 value=ast.Call(
+
298 func=ast.Name(id="next", ctx=ast.Load()),
+
299 args=[ast.Name(id=iter_var, ctx=ast.Load())],
+
300 keywords=[]
+
301 )
+
302 )
+
303 ],
+
304 # except StopIteration: goto else_clause or skip if no else
+
305 handlers=[
+
306 ast.ExceptHandler(
+
307 type=ast.Name(id="StopIteration", ctx=ast.Load()),
+
308 name=None,
+
309 body=[
+
310 ast.Assign(
+
311 targets=[ast.Name(id=self.state_var_name, ctx=ast.Store())],
+
312 value=ast.Constant(
+
313 value=(self.current_block_id if node.orelse else -1),
+
314 kind=None
+
315 )
+
316 )
+
317 ]
+
318 )
+
319 ],
+
320 # no finally
+
321 orelse=[],
+
322 finalbody=[]
+
323 )
+
324 ] + node.body + [
+
325 # Increment index
+
326 ast.AugAssign(
+
327 target=ast.Name(id=index_var, ctx=ast.Store()),
+
328 op=ast.Add(),
+
329 value=ast.Constant(value=1, kind=None)
+
330 ),
+
331 # Loop back to body
+
332 ast.Assign(
+
333 targets=[ast.Name(id=self.state_var_name, ctx=ast.Store())],
+
334 value=ast.Constant(value=loop_body_id, kind=None)
+
335 )
+
336 ]
+
337
+
338 self.states[loop_body_id] = loop_body
+
339
+
340 # Handle else clause if present
+
341 if node.orelse:
+
342 else_id = self.current_block_id
+
343 self.current_block_id += 1
+
344 self.states[else_id] = node.orelse
+
345
+
346 if self.debug_mode:
+
347 self.log_debug("for_loop_transformation", {
+
348 "iterator_var": iter_var,
+
349 "index_var": index_var,
+
350 "body_block": loop_body_id,
+
351 "has_else": bool(node.orelse),
+
352 "else_block": else_id if node.orelse else None
+
353 })
+
354
+
355 # Transition to the loop body after setup
+
356 setup_stmts.append(
+
357 ast.Assign(
+
358 targets=[ast.Name(id=self.state_var_name, ctx=ast.Store())],
+
359 value=ast.Constant(value=loop_body_id, kind=None)
+
360 )
+
361 )
+
362
+
363 return setup_stmts
+
364
+
+

References transformers.control_flow.ControlFlowFlattener.current_block_id, obfuscator.AdvancedObfuscator.debug_mode, transformers.control_flow.ControlFlowFlattener.debug_mode, transformers.rename.RenameTransformer.debug_mode, obfuscator.AdvancedObfuscator.log_debug(), transformers.control_flow.ControlFlowFlattener.log_debug(), transformers.rename.RenameTransformer.log_debug(), transformers.control_flow.ControlFlowFlattener.state_var_name, and transformers.control_flow.ControlFlowFlattener.states.

+ +
+
+ +

◆ visit_FunctionDef()

+ +
+
+ + + + + + + + + + + + + + + + + + +
ast.FunctionDef transformers.control_flow.ControlFlowFlattener.visit_FunctionDef ( self,
ast.FunctionDef node 
)
+
+
Transform a function body into a flattened control flow.
+
+Keeps function signature the same but replaces the body with
+state-machine style execution.
+
+

Definition at line 44 of file control_flow.py.

+
44 def visit_FunctionDef(self, node: ast.FunctionDef) -> ast.FunctionDef:
+
45 """
+
46 Transform a function body into a flattened control flow.
+
47
+
48 Keeps function signature the same but replaces the body with
+
49 state-machine style execution.
+
50 """
+
51 # Skip small functions as flattening them might cause more overhead than obfuscation
+
52 if len(node.body) <= 2:
+
53 return self.generic_visit(node)
+
54
+
55 # Reset state for this function
+
56 self.states = {}
+
57 self.current_block_id = 0
+
58
+
59 # Process decorators and args normally
+
60 node.decorator_list = [self.visit(d) for d in node.decorator_list]
+
61 if hasattr(node, 'args'):
+
62 node.args = self.visit(node.args)
+
63
+
64 # Create entry block (state 0)
+
65 entry_block_id = self.current_block_id
+
66 self.current_block_id += 1
+
67 self.states[entry_block_id] = node.body
+
68
+
69 # Create the flattened control flow
+
70 flattened_body = self.flatten_blocks()
+
71 node.body = flattened_body
+
72
+
73 if self.debug_mode:
+
74 self.debug_data["flattened_functions"].append(node.name)
+
75 self.debug_data["block_counts"][node.name] = len(self.states)
+
76 self.log_debug("function_flattened", {
+
77 "name": node.name,
+
78 "original_statements": len(self.states[entry_block_id]),
+
79 "flattened_blocks": len(self.states)
+
80 })
+
81
+
82 return node
+
83
+
+

References transformers.control_flow.ControlFlowFlattener.current_block_id, obfuscator.AdvancedObfuscator.debug_data, transformers.control_flow.ControlFlowFlattener.debug_data, transformers.rename.RenameTransformer.debug_data, obfuscator.AdvancedObfuscator.debug_mode, transformers.control_flow.ControlFlowFlattener.debug_mode, transformers.rename.RenameTransformer.debug_mode, transformers.control_flow.ControlFlowFlattener.flatten_blocks(), obfuscator.AdvancedObfuscator.log_debug(), transformers.control_flow.ControlFlowFlattener.log_debug(), transformers.rename.RenameTransformer.log_debug(), and transformers.control_flow.ControlFlowFlattener.states.

+ +
+
+ +

◆ visit_If()

+ +
+
+ + + + + + + + + + + + + + + + + + +
ast.stmt transformers.control_flow.ControlFlowFlattener.visit_If ( self,
ast.If node 
)
+
+
Transform if statements into state transitions.
+Conditional branches become separate states in the state machine.
+
+

Definition at line 222 of file control_flow.py.

+
222 def visit_If(self, node: ast.If) -> ast.stmt:
+
223 """
+
224 Transform if statements into state transitions.
+
225 Conditional branches become separate states in the state machine.
+
226 """
+
227 # Create new states for the true and false branches
+
228 true_branch_id = self.current_block_id
+
229 self.current_block_id += 1
+
230 self.states[true_branch_id] = node.body
+
231
+
232 if node.orelse:
+
233 false_branch_id = self.current_block_id
+
234 self.current_block_id += 1
+
235 self.states[false_branch_id] = node.orelse
+
236 else:
+
237 # If no else branch, use the next block in sequence
+
238 false_branch_id = self.current_block_id
+
239
+
240 # Create a conditional assignment to the state variable
+
241 result = ast.Assign(
+
242 targets=[ast.Name(id=self.state_var_name, ctx=ast.Store())],
+
243 value=ast.IfExp(
+
244 test=self.visit(node.test),
+
245 body=ast.Constant(value=true_branch_id, kind=None),
+
246 orelse=ast.Constant(value=false_branch_id, kind=None)
+
247 )
+
248 )
+
249
+
250 if self.debug_mode:
+
251 self.log_debug("if_transformation", {
+
252 "true_branch": true_branch_id,
+
253 "false_branch": false_branch_id,
+
254 "has_else": bool(node.orelse)
+
255 })
+
256
+
257 return result
+
258
+
+

References transformers.control_flow.ControlFlowFlattener.current_block_id, obfuscator.AdvancedObfuscator.debug_mode, transformers.control_flow.ControlFlowFlattener.debug_mode, transformers.rename.RenameTransformer.debug_mode, obfuscator.AdvancedObfuscator.log_debug(), transformers.control_flow.ControlFlowFlattener.log_debug(), transformers.rename.RenameTransformer.log_debug(), transformers.control_flow.ControlFlowFlattener.state_var_name, and transformers.control_flow.ControlFlowFlattener.states.

+ +
+
+ +

◆ visit_Return()

+ +
+
+ + + + + + + + + + + + + + + + + + +
List[ast.stmt] transformers.control_flow.ControlFlowFlattener.visit_Return ( self,
ast.Return node 
)
+
+
Transform return statements into state transitions that terminate the function.
+
+

Definition at line 463 of file control_flow.py.

+
463 def visit_Return(self, node: ast.Return) -> List[ast.stmt]:
+
464 """
+
465 Transform return statements into state transitions that terminate the function.
+
466 """
+
467 # Evaluate return value if present, then exit the state machine
+
468 if node.value:
+
469 return_stmt = ast.Return(value=self.visit(node.value))
+
470 exit_stmt = ast.Assign(
+
471 targets=[ast.Name(id=self.state_var_name, ctx=ast.Store())],
+
472 value=ast.Constant(value=-1, kind=None)
+
473 )
+
474
+
475 if self.debug_mode:
+
476 self.log_debug("return_transformation", {
+
477 "has_value": True
+
478 })
+
479
+
480 return [return_stmt, exit_stmt]
+
481 else:
+
482 # No return value
+
483 if self.debug_mode:
+
484 self.log_debug("return_transformation", {
+
485 "has_value": False
+
486 })
+
487
+
488 return [
+
489 ast.Return(value=None),
+
490 ast.Assign(
+
491 targets=[ast.Name(id=self.state_var_name, ctx=ast.Store())],
+
492 value=ast.Constant(value=-1, kind=None)
+
493 )
+
494 ]
+
+

References obfuscator.AdvancedObfuscator.debug_mode, transformers.control_flow.ControlFlowFlattener.debug_mode, transformers.rename.RenameTransformer.debug_mode, obfuscator.AdvancedObfuscator.log_debug(), transformers.control_flow.ControlFlowFlattener.log_debug(), transformers.rename.RenameTransformer.log_debug(), and transformers.control_flow.ControlFlowFlattener.state_var_name.

+ +
+
+ +

◆ visit_While()

+ +
+
+ + + + + + + + + + + + + + + + + + +
List[ast.stmt] transformers.control_flow.ControlFlowFlattener.visit_While ( self,
ast.While node 
)
+
+
Transform while loops into state transitions with conditional jumps.
+
+

Definition at line 365 of file control_flow.py.

+
365 def visit_While(self, node: ast.While) -> List[ast.stmt]:
+
366 """
+
367 Transform while loops into state transitions with conditional jumps.
+
368 """
+
369 # Create states for the condition check, body, and else clause
+
370 cond_check_id = self.current_block_id
+
371 self.current_block_id += 1
+
372
+
373 # Body state ID
+
374 body_id = self.current_block_id
+
375 self.current_block_id += 1
+
376
+
377 # Else state ID (if present)
+
378 else_id = self.current_block_id if node.orelse else -1
+
379 if node.orelse:
+
380 self.current_block_id += 1
+
381
+
382 # Condition check state: if test: goto body else: goto else/exit
+
383 cond_check = [
+
384 ast.Assign(
+
385 targets=[ast.Name(id=self.state_var_name, ctx=ast.Store())],
+
386 value=ast.IfExp(
+
387 test=self.visit(node.test),
+
388 body=ast.Constant(value=body_id, kind=None),
+
389 orelse=ast.Constant(value=else_id, kind=None)
+
390 )
+
391 )
+
392 ]
+
393 self.states[cond_check_id] = cond_check
+
394
+
395 # Body state: execute body then goto condition check
+
396 body = list(node.body) + [
+
397 ast.Assign(
+
398 targets=[ast.Name(id=self.state_var_name, ctx=ast.Store())],
+
399 value=ast.Constant(value=cond_check_id, kind=None)
+
400 )
+
401 ]
+
402 self.states[body_id] = body
+
403
+
404 # Else state (if present)
+
405 if node.orelse:
+
406 self.states[else_id] = node.orelse
+
407
+
408 if self.debug_mode:
+
409 self.log_debug("while_loop_transformation", {
+
410 "condition_check_block": cond_check_id,
+
411 "body_block": body_id,
+
412 "has_else": bool(node.orelse),
+
413 "else_block": else_id if else_id != -1 else None
+
414 })
+
415
+
416 # Initial transition to the condition check
+
417 return [
+
418 ast.Assign(
+
419 targets=[ast.Name(id=self.state_var_name, ctx=ast.Store())],
+
420 value=ast.Constant(value=cond_check_id, kind=None)
+
421 )
+
422 ]
+
423
+
+

References transformers.control_flow.ControlFlowFlattener.current_block_id, obfuscator.AdvancedObfuscator.debug_mode, transformers.control_flow.ControlFlowFlattener.debug_mode, transformers.rename.RenameTransformer.debug_mode, obfuscator.AdvancedObfuscator.log_debug(), transformers.control_flow.ControlFlowFlattener.log_debug(), transformers.rename.RenameTransformer.log_debug(), transformers.control_flow.ControlFlowFlattener.state_var_name, and transformers.control_flow.ControlFlowFlattener.states.

+ +
+
+

Member Data Documentation

+ +

◆ current_block_id

+ + + +

◆ debug_data

+ + + +

◆ debug_mode

+ + + +

◆ state_var_name

+ + + +

◆ states

+ + +
The documentation for this class was generated from the following file: +
+
+ + + + diff --git a/doxygen/classtransformers_1_1control__flow_1_1ControlFlowFlattener.js b/doxygen/classtransformers_1_1control__flow_1_1ControlFlowFlattener.js new file mode 100644 index 0000000..1a6e02d --- /dev/null +++ b/doxygen/classtransformers_1_1control__flow_1_1ControlFlowFlattener.js @@ -0,0 +1,19 @@ +var classtransformers_1_1control__flow_1_1ControlFlowFlattener = +[ + [ "__init__", "classtransformers_1_1control__flow_1_1ControlFlowFlattener.html#a08a538261912ba3c8ec059dd8f528732", null ], + [ "flatten_blocks", "classtransformers_1_1control__flow_1_1ControlFlowFlattener.html#af8cf7ecbaf8d1fdc4127dfecca51c022", null ], + [ "generate_junk_code", "classtransformers_1_1control__flow_1_1ControlFlowFlattener.html#a4c787cc400a0a7ab154c09388e016946", null ], + [ "log_debug", "classtransformers_1_1control__flow_1_1ControlFlowFlattener.html#a53e89d0d92bb71c22e2721272c27c35c", null ], + [ "visit_Break", "classtransformers_1_1control__flow_1_1ControlFlowFlattener.html#a0af6bdcc5f0423e92bbaff8f11134ee9", null ], + [ "visit_Continue", "classtransformers_1_1control__flow_1_1ControlFlowFlattener.html#a3f96cc0e595090bd445525dacc81a52e", null ], + [ "visit_For", "classtransformers_1_1control__flow_1_1ControlFlowFlattener.html#a336fefe281452a4cefb0017de41f6cb5", null ], + [ "visit_FunctionDef", "classtransformers_1_1control__flow_1_1ControlFlowFlattener.html#a708096f6acd688fa597f7695d9eea010", null ], + [ "visit_If", "classtransformers_1_1control__flow_1_1ControlFlowFlattener.html#ac394afa0ffcadb438bf3419375480ba8", null ], + [ "visit_Return", "classtransformers_1_1control__flow_1_1ControlFlowFlattener.html#ae1e8400d54ec1b75fdc514cd1609120f", null ], + [ "visit_While", "classtransformers_1_1control__flow_1_1ControlFlowFlattener.html#aed99b58ddd8e19899955f356323d7a71", null ], + [ "current_block_id", "classtransformers_1_1control__flow_1_1ControlFlowFlattener.html#a703ccda2bc9fbe6c10ca4070a0e6940d", null ], + [ "debug_data", "classtransformers_1_1control__flow_1_1ControlFlowFlattener.html#a451d4b05a74909802cbde2220cf9a013", null ], + [ "debug_mode", "classtransformers_1_1control__flow_1_1ControlFlowFlattener.html#a8113e193915bc1952bc25d039693e38a", null ], + [ "state_var_name", "classtransformers_1_1control__flow_1_1ControlFlowFlattener.html#aee799638015280dec91b61e46efc6a95", null ], + [ "states", "classtransformers_1_1control__flow_1_1ControlFlowFlattener.html#a58c53389a3591f693045f05e6aff79ab", null ] +]; \ No newline at end of file diff --git a/doxygen/classtransformers_1_1control__flow_1_1ControlFlowFlattener__coll__graph.dot b/doxygen/classtransformers_1_1control__flow_1_1ControlFlowFlattener__coll__graph.dot new file mode 100644 index 0000000..f8805ee --- /dev/null +++ b/doxygen/classtransformers_1_1control__flow_1_1ControlFlowFlattener__coll__graph.dot @@ -0,0 +1,10 @@ +digraph "transformers.control_flow.ControlFlowFlattener" +{ + // LATEX_PDF_SIZE + bgcolor="transparent"; + edge [fontname=Helvetica,fontsize=10,labelfontname=Helvetica,labelfontsize=10]; + node [fontname=Helvetica,fontsize=10,shape=box,height=0.2,width=0.4]; + Node1 [id="Node000001",label="transformers.control\l_flow.ControlFlowFlattener",height=0.2,width=0.4,color="gray40", fillcolor="grey60", style="filled", fontcolor="black",tooltip=" "]; + Node2 -> Node1 [id="edge1_Node000001_Node000002",dir="back",color="steelblue1",style="solid",tooltip=" "]; + Node2 [id="Node000002",label="ast.NodeTransformer",height=0.2,width=0.4,color="gray40", fillcolor="white", style="filled",tooltip=" "]; +} diff --git a/doxygen/classtransformers_1_1control__flow_1_1ControlFlowFlattener__inherit__graph.dot b/doxygen/classtransformers_1_1control__flow_1_1ControlFlowFlattener__inherit__graph.dot new file mode 100644 index 0000000..f8805ee --- /dev/null +++ b/doxygen/classtransformers_1_1control__flow_1_1ControlFlowFlattener__inherit__graph.dot @@ -0,0 +1,10 @@ +digraph "transformers.control_flow.ControlFlowFlattener" +{ + // LATEX_PDF_SIZE + bgcolor="transparent"; + edge [fontname=Helvetica,fontsize=10,labelfontname=Helvetica,labelfontsize=10]; + node [fontname=Helvetica,fontsize=10,shape=box,height=0.2,width=0.4]; + Node1 [id="Node000001",label="transformers.control\l_flow.ControlFlowFlattener",height=0.2,width=0.4,color="gray40", fillcolor="grey60", style="filled", fontcolor="black",tooltip=" "]; + Node2 -> Node1 [id="edge1_Node000001_Node000002",dir="back",color="steelblue1",style="solid",tooltip=" "]; + Node2 [id="Node000002",label="ast.NodeTransformer",height=0.2,width=0.4,color="gray40", fillcolor="white", style="filled",tooltip=" "]; +} diff --git a/doxygen/classtransformers_1_1rename_1_1RenameTransformer-members.html b/doxygen/classtransformers_1_1rename_1_1RenameTransformer-members.html new file mode 100644 index 0000000..62c0518 --- /dev/null +++ b/doxygen/classtransformers_1_1rename_1_1RenameTransformer-members.html @@ -0,0 +1,141 @@ + + + + + + + +OMG-Fuscator: Member List + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
transformers.rename.RenameTransformer Member List
+
+
+ +

This is the complete list of members for transformers.rename.RenameTransformer, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
__init__(self, name_generator, global_var_renames, class_attr_mapping, primary_key, secondary_key, salt, debug_mode=False)transformers.rename.RenameTransformer
_pop_scope(self)transformers.rename.RenameTransformerprotected
_push_scope(self)transformers.rename.RenameTransformerprotected
class_attr_mappingtransformers.rename.RenameTransformer
class_method_mappingtransformers.rename.RenameTransformer
current_class_nametransformers.rename.RenameTransformer
debug_datatransformers.rename.RenameTransformer
debug_modetransformers.rename.RenameTransformer
encryptortransformers.rename.RenameTransformer
first_passtransformers.rename.RenameTransformer
global_var_renamestransformers.rename.RenameTransformer
in_classtransformers.rename.RenameTransformer
key_setup_codetransformers.rename.RenameTransformer
log_debug(self, str category, any data)transformers.rename.RenameTransformer
name_generatortransformers.rename.RenameTransformer
scan_class_methods(self, node)transformers.rename.RenameTransformer
scope_stacktransformers.rename.RenameTransformer
visit_Attribute(self, ast.Attribute node)transformers.rename.RenameTransformer
visit_Call(self, ast.Call node)transformers.rename.RenameTransformer
visit_ClassDef(self, ast.ClassDef node)transformers.rename.RenameTransformer
visit_comprehension(self, ast.comprehension node)transformers.rename.RenameTransformer
visit_Constant(self, ast.Constant node)transformers.rename.RenameTransformer
visit_DictComp(self, ast.DictComp node)transformers.rename.RenameTransformer
visit_FunctionDef(self, ast.FunctionDef node)transformers.rename.RenameTransformer
visit_GeneratorExp(self, ast.GeneratorExp node)transformers.rename.RenameTransformer
visit_Global(self, ast.Global node)transformers.rename.RenameTransformer
visit_Import(self, ast.Import node)transformers.rename.RenameTransformer
visit_ImportFrom(self, ast.ImportFrom node)transformers.rename.RenameTransformer
visit_ListComp(self, ast.ListComp node)transformers.rename.RenameTransformer
visit_Module(self, ast.Module node)transformers.rename.RenameTransformer
visit_Name(self, ast.Name node)transformers.rename.RenameTransformer
visit_SetComp(self, ast.SetComp node)transformers.rename.RenameTransformer
visit_Subscript(self, ast.Subscript node)transformers.rename.RenameTransformer
+
+ + + + diff --git a/doxygen/classtransformers_1_1rename_1_1RenameTransformer.html b/doxygen/classtransformers_1_1rename_1_1RenameTransformer.html new file mode 100644 index 0000000..9d07998 --- /dev/null +++ b/doxygen/classtransformers_1_1rename_1_1RenameTransformer.html @@ -0,0 +1,1570 @@ + + + + + + + +OMG-Fuscator: transformers.rename.RenameTransformer Class Reference + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
transformers.rename.RenameTransformer Class Reference
+
+
+
+ + Inheritance diagram for transformers.rename.RenameTransformer:
+
+
+ +
+ + Collaboration diagram for transformers.rename.RenameTransformer:
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 __init__ (self, name_generator, global_var_renames, class_attr_mapping, primary_key, secondary_key, salt, debug_mode=False)
 
 log_debug (self, str category, any data)
 
 scan_class_methods (self, node)
 
ast.AST visit_Attribute (self, ast.Attribute node)
 
ast.Call visit_Call (self, ast.Call node)
 
ast.ClassDef visit_ClassDef (self, ast.ClassDef node)
 
ast.comprehension visit_comprehension (self, ast.comprehension node)
 
ast.AST visit_Constant (self, ast.Constant node)
 
ast.DictComp visit_DictComp (self, ast.DictComp node)
 
ast.FunctionDef visit_FunctionDef (self, ast.FunctionDef node)
 
ast.GeneratorExp visit_GeneratorExp (self, ast.GeneratorExp node)
 
ast.Global visit_Global (self, ast.Global node)
 
ast.AST visit_Import (self, ast.Import node)
 
ast.AST visit_ImportFrom (self, ast.ImportFrom node)
 
ast.ListComp visit_ListComp (self, ast.ListComp node)
 
ast.Module visit_Module (self, ast.Module node)
 
ast.AST visit_Name (self, ast.Name node)
 
ast.SetComp visit_SetComp (self, ast.SetComp node)
 
ast.AST visit_Subscript (self, ast.Subscript node)
 
+ + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Attributes

 class_attr_mapping
 
 class_method_mapping
 
 current_class_name
 
 debug_data
 
 debug_mode
 
 encryptor
 
 first_pass
 
 global_var_renames
 
 in_class
 
 key_setup_code
 
 name_generator
 
 scope_stack
 
+ + + + + +

+Protected Member Functions

 _pop_scope (self)
 
 _push_scope (self)
 
+

Detailed Description

+
@brief AST transformer for renaming and string encryption.
+@details Maintains scope stacks, global mappings, class method/attribute maps, and
+         collects key-setup code for runtime decryption. Can emit debug telemetry.
+
+

Definition at line 17 of file rename.py.

+

Constructor & Destructor Documentation

+ +

◆ __init__()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
transformers.rename.RenameTransformer.__init__ ( self,
 name_generator,
 global_var_renames,
 class_attr_mapping,
 primary_key,
 secondary_key,
 salt,
 debug_mode = False 
)
+
+ +

Definition at line 23 of file rename.py.

+
24 primary_key, secondary_key, salt, debug_mode=False):
+
25 self.name_generator = name_generator
+
26 self.global_var_renames = global_var_renames
+
27 self.class_attr_mapping = class_attr_mapping
+
28
+
29 # String encryption
+
30 self.encryptor = StringEncryptor(primary_key, secondary_key, salt)
+
31
+
32 # We'll collect any code needed for key setup (from encrypt_string calls).
+
33 self.key_setup_code = []
+
34
+
35 # Each element is a dict that maps old_name -> new_name for the local scope
+
36 self.scope_stack = [{}]
+
37
+
38 # For class/attribute rename support
+
39 self.in_class = False
+
40 self.current_class_name = None
+
41 # Add this to track methods in each class
+
42 self.class_method_mapping = {}
+
43 # Add a first-pass flag to help with method detection
+
44 self.first_pass = True
+
45
+
46 # Debug data if debug mode is enabled
+
47 self.debug_mode = debug_mode
+
48 if self.debug_mode:
+
49 self.debug_data = {
+
50 "variable_mappings": {},
+
51 "string_encryption": [],
+
52 "renamed_nodes": 0,
+
53 "issues": []
+
54 }
+
55
+
+
+
+

Member Function Documentation

+ +

◆ _pop_scope()

+ +
+
+ + + + + +
+ + + + + + + + +
transformers.rename.RenameTransformer._pop_scope ( self)
+
+protected
+
+
+ +

◆ _push_scope()

+ +
+
+ + + + + +
+ + + + + + + + +
transformers.rename.RenameTransformer._push_scope ( self)
+
+protected
+
+
+ +

◆ log_debug()

+ + + +

◆ scan_class_methods()

+ +
+
+ + + + + + + + + + + + + + + + + + +
transformers.rename.RenameTransformer.scan_class_methods ( self,
 node 
)
+
+
Pre-scan a class to identify and map all its methods before actual renaming.
+
+

Definition at line 125 of file rename.py.

+
125 def scan_class_methods(self, node):
+
126 """
+
127 Pre-scan a class to identify and map all its methods before actual renaming.
+
128 """
+
129 class_name = node.name
+
130 # Create a mapping entry for this class if not exists
+
131 if class_name not in self.class_method_mapping:
+
132 self.class_method_mapping[class_name] = {}
+
133
+
134 # Scan all method definitions in the class
+
135 for item in node.body:
+
136 if isinstance(item, ast.FunctionDef):
+
137 method_name = item.name
+
138 # Skip dunder methods
+
139 if not (method_name.startswith('__') and method_name.endswith('__')):
+
140 # Generate a consistent obfuscated name for this method
+
141 new_name = self.name_generator.generate_name()
+
142 self.class_method_mapping[class_name][method_name] = new_name
+
143
+
+

References transformers.rename.RenameTransformer.class_method_mapping, obfuscator.AdvancedObfuscator.name_generator, transformers.class_analyzer.ClassAnalyzer.name_generator, transformers.class_mapper.ClassMapAnalyzer.name_generator, transformers.rename.RenameTransformer.name_generator, and utils.junk_gen.JunkGenerator.name_generator.

+ +

Referenced by transformers.rename.RenameTransformer.visit_Module().

+ +
+
+ +

◆ visit_Attribute()

+ +
+
+ + + + + + + + + + + + + + + + + + +
ast.AST transformers.rename.RenameTransformer.visit_Attribute ( self,
ast.Attribute node 
)
+
+
Handle attribute access for renaming:
+1. Map method calls on self to the corresponding renamed methods
+2. Preserve external/inherited method names 
+3. Rename self.attribute for class-defined attributes
+
+

Definition at line 335 of file rename.py.

+
335 def visit_Attribute(self, node: ast.Attribute) -> ast.AST:
+
336 """
+
337 Handle attribute access for renaming:
+
338 1. Map method calls on self to the corresponding renamed methods
+
339 2. Preserve external/inherited method names
+
340 3. Rename self.attribute for class-defined attributes
+
341 """
+
342 # First visit any nested expressions
+
343 node = self.generic_visit(node)
+
344
+
345 # Check if this is a self.something attribute access
+
346 if isinstance(node.value, ast.Name) and node.value.id == 'self':
+
347 # Check all class methods across all classes (more robust)
+
348 for class_name, methods in self.class_method_mapping.items():
+
349 if node.attr in methods:
+
350 # We found a match in our method mapping
+
351 node.attr = methods[node.attr]
+
352 return node
+
353
+
354 # If we're in a class context, apply class-specific logic
+
355 if self.current_class_name:
+
356 # Case 1: Is it a call to one of our renamed methods?
+
357 class_methods = self.class_method_mapping.get(self.current_class_name, {})
+
358 if node.attr in class_methods:
+
359 node.attr = class_methods[node.attr]
+
360 return node
+
361
+
362 # Case 2: Is it an external method call with Qt-style naming?
+
363 is_external_method = (
+
364 node.attr[0].islower() and
+
365 any(c.isupper() for c in node.attr) and
+
366 not node.attr.startswith('__')
+
367 )
+
368 if is_external_method:
+
369 return node
+
370
+
371 # Case 3: Handle normal class attributes
+
372 attr_map = self.class_attr_mapping.get(self.current_class_name, {})
+
373 if node.attr not in attr_map:
+
374 attr_map[node.attr] = self.name_generator.generate_name()
+
375 node.attr = attr_map[node.attr]
+
376
+
377 return node
+
378
+
+

References obfuscator.AdvancedObfuscator.class_attr_mapping, transformers.attribute_transformer.AttributeTransformer.class_attr_mapping, transformers.rename.RenameTransformer.class_attr_mapping, transformers.rename.RenameTransformer.class_method_mapping, transformers.rename.RenameTransformer.current_class_name, obfuscator.AdvancedObfuscator.name_generator, transformers.class_analyzer.ClassAnalyzer.name_generator, transformers.class_mapper.ClassMapAnalyzer.name_generator, transformers.rename.RenameTransformer.name_generator, and utils.junk_gen.JunkGenerator.name_generator.

+ +
+
+ +

◆ visit_Call()

+ +
+
+ + + + + + + + + + + + + + + + + + +
ast.Call transformers.rename.RenameTransformer.visit_Call ( self,
ast.Call node 
)
+
+
Handle super() calls specifically to ensure class names are properly updated.
+
+

Definition at line 413 of file rename.py.

+
413 def visit_Call(self, node: ast.Call) -> ast.Call:
+
414 """
+
415 Handle super() calls specifically to ensure class names are properly updated.
+
416 """
+
417 # First visit all arguments and the function itself
+
418 node = self.generic_visit(node)
+
419
+
420 # Check if this is a super() call
+
421 if isinstance(node.func, ast.Name) and node.func.id == 'super':
+
422 # For super() with no args in Python 3
+
423 if not node.args:
+
424 return node
+
425
+
426 # For super(Class, self) style calls
+
427 if len(node.args) >= 1 and isinstance(node.args[0], ast.Name):
+
428 class_name = node.args[0].id
+
429 # Look for the renamed class in all scopes
+
430 for scope in reversed(self.scope_stack):
+
431 if class_name in scope:
+
432 node.args[0].id = scope[class_name]
+
433 break
+
434
+
435 return node
+
+

References transformers.rename.RenameTransformer.scope_stack.

+ +
+
+ +

◆ visit_ClassDef()

+ +
+
+ + + + + + + + + + + + + + + + + + +
ast.ClassDef transformers.rename.RenameTransformer.visit_ClassDef ( self,
ast.ClassDef node 
)
+
+ +

Definition at line 254 of file rename.py.

+
254 def visit_ClassDef(self, node: ast.ClassDef) -> ast.ClassDef:
+
255 has_bases = len(node.bases) > 0
+
256 self.scope_stack[-1]['_has_bases'] = has_bases
+
257 prev_in_class = self.in_class
+
258 prev_class_name = self.current_class_name
+
259
+
260 self.in_class = True
+
261 new_class_name = self.name_generator.generate_name()
+
262 self.scope_stack[-1][node.name] = new_class_name
+
263 self.current_class_name = new_class_name
+
264 self.class_attr_mapping[new_class_name] = {}
+
265
+
266 # Transfer method mappings from the original class name to the renamed one
+
267 if node.name in self.class_method_mapping:
+
268 self.class_method_mapping[new_class_name] = self.class_method_mapping[node.name]
+
269 del self.class_method_mapping[node.name]
+
270
+
271 self.scope_stack.append({})
+
272 node.bases = [self.visit(base) for base in node.bases]
+
273 node.body = [self.visit(b) for b in node.body]
+
274
+
275 self.scope_stack[-2][node.name] = new_class_name
+
276 node.name = new_class_name
+
277
+
278 self.in_class = prev_in_class
+
279 self.current_class_name = prev_class_name
+
280 self.scope_stack.pop()
+
281 return node
+
282
+
+

References obfuscator.AdvancedObfuscator.class_attr_mapping, transformers.attribute_transformer.AttributeTransformer.class_attr_mapping, transformers.rename.RenameTransformer.class_attr_mapping, transformers.rename.RenameTransformer.class_method_mapping, transformers.rename.RenameTransformer.current_class_name, transformers.rename.RenameTransformer.in_class, obfuscator.AdvancedObfuscator.name_generator, transformers.class_analyzer.ClassAnalyzer.name_generator, transformers.class_mapper.ClassMapAnalyzer.name_generator, transformers.rename.RenameTransformer.name_generator, utils.junk_gen.JunkGenerator.name_generator, and transformers.rename.RenameTransformer.scope_stack.

+ +
+
+ +

◆ visit_comprehension()

+ +
+
+ + + + + + + + + + + + + + + + + + +
ast.comprehension transformers.rename.RenameTransformer.visit_comprehension ( self,
ast.comprehension node 
)
+
+ +

Definition at line 201 of file rename.py.

+
201 def visit_comprehension(self, node: ast.comprehension) -> ast.comprehension:
+
202 if isinstance(node.target, ast.Name):
+
203 if node.target.id not in self.global_var_renames:
+
204 new_name = self.name_generator.generate_name()
+
205 self.scope_stack[-1][node.target.id] = new_name
+
206 node.target.id = new_name
+
207 else:
+
208 node.target = self.visit(node.target)
+
209
+
210 node.iter = self.visit(node.iter)
+
211 node.ifs = [self.visit(i) for i in node.ifs]
+
212 return node
+
213
+
+

References obfuscator.AdvancedObfuscator.global_var_renames, transformers.rename.RenameTransformer.global_var_renames, obfuscator.AdvancedObfuscator.name_generator, transformers.class_analyzer.ClassAnalyzer.name_generator, transformers.class_mapper.ClassMapAnalyzer.name_generator, transformers.rename.RenameTransformer.name_generator, utils.junk_gen.JunkGenerator.name_generator, and transformers.rename.RenameTransformer.scope_stack.

+ +
+
+ +

◆ visit_Constant()

+ +
+
+ + + + + + + + + + + + + + + + + + +
ast.AST transformers.rename.RenameTransformer.visit_Constant ( self,
ast.Constant node 
)
+
+
Encrypt string literals into a multi-step XOR, then base85 decode at runtime.
+
+

Definition at line 385 of file rename.py.

+
385 def visit_Constant(self, node: ast.Constant) -> ast.AST:
+
386 """
+
387 Encrypt string literals into a multi-step XOR, then base85 decode at runtime.
+
388 """
+
389 if isinstance(node.value, str):
+
390 encoded, key_setup, modifier = self.encryptor.encrypt_string(node.value)
+
391 if key_setup not in self.key_setup_code:
+
392 self.key_setup_code.append(key_setup)
+
393
+
394 decrypt_str = (
+
395 f"bytes(("
+
396 f"k2^k1^m for k1,k2,m in zip("
+
397 f"bytes(c^k for c,k in zip(base64.b85decode('{encoded}'),"
+
398 f"_sk*((len(base64.b85decode('{encoded}'))//8)+1))),"
+
399 f"_pk*((len(base64.b85decode('{encoded}'))//8)+1),"
+
400 f"bytes.fromhex('{modifier}')*((len(base64.b85decode('{encoded}'))//8)+1)))"
+
401 f").decode()"
+
402 )
+
403 return ast.parse(decrypt_str).body[0].value
+
404
+
405 return node
+
406
+
+

References transformers.rename.RenameTransformer.encryptor, and transformers.rename.RenameTransformer.key_setup_code.

+ +
+
+ +

◆ visit_DictComp()

+ +
+
+ + + + + + + + + + + + + + + + + + +
ast.DictComp transformers.rename.RenameTransformer.visit_DictComp ( self,
ast.DictComp node 
)
+
+ +

Definition at line 184 of file rename.py.

+
184 def visit_DictComp(self, node: ast.DictComp) -> ast.DictComp:
+
185 self._push_scope()
+
186 for gen in node.generators:
+
187 gen = self.visit(gen)
+
188 node.key = self.visit(node.key)
+
189 node.value = self.visit(node.value)
+
190 self._pop_scope()
+
191 return node
+
192
+
+

References transformers.rename.RenameTransformer._pop_scope(), and transformers.rename.RenameTransformer._push_scope().

+ +
+
+ +

◆ visit_FunctionDef()

+ +
+
+ + + + + + + + + + + + + + + + + + +
ast.FunctionDef transformers.rename.RenameTransformer.visit_FunctionDef ( self,
ast.FunctionDef node 
)
+
+
Make sure top-level function definitions also get renamed 
+if they're in global_var_renames.
+
+

Definition at line 283 of file rename.py.

+
283 def visit_FunctionDef(self, node: ast.FunctionDef) -> ast.FunctionDef:
+
284 """
+
285 Make sure top-level function definitions also get renamed
+
286 if they're in global_var_renames.
+
287 """
+
288 is_special = node.name.startswith('__') and node.name.endswith('__')
+
289 has_bases = any(('_has_bases' in scope and scope['_has_bases']) for scope in self.scope_stack)
+
290
+
291 # Save original name for later
+
292 orig_name = node.name
+
293
+
294 self._push_scope()
+
295
+
296 # Handle arguments (skip renaming for self if method):
+
297 if self.in_class and len(node.args.args) > 0:
+
298 self.scope_stack[-1][node.args.args[0].arg] = node.args.args[0].arg
+
299 for arg in node.args.args[1:]:
+
300 if arg.arg not in self.global_var_renames:
+
301 new_arg_name = self.name_generator.generate_name()
+
302 self.scope_stack[-1][arg.arg] = new_arg_name
+
303 arg.arg = new_arg_name
+
304 else:
+
305 for arg in node.args.args:
+
306 if arg.arg not in self.global_var_renames:
+
307 new_arg_name = self.name_generator.generate_name()
+
308 self.scope_stack[-1][arg.arg] = new_arg_name
+
309 arg.arg = new_arg_name
+
310
+
311 # Visit body
+
312 node.body = [self.visit(n) for n in node.body]
+
313
+
314 # --------------------------------
+
315 # NEW LOGIC: Actually rename the func if it's top-level
+
316 # or if we want to rename it anyway (and not dunder).
+
317 # --------------------------------
+
318 if not is_special:
+
319 # If the function was declared top-level and recognized in global_var_renames,
+
320 # then rename using that. Otherwise generate a brand new obfuscated name.
+
321 if node.name in self.global_var_renames:
+
322 node.name = self.global_var_renames[node.name]
+
323 elif self.in_class and not has_bases:
+
324 # For class methods, use the name we saved earlier
+
325 if self.current_class_name and orig_name in self.class_method_mapping.get(self.current_class_name, {}):
+
326 node.name = self.class_method_mapping[self.current_class_name][orig_name]
+
327 else:
+
328 new_fn_name = self.name_generator.generate_name()
+
329 self.scope_stack[-2][node.name] = new_fn_name
+
330 node.name = new_fn_name
+
331
+
332 self._pop_scope()
+
333 return node
+
334
+
+

References transformers.rename.RenameTransformer._pop_scope(), transformers.rename.RenameTransformer._push_scope(), transformers.rename.RenameTransformer.class_method_mapping, transformers.rename.RenameTransformer.current_class_name, obfuscator.AdvancedObfuscator.global_var_renames, transformers.rename.RenameTransformer.global_var_renames, transformers.rename.RenameTransformer.in_class, obfuscator.AdvancedObfuscator.name_generator, transformers.class_analyzer.ClassAnalyzer.name_generator, transformers.class_mapper.ClassMapAnalyzer.name_generator, transformers.rename.RenameTransformer.name_generator, utils.junk_gen.JunkGenerator.name_generator, and transformers.rename.RenameTransformer.scope_stack.

+ +
+
+ +

◆ visit_GeneratorExp()

+ +
+
+ + + + + + + + + + + + + + + + + + +
ast.GeneratorExp transformers.rename.RenameTransformer.visit_GeneratorExp ( self,
ast.GeneratorExp node 
)
+
+ +

Definition at line 193 of file rename.py.

+
193 def visit_GeneratorExp(self, node: ast.GeneratorExp) -> ast.GeneratorExp:
+
194 self._push_scope()
+
195 for gen in node.generators:
+
196 gen = self.visit(gen)
+
197 node.elt = self.visit(node.elt)
+
198 self._pop_scope()
+
199 return node
+
200
+
+

References transformers.rename.RenameTransformer._pop_scope(), and transformers.rename.RenameTransformer._push_scope().

+ +
+
+ +

◆ visit_Global()

+ +
+
+ + + + + + + + + + + + + + + + + + +
ast.Global transformers.rename.RenameTransformer.visit_Global ( self,
ast.Global node 
)
+
+
Handle global statement declarations by:
+1. Adding the variable names to global_var_renames if not already there
+2. Adding them to the current scope to mark them as global
+
+

Definition at line 150 of file rename.py.

+
150 def visit_Global(self, node: ast.Global) -> ast.Global:
+
151 """
+
152 Handle global statement declarations by:
+
153 1. Adding the variable names to global_var_renames if not already there
+
154 2. Adding them to the current scope to mark them as global
+
155 """
+
156 for name in node.names:
+
157 # If this global name hasn't been seen before, generate a new obfuscated name
+
158 if name not in self.global_var_renames:
+
159 self.global_var_renames[name] = self.name_generator.generate_name()
+
160
+
161 # Mark this name as global in the current scope
+
162 self.scope_stack[-1][name] = self.global_var_renames[name]
+
163
+
164 # Update the global statement with obfuscated names
+
165 node.names = [self.global_var_renames[name] for name in node.names]
+
166 return node
+
167
+
+

References obfuscator.AdvancedObfuscator.global_var_renames, transformers.rename.RenameTransformer.global_var_renames, obfuscator.AdvancedObfuscator.name_generator, transformers.class_analyzer.ClassAnalyzer.name_generator, transformers.class_mapper.ClassMapAnalyzer.name_generator, transformers.rename.RenameTransformer.name_generator, utils.junk_gen.JunkGenerator.name_generator, and transformers.rename.RenameTransformer.scope_stack.

+ +
+
+ +

◆ visit_Import()

+ +
+
+ + + + + + + + + + + + + + + + + + +
ast.AST transformers.rename.RenameTransformer.visit_Import ( self,
ast.Import node 
)
+
+ +

Definition at line 407 of file rename.py.

+
407 def visit_Import(self, node: ast.Import) -> ast.AST:
+
408 return self.generic_visit(node)
+
409
+
+
+
+ +

◆ visit_ImportFrom()

+ +
+
+ + + + + + + + + + + + + + + + + + +
ast.AST transformers.rename.RenameTransformer.visit_ImportFrom ( self,
ast.ImportFrom node 
)
+
+ +

Definition at line 410 of file rename.py.

+
410 def visit_ImportFrom(self, node: ast.ImportFrom) -> ast.AST:
+
411 return self.generic_visit(node)
+
412
+
+
+
+ +

◆ visit_ListComp()

+ +
+
+ + + + + + + + + + + + + + + + + + +
ast.ListComp transformers.rename.RenameTransformer.visit_ListComp ( self,
ast.ListComp node 
)
+
+ +

Definition at line 168 of file rename.py.

+
168 def visit_ListComp(self, node: ast.ListComp) -> ast.ListComp:
+
169 self._push_scope()
+
170 for gen in node.generators:
+
171 gen = self.visit(gen)
+
172 node.elt = self.visit(node.elt)
+
173 self._pop_scope()
+
174 return node
+
175
+
+

References transformers.rename.RenameTransformer._pop_scope(), and transformers.rename.RenameTransformer._push_scope().

+ +
+
+ +

◆ visit_Module()

+ +
+
+ + + + + + + + + + + + + + + + + + +
ast.Module transformers.rename.RenameTransformer.visit_Module ( self,
ast.Module node 
)
+
+
Enhanced module visitor to properly handle global variables 
+AND top-level function definitions for consistent renaming.
+
+Now includes a two-pass strategy for classes to ensure method consistency.
+
+

Definition at line 63 of file rename.py.

+
63 def visit_Module(self, node: ast.Module) -> ast.Module:
+
64 """
+
65 Enhanced module visitor to properly handle global variables
+
66 AND top-level function definitions for consistent renaming.
+
67
+
68 Now includes a two-pass strategy for classes to ensure method consistency.
+
69 """
+
70 # First pass: detect methods in classes
+
71 if self.first_pass:
+
72 self.first_pass = False
+
73 # First scan all classes and methods recursively
+
74 for stmt in ast.walk(node):
+
75 if isinstance(stmt, ast.ClassDef):
+
76 self.scan_class_methods(stmt)
+
77
+
78 # Rest of the code remains the same...
+
79 # First pass: detect top-level assignments, globals, AND function definitions
+
80 for stmt in node.body:
+
81 # 1. If a global statement
+
82 if isinstance(stmt, ast.Global):
+
83 for name in stmt.names:
+
84 if name not in self.global_var_renames:
+
85 self.global_var_renames[name] = self.name_generator.generate_name()
+
86
+
87 # 2. If a top-level assignment
+
88 elif isinstance(stmt, ast.Assign):
+
89 for target in stmt.targets:
+
90 if isinstance(target, ast.Name):
+
91 if target.id not in self.global_var_renames:
+
92 self.global_var_renames[target.id] = self.name_generator.generate_name()
+
93
+
94 # 3. If a top-level function definition
+
95 elif isinstance(stmt, ast.FunctionDef):
+
96 # Skip special (dunder) methods to avoid messing up e.g. __init__
+
97 if not (stmt.name.startswith('__') and stmt.name.endswith('__')):
+
98 if stmt.name not in self.global_var_renames:
+
99 self.global_var_renames[stmt.name] = self.name_generator.generate_name()
+
100
+
101 # Create a new body that starts with any needed imports
+
102 new_body = [
+
103 ast.parse("import base64").body[0],
+
104 ast.parse("import random").body[0]
+
105 ]
+
106
+
107 # Transform the module body
+
108 transformed_body = []
+
109 for item in node.body:
+
110 visited = self.visit(item)
+
111 if isinstance(visited, list):
+
112 transformed_body.extend(visited)
+
113 else:
+
114 transformed_body.append(visited)
+
115
+
116 # If there's any key setup code, parse & insert that
+
117 if self.key_setup_code:
+
118 setup_nodes = ast.parse('\n'.join(self.key_setup_code)).body
+
119 new_body.extend(setup_nodes)
+
120
+
121 new_body.extend(transformed_body)
+
122 node.body = new_body
+
123 return node
+
124
+
+

References transformers.rename.RenameTransformer.first_pass, obfuscator.AdvancedObfuscator.global_var_renames, transformers.rename.RenameTransformer.global_var_renames, transformers.rename.RenameTransformer.key_setup_code, obfuscator.AdvancedObfuscator.name_generator, transformers.class_analyzer.ClassAnalyzer.name_generator, transformers.class_mapper.ClassMapAnalyzer.name_generator, transformers.rename.RenameTransformer.name_generator, utils.junk_gen.JunkGenerator.name_generator, and transformers.rename.RenameTransformer.scan_class_methods().

+ +
+
+ +

◆ visit_Name()

+ +
+
+ + + + + + + + + + + + + + + + + + +
ast.AST transformers.rename.RenameTransformer.visit_Name ( self,
ast.Name node 
)
+
+
Handle variable names and function names in calls.  
+1. If it's a known global/ top-level function, use global_var_renames.  
+2. Otherwise, handle locally within scope_stack.
+
+

Definition at line 214 of file rename.py.

+
214 def visit_Name(self, node: ast.Name) -> ast.AST:
+
215 """
+
216 Handle variable names and function names in calls.
+
217 1. If it's a known global/ top-level function, use global_var_renames.
+
218 2. Otherwise, handle locally within scope_stack.
+
219 """
+
220 if node.id in self.global_var_renames:
+
221 node.id = self.global_var_renames[node.id]
+
222 return node
+
223
+
224 # Check if this name is marked as global in any scope
+
225 for scope in self.scope_stack:
+
226 if node.id in scope and node.id in self.global_var_renames:
+
227 node.id = self.global_var_renames[node.id]
+
228 return node
+
229
+
230 # Otherwise, handle local variables
+
231 if isinstance(node.ctx, ast.Store):
+
232 if self.in_class and not isinstance(node.ctx, ast.Param):
+
233 # Class attribute
+
234 if node.id not in self.scope_stack[-1]:
+
235 new_name = self.name_generator.generate_name()
+
236 self.scope_stack[-1][node.id] = new_name
+
237 if self.current_class_name:
+
238 self.class_attr_mapping[self.current_class_name][node.id] = new_name
+
239 node.id = self.scope_stack[-1][node.id]
+
240 else:
+
241 # Regular variable assignment
+
242 if node.id not in self.scope_stack[-1]:
+
243 self.scope_stack[-1][node.id] = self.name_generator.generate_name()
+
244 node.id = self.scope_stack[-1][node.id]
+
245 else:
+
246 # Load context
+
247 for scope in reversed(self.scope_stack):
+
248 if node.id in scope:
+
249 node.id = scope[node.id]
+
250 break
+
251
+
252 return node
+
253
+
+

References obfuscator.AdvancedObfuscator.class_attr_mapping, transformers.attribute_transformer.AttributeTransformer.class_attr_mapping, transformers.rename.RenameTransformer.class_attr_mapping, transformers.rename.RenameTransformer.current_class_name, obfuscator.AdvancedObfuscator.global_var_renames, transformers.rename.RenameTransformer.global_var_renames, transformers.rename.RenameTransformer.in_class, obfuscator.AdvancedObfuscator.name_generator, transformers.class_analyzer.ClassAnalyzer.name_generator, transformers.class_mapper.ClassMapAnalyzer.name_generator, transformers.rename.RenameTransformer.name_generator, utils.junk_gen.JunkGenerator.name_generator, and transformers.rename.RenameTransformer.scope_stack.

+ +
+
+ +

◆ visit_SetComp()

+ +
+
+ + + + + + + + + + + + + + + + + + +
ast.SetComp transformers.rename.RenameTransformer.visit_SetComp ( self,
ast.SetComp node 
)
+
+ +

Definition at line 176 of file rename.py.

+
176 def visit_SetComp(self, node: ast.SetComp) -> ast.SetComp:
+
177 self._push_scope()
+
178 for gen in node.generators:
+
179 gen = self.visit(gen)
+
180 node.elt = self.visit(node.elt)
+
181 self._pop_scope()
+
182 return node
+
183
+
+

References transformers.rename.RenameTransformer._pop_scope(), and transformers.rename.RenameTransformer._push_scope().

+ +
+
+ +

◆ visit_Subscript()

+ +
+
+ + + + + + + + + + + + + + + + + + +
ast.AST transformers.rename.RenameTransformer.visit_Subscript ( self,
ast.Subscript node 
)
+
+ +

Definition at line 379 of file rename.py.

+
379 def visit_Subscript(self, node: ast.Subscript) -> ast.AST:
+
380 node.value = self.visit(node.value)
+
381 if isinstance(node.slice, ast.AST):
+
382 self.visit(node.slice)
+
383 return node
+
384
+
+
+
+

Member Data Documentation

+ +

◆ class_attr_mapping

+ + + +

◆ class_method_mapping

+ + + +

◆ current_class_name

+ + + +

◆ debug_data

+ + + +

◆ debug_mode

+ + + +

◆ encryptor

+ +
+
+ + + + +
transformers.rename.RenameTransformer.encryptor
+
+ +

Definition at line 30 of file rename.py.

+ +

Referenced by transformers.rename.RenameTransformer.visit_Constant().

+ +
+
+ +

◆ first_pass

+ +
+
+ + + + +
transformers.rename.RenameTransformer.first_pass
+
+ +

Definition at line 44 of file rename.py.

+ +

Referenced by transformers.rename.RenameTransformer.visit_Module().

+ +
+
+ +

◆ global_var_renames

+ + + +

◆ in_class

+ +
+
+ + + + +
transformers.rename.RenameTransformer.in_class
+
+
+ +

◆ key_setup_code

+ +
+
+ + + + +
transformers.rename.RenameTransformer.key_setup_code
+
+
+ +

◆ name_generator

+ + + +

◆ scope_stack

+ + +
The documentation for this class was generated from the following file: +
+
+ + + + diff --git a/doxygen/classtransformers_1_1rename_1_1RenameTransformer.js b/doxygen/classtransformers_1_1rename_1_1RenameTransformer.js new file mode 100644 index 0000000..a2a84b5 --- /dev/null +++ b/doxygen/classtransformers_1_1rename_1_1RenameTransformer.js @@ -0,0 +1,36 @@ +var classtransformers_1_1rename_1_1RenameTransformer = +[ + [ "__init__", "classtransformers_1_1rename_1_1RenameTransformer.html#a41c7ff17fad58c5d75f9b42c3bae8b98", null ], + [ "_pop_scope", "classtransformers_1_1rename_1_1RenameTransformer.html#abdbb42558625854c0535dfb7610ec136", null ], + [ "_push_scope", "classtransformers_1_1rename_1_1RenameTransformer.html#acd49db2a6b3c22d6eaaec55ddcc95620", null ], + [ "log_debug", "classtransformers_1_1rename_1_1RenameTransformer.html#a0d8e460a12ba4bf74a95882aa6bb3835", null ], + [ "scan_class_methods", "classtransformers_1_1rename_1_1RenameTransformer.html#ab87d8148ef510b4803c4332deff663d5", null ], + [ "visit_Attribute", "classtransformers_1_1rename_1_1RenameTransformer.html#a89a7f9a7f5c45440346c798fc8840ac7", null ], + [ "visit_Call", "classtransformers_1_1rename_1_1RenameTransformer.html#a6dc39dff4863373a67b4095f234793dc", null ], + [ "visit_ClassDef", "classtransformers_1_1rename_1_1RenameTransformer.html#a9d9392f24ca47278859f5e46da1bce45", null ], + [ "visit_comprehension", "classtransformers_1_1rename_1_1RenameTransformer.html#a0660f79cdf349288c43d6fc49ae23a2c", null ], + [ "visit_Constant", "classtransformers_1_1rename_1_1RenameTransformer.html#ad81bc6a0c7abb3094b23b6dc03ecfd29", null ], + [ "visit_DictComp", "classtransformers_1_1rename_1_1RenameTransformer.html#a1fa5c552e136af25f432f975094b7cbf", null ], + [ "visit_FunctionDef", "classtransformers_1_1rename_1_1RenameTransformer.html#a4309d59dde0369e0b8476b8d6b84d500", null ], + [ "visit_GeneratorExp", "classtransformers_1_1rename_1_1RenameTransformer.html#a771a06f14514e325c016778767307274", null ], + [ "visit_Global", "classtransformers_1_1rename_1_1RenameTransformer.html#ae366228dc64c18fa26f2ba7fa6453444", null ], + [ "visit_Import", "classtransformers_1_1rename_1_1RenameTransformer.html#a99663ce64c7051d684d84cf8fd1dca5a", null ], + [ "visit_ImportFrom", "classtransformers_1_1rename_1_1RenameTransformer.html#ae4a3532894dd265babf99765ca109dc6", null ], + [ "visit_ListComp", "classtransformers_1_1rename_1_1RenameTransformer.html#a6583f4eb358270431dda81d0d939162d", null ], + [ "visit_Module", "classtransformers_1_1rename_1_1RenameTransformer.html#af219e2b8032497024cf99f76578eea8b", null ], + [ "visit_Name", "classtransformers_1_1rename_1_1RenameTransformer.html#a6ffe49f1216346f0727df849dae7163a", null ], + [ "visit_SetComp", "classtransformers_1_1rename_1_1RenameTransformer.html#a29d393746b1977c8181a439c51207bf1", null ], + [ "visit_Subscript", "classtransformers_1_1rename_1_1RenameTransformer.html#ab4fcef7ad6262e7595e449738e977a5d", null ], + [ "class_attr_mapping", "classtransformers_1_1rename_1_1RenameTransformer.html#ac4975f5038d05ec36f550bf6706e4d84", null ], + [ "class_method_mapping", "classtransformers_1_1rename_1_1RenameTransformer.html#ab89f9fee976059e47e655e21952dc010", null ], + [ "current_class_name", "classtransformers_1_1rename_1_1RenameTransformer.html#afdd8f38035ed680a0c28236d51c1cd69", null ], + [ "debug_data", "classtransformers_1_1rename_1_1RenameTransformer.html#a2c367ecd7eb38ba4600dda4671b0ab37", null ], + [ "debug_mode", "classtransformers_1_1rename_1_1RenameTransformer.html#a285d017ddc69b2f8b20824251e8ddad4", null ], + [ "encryptor", "classtransformers_1_1rename_1_1RenameTransformer.html#ae8272a419a6f3c2ea0ab6b8cc42e376e", null ], + [ "first_pass", "classtransformers_1_1rename_1_1RenameTransformer.html#aa61f87dcb4066c6e3676e39a309a523d", null ], + [ "global_var_renames", "classtransformers_1_1rename_1_1RenameTransformer.html#a8d691eb384ad7616eda40956de5bb95e", null ], + [ "in_class", "classtransformers_1_1rename_1_1RenameTransformer.html#a44a154d4cf962916a1d861e12d593642", null ], + [ "key_setup_code", "classtransformers_1_1rename_1_1RenameTransformer.html#a15d28a47a1cde0841e7395822acc1763", null ], + [ "name_generator", "classtransformers_1_1rename_1_1RenameTransformer.html#a04dd79b46f0e252cc1c55f10e63ad938", null ], + [ "scope_stack", "classtransformers_1_1rename_1_1RenameTransformer.html#a41eded65457e873912b6874d6a0c2909", null ] +]; \ No newline at end of file diff --git a/doxygen/classtransformers_1_1rename_1_1RenameTransformer__coll__graph.dot b/doxygen/classtransformers_1_1rename_1_1RenameTransformer__coll__graph.dot new file mode 100644 index 0000000..1f6d99c --- /dev/null +++ b/doxygen/classtransformers_1_1rename_1_1RenameTransformer__coll__graph.dot @@ -0,0 +1,10 @@ +digraph "transformers.rename.RenameTransformer" +{ + // LATEX_PDF_SIZE + bgcolor="transparent"; + edge [fontname=Helvetica,fontsize=10,labelfontname=Helvetica,labelfontsize=10]; + node [fontname=Helvetica,fontsize=10,shape=box,height=0.2,width=0.4]; + Node1 [id="Node000001",label="transformers.rename.Rename\lTransformer",height=0.2,width=0.4,color="gray40", fillcolor="grey60", style="filled", fontcolor="black",tooltip=" "]; + Node2 -> Node1 [id="edge1_Node000001_Node000002",dir="back",color="steelblue1",style="solid",tooltip=" "]; + Node2 [id="Node000002",label="ast.NodeTransformer",height=0.2,width=0.4,color="gray40", fillcolor="white", style="filled",tooltip=" "]; +} diff --git a/doxygen/classtransformers_1_1rename_1_1RenameTransformer__inherit__graph.dot b/doxygen/classtransformers_1_1rename_1_1RenameTransformer__inherit__graph.dot new file mode 100644 index 0000000..1f6d99c --- /dev/null +++ b/doxygen/classtransformers_1_1rename_1_1RenameTransformer__inherit__graph.dot @@ -0,0 +1,10 @@ +digraph "transformers.rename.RenameTransformer" +{ + // LATEX_PDF_SIZE + bgcolor="transparent"; + edge [fontname=Helvetica,fontsize=10,labelfontname=Helvetica,labelfontsize=10]; + node [fontname=Helvetica,fontsize=10,shape=box,height=0.2,width=0.4]; + Node1 [id="Node000001",label="transformers.rename.Rename\lTransformer",height=0.2,width=0.4,color="gray40", fillcolor="grey60", style="filled", fontcolor="black",tooltip=" "]; + Node2 -> Node1 [id="edge1_Node000001_Node000002",dir="back",color="steelblue1",style="solid",tooltip=" "]; + Node2 [id="Node000002",label="ast.NodeTransformer",height=0.2,width=0.4,color="gray40", fillcolor="white", style="filled",tooltip=" "]; +} diff --git a/doxygen/classtransformers_1_1symbol__tree_1_1ClassScope-members.html b/doxygen/classtransformers_1_1symbol__tree_1_1ClassScope-members.html new file mode 100644 index 0000000..e355703 --- /dev/null +++ b/doxygen/classtransformers_1_1symbol__tree_1_1ClassScope-members.html @@ -0,0 +1,112 @@ + + + + + + + +OMG-Fuscator: Member List + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
transformers.symbol_tree.ClassScope Member List
+
+
+ +

This is the complete list of members for transformers.symbol_tree.ClassScope, including all inherited members.

+ + + + + +
__init__(self, str name, ast.ClassDef node)transformers.symbol_tree.ClassScope
add_attribute(self, Symbol attr)transformers.symbol_tree.ClassScope
add_base_class(self, str base_name)transformers.symbol_tree.ClassScope
add_method(self, Symbol method)transformers.symbol_tree.ClassScope
+
+ + + + diff --git a/doxygen/classtransformers_1_1symbol__tree_1_1ClassScope.html b/doxygen/classtransformers_1_1symbol__tree_1_1ClassScope.html new file mode 100644 index 0000000..fd8fce0 --- /dev/null +++ b/doxygen/classtransformers_1_1symbol__tree_1_1ClassScope.html @@ -0,0 +1,322 @@ + + + + + + + +OMG-Fuscator: transformers.symbol_tree.ClassScope Class Reference + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
transformers.symbol_tree.ClassScope Class Reference
+
+
+
+ + Inheritance diagram for transformers.symbol_tree.ClassScope:
+
+
+ +
+ + Collaboration diagram for transformers.symbol_tree.ClassScope:
+
+
+ + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 __init__ (self, str name, ast.ClassDef node)
 
Symbol add_attribute (self, Symbol attr)
 
 add_base_class (self, str base_name)
 
Symbol add_method (self, Symbol method)
 
- Public Member Functions inherited from transformers.symbol_tree.Scope
 __repr__ (self)
 
'Scopeadd_child_scope (self, 'Scope' scope)
 
Symbol add_symbol (self, Symbol symbol)
 
str get_qualified_name (self)
 
Optional[Symbollookup (self, str name)
 
+ + + + + + + + +

+Additional Inherited Members

- Public Attributes inherited from transformers.symbol_tree.Scope
 name
 
 node
 
 scope_type
 
+

Detailed Description

+
A specialized scope for classes with additional tracking for inheritance.
+

Definition at line 102 of file symbol_tree.py.

+

Constructor & Destructor Documentation

+ +

◆ __init__()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
transformers.symbol_tree.ClassScope.__init__ ( self,
str name,
ast.ClassDef node 
)
+
+ +

Reimplemented from transformers.symbol_tree.Scope.

+ +

Definition at line 105 of file symbol_tree.py.

+
105 def __init__(self, name: str, node: ast.ClassDef):
+
106 super().__init__(name, "class", node)
+
107 self.base_classes: List[str] = [] # Names of base classes
+
108 self.methods: Dict[str, Symbol] = {} # Methods defined in this class
+
109 self.attributes: Dict[str, Symbol] = {} # Attributes defined in this class
+
110
+
+

References transformers.symbol_tree.ClassScope.__init__().

+ +

Referenced by transformers.symbol_tree.ClassScope.__init__().

+ +
+
+

Member Function Documentation

+ +

◆ add_attribute()

+ +
+
+ + + + + + + + + + + + + + + + + + +
Symbol transformers.symbol_tree.ClassScope.add_attribute ( self,
Symbol attr 
)
+
+
Add an attribute to this class.
+

Definition at line 121 of file symbol_tree.py.

+
121 def add_attribute(self, attr: Symbol) -> Symbol:
+
122 """Add an attribute to this class."""
+
123 self.attributes[attr.name] = attr
+
124 return self.add_symbol(attr)
+
125
+
126
+
+

References transformers.symbol_tree.SymbolTree.add_symbol(), and transformers.symbol_tree.Scope.add_symbol().

+ +
+
+ +

◆ add_base_class()

+ +
+
+ + + + + + + + + + + + + + + + + + +
transformers.symbol_tree.ClassScope.add_base_class ( self,
str base_name 
)
+
+
Add a base class to this class's inheritance list.
+

Definition at line 111 of file symbol_tree.py.

+
111 def add_base_class(self, base_name: str):
+
112 """Add a base class to this class's inheritance list."""
+
113 if base_name not in self.base_classes:
+
114 self.base_classes.append(base_name)
+
115
+
+
+
+ +

◆ add_method()

+ +
+
+ + + + + + + + + + + + + + + + + + +
Symbol transformers.symbol_tree.ClassScope.add_method ( self,
Symbol method 
)
+
+
Add a method to this class.
+

Definition at line 116 of file symbol_tree.py.

+
116 def add_method(self, method: Symbol) -> Symbol:
+
117 """Add a method to this class."""
+
118 self.methods[method.name] = method
+
119 return self.add_symbol(method)
+
120
+
+

References transformers.symbol_tree.SymbolTree.add_symbol(), and transformers.symbol_tree.Scope.add_symbol().

+ +
+
+
The documentation for this class was generated from the following file: +
+
+ + + + diff --git a/doxygen/classtransformers_1_1symbol__tree_1_1ClassScope.js b/doxygen/classtransformers_1_1symbol__tree_1_1ClassScope.js new file mode 100644 index 0000000..d89bf32 --- /dev/null +++ b/doxygen/classtransformers_1_1symbol__tree_1_1ClassScope.js @@ -0,0 +1,7 @@ +var classtransformers_1_1symbol__tree_1_1ClassScope = +[ + [ "__init__", "classtransformers_1_1symbol__tree_1_1ClassScope.html#a359688eee5249d7f4c8929ab5348115f", null ], + [ "add_attribute", "classtransformers_1_1symbol__tree_1_1ClassScope.html#a279fe21a8a95cd5b3b3c64d699922aa3", null ], + [ "add_base_class", "classtransformers_1_1symbol__tree_1_1ClassScope.html#a802567dd6aeb95d3c45929992cbe4ce8", null ], + [ "add_method", "classtransformers_1_1symbol__tree_1_1ClassScope.html#ad8149b754ff7a1a122a8735b733b3853", null ] +]; \ No newline at end of file diff --git a/doxygen/classtransformers_1_1symbol__tree_1_1ClassScope__coll__graph.dot b/doxygen/classtransformers_1_1symbol__tree_1_1ClassScope__coll__graph.dot new file mode 100644 index 0000000..82ebc77 --- /dev/null +++ b/doxygen/classtransformers_1_1symbol__tree_1_1ClassScope__coll__graph.dot @@ -0,0 +1,10 @@ +digraph "transformers.symbol_tree.ClassScope" +{ + // LATEX_PDF_SIZE + bgcolor="transparent"; + edge [fontname=Helvetica,fontsize=10,labelfontname=Helvetica,labelfontsize=10]; + node [fontname=Helvetica,fontsize=10,shape=box,height=0.2,width=0.4]; + Node1 [id="Node000001",label="transformers.symbol\l_tree.ClassScope",height=0.2,width=0.4,color="gray40", fillcolor="grey60", style="filled", fontcolor="black",tooltip=" "]; + Node2 -> Node1 [id="edge1_Node000001_Node000002",dir="back",color="steelblue1",style="solid",tooltip=" "]; + Node2 [id="Node000002",label="transformers.symbol\l_tree.Scope",height=0.2,width=0.4,color="gray40", fillcolor="white", style="filled",URL="$classtransformers_1_1symbol__tree_1_1Scope.html",tooltip=" "]; +} diff --git a/doxygen/classtransformers_1_1symbol__tree_1_1ClassScope__inherit__graph.dot b/doxygen/classtransformers_1_1symbol__tree_1_1ClassScope__inherit__graph.dot new file mode 100644 index 0000000..82ebc77 --- /dev/null +++ b/doxygen/classtransformers_1_1symbol__tree_1_1ClassScope__inherit__graph.dot @@ -0,0 +1,10 @@ +digraph "transformers.symbol_tree.ClassScope" +{ + // LATEX_PDF_SIZE + bgcolor="transparent"; + edge [fontname=Helvetica,fontsize=10,labelfontname=Helvetica,labelfontsize=10]; + node [fontname=Helvetica,fontsize=10,shape=box,height=0.2,width=0.4]; + Node1 [id="Node000001",label="transformers.symbol\l_tree.ClassScope",height=0.2,width=0.4,color="gray40", fillcolor="grey60", style="filled", fontcolor="black",tooltip=" "]; + Node2 -> Node1 [id="edge1_Node000001_Node000002",dir="back",color="steelblue1",style="solid",tooltip=" "]; + Node2 [id="Node000002",label="transformers.symbol\l_tree.Scope",height=0.2,width=0.4,color="gray40", fillcolor="white", style="filled",URL="$classtransformers_1_1symbol__tree_1_1Scope.html",tooltip=" "]; +} diff --git a/doxygen/classtransformers_1_1symbol__tree_1_1ModuleScope-members.html b/doxygen/classtransformers_1_1symbol__tree_1_1ModuleScope-members.html new file mode 100644 index 0000000..b0c53e7 --- /dev/null +++ b/doxygen/classtransformers_1_1symbol__tree_1_1ModuleScope-members.html @@ -0,0 +1,111 @@ + + + + + + + +OMG-Fuscator: Member List + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
transformers.symbol_tree.ModuleScope Member List
+
+
+ +

This is the complete list of members for transformers.symbol_tree.ModuleScope, including all inherited members.

+ + + + +
__init__(self, str name, ast.Module node)transformers.symbol_tree.ModuleScope
add_from_import(self, str module, str alias, str original)transformers.symbol_tree.ModuleScope
add_import(self, str alias, str original)transformers.symbol_tree.ModuleScope
+
+ + + + diff --git a/doxygen/classtransformers_1_1symbol__tree_1_1ModuleScope.html b/doxygen/classtransformers_1_1symbol__tree_1_1ModuleScope.html new file mode 100644 index 0000000..8a7c635 --- /dev/null +++ b/doxygen/classtransformers_1_1symbol__tree_1_1ModuleScope.html @@ -0,0 +1,298 @@ + + + + + + + +OMG-Fuscator: transformers.symbol_tree.ModuleScope Class Reference + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
transformers.symbol_tree.ModuleScope Class Reference
+
+
+
+ + Inheritance diagram for transformers.symbol_tree.ModuleScope:
+
+
+ +
+ + Collaboration diagram for transformers.symbol_tree.ModuleScope:
+
+
+ + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 __init__ (self, str name, ast.Module node)
 
 add_from_import (self, str module, str alias, str original)
 
 add_import (self, str alias, str original)
 
- Public Member Functions inherited from transformers.symbol_tree.Scope
 __repr__ (self)
 
'Scopeadd_child_scope (self, 'Scope' scope)
 
Symbol add_symbol (self, Symbol symbol)
 
str get_qualified_name (self)
 
Optional[Symbollookup (self, str name)
 
+ + + + + + + + +

+Additional Inherited Members

- Public Attributes inherited from transformers.symbol_tree.Scope
 name
 
 node
 
 scope_type
 
+

Detailed Description

+
A specialized scope for modules with additional tracking for imports.
+

Definition at line 127 of file symbol_tree.py.

+

Constructor & Destructor Documentation

+ +

◆ __init__()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
transformers.symbol_tree.ModuleScope.__init__ ( self,
str name,
ast.Module node 
)
+
+ +

Reimplemented from transformers.symbol_tree.Scope.

+ +

Definition at line 130 of file symbol_tree.py.

+
130 def __init__(self, name: str, node: ast.Module):
+
131 super().__init__(name, "module", node)
+
132 self.imports: Dict[str, str] = {} # Import alias -> original name
+
133 self.from_imports: Dict[str, Dict[str, str]] = {} # Module -> {alias -> original name}
+
134
+
+

References transformers.symbol_tree.ModuleScope.__init__().

+ +

Referenced by transformers.symbol_tree.ModuleScope.__init__().

+ +
+
+

Member Function Documentation

+ +

◆ add_from_import()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
transformers.symbol_tree.ModuleScope.add_from_import ( self,
str module,
str alias,
str original 
)
+
+
Add a from-import to this module.
+

Definition at line 139 of file symbol_tree.py.

+
139 def add_from_import(self, module: str, alias: str, original: str):
+
140 """Add a from-import to this module."""
+
141 if module not in self.from_imports:
+
142 self.from_imports[module] = {}
+
143 self.from_imports[module][alias] = original
+
144
+
145
+
+
+
+ +

◆ add_import()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
transformers.symbol_tree.ModuleScope.add_import ( self,
str alias,
str original 
)
+
+
Add an import to this module.
+

Definition at line 135 of file symbol_tree.py.

+
135 def add_import(self, alias: str, original: str):
+
136 """Add an import to this module."""
+
137 self.imports[alias] = original
+
138
+
+
+
+
The documentation for this class was generated from the following file: +
+
+ + + + diff --git a/doxygen/classtransformers_1_1symbol__tree_1_1ModuleScope.js b/doxygen/classtransformers_1_1symbol__tree_1_1ModuleScope.js new file mode 100644 index 0000000..87ce533 --- /dev/null +++ b/doxygen/classtransformers_1_1symbol__tree_1_1ModuleScope.js @@ -0,0 +1,6 @@ +var classtransformers_1_1symbol__tree_1_1ModuleScope = +[ + [ "__init__", "classtransformers_1_1symbol__tree_1_1ModuleScope.html#a08701d98e737973214f9370291b63188", null ], + [ "add_from_import", "classtransformers_1_1symbol__tree_1_1ModuleScope.html#a28659edddf055d62956a87218c564c46", null ], + [ "add_import", "classtransformers_1_1symbol__tree_1_1ModuleScope.html#af789af3957432b1d74e19d2e945aea80", null ] +]; \ No newline at end of file diff --git a/doxygen/classtransformers_1_1symbol__tree_1_1ModuleScope__coll__graph.dot b/doxygen/classtransformers_1_1symbol__tree_1_1ModuleScope__coll__graph.dot new file mode 100644 index 0000000..ad34f4e --- /dev/null +++ b/doxygen/classtransformers_1_1symbol__tree_1_1ModuleScope__coll__graph.dot @@ -0,0 +1,10 @@ +digraph "transformers.symbol_tree.ModuleScope" +{ + // LATEX_PDF_SIZE + bgcolor="transparent"; + edge [fontname=Helvetica,fontsize=10,labelfontname=Helvetica,labelfontsize=10]; + node [fontname=Helvetica,fontsize=10,shape=box,height=0.2,width=0.4]; + Node1 [id="Node000001",label="transformers.symbol\l_tree.ModuleScope",height=0.2,width=0.4,color="gray40", fillcolor="grey60", style="filled", fontcolor="black",tooltip=" "]; + Node2 -> Node1 [id="edge1_Node000001_Node000002",dir="back",color="steelblue1",style="solid",tooltip=" "]; + Node2 [id="Node000002",label="transformers.symbol\l_tree.Scope",height=0.2,width=0.4,color="gray40", fillcolor="white", style="filled",URL="$classtransformers_1_1symbol__tree_1_1Scope.html",tooltip=" "]; +} diff --git a/doxygen/classtransformers_1_1symbol__tree_1_1ModuleScope__inherit__graph.dot b/doxygen/classtransformers_1_1symbol__tree_1_1ModuleScope__inherit__graph.dot new file mode 100644 index 0000000..ad34f4e --- /dev/null +++ b/doxygen/classtransformers_1_1symbol__tree_1_1ModuleScope__inherit__graph.dot @@ -0,0 +1,10 @@ +digraph "transformers.symbol_tree.ModuleScope" +{ + // LATEX_PDF_SIZE + bgcolor="transparent"; + edge [fontname=Helvetica,fontsize=10,labelfontname=Helvetica,labelfontsize=10]; + node [fontname=Helvetica,fontsize=10,shape=box,height=0.2,width=0.4]; + Node1 [id="Node000001",label="transformers.symbol\l_tree.ModuleScope",height=0.2,width=0.4,color="gray40", fillcolor="grey60", style="filled", fontcolor="black",tooltip=" "]; + Node2 -> Node1 [id="edge1_Node000001_Node000002",dir="back",color="steelblue1",style="solid",tooltip=" "]; + Node2 [id="Node000002",label="transformers.symbol\l_tree.Scope",height=0.2,width=0.4,color="gray40", fillcolor="white", style="filled",URL="$classtransformers_1_1symbol__tree_1_1Scope.html",tooltip=" "]; +} diff --git a/doxygen/classtransformers_1_1symbol__tree_1_1Scope-members.html b/doxygen/classtransformers_1_1symbol__tree_1_1Scope-members.html new file mode 100644 index 0000000..a676002 --- /dev/null +++ b/doxygen/classtransformers_1_1symbol__tree_1_1Scope-members.html @@ -0,0 +1,117 @@ + + + + + + + +OMG-Fuscator: Member List + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
transformers.symbol_tree.Scope Member List
+
+ +
+ + + + diff --git a/doxygen/classtransformers_1_1symbol__tree_1_1Scope.html b/doxygen/classtransformers_1_1symbol__tree_1_1Scope.html new file mode 100644 index 0000000..c8b035c --- /dev/null +++ b/doxygen/classtransformers_1_1symbol__tree_1_1Scope.html @@ -0,0 +1,428 @@ + + + + + + + +OMG-Fuscator: transformers.symbol_tree.Scope Class Reference + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
transformers.symbol_tree.Scope Class Reference
+
+
+
+ + Inheritance diagram for transformers.symbol_tree.Scope:
+
+
+ + + + + + + + + + + + + + + +

+Public Member Functions

 __init__ (self, str name, str scope_type, ast.AST node=None)
 
 __repr__ (self)
 
'Scopeadd_child_scope (self, 'Scope' scope)
 
Symbol add_symbol (self, Symbol symbol)
 
str get_qualified_name (self)
 
Optional[Symbollookup (self, str name)
 
+ + + + + + + +

+Public Attributes

 name
 
 node
 
 scope_type
 
+

Detailed Description

+
Represents a scope in the code, such as a module, function, class, or comprehension.
+
+

Definition at line 54 of file symbol_tree.py.

+

Constructor & Destructor Documentation

+ +

◆ __init__()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
transformers.symbol_tree.Scope.__init__ ( self,
str name,
str scope_type,
ast.AST  node = None 
)
+
+ +

Reimplemented in transformers.symbol_tree.ClassScope, and transformers.symbol_tree.ModuleScope.

+ +

Definition at line 58 of file symbol_tree.py.

+
58 def __init__(self, name: str, scope_type: str, node: ast.AST = None):
+
59 self.name = name
+
60 self.scope_type = scope_type
+
61 self.node = node
+
62
+
63 # Maps: symbol name -> Symbol object
+
64 self.symbols: Dict[str, Symbol] = {}
+
65
+
66 # Child scopes within this scope
+
67 self.children: List['Scope'] = []
+
68
+
69 # Parent scope (None for the global/module scope)
+
70 self.parent: Optional['Scope'] = None
+
71
+
+
+
+

Member Function Documentation

+ +

◆ __repr__()

+ +
+
+ + + + + + + + +
transformers.symbol_tree.Scope.__repr__ ( self)
+
+ +

Definition at line 98 of file symbol_tree.py.

+
98 def __repr__(self):
+
99 return f"<Scope {self.get_qualified_name()} [{self.scope_type}] symbols:{len(self.symbols)} children:{len(self.children)}>"
+
100
+
101
+
+
+
+ +

◆ add_child_scope()

+ +
+
+ + + + + + + + + + + + + + + + + + +
'Scope' transformers.symbol_tree.Scope.add_child_scope ( self,
'Scopescope 
)
+
+
Add a child scope to this scope and return it.
+

Definition at line 78 of file symbol_tree.py.

+
78 def add_child_scope(self, scope: 'Scope') -> 'Scope':
+
79 """Add a child scope to this scope and return it."""
+
80 self.children.append(scope)
+
81 scope.parent = self
+
82 return scope
+
83
+
+
+
+ +

◆ add_symbol()

+ +
+
+ + + + + + + + + + + + + + + + + + +
Symbol transformers.symbol_tree.Scope.add_symbol ( self,
Symbol symbol 
)
+
+
Add a symbol to this scope and return it.
+

Definition at line 72 of file symbol_tree.py.

+
72 def add_symbol(self, symbol: Symbol) -> Symbol:
+
73 """Add a symbol to this scope and return it."""
+
74 self.symbols[symbol.name] = symbol
+
75 symbol.parent = self
+
76 return symbol
+
77
+
+

Referenced by transformers.symbol_tree.ClassScope.add_attribute(), and transformers.symbol_tree.ClassScope.add_method().

+ +
+
+ +

◆ get_qualified_name()

+ +
+
+ + + + + + + + +
str transformers.symbol_tree.Scope.get_qualified_name ( self)
+
+
Get the fully qualified name of this scope.
+

Definition at line 92 of file symbol_tree.py.

+
92 def get_qualified_name(self) -> str:
+
93 """Get the fully qualified name of this scope."""
+
94 if self.parent and self.parent.name:
+
95 return f"{self.parent.get_qualified_name()}.{self.name}"
+
96 return self.name
+
97
+
+

References transformers.symbol_tree.Symbol.name, and transformers.symbol_tree.Scope.name.

+ +
+
+ +

◆ lookup()

+ +
+
+ + + + + + + + + + + + + + + + + + +
Optional[Symbol] transformers.symbol_tree.Scope.lookup ( self,
str name 
)
+
+
Look up a symbol in this scope, or in parent scopes.
+

Definition at line 84 of file symbol_tree.py.

+
84 def lookup(self, name: str) -> Optional[Symbol]:
+
85 """Look up a symbol in this scope, or in parent scopes."""
+
86 if name in self.symbols:
+
87 return self.symbols[name]
+
88 elif self.parent:
+
89 return self.parent.lookup(name)
+
90 return None
+
91
+
+

References transformers.symbol_tree.Scope.lookup().

+ +

Referenced by transformers.symbol_tree.Scope.lookup().

+ +
+
+

Member Data Documentation

+ +

◆ name

+ +
+
+ + + + +
transformers.symbol_tree.Scope.name
+
+ +

Definition at line 59 of file symbol_tree.py.

+ +

Referenced by transformers.symbol_tree.Scope.get_qualified_name().

+ +
+
+ +

◆ node

+ +
+
+ + + + +
transformers.symbol_tree.Scope.node
+
+ +

Definition at line 61 of file symbol_tree.py.

+ +
+
+ +

◆ scope_type

+ +
+
+ + + + +
transformers.symbol_tree.Scope.scope_type
+
+ +

Definition at line 60 of file symbol_tree.py.

+ +
+
+
The documentation for this class was generated from the following file: +
+
+ + + + diff --git a/doxygen/classtransformers_1_1symbol__tree_1_1Scope.js b/doxygen/classtransformers_1_1symbol__tree_1_1Scope.js new file mode 100644 index 0000000..c17a612 --- /dev/null +++ b/doxygen/classtransformers_1_1symbol__tree_1_1Scope.js @@ -0,0 +1,12 @@ +var classtransformers_1_1symbol__tree_1_1Scope = +[ + [ "__init__", "classtransformers_1_1symbol__tree_1_1Scope.html#a46787477db922894246fecb5c12486b4", null ], + [ "__repr__", "classtransformers_1_1symbol__tree_1_1Scope.html#af3b53a662c490b6d028b629d05661f08", null ], + [ "add_child_scope", "classtransformers_1_1symbol__tree_1_1Scope.html#a0081ee771c31639c01b2b1da2616100c", null ], + [ "add_symbol", "classtransformers_1_1symbol__tree_1_1Scope.html#abfdd86fbdb9eb9f43e59407433981217", null ], + [ "get_qualified_name", "classtransformers_1_1symbol__tree_1_1Scope.html#a72bf2569e37369e3f845ac2441080a9d", null ], + [ "lookup", "classtransformers_1_1symbol__tree_1_1Scope.html#aea26fa0ade2ce3d7f82cf28a7fec0d16", null ], + [ "name", "classtransformers_1_1symbol__tree_1_1Scope.html#ab08134920b738ab813bcd04724cc3696", null ], + [ "node", "classtransformers_1_1symbol__tree_1_1Scope.html#a51ed89fe0be033cd0643a4d943a1f12b", null ], + [ "scope_type", "classtransformers_1_1symbol__tree_1_1Scope.html#afcd5b42c282fac61354d80897b5c751e", null ] +]; \ No newline at end of file diff --git a/doxygen/classtransformers_1_1symbol__tree_1_1Scope__inherit__graph.dot b/doxygen/classtransformers_1_1symbol__tree_1_1Scope__inherit__graph.dot new file mode 100644 index 0000000..5f852da --- /dev/null +++ b/doxygen/classtransformers_1_1symbol__tree_1_1Scope__inherit__graph.dot @@ -0,0 +1,12 @@ +digraph "transformers.symbol_tree.Scope" +{ + // LATEX_PDF_SIZE + bgcolor="transparent"; + edge [fontname=Helvetica,fontsize=10,labelfontname=Helvetica,labelfontsize=10]; + node [fontname=Helvetica,fontsize=10,shape=box,height=0.2,width=0.4]; + Node1 [id="Node000001",label="transformers.symbol\l_tree.Scope",height=0.2,width=0.4,color="gray40", fillcolor="grey60", style="filled", fontcolor="black",tooltip=" "]; + Node1 -> Node2 [id="edge1_Node000001_Node000002",dir="back",color="steelblue1",style="solid",tooltip=" "]; + Node2 [id="Node000002",label="transformers.symbol\l_tree.ClassScope",height=0.2,width=0.4,color="gray40", fillcolor="white", style="filled",URL="$classtransformers_1_1symbol__tree_1_1ClassScope.html",tooltip=" "]; + Node1 -> Node3 [id="edge2_Node000001_Node000003",dir="back",color="steelblue1",style="solid",tooltip=" "]; + Node3 [id="Node000003",label="transformers.symbol\l_tree.ModuleScope",height=0.2,width=0.4,color="gray40", fillcolor="white", style="filled",URL="$classtransformers_1_1symbol__tree_1_1ModuleScope.html",tooltip=" "]; +} diff --git a/doxygen/classtransformers_1_1symbol__tree_1_1Symbol-members.html b/doxygen/classtransformers_1_1symbol__tree_1_1Symbol-members.html new file mode 100644 index 0000000..fd46a34 --- /dev/null +++ b/doxygen/classtransformers_1_1symbol__tree_1_1Symbol-members.html @@ -0,0 +1,116 @@ + + + + + + + +OMG-Fuscator: Member List + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
transformers.symbol_tree.Symbol Member List
+
+ +
+ + + + diff --git a/doxygen/classtransformers_1_1symbol__tree_1_1Symbol.html b/doxygen/classtransformers_1_1symbol__tree_1_1Symbol.html new file mode 100644 index 0000000..bbea586 --- /dev/null +++ b/doxygen/classtransformers_1_1symbol__tree_1_1Symbol.html @@ -0,0 +1,337 @@ + + + + + + + +OMG-Fuscator: transformers.symbol_tree.Symbol Class Reference + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
transformers.symbol_tree.Symbol Class Reference
+
+
+ + + + + + + + +

+Public Member Functions

 __init__ (self, str name, SymbolType symbol_type, ast.AST node=None)
 
 __repr__ (self)
 
 add_reference (self, ast.AST node)
 
+ + + + + + + + + + + +

+Public Attributes

 is_imported
 
 is_obfuscatable
 
 name
 
 node
 
 symbol_type
 
+

Detailed Description

+
Represents a symbol in the code with its name, type and other metadata.
+

Definition at line 30 of file symbol_tree.py.

+

Constructor & Destructor Documentation

+ +

◆ __init__()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
transformers.symbol_tree.Symbol.__init__ ( self,
str name,
SymbolType symbol_type,
ast.AST  node = None 
)
+
+ +

Definition at line 33 of file symbol_tree.py.

+
33 def __init__(self, name: str, symbol_type: SymbolType, node: ast.AST = None):
+
34 self.name = name # Original name
+
35 self.obfuscated_name: Optional[str] = None # Obfuscated name (if assigned)
+
36 self.symbol_type = symbol_type
+
37 self.node = node # AST node where this symbol is defined
+
38 self.references: List[ast.AST] = [] # AST nodes where this symbol is referenced
+
39 self.parent: Optional['Scope'] = None # Parent scope
+
40 self.is_obfuscatable = True # Whether this symbol should be obfuscated
+
41
+
42 # Additional attributes for specific symbol types
+
43 self.is_imported = False # Whether this symbol was imported
+
44 self.original_module: Optional[str] = None # If imported, the module it was imported from
+
45
+
+
+
+

Member Function Documentation

+ +

◆ __repr__()

+ +
+
+ + + + + + + + +
transformers.symbol_tree.Symbol.__repr__ ( self)
+
+ +

Definition at line 50 of file symbol_tree.py.

+
50 def __repr__(self):
+
51 return f"<Symbol {self.name} [{self.symbol_type.value}] {'→ ' + self.obfuscated_name if self.obfuscated_name else ''} refs:{len(self.references)}>"
+
52
+
53
+
+
+
+ +

◆ add_reference()

+ +
+
+ + + + + + + + + + + + + + + + + + +
transformers.symbol_tree.Symbol.add_reference ( self,
ast.AST node 
)
+
+
Add a reference to this symbol.
+

Definition at line 46 of file symbol_tree.py.

+
46 def add_reference(self, node: ast.AST):
+
47 """Add a reference to this symbol."""
+
48 self.references.append(node)
+
49
+
+
+
+

Member Data Documentation

+ +

◆ is_imported

+ +
+
+ + + + +
transformers.symbol_tree.Symbol.is_imported
+
+ +

Definition at line 43 of file symbol_tree.py.

+ +
+
+ +

◆ is_obfuscatable

+ +
+
+ + + + +
transformers.symbol_tree.Symbol.is_obfuscatable
+
+ +

Definition at line 40 of file symbol_tree.py.

+ +
+
+ +

◆ name

+ +
+
+ + + + +
transformers.symbol_tree.Symbol.name
+
+ +

Definition at line 34 of file symbol_tree.py.

+ +

Referenced by transformers.symbol_tree.Scope.get_qualified_name().

+ +
+
+ +

◆ node

+ +
+
+ + + + +
transformers.symbol_tree.Symbol.node
+
+ +

Definition at line 37 of file symbol_tree.py.

+ +
+
+ +

◆ symbol_type

+ +
+
+ + + + +
transformers.symbol_tree.Symbol.symbol_type
+
+ +

Definition at line 36 of file symbol_tree.py.

+ +
+
+
The documentation for this class was generated from the following file: +
+
+ + + + diff --git a/doxygen/classtransformers_1_1symbol__tree_1_1Symbol.js b/doxygen/classtransformers_1_1symbol__tree_1_1Symbol.js new file mode 100644 index 0000000..58e162e --- /dev/null +++ b/doxygen/classtransformers_1_1symbol__tree_1_1Symbol.js @@ -0,0 +1,11 @@ +var classtransformers_1_1symbol__tree_1_1Symbol = +[ + [ "__init__", "classtransformers_1_1symbol__tree_1_1Symbol.html#a391a0c0a2d4a4a88690b287c2c0901a9", null ], + [ "__repr__", "classtransformers_1_1symbol__tree_1_1Symbol.html#ab98bc4a99007d752ce57d203a022706f", null ], + [ "add_reference", "classtransformers_1_1symbol__tree_1_1Symbol.html#a77426bdaaddd0c9a5f5cf2939af5e82d", null ], + [ "is_imported", "classtransformers_1_1symbol__tree_1_1Symbol.html#a83a7262213d2f81c6493a8a4daedb81a", null ], + [ "is_obfuscatable", "classtransformers_1_1symbol__tree_1_1Symbol.html#a6220ff5bd5621ab52c59a6b240eddd0d", null ], + [ "name", "classtransformers_1_1symbol__tree_1_1Symbol.html#ab704c166075e326fa3d0cc1d3cb3d48e", null ], + [ "node", "classtransformers_1_1symbol__tree_1_1Symbol.html#ac9a2c001371dbb1876e4d5eb2f618aed", null ], + [ "symbol_type", "classtransformers_1_1symbol__tree_1_1Symbol.html#aa4a20656cbca365de328bb0f33b89ff0", null ] +]; \ No newline at end of file diff --git a/doxygen/classtransformers_1_1symbol__tree_1_1SymbolTree-members.html b/doxygen/classtransformers_1_1symbol__tree_1_1SymbolTree-members.html new file mode 100644 index 0000000..bb47132 --- /dev/null +++ b/doxygen/classtransformers_1_1symbol__tree_1_1SymbolTree-members.html @@ -0,0 +1,119 @@ + + + + + + + +OMG-Fuscator: Member List + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
transformers.symbol_tree.SymbolTree Member List
+
+ +
+ + + + diff --git a/doxygen/classtransformers_1_1symbol__tree_1_1SymbolTree.html b/doxygen/classtransformers_1_1symbol__tree_1_1SymbolTree.html new file mode 100644 index 0000000..2ad805c --- /dev/null +++ b/doxygen/classtransformers_1_1symbol__tree_1_1SymbolTree.html @@ -0,0 +1,666 @@ + + + + + + + +OMG-Fuscator: transformers.symbol_tree.SymbolTree Class Reference + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
transformers.symbol_tree.SymbolTree Class Reference
+
+
+ + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 __init__ (self)
 
 add_reference (self, str name, ast.AST node)
 
Symbol add_symbol (self, str name, SymbolType symbol_type, ast.AST node=None)
 
 apply_name_generator (self, name_generator)
 
List[Dict] check_for_issues (self)
 
Dict[str, Dict[str, str]] get_rename_mapping (self)
 
Scope pop_scope (self)
 
Scope push_scope (self, str name, str scope_type, ast.AST node)
 
 resolve_inheritance (self)
 
+ + + + + +

+Public Attributes

 current_scope
 
 root_scope
 
+

Detailed Description

+
Global symbol tree that maintains a hierarchy of scopes and symbols
+across the entire codebase.
+
+

Definition at line 146 of file symbol_tree.py.

+

Constructor & Destructor Documentation

+ +

◆ __init__()

+ +
+
+ + + + + + + + +
transformers.symbol_tree.SymbolTree.__init__ ( self)
+
+ +

Definition at line 152 of file symbol_tree.py.

+
152 def __init__(self):
+
153 # The root scope is a special module scope named "__root__"
+
154 self.root_scope = ModuleScope("__root__", None)
+
155 # Current scope being processed
+
156 self.current_scope = self.root_scope
+
157 # Track classes for inheritance resolution
+
158 self.classes: Dict[str, ClassScope] = {}
+
159 # Track all symbols by their fully qualified name
+
160 self.all_symbols: Dict[str, Symbol] = {}
+
161 # Track imports for proper resolution
+
162 self.imports: Dict[str, str] = {} # alias -> module
+
163
+
+
+
+

Member Function Documentation

+ +

◆ add_reference()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
transformers.symbol_tree.SymbolTree.add_reference ( self,
str name,
ast.AST node 
)
+
+
Add a reference to a symbol.
+

Definition at line 210 of file symbol_tree.py.

+
210 def add_reference(self, name: str, node: ast.AST):
+
211 """Add a reference to a symbol."""
+
212 symbol = self.current_scope.lookup(name)
+
213 if symbol:
+
214 symbol.add_reference(node)
+
215
+
+

References transformers.symbol_tree.SymbolTree.current_scope.

+ +
+
+ +

◆ add_symbol()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Symbol transformers.symbol_tree.SymbolTree.add_symbol ( self,
str name,
SymbolType symbol_type,
ast.AST  node = None 
)
+
+
Add a symbol to the current scope.
+

Definition at line 192 of file symbol_tree.py.

+
192 def add_symbol(self, name: str, symbol_type: SymbolType, node: ast.AST = None) -> Symbol:
+
193 """Add a symbol to the current scope."""
+
194 symbol = Symbol(name, symbol_type, node)
+
195 self.current_scope.add_symbol(symbol)
+
196
+
197 # Track in the global map
+
198 qualified_name = f"{self.current_scope.get_qualified_name()}.{name}"
+
199 self.all_symbols[qualified_name] = symbol
+
200
+
201 # If this is a method in a class scope
+
202 if symbol_type == SymbolType.METHOD and isinstance(self.current_scope, ClassScope):
+
203 self.current_scope.add_method(symbol)
+
204 # If this is an attribute in a class scope
+
205 elif symbol_type == SymbolType.ATTRIBUTE and isinstance(self.current_scope, ClassScope):
+
206 self.current_scope.add_attribute(symbol)
+
207
+
208 return symbol
+
209
+
+

References transformers.symbol_tree.SymbolTree.add_symbol(), and transformers.symbol_tree.SymbolTree.current_scope.

+ +

Referenced by transformers.symbol_tree.ClassScope.add_attribute(), transformers.symbol_tree.ClassScope.add_method(), and transformers.symbol_tree.SymbolTree.add_symbol().

+ +
+
+ +

◆ apply_name_generator()

+ +
+
+ + + + + + + + + + + + + + + + + + +
transformers.symbol_tree.SymbolTree.apply_name_generator ( self,
 name_generator 
)
+
+
Apply a name generator to all symbols that need obfuscation.
+Ensures consistent renaming across the entire codebase.
+
+

Definition at line 297 of file symbol_tree.py.

+
297 def apply_name_generator(self, name_generator):
+
298 """
+
299 Apply a name generator to all symbols that need obfuscation.
+
300 Ensures consistent renaming across the entire codebase.
+
301 """
+
302 # First, handle classes
+
303 for class_scope in self.classes.values():
+
304 class_symbol = self.current_scope.lookup(class_scope.name)
+
305 if class_symbol and class_symbol.is_obfuscatable:
+
306 class_symbol.obfuscated_name = name_generator.generate_name()
+
307
+
308 # Then handle methods to ensure consistency across inheritance
+
309 self.resolve_inheritance()
+
310
+
311 # Apply to all other symbols
+
312 for symbol in self.all_symbols.values():
+
313 # Skip if already obfuscated or not obfuscatable
+
314 if symbol.obfuscated_name or not symbol.is_obfuscatable:
+
315 continue
+
316
+
317 # Skip special names
+
318 if symbol.name.startswith("__") and symbol.name.endswith("__"):
+
319 continue
+
320
+
321 symbol.obfuscated_name = name_generator.generate_name()
+
322
+
+

References transformers.symbol_tree.SymbolTree.current_scope, and transformers.symbol_tree.SymbolTree.resolve_inheritance().

+ +
+
+ +

◆ check_for_issues()

+ +
+
+ + + + + + + + +
List[Dict] transformers.symbol_tree.SymbolTree.check_for_issues ( self)
+
+
Check for potential issues in the symbol tree.
+

Definition at line 255 of file symbol_tree.py.

+
255 def check_for_issues(self) -> List[Dict]:
+
256 """Check for potential issues in the symbol tree."""
+
257 issues = []
+
258
+
259 # Check for duplicated obfuscated names
+
260 obfuscated_names = {}
+
261 for qualified_name, symbol in self.all_symbols.items():
+
262 if not symbol.obfuscated_name:
+
263 continue
+
264
+
265 if symbol.obfuscated_name in obfuscated_names:
+
266 issues.append({
+
267 "type": "duplicate_obfuscated_name",
+
268 "obfuscated_name": symbol.obfuscated_name,
+
269 "symbols": [qualified_name, obfuscated_names[symbol.obfuscated_name]]
+
270 })
+
271 else:
+
272 obfuscated_names[symbol.obfuscated_name] = qualified_name
+
273
+
274 # Check for inconsistent method obfuscation in inheritance hierarchies
+
275 for class_name, class_scope in self.classes.items():
+
276 for base_name in class_scope.base_classes:
+
277 if base_name not in self.classes:
+
278 continue
+
279
+
280 base_scope = self.classes[base_name]
+
281 for method_name, method_symbol in base_scope.methods.items():
+
282 if method_name in class_scope.methods:
+
283 derived_method = class_scope.methods[method_name]
+
284 if (method_symbol.obfuscated_name and derived_method.obfuscated_name and
+
285 method_symbol.obfuscated_name != derived_method.obfuscated_name):
+
286 issues.append({
+
287 "type": "inconsistent_method_obfuscation",
+
288 "method_name": method_name,
+
289 "base_class": base_name,
+
290 "derived_class": class_name,
+
291 "base_obfuscated": method_symbol.obfuscated_name,
+
292 "derived_obfuscated": derived_method.obfuscated_name
+
293 })
+
294
+
295 return issues
+
296
+
+
+
+ +

◆ get_rename_mapping()

+ +
+
+ + + + + + + + +
Dict[str, Dict[str, str]] transformers.symbol_tree.SymbolTree.get_rename_mapping ( self)
+
+
Get a mapping for all symbols to their obfuscated names,
+organized by symbol type for use in transformers.
+
+

Definition at line 323 of file symbol_tree.py.

+
323 def get_rename_mapping(self) -> Dict[str, Dict[str, str]]:
+
324 """
+
325 Get a mapping for all symbols to their obfuscated names,
+
326 organized by symbol type for use in transformers.
+
327 """
+
328 mapping = {
+
329 "variables": {},
+
330 "functions": {},
+
331 "classes": {},
+
332 "methods": {},
+
333 "attributes": {}
+
334 }
+
335
+
336 for symbol in self.all_symbols.values():
+
337 if not symbol.obfuscated_name:
+
338 continue
+
339
+
340 if symbol.symbol_type == SymbolType.VARIABLE:
+
341 mapping["variables"][symbol.name] = symbol.obfuscated_name
+
342 elif symbol.symbol_type == SymbolType.FUNCTION:
+
343 mapping["functions"][symbol.name] = symbol.obfuscated_name
+
344 elif symbol.symbol_type == SymbolType.CLASS:
+
345 mapping["classes"][symbol.name] = symbol.obfuscated_name
+
346 elif symbol.symbol_type == SymbolType.METHOD:
+
347 # For methods, we need the class name
+
348 if isinstance(symbol.parent, ClassScope):
+
349 class_name = symbol.parent.name
+
350 if class_name not in mapping["methods"]:
+
351 mapping["methods"][class_name] = {}
+
352 mapping["methods"][class_name][symbol.name] = symbol.obfuscated_name
+
353 elif symbol.symbol_type == SymbolType.ATTRIBUTE:
+
354 # For attributes, we need the class name
+
355 if isinstance(symbol.parent, ClassScope):
+
356 class_name = symbol.parent.name
+
357 if class_name not in mapping["attributes"]:
+
358 mapping["attributes"][class_name] = {}
+
359 mapping["attributes"][class_name][symbol.name] = symbol.obfuscated_name
+
360
+
361 return mapping
+
362
+
363
+
+
+
+ +

◆ pop_scope()

+ +
+
+ + + + + + + + +
Scope transformers.symbol_tree.SymbolTree.pop_scope ( self)
+
+
Exit the current scope and return to its parent.
+

Definition at line 185 of file symbol_tree.py.

+
185 def pop_scope(self) -> Scope:
+
186 """Exit the current scope and return to its parent."""
+
187 old_scope = self.current_scope
+
188 if self.current_scope.parent:
+
189 self.current_scope = self.current_scope.parent
+
190 return old_scope
+
191
+
+

References transformers.symbol_tree.SymbolTree.current_scope.

+ +
+
+ +

◆ push_scope()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Scope transformers.symbol_tree.SymbolTree.push_scope ( self,
str name,
str scope_type,
ast.AST node 
)
+
+
Create a new scope and make it the current scope.
+

Definition at line 164 of file symbol_tree.py.

+
164 def push_scope(self, name: str, scope_type: str, node: ast.AST) -> Scope:
+
165 """Create a new scope and make it the current scope."""
+
166 if scope_type == "class":
+
167 new_scope = ClassScope(name, node)
+
168 elif scope_type == "module":
+
169 new_scope = ModuleScope(name, node)
+
170 else:
+
171 new_scope = Scope(name, scope_type, node)
+
172
+
173 self.current_scope.add_child_scope(new_scope)
+
174 self.current_scope = new_scope
+
175
+
176 # If this is a class, track it
+
177 if scope_type == "class":
+
178 fully_qualified = new_scope.get_qualified_name()
+
179 self.classes[fully_qualified] = new_scope
+
180 # Also track with just the class name for simpler lookups
+
181 self.classes[name] = new_scope
+
182
+
183 return new_scope
+
184
+
+

References transformers.symbol_tree.SymbolTree.current_scope.

+ +
+
+ +

◆ resolve_inheritance()

+ +
+
+ + + + + + + + +
transformers.symbol_tree.SymbolTree.resolve_inheritance ( self)
+
+
Resolve inheritance relationships between classes to ensure
+consistent method and attribute renaming.
+
+

Definition at line 216 of file symbol_tree.py.

+
216 def resolve_inheritance(self):
+
217 """
+
218 Resolve inheritance relationships between classes to ensure
+
219 consistent method and attribute renaming.
+
220 """
+
221 def resolve_class(class_scope: ClassScope, visited=None):
+
222 if visited is None:
+
223 visited = set()
+
224
+
225 # Skip if already visited to prevent infinite recursion
+
226 if class_scope.name in visited:
+
227 return
+
228 visited.add(class_scope.name)
+
229
+
230 # Process each base class
+
231 for base_name in class_scope.base_classes:
+
232 # Skip if the base class is not in our tree (e.g., external library)
+
233 if base_name not in self.classes:
+
234 continue
+
235
+
236 base_scope = self.classes[base_name]
+
237 # Resolve the base class first
+
238 resolve_class(base_scope, visited)
+
239
+
240 # Copy method symbols from base to derived if not overridden
+
241 for method_name, method_symbol in base_scope.methods.items():
+
242 if method_name not in class_scope.methods:
+
243 # Create a new symbol in the derived class that references the base class method
+
244 derived_method = Symbol(method_name, SymbolType.METHOD)
+
245 class_scope.add_method(derived_method)
+
246
+
247 # Use the same obfuscated name as the base class method
+
248 # (even if the base class method hasn't been obfuscated yet)
+
249 derived_method.obfuscated_name = method_symbol.obfuscated_name
+
250
+
251 # Process all classes
+
252 for class_scope in self.classes.values():
+
253 resolve_class(class_scope)
+
254
+
+

Referenced by transformers.symbol_tree.SymbolTree.apply_name_generator().

+ +
+
+

Member Data Documentation

+ +

◆ current_scope

+ + + +

◆ root_scope

+ +
+
+ + + + +
transformers.symbol_tree.SymbolTree.root_scope
+
+ +

Definition at line 154 of file symbol_tree.py.

+ +
+
+
The documentation for this class was generated from the following file: +
+
+ + + + diff --git a/doxygen/classtransformers_1_1symbol__tree_1_1SymbolTree.js b/doxygen/classtransformers_1_1symbol__tree_1_1SymbolTree.js new file mode 100644 index 0000000..fb55c05 --- /dev/null +++ b/doxygen/classtransformers_1_1symbol__tree_1_1SymbolTree.js @@ -0,0 +1,14 @@ +var classtransformers_1_1symbol__tree_1_1SymbolTree = +[ + [ "__init__", "classtransformers_1_1symbol__tree_1_1SymbolTree.html#ae5a94636b396b77c05857572823b1285", null ], + [ "add_reference", "classtransformers_1_1symbol__tree_1_1SymbolTree.html#ab45a75613adc005d160afbc3a5d4034c", null ], + [ "add_symbol", "classtransformers_1_1symbol__tree_1_1SymbolTree.html#a059c692815d67b54786eeae7a69a699d", null ], + [ "apply_name_generator", "classtransformers_1_1symbol__tree_1_1SymbolTree.html#ab21d8bdd7653df8f0cddf0fbb1f916b2", null ], + [ "check_for_issues", "classtransformers_1_1symbol__tree_1_1SymbolTree.html#a5a585fa57a9f8fd224cf4d55b8180a78", null ], + [ "get_rename_mapping", "classtransformers_1_1symbol__tree_1_1SymbolTree.html#aad251f8dde7939c5194c6cfc4caf62a5", null ], + [ "pop_scope", "classtransformers_1_1symbol__tree_1_1SymbolTree.html#ac3622dfd3cf0c24f591974f4daf542b7", null ], + [ "push_scope", "classtransformers_1_1symbol__tree_1_1SymbolTree.html#a552a46afd0e3e2eed55366a9d0b037b6", null ], + [ "resolve_inheritance", "classtransformers_1_1symbol__tree_1_1SymbolTree.html#af5a83401d437658d233d32f15071305c", null ], + [ "current_scope", "classtransformers_1_1symbol__tree_1_1SymbolTree.html#ab61ebd1549ee934fa7e468407a410b14", null ], + [ "root_scope", "classtransformers_1_1symbol__tree_1_1SymbolTree.html#a69923f85f26cb752607ec256796647be", null ] +]; \ No newline at end of file diff --git a/doxygen/classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder-members.html b/doxygen/classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder-members.html new file mode 100644 index 0000000..174c005 --- /dev/null +++ b/doxygen/classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder-members.html @@ -0,0 +1,125 @@ + + + + + + + +OMG-Fuscator: Member List + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
transformers.symbol_tree.SymbolTreeBuilder Member List
+
+ +
+ + + + diff --git a/doxygen/classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html b/doxygen/classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html new file mode 100644 index 0000000..0d2f0a2 --- /dev/null +++ b/doxygen/classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html @@ -0,0 +1,827 @@ + + + + + + + +OMG-Fuscator: transformers.symbol_tree.SymbolTreeBuilder Class Reference + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
transformers.symbol_tree.SymbolTreeBuilder Class Reference
+
+
+
+ + Inheritance diagram for transformers.symbol_tree.SymbolTreeBuilder:
+
+
+ +
+ + Collaboration diagram for transformers.symbol_tree.SymbolTreeBuilder:
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 __init__ (self)
 
SymbolTree build_tree (self, ast.AST tree)
 
 visit_arguments (self, ast.arguments node)
 
 visit_Assign (self, ast.Assign node)
 
 visit_Attribute (self, ast.Attribute node)
 
 visit_attribute_assignment (self, ast.Attribute node)
 
 visit_ClassDef (self, ast.ClassDef node)
 
 visit_FunctionDef (self, ast.FunctionDef node)
 
 visit_Import (self, ast.Import node)
 
 visit_ImportFrom (self, ast.ImportFrom node)
 
 visit_Module (self, ast.Module node)
 
 visit_Name (self, ast.Name node)
 
+ + + + + + + + + + + +

+Public Attributes

 current_class
 
 current_function_args
 
 in_attribute_ctx
 
 in_class_def
 
 tree
 
+

Detailed Description

+
Builds a symbol tree by visiting all nodes in the AST.
+
+

Definition at line 364 of file symbol_tree.py.

+

Constructor & Destructor Documentation

+ +

◆ __init__()

+ +
+
+ + + + + + + + +
transformers.symbol_tree.SymbolTreeBuilder.__init__ ( self)
+
+ +

Definition at line 369 of file symbol_tree.py.

+
369 def __init__(self):
+
370 self.tree = SymbolTree()
+
371
+
372 # Track whether we're in a class definition
+
373 self.in_class_def = False
+
374 self.current_class = None
+
375
+
376 # Track function augments to avoid creating symbols for them twice
+
377 self.current_function_args = set()
+
378
+
379 # Track whether we're in an attribute context
+
380 self.in_attribute_ctx = False
+
381
+
+
+
+

Member Function Documentation

+ +

◆ build_tree()

+ +
+
+ + + + + + + + + + + + + + + + + + +
SymbolTree transformers.symbol_tree.SymbolTreeBuilder.build_tree ( self,
ast.AST tree 
)
+
+
Build the symbol tree from the AST.
+

Definition at line 553 of file symbol_tree.py.

+
553 def build_tree(self, tree: ast.AST) -> SymbolTree:
+
554 """Build the symbol tree from the AST."""
+
555 self.visit(tree)
+
556 # Perform final processing
+
557 self.tree.resolve_inheritance()
+
558 return self.tree
+
+

References transformers.symbol_tree.SymbolTreeBuilder.tree.

+ +
+
+ +

◆ visit_arguments()

+ +
+
+ + + + + + + + + + + + + + + + + + +
transformers.symbol_tree.SymbolTreeBuilder.visit_arguments ( self,
ast.arguments node 
)
+
+
Process function arguments.
+

Definition at line 446 of file symbol_tree.py.

+
446 def visit_arguments(self, node: ast.arguments):
+
447 """Process function arguments."""
+
448 # Process positional arguments
+
449 for arg in node.args:
+
450 self.current_function_args.add(arg.arg)
+
451 self.tree.add_symbol(arg.arg, SymbolType.ARGUMENT, arg)
+
452
+
453 # Process vararg (e.g., *args)
+
454 if node.vararg:
+
455 self.current_function_args.add(node.vararg.arg)
+
456 self.tree.add_symbol(node.vararg.arg, SymbolType.ARGUMENT, node.vararg)
+
457
+
458 # Process keyword arguments
+
459 for kwarg in node.kwonlyargs:
+
460 self.current_function_args.add(kwarg.arg)
+
461 self.tree.add_symbol(kwarg.arg, SymbolType.ARGUMENT, kwarg)
+
462
+
463 # Process kwarg (e.g., **kwargs)
+
464 if node.kwarg:
+
465 self.current_function_args.add(node.kwarg.arg)
+
466 self.tree.add_symbol(node.kwarg.arg, SymbolType.ARGUMENT, node.kwarg)
+
467
+
+

References transformers.symbol_tree.SymbolTreeBuilder.current_function_args, and transformers.symbol_tree.SymbolTreeBuilder.tree.

+ +
+
+ +

◆ visit_Assign()

+ +
+
+ + + + + + + + + + + + + + + + + + +
transformers.symbol_tree.SymbolTreeBuilder.visit_Assign ( self,
ast.Assign node 
)
+
+
Process an assignment statement.
+

Definition at line 468 of file symbol_tree.py.

+
468 def visit_Assign(self, node: ast.Assign):
+
469 """Process an assignment statement."""
+
470 # Visit the right side first to capture any variable references
+
471 self.visit(node.value)
+
472
+
473 # Now visit the targets (left-hand side)
+
474 for target in node.targets:
+
475 # Handle attribute assignment (e.g., self.x = value)
+
476 if isinstance(target, ast.Attribute):
+
477 self.visit_attribute_assignment(target)
+
478 # Handle simple name assignment
+
479 elif isinstance(target, ast.Name):
+
480 # Only add symbol if it's not already a function argument
+
481 if target.id not in self.current_function_args:
+
482 self.tree.add_symbol(target.id, SymbolType.VARIABLE, target)
+
483 # Handle other target types (e.g., subscripts, tuples)
+
484 else:
+
485 self.visit(target)
+
486
+
+

References transformers.symbol_tree.SymbolTreeBuilder.current_function_args, transformers.symbol_tree.SymbolTreeBuilder.tree, and transformers.symbol_tree.SymbolTreeBuilder.visit_attribute_assignment().

+ +
+
+ +

◆ visit_Attribute()

+ +
+
+ + + + + + + + + + + + + + + + + + +
transformers.symbol_tree.SymbolTreeBuilder.visit_Attribute ( self,
ast.Attribute node 
)
+
+
Process attribute access (e.g., obj.attr).
+

Definition at line 504 of file symbol_tree.py.

+
504 def visit_Attribute(self, node: ast.Attribute):
+
505 """Process attribute access (e.g., obj.attr)."""
+
506 # Track that we're in an attribute context
+
507 prev_in_attribute_ctx = self.in_attribute_ctx
+
508 self.in_attribute_ctx = True
+
509
+
510 # Visit the left side
+
511 self.visit(node.value)
+
512
+
513 # Handle self.attr access in a class
+
514 if (isinstance(node.value, ast.Name) and node.value.id == 'self'
+
515 and self.in_class_def and self.current_class):
+
516 # The attribute might be accessed before it's assigned, so we need to ensure it's in the symbol table
+
517 class_scope = self.tree.classes.get(self.current_class)
+
518 if class_scope and node.attr not in class_scope.attributes:
+
519 self.tree.add_symbol(node.attr, SymbolType.ATTRIBUTE, node)
+
520
+
521 # Restore previous state
+
522 self.in_attribute_ctx = prev_in_attribute_ctx
+
523
+
+

References transformers.attribute_transformer.AttributeTransformer.current_class, transformers.class_analyzer.ClassAnalyzer.current_class, transformers.class_mapper.ClassMapAnalyzer.current_class, transformers.class_mapper.ClassTransformer.current_class, transformers.symbol_tree.SymbolTreeBuilder.current_class, transformers.symbol_tree.SymbolTreeBuilder.in_attribute_ctx, transformers.symbol_tree.SymbolTreeBuilder.in_class_def, and transformers.symbol_tree.SymbolTreeBuilder.tree.

+ +
+
+ +

◆ visit_attribute_assignment()

+ +
+
+ + + + + + + + + + + + + + + + + + +
transformers.symbol_tree.SymbolTreeBuilder.visit_attribute_assignment ( self,
ast.Attribute node 
)
+
+
Process attribute assignment (e.g., self.x = value).
+

Definition at line 487 of file symbol_tree.py.

+
487 def visit_attribute_assignment(self, node: ast.Attribute):
+
488 """Process attribute assignment (e.g., self.x = value)."""
+
489 # Check if this is a self.attr assignment in a class
+
490 if (isinstance(node.value, ast.Name) and node.value.id == 'self'
+
491 and self.in_class_def and self.current_class):
+
492 # Add attribute to the current class
+
493 self.tree.add_symbol(node.attr, SymbolType.ATTRIBUTE, node)
+
494 else:
+
495 # Visit the left side to capture any variable references
+
496 self.visit(node.value)
+
497
+
+

References transformers.attribute_transformer.AttributeTransformer.current_class, transformers.class_analyzer.ClassAnalyzer.current_class, transformers.class_mapper.ClassMapAnalyzer.current_class, transformers.class_mapper.ClassTransformer.current_class, transformers.symbol_tree.SymbolTreeBuilder.current_class, transformers.symbol_tree.SymbolTreeBuilder.in_class_def, and transformers.symbol_tree.SymbolTreeBuilder.tree.

+ +

Referenced by transformers.symbol_tree.SymbolTreeBuilder.visit_Assign().

+ +
+
+ +

◆ visit_ClassDef()

+ +
+
+ + + + + + + + + + + + + + + + + + +
transformers.symbol_tree.SymbolTreeBuilder.visit_ClassDef ( self,
ast.ClassDef node 
)
+
+
Process a class definition.
+

Definition at line 390 of file symbol_tree.py.

+
390 def visit_ClassDef(self, node: ast.ClassDef):
+
391 """Process a class definition."""
+
392 # Create a new class scope
+
393 class_scope = self.tree.push_scope(node.name, "class", node)
+
394
+
395 # Add class to current scope's symbols
+
396 self.tree.add_symbol(node.name, SymbolType.CLASS, node)
+
397
+
398 # Track base classes
+
399 for base in node.bases:
+
400 if isinstance(base, ast.Name):
+
401 class_scope.add_base_class(base.id)
+
402 # Track reference to the base class
+
403 self.tree.add_reference(base.id, base)
+
404
+
405 # Save previous state and update current state
+
406 prev_in_class = self.in_class_def
+
407 prev_class = self.current_class
+
408 self.in_class_def = True
+
409 self.current_class = node.name
+
410
+
411 # Visit class body
+
412 for item in node.body:
+
413 self.visit(item)
+
414
+
415 # Restore previous state
+
416 self.in_class_def = prev_in_class
+
417 self.current_class = prev_class
+
418
+
419 # Exit class scope
+
420 self.tree.pop_scope()
+
421
+
+

References transformers.attribute_transformer.AttributeTransformer.current_class, transformers.class_analyzer.ClassAnalyzer.current_class, transformers.class_mapper.ClassMapAnalyzer.current_class, transformers.class_mapper.ClassTransformer.current_class, transformers.symbol_tree.SymbolTreeBuilder.current_class, transformers.symbol_tree.SymbolTreeBuilder.in_class_def, and transformers.symbol_tree.SymbolTreeBuilder.tree.

+ +
+
+ +

◆ visit_FunctionDef()

+ +
+
+ + + + + + + + + + + + + + + + + + +
transformers.symbol_tree.SymbolTreeBuilder.visit_FunctionDef ( self,
ast.FunctionDef node 
)
+
+
Process a function definition.
+

Definition at line 422 of file symbol_tree.py.

+
422 def visit_FunctionDef(self, node: ast.FunctionDef):
+
423 """Process a function definition."""
+
424 # Determine if this is a method or a regular function
+
425 symbol_type = SymbolType.METHOD if self.in_class_def else SymbolType.FUNCTION
+
426
+
427 # Add function/method to current scope's symbols
+
428 self.tree.add_symbol(node.name, symbol_type, node)
+
429
+
430 # Create a new function scope
+
431 self.tree.push_scope(node.name, "function", node)
+
432
+
433 # Clear current function arguments set
+
434 self.current_function_args = set()
+
435
+
436 # Process arguments
+
437 self.visit(node.args)
+
438
+
439 # Visit function body
+
440 for item in node.body:
+
441 self.visit(item)
+
442
+
443 # Exit function scope
+
444 self.tree.pop_scope()
+
445
+
+

References transformers.symbol_tree.SymbolTreeBuilder.current_function_args, transformers.symbol_tree.SymbolTreeBuilder.in_class_def, and transformers.symbol_tree.SymbolTreeBuilder.tree.

+ +
+
+ +

◆ visit_Import()

+ +
+
+ + + + + + + + + + + + + + + + + + +
transformers.symbol_tree.SymbolTreeBuilder.visit_Import ( self,
ast.Import node 
)
+
+
Process an import statement.
+

Definition at line 524 of file symbol_tree.py.

+
524 def visit_Import(self, node: ast.Import):
+
525 """Process an import statement."""
+
526 for item in node.names:
+
527 # The imported name should not be obfuscated
+
528 symbol = self.tree.add_symbol(item.asname or item.name, SymbolType.IMPORT, node)
+
529 symbol.is_obfuscatable = False
+
530 symbol.is_imported = True
+
531
+
532 # Track the import
+
533 if isinstance(self.tree.current_scope, ModuleScope):
+
534 module_scope = self.tree.current_scope
+
535 module_scope.add_import(item.asname or item.name, item.name)
+
536
+
+

References transformers.symbol_tree.SymbolTreeBuilder.tree.

+ +
+
+ +

◆ visit_ImportFrom()

+ +
+
+ + + + + + + + + + + + + + + + + + +
transformers.symbol_tree.SymbolTreeBuilder.visit_ImportFrom ( self,
ast.ImportFrom node 
)
+
+
Process a from-import statement.
+

Definition at line 537 of file symbol_tree.py.

+
537 def visit_ImportFrom(self, node: ast.ImportFrom):
+
538 """Process a from-import statement."""
+
539 for item in node.names:
+
540 # The imported name should not be obfuscated
+
541 symbol = self.tree.add_symbol(item.asname or item.name, SymbolType.IMPORT, node)
+
542 symbol.is_obfuscatable = False
+
543 symbol.is_imported = True
+
544 symbol.original_module = node.module
+
545
+
546 # Track the import
+
547 if isinstance(self.tree.current_scope, ModuleScope):
+
548 module_scope = self.tree.current_scope
+
549 module_scope.add_from_import(node.module, item.asname or item.name, item.name)
+
550
+
+

References transformers.symbol_tree.SymbolTreeBuilder.tree.

+ +
+
+ +

◆ visit_Module()

+ +
+
+ + + + + + + + + + + + + + + + + + +
transformers.symbol_tree.SymbolTreeBuilder.visit_Module ( self,
ast.Module node 
)
+
+
Process a module node.
+

Definition at line 382 of file symbol_tree.py.

+
382 def visit_Module(self, node: ast.Module):
+
383 """Process a module node."""
+
384 self.tree.push_scope("__main__", "module", node)
+
385 # Visit all statements in the module
+
386 for stmt in node.body:
+
387 self.visit(stmt)
+
388 self.tree.pop_scope()
+
389
+
+

References transformers.symbol_tree.SymbolTreeBuilder.tree.

+ +
+
+ +

◆ visit_Name()

+ +
+
+ + + + + + + + + + + + + + + + + + +
transformers.symbol_tree.SymbolTreeBuilder.visit_Name ( self,
ast.Name node 
)
+
+
Process a name (variable reference).
+

Definition at line 498 of file symbol_tree.py.

+
498 def visit_Name(self, node: ast.Name):
+
499 """Process a name (variable reference)."""
+
500 # This is a variable/function/class reference, not a definition
+
501 if isinstance(node.ctx, ast.Load):
+
502 self.tree.add_reference(node.id, node)
+
503
+
+

References transformers.symbol_tree.SymbolTreeBuilder.tree.

+ +
+
+

Member Data Documentation

+ +

◆ current_class

+ + + +

◆ current_function_args

+ +
+
+ + + + +
transformers.symbol_tree.SymbolTreeBuilder.current_function_args
+
+
+ +

◆ in_attribute_ctx

+ +
+
+ + + + +
transformers.symbol_tree.SymbolTreeBuilder.in_attribute_ctx
+
+ +

Definition at line 380 of file symbol_tree.py.

+ +

Referenced by transformers.symbol_tree.SymbolTreeBuilder.visit_Attribute().

+ +
+
+ +

◆ in_class_def

+ + + +

◆ tree

+ + +
The documentation for this class was generated from the following file: +
+
+ + + + diff --git a/doxygen/classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.js b/doxygen/classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.js new file mode 100644 index 0000000..7937a81 --- /dev/null +++ b/doxygen/classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.js @@ -0,0 +1,20 @@ +var classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder = +[ + [ "__init__", "classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#adb9a525c0003b90a619179e8c9d42f4f", null ], + [ "build_tree", "classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#a32eb8339c1450dc3def80e5bc94974ee", null ], + [ "visit_arguments", "classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#a565b94a735a3899055141b19bdcdd7e0", null ], + [ "visit_Assign", "classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#a1a43a6e373b68b4bfee55ea12f96fdb0", null ], + [ "visit_Attribute", "classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#a50731af5433062399d9d9be18e3c65f5", null ], + [ "visit_attribute_assignment", "classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#a4347feddd371651de92d2a27521b7db4", null ], + [ "visit_ClassDef", "classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#ac2a538f11fab8831b20026881c148744", null ], + [ "visit_FunctionDef", "classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#a52448d9c2f26302f3fec276aac37a19b", null ], + [ "visit_Import", "classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#a662cfd0c23a2b7578efe656479c75269", null ], + [ "visit_ImportFrom", "classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#ae098863349f3088291bf86dbe0275590", null ], + [ "visit_Module", "classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#a5706641787b556edc011c99fc5233b01", null ], + [ "visit_Name", "classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#add1ec41f47e2b9d45d01ddaa8848a846", null ], + [ "current_class", "classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#ac65977004ca9efc10798bf3ba482456e", null ], + [ "current_function_args", "classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#ae91f0ddf23926d9bd4c46a448248d006", null ], + [ "in_attribute_ctx", "classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#a2085ee40b893a6a08ce7c4dab5734ba2", null ], + [ "in_class_def", "classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#a7be7f365eb0a88520418350d0489198c", null ], + [ "tree", "classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#aeedf41282ae721713024904629c2c8a4", null ] +]; \ No newline at end of file diff --git a/doxygen/classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder__coll__graph.dot b/doxygen/classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder__coll__graph.dot new file mode 100644 index 0000000..e7968a9 --- /dev/null +++ b/doxygen/classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder__coll__graph.dot @@ -0,0 +1,10 @@ +digraph "transformers.symbol_tree.SymbolTreeBuilder" +{ + // LATEX_PDF_SIZE + bgcolor="transparent"; + edge [fontname=Helvetica,fontsize=10,labelfontname=Helvetica,labelfontsize=10]; + node [fontname=Helvetica,fontsize=10,shape=box,height=0.2,width=0.4]; + Node1 [id="Node000001",label="transformers.symbol\l_tree.SymbolTreeBuilder",height=0.2,width=0.4,color="gray40", fillcolor="grey60", style="filled", fontcolor="black",tooltip=" "]; + Node2 -> Node1 [id="edge1_Node000001_Node000002",dir="back",color="steelblue1",style="solid",tooltip=" "]; + Node2 [id="Node000002",label="ast.NodeVisitor",height=0.2,width=0.4,color="gray40", fillcolor="white", style="filled",tooltip=" "]; +} diff --git a/doxygen/classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder__inherit__graph.dot b/doxygen/classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder__inherit__graph.dot new file mode 100644 index 0000000..e7968a9 --- /dev/null +++ b/doxygen/classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder__inherit__graph.dot @@ -0,0 +1,10 @@ +digraph "transformers.symbol_tree.SymbolTreeBuilder" +{ + // LATEX_PDF_SIZE + bgcolor="transparent"; + edge [fontname=Helvetica,fontsize=10,labelfontname=Helvetica,labelfontsize=10]; + node [fontname=Helvetica,fontsize=10,shape=box,height=0.2,width=0.4]; + Node1 [id="Node000001",label="transformers.symbol\l_tree.SymbolTreeBuilder",height=0.2,width=0.4,color="gray40", fillcolor="grey60", style="filled", fontcolor="black",tooltip=" "]; + Node2 -> Node1 [id="edge1_Node000001_Node000002",dir="back",color="steelblue1",style="solid",tooltip=" "]; + Node2 [id="Node000002",label="ast.NodeVisitor",height=0.2,width=0.4,color="gray40", fillcolor="white", style="filled",tooltip=" "]; +} diff --git a/doxygen/classtransformers_1_1symbol__tree_1_1SymbolType-members.html b/doxygen/classtransformers_1_1symbol__tree_1_1SymbolType-members.html new file mode 100644 index 0000000..3935c52 --- /dev/null +++ b/doxygen/classtransformers_1_1symbol__tree_1_1SymbolType-members.html @@ -0,0 +1,116 @@ + + + + + + + +OMG-Fuscator: Member List + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
transformers.symbol_tree.SymbolType Member List
+
+ +
+ + + + diff --git a/doxygen/classtransformers_1_1symbol__tree_1_1SymbolType.html b/doxygen/classtransformers_1_1symbol__tree_1_1SymbolType.html new file mode 100644 index 0000000..3e17b15 --- /dev/null +++ b/doxygen/classtransformers_1_1symbol__tree_1_1SymbolType.html @@ -0,0 +1,342 @@ + + + + + + + +OMG-Fuscator: transformers.symbol_tree.SymbolType Class Reference + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
transformers.symbol_tree.SymbolType Class Reference
+
+
+
+ + Inheritance diagram for transformers.symbol_tree.SymbolType:
+
+
+ +
+ + Collaboration diagram for transformers.symbol_tree.SymbolType:
+
+
+ + + + + + + + + + + + + + + + + + + +

+Static Public Attributes

str ARGUMENT = "argument"
 
str ATTRIBUTE = "attribute"
 
str CLASS = "class"
 
str FUNCTION = "function"
 
str IMPORT = "import"
 
str METHOD = "method"
 
str MODULE = "module"
 
str VARIABLE = "variable"
 
+

Detailed Description

+
Defines the different types of symbols that can be tracked.
+

Definition at line 18 of file symbol_tree.py.

+

Member Data Documentation

+ +

◆ ARGUMENT

+ +
+
+ + + + + +
+ + + + +
str transformers.symbol_tree.SymbolType.ARGUMENT = "argument"
+
+static
+
+ +

Definition at line 24 of file symbol_tree.py.

+ +
+
+ +

◆ ATTRIBUTE

+ +
+
+ + + + + +
+ + + + +
str transformers.symbol_tree.SymbolType.ATTRIBUTE = "attribute"
+
+static
+
+ +

Definition at line 25 of file symbol_tree.py.

+ +
+
+ +

◆ CLASS

+ +
+
+ + + + + +
+ + + + +
str transformers.symbol_tree.SymbolType.CLASS = "class"
+
+static
+
+ +

Definition at line 22 of file symbol_tree.py.

+ +
+
+ +

◆ FUNCTION

+ +
+
+ + + + + +
+ + + + +
str transformers.symbol_tree.SymbolType.FUNCTION = "function"
+
+static
+
+ +

Definition at line 21 of file symbol_tree.py.

+ +
+
+ +

◆ IMPORT

+ +
+
+ + + + + +
+ + + + +
str transformers.symbol_tree.SymbolType.IMPORT = "import"
+
+static
+
+ +

Definition at line 27 of file symbol_tree.py.

+ +
+
+ +

◆ METHOD

+ +
+
+ + + + + +
+ + + + +
str transformers.symbol_tree.SymbolType.METHOD = "method"
+
+static
+
+ +

Definition at line 23 of file symbol_tree.py.

+ +
+
+ +

◆ MODULE

+ +
+
+ + + + + +
+ + + + +
str transformers.symbol_tree.SymbolType.MODULE = "module"
+
+static
+
+ +

Definition at line 26 of file symbol_tree.py.

+ +
+
+ +

◆ VARIABLE

+ +
+
+ + + + + +
+ + + + +
str transformers.symbol_tree.SymbolType.VARIABLE = "variable"
+
+static
+
+ +

Definition at line 20 of file symbol_tree.py.

+ +
+
+
The documentation for this class was generated from the following file: +
+
+ + + + diff --git a/doxygen/classtransformers_1_1symbol__tree_1_1SymbolType.js b/doxygen/classtransformers_1_1symbol__tree_1_1SymbolType.js new file mode 100644 index 0000000..f1af401 --- /dev/null +++ b/doxygen/classtransformers_1_1symbol__tree_1_1SymbolType.js @@ -0,0 +1,11 @@ +var classtransformers_1_1symbol__tree_1_1SymbolType = +[ + [ "ARGUMENT", "classtransformers_1_1symbol__tree_1_1SymbolType.html#afe39c27276fa3655e49323158a3e87ca", null ], + [ "ATTRIBUTE", "classtransformers_1_1symbol__tree_1_1SymbolType.html#a03194cf85b1f80973db4dec5365f6b52", null ], + [ "CLASS", "classtransformers_1_1symbol__tree_1_1SymbolType.html#a7f25c4e953938b6761f49360f014c9da", null ], + [ "FUNCTION", "classtransformers_1_1symbol__tree_1_1SymbolType.html#a747e62c99ce5d23c7978cd7558eeffbc", null ], + [ "IMPORT", "classtransformers_1_1symbol__tree_1_1SymbolType.html#a5414ea5b01801f342af004f241afa62a", null ], + [ "METHOD", "classtransformers_1_1symbol__tree_1_1SymbolType.html#a0a47aadbdfff9fca91e0f2944dd8fd17", null ], + [ "MODULE", "classtransformers_1_1symbol__tree_1_1SymbolType.html#a9afafe6de92dc3689de599a44fb53f06", null ], + [ "VARIABLE", "classtransformers_1_1symbol__tree_1_1SymbolType.html#ad9d2f0f2f9c17ba5c68a15d0c18cbb41", null ] +]; \ No newline at end of file diff --git a/doxygen/classtransformers_1_1symbol__tree_1_1SymbolType__coll__graph.dot b/doxygen/classtransformers_1_1symbol__tree_1_1SymbolType__coll__graph.dot new file mode 100644 index 0000000..0841777 --- /dev/null +++ b/doxygen/classtransformers_1_1symbol__tree_1_1SymbolType__coll__graph.dot @@ -0,0 +1,10 @@ +digraph "transformers.symbol_tree.SymbolType" +{ + // LATEX_PDF_SIZE + bgcolor="transparent"; + edge [fontname=Helvetica,fontsize=10,labelfontname=Helvetica,labelfontsize=10]; + node [fontname=Helvetica,fontsize=10,shape=box,height=0.2,width=0.4]; + Node1 [id="Node000001",label="transformers.symbol\l_tree.SymbolType",height=0.2,width=0.4,color="gray40", fillcolor="grey60", style="filled", fontcolor="black",tooltip=" "]; + Node2 -> Node1 [id="edge1_Node000001_Node000002",dir="back",color="steelblue1",style="solid",tooltip=" "]; + Node2 [id="Node000002",label="Enum",height=0.2,width=0.4,color="gray40", fillcolor="white", style="filled",tooltip=" "]; +} diff --git a/doxygen/classtransformers_1_1symbol__tree_1_1SymbolType__inherit__graph.dot b/doxygen/classtransformers_1_1symbol__tree_1_1SymbolType__inherit__graph.dot new file mode 100644 index 0000000..0841777 --- /dev/null +++ b/doxygen/classtransformers_1_1symbol__tree_1_1SymbolType__inherit__graph.dot @@ -0,0 +1,10 @@ +digraph "transformers.symbol_tree.SymbolType" +{ + // LATEX_PDF_SIZE + bgcolor="transparent"; + edge [fontname=Helvetica,fontsize=10,labelfontname=Helvetica,labelfontsize=10]; + node [fontname=Helvetica,fontsize=10,shape=box,height=0.2,width=0.4]; + Node1 [id="Node000001",label="transformers.symbol\l_tree.SymbolType",height=0.2,width=0.4,color="gray40", fillcolor="grey60", style="filled", fontcolor="black",tooltip=" "]; + Node2 -> Node1 [id="edge1_Node000001_Node000002",dir="back",color="steelblue1",style="solid",tooltip=" "]; + Node2 [id="Node000002",label="Enum",height=0.2,width=0.4,color="gray40", fillcolor="white", style="filled",tooltip=" "]; +} diff --git a/doxygen/classutils_1_1encryption_1_1StringEncryptor-members.html b/doxygen/classutils_1_1encryption_1_1StringEncryptor-members.html new file mode 100644 index 0000000..d16c7f3 --- /dev/null +++ b/doxygen/classutils_1_1encryption_1_1StringEncryptor-members.html @@ -0,0 +1,114 @@ + + + + + + + +OMG-Fuscator: Member List + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
utils.encryption.StringEncryptor Member List
+
+ +
+ + + + diff --git a/doxygen/classutils_1_1encryption_1_1StringEncryptor.html b/doxygen/classutils_1_1encryption_1_1StringEncryptor.html new file mode 100644 index 0000000..7fce951 --- /dev/null +++ b/doxygen/classutils_1_1encryption_1_1StringEncryptor.html @@ -0,0 +1,396 @@ + + + + + + + +OMG-Fuscator: utils.encryption.StringEncryptor Class Reference + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
utils.encryption.StringEncryptor Class Reference
+
+
+ + + + + + + + +

+Public Member Functions

 __init__ (self, bytes primary_key, bytes secondary_key, bytes salt)
 
Tuple[str, str, str] encrypt_string (self, str s)
 
str hide_byte (self, int b)
 
+ + + + + + + +

+Public Attributes

 primary_key
 
 salt
 
 secondary_key
 
+

Detailed Description

+
@brief Encrypts strings for obfuscation using layered XOR and Base85 encoding.
+@details Produces both an encoded payload and Python code that reconstructs
+         the keys at runtime without embedding raw key bytes.
+
+

Definition at line 14 of file encryption.py.

+

Constructor & Destructor Documentation

+ +

◆ __init__()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
utils.encryption.StringEncryptor.__init__ ( self,
bytes primary_key,
bytes secondary_key,
bytes salt 
)
+
+
@brief Initialize encryptor keys.
+@param primary_key Primary XOR key bytes.
+@param secondary_key Secondary XOR key bytes.
+@param salt Salt bytes used to derive a per-string modifier.
+
+

Definition at line 20 of file encryption.py.

+
20 def __init__(self, primary_key: bytes, secondary_key: bytes, salt: bytes):
+
21 """
+
22 @brief Initialize encryptor keys.
+
23 @param primary_key Primary XOR key bytes.
+
24 @param secondary_key Secondary XOR key bytes.
+
25 @param salt Salt bytes used to derive a per-string modifier.
+
26 """
+
27 self.primary_key = primary_key
+
28 self.secondary_key = secondary_key
+
29 self.salt = salt
+
30
+
+
+
+

Member Function Documentation

+ +

◆ encrypt_string()

+ +
+
+ + + + + + + + + + + + + + + + + + +
Tuple[str, str, str] utils.encryption.StringEncryptor.encrypt_string ( self,
str s 
)
+
+
@brief Encrypt a string with layered XOR and Base85 encoding.
+@param s UTF-8 string to encrypt.
+@return Tuple[str, str, str]:
+    - encoded: Base85 text of the encrypted payload
+    - key_setup: Python code that reconstructs keys at runtime
+    - modifier_hex: Hex string for the per-string modifier
+
+

Definition at line 62 of file encryption.py.

+
62 def encrypt_string(self, s: str) -> Tuple[str, str, str]:
+
63 """
+
64 @brief Encrypt a string with layered XOR and Base85 encoding.
+
65 @param s UTF-8 string to encrypt.
+
66 @return Tuple[str, str, str]:
+
67 - encoded: Base85 text of the encrypted payload
+
68 - key_setup: Python code that reconstructs keys at runtime
+
69 - modifier_hex: Hex string for the per-string modifier
+
70 """
+
71 data = s.encode('utf-8')
+
72 modifier = hashlib.sha256(self.salt + data).digest()[:8]
+
73
+
74 layer1 = bytes(
+
75 d ^ k ^ m
+
76 for d, k, m in zip(
+
77 data,
+
78 self.primary_key * ((len(data) // len(self.primary_key)) + 1),
+
79 modifier * ((len(data) // len(modifier)) + 1)
+
80 )
+
81 )
+
82
+
83 final_data = bytes(
+
84 d ^ k
+
85 for d, k in zip(
+
86 layer1,
+
87 self.secondary_key * ((len(layer1) // len(self.secondary_key)) + 1)
+
88 )
+
89 )
+
90
+
91 encoded = base64.b85encode(final_data).decode()
+
92
+
93 primary_key_code = f"bytes([{','.join(self.hide_byte(b) for b in self.primary_key)}])"
+
94 secondary_key_code = f"bytes([{','.join(self.hide_byte(b) for b in self.secondary_key)}])"
+
95 salt_code = f"bytes([{','.join(self.hide_byte(b) for b in self.salt)}])"
+
96
+
97 key_setup = (
+
98 f"_pk = {primary_key_code}\n"
+
99 f"_sk = {secondary_key_code}\n"
+
100 f"_st = {salt_code}"
+
101 )
+
102
+
103 return encoded, key_setup, modifier.hex()
+
+

References obfuscator.AdvancedObfuscator.primary_key, utils.encryption.StringEncryptor.primary_key, obfuscator.AdvancedObfuscator.salt, utils.encryption.StringEncryptor.salt, obfuscator.AdvancedObfuscator.secondary_key, and utils.encryption.StringEncryptor.secondary_key.

+ +
+
+ +

◆ hide_byte()

+ +
+
+ + + + + + + + + + + + + + + + + + +
str utils.encryption.StringEncryptor.hide_byte ( self,
int b 
)
+
+
@brief Obfuscate a single key byte into an arithmetic/bitwise expression.
+@param b Input byte value in range [0, 255].
+@return Python expression string that evaluates to the original byte at runtime.
+
+

Definition at line 31 of file encryption.py.

+
31 def hide_byte(self, b: int) -> str:
+
32 """
+
33 @brief Obfuscate a single key byte into an arithmetic/bitwise expression.
+
34 @param b Input byte value in range [0, 255].
+
35 @return Python expression string that evaluates to the original byte at runtime.
+
36 """
+
37 pattern = random.randint(1, 5)
+
38 if pattern == 1:
+
39 x1, x2, x3 = [random.randint(65, 90) for _ in range(3)]
+
40 result = x1 ^ x2 ^ x3 ^ b
+
41 return f"({x1}^{x2}^{x3}^{result})"
+
42 elif pattern == 2:
+
43 base = random.randint(65, 90)
+
44 multiplier = random.randint(2, 4)
+
45 adjusted = (base * multiplier - b)
+
46 return f"(({base}*{multiplier}-{adjusted}))"
+
47 elif pattern == 3:
+
48 shift = random.randint(1, 3)
+
49 modified = (b << shift) >> shift
+
50 diff = b - modified
+
51 return f"((({b << shift})>>{shift})+{diff})"
+
52 elif pattern == 4:
+
53 char1, char2 = random.sample(range(65, 91), 2)
+
54 result = char1 + char2 - b
+
55 return f"({char1}+{char2}-{result})"
+
56 else:
+
57 mod_base = random.randint(91, 100)
+
58 result = b % mod_base
+
59 factor = b // mod_base
+
60 return f"({factor}*{mod_base}+{result})"
+
61
+
+
+
+

Member Data Documentation

+ +

◆ primary_key

+ +
+
+ + + + +
utils.encryption.StringEncryptor.primary_key
+
+
+ +

◆ salt

+ +
+
+ + + + +
utils.encryption.StringEncryptor.salt
+
+
+ +

◆ secondary_key

+ +
+
+ + + + +
utils.encryption.StringEncryptor.secondary_key
+
+
+
The documentation for this class was generated from the following file: +
+
+ + + + diff --git a/doxygen/classutils_1_1encryption_1_1StringEncryptor.js b/doxygen/classutils_1_1encryption_1_1StringEncryptor.js new file mode 100644 index 0000000..54daa88 --- /dev/null +++ b/doxygen/classutils_1_1encryption_1_1StringEncryptor.js @@ -0,0 +1,9 @@ +var classutils_1_1encryption_1_1StringEncryptor = +[ + [ "__init__", "classutils_1_1encryption_1_1StringEncryptor.html#aeeab3fb282428a253a857668c8ad7545", null ], + [ "encrypt_string", "classutils_1_1encryption_1_1StringEncryptor.html#a6c2cacc40f85e399dee8e47e20f81739", null ], + [ "hide_byte", "classutils_1_1encryption_1_1StringEncryptor.html#a182add66c3f8039da6f1accf0b52c3c3", null ], + [ "primary_key", "classutils_1_1encryption_1_1StringEncryptor.html#a3359e4b96fb9553a0c9cc4184fc2c434", null ], + [ "salt", "classutils_1_1encryption_1_1StringEncryptor.html#a46597c8e3f7981b5f55ca974a5355dd3", null ], + [ "secondary_key", "classutils_1_1encryption_1_1StringEncryptor.html#ac923cfbf0a09c75e6bb0cea01cde8cd8", null ] +]; \ No newline at end of file diff --git a/doxygen/classutils_1_1junk__gen_1_1JunkGenerator-members.html b/doxygen/classutils_1_1junk__gen_1_1JunkGenerator-members.html new file mode 100644 index 0000000..e915f01 --- /dev/null +++ b/doxygen/classutils_1_1junk__gen_1_1JunkGenerator-members.html @@ -0,0 +1,112 @@ + + + + + + + +OMG-Fuscator: Member List + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
utils.junk_gen.JunkGenerator Member List
+
+
+ +

This is the complete list of members for utils.junk_gen.JunkGenerator, including all inherited members.

+ + + + + +
__init__(self, NameGenerator name_generator)utils.junk_gen.JunkGenerator
add_junk(self)utils.junk_gen.JunkGenerator
generate_junk(self)utils.junk_gen.JunkGenerator
name_generatorutils.junk_gen.JunkGenerator
+
+ + + + diff --git a/doxygen/classutils_1_1junk__gen_1_1JunkGenerator.html b/doxygen/classutils_1_1junk__gen_1_1JunkGenerator.html new file mode 100644 index 0000000..126e540 --- /dev/null +++ b/doxygen/classutils_1_1junk__gen_1_1JunkGenerator.html @@ -0,0 +1,289 @@ + + + + + + + +OMG-Fuscator: utils.junk_gen.JunkGenerator Class Reference + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
utils.junk_gen.JunkGenerator Class Reference
+
+
+ + + + + + + + +

+Public Member Functions

 __init__ (self, NameGenerator name_generator)
 
str add_junk (self)
 
str generate_junk (self)
 
+ + + +

+Public Attributes

 name_generator
 
+

Detailed Description

+
@brief Produces pseudo-random junk code.
+@param name_generator Name generator used for variable identifiers.
+
+

Definition at line 11 of file junk_gen.py.

+

Constructor & Destructor Documentation

+ +

◆ __init__()

+ +
+
+ + + + + + + + + + + + + + + + + + +
utils.junk_gen.JunkGenerator.__init__ ( self,
NameGenerator name_generator 
)
+
+
@brief Constructor.
+@param name_generator NameGenerator instance used to create junk variable names.
+
+

Definition at line 16 of file junk_gen.py.

+
16 def __init__(self, name_generator: NameGenerator):
+
17 """
+
18 @brief Constructor.
+
19 @param name_generator NameGenerator instance used to create junk variable names.
+
20 """
+
21 self.name_generator = name_generator
+
22
+
+
+
+

Member Function Documentation

+ +

◆ add_junk()

+ +
+
+ + + + + + + + +
str utils.junk_gen.JunkGenerator.add_junk ( self)
+
+
@brief Generate a random multi-line junk code snippet.
+@return Python source string with one or more lines.
+
+

Definition at line 23 of file junk_gen.py.

+
23 def add_junk(self) -> str:
+
24 """
+
25 @brief Generate a random multi-line junk code snippet.
+
26 @return Python source string with one or more lines.
+
27 """
+
28 var1 = self.name_generator.generate_name()
+
29 var2 = self.name_generator.generate_name()
+
30
+
31 example_strings = ["HelloWorld", "CryptoMagic", "XxX_Obf_42", "DataStorm", "RandomStr", "TestString"]
+
32 s1 = random.choice(example_strings)
+
33 s2 = random.choice(example_strings)
+
34
+
35 multi_line_junks = [
+
36 f"{var1} = chr({random.randint(65, 90)}) + chr({random.randint(65, 90)})",
+
37 f"{var1} = sum([{random.randint(1,10)} for _ in range({random.randint(1,5)})])",
+
38 f"{var1} = len(bytes([{random.randint(65,90)}, {random.randint(65,90)}, {random.randint(65,90)}]))",
+
39 f"if chr({random.randint(65,90)}).isupper(): {var1} = {random.randint(0, 999)}",
+
40 f"{var1} = bytes([{random.randint(65,90)}] * {random.randint(1,3)})",
+
41 f"{var1} = ord(chr({random.randint(65,90)})) - {random.randint(1,10)}",
+
42
+
43 f"{var1} = '{s1}'.lower()\n{var2} = '{s2}'.upper()",
+
44 f"{var1} = [chr(random.randint(65,90)) for _ in range({random.randint(2,5)})]\n{var2} = ''.join({var1})",
+
45 f"{var1} = {random.randint(1,10)} ** {random.randint(1,3)}\n{var2} = {var1} % {random.randint(1,10)}",
+
46 f"{var1} = [{random.randint(1,5)} for _ in range({random.randint(3,5)})]\nif len({var1}) > {random.randint(1,4)}: {var2} = sum({var1})",
+
47 f"{var1} = {{ {random.randint(1,10)} : '{s1}' }}\n{var2} = {var1}.get({random.randint(1,10)}, None)",
+
48 f"{var1} = set(range({random.randint(2,5)}))\n{var2} = set(range({random.randint(2,5)}))\n{var1}.intersection({var2})"
+
49 ]
+
50 return random.choice(multi_line_junks)
+
51
+
+

References obfuscator.AdvancedObfuscator.name_generator, transformers.class_analyzer.ClassAnalyzer.name_generator, transformers.class_mapper.ClassMapAnalyzer.name_generator, transformers.rename.RenameTransformer.name_generator, and utils.junk_gen.JunkGenerator.name_generator.

+ +
+
+ +

◆ generate_junk()

+ +
+
+ + + + + + + + +
str utils.junk_gen.JunkGenerator.generate_junk ( self)
+
+
@brief Generate a single-line junk statement.
+@return Python source string for a single assignment or expression.
+
+

Definition at line 52 of file junk_gen.py.

+
52 def generate_junk(self) -> str:
+
53 """
+
54 @brief Generate a single-line junk statement.
+
55 @return Python source string for a single assignment or expression.
+
56 """
+
57 var_name = self.name_generator.generate_name()
+
58 junk_code = [
+
59 f"{var_name} = {random.randint(0, 100)}",
+
60 f"{var_name} = '{''.join(random.choices(string.ascii_letters, k=10))}'",
+
61 f"{var_name} = {random.randint(0, 100)} + {random.randint(0, 100)}",
+
62 f"{var_name} = {random.randint(0, 100)} * {random.randint(0, 100)}",
+
63 f"{var_name} = {random.randint(0, 100)} - {random.randint(0, 100)}",
+
64 f"{var_name} = {random.randint(0, 100)} / {random.randint(1, 100)}",
+
65 f"{var_name} = '{''.join(random.choices(string.ascii_letters + string.digits, k=15))}'",
+
66 f"{var_name} = {random.randint(0, 100)} % {random.randint(1, 100)}",
+
67 f"{var_name} = {random.randint(0, 100)} ** {random.randint(0, 5)}",
+
68 f"{var_name} = {random.randint(0, 100)} // {random.randint(1, 100)}"
+
69 ]
+
70 return random.choice(junk_code)
+
+

References obfuscator.AdvancedObfuscator.name_generator, transformers.class_analyzer.ClassAnalyzer.name_generator, transformers.class_mapper.ClassMapAnalyzer.name_generator, transformers.rename.RenameTransformer.name_generator, and utils.junk_gen.JunkGenerator.name_generator.

+ +
+
+

Member Data Documentation

+ +

◆ name_generator

+ + +
The documentation for this class was generated from the following file: +
+
+ + + + diff --git a/doxygen/classutils_1_1junk__gen_1_1JunkGenerator.js b/doxygen/classutils_1_1junk__gen_1_1JunkGenerator.js new file mode 100644 index 0000000..013a78f --- /dev/null +++ b/doxygen/classutils_1_1junk__gen_1_1JunkGenerator.js @@ -0,0 +1,7 @@ +var classutils_1_1junk__gen_1_1JunkGenerator = +[ + [ "__init__", "classutils_1_1junk__gen_1_1JunkGenerator.html#ad1c240cacad785c775dfeddc9eea76b5", null ], + [ "add_junk", "classutils_1_1junk__gen_1_1JunkGenerator.html#ad5fdca002e6e7b5e5de74b6836a26887", null ], + [ "generate_junk", "classutils_1_1junk__gen_1_1JunkGenerator.html#a0302efd5f4dda3da3c02280d9739d4d3", null ], + [ "name_generator", "classutils_1_1junk__gen_1_1JunkGenerator.html#a6edc8f910180d399302e33b48a0346ee", null ] +]; \ No newline at end of file diff --git a/doxygen/classutils_1_1name__gen_1_1NameGenerator-members.html b/doxygen/classutils_1_1name__gen_1_1NameGenerator-members.html new file mode 100644 index 0000000..4c12712 --- /dev/null +++ b/doxygen/classutils_1_1name__gen_1_1NameGenerator-members.html @@ -0,0 +1,113 @@ + + + + + + + +OMG-Fuscator: Member List + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
utils.name_gen.NameGenerator Member List
+
+ +
+ + + + diff --git a/doxygen/classutils_1_1name__gen_1_1NameGenerator.html b/doxygen/classutils_1_1name__gen_1_1NameGenerator.html new file mode 100644 index 0000000..80b4fa2 --- /dev/null +++ b/doxygen/classutils_1_1name__gen_1_1NameGenerator.html @@ -0,0 +1,293 @@ + + + + + + + +OMG-Fuscator: utils.name_gen.NameGenerator Class Reference + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ + +
+ + + + + + +

+Public Member Functions

 __init__ (self)
 
str generate_name (self)
 
+ + + +

+Public Attributes

 used_names
 
+ + + +

+Protected Member Functions

Iterator[str] _create_iterator (self)
 
+ + + +

+Protected Attributes

 _name_iterator
 
+

Detailed Description

+
@brief Generates unique obfuscated identifiers.
+@details Uses patterned Cartesian products to create long, confusing names and
+         tracks used names to avoid collisions.
+
+

Definition at line 10 of file name_gen.py.

+

Constructor & Destructor Documentation

+ +

◆ __init__()

+ +
+
+ + + + + + + + +
utils.name_gen.NameGenerator.__init__ ( self)
+
+
@brief Initialize internal iterator and used-name set.
+
+

Definition at line 16 of file name_gen.py.

+
16 def __init__(self):
+
17 """
+
18 @brief Initialize internal iterator and used-name set.
+
19 """
+
20 self._name_iterator = self._create_iterator()
+
21 self.used_names = set()
+
22
+
+
+
+

Member Function Documentation

+ +

◆ _create_iterator()

+ +
+
+ + + + + +
+ + + + + + + + +
Iterator[str] utils.name_gen.NameGenerator._create_iterator ( self)
+
+protected
+
+
@brief Iterator producing obfuscated identifier candidates.
+@return Iterator[str] Infinite stream of names such as vIl1lO0o0Z2z2...
+
+

Definition at line 23 of file name_gen.py.

+
23 def _create_iterator(self) -> Iterator[str]:
+
24 """
+
25 @brief Iterator producing obfuscated identifier candidates.
+
26 @return Iterator[str] Infinite stream of names such as vIl1lO0o0Z2z2...
+
27 """
+
28 patterns = ['Il1l', 'O0o0', 'Z2z2', 'S5s5', 'B8b8', 'Q9q9']
+
29 for length in itertools.count(2): # Start with length=2, continue forever
+
30 for combo in itertools.product(patterns, repeat=length):
+
31 yield 'v' + ''.join(combo)
+
32
+
+
+
+ +

◆ generate_name()

+ +
+
+ + + + + + + + +
str utils.name_gen.NameGenerator.generate_name ( self)
+
+
@brief Produce a fresh, unique obfuscated name.
+@return str Name guaranteed not to have been produced before by this instance.
+
+

Definition at line 33 of file name_gen.py.

+
33 def generate_name(self) -> str:
+
34 """
+
35 @brief Produce a fresh, unique obfuscated name.
+
36 @return str Name guaranteed not to have been produced before by this instance.
+
37 """
+
38 while True:
+
39 candidate = next(self._name_iterator)
+
40 if candidate not in self.used_names:
+
41 self.used_names.add(candidate)
+
42 return candidate
+
+

References utils.name_gen.NameGenerator._name_iterator, obfuscator.AdvancedObfuscator.used_names, and utils.name_gen.NameGenerator.used_names.

+ +
+
+

Member Data Documentation

+ +

◆ _name_iterator

+ +
+
+ + + + + +
+ + + + +
utils.name_gen.NameGenerator._name_iterator
+
+protected
+
+ +

Definition at line 20 of file name_gen.py.

+ +

Referenced by utils.name_gen.NameGenerator.generate_name().

+ +
+
+ +

◆ used_names

+ +
+
+ + + + +
utils.name_gen.NameGenerator.used_names
+
+ +

Definition at line 21 of file name_gen.py.

+ +

Referenced by utils.name_gen.NameGenerator.generate_name().

+ +
+
+
The documentation for this class was generated from the following file: +
+
+ + + + diff --git a/doxygen/classutils_1_1name__gen_1_1NameGenerator.js b/doxygen/classutils_1_1name__gen_1_1NameGenerator.js new file mode 100644 index 0000000..6ffc306 --- /dev/null +++ b/doxygen/classutils_1_1name__gen_1_1NameGenerator.js @@ -0,0 +1,8 @@ +var classutils_1_1name__gen_1_1NameGenerator = +[ + [ "__init__", "classutils_1_1name__gen_1_1NameGenerator.html#aff640e7a1a975e664ca4fe3a54ec2cfb", null ], + [ "_create_iterator", "classutils_1_1name__gen_1_1NameGenerator.html#a2a43fa241cee73c532a98c366fe7df71", null ], + [ "generate_name", "classutils_1_1name__gen_1_1NameGenerator.html#ac05b7a033f2ccb1a238b7e5e0877e2c6", null ], + [ "_name_iterator", "classutils_1_1name__gen_1_1NameGenerator.html#ae45ad0a202daf1572a4f76cf79e791e7", null ], + [ "used_names", "classutils_1_1name__gen_1_1NameGenerator.html#ab773c0140d1b4ef0654215de2c2b37df", null ] +]; \ No newline at end of file diff --git a/doxygen/closed.png b/doxygen/closed.png new file mode 100644 index 0000000000000000000000000000000000000000..98cc2c909da37a6df914fbf67780eebd99c597f5 GIT binary patch literal 132 zcmeAS@N?(olHy`uVBq!ia0vp^oFL4>1|%O$WD@{V-kvUwAr*{o@8{^CZMh(5KoB^r_<4^zF@3)Cp&&t3hdujKf f*?bjBoY!V+E))@{xMcbjXe@)LtDnm{r-UW|*e5JT literal 0 HcmV?d00001 diff --git a/doxygen/control__flow_8py.html b/doxygen/control__flow_8py.html new file mode 100644 index 0000000..b14fcfa --- /dev/null +++ b/doxygen/control__flow_8py.html @@ -0,0 +1,132 @@ + + + + + + + +OMG-Fuscator: control_flow.py File Reference + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
control_flow.py File Reference
+
+
+ +

Go to the source code of this file.

+ + + + +

+Classes

class  transformers.control_flow.ControlFlowFlattener
 
+ + + + + +

+Namespaces

namespace  transformers
 
namespace  transformers.control_flow
 
+ + + + + +

+Variables

 transformers.control_flow.level
 
 transformers.control_flow.logger = logging.getLogger("ControlFlowFlattener")
 
+
+
+ + + + diff --git a/doxygen/control__flow_8py.js b/doxygen/control__flow_8py.js new file mode 100644 index 0000000..8f761de --- /dev/null +++ b/doxygen/control__flow_8py.js @@ -0,0 +1,6 @@ +var control__flow_8py = +[ + [ "transformers.control_flow.ControlFlowFlattener", "classtransformers_1_1control__flow_1_1ControlFlowFlattener.html", "classtransformers_1_1control__flow_1_1ControlFlowFlattener" ], + [ "level", "control__flow_8py.html#a8c90b886e8d2a91a19bc062aebcd5682", null ], + [ "logger", "control__flow_8py.html#a6509497a1f3193babfae90f14a285aa3", null ] +]; \ No newline at end of file diff --git a/doxygen/control__flow_8py_source.html b/doxygen/control__flow_8py_source.html new file mode 100644 index 0000000..b07fadd --- /dev/null +++ b/doxygen/control__flow_8py_source.html @@ -0,0 +1,646 @@ + + + + + + + +OMG-Fuscator: control_flow.py Source File + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
control_flow.py
+
+
+Go to the documentation of this file.
1"""
+
2@file transformers/control_flow.py
+
3@brief Control-flow flattening transformer.
+
4@details Converts structured control flow into a state-machine with a while/dispatch
+
5 loop to hinder static analysis, and can emit debug telemetry in debug mode.
+
6"""
+
7import ast
+
8import random
+
9from typing import Dict, List, Set, Tuple, Any, Optional
+
10import logging
+
11
+
12# Configure logging
+
13logging.basicConfig(level=logging.INFO)
+
14logger = logging.getLogger("ControlFlowFlattener")
+
15
+
+
16class ControlFlowFlattener(ast.NodeTransformer):
+
17 """
+
18 A transformer that flattens control flow by converting branching structures
+
19 into a dispatch table with a while loop.
+
20 """
+
21
+
+
22 def __init__(self, debug_mode=False):
+
23 self.state_var_name = "_state"
+
24 self.states = {}
+ +
26 self.debug_mode = debug_mode
+
27
+
28 # For tracking transformations when debug mode is enabled
+
29 if debug_mode:
+
30 self.debug_data = {
+
31 "flattened_functions": [],
+
32 "block_counts": {},
+
33 "transformations": []
+
34 }
+
35
+
+
+
36 def log_debug(self, category: str, data: Any):
+
37 """Log debugging information if debug mode is enabled."""
+
38 if self.debug_mode:
+
39 self.debug_data["transformations"].append({
+
40 "type": category,
+
41 "data": data
+
42 })
+
43
+
+
+
44 def visit_FunctionDef(self, node: ast.FunctionDef) -> ast.FunctionDef:
+
45 """
+
46 Transform a function body into a flattened control flow.
+
47
+
48 Keeps function signature the same but replaces the body with
+
49 state-machine style execution.
+
50 """
+
51 # Skip small functions as flattening them might cause more overhead than obfuscation
+
52 if len(node.body) <= 2:
+
53 return self.generic_visit(node)
+
54
+
55 # Reset state for this function
+
56 self.states = {}
+
57 self.current_block_id = 0
+
58
+
59 # Process decorators and args normally
+
60 node.decorator_list = [self.visit(d) for d in node.decorator_list]
+
61 if hasattr(node, 'args'):
+
62 node.args = self.visit(node.args)
+
63
+
64 # Create entry block (state 0)
+
65 entry_block_id = self.current_block_id
+
66 self.current_block_id += 1
+
67 self.states[entry_block_id] = node.body
+
68
+
69 # Create the flattened control flow
+
70 flattened_body = self.flatten_blocks()
+
71 node.body = flattened_body
+
72
+
73 if self.debug_mode:
+
74 self.debug_data["flattened_functions"].append(node.name)
+
75 self.debug_data["block_counts"][node.name] = len(self.states)
+
76 self.log_debug("function_flattened", {
+
77 "name": node.name,
+
78 "original_statements": len(self.states[entry_block_id]),
+
79 "flattened_blocks": len(self.states)
+
80 })
+
81
+
82 return node
+
83
+
+
+
84 def flatten_blocks(self) -> List[ast.stmt]:
+
85 """
+
86 Create a flattened control flow structure using a while loop and switch-like
+
87 dispatch based on a state variable.
+
88 """
+
89 # Create the state variable and initialize it
+
90 state_var = ast.Name(id=self.state_var_name, ctx=ast.Store())
+
91 init_state = ast.Assign(
+
92 targets=[state_var],
+
93 value=ast.Constant(value=0, kind=None)
+
94 )
+
95
+
96 # Create the while loop condition (state != -1)
+
97 loop_condition = ast.Compare(
+
98 left=ast.Name(id=self.state_var_name, ctx=ast.Load()),
+
99 ops=[ast.NotEq()],
+
100 comparators=[ast.Constant(value=-1, kind=None)]
+
101 )
+
102
+
103 # Create the dispatch table as a series of if/elif statements
+
104 dispatch_cases = []
+
105 for state_id, block in self.states.items():
+
106 # Create the condition (state == state_id)
+
107 condition = ast.Compare(
+
108 left=ast.Name(id=self.state_var_name, ctx=ast.Load()),
+
109 ops=[ast.Eq()],
+
110 comparators=[ast.Constant(value=state_id, kind=None)]
+
111 )
+
112
+
113 # Process the block statements
+
114 processed_block = []
+
115 for stmt in block:
+
116 processed_stmt = self.visit(stmt)
+
117 if isinstance(processed_stmt, list):
+
118 processed_block.extend(processed_stmt)
+
119 else:
+
120 processed_block.append(processed_stmt)
+
121
+
122 # If this block doesn't modify the state, add a transition to the next block
+
123 last_stmt = processed_block[-1] if processed_block else None
+
124 if not (isinstance(last_stmt, ast.Assign) and
+
125 isinstance(last_stmt.targets[0], ast.Name) and
+
126 last_stmt.targets[0].id == self.state_var_name):
+
127 # Add transition to next block
+
128 next_state = state_id + 1
+
129 if next_state not in self.states:
+
130 # If no next state, exit the loop
+
131 next_state = -1
+
132
+
133 processed_block.append(
+
134 ast.Assign(
+
135 targets=[ast.Name(id=self.state_var_name, ctx=ast.Store())],
+
136 value=ast.Constant(value=next_state, kind=None)
+
137 )
+
138 )
+
139
+
140 # Create the if/elif body
+
141 if_body = processed_block
+
142
+
143 # Add to dispatch cases
+
144 dispatch_cases.append((condition, if_body))
+
145
+
146 # Convert dispatch cases to if/elif/else structure
+
147 if_node = None
+
148 for i, (condition, body) in enumerate(reversed(dispatch_cases)):
+
149 if i == 0: # Last case (will be the 'else' clause)
+
150 if_node = ast.If(
+
151 test=condition,
+
152 body=body,
+
153 orelse=[]
+
154 )
+
155 else:
+
156 if_node = ast.If(
+
157 test=condition,
+
158 body=body,
+
159 orelse=[if_node] if if_node else []
+
160 )
+
161
+
162 # Create the while loop with the dispatch logic
+
163 while_body = [if_node] if if_node else []
+
164 while_loop = ast.While(
+
165 test=loop_condition,
+
166 body=while_body,
+
167 orelse=[]
+
168 )
+
169
+
170 # Add some junk code to obscure the control flow
+
171 junk = self.generate_junk_code()
+
172
+
173 # Assemble the flattened function body
+
174 flattened_body = [init_state] + junk + [while_loop]
+
175
+
176 return flattened_body
+
177
+
+
+
178 def generate_junk_code(self) -> List[ast.stmt]:
+
179 """Generate meaningless code to obscure the control flow."""
+
180 junk = []
+
181
+
182 # Add dummy variables that look like they're used for control flow
+
183 dummy_vars = [f"_cflow_{i}" for i in range(random.randint(2, 5))]
+
184 for var in dummy_vars:
+
185 # Initialize with random value
+
186 junk.append(
+
187 ast.Assign(
+
188 targets=[ast.Name(id=var, ctx=ast.Store())],
+
189 value=ast.Constant(value=random.randint(0, 100), kind=None)
+
190 )
+
191 )
+
192
+
193 # Add some conditional statements that don't do anything important
+
194 if dummy_vars:
+
195 cond = ast.Compare(
+
196 left=ast.Name(id=random.choice(dummy_vars), ctx=ast.Load()),
+
197 ops=[ast.Gt()],
+
198 comparators=[ast.Constant(value=50, kind=None)]
+
199 )
+
200
+
201 junk.append(
+
202 ast.If(
+
203 test=cond,
+
204 body=[
+
205 ast.Assign(
+
206 targets=[ast.Name(id=random.choice(dummy_vars), ctx=ast.Store())],
+
207 value=ast.Constant(value=random.randint(0, 100), kind=None)
+
208 )
+
209 ],
+
210 orelse=[]
+
211 )
+
212 )
+
213
+
214 if self.debug_mode:
+
215 self.log_debug("junk_code", {
+
216 "statements": len(junk),
+
217 "variables": dummy_vars
+
218 })
+
219
+
220 return junk
+
221
+
+
+
222 def visit_If(self, node: ast.If) -> ast.stmt:
+
223 """
+
224 Transform if statements into state transitions.
+
225 Conditional branches become separate states in the state machine.
+
226 """
+
227 # Create new states for the true and false branches
+
228 true_branch_id = self.current_block_id
+
229 self.current_block_id += 1
+
230 self.states[true_branch_id] = node.body
+
231
+
232 if node.orelse:
+
233 false_branch_id = self.current_block_id
+
234 self.current_block_id += 1
+
235 self.states[false_branch_id] = node.orelse
+
236 else:
+
237 # If no else branch, use the next block in sequence
+
238 false_branch_id = self.current_block_id
+
239
+
240 # Create a conditional assignment to the state variable
+
241 result = ast.Assign(
+
242 targets=[ast.Name(id=self.state_var_name, ctx=ast.Store())],
+
243 value=ast.IfExp(
+
244 test=self.visit(node.test),
+
245 body=ast.Constant(value=true_branch_id, kind=None),
+
246 orelse=ast.Constant(value=false_branch_id, kind=None)
+
247 )
+
248 )
+
249
+
250 if self.debug_mode:
+
251 self.log_debug("if_transformation", {
+
252 "true_branch": true_branch_id,
+
253 "false_branch": false_branch_id,
+
254 "has_else": bool(node.orelse)
+
255 })
+
256
+
257 return result
+
258
+
+
+
259 def visit_For(self, node: ast.For) -> List[ast.stmt]:
+
260 """
+
261 Transform for loops into state transitions with loop body and else clause
+
262 as separate states.
+
263 """
+
264 # Create unique variable names for this loop
+
265 iter_var = f"_iter_{self.current_block_id}"
+
266 index_var = f"_idx_{self.current_block_id}"
+
267
+
268 # Setup the iteration
+
269 setup_stmts = [
+
270 # Create iterator: _iter_X = iter(iterable)
+
271 ast.Assign(
+
272 targets=[ast.Name(id=iter_var, ctx=ast.Store())],
+
273 value=ast.Call(
+
274 func=ast.Name(id="iter", ctx=ast.Load()),
+
275 args=[self.visit(node.iter)],
+
276 keywords=[]
+
277 )
+
278 ),
+
279 # Initialize index: _idx_X = 0
+
280 ast.Assign(
+
281 targets=[ast.Name(id=index_var, ctx=ast.Store())],
+
282 value=ast.Constant(value=0, kind=None)
+
283 )
+
284 ]
+
285
+
286 # Create states for the loop body and else clause
+
287 loop_body_id = self.current_block_id
+
288 self.current_block_id += 1
+
289
+
290 # Loop body needs to get the next item and assign it to the target
+
291 loop_body = [
+
292 # try: target = next(_iter_X)
+
293 ast.Try(
+
294 body=[
+
295 ast.Assign(
+
296 targets=[self.visit(node.target)],
+
297 value=ast.Call(
+
298 func=ast.Name(id="next", ctx=ast.Load()),
+
299 args=[ast.Name(id=iter_var, ctx=ast.Load())],
+
300 keywords=[]
+
301 )
+
302 )
+
303 ],
+
304 # except StopIteration: goto else_clause or skip if no else
+
305 handlers=[
+
306 ast.ExceptHandler(
+
307 type=ast.Name(id="StopIteration", ctx=ast.Load()),
+
308 name=None,
+
309 body=[
+
310 ast.Assign(
+
311 targets=[ast.Name(id=self.state_var_name, ctx=ast.Store())],
+
312 value=ast.Constant(
+
313 value=(self.current_block_id if node.orelse else -1),
+
314 kind=None
+
315 )
+
316 )
+
317 ]
+
318 )
+
319 ],
+
320 # no finally
+
321 orelse=[],
+
322 finalbody=[]
+
323 )
+
324 ] + node.body + [
+
325 # Increment index
+
326 ast.AugAssign(
+
327 target=ast.Name(id=index_var, ctx=ast.Store()),
+
328 op=ast.Add(),
+
329 value=ast.Constant(value=1, kind=None)
+
330 ),
+
331 # Loop back to body
+
332 ast.Assign(
+
333 targets=[ast.Name(id=self.state_var_name, ctx=ast.Store())],
+
334 value=ast.Constant(value=loop_body_id, kind=None)
+
335 )
+
336 ]
+
337
+
338 self.states[loop_body_id] = loop_body
+
339
+
340 # Handle else clause if present
+
341 if node.orelse:
+
342 else_id = self.current_block_id
+
343 self.current_block_id += 1
+
344 self.states[else_id] = node.orelse
+
345
+
346 if self.debug_mode:
+
347 self.log_debug("for_loop_transformation", {
+
348 "iterator_var": iter_var,
+
349 "index_var": index_var,
+
350 "body_block": loop_body_id,
+
351 "has_else": bool(node.orelse),
+
352 "else_block": else_id if node.orelse else None
+
353 })
+
354
+
355 # Transition to the loop body after setup
+
356 setup_stmts.append(
+
357 ast.Assign(
+
358 targets=[ast.Name(id=self.state_var_name, ctx=ast.Store())],
+
359 value=ast.Constant(value=loop_body_id, kind=None)
+
360 )
+
361 )
+
362
+
363 return setup_stmts
+
364
+
+
+
365 def visit_While(self, node: ast.While) -> List[ast.stmt]:
+
366 """
+
367 Transform while loops into state transitions with conditional jumps.
+
368 """
+
369 # Create states for the condition check, body, and else clause
+
370 cond_check_id = self.current_block_id
+
371 self.current_block_id += 1
+
372
+
373 # Body state ID
+
374 body_id = self.current_block_id
+
375 self.current_block_id += 1
+
376
+
377 # Else state ID (if present)
+
378 else_id = self.current_block_id if node.orelse else -1
+
379 if node.orelse:
+
380 self.current_block_id += 1
+
381
+
382 # Condition check state: if test: goto body else: goto else/exit
+
383 cond_check = [
+
384 ast.Assign(
+
385 targets=[ast.Name(id=self.state_var_name, ctx=ast.Store())],
+
386 value=ast.IfExp(
+
387 test=self.visit(node.test),
+
388 body=ast.Constant(value=body_id, kind=None),
+
389 orelse=ast.Constant(value=else_id, kind=None)
+
390 )
+
391 )
+
392 ]
+
393 self.states[cond_check_id] = cond_check
+
394
+
395 # Body state: execute body then goto condition check
+
396 body = list(node.body) + [
+
397 ast.Assign(
+
398 targets=[ast.Name(id=self.state_var_name, ctx=ast.Store())],
+
399 value=ast.Constant(value=cond_check_id, kind=None)
+
400 )
+
401 ]
+
402 self.states[body_id] = body
+
403
+
404 # Else state (if present)
+
405 if node.orelse:
+
406 self.states[else_id] = node.orelse
+
407
+
408 if self.debug_mode:
+
409 self.log_debug("while_loop_transformation", {
+
410 "condition_check_block": cond_check_id,
+
411 "body_block": body_id,
+
412 "has_else": bool(node.orelse),
+
413 "else_block": else_id if else_id != -1 else None
+
414 })
+
415
+
416 # Initial transition to the condition check
+
417 return [
+
418 ast.Assign(
+
419 targets=[ast.Name(id=self.state_var_name, ctx=ast.Store())],
+
420 value=ast.Constant(value=cond_check_id, kind=None)
+
421 )
+
422 ]
+
423
+
+
+
424 def visit_Break(self, node: ast.Break) -> ast.Assign:
+
425 """
+
426 Transform break statements into a state change to exit the current loop.
+
427 In a flattened control flow, this means finding the next state after the loop.
+
428
+
429 For simplicity, we'll just set to -1 (terminate), but a more sophisticated
+
430 approach would track enclosing loops and their exit states.
+
431 """
+
432 if self.debug_mode:
+
433 self.log_debug("break_transformation", {
+
434 "exit_state": -1
+
435 })
+
436
+
437 return ast.Assign(
+
438 targets=[ast.Name(id=self.state_var_name, ctx=ast.Store())],
+
439 value=ast.Constant(value=-1, kind=None)
+
440 )
+
441
+
+
+
442 def visit_Continue(self, node: ast.Continue) -> ast.Assign:
+
443 """
+
444 Transform continue statements to go back to the loop condition.
+
445 In a flattened control flow, we need to know the loop condition state.
+
446
+
447 For simplicity, we'll implement a jump to the current state, effectively
+
448 rerunning the current block, but a more sophisticated approach would track
+
449 enclosing loops and their condition states.
+
450 """
+
451 if self.debug_mode:
+
452 self.log_debug("continue_transformation", {
+
453 "target_state": "current loop condition (simplified)"
+
454 })
+
455
+
456 # In this simplified model, we just loop back to the current state
+
457 # A more complete implementation would track the loop stack and jump to the loop start
+
458 return ast.Assign(
+
459 targets=[ast.Name(id=self.state_var_name, ctx=ast.Store())],
+
460 value=ast.Constant(value=0, kind=None)
+
461 )
+
462
+
+
+
463 def visit_Return(self, node: ast.Return) -> List[ast.stmt]:
+
464 """
+
465 Transform return statements into state transitions that terminate the function.
+
466 """
+
467 # Evaluate return value if present, then exit the state machine
+
468 if node.value:
+
469 return_stmt = ast.Return(value=self.visit(node.value))
+
470 exit_stmt = ast.Assign(
+
471 targets=[ast.Name(id=self.state_var_name, ctx=ast.Store())],
+
472 value=ast.Constant(value=-1, kind=None)
+
473 )
+
474
+
475 if self.debug_mode:
+
476 self.log_debug("return_transformation", {
+
477 "has_value": True
+
478 })
+
479
+
480 return [return_stmt, exit_stmt]
+
481 else:
+
482 # No return value
+
483 if self.debug_mode:
+
484 self.log_debug("return_transformation", {
+
485 "has_value": False
+
486 })
+
487
+
488 return [
+
489 ast.Return(value=None),
+
490 ast.Assign(
+
491 targets=[ast.Name(id=self.state_var_name, ctx=ast.Store())],
+
492 value=ast.Constant(value=-1, kind=None)
+
493 )
+
494 ]
+
+
+ + +
ast.Assign visit_Break(self, ast.Break node)
+
List[ast.stmt] visit_For(self, ast.For node)
+
ast.Assign visit_Continue(self, ast.Continue node)
+ + +
log_debug(self, str category, Any data)
+ + +
ast.FunctionDef visit_FunctionDef(self, ast.FunctionDef node)
+ + +
List[ast.stmt] visit_Return(self, ast.Return node)
+
List[ast.stmt] visit_While(self, ast.While node)
+ + +
+
+ + + + diff --git a/doxygen/dir_33a1d53dde8f74081d79f81ccfb4e6df.html b/doxygen/dir_33a1d53dde8f74081d79f81ccfb4e6df.html new file mode 100644 index 0000000..eb80bb2 --- /dev/null +++ b/doxygen/dir_33a1d53dde8f74081d79f81ccfb4e6df.html @@ -0,0 +1,124 @@ + + + + + + + +OMG-Fuscator: transformers Directory Reference + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
transformers Directory Reference
+
+
+ + + + + + + + + + + + + + + + +

+Files

 __init__.py
 
 attribute_transformer.py
 
 class_analyzer.py
 
 class_mapper.py
 
 control_flow.py
 
 rename.py
 
 symbol_tree.py
 
+
+
+ + + + diff --git a/doxygen/dir_33a1d53dde8f74081d79f81ccfb4e6df.js b/doxygen/dir_33a1d53dde8f74081d79f81ccfb4e6df.js new file mode 100644 index 0000000..69be00c --- /dev/null +++ b/doxygen/dir_33a1d53dde8f74081d79f81ccfb4e6df.js @@ -0,0 +1,10 @@ +var dir_33a1d53dde8f74081d79f81ccfb4e6df = +[ + [ "__init__.py", "transformers_2____init_____8py.html", null ], + [ "attribute_transformer.py", "attribute__transformer_8py.html", "attribute__transformer_8py" ], + [ "class_analyzer.py", "class__analyzer_8py.html", "class__analyzer_8py" ], + [ "class_mapper.py", "class__mapper_8py.html", "class__mapper_8py" ], + [ "control_flow.py", "control__flow_8py.html", "control__flow_8py" ], + [ "rename.py", "rename_8py.html", "rename_8py" ], + [ "symbol_tree.py", "symbol__tree_8py.html", "symbol__tree_8py" ] +]; \ No newline at end of file diff --git a/doxygen/dir_cbdb8362360e11eafe2fa3bc74cf0ffd.html b/doxygen/dir_cbdb8362360e11eafe2fa3bc74cf0ffd.html new file mode 100644 index 0000000..5777fdf --- /dev/null +++ b/doxygen/dir_cbdb8362360e11eafe2fa3bc74cf0ffd.html @@ -0,0 +1,118 @@ + + + + + + + +OMG-Fuscator: utils Directory Reference + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
utils Directory Reference
+
+
+ + + + + + + + + + +

+Files

 __init__.py
 
 encryption.py
 
 junk_gen.py
 
 name_gen.py
 
+
+
+ + + + diff --git a/doxygen/dir_cbdb8362360e11eafe2fa3bc74cf0ffd.js b/doxygen/dir_cbdb8362360e11eafe2fa3bc74cf0ffd.js new file mode 100644 index 0000000..8c8c159 --- /dev/null +++ b/doxygen/dir_cbdb8362360e11eafe2fa3bc74cf0ffd.js @@ -0,0 +1,7 @@ +var dir_cbdb8362360e11eafe2fa3bc74cf0ffd = +[ + [ "__init__.py", "utils_2____init_____8py.html", null ], + [ "encryption.py", "encryption_8py.html", "encryption_8py" ], + [ "junk_gen.py", "junk__gen_8py.html", "junk__gen_8py" ], + [ "name_gen.py", "name__gen_8py.html", "name__gen_8py" ] +]; \ No newline at end of file diff --git a/doxygen/doc.svg b/doxygen/doc.svg new file mode 100644 index 0000000..0b928a5 --- /dev/null +++ b/doxygen/doc.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/doxygen/docd.svg b/doxygen/docd.svg new file mode 100644 index 0000000..ac18b27 --- /dev/null +++ b/doxygen/docd.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/doxygen/doxygen.css b/doxygen/doxygen.css new file mode 100644 index 0000000..009a9b5 --- /dev/null +++ b/doxygen/doxygen.css @@ -0,0 +1,2045 @@ +/* The standard CSS for doxygen 1.9.8*/ + +html { +/* page base colors */ +--page-background-color: white; +--page-foreground-color: black; +--page-link-color: #3D578C; +--page-visited-link-color: #4665A2; + +/* index */ +--index-odd-item-bg-color: #F8F9FC; +--index-even-item-bg-color: white; +--index-header-color: black; +--index-separator-color: #A0A0A0; + +/* header */ +--header-background-color: #F9FAFC; +--header-separator-color: #C4CFE5; +--header-gradient-image: url('nav_h.png'); +--group-header-separator-color: #879ECB; +--group-header-color: #354C7B; +--inherit-header-color: gray; + +--footer-foreground-color: #2A3D61; +--footer-logo-width: 104px; +--citation-label-color: #334975; +--glow-color: cyan; + +--title-background-color: white; +--title-separator-color: #5373B4; +--directory-separator-color: #9CAFD4; +--separator-color: #4A6AAA; + +--blockquote-background-color: #F7F8FB; +--blockquote-border-color: #9CAFD4; + +--scrollbar-thumb-color: #9CAFD4; +--scrollbar-background-color: #F9FAFC; + +--icon-background-color: #728DC1; +--icon-foreground-color: white; +--icon-doc-image: url('doc.svg'); +--icon-folder-open-image: url('folderopen.svg'); +--icon-folder-closed-image: url('folderclosed.svg'); + +/* brief member declaration list */ +--memdecl-background-color: #F9FAFC; +--memdecl-separator-color: #DEE4F0; +--memdecl-foreground-color: #555; +--memdecl-template-color: #4665A2; + +/* detailed member list */ +--memdef-border-color: #A8B8D9; +--memdef-title-background-color: #E2E8F2; +--memdef-title-gradient-image: url('nav_f.png'); +--memdef-proto-background-color: #DFE5F1; +--memdef-proto-text-color: #253555; +--memdef-proto-text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); +--memdef-doc-background-color: white; +--memdef-param-name-color: #602020; +--memdef-template-color: #4665A2; + +/* tables */ +--table-cell-border-color: #2D4068; +--table-header-background-color: #374F7F; +--table-header-foreground-color: #FFFFFF; + +/* labels */ +--label-background-color: #728DC1; +--label-left-top-border-color: #5373B4; +--label-right-bottom-border-color: #C4CFE5; +--label-foreground-color: white; + +/** navigation bar/tree/menu */ +--nav-background-color: #F9FAFC; +--nav-foreground-color: #364D7C; +--nav-gradient-image: url('tab_b.png'); +--nav-gradient-hover-image: url('tab_h.png'); +--nav-gradient-active-image: url('tab_a.png'); +--nav-gradient-active-image-parent: url("../tab_a.png"); +--nav-separator-image: url('tab_s.png'); +--nav-breadcrumb-image: url('bc_s.png'); +--nav-breadcrumb-border-color: #C2CDE4; +--nav-splitbar-image: url('splitbar.png'); +--nav-font-size-level1: 13px; +--nav-font-size-level2: 10px; +--nav-font-size-level3: 9px; +--nav-text-normal-color: #283A5D; +--nav-text-hover-color: white; +--nav-text-active-color: white; +--nav-text-normal-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); +--nav-text-hover-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); +--nav-text-active-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); +--nav-menu-button-color: #364D7C; +--nav-menu-background-color: white; +--nav-menu-foreground-color: #555555; +--nav-menu-toggle-color: rgba(255, 255, 255, 0.5); +--nav-arrow-color: #9CAFD4; +--nav-arrow-selected-color: #9CAFD4; + +/* table of contents */ +--toc-background-color: #F4F6FA; +--toc-border-color: #D8DFEE; +--toc-header-color: #4665A2; +--toc-down-arrow-image: url("data:image/svg+xml;utf8,&%238595;"); + +/** search field */ +--search-background-color: white; +--search-foreground-color: #909090; +--search-magnification-image: url('mag.svg'); +--search-magnification-select-image: url('mag_sel.svg'); +--search-active-color: black; +--search-filter-background-color: #F9FAFC; +--search-filter-foreground-color: black; +--search-filter-border-color: #90A5CE; +--search-filter-highlight-text-color: white; +--search-filter-highlight-bg-color: #3D578C; +--search-results-foreground-color: #425E97; +--search-results-background-color: #EEF1F7; +--search-results-border-color: black; +--search-box-shadow: inset 0.5px 0.5px 3px 0px #555; + +/** code fragments */ +--code-keyword-color: #008000; +--code-type-keyword-color: #604020; +--code-flow-keyword-color: #E08000; +--code-comment-color: #800000; +--code-preprocessor-color: #806020; +--code-string-literal-color: #002080; +--code-char-literal-color: #008080; +--code-xml-cdata-color: black; +--code-vhdl-digit-color: #FF00FF; +--code-vhdl-char-color: #000000; +--code-vhdl-keyword-color: #700070; +--code-vhdl-logic-color: #FF0000; +--code-link-color: #4665A2; +--code-external-link-color: #4665A2; +--fragment-foreground-color: black; +--fragment-background-color: #FBFCFD; +--fragment-border-color: #C4CFE5; +--fragment-lineno-border-color: #00FF00; +--fragment-lineno-background-color: #E8E8E8; +--fragment-lineno-foreground-color: black; +--fragment-lineno-link-fg-color: #4665A2; +--fragment-lineno-link-bg-color: #D8D8D8; +--fragment-lineno-link-hover-fg-color: #4665A2; +--fragment-lineno-link-hover-bg-color: #C8C8C8; +--tooltip-foreground-color: black; +--tooltip-background-color: white; +--tooltip-border-color: gray; +--tooltip-doc-color: grey; +--tooltip-declaration-color: #006318; +--tooltip-link-color: #4665A2; +--tooltip-shadow: 1px 1px 7px gray; +--fold-line-color: #808080; +--fold-minus-image: url('minus.svg'); +--fold-plus-image: url('plus.svg'); +--fold-minus-image-relpath: url('../../minus.svg'); +--fold-plus-image-relpath: url('../../plus.svg'); + +/** font-family */ +--font-family-normal: Roboto,sans-serif; +--font-family-monospace: 'JetBrains Mono',Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace,fixed; +--font-family-nav: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; +--font-family-title: Tahoma,Arial,sans-serif; +--font-family-toc: Verdana,'DejaVu Sans',Geneva,sans-serif; +--font-family-search: Arial,Verdana,sans-serif; +--font-family-icon: Arial,Helvetica; +--font-family-tooltip: Roboto,sans-serif; + +} + +@media (prefers-color-scheme: dark) { + html:not(.dark-mode) { + color-scheme: dark; + +/* page base colors */ +--page-background-color: black; +--page-foreground-color: #C9D1D9; +--page-link-color: #90A5CE; +--page-visited-link-color: #A3B4D7; + +/* index */ +--index-odd-item-bg-color: #0B101A; +--index-even-item-bg-color: black; +--index-header-color: #C4CFE5; +--index-separator-color: #334975; + +/* header */ +--header-background-color: #070B11; +--header-separator-color: #141C2E; +--header-gradient-image: url('nav_hd.png'); +--group-header-separator-color: #283A5D; +--group-header-color: #90A5CE; +--inherit-header-color: #A0A0A0; + +--footer-foreground-color: #5B7AB7; +--footer-logo-width: 60px; +--citation-label-color: #90A5CE; +--glow-color: cyan; + +--title-background-color: #090D16; +--title-separator-color: #354C79; +--directory-separator-color: #283A5D; +--separator-color: #283A5D; + +--blockquote-background-color: #101826; +--blockquote-border-color: #283A5D; + +--scrollbar-thumb-color: #283A5D; +--scrollbar-background-color: #070B11; + +--icon-background-color: #334975; +--icon-foreground-color: #C4CFE5; +--icon-doc-image: url('docd.svg'); +--icon-folder-open-image: url('folderopend.svg'); +--icon-folder-closed-image: url('folderclosedd.svg'); + +/* brief member declaration list */ +--memdecl-background-color: #0B101A; +--memdecl-separator-color: #2C3F65; +--memdecl-foreground-color: #BBB; +--memdecl-template-color: #7C95C6; + +/* detailed member list */ +--memdef-border-color: #233250; +--memdef-title-background-color: #1B2840; +--memdef-title-gradient-image: url('nav_fd.png'); +--memdef-proto-background-color: #19243A; +--memdef-proto-text-color: #9DB0D4; +--memdef-proto-text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.9); +--memdef-doc-background-color: black; +--memdef-param-name-color: #D28757; +--memdef-template-color: #7C95C6; + +/* tables */ +--table-cell-border-color: #283A5D; +--table-header-background-color: #283A5D; +--table-header-foreground-color: #C4CFE5; + +/* labels */ +--label-background-color: #354C7B; +--label-left-top-border-color: #4665A2; +--label-right-bottom-border-color: #283A5D; +--label-foreground-color: #CCCCCC; + +/** navigation bar/tree/menu */ +--nav-background-color: #101826; +--nav-foreground-color: #364D7C; +--nav-gradient-image: url('tab_bd.png'); +--nav-gradient-hover-image: url('tab_hd.png'); +--nav-gradient-active-image: url('tab_ad.png'); +--nav-gradient-active-image-parent: url("../tab_ad.png"); +--nav-separator-image: url('tab_sd.png'); +--nav-breadcrumb-image: url('bc_sd.png'); +--nav-breadcrumb-border-color: #2A3D61; +--nav-splitbar-image: url('splitbard.png'); +--nav-font-size-level1: 13px; +--nav-font-size-level2: 10px; +--nav-font-size-level3: 9px; +--nav-text-normal-color: #B6C4DF; +--nav-text-hover-color: #DCE2EF; +--nav-text-active-color: #DCE2EF; +--nav-text-normal-shadow: 0px 1px 1px black; +--nav-text-hover-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); +--nav-text-active-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); +--nav-menu-button-color: #B6C4DF; +--nav-menu-background-color: #05070C; +--nav-menu-foreground-color: #BBBBBB; +--nav-menu-toggle-color: rgba(255, 255, 255, 0.2); +--nav-arrow-color: #334975; +--nav-arrow-selected-color: #90A5CE; + +/* table of contents */ +--toc-background-color: #151E30; +--toc-border-color: #202E4A; +--toc-header-color: #A3B4D7; +--toc-down-arrow-image: url("data:image/svg+xml;utf8,&%238595;"); + +/** search field */ +--search-background-color: black; +--search-foreground-color: #C5C5C5; +--search-magnification-image: url('mag_d.svg'); +--search-magnification-select-image: url('mag_seld.svg'); +--search-active-color: #C5C5C5; +--search-filter-background-color: #101826; +--search-filter-foreground-color: #90A5CE; +--search-filter-border-color: #7C95C6; +--search-filter-highlight-text-color: #BCC9E2; +--search-filter-highlight-bg-color: #283A5D; +--search-results-background-color: #101826; +--search-results-foreground-color: #90A5CE; +--search-results-border-color: #7C95C6; +--search-box-shadow: inset 0.5px 0.5px 3px 0px #2F436C; + +/** code fragments */ +--code-keyword-color: #CC99CD; +--code-type-keyword-color: #AB99CD; +--code-flow-keyword-color: #E08000; +--code-comment-color: #717790; +--code-preprocessor-color: #65CABE; +--code-string-literal-color: #7EC699; +--code-char-literal-color: #00E0F0; +--code-xml-cdata-color: #C9D1D9; +--code-vhdl-digit-color: #FF00FF; +--code-vhdl-char-color: #C0C0C0; +--code-vhdl-keyword-color: #CF53C9; +--code-vhdl-logic-color: #FF0000; +--code-link-color: #79C0FF; +--code-external-link-color: #79C0FF; +--fragment-foreground-color: #C9D1D9; +--fragment-background-color: black; +--fragment-border-color: #30363D; +--fragment-lineno-border-color: #30363D; +--fragment-lineno-background-color: black; +--fragment-lineno-foreground-color: #6E7681; +--fragment-lineno-link-fg-color: #6E7681; +--fragment-lineno-link-bg-color: #303030; +--fragment-lineno-link-hover-fg-color: #8E96A1; +--fragment-lineno-link-hover-bg-color: #505050; +--tooltip-foreground-color: #C9D1D9; +--tooltip-background-color: #202020; +--tooltip-border-color: #C9D1D9; +--tooltip-doc-color: #D9E1E9; +--tooltip-declaration-color: #20C348; +--tooltip-link-color: #79C0FF; +--tooltip-shadow: none; +--fold-line-color: #808080; +--fold-minus-image: url('minusd.svg'); +--fold-plus-image: url('plusd.svg'); +--fold-minus-image-relpath: url('../../minusd.svg'); +--fold-plus-image-relpath: url('../../plusd.svg'); + +/** font-family */ +--font-family-normal: Roboto,sans-serif; +--font-family-monospace: 'JetBrains Mono',Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace,fixed; +--font-family-nav: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; +--font-family-title: Tahoma,Arial,sans-serif; +--font-family-toc: Verdana,'DejaVu Sans',Geneva,sans-serif; +--font-family-search: Arial,Verdana,sans-serif; +--font-family-icon: Arial,Helvetica; +--font-family-tooltip: Roboto,sans-serif; + +}} +body { + background-color: var(--page-background-color); + color: var(--page-foreground-color); +} + +body, table, div, p, dl { + font-weight: 400; + font-size: 14px; + font-family: var(--font-family-normal); + line-height: 22px; +} + +/* @group Heading Levels */ + +.title { + font-weight: 400; + font-size: 14px; + font-family: var(--font-family-normal); + line-height: 28px; + font-size: 150%; + font-weight: bold; + margin: 10px 2px; +} + +h1.groupheader { + font-size: 150%; +} + +h2.groupheader { + border-bottom: 1px solid var(--group-header-separator-color); + color: var(--group-header-color); + font-size: 150%; + font-weight: normal; + margin-top: 1.75em; + padding-top: 8px; + padding-bottom: 4px; + width: 100%; +} + +h3.groupheader { + font-size: 100%; +} + +h1, h2, h3, h4, h5, h6 { + -webkit-transition: text-shadow 0.5s linear; + -moz-transition: text-shadow 0.5s linear; + -ms-transition: text-shadow 0.5s linear; + -o-transition: text-shadow 0.5s linear; + transition: text-shadow 0.5s linear; + margin-right: 15px; +} + +h1.glow, h2.glow, h3.glow, h4.glow, h5.glow, h6.glow { + text-shadow: 0 0 15px var(--glow-color); +} + +dt { + font-weight: bold; +} + +p.startli, p.startdd { + margin-top: 2px; +} + +th p.starttd, th p.intertd, th p.endtd { + font-size: 100%; + font-weight: 700; +} + +p.starttd { + margin-top: 0px; +} + +p.endli { + margin-bottom: 0px; +} + +p.enddd { + margin-bottom: 4px; +} + +p.endtd { + margin-bottom: 2px; +} + +p.interli { +} + +p.interdd { +} + +p.intertd { +} + +/* @end */ + +caption { + font-weight: bold; +} + +span.legend { + font-size: 70%; + text-align: center; +} + +h3.version { + font-size: 90%; + text-align: center; +} + +div.navtab { + padding-right: 15px; + text-align: right; + line-height: 110%; +} + +div.navtab table { + border-spacing: 0; +} + +td.navtab { + padding-right: 6px; + padding-left: 6px; +} + +td.navtabHL { + background-image: var(--nav-gradient-active-image); + background-repeat:repeat-x; + padding-right: 6px; + padding-left: 6px; +} + +td.navtabHL a, td.navtabHL a:visited { + color: var(--nav-text-hover-color); + text-shadow: var(--nav-text-hover-shadow); +} + +a.navtab { + font-weight: bold; +} + +div.qindex{ + text-align: center; + width: 100%; + line-height: 140%; + font-size: 130%; + color: var(--index-separator-color); +} + +#main-menu a:focus { + outline: auto; + z-index: 10; + position: relative; +} + +dt.alphachar{ + font-size: 180%; + font-weight: bold; +} + +.alphachar a{ + color: var(--index-header-color); +} + +.alphachar a:hover, .alphachar a:visited{ + text-decoration: none; +} + +.classindex dl { + padding: 25px; + column-count:1 +} + +.classindex dd { + display:inline-block; + margin-left: 50px; + width: 90%; + line-height: 1.15em; +} + +.classindex dl.even { + background-color: var(--index-even-item-bg-color); +} + +.classindex dl.odd { + background-color: var(--index-odd-item-bg-color); +} + +@media(min-width: 1120px) { + .classindex dl { + column-count:2 + } +} + +@media(min-width: 1320px) { + .classindex dl { + column-count:3 + } +} + + +/* @group Link Styling */ + +a { + color: var(--page-link-color); + font-weight: normal; + text-decoration: none; +} + +.contents a:visited { + color: var(--page-visited-link-color); +} + +a:hover { + text-decoration: underline; +} + +a.el { + font-weight: bold; +} + +a.elRef { +} + +a.code, a.code:visited, a.line, a.line:visited { + color: var(--code-link-color); +} + +a.codeRef, a.codeRef:visited, a.lineRef, a.lineRef:visited { + color: var(--code-external-link-color); +} + +a.code.hl_class { /* style for links to class names in code snippets */ } +a.code.hl_struct { /* style for links to struct names in code snippets */ } +a.code.hl_union { /* style for links to union names in code snippets */ } +a.code.hl_interface { /* style for links to interface names in code snippets */ } +a.code.hl_protocol { /* style for links to protocol names in code snippets */ } +a.code.hl_category { /* style for links to category names in code snippets */ } +a.code.hl_exception { /* style for links to exception names in code snippets */ } +a.code.hl_service { /* style for links to service names in code snippets */ } +a.code.hl_singleton { /* style for links to singleton names in code snippets */ } +a.code.hl_concept { /* style for links to concept names in code snippets */ } +a.code.hl_namespace { /* style for links to namespace names in code snippets */ } +a.code.hl_package { /* style for links to package names in code snippets */ } +a.code.hl_define { /* style for links to macro names in code snippets */ } +a.code.hl_function { /* style for links to function names in code snippets */ } +a.code.hl_variable { /* style for links to variable names in code snippets */ } +a.code.hl_typedef { /* style for links to typedef names in code snippets */ } +a.code.hl_enumvalue { /* style for links to enum value names in code snippets */ } +a.code.hl_enumeration { /* style for links to enumeration names in code snippets */ } +a.code.hl_signal { /* style for links to Qt signal names in code snippets */ } +a.code.hl_slot { /* style for links to Qt slot names in code snippets */ } +a.code.hl_friend { /* style for links to friend names in code snippets */ } +a.code.hl_dcop { /* style for links to KDE3 DCOP names in code snippets */ } +a.code.hl_property { /* style for links to property names in code snippets */ } +a.code.hl_event { /* style for links to event names in code snippets */ } +a.code.hl_sequence { /* style for links to sequence names in code snippets */ } +a.code.hl_dictionary { /* style for links to dictionary names in code snippets */ } + +/* @end */ + +dl.el { + margin-left: -1cm; +} + +ul { + overflow: visible; +} + +ul.multicol { + -moz-column-gap: 1em; + -webkit-column-gap: 1em; + column-gap: 1em; + -moz-column-count: 3; + -webkit-column-count: 3; + column-count: 3; + list-style-type: none; +} + +#side-nav ul { + overflow: visible; /* reset ul rule for scroll bar in GENERATE_TREEVIEW window */ +} + +#main-nav ul { + overflow: visible; /* reset ul rule for the navigation bar drop down lists */ +} + +.fragment { + text-align: left; + direction: ltr; + overflow-x: auto; /*Fixed: fragment lines overlap floating elements*/ + overflow-y: hidden; +} + +pre.fragment { + border: 1px solid var(--fragment-border-color); + background-color: var(--fragment-background-color); + color: var(--fragment-foreground-color); + padding: 4px 6px; + margin: 4px 8px 4px 2px; + overflow: auto; + word-wrap: break-word; + font-size: 9pt; + line-height: 125%; + font-family: var(--font-family-monospace); + font-size: 105%; +} + +div.fragment { + padding: 0 0 1px 0; /*Fixed: last line underline overlap border*/ + margin: 4px 8px 4px 2px; + color: var(--fragment-foreground-color); + background-color: var(--fragment-background-color); + border: 1px solid var(--fragment-border-color); +} + +div.line { + font-family: var(--font-family-monospace); + font-size: 13px; + min-height: 13px; + line-height: 1.2; + text-wrap: unrestricted; + white-space: -moz-pre-wrap; /* Moz */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + white-space: pre-wrap; /* CSS3 */ + word-wrap: break-word; /* IE 5.5+ */ + text-indent: -53px; + padding-left: 53px; + padding-bottom: 0px; + margin: 0px; + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +div.line:after { + content:"\000A"; + white-space: pre; +} + +div.line.glow { + background-color: var(--glow-color); + box-shadow: 0 0 10px var(--glow-color); +} + +span.fold { + margin-left: 5px; + margin-right: 1px; + margin-top: 0px; + margin-bottom: 0px; + padding: 0px; + display: inline-block; + width: 12px; + height: 12px; + background-repeat:no-repeat; + background-position:center; +} + +span.lineno { + padding-right: 4px; + margin-right: 9px; + text-align: right; + border-right: 2px solid var(--fragment-lineno-border-color); + color: var(--fragment-lineno-foreground-color); + background-color: var(--fragment-lineno-background-color); + white-space: pre; +} +span.lineno a, span.lineno a:visited { + color: var(--fragment-lineno-link-fg-color); + background-color: var(--fragment-lineno-link-bg-color); +} + +span.lineno a:hover { + color: var(--fragment-lineno-link-hover-fg-color); + background-color: var(--fragment-lineno-link-hover-bg-color); +} + +.lineno { + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +div.classindex ul { + list-style: none; + padding-left: 0; +} + +div.classindex span.ai { + display: inline-block; +} + +div.groupHeader { + margin-left: 16px; + margin-top: 12px; + font-weight: bold; +} + +div.groupText { + margin-left: 16px; + font-style: italic; +} + +body { + color: var(--page-foreground-color); + margin: 0; +} + +div.contents { + margin-top: 10px; + margin-left: 12px; + margin-right: 8px; +} + +p.formulaDsp { + text-align: center; +} + +img.dark-mode-visible { + display: none; +} +img.light-mode-visible { + display: none; +} + +img.formulaDsp { + +} + +img.formulaInl, img.inline { + vertical-align: middle; +} + +div.center { + text-align: center; + margin-top: 0px; + margin-bottom: 0px; + padding: 0px; +} + +div.center img { + border: 0px; +} + +address.footer { + text-align: right; + padding-right: 12px; +} + +img.footer { + border: 0px; + vertical-align: middle; + width: var(--footer-logo-width); +} + +.compoundTemplParams { + color: var(--memdecl-template-color); + font-size: 80%; + line-height: 120%; +} + +/* @group Code Colorization */ + +span.keyword { + color: var(--code-keyword-color); +} + +span.keywordtype { + color: var(--code-type-keyword-color); +} + +span.keywordflow { + color: var(--code-flow-keyword-color); +} + +span.comment { + color: var(--code-comment-color); +} + +span.preprocessor { + color: var(--code-preprocessor-color); +} + +span.stringliteral { + color: var(--code-string-literal-color); +} + +span.charliteral { + color: var(--code-char-literal-color); +} + +span.xmlcdata { + color: var(--code-xml-cdata-color); +} + +span.vhdldigit { + color: var(--code-vhdl-digit-color); +} + +span.vhdlchar { + color: var(--code-vhdl-char-color); +} + +span.vhdlkeyword { + color: var(--code-vhdl-keyword-color); +} + +span.vhdllogic { + color: var(--code-vhdl-logic-color); +} + +blockquote { + background-color: var(--blockquote-background-color); + border-left: 2px solid var(--blockquote-border-color); + margin: 0 24px 0 4px; + padding: 0 12px 0 16px; +} + +/* @end */ + +td.tiny { + font-size: 75%; +} + +.dirtab { + padding: 4px; + border-collapse: collapse; + border: 1px solid var(--table-cell-border-color); +} + +th.dirtab { + background-color: var(--table-header-background-color); + color: var(--table-header-foreground-color); + font-weight: bold; +} + +hr { + height: 0px; + border: none; + border-top: 1px solid var(--separator-color); +} + +hr.footer { + height: 1px; +} + +/* @group Member Descriptions */ + +table.memberdecls { + border-spacing: 0px; + padding: 0px; +} + +.memberdecls td, .fieldtable tr { + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +.memberdecls td.glow, .fieldtable tr.glow { + background-color: var(--glow-color); + box-shadow: 0 0 15px var(--glow-color); +} + +.mdescLeft, .mdescRight, +.memItemLeft, .memItemRight, +.memTemplItemLeft, .memTemplItemRight, .memTemplParams { + background-color: var(--memdecl-background-color); + border: none; + margin: 4px; + padding: 1px 0 0 8px; +} + +.mdescLeft, .mdescRight { + padding: 0px 8px 4px 8px; + color: var(--memdecl-foreground-color); +} + +.memSeparator { + border-bottom: 1px solid var(--memdecl-separator-color); + line-height: 1px; + margin: 0px; + padding: 0px; +} + +.memItemLeft, .memTemplItemLeft { + white-space: nowrap; +} + +.memItemRight, .memTemplItemRight { + width: 100%; +} + +.memTemplParams { + color: var(--memdecl-template-color); + white-space: nowrap; + font-size: 80%; +} + +/* @end */ + +/* @group Member Details */ + +/* Styles for detailed member documentation */ + +.memtitle { + padding: 8px; + border-top: 1px solid var(--memdef-border-color); + border-left: 1px solid var(--memdef-border-color); + border-right: 1px solid var(--memdef-border-color); + border-top-right-radius: 4px; + border-top-left-radius: 4px; + margin-bottom: -1px; + background-image: var(--memdef-title-gradient-image); + background-repeat: repeat-x; + background-color: var(--memdef-title-background-color); + line-height: 1.25; + font-weight: 300; + float:left; +} + +.permalink +{ + font-size: 65%; + display: inline-block; + vertical-align: middle; +} + +.memtemplate { + font-size: 80%; + color: var(--memdef-template-color); + font-weight: normal; + margin-left: 9px; +} + +.mempage { + width: 100%; +} + +.memitem { + padding: 0; + margin-bottom: 10px; + margin-right: 5px; + -webkit-transition: box-shadow 0.5s linear; + -moz-transition: box-shadow 0.5s linear; + -ms-transition: box-shadow 0.5s linear; + -o-transition: box-shadow 0.5s linear; + transition: box-shadow 0.5s linear; + display: table !important; + width: 100%; +} + +.memitem.glow { + box-shadow: 0 0 15px var(--glow-color); +} + +.memname { + font-weight: 400; + margin-left: 6px; +} + +.memname td { + vertical-align: bottom; +} + +.memproto, dl.reflist dt { + border-top: 1px solid var(--memdef-border-color); + border-left: 1px solid var(--memdef-border-color); + border-right: 1px solid var(--memdef-border-color); + padding: 6px 0px 6px 0px; + color: var(--memdef-proto-text-color); + font-weight: bold; + text-shadow: var(--memdef-proto-text-shadow); + background-color: var(--memdef-proto-background-color); + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + border-top-right-radius: 4px; +} + +.overload { + font-family: var(--font-family-monospace); + font-size: 65%; +} + +.memdoc, dl.reflist dd { + border-bottom: 1px solid var(--memdef-border-color); + border-left: 1px solid var(--memdef-border-color); + border-right: 1px solid var(--memdef-border-color); + padding: 6px 10px 2px 10px; + border-top-width: 0; + background-image:url('nav_g.png'); + background-repeat:repeat-x; + background-color: var(--memdef-doc-background-color); + /* opera specific markup */ + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + /* firefox specific markup */ + -moz-border-radius-bottomleft: 4px; + -moz-border-radius-bottomright: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + /* webkit specific markup */ + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); +} + +dl.reflist dt { + padding: 5px; +} + +dl.reflist dd { + margin: 0px 0px 10px 0px; + padding: 5px; +} + +.paramkey { + text-align: right; +} + +.paramtype { + white-space: nowrap; +} + +.paramname { + color: var(--memdef-param-name-color); + white-space: nowrap; +} +.paramname em { + font-style: normal; +} +.paramname code { + line-height: 14px; +} + +.params, .retval, .exception, .tparams { + margin-left: 0px; + padding-left: 0px; +} + +.params .paramname, .retval .paramname, .tparams .paramname, .exception .paramname { + font-weight: bold; + vertical-align: top; +} + +.params .paramtype, .tparams .paramtype { + font-style: italic; + vertical-align: top; +} + +.params .paramdir, .tparams .paramdir { + font-family: var(--font-family-monospace); + vertical-align: top; +} + +table.mlabels { + border-spacing: 0px; +} + +td.mlabels-left { + width: 100%; + padding: 0px; +} + +td.mlabels-right { + vertical-align: bottom; + padding: 0px; + white-space: nowrap; +} + +span.mlabels { + margin-left: 8px; +} + +span.mlabel { + background-color: var(--label-background-color); + border-top:1px solid var(--label-left-top-border-color); + border-left:1px solid var(--label-left-top-border-color); + border-right:1px solid var(--label-right-bottom-border-color); + border-bottom:1px solid var(--label-right-bottom-border-color); + text-shadow: none; + color: var(--label-foreground-color); + margin-right: 4px; + padding: 2px 3px; + border-radius: 3px; + font-size: 7pt; + white-space: nowrap; + vertical-align: middle; +} + + + +/* @end */ + +/* these are for tree view inside a (index) page */ + +div.directory { + margin: 10px 0px; + border-top: 1px solid var(--directory-separator-color); + border-bottom: 1px solid var(--directory-separator-color); + width: 100%; +} + +.directory table { + border-collapse:collapse; +} + +.directory td { + margin: 0px; + padding: 0px; + vertical-align: top; +} + +.directory td.entry { + white-space: nowrap; + padding-right: 6px; + padding-top: 3px; +} + +.directory td.entry a { + outline:none; +} + +.directory td.entry a img { + border: none; +} + +.directory td.desc { + width: 100%; + padding-left: 6px; + padding-right: 6px; + padding-top: 3px; + border-left: 1px solid rgba(0,0,0,0.05); +} + +.directory tr.odd { + padding-left: 6px; + background-color: var(--index-odd-item-bg-color); +} + +.directory tr.even { + padding-left: 6px; + background-color: var(--index-even-item-bg-color); +} + +.directory img { + vertical-align: -30%; +} + +.directory .levels { + white-space: nowrap; + width: 100%; + text-align: right; + font-size: 9pt; +} + +.directory .levels span { + cursor: pointer; + padding-left: 2px; + padding-right: 2px; + color: var(--page-link-color); +} + +.arrow { + color: var(--nav-arrow-color); + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + cursor: pointer; + font-size: 80%; + display: inline-block; + width: 16px; + height: 22px; +} + +.icon { + font-family: var(--font-family-icon); + line-height: normal; + font-weight: bold; + font-size: 12px; + height: 14px; + width: 16px; + display: inline-block; + background-color: var(--icon-background-color); + color: var(--icon-foreground-color); + text-align: center; + border-radius: 4px; + margin-left: 2px; + margin-right: 2px; +} + +.icona { + width: 24px; + height: 22px; + display: inline-block; +} + +.iconfopen { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:var(--icon-folder-open-image); + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +.iconfclosed { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:var(--icon-folder-closed-image); + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +.icondoc { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:var(--icon-doc-image); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +/* @end */ + +div.dynheader { + margin-top: 8px; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +address { + font-style: normal; + color: var(--footer-foreground-color); +} + +table.doxtable caption { + caption-side: top; +} + +table.doxtable { + border-collapse:collapse; + margin-top: 4px; + margin-bottom: 4px; +} + +table.doxtable td, table.doxtable th { + border: 1px solid var(--table-cell-border-color); + padding: 3px 7px 2px; +} + +table.doxtable th { + background-color: var(--table-header-background-color); + color: var(--table-header-foreground-color); + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; +} + +table.fieldtable { + margin-bottom: 10px; + border: 1px solid var(--memdef-border-color); + border-spacing: 0px; + border-radius: 4px; + box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); +} + +.fieldtable td, .fieldtable th { + padding: 3px 7px 2px; +} + +.fieldtable td.fieldtype, .fieldtable td.fieldname { + white-space: nowrap; + border-right: 1px solid var(--memdef-border-color); + border-bottom: 1px solid var(--memdef-border-color); + vertical-align: top; +} + +.fieldtable td.fieldname { + padding-top: 3px; +} + +.fieldtable td.fielddoc { + border-bottom: 1px solid var(--memdef-border-color); +} + +.fieldtable td.fielddoc p:first-child { + margin-top: 0px; +} + +.fieldtable td.fielddoc p:last-child { + margin-bottom: 2px; +} + +.fieldtable tr:last-child td { + border-bottom: none; +} + +.fieldtable th { + background-image: var(--memdef-title-gradient-image); + background-repeat:repeat-x; + background-color: var(--memdef-title-background-color); + font-size: 90%; + color: var(--memdef-proto-text-color); + padding-bottom: 4px; + padding-top: 5px; + text-align:left; + font-weight: 400; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-bottom: 1px solid var(--memdef-border-color); +} + + +.tabsearch { + top: 0px; + left: 10px; + height: 36px; + background-image: var(--nav-gradient-image); + z-index: 101; + overflow: hidden; + font-size: 13px; +} + +.navpath ul +{ + font-size: 11px; + background-image: var(--nav-gradient-image); + background-repeat:repeat-x; + background-position: 0 -5px; + height:30px; + line-height:30px; + color:var(--nav-text-normal-color); + border:solid 1px var(--nav-breadcrumb-border-color); + overflow:hidden; + margin:0px; + padding:0px; +} + +.navpath li +{ + list-style-type:none; + float:left; + padding-left:10px; + padding-right:15px; + background-image:var(--nav-breadcrumb-image); + background-repeat:no-repeat; + background-position:right; + color: var(--nav-foreground-color); +} + +.navpath li.navelem a +{ + height:32px; + display:block; + text-decoration: none; + outline: none; + color: var(--nav-text-normal-color); + font-family: var(--font-family-nav); + text-shadow: var(--nav-text-normal-shadow); + text-decoration: none; +} + +.navpath li.navelem a:hover +{ + color: var(--nav-text-hover-color); + text-shadow: var(--nav-text-hover-shadow); +} + +.navpath li.footer +{ + list-style-type:none; + float:right; + padding-left:10px; + padding-right:15px; + background-image:none; + background-repeat:no-repeat; + background-position:right; + color: var(--footer-foreground-color); + font-size: 8pt; +} + + +div.summary +{ + float: right; + font-size: 8pt; + padding-right: 5px; + width: 50%; + text-align: right; +} + +div.summary a +{ + white-space: nowrap; +} + +table.classindex +{ + margin: 10px; + white-space: nowrap; + margin-left: 3%; + margin-right: 3%; + width: 94%; + border: 0; + border-spacing: 0; + padding: 0; +} + +div.ingroups +{ + font-size: 8pt; + width: 50%; + text-align: left; +} + +div.ingroups a +{ + white-space: nowrap; +} + +div.header +{ + background-image: var(--header-gradient-image); + background-repeat:repeat-x; + background-color: var(--header-background-color); + margin: 0px; + border-bottom: 1px solid var(--header-separator-color); +} + +div.headertitle +{ + padding: 5px 5px 5px 10px; +} + +.PageDocRTL-title div.headertitle { + text-align: right; + direction: rtl; +} + +dl { + padding: 0 0 0 0; +} + +/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug, dl.examples */ +dl.section { + margin-left: 0px; + padding-left: 0px; +} + +dl.note { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #D0C000; +} + +dl.warning, dl.attention { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #FF0000; +} + +dl.pre, dl.post, dl.invariant { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #00D000; +} + +dl.deprecated { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #505050; +} + +dl.todo { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #00C0E0; +} + +dl.test { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #3030E0; +} + +dl.bug { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #C08050; +} + +dl.section dd { + margin-bottom: 6px; +} + + +#projectrow +{ + height: 56px; +} + +#projectlogo +{ + text-align: center; + vertical-align: bottom; + border-collapse: separate; +} + +#projectlogo img +{ + border: 0px none; +} + +#projectalign +{ + vertical-align: middle; + padding-left: 0.5em; +} + +#projectname +{ + font-size: 200%; + font-family: var(--font-family-title); + margin: 0px; + padding: 2px 0px; +} + +#projectbrief +{ + font-size: 90%; + font-family: var(--font-family-title); + margin: 0px; + padding: 0px; +} + +#projectnumber +{ + font-size: 50%; + font-family: 50% var(--font-family-title); + margin: 0px; + padding: 0px; +} + +#titlearea +{ + padding: 0px; + margin: 0px; + width: 100%; + border-bottom: 1px solid var(--title-separator-color); + background-color: var(--title-background-color); +} + +.image +{ + text-align: center; +} + +.dotgraph +{ + text-align: center; +} + +.mscgraph +{ + text-align: center; +} + +.plantumlgraph +{ + text-align: center; +} + +.diagraph +{ + text-align: center; +} + +.caption +{ + font-weight: bold; +} + +dl.citelist { + margin-bottom:50px; +} + +dl.citelist dt { + color:var(--citation-label-color); + float:left; + font-weight:bold; + margin-right:10px; + padding:5px; + text-align:right; + width:52px; +} + +dl.citelist dd { + margin:2px 0 2px 72px; + padding:5px 0; +} + +div.toc { + padding: 14px 25px; + background-color: var(--toc-background-color); + border: 1px solid var(--toc-border-color); + border-radius: 7px 7px 7px 7px; + float: right; + height: auto; + margin: 0 8px 10px 10px; + width: 200px; +} + +div.toc li { + background: var(--toc-down-arrow-image) no-repeat scroll 0 5px transparent; + font: 10px/1.2 var(--font-family-toc); + margin-top: 5px; + padding-left: 10px; + padding-top: 2px; +} + +div.toc h3 { + font: bold 12px/1.2 var(--font-family-toc); + color: var(--toc-header-color); + border-bottom: 0 none; + margin: 0; +} + +div.toc ul { + list-style: none outside none; + border: medium none; + padding: 0px; +} + +div.toc li.level1 { + margin-left: 0px; +} + +div.toc li.level2 { + margin-left: 15px; +} + +div.toc li.level3 { + margin-left: 15px; +} + +div.toc li.level4 { + margin-left: 15px; +} + +span.emoji { + /* font family used at the site: https://unicode.org/emoji/charts/full-emoji-list.html + * font-family: "Noto Color Emoji", "Apple Color Emoji", "Segoe UI Emoji", Times, Symbola, Aegyptus, Code2000, Code2001, Code2002, Musica, serif, LastResort; + */ +} + +span.obfuscator { + display: none; +} + +.inherit_header { + font-weight: bold; + color: var(--inherit-header-color); + cursor: pointer; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.inherit_header td { + padding: 6px 0px 2px 5px; +} + +.inherit { + display: none; +} + +tr.heading h2 { + margin-top: 12px; + margin-bottom: 4px; +} + +/* tooltip related style info */ + +.ttc { + position: absolute; + display: none; +} + +#powerTip { + cursor: default; + /*white-space: nowrap;*/ + color: var(--tooltip-foreground-color); + background-color: var(--tooltip-background-color); + border: 1px solid var(--tooltip-border-color); + border-radius: 4px 4px 4px 4px; + box-shadow: var(--tooltip-shadow); + display: none; + font-size: smaller; + max-width: 80%; + opacity: 0.9; + padding: 1ex 1em 1em; + position: absolute; + z-index: 2147483647; +} + +#powerTip div.ttdoc { + color: var(--tooltip-doc-color); + font-style: italic; +} + +#powerTip div.ttname a { + font-weight: bold; +} + +#powerTip a { + color: var(--tooltip-link-color); +} + +#powerTip div.ttname { + font-weight: bold; +} + +#powerTip div.ttdeci { + color: var(--tooltip-declaration-color); +} + +#powerTip div { + margin: 0px; + padding: 0px; + font-size: 12px; + font-family: var(--font-family-tooltip); + line-height: 16px; +} + +#powerTip:before, #powerTip:after { + content: ""; + position: absolute; + margin: 0px; +} + +#powerTip.n:after, #powerTip.n:before, +#powerTip.s:after, #powerTip.s:before, +#powerTip.w:after, #powerTip.w:before, +#powerTip.e:after, #powerTip.e:before, +#powerTip.ne:after, #powerTip.ne:before, +#powerTip.se:after, #powerTip.se:before, +#powerTip.nw:after, #powerTip.nw:before, +#powerTip.sw:after, #powerTip.sw:before { + border: solid transparent; + content: " "; + height: 0; + width: 0; + position: absolute; +} + +#powerTip.n:after, #powerTip.s:after, +#powerTip.w:after, #powerTip.e:after, +#powerTip.nw:after, #powerTip.ne:after, +#powerTip.sw:after, #powerTip.se:after { + border-color: rgba(255, 255, 255, 0); +} + +#powerTip.n:before, #powerTip.s:before, +#powerTip.w:before, #powerTip.e:before, +#powerTip.nw:before, #powerTip.ne:before, +#powerTip.sw:before, #powerTip.se:before { + border-color: rgba(128, 128, 128, 0); +} + +#powerTip.n:after, #powerTip.n:before, +#powerTip.ne:after, #powerTip.ne:before, +#powerTip.nw:after, #powerTip.nw:before { + top: 100%; +} + +#powerTip.n:after, #powerTip.ne:after, #powerTip.nw:after { + border-top-color: var(--tooltip-background-color); + border-width: 10px; + margin: 0px -10px; +} +#powerTip.n:before, #powerTip.ne:before, #powerTip.nw:before { + border-top-color: var(--tooltip-border-color); + border-width: 11px; + margin: 0px -11px; +} +#powerTip.n:after, #powerTip.n:before { + left: 50%; +} + +#powerTip.nw:after, #powerTip.nw:before { + right: 14px; +} + +#powerTip.ne:after, #powerTip.ne:before { + left: 14px; +} + +#powerTip.s:after, #powerTip.s:before, +#powerTip.se:after, #powerTip.se:before, +#powerTip.sw:after, #powerTip.sw:before { + bottom: 100%; +} + +#powerTip.s:after, #powerTip.se:after, #powerTip.sw:after { + border-bottom-color: var(--tooltip-background-color); + border-width: 10px; + margin: 0px -10px; +} + +#powerTip.s:before, #powerTip.se:before, #powerTip.sw:before { + border-bottom-color: var(--tooltip-border-color); + border-width: 11px; + margin: 0px -11px; +} + +#powerTip.s:after, #powerTip.s:before { + left: 50%; +} + +#powerTip.sw:after, #powerTip.sw:before { + right: 14px; +} + +#powerTip.se:after, #powerTip.se:before { + left: 14px; +} + +#powerTip.e:after, #powerTip.e:before { + left: 100%; +} +#powerTip.e:after { + border-left-color: var(--tooltip-border-color); + border-width: 10px; + top: 50%; + margin-top: -10px; +} +#powerTip.e:before { + border-left-color: var(--tooltip-border-color); + border-width: 11px; + top: 50%; + margin-top: -11px; +} + +#powerTip.w:after, #powerTip.w:before { + right: 100%; +} +#powerTip.w:after { + border-right-color: var(--tooltip-border-color); + border-width: 10px; + top: 50%; + margin-top: -10px; +} +#powerTip.w:before { + border-right-color: var(--tooltip-border-color); + border-width: 11px; + top: 50%; + margin-top: -11px; +} + +@media print +{ + #top { display: none; } + #side-nav { display: none; } + #nav-path { display: none; } + body { overflow:visible; } + h1, h2, h3, h4, h5, h6 { page-break-after: avoid; } + .summary { display: none; } + .memitem { page-break-inside: avoid; } + #doc-content + { + margin-left:0 !important; + height:auto !important; + width:auto !important; + overflow:inherit; + display:inline; + } +} + +/* @group Markdown */ + +table.markdownTable { + border-collapse:collapse; + margin-top: 4px; + margin-bottom: 4px; +} + +table.markdownTable td, table.markdownTable th { + border: 1px solid var(--table-cell-border-color); + padding: 3px 7px 2px; +} + +table.markdownTable tr { +} + +th.markdownTableHeadLeft, th.markdownTableHeadRight, th.markdownTableHeadCenter, th.markdownTableHeadNone { + background-color: var(--table-header-background-color); + color: var(--table-header-foreground-color); + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; +} + +th.markdownTableHeadLeft, td.markdownTableBodyLeft { + text-align: left +} + +th.markdownTableHeadRight, td.markdownTableBodyRight { + text-align: right +} + +th.markdownTableHeadCenter, td.markdownTableBodyCenter { + text-align: center +} + +tt, code, kbd, samp +{ + display: inline-block; +} +/* @end */ + +u { + text-decoration: underline; +} + +details>summary { + list-style-type: none; +} + +details > summary::-webkit-details-marker { + display: none; +} + +details>summary::before { + content: "\25ba"; + padding-right:4px; + font-size: 80%; +} + +details[open]>summary::before { + content: "\25bc"; + padding-right:4px; + font-size: 80%; +} + +body { + scrollbar-color: var(--scrollbar-thumb-color) var(--scrollbar-background-color); +} + +::-webkit-scrollbar { + background-color: var(--scrollbar-background-color); + height: 12px; + width: 12px; +} +::-webkit-scrollbar-thumb { + border-radius: 6px; + box-shadow: inset 0 0 12px 12px var(--scrollbar-thumb-color); + border: solid 2px transparent; +} +::-webkit-scrollbar-corner { + background-color: var(--scrollbar-background-color); +} + diff --git a/doxygen/doxygen.svg b/doxygen/doxygen.svg new file mode 100644 index 0000000..79a7635 --- /dev/null +++ b/doxygen/doxygen.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doxygen/dynsections.js b/doxygen/dynsections.js new file mode 100644 index 0000000..9b28156 --- /dev/null +++ b/doxygen/dynsections.js @@ -0,0 +1,199 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @licend The above is the entire license notice for the JavaScript code in this file + */ +function toggleVisibility(linkObj) +{ + var base = $(linkObj).attr('id'); + var summary = $('#'+base+'-summary'); + var content = $('#'+base+'-content'); + var trigger = $('#'+base+'-trigger'); + var src=$(trigger).attr('src'); + if (content.is(':visible')===true) { + content.hide(); + summary.show(); + $(linkObj).addClass('closed').removeClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-8)+'closed.png'); + } else { + content.show(); + summary.hide(); + $(linkObj).removeClass('closed').addClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-10)+'open.png'); + } + return false; +} + +function updateStripes() +{ + $('table.directory tr'). + removeClass('even').filter(':visible:even').addClass('even'); + $('table.directory tr'). + removeClass('odd').filter(':visible:odd').addClass('odd'); +} + +function toggleLevel(level) +{ + $('table.directory tr').each(function() { + var l = this.id.split('_').length-1; + var i = $('#img'+this.id.substring(3)); + var a = $('#arr'+this.id.substring(3)); + if (l'); + // add vertical lines to other rows + $('span[class=lineno]').not(':eq(0)').append(''); + // add toggle controls to lines with fold divs + $('div[class=foldopen]').each(function() { + // extract specific id to use + var id = $(this).attr('id').replace('foldopen',''); + // extract start and end foldable fragment attributes + var start = $(this).attr('data-start'); + var end = $(this).attr('data-end'); + // replace normal fold span with controls for the first line of a foldable fragment + $(this).find('span[class=fold]:first').replaceWith(''); + // append div for folded (closed) representation + $(this).after(''); + // extract the first line from the "open" section to represent closed content + var line = $(this).children().first().clone(); + // remove any glow that might still be active on the original line + $(line).removeClass('glow'); + if (start) { + // if line already ends with a start marker (e.g. trailing {), remove it + $(line).html($(line).html().replace(new RegExp('\\s*'+start+'\\s*$','g'),'')); + } + // replace minus with plus symbol + $(line).find('span[class=fold]').css('background-image',plusImg[relPath]); + // append ellipsis + $(line).append(' '+start+''+end); + // insert constructed line into closed div + $('#foldclosed'+id).html(line); + }); +} + +/* @license-end */ +$(document).ready(function() { + $('.code,.codeRef').each(function() { + $(this).data('powertip',$('#a'+$(this).attr('href').replace(/.*\//,'').replace(/[^a-z_A-Z0-9]/g,'_')).html()); + $.fn.powerTip.smartPlacementLists.s = [ 's', 'n', 'ne', 'se' ]; + $(this).powerTip({ placement: 's', smartPlacement: true, mouseOnToPopup: true }); + }); +}); diff --git a/doxygen/encryption_8py.html b/doxygen/encryption_8py.html new file mode 100644 index 0000000..e28d717 --- /dev/null +++ b/doxygen/encryption_8py.html @@ -0,0 +1,124 @@ + + + + + + + +OMG-Fuscator: encryption.py File Reference + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
encryption.py File Reference
+
+
+ +

Go to the source code of this file.

+ + + + +

+Classes

class  utils.encryption.StringEncryptor
 
+ + + + + +

+Namespaces

namespace  utils
 
namespace  utils.encryption
 
+
+
+ + + + diff --git a/doxygen/encryption_8py.js b/doxygen/encryption_8py.js new file mode 100644 index 0000000..40c16f8 --- /dev/null +++ b/doxygen/encryption_8py.js @@ -0,0 +1,4 @@ +var encryption_8py = +[ + [ "utils.encryption.StringEncryptor", "classutils_1_1encryption_1_1StringEncryptor.html", "classutils_1_1encryption_1_1StringEncryptor" ] +]; \ No newline at end of file diff --git a/doxygen/encryption_8py_source.html b/doxygen/encryption_8py_source.html new file mode 100644 index 0000000..17fc648 --- /dev/null +++ b/doxygen/encryption_8py_source.html @@ -0,0 +1,229 @@ + + + + + + + +OMG-Fuscator: encryption.py Source File + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
encryption.py
+
+
+Go to the documentation of this file.
1"""
+
2@file utils/encryption.py
+
3@brief String encryption utilities for OMG-Fuscator.
+
4@details Provides the StringEncryptor used by the obfuscation pipeline to transform
+
5 string literals into runtime-decrypted expressions, making static analysis
+
6 significantly harder.
+
7"""
+
8
+
9import base64
+
10import hashlib
+
11import random
+
12from typing import Tuple
+
13
+
+ +
15 """
+
16 @brief Encrypts strings for obfuscation using layered XOR and Base85 encoding.
+
17 @details Produces both an encoded payload and Python code that reconstructs
+
18 the keys at runtime without embedding raw key bytes.
+
19 """
+
+
20 def __init__(self, primary_key: bytes, secondary_key: bytes, salt: bytes):
+
21 """
+
22 @brief Initialize encryptor keys.
+
23 @param primary_key Primary XOR key bytes.
+
24 @param secondary_key Secondary XOR key bytes.
+
25 @param salt Salt bytes used to derive a per-string modifier.
+
26 """
+
27 self.primary_key = primary_key
+
28 self.secondary_key = secondary_key
+
29 self.salt = salt
+
30
+
+
+
31 def hide_byte(self, b: int) -> str:
+
32 """
+
33 @brief Obfuscate a single key byte into an arithmetic/bitwise expression.
+
34 @param b Input byte value in range [0, 255].
+
35 @return Python expression string that evaluates to the original byte at runtime.
+
36 """
+
37 pattern = random.randint(1, 5)
+
38 if pattern == 1:
+
39 x1, x2, x3 = [random.randint(65, 90) for _ in range(3)]
+
40 result = x1 ^ x2 ^ x3 ^ b
+
41 return f"({x1}^{x2}^{x3}^{result})"
+
42 elif pattern == 2:
+
43 base = random.randint(65, 90)
+
44 multiplier = random.randint(2, 4)
+
45 adjusted = (base * multiplier - b)
+
46 return f"(({base}*{multiplier}-{adjusted}))"
+
47 elif pattern == 3:
+
48 shift = random.randint(1, 3)
+
49 modified = (b << shift) >> shift
+
50 diff = b - modified
+
51 return f"((({b << shift})>>{shift})+{diff})"
+
52 elif pattern == 4:
+
53 char1, char2 = random.sample(range(65, 91), 2)
+
54 result = char1 + char2 - b
+
55 return f"({char1}+{char2}-{result})"
+
56 else:
+
57 mod_base = random.randint(91, 100)
+
58 result = b % mod_base
+
59 factor = b // mod_base
+
60 return f"({factor}*{mod_base}+{result})"
+
61
+
+
+
62 def encrypt_string(self, s: str) -> Tuple[str, str, str]:
+
63 """
+
64 @brief Encrypt a string with layered XOR and Base85 encoding.
+
65 @param s UTF-8 string to encrypt.
+
66 @return Tuple[str, str, str]:
+
67 - encoded: Base85 text of the encrypted payload
+
68 - key_setup: Python code that reconstructs keys at runtime
+
69 - modifier_hex: Hex string for the per-string modifier
+
70 """
+
71 data = s.encode('utf-8')
+
72 modifier = hashlib.sha256(self.salt + data).digest()[:8]
+
73
+
74 layer1 = bytes(
+
75 d ^ k ^ m
+
76 for d, k, m in zip(
+
77 data,
+
78 self.primary_key * ((len(data) // len(self.primary_key)) + 1),
+
79 modifier * ((len(data) // len(modifier)) + 1)
+
80 )
+
81 )
+
82
+
83 final_data = bytes(
+
84 d ^ k
+
85 for d, k in zip(
+
86 layer1,
+
87 self.secondary_key * ((len(layer1) // len(self.secondary_key)) + 1)
+
88 )
+
89 )
+
90
+
91 encoded = base64.b85encode(final_data).decode()
+
92
+
93 primary_key_code = f"bytes([{','.join(self.hide_byte(b) for b in self.primary_key)}])"
+
94 secondary_key_code = f"bytes([{','.join(self.hide_byte(b) for b in self.secondary_key)}])"
+
95 salt_code = f"bytes([{','.join(self.hide_byte(b) for b in self.salt)}])"
+
96
+
97 key_setup = (
+
98 f"_pk = {primary_key_code}\n"
+
99 f"_sk = {secondary_key_code}\n"
+
100 f"_st = {salt_code}"
+
101 )
+
102
+
103 return encoded, key_setup, modifier.hex()
+
+
+ + + + +
Tuple[str, str, str] encrypt_string(self, str s)
Definition encryption.py:62
+ +
__init__(self, bytes primary_key, bytes secondary_key, bytes salt)
Definition encryption.py:20
+
+
+ + + + diff --git a/doxygen/files.html b/doxygen/files.html new file mode 100644 index 0000000..e1985c6 --- /dev/null +++ b/doxygen/files.html @@ -0,0 +1,124 @@ + + + + + + + +OMG-Fuscator: File List + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
File List
+
+
+
Here is a list of all files with brief descriptions:
+
+
+ + + + diff --git a/doxygen/files_dup.js b/doxygen/files_dup.js new file mode 100644 index 0000000..2786f56 --- /dev/null +++ b/doxygen/files_dup.js @@ -0,0 +1,7 @@ +var files_dup = +[ + [ "transformers", "dir_33a1d53dde8f74081d79f81ccfb4e6df.html", "dir_33a1d53dde8f74081d79f81ccfb4e6df" ], + [ "utils", "dir_cbdb8362360e11eafe2fa3bc74cf0ffd.html", "dir_cbdb8362360e11eafe2fa3bc74cf0ffd" ], + [ "main.py", "main_8py.html", "main_8py" ], + [ "obfuscator.py", "obfuscator_8py.html", "obfuscator_8py" ] +]; \ No newline at end of file diff --git a/doxygen/folderclosed.svg b/doxygen/folderclosed.svg new file mode 100644 index 0000000..b04bed2 --- /dev/null +++ b/doxygen/folderclosed.svg @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/doxygen/folderclosedd.svg b/doxygen/folderclosedd.svg new file mode 100644 index 0000000..52f0166 --- /dev/null +++ b/doxygen/folderclosedd.svg @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/doxygen/folderopen.svg b/doxygen/folderopen.svg new file mode 100644 index 0000000..f6896dd --- /dev/null +++ b/doxygen/folderopen.svg @@ -0,0 +1,17 @@ + + + + + + + + + + diff --git a/doxygen/folderopend.svg b/doxygen/folderopend.svg new file mode 100644 index 0000000..2d1f06e --- /dev/null +++ b/doxygen/folderopend.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/doxygen/functions.html b/doxygen/functions.html new file mode 100644 index 0000000..f66ecfc --- /dev/null +++ b/doxygen/functions.html @@ -0,0 +1,307 @@ + + + + + + + +OMG-Fuscator: Class Members + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- _ -

+ + +

- a -

+ + +

- b -

+ + +

- c -

+ + +

- d -

+ + +

- e -

+ + +

- f -

+ + +

- g -

+ + +

- h -

+ + +

- i -

+ + +

- j -

+ + +

- k -

+ + +

- l -

+ + +

- m -

+ + +

- n -

+ + +

- o -

+ + +

- p -

+ + +

- r -

+ + +

- s -

+ + +

- t -

+ + +

- u -

+ + +

- v -

+
+
+ + + + diff --git a/doxygen/functions_func.html b/doxygen/functions_func.html new file mode 100644 index 0000000..73cd4de --- /dev/null +++ b/doxygen/functions_func.html @@ -0,0 +1,232 @@ + + + + + + + +OMG-Fuscator: Class Members - Functions + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all functions with links to the classes they belong to:
+ +

- _ -

+ + +

- a -

+ + +

- b -

+ + +

- c -

+ + +

- d -

+ + +

- e -

+ + +

- f -

+ + +

- g -

+ + +

- h -

+ + +

- l -

+ + +

- o -

+ + +

- p -

+ + +

- r -

+ + +

- s -

+ + +

- v -

+
+
+ + + + diff --git a/doxygen/functions_vars.html b/doxygen/functions_vars.html new file mode 100644 index 0000000..3968d66 --- /dev/null +++ b/doxygen/functions_vars.html @@ -0,0 +1,221 @@ + + + + + + + +OMG-Fuscator: Class Members - Variables + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all variables with links to the classes they belong to:
+ +

- _ -

+ + +

- a -

+ + +

- c -

+ + +

- d -

+ + +

- e -

+ + +

- f -

+ + +

- g -

+ + +

- i -

+ + +

- j -

+ + +

- k -

+ + +

- m -

+ + +

- n -

+ + +

- p -

+ + +

- r -

+ + +

- s -

+ + +

- t -

+ + +

- u -

+ + +

- v -

+
+
+ + + + diff --git a/doxygen/graph_legend.dot b/doxygen/graph_legend.dot new file mode 100644 index 0000000..97a6d61 --- /dev/null +++ b/doxygen/graph_legend.dot @@ -0,0 +1,24 @@ +digraph "Graph Legend" +{ + // LATEX_PDF_SIZE + bgcolor="transparent"; + edge [fontname=Helvetica,fontsize=10,labelfontname=Helvetica,labelfontsize=10]; + node [fontname=Helvetica,fontsize=10,shape=box,height=0.2,width=0.4]; + Node9 [id="Node000009",label="Inherited",height=0.2,width=0.4,color="gray40", fillcolor="grey60", style="filled", fontcolor="black",tooltip=" "]; + Node10 -> Node9 [dir="back",color="steelblue1",style="solid" tooltip=" "]; + Node10 [id="Node000010",label="PublicBase",height=0.2,width=0.4,color="grey40", fillcolor="white", style="filled",tooltip=" "]; + Node11 -> Node10 [dir="back",color="steelblue1",style="solid" tooltip=" "]; + Node11 [id="Node000011",label="Truncated",height=0.2,width=0.4,color="red", fillcolor="#FFF0F0", style="filled",tooltip=" "]; + Node13 -> Node9 [dir="back",color="darkgreen",style="solid" tooltip=" "]; + Node13 [label="ProtectedBase",color="gray40",fillcolor="white",style="filled" tooltip=" "]; + Node14 -> Node9 [dir="back",color="firebrick4",style="solid" tooltip=" "]; + Node14 [label="PrivateBase",color="gray40",fillcolor="white",style="filled" tooltip=" "]; + Node15 -> Node9 [dir="back",color="steelblue1",style="solid" tooltip=" "]; + Node15 [id="Node000015",label="Undocumented",height=0.2,width=0.4,color="grey60", fillcolor="#E0E0E0", style="filled",tooltip=" "]; + Node16 -> Node9 [dir="back",color="steelblue1",style="solid" tooltip=" "]; + Node16 [label="Templ\< int \>",color="gray40",fillcolor="white",style="filled" tooltip=" "]; + Node17 -> Node16 [dir="back",color="orange",style="dashed",label="< int >",fontcolor="grey" tooltip=" "]; + Node17 [label="Templ\< T \>",color="gray40",fillcolor="white",style="filled" tooltip=" "]; + Node18 -> Node9 [dir="back",color="darkorchid3",style="dashed",label="m_usedClass",fontcolor="grey" tooltip=" "]; + Node18 [label="Used",color="gray40",fillcolor="white",style="filled" tooltip=" "]; +} diff --git a/doxygen/graph_legend.html b/doxygen/graph_legend.html new file mode 100644 index 0000000..61e6767 --- /dev/null +++ b/doxygen/graph_legend.html @@ -0,0 +1,165 @@ + + + + + + + +OMG-Fuscator: Graph Legend + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Graph Legend
+
+
+

This page explains how to interpret the graphs that are generated by doxygen.

+

Consider the following example:

/*! Invisible class because of truncation */
+
class Invisible { };
+
+
/*! Truncated class, inheritance relation is hidden */
+
class Truncated : public Invisible { };
+
+
/* Class not documented with doxygen comments */
+
class Undocumented { };
+
+
/*! Class that is inherited using public inheritance */
+
class PublicBase : public Truncated { };
+
+
/*! A template class */
+
template<class T> class Templ { };
+
+
/*! Class that is inherited using protected inheritance */
+
class ProtectedBase { };
+
+
/*! Class that is inherited using private inheritance */
+
class PrivateBase { };
+
+
/*! Class that is used by the Inherited class */
+
class Used { };
+
+
/*! Super class that inherits a number of other classes */
+
class Inherited : public PublicBase,
+
protected ProtectedBase,
+
private PrivateBase,
+
public Undocumented,
+
public Templ<int>
+
{
+
private:
+
Used *m_usedClass;
+
};
+

This will result in the following graph:

+

The boxes in the above graph have the following meaning:

+
    +
  • +A filled gray box represents the struct or class for which the graph is generated.
  • +
  • +A box with a black border denotes a documented struct or class.
  • +
  • +A box with a gray border denotes an undocumented struct or class.
  • +
  • +A box with a red border denotes a documented struct or class forwhich not all inheritance/containment relations are shown. A graph is truncated if it does not fit within the specified boundaries.
  • +
+

The arrows have the following meaning:

+
    +
  • +A blue arrow is used to visualize a public inheritance relation between two classes.
  • +
  • +A dark green arrow is used for protected inheritance.
  • +
  • +A dark red arrow is used for private inheritance.
  • +
  • +A purple dashed arrow is used if a class is contained or used by another class. The arrow is labelled with the variable(s) through which the pointed class or struct is accessible.
  • +
  • +A yellow dashed arrow denotes a relation between a template instance and the template class it was instantiated from. The arrow is labelled with the template parameters of the instance.
  • +
+
+
+ + + + diff --git a/doxygen/hierarchy.html b/doxygen/hierarchy.html new file mode 100644 index 0000000..0ee9ae1 --- /dev/null +++ b/doxygen/hierarchy.html @@ -0,0 +1,133 @@ + + + + + + + +OMG-Fuscator: Class Hierarchy + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ + + + + + diff --git a/doxygen/hierarchy.js b/doxygen/hierarchy.js new file mode 100644 index 0000000..edfcfc6 --- /dev/null +++ b/doxygen/hierarchy.js @@ -0,0 +1,29 @@ +var hierarchy = +[ + [ "ast.NodeTransformer", null, [ + [ "transformers.attribute_transformer.AttributeTransformer", "classtransformers_1_1attribute__transformer_1_1AttributeTransformer.html", null ], + [ "transformers.class_mapper.ClassTransformer", "classtransformers_1_1class__mapper_1_1ClassTransformer.html", null ], + [ "transformers.control_flow.ControlFlowFlattener", "classtransformers_1_1control__flow_1_1ControlFlowFlattener.html", null ], + [ "transformers.rename.RenameTransformer", "classtransformers_1_1rename_1_1RenameTransformer.html", null ] + ] ], + [ "ast.NodeVisitor", null, [ + [ "transformers.class_analyzer.ClassAnalyzer", "classtransformers_1_1class__analyzer_1_1ClassAnalyzer.html", null ], + [ "transformers.class_mapper.ClassMapAnalyzer", "classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html", null ], + [ "transformers.symbol_tree.SymbolTreeBuilder", "classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html", null ] + ] ], + [ "obfuscator.AdvancedObfuscator", "classobfuscator_1_1AdvancedObfuscator.html", null ], + [ "transformers.class_analyzer.ClassMethodMap", "classtransformers_1_1class__analyzer_1_1ClassMethodMap.html", null ], + [ "transformers.class_mapper.ClassMapping", "classtransformers_1_1class__mapper_1_1ClassMapping.html", null ], + [ "transformers.symbol_tree.Scope", "classtransformers_1_1symbol__tree_1_1Scope.html", [ + [ "transformers.symbol_tree.ClassScope", "classtransformers_1_1symbol__tree_1_1ClassScope.html", null ], + [ "transformers.symbol_tree.ModuleScope", "classtransformers_1_1symbol__tree_1_1ModuleScope.html", null ] + ] ], + [ "transformers.symbol_tree.Symbol", "classtransformers_1_1symbol__tree_1_1Symbol.html", null ], + [ "transformers.symbol_tree.SymbolTree", "classtransformers_1_1symbol__tree_1_1SymbolTree.html", null ], + [ "utils.encryption.StringEncryptor", "classutils_1_1encryption_1_1StringEncryptor.html", null ], + [ "utils.junk_gen.JunkGenerator", "classutils_1_1junk__gen_1_1JunkGenerator.html", null ], + [ "utils.name_gen.NameGenerator", "classutils_1_1name__gen_1_1NameGenerator.html", null ], + [ "Enum", null, [ + [ "transformers.symbol_tree.SymbolType", "classtransformers_1_1symbol__tree_1_1SymbolType.html", null ] + ] ] +]; \ No newline at end of file diff --git a/doxygen/index.html b/doxygen/index.html new file mode 100644 index 0000000..9de1e8d --- /dev/null +++ b/doxygen/index.html @@ -0,0 +1,218 @@ + + + + + + + +OMG-Fuscator: OMG-Fuscator + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
OMG-Fuscator
+
+
+

Advanced Python code obfuscator for renaming identifiers, encrypting strings, flattening control flow, and injecting junk code.

+

Quick start: use the CLI in main.py or the library API via AdvancedObfuscator().

+

+Features

+ +

+Requirements

+
    +
  • Python 3.9+ (uses ast.unparse)
  • +
  • No external dependencies; standard library only
  • +
+

+Installation

+
    +
  • Clone or download this repository into a working directory.
  • +
  • Optional: create and activate a virtual environment.
  • +
  • There are no packages to install.
  • +
+

+CLI usage

+

The CLI entrypoint is main.py with handler main().

+

Examples:

    +
  • Test mode (prints and executes obfuscated sample code): python main.py –test
  • +
  • Obfuscate a file with verbose logging and default output name: python main.py -i path/to/app.py -v
  • +
  • Obfuscate to a specific file: python main.py -i path/to/app.py -o path/to/app_obf.py
  • +
+

Arguments:

    +
  • -i, –input: Input .py file path
  • +
  • -o, –output: Output file path (default: input_stem_obfuscated.py)
  • +
  • -v, –verbose: Enable verbose console logs
  • +
  • –test: Run built-in demo
  • +
+

+Library usage

+ +

Minimal flow: 1) Parse to AST: AdvancedObfuscator.obfuscate() 2) Rename + encrypt: AdvancedObfuscator._rename_and_encrypt(), RenameTransformer() 3) Flatten control flow: AdvancedObfuscator._flatten_control_flow(), ControlFlowFlattener() 4) Generate code and inject junk: AdvancedObfuscator._generate_final_code()

+

+Project structure

+ +

+Debugging and diagnostics

+ +

+Notes and limitations

+
    +
  • Control-flow flattening may increase code size and reduce performance for small functions; tiny functions are skipped in ControlFlowFlattener.visit_FunctionDef().
  • +
  • Obfuscation can impact reflection, dynamic imports, serialization, or frameworks that rely on exact names.
  • +
  • String encryption decrypts at runtime; extremely performance‑sensitive hot paths may incur overhead.
  • +
  • Avoid obfuscating code that uses eval/exec on source strings that expect original identifiers.
  • +
+

+License

+

Specify a license for this project (e.g., MIT). If adding a LICENSE file, reference it here.

+

+Documentation

+

Generate Doxygen HTML docs for this codebase.

+ +
+
+
+ + + + diff --git a/doxygen/inherit_graph_0.dot b/doxygen/inherit_graph_0.dot new file mode 100644 index 0000000..ef1d8ab --- /dev/null +++ b/doxygen/inherit_graph_0.dot @@ -0,0 +1,17 @@ +digraph "Graphical Class Hierarchy" +{ + // LATEX_PDF_SIZE + bgcolor="transparent"; + edge [fontname=Helvetica,fontsize=10,labelfontname=Helvetica,labelfontsize=10]; + node [fontname=Helvetica,fontsize=10,shape=box,height=0.2,width=0.4]; + rankdir="LR"; + Node0 [id="Node000000",label="ast.NodeTransformer",height=0.2,width=0.4,color="grey60", fillcolor="#E0E0E0", style="filled",tooltip=" "]; + Node0 -> Node1 [id="edge1_Node000000_Node000001",dir="back",color="steelblue1",style="solid",tooltip=" "]; + Node1 [id="Node000001",label="transformers.attribute\l_transformer.AttributeTransformer",height=0.2,width=0.4,color="grey40", fillcolor="white", style="filled",URL="$classtransformers_1_1attribute__transformer_1_1AttributeTransformer.html",tooltip=" "]; + Node0 -> Node2 [id="edge2_Node000000_Node000002",dir="back",color="steelblue1",style="solid",tooltip=" "]; + Node2 [id="Node000002",label="transformers.class\l_mapper.ClassTransformer",height=0.2,width=0.4,color="grey40", fillcolor="white", style="filled",URL="$classtransformers_1_1class__mapper_1_1ClassTransformer.html",tooltip=" "]; + Node0 -> Node3 [id="edge3_Node000000_Node000003",dir="back",color="steelblue1",style="solid",tooltip=" "]; + Node3 [id="Node000003",label="transformers.control\l_flow.ControlFlowFlattener",height=0.2,width=0.4,color="grey40", fillcolor="white", style="filled",URL="$classtransformers_1_1control__flow_1_1ControlFlowFlattener.html",tooltip=" "]; + Node0 -> Node4 [id="edge4_Node000000_Node000004",dir="back",color="steelblue1",style="solid",tooltip=" "]; + Node4 [id="Node000004",label="transformers.rename.Rename\lTransformer",height=0.2,width=0.4,color="grey40", fillcolor="white", style="filled",URL="$classtransformers_1_1rename_1_1RenameTransformer.html",tooltip=" "]; +} diff --git a/doxygen/inherit_graph_1.dot b/doxygen/inherit_graph_1.dot new file mode 100644 index 0000000..452c279 --- /dev/null +++ b/doxygen/inherit_graph_1.dot @@ -0,0 +1,15 @@ +digraph "Graphical Class Hierarchy" +{ + // LATEX_PDF_SIZE + bgcolor="transparent"; + edge [fontname=Helvetica,fontsize=10,labelfontname=Helvetica,labelfontsize=10]; + node [fontname=Helvetica,fontsize=10,shape=box,height=0.2,width=0.4]; + rankdir="LR"; + Node0 [id="Node000000",label="ast.NodeVisitor",height=0.2,width=0.4,color="grey60", fillcolor="#E0E0E0", style="filled",tooltip=" "]; + Node0 -> Node1 [id="edge5_Node000000_Node000001",dir="back",color="steelblue1",style="solid",tooltip=" "]; + Node1 [id="Node000001",label="transformers.class\l_analyzer.ClassAnalyzer",height=0.2,width=0.4,color="grey40", fillcolor="white", style="filled",URL="$classtransformers_1_1class__analyzer_1_1ClassAnalyzer.html",tooltip=" "]; + Node0 -> Node2 [id="edge6_Node000000_Node000002",dir="back",color="steelblue1",style="solid",tooltip=" "]; + Node2 [id="Node000002",label="transformers.class\l_mapper.ClassMapAnalyzer",height=0.2,width=0.4,color="grey40", fillcolor="white", style="filled",URL="$classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html",tooltip=" "]; + Node0 -> Node3 [id="edge7_Node000000_Node000003",dir="back",color="steelblue1",style="solid",tooltip=" "]; + Node3 [id="Node000003",label="transformers.symbol\l_tree.SymbolTreeBuilder",height=0.2,width=0.4,color="grey40", fillcolor="white", style="filled",URL="$classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html",tooltip=" "]; +} diff --git a/doxygen/inherit_graph_10.dot b/doxygen/inherit_graph_10.dot new file mode 100644 index 0000000..d8b667a --- /dev/null +++ b/doxygen/inherit_graph_10.dot @@ -0,0 +1,9 @@ +digraph "Graphical Class Hierarchy" +{ + // LATEX_PDF_SIZE + bgcolor="transparent"; + edge [fontname=Helvetica,fontsize=10,labelfontname=Helvetica,labelfontsize=10]; + node [fontname=Helvetica,fontsize=10,shape=box,height=0.2,width=0.4]; + rankdir="LR"; + Node0 [id="Node000000",label="utils.junk_gen.JunkGenerator",height=0.2,width=0.4,color="grey40", fillcolor="white", style="filled",URL="$classutils_1_1junk__gen_1_1JunkGenerator.html",tooltip=" "]; +} diff --git a/doxygen/inherit_graph_11.dot b/doxygen/inherit_graph_11.dot new file mode 100644 index 0000000..e3e280d --- /dev/null +++ b/doxygen/inherit_graph_11.dot @@ -0,0 +1,9 @@ +digraph "Graphical Class Hierarchy" +{ + // LATEX_PDF_SIZE + bgcolor="transparent"; + edge [fontname=Helvetica,fontsize=10,labelfontname=Helvetica,labelfontsize=10]; + node [fontname=Helvetica,fontsize=10,shape=box,height=0.2,width=0.4]; + rankdir="LR"; + Node0 [id="Node000000",label="utils.name_gen.NameGenerator",height=0.2,width=0.4,color="grey40", fillcolor="white", style="filled",URL="$classutils_1_1name__gen_1_1NameGenerator.html",tooltip=" "]; +} diff --git a/doxygen/inherit_graph_2.dot b/doxygen/inherit_graph_2.dot new file mode 100644 index 0000000..fb3ed46 --- /dev/null +++ b/doxygen/inherit_graph_2.dot @@ -0,0 +1,11 @@ +digraph "Graphical Class Hierarchy" +{ + // LATEX_PDF_SIZE + bgcolor="transparent"; + edge [fontname=Helvetica,fontsize=10,labelfontname=Helvetica,labelfontsize=10]; + node [fontname=Helvetica,fontsize=10,shape=box,height=0.2,width=0.4]; + rankdir="LR"; + Node0 [id="Node000000",label="Enum",height=0.2,width=0.4,color="grey60", fillcolor="#E0E0E0", style="filled",tooltip=" "]; + Node0 -> Node1 [id="edge8_Node000000_Node000001",dir="back",color="steelblue1",style="solid",tooltip=" "]; + Node1 [id="Node000001",label="transformers.symbol\l_tree.SymbolType",height=0.2,width=0.4,color="grey40", fillcolor="white", style="filled",URL="$classtransformers_1_1symbol__tree_1_1SymbolType.html",tooltip=" "]; +} diff --git a/doxygen/inherit_graph_3.dot b/doxygen/inherit_graph_3.dot new file mode 100644 index 0000000..942f2c5 --- /dev/null +++ b/doxygen/inherit_graph_3.dot @@ -0,0 +1,9 @@ +digraph "Graphical Class Hierarchy" +{ + // LATEX_PDF_SIZE + bgcolor="transparent"; + edge [fontname=Helvetica,fontsize=10,labelfontname=Helvetica,labelfontsize=10]; + node [fontname=Helvetica,fontsize=10,shape=box,height=0.2,width=0.4]; + rankdir="LR"; + Node0 [id="Node000000",label="obfuscator.AdvancedObfuscator",height=0.2,width=0.4,color="grey40", fillcolor="white", style="filled",URL="$classobfuscator_1_1AdvancedObfuscator.html",tooltip=" "]; +} diff --git a/doxygen/inherit_graph_4.dot b/doxygen/inherit_graph_4.dot new file mode 100644 index 0000000..ab7e02e --- /dev/null +++ b/doxygen/inherit_graph_4.dot @@ -0,0 +1,9 @@ +digraph "Graphical Class Hierarchy" +{ + // LATEX_PDF_SIZE + bgcolor="transparent"; + edge [fontname=Helvetica,fontsize=10,labelfontname=Helvetica,labelfontsize=10]; + node [fontname=Helvetica,fontsize=10,shape=box,height=0.2,width=0.4]; + rankdir="LR"; + Node0 [id="Node000000",label="transformers.class\l_analyzer.ClassMethodMap",height=0.2,width=0.4,color="grey40", fillcolor="white", style="filled",URL="$classtransformers_1_1class__analyzer_1_1ClassMethodMap.html",tooltip=" "]; +} diff --git a/doxygen/inherit_graph_5.dot b/doxygen/inherit_graph_5.dot new file mode 100644 index 0000000..6504668 --- /dev/null +++ b/doxygen/inherit_graph_5.dot @@ -0,0 +1,9 @@ +digraph "Graphical Class Hierarchy" +{ + // LATEX_PDF_SIZE + bgcolor="transparent"; + edge [fontname=Helvetica,fontsize=10,labelfontname=Helvetica,labelfontsize=10]; + node [fontname=Helvetica,fontsize=10,shape=box,height=0.2,width=0.4]; + rankdir="LR"; + Node0 [id="Node000000",label="transformers.class\l_mapper.ClassMapping",height=0.2,width=0.4,color="grey40", fillcolor="white", style="filled",URL="$classtransformers_1_1class__mapper_1_1ClassMapping.html",tooltip=" "]; +} diff --git a/doxygen/inherit_graph_6.dot b/doxygen/inherit_graph_6.dot new file mode 100644 index 0000000..4469cb8 --- /dev/null +++ b/doxygen/inherit_graph_6.dot @@ -0,0 +1,13 @@ +digraph "Graphical Class Hierarchy" +{ + // LATEX_PDF_SIZE + bgcolor="transparent"; + edge [fontname=Helvetica,fontsize=10,labelfontname=Helvetica,labelfontsize=10]; + node [fontname=Helvetica,fontsize=10,shape=box,height=0.2,width=0.4]; + rankdir="LR"; + Node0 [id="Node000000",label="transformers.symbol\l_tree.Scope",height=0.2,width=0.4,color="grey40", fillcolor="white", style="filled",URL="$classtransformers_1_1symbol__tree_1_1Scope.html",tooltip=" "]; + Node0 -> Node1 [id="edge9_Node000000_Node000001",dir="back",color="steelblue1",style="solid",tooltip=" "]; + Node1 [id="Node000001",label="transformers.symbol\l_tree.ClassScope",height=0.2,width=0.4,color="grey40", fillcolor="white", style="filled",URL="$classtransformers_1_1symbol__tree_1_1ClassScope.html",tooltip=" "]; + Node0 -> Node2 [id="edge10_Node000000_Node000002",dir="back",color="steelblue1",style="solid",tooltip=" "]; + Node2 [id="Node000002",label="transformers.symbol\l_tree.ModuleScope",height=0.2,width=0.4,color="grey40", fillcolor="white", style="filled",URL="$classtransformers_1_1symbol__tree_1_1ModuleScope.html",tooltip=" "]; +} diff --git a/doxygen/inherit_graph_7.dot b/doxygen/inherit_graph_7.dot new file mode 100644 index 0000000..b4d04f5 --- /dev/null +++ b/doxygen/inherit_graph_7.dot @@ -0,0 +1,9 @@ +digraph "Graphical Class Hierarchy" +{ + // LATEX_PDF_SIZE + bgcolor="transparent"; + edge [fontname=Helvetica,fontsize=10,labelfontname=Helvetica,labelfontsize=10]; + node [fontname=Helvetica,fontsize=10,shape=box,height=0.2,width=0.4]; + rankdir="LR"; + Node0 [id="Node000000",label="transformers.symbol\l_tree.Symbol",height=0.2,width=0.4,color="grey40", fillcolor="white", style="filled",URL="$classtransformers_1_1symbol__tree_1_1Symbol.html",tooltip=" "]; +} diff --git a/doxygen/inherit_graph_8.dot b/doxygen/inherit_graph_8.dot new file mode 100644 index 0000000..75a2bc6 --- /dev/null +++ b/doxygen/inherit_graph_8.dot @@ -0,0 +1,9 @@ +digraph "Graphical Class Hierarchy" +{ + // LATEX_PDF_SIZE + bgcolor="transparent"; + edge [fontname=Helvetica,fontsize=10,labelfontname=Helvetica,labelfontsize=10]; + node [fontname=Helvetica,fontsize=10,shape=box,height=0.2,width=0.4]; + rankdir="LR"; + Node0 [id="Node000000",label="transformers.symbol\l_tree.SymbolTree",height=0.2,width=0.4,color="grey40", fillcolor="white", style="filled",URL="$classtransformers_1_1symbol__tree_1_1SymbolTree.html",tooltip=" "]; +} diff --git a/doxygen/inherit_graph_9.dot b/doxygen/inherit_graph_9.dot new file mode 100644 index 0000000..ddd8cfc --- /dev/null +++ b/doxygen/inherit_graph_9.dot @@ -0,0 +1,9 @@ +digraph "Graphical Class Hierarchy" +{ + // LATEX_PDF_SIZE + bgcolor="transparent"; + edge [fontname=Helvetica,fontsize=10,labelfontname=Helvetica,labelfontsize=10]; + node [fontname=Helvetica,fontsize=10,shape=box,height=0.2,width=0.4]; + rankdir="LR"; + Node0 [id="Node000000",label="utils.encryption.StringEncryptor",height=0.2,width=0.4,color="grey40", fillcolor="white", style="filled",URL="$classutils_1_1encryption_1_1StringEncryptor.html",tooltip=" "]; +} diff --git a/doxygen/inherits.html b/doxygen/inherits.html new file mode 100644 index 0000000..736627e --- /dev/null +++ b/doxygen/inherits.html @@ -0,0 +1,133 @@ + + + + + + + +OMG-Fuscator: Class Hierarchy + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Class Hierarchy
+
+
+ + + + + + + + + + + + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + diff --git a/doxygen/jquery.js b/doxygen/jquery.js new file mode 100644 index 0000000..1dffb65 --- /dev/null +++ b/doxygen/jquery.js @@ -0,0 +1,34 @@ +/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0",options:{classes:{},disabled:!1,create:null},_createWidget:function(t,e){e=y(e||this.defaultElement||this)[0],this.element=y(e),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=y(),this.hoverable=y(),this.focusable=y(),this.classesElementLookup={},e!==this&&(y.data(e,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===e&&this.destroy()}}),this.document=y(e.style?e.ownerDocument:e.document||e),this.window=y(this.document[0].defaultView||this.document[0].parentWindow)),this.options=y.widget.extend({},this.options,this._getCreateOptions(),t),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:y.noop,_create:y.noop,_init:y.noop,destroy:function(){var i=this;this._destroy(),y.each(this.classesElementLookup,function(t,e){i._removeClass(e,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:y.noop,widget:function(){return this.element},option:function(t,e){var i,s,n,o=t;if(0===arguments.length)return y.widget.extend({},this.options);if("string"==typeof t)if(o={},t=(i=t.split(".")).shift(),i.length){for(s=o[t]=y.widget.extend({},this.options[t]),n=0;n
"),i=e.children()[0];return y("body").append(e),t=i.offsetWidth,e.css("overflow","scroll"),t===(i=i.offsetWidth)&&(i=e[0].clientWidth),e.remove(),s=t-i},getScrollInfo:function(t){var e=t.isWindow||t.isDocument?"":t.element.css("overflow-x"),i=t.isWindow||t.isDocument?"":t.element.css("overflow-y"),e="scroll"===e||"auto"===e&&t.widthx(D(s),D(n))?o.important="horizontal":o.important="vertical",p.using.call(this,t,o)}),h.offset(y.extend(l,{using:t}))})},y.ui.position={fit:{left:function(t,e){var i=e.within,s=i.isWindow?i.scrollLeft:i.offset.left,n=i.width,o=t.left-e.collisionPosition.marginLeft,h=s-o,a=o+e.collisionWidth-n-s;e.collisionWidth>n?0n?0=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),y.ui.plugin={add:function(t,e,i){var s,n=y.ui[t].prototype;for(s in i)n.plugins[s]=n.plugins[s]||[],n.plugins[s].push([e,i[s]])},call:function(t,e,i,s){var n,o=t.plugins[e];if(o&&(s||t.element[0].parentNode&&11!==t.element[0].parentNode.nodeType))for(n=0;n").css({overflow:"hidden",position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.resizable("instance")),this.elementIsWrapper=!0,t={marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom"),marginLeft:this.originalElement.css("marginLeft")},this.element.css(t),this.originalElement.css("margin",0),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css(t),this._proportionallyResize()),this._setupHandles(),e.autoHide&&y(this.element).on("mouseenter",function(){e.disabled||(i._removeClass("ui-resizable-autohide"),i._handles.show())}).on("mouseleave",function(){e.disabled||i.resizing||(i._addClass("ui-resizable-autohide"),i._handles.hide())}),this._mouseInit()},_destroy:function(){this._mouseDestroy(),this._addedHandles.remove();function t(t){y(t).removeData("resizable").removeData("ui-resizable").off(".resizable")}var e;return this.elementIsWrapper&&(t(this.element),e=this.element,this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")}).insertAfter(e),e.remove()),this.originalElement.css("resize",this.originalResizeStyle),t(this.originalElement),this},_setOption:function(t,e){switch(this._super(t,e),t){case"handles":this._removeHandles(),this._setupHandles();break;case"aspectRatio":this._aspectRatio=!!e}},_setupHandles:function(){var t,e,i,s,n,o=this.options,h=this;if(this.handles=o.handles||(y(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this._handles=y(),this._addedHandles=y(),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),i=this.handles.split(","),this.handles={},e=0;e"),this._addClass(n,"ui-resizable-handle "+s),n.css({zIndex:o.zIndex}),this.handles[t]=".ui-resizable-"+t,this.element.children(this.handles[t]).length||(this.element.append(n),this._addedHandles=this._addedHandles.add(n));this._renderAxis=function(t){var e,i,s;for(e in t=t||this.element,this.handles)this.handles[e].constructor===String?this.handles[e]=this.element.children(this.handles[e]).first().show():(this.handles[e].jquery||this.handles[e].nodeType)&&(this.handles[e]=y(this.handles[e]),this._on(this.handles[e],{mousedown:h._mouseDown})),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)&&(i=y(this.handles[e],this.element),s=/sw|ne|nw|se|n|s/.test(e)?i.outerHeight():i.outerWidth(),i=["padding",/ne|nw|n/.test(e)?"Top":/se|sw|s/.test(e)?"Bottom":/^e$/.test(e)?"Right":"Left"].join(""),t.css(i,s),this._proportionallyResize()),this._handles=this._handles.add(this.handles[e])},this._renderAxis(this.element),this._handles=this._handles.add(this.element.find(".ui-resizable-handle")),this._handles.disableSelection(),this._handles.on("mouseover",function(){h.resizing||(this.className&&(n=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),h.axis=n&&n[1]?n[1]:"se")}),o.autoHide&&(this._handles.hide(),this._addClass("ui-resizable-autohide"))},_removeHandles:function(){this._addedHandles.remove()},_mouseCapture:function(t){var e,i,s=!1;for(e in this.handles)(i=y(this.handles[e])[0])!==t.target&&!y.contains(i,t.target)||(s=!0);return!this.options.disabled&&s},_mouseStart:function(t){var e,i,s=this.options,n=this.element;return this.resizing=!0,this._renderProxy(),e=this._num(this.helper.css("left")),i=this._num(this.helper.css("top")),s.containment&&(e+=y(s.containment).scrollLeft()||0,i+=y(s.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:e,top:i},this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:n.width(),height:n.height()},this.originalSize=this._helper?{width:n.outerWidth(),height:n.outerHeight()}:{width:n.width(),height:n.height()},this.sizeDiff={width:n.outerWidth()-n.width(),height:n.outerHeight()-n.height()},this.originalPosition={left:e,top:i},this.originalMousePosition={left:t.pageX,top:t.pageY},this.aspectRatio="number"==typeof s.aspectRatio?s.aspectRatio:this.originalSize.width/this.originalSize.height||1,s=y(".ui-resizable-"+this.axis).css("cursor"),y("body").css("cursor","auto"===s?this.axis+"-resize":s),this._addClass("ui-resizable-resizing"),this._propagate("start",t),!0},_mouseDrag:function(t){var e=this.originalMousePosition,i=this.axis,s=t.pageX-e.left||0,e=t.pageY-e.top||0,i=this._change[i];return this._updatePrevProperties(),i&&(e=i.apply(this,[t,s,e]),this._updateVirtualBoundaries(t.shiftKey),(this._aspectRatio||t.shiftKey)&&(e=this._updateRatio(e,t)),e=this._respectSize(e,t),this._updateCache(e),this._propagate("resize",t),e=this._applyChanges(),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),y.isEmptyObject(e)||(this._updatePrevProperties(),this._trigger("resize",t,this.ui()),this._applyChanges())),!1},_mouseStop:function(t){this.resizing=!1;var e,i,s,n=this.options,o=this;return this._helper&&(s=(e=(i=this._proportionallyResizeElements).length&&/textarea/i.test(i[0].nodeName))&&this._hasScroll(i[0],"left")?0:o.sizeDiff.height,i=e?0:o.sizeDiff.width,e={width:o.helper.width()-i,height:o.helper.height()-s},i=parseFloat(o.element.css("left"))+(o.position.left-o.originalPosition.left)||null,s=parseFloat(o.element.css("top"))+(o.position.top-o.originalPosition.top)||null,n.animate||this.element.css(y.extend(e,{top:s,left:i})),o.helper.height(o.size.height),o.helper.width(o.size.width),this._helper&&!n.animate&&this._proportionallyResize()),y("body").css("cursor","auto"),this._removeClass("ui-resizable-resizing"),this._propagate("stop",t),this._helper&&this.helper.remove(),!1},_updatePrevProperties:function(){this.prevPosition={top:this.position.top,left:this.position.left},this.prevSize={width:this.size.width,height:this.size.height}},_applyChanges:function(){var t={};return this.position.top!==this.prevPosition.top&&(t.top=this.position.top+"px"),this.position.left!==this.prevPosition.left&&(t.left=this.position.left+"px"),this.size.width!==this.prevSize.width&&(t.width=this.size.width+"px"),this.size.height!==this.prevSize.height&&(t.height=this.size.height+"px"),this.helper.css(t),t},_updateVirtualBoundaries:function(t){var e,i,s=this.options,n={minWidth:this._isNumber(s.minWidth)?s.minWidth:0,maxWidth:this._isNumber(s.maxWidth)?s.maxWidth:1/0,minHeight:this._isNumber(s.minHeight)?s.minHeight:0,maxHeight:this._isNumber(s.maxHeight)?s.maxHeight:1/0};(this._aspectRatio||t)&&(e=n.minHeight*this.aspectRatio,i=n.minWidth/this.aspectRatio,s=n.maxHeight*this.aspectRatio,t=n.maxWidth/this.aspectRatio,e>n.minWidth&&(n.minWidth=e),i>n.minHeight&&(n.minHeight=i),st.width,h=this._isNumber(t.height)&&e.minHeight&&e.minHeight>t.height,a=this.originalPosition.left+this.originalSize.width,r=this.originalPosition.top+this.originalSize.height,l=/sw|nw|w/.test(i),i=/nw|ne|n/.test(i);return o&&(t.width=e.minWidth),h&&(t.height=e.minHeight),s&&(t.width=e.maxWidth),n&&(t.height=e.maxHeight),o&&l&&(t.left=a-e.minWidth),s&&l&&(t.left=a-e.maxWidth),h&&i&&(t.top=r-e.minHeight),n&&i&&(t.top=r-e.maxHeight),t.width||t.height||t.left||!t.top?t.width||t.height||t.top||!t.left||(t.left=null):t.top=null,t},_getPaddingPlusBorderDimensions:function(t){for(var e=0,i=[],s=[t.css("borderTopWidth"),t.css("borderRightWidth"),t.css("borderBottomWidth"),t.css("borderLeftWidth")],n=[t.css("paddingTop"),t.css("paddingRight"),t.css("paddingBottom"),t.css("paddingLeft")];e<4;e++)i[e]=parseFloat(s[e])||0,i[e]+=parseFloat(n[e])||0;return{height:i[0]+i[2],width:i[1]+i[3]}},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var t,e=0,i=this.helper||this.element;e").css({overflow:"hidden"}),this._addClass(this.helper,this._helper),this.helper.css({width:this.element.outerWidth(),height:this.element.outerHeight(),position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++e.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element},_change:{e:function(t,e){return{width:this.originalSize.width+e}},w:function(t,e){var i=this.originalSize;return{left:this.originalPosition.left+e,width:i.width-e}},n:function(t,e,i){var s=this.originalSize;return{top:this.originalPosition.top+i,height:s.height-i}},s:function(t,e,i){return{height:this.originalSize.height+i}},se:function(t,e,i){return y.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[t,e,i]))},sw:function(t,e,i){return y.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[t,e,i]))},ne:function(t,e,i){return y.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[t,e,i]))},nw:function(t,e,i){return y.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[t,e,i]))}},_propagate:function(t,e){y.ui.plugin.call(this,t,[e,this.ui()]),"resize"!==t&&this._trigger(t,e,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),y.ui.plugin.add("resizable","animate",{stop:function(e){var i=y(this).resizable("instance"),t=i.options,s=i._proportionallyResizeElements,n=s.length&&/textarea/i.test(s[0].nodeName),o=n&&i._hasScroll(s[0],"left")?0:i.sizeDiff.height,h=n?0:i.sizeDiff.width,n={width:i.size.width-h,height:i.size.height-o},h=parseFloat(i.element.css("left"))+(i.position.left-i.originalPosition.left)||null,o=parseFloat(i.element.css("top"))+(i.position.top-i.originalPosition.top)||null;i.element.animate(y.extend(n,o&&h?{top:o,left:h}:{}),{duration:t.animateDuration,easing:t.animateEasing,step:function(){var t={width:parseFloat(i.element.css("width")),height:parseFloat(i.element.css("height")),top:parseFloat(i.element.css("top")),left:parseFloat(i.element.css("left"))};s&&s.length&&y(s[0]).css({width:t.width,height:t.height}),i._updateCache(t),i._propagate("resize",e)}})}}),y.ui.plugin.add("resizable","containment",{start:function(){var i,s,n=y(this).resizable("instance"),t=n.options,e=n.element,o=t.containment,h=o instanceof y?o.get(0):/parent/.test(o)?e.parent().get(0):o;h&&(n.containerElement=y(h),/document/.test(o)||o===document?(n.containerOffset={left:0,top:0},n.containerPosition={left:0,top:0},n.parentData={element:y(document),left:0,top:0,width:y(document).width(),height:y(document).height()||document.body.parentNode.scrollHeight}):(i=y(h),s=[],y(["Top","Right","Left","Bottom"]).each(function(t,e){s[t]=n._num(i.css("padding"+e))}),n.containerOffset=i.offset(),n.containerPosition=i.position(),n.containerSize={height:i.innerHeight()-s[3],width:i.innerWidth()-s[1]},t=n.containerOffset,e=n.containerSize.height,o=n.containerSize.width,o=n._hasScroll(h,"left")?h.scrollWidth:o,e=n._hasScroll(h)?h.scrollHeight:e,n.parentData={element:h,left:t.left,top:t.top,width:o,height:e}))},resize:function(t){var e=y(this).resizable("instance"),i=e.options,s=e.containerOffset,n=e.position,o=e._aspectRatio||t.shiftKey,h={top:0,left:0},a=e.containerElement,t=!0;a[0]!==document&&/static/.test(a.css("position"))&&(h=s),n.left<(e._helper?s.left:0)&&(e.size.width=e.size.width+(e._helper?e.position.left-s.left:e.position.left-h.left),o&&(e.size.height=e.size.width/e.aspectRatio,t=!1),e.position.left=i.helper?s.left:0),n.top<(e._helper?s.top:0)&&(e.size.height=e.size.height+(e._helper?e.position.top-s.top:e.position.top),o&&(e.size.width=e.size.height*e.aspectRatio,t=!1),e.position.top=e._helper?s.top:0),i=e.containerElement.get(0)===e.element.parent().get(0),n=/relative|absolute/.test(e.containerElement.css("position")),i&&n?(e.offset.left=e.parentData.left+e.position.left,e.offset.top=e.parentData.top+e.position.top):(e.offset.left=e.element.offset().left,e.offset.top=e.element.offset().top),n=Math.abs(e.sizeDiff.width+(e._helper?e.offset.left-h.left:e.offset.left-s.left)),s=Math.abs(e.sizeDiff.height+(e._helper?e.offset.top-h.top:e.offset.top-s.top)),n+e.size.width>=e.parentData.width&&(e.size.width=e.parentData.width-n,o&&(e.size.height=e.size.width/e.aspectRatio,t=!1)),s+e.size.height>=e.parentData.height&&(e.size.height=e.parentData.height-s,o&&(e.size.width=e.size.height*e.aspectRatio,t=!1)),t||(e.position.left=e.prevPosition.left,e.position.top=e.prevPosition.top,e.size.width=e.prevSize.width,e.size.height=e.prevSize.height)},stop:function(){var t=y(this).resizable("instance"),e=t.options,i=t.containerOffset,s=t.containerPosition,n=t.containerElement,o=y(t.helper),h=o.offset(),a=o.outerWidth()-t.sizeDiff.width,o=o.outerHeight()-t.sizeDiff.height;t._helper&&!e.animate&&/relative/.test(n.css("position"))&&y(this).css({left:h.left-s.left-i.left,width:a,height:o}),t._helper&&!e.animate&&/static/.test(n.css("position"))&&y(this).css({left:h.left-s.left-i.left,width:a,height:o})}}),y.ui.plugin.add("resizable","alsoResize",{start:function(){var t=y(this).resizable("instance").options;y(t.alsoResize).each(function(){var t=y(this);t.data("ui-resizable-alsoresize",{width:parseFloat(t.width()),height:parseFloat(t.height()),left:parseFloat(t.css("left")),top:parseFloat(t.css("top"))})})},resize:function(t,i){var e=y(this).resizable("instance"),s=e.options,n=e.originalSize,o=e.originalPosition,h={height:e.size.height-n.height||0,width:e.size.width-n.width||0,top:e.position.top-o.top||0,left:e.position.left-o.left||0};y(s.alsoResize).each(function(){var t=y(this),s=y(this).data("ui-resizable-alsoresize"),n={},e=t.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];y.each(e,function(t,e){var i=(s[e]||0)+(h[e]||0);i&&0<=i&&(n[e]=i||null)}),t.css(n)})},stop:function(){y(this).removeData("ui-resizable-alsoresize")}}),y.ui.plugin.add("resizable","ghost",{start:function(){var t=y(this).resizable("instance"),e=t.size;t.ghost=t.originalElement.clone(),t.ghost.css({opacity:.25,display:"block",position:"relative",height:e.height,width:e.width,margin:0,left:0,top:0}),t._addClass(t.ghost,"ui-resizable-ghost"),!1!==y.uiBackCompat&&"string"==typeof t.options.ghost&&t.ghost.addClass(this.options.ghost),t.ghost.appendTo(t.helper)},resize:function(){var t=y(this).resizable("instance");t.ghost&&t.ghost.css({position:"relative",height:t.size.height,width:t.size.width})},stop:function(){var t=y(this).resizable("instance");t.ghost&&t.helper&&t.helper.get(0).removeChild(t.ghost.get(0))}}),y.ui.plugin.add("resizable","grid",{resize:function(){var t,e=y(this).resizable("instance"),i=e.options,s=e.size,n=e.originalSize,o=e.originalPosition,h=e.axis,a="number"==typeof i.grid?[i.grid,i.grid]:i.grid,r=a[0]||1,l=a[1]||1,u=Math.round((s.width-n.width)/r)*r,p=Math.round((s.height-n.height)/l)*l,d=n.width+u,c=n.height+p,f=i.maxWidth&&i.maxWidthd,s=i.minHeight&&i.minHeight>c;i.grid=a,m&&(d+=r),s&&(c+=l),f&&(d-=r),g&&(c-=l),/^(se|s|e)$/.test(h)?(e.size.width=d,e.size.height=c):/^(ne)$/.test(h)?(e.size.width=d,e.size.height=c,e.position.top=o.top-p):/^(sw)$/.test(h)?(e.size.width=d,e.size.height=c,e.position.left=o.left-u):((c-l<=0||d-r<=0)&&(t=e._getPaddingPlusBorderDimensions(this)),0=f[g]?0:Math.min(f[g],n));!a&&1-1){targetElements.on(evt+EVENT_NAMESPACE,function elementToggle(event){$.powerTip.toggle(this,event)})}else{targetElements.on(evt+EVENT_NAMESPACE,function elementOpen(event){$.powerTip.show(this,event)})}});$.each(options.closeEvents,function(idx,evt){if($.inArray(evt,options.openEvents)<0){targetElements.on(evt+EVENT_NAMESPACE,function elementClose(event){$.powerTip.hide(this,!isMouseEvent(event))})}});targetElements.on("keydown"+EVENT_NAMESPACE,function elementKeyDown(event){if(event.keyCode===27){$.powerTip.hide(this,true)}})}return targetElements};$.fn.powerTip.defaults={fadeInTime:200,fadeOutTime:100,followMouse:false,popupId:"powerTip",popupClass:null,intentSensitivity:7,intentPollInterval:100,closeDelay:100,placement:"n",smartPlacement:false,offset:10,mouseOnToPopup:false,manual:false,openEvents:["mouseenter","focus"],closeEvents:["mouseleave","blur"]};$.fn.powerTip.smartPlacementLists={n:["n","ne","nw","s"],e:["e","ne","se","w","nw","sw","n","s","e"],s:["s","se","sw","n"],w:["w","nw","sw","e","ne","se","n","s","w"],nw:["nw","w","sw","n","s","se","nw"],ne:["ne","e","se","n","s","sw","ne"],sw:["sw","w","nw","s","n","ne","sw"],se:["se","e","ne","s","n","nw","se"],"nw-alt":["nw-alt","n","ne-alt","sw-alt","s","se-alt","w","e"],"ne-alt":["ne-alt","n","nw-alt","se-alt","s","sw-alt","e","w"],"sw-alt":["sw-alt","s","se-alt","nw-alt","n","ne-alt","w","e"],"se-alt":["se-alt","s","sw-alt","ne-alt","n","nw-alt","e","w"]};$.powerTip={show:function apiShowTip(element,event){if(isMouseEvent(event)){trackMouse(event);session.previousX=event.pageX;session.previousY=event.pageY;$(element).data(DATA_DISPLAYCONTROLLER).show()}else{$(element).first().data(DATA_DISPLAYCONTROLLER).show(true,true)}return element},reposition:function apiResetPosition(element){$(element).first().data(DATA_DISPLAYCONTROLLER).resetPosition();return element},hide:function apiCloseTip(element,immediate){var displayController;immediate=element?immediate:true;if(element){displayController=$(element).first().data(DATA_DISPLAYCONTROLLER)}else if(session.activeHover){displayController=session.activeHover.data(DATA_DISPLAYCONTROLLER)}if(displayController){displayController.hide(immediate)}return element},toggle:function apiToggle(element,event){if(session.activeHover&&session.activeHover.is(element)){$.powerTip.hide(element,!isMouseEvent(event))}else{$.powerTip.show(element,event)}return element}};$.powerTip.showTip=$.powerTip.show;$.powerTip.closeTip=$.powerTip.hide;function CSSCoordinates(){var me=this;me.top="auto";me.left="auto";me.right="auto";me.bottom="auto";me.set=function(property,value){if($.isNumeric(value)){me[property]=Math.round(value)}}}function DisplayController(element,options,tipController){var hoverTimer=null,myCloseDelay=null;function openTooltip(immediate,forceOpen){cancelTimer();if(!element.data(DATA_HASACTIVEHOVER)){if(!immediate){session.tipOpenImminent=true;hoverTimer=setTimeout(function intentDelay(){hoverTimer=null;checkForIntent()},options.intentPollInterval)}else{if(forceOpen){element.data(DATA_FORCEDOPEN,true)}closeAnyDelayed();tipController.showTip(element)}}else{cancelClose()}}function closeTooltip(disableDelay){if(myCloseDelay){myCloseDelay=session.closeDelayTimeout=clearTimeout(myCloseDelay);session.delayInProgress=false}cancelTimer();session.tipOpenImminent=false;if(element.data(DATA_HASACTIVEHOVER)){element.data(DATA_FORCEDOPEN,false);if(!disableDelay){session.delayInProgress=true;session.closeDelayTimeout=setTimeout(function closeDelay(){session.closeDelayTimeout=null;tipController.hideTip(element);session.delayInProgress=false;myCloseDelay=null},options.closeDelay);myCloseDelay=session.closeDelayTimeout}else{tipController.hideTip(element)}}}function checkForIntent(){var xDifference=Math.abs(session.previousX-session.currentX),yDifference=Math.abs(session.previousY-session.currentY),totalDifference=xDifference+yDifference;if(totalDifference",{id:options.popupId});if($body.length===0){$body=$("body")}$body.append(tipElement);session.tooltips=session.tooltips?session.tooltips.add(tipElement):tipElement}if(options.followMouse){if(!tipElement.data(DATA_HASMOUSEMOVE)){$document.on("mousemove"+EVENT_NAMESPACE,positionTipOnCursor);$window.on("scroll"+EVENT_NAMESPACE,positionTipOnCursor);tipElement.data(DATA_HASMOUSEMOVE,true)}}function beginShowTip(element){element.data(DATA_HASACTIVEHOVER,true);tipElement.queue(function queueTipInit(next){showTip(element);next()})}function showTip(element){var tipContent;if(!element.data(DATA_HASACTIVEHOVER)){return}if(session.isTipOpen){if(!session.isClosing){hideTip(session.activeHover)}tipElement.delay(100).queue(function queueTipAgain(next){showTip(element);next()});return}element.trigger("powerTipPreRender");tipContent=getTooltipContent(element);if(tipContent){tipElement.empty().append(tipContent)}else{return}element.trigger("powerTipRender");session.activeHover=element;session.isTipOpen=true;tipElement.data(DATA_MOUSEONTOTIP,options.mouseOnToPopup);tipElement.addClass(options.popupClass);if(!options.followMouse||element.data(DATA_FORCEDOPEN)){positionTipOnElement(element);session.isFixedTipOpen=true}else{positionTipOnCursor()}if(!element.data(DATA_FORCEDOPEN)&&!options.followMouse){$document.on("click"+EVENT_NAMESPACE,function documentClick(event){var target=event.target;if(target!==element[0]){if(options.mouseOnToPopup){if(target!==tipElement[0]&&!$.contains(tipElement[0],target)){$.powerTip.hide()}}else{$.powerTip.hide()}}})}if(options.mouseOnToPopup&&!options.manual){tipElement.on("mouseenter"+EVENT_NAMESPACE,function tipMouseEnter(){if(session.activeHover){session.activeHover.data(DATA_DISPLAYCONTROLLER).cancel()}});tipElement.on("mouseleave"+EVENT_NAMESPACE,function tipMouseLeave(){if(session.activeHover){session.activeHover.data(DATA_DISPLAYCONTROLLER).hide()}})}tipElement.fadeIn(options.fadeInTime,function fadeInCallback(){if(!session.desyncTimeout){session.desyncTimeout=setInterval(closeDesyncedTip,500)}element.trigger("powerTipOpen")})}function hideTip(element){session.isClosing=true;session.isTipOpen=false;session.desyncTimeout=clearInterval(session.desyncTimeout);element.data(DATA_HASACTIVEHOVER,false);element.data(DATA_FORCEDOPEN,false);$document.off("click"+EVENT_NAMESPACE);tipElement.off(EVENT_NAMESPACE);tipElement.fadeOut(options.fadeOutTime,function fadeOutCallback(){var coords=new CSSCoordinates;session.activeHover=null;session.isClosing=false;session.isFixedTipOpen=false;tipElement.removeClass();coords.set("top",session.currentY+options.offset);coords.set("left",session.currentX+options.offset);tipElement.css(coords);element.trigger("powerTipClose")})}function positionTipOnCursor(){var tipWidth,tipHeight,coords,collisions,collisionCount;if(!session.isFixedTipOpen&&(session.isTipOpen||session.tipOpenImminent&&tipElement.data(DATA_HASMOUSEMOVE))){tipWidth=tipElement.outerWidth();tipHeight=tipElement.outerHeight();coords=new CSSCoordinates;coords.set("top",session.currentY+options.offset);coords.set("left",session.currentX+options.offset);collisions=getViewportCollisions(coords,tipWidth,tipHeight);if(collisions!==Collision.none){collisionCount=countFlags(collisions);if(collisionCount===1){if(collisions===Collision.right){coords.set("left",session.scrollLeft+session.windowWidth-tipWidth)}else if(collisions===Collision.bottom){coords.set("top",session.scrollTop+session.windowHeight-tipHeight)}}else{coords.set("left",session.currentX-tipWidth-options.offset);coords.set("top",session.currentY-tipHeight-options.offset)}}tipElement.css(coords)}}function positionTipOnElement(element){var priorityList,finalPlacement;if(options.smartPlacement||options.followMouse&&element.data(DATA_FORCEDOPEN)){priorityList=$.fn.powerTip.smartPlacementLists[options.placement];$.each(priorityList,function(idx,pos){var collisions=getViewportCollisions(placeTooltip(element,pos),tipElement.outerWidth(),tipElement.outerHeight());finalPlacement=pos;return collisions!==Collision.none})}else{placeTooltip(element,options.placement);finalPlacement=options.placement}tipElement.removeClass("w nw sw e ne se n s w se-alt sw-alt ne-alt nw-alt");tipElement.addClass(finalPlacement)}function placeTooltip(element,placement){var iterationCount=0,tipWidth,tipHeight,coords=new CSSCoordinates;coords.set("top",0);coords.set("left",0);tipElement.css(coords);do{tipWidth=tipElement.outerWidth();tipHeight=tipElement.outerHeight();coords=placementCalculator.compute(element,placement,tipWidth,tipHeight,options.offset);tipElement.css(coords)}while(++iterationCount<=5&&(tipWidth!==tipElement.outerWidth()||tipHeight!==tipElement.outerHeight()));return coords}function closeDesyncedTip(){var isDesynced=false,hasDesyncableCloseEvent=$.grep(["mouseleave","mouseout","blur","focusout"],function(eventType){return $.inArray(eventType,options.closeEvents)!==-1}).length>0;if(session.isTipOpen&&!session.isClosing&&!session.delayInProgress&&hasDesyncableCloseEvent){if(session.activeHover.data(DATA_HASACTIVEHOVER)===false||session.activeHover.is(":disabled")){isDesynced=true}else if(!isMouseOver(session.activeHover)&&!session.activeHover.is(":focus")&&!session.activeHover.data(DATA_FORCEDOPEN)){if(tipElement.data(DATA_MOUSEONTOTIP)){if(!isMouseOver(tipElement)){isDesynced=true}}else{isDesynced=true}}if(isDesynced){hideTip(session.activeHover)}}}this.showTip=beginShowTip;this.hideTip=hideTip;this.resetPosition=positionTipOnElement}function isSvgElement(element){return Boolean(window.SVGElement&&element[0]instanceof SVGElement)}function isMouseEvent(event){return Boolean(event&&$.inArray(event.type,MOUSE_EVENTS)>-1&&typeof event.pageX==="number")}function initTracking(){if(!session.mouseTrackingActive){session.mouseTrackingActive=true;getViewportDimensions();$(getViewportDimensions);$document.on("mousemove"+EVENT_NAMESPACE,trackMouse);$window.on("resize"+EVENT_NAMESPACE,trackResize);$window.on("scroll"+EVENT_NAMESPACE,trackScroll)}}function getViewportDimensions(){session.scrollLeft=$window.scrollLeft();session.scrollTop=$window.scrollTop();session.windowWidth=$window.width();session.windowHeight=$window.height()}function trackResize(){session.windowWidth=$window.width();session.windowHeight=$window.height()}function trackScroll(){var x=$window.scrollLeft(),y=$window.scrollTop();if(x!==session.scrollLeft){session.currentX+=x-session.scrollLeft;session.scrollLeft=x}if(y!==session.scrollTop){session.currentY+=y-session.scrollTop;session.scrollTop=y}}function trackMouse(event){session.currentX=event.pageX;session.currentY=event.pageY}function isMouseOver(element){var elementPosition=element.offset(),elementBox=element[0].getBoundingClientRect(),elementWidth=elementBox.right-elementBox.left,elementHeight=elementBox.bottom-elementBox.top;return session.currentX>=elementPosition.left&&session.currentX<=elementPosition.left+elementWidth&&session.currentY>=elementPosition.top&&session.currentY<=elementPosition.top+elementHeight}function getTooltipContent(element){var tipText=element.data(DATA_POWERTIP),tipObject=element.data(DATA_POWERTIPJQ),tipTarget=element.data(DATA_POWERTIPTARGET),targetElement,content;if(tipText){if($.isFunction(tipText)){tipText=tipText.call(element[0])}content=tipText}else if(tipObject){if($.isFunction(tipObject)){tipObject=tipObject.call(element[0])}if(tipObject.length>0){content=tipObject.clone(true,true)}}else if(tipTarget){targetElement=$("#"+tipTarget);if(targetElement.length>0){content=targetElement.html()}}return content}function getViewportCollisions(coords,elementWidth,elementHeight){var viewportTop=session.scrollTop,viewportLeft=session.scrollLeft,viewportBottom=viewportTop+session.windowHeight,viewportRight=viewportLeft+session.windowWidth,collisions=Collision.none;if(coords.topviewportBottom||Math.abs(coords.bottom-session.windowHeight)>viewportBottom){collisions|=Collision.bottom}if(coords.leftviewportRight){collisions|=Collision.left}if(coords.left+elementWidth>viewportRight||coords.right1)){a.preventDefault();var c=a.originalEvent.changedTouches[0],d=document.createEvent("MouseEvents");d.initMouseEvent(b,!0,!0,window,1,c.screenX,c.screenY,c.clientX,c.clientY,!1,!1,!1,!1,0,null),a.target.dispatchEvent(d)}}if(a.support.touch="ontouchend"in document,a.support.touch){var e,b=a.ui.mouse.prototype,c=b._mouseInit,d=b._mouseDestroy;b._touchStart=function(a){var b=this;!e&&b._mouseCapture(a.originalEvent.changedTouches[0])&&(e=!0,b._touchMoved=!1,f(a,"mouseover"),f(a,"mousemove"),f(a,"mousedown"))},b._touchMove=function(a){e&&(this._touchMoved=!0,f(a,"mousemove"))},b._touchEnd=function(a){e&&(f(a,"mouseup"),f(a,"mouseout"),this._touchMoved||f(a,"click"),e=!1)},b._mouseInit=function(){var b=this;b.element.bind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),c.call(b)},b._mouseDestroy=function(){var b=this;b.element.unbind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),d.call(b)}}}(jQuery);/*! SmartMenus jQuery Plugin - v1.1.0 - September 17, 2017 + * http://www.smartmenus.org/ + * Copyright Vasil Dinkov, Vadikom Web Ltd. http://vadikom.com; Licensed MIT */(function(t){"function"==typeof define&&define.amd?define(["jquery"],t):"object"==typeof module&&"object"==typeof module.exports?module.exports=t(require("jquery")):t(jQuery)})(function($){function initMouseDetection(t){var e=".smartmenus_mouse";if(mouseDetectionEnabled||t)mouseDetectionEnabled&&t&&($(document).off(e),mouseDetectionEnabled=!1);else{var i=!0,s=null,o={mousemove:function(t){var e={x:t.pageX,y:t.pageY,timeStamp:(new Date).getTime()};if(s){var o=Math.abs(s.x-e.x),a=Math.abs(s.y-e.y);if((o>0||a>0)&&2>=o&&2>=a&&300>=e.timeStamp-s.timeStamp&&(mouse=!0,i)){var n=$(t.target).closest("a");n.is("a")&&$.each(menuTrees,function(){return $.contains(this.$root[0],n[0])?(this.itemEnter({currentTarget:n[0]}),!1):void 0}),i=!1}}s=e}};o[touchEvents?"touchstart":"pointerover pointermove pointerout MSPointerOver MSPointerMove MSPointerOut"]=function(t){isTouchEvent(t.originalEvent)&&(mouse=!1)},$(document).on(getEventsNS(o,e)),mouseDetectionEnabled=!0}}function isTouchEvent(t){return!/^(4|mouse)$/.test(t.pointerType)}function getEventsNS(t,e){e||(e="");var i={};for(var s in t)i[s.split(" ").join(e+" ")+e]=t[s];return i}var menuTrees=[],mouse=!1,touchEvents="ontouchstart"in window,mouseDetectionEnabled=!1,requestAnimationFrame=window.requestAnimationFrame||function(t){return setTimeout(t,1e3/60)},cancelAnimationFrame=window.cancelAnimationFrame||function(t){clearTimeout(t)},canAnimate=!!$.fn.animate;return $.SmartMenus=function(t,e){this.$root=$(t),this.opts=e,this.rootId="",this.accessIdPrefix="",this.$subArrow=null,this.activatedItems=[],this.visibleSubMenus=[],this.showTimeout=0,this.hideTimeout=0,this.scrollTimeout=0,this.clickActivated=!1,this.focusActivated=!1,this.zIndexInc=0,this.idInc=0,this.$firstLink=null,this.$firstSub=null,this.disabled=!1,this.$disableOverlay=null,this.$touchScrollingSub=null,this.cssTransforms3d="perspective"in t.style||"webkitPerspective"in t.style,this.wasCollapsible=!1,this.init()},$.extend($.SmartMenus,{hideAll:function(){$.each(menuTrees,function(){this.menuHideAll()})},destroy:function(){for(;menuTrees.length;)menuTrees[0].destroy();initMouseDetection(!0)},prototype:{init:function(t){var e=this;if(!t){menuTrees.push(this),this.rootId=((new Date).getTime()+Math.random()+"").replace(/\D/g,""),this.accessIdPrefix="sm-"+this.rootId+"-",this.$root.hasClass("sm-rtl")&&(this.opts.rightToLeftSubMenus=!0);var i=".smartmenus";this.$root.data("smartmenus",this).attr("data-smartmenus-id",this.rootId).dataSM("level",1).on(getEventsNS({"mouseover focusin":$.proxy(this.rootOver,this),"mouseout focusout":$.proxy(this.rootOut,this),keydown:$.proxy(this.rootKeyDown,this)},i)).on(getEventsNS({mouseenter:$.proxy(this.itemEnter,this),mouseleave:$.proxy(this.itemLeave,this),mousedown:$.proxy(this.itemDown,this),focus:$.proxy(this.itemFocus,this),blur:$.proxy(this.itemBlur,this),click:$.proxy(this.itemClick,this)},i),"a"),i+=this.rootId,this.opts.hideOnClick&&$(document).on(getEventsNS({touchstart:$.proxy(this.docTouchStart,this),touchmove:$.proxy(this.docTouchMove,this),touchend:$.proxy(this.docTouchEnd,this),click:$.proxy(this.docClick,this)},i)),$(window).on(getEventsNS({"resize orientationchange":$.proxy(this.winResize,this)},i)),this.opts.subIndicators&&(this.$subArrow=$("").addClass("sub-arrow"),this.opts.subIndicatorsText&&this.$subArrow.html(this.opts.subIndicatorsText)),initMouseDetection()}if(this.$firstSub=this.$root.find("ul").each(function(){e.menuInit($(this))}).eq(0),this.$firstLink=this.$root.find("a").eq(0),this.opts.markCurrentItem){var s=/(index|default)\.[^#\?\/]*/i,o=/#.*/,a=window.location.href.replace(s,""),n=a.replace(o,"");this.$root.find("a").each(function(){var t=this.href.replace(s,""),i=$(this);(t==a||t==n)&&(i.addClass("current"),e.opts.markCurrentTree&&i.parentsUntil("[data-smartmenus-id]","ul").each(function(){$(this).dataSM("parent-a").addClass("current")}))})}this.wasCollapsible=this.isCollapsible()},destroy:function(t){if(!t){var e=".smartmenus";this.$root.removeData("smartmenus").removeAttr("data-smartmenus-id").removeDataSM("level").off(e),e+=this.rootId,$(document).off(e),$(window).off(e),this.opts.subIndicators&&(this.$subArrow=null)}this.menuHideAll();var i=this;this.$root.find("ul").each(function(){var t=$(this);t.dataSM("scroll-arrows")&&t.dataSM("scroll-arrows").remove(),t.dataSM("shown-before")&&((i.opts.subMenusMinWidth||i.opts.subMenusMaxWidth)&&t.css({width:"",minWidth:"",maxWidth:""}).removeClass("sm-nowrap"),t.dataSM("scroll-arrows")&&t.dataSM("scroll-arrows").remove(),t.css({zIndex:"",top:"",left:"",marginLeft:"",marginTop:"",display:""})),0==(t.attr("id")||"").indexOf(i.accessIdPrefix)&&t.removeAttr("id")}).removeDataSM("in-mega").removeDataSM("shown-before").removeDataSM("scroll-arrows").removeDataSM("parent-a").removeDataSM("level").removeDataSM("beforefirstshowfired").removeAttr("role").removeAttr("aria-hidden").removeAttr("aria-labelledby").removeAttr("aria-expanded"),this.$root.find("a.has-submenu").each(function(){var t=$(this);0==t.attr("id").indexOf(i.accessIdPrefix)&&t.removeAttr("id")}).removeClass("has-submenu").removeDataSM("sub").removeAttr("aria-haspopup").removeAttr("aria-controls").removeAttr("aria-expanded").closest("li").removeDataSM("sub"),this.opts.subIndicators&&this.$root.find("span.sub-arrow").remove(),this.opts.markCurrentItem&&this.$root.find("a.current").removeClass("current"),t||(this.$root=null,this.$firstLink=null,this.$firstSub=null,this.$disableOverlay&&(this.$disableOverlay.remove(),this.$disableOverlay=null),menuTrees.splice($.inArray(this,menuTrees),1))},disable:function(t){if(!this.disabled){if(this.menuHideAll(),!t&&!this.opts.isPopup&&this.$root.is(":visible")){var e=this.$root.offset();this.$disableOverlay=$('
').css({position:"absolute",top:e.top,left:e.left,width:this.$root.outerWidth(),height:this.$root.outerHeight(),zIndex:this.getStartZIndex(!0),opacity:0}).appendTo(document.body)}this.disabled=!0}},docClick:function(t){return this.$touchScrollingSub?(this.$touchScrollingSub=null,void 0):((this.visibleSubMenus.length&&!$.contains(this.$root[0],t.target)||$(t.target).closest("a").length)&&this.menuHideAll(),void 0)},docTouchEnd:function(){if(this.lastTouch){if(!(!this.visibleSubMenus.length||void 0!==this.lastTouch.x2&&this.lastTouch.x1!=this.lastTouch.x2||void 0!==this.lastTouch.y2&&this.lastTouch.y1!=this.lastTouch.y2||this.lastTouch.target&&$.contains(this.$root[0],this.lastTouch.target))){this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0);var t=this;this.hideTimeout=setTimeout(function(){t.menuHideAll()},350)}this.lastTouch=null}},docTouchMove:function(t){if(this.lastTouch){var e=t.originalEvent.touches[0];this.lastTouch.x2=e.pageX,this.lastTouch.y2=e.pageY}},docTouchStart:function(t){var e=t.originalEvent.touches[0];this.lastTouch={x1:e.pageX,y1:e.pageY,target:e.target}},enable:function(){this.disabled&&(this.$disableOverlay&&(this.$disableOverlay.remove(),this.$disableOverlay=null),this.disabled=!1)},getClosestMenu:function(t){for(var e=$(t).closest("ul");e.dataSM("in-mega");)e=e.parent().closest("ul");return e[0]||null},getHeight:function(t){return this.getOffset(t,!0)},getOffset:function(t,e){var i;"none"==t.css("display")&&(i={position:t[0].style.position,visibility:t[0].style.visibility},t.css({position:"absolute",visibility:"hidden"}).show());var s=t[0].getBoundingClientRect&&t[0].getBoundingClientRect(),o=s&&(e?s.height||s.bottom-s.top:s.width||s.right-s.left);return o||0===o||(o=e?t[0].offsetHeight:t[0].offsetWidth),i&&t.hide().css(i),o},getStartZIndex:function(t){var e=parseInt(this[t?"$root":"$firstSub"].css("z-index"));return!t&&isNaN(e)&&(e=parseInt(this.$root.css("z-index"))),isNaN(e)?1:e},getTouchPoint:function(t){return t.touches&&t.touches[0]||t.changedTouches&&t.changedTouches[0]||t},getViewport:function(t){var e=t?"Height":"Width",i=document.documentElement["client"+e],s=window["inner"+e];return s&&(i=Math.min(i,s)),i},getViewportHeight:function(){return this.getViewport(!0)},getViewportWidth:function(){return this.getViewport()},getWidth:function(t){return this.getOffset(t)},handleEvents:function(){return!this.disabled&&this.isCSSOn()},handleItemEvents:function(t){return this.handleEvents()&&!this.isLinkInMegaMenu(t)},isCollapsible:function(){return"static"==this.$firstSub.css("position")},isCSSOn:function(){return"inline"!=this.$firstLink.css("display")},isFixed:function(){var t="fixed"==this.$root.css("position");return t||this.$root.parentsUntil("body").each(function(){return"fixed"==$(this).css("position")?(t=!0,!1):void 0}),t},isLinkInMegaMenu:function(t){return $(this.getClosestMenu(t[0])).hasClass("mega-menu")},isTouchMode:function(){return!mouse||this.opts.noMouseOver||this.isCollapsible()},itemActivate:function(t,e){var i=t.closest("ul"),s=i.dataSM("level");if(s>1&&(!this.activatedItems[s-2]||this.activatedItems[s-2][0]!=i.dataSM("parent-a")[0])){var o=this;$(i.parentsUntil("[data-smartmenus-id]","ul").get().reverse()).add(i).each(function(){o.itemActivate($(this).dataSM("parent-a"))})}if((!this.isCollapsible()||e)&&this.menuHideSubMenus(this.activatedItems[s-1]&&this.activatedItems[s-1][0]==t[0]?s:s-1),this.activatedItems[s-1]=t,this.$root.triggerHandler("activate.smapi",t[0])!==!1){var a=t.dataSM("sub");a&&(this.isTouchMode()||!this.opts.showOnClick||this.clickActivated)&&this.menuShow(a)}},itemBlur:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&this.$root.triggerHandler("blur.smapi",e[0])},itemClick:function(t){var e=$(t.currentTarget);if(this.handleItemEvents(e)){if(this.$touchScrollingSub&&this.$touchScrollingSub[0]==e.closest("ul")[0])return this.$touchScrollingSub=null,t.stopPropagation(),!1;if(this.$root.triggerHandler("click.smapi",e[0])===!1)return!1;var i=$(t.target).is(".sub-arrow"),s=e.dataSM("sub"),o=s?2==s.dataSM("level"):!1,a=this.isCollapsible(),n=/toggle$/.test(this.opts.collapsibleBehavior),r=/link$/.test(this.opts.collapsibleBehavior),h=/^accordion/.test(this.opts.collapsibleBehavior);if(s&&!s.is(":visible")){if((!r||!a||i)&&(this.opts.showOnClick&&o&&(this.clickActivated=!0),this.itemActivate(e,h),s.is(":visible")))return this.focusActivated=!0,!1}else if(a&&(n||i))return this.itemActivate(e,h),this.menuHide(s),n&&(this.focusActivated=!1),!1;return this.opts.showOnClick&&o||e.hasClass("disabled")||this.$root.triggerHandler("select.smapi",e[0])===!1?!1:void 0}},itemDown:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&e.dataSM("mousedown",!0)},itemEnter:function(t){var e=$(t.currentTarget);if(this.handleItemEvents(e)){if(!this.isTouchMode()){this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0);var i=this;this.showTimeout=setTimeout(function(){i.itemActivate(e)},this.opts.showOnClick&&1==e.closest("ul").dataSM("level")?1:this.opts.showTimeout)}this.$root.triggerHandler("mouseenter.smapi",e[0])}},itemFocus:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&(!this.focusActivated||this.isTouchMode()&&e.dataSM("mousedown")||this.activatedItems.length&&this.activatedItems[this.activatedItems.length-1][0]==e[0]||this.itemActivate(e,!0),this.$root.triggerHandler("focus.smapi",e[0]))},itemLeave:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&(this.isTouchMode()||(e[0].blur(),this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0)),e.removeDataSM("mousedown"),this.$root.triggerHandler("mouseleave.smapi",e[0]))},menuHide:function(t){if(this.$root.triggerHandler("beforehide.smapi",t[0])!==!1&&(canAnimate&&t.stop(!0,!0),"none"!=t.css("display"))){var e=function(){t.css("z-index","")};this.isCollapsible()?canAnimate&&this.opts.collapsibleHideFunction?this.opts.collapsibleHideFunction.call(this,t,e):t.hide(this.opts.collapsibleHideDuration,e):canAnimate&&this.opts.hideFunction?this.opts.hideFunction.call(this,t,e):t.hide(this.opts.hideDuration,e),t.dataSM("scroll")&&(this.menuScrollStop(t),t.css({"touch-action":"","-ms-touch-action":"","-webkit-transform":"",transform:""}).off(".smartmenus_scroll").removeDataSM("scroll").dataSM("scroll-arrows").hide()),t.dataSM("parent-a").removeClass("highlighted").attr("aria-expanded","false"),t.attr({"aria-expanded":"false","aria-hidden":"true"});var i=t.dataSM("level");this.activatedItems.splice(i-1,1),this.visibleSubMenus.splice($.inArray(t,this.visibleSubMenus),1),this.$root.triggerHandler("hide.smapi",t[0])}},menuHideAll:function(){this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0);for(var t=this.opts.isPopup?1:0,e=this.visibleSubMenus.length-1;e>=t;e--)this.menuHide(this.visibleSubMenus[e]);this.opts.isPopup&&(canAnimate&&this.$root.stop(!0,!0),this.$root.is(":visible")&&(canAnimate&&this.opts.hideFunction?this.opts.hideFunction.call(this,this.$root):this.$root.hide(this.opts.hideDuration))),this.activatedItems=[],this.visibleSubMenus=[],this.clickActivated=!1,this.focusActivated=!1,this.zIndexInc=0,this.$root.triggerHandler("hideAll.smapi")},menuHideSubMenus:function(t){for(var e=this.activatedItems.length-1;e>=t;e--){var i=this.activatedItems[e].dataSM("sub");i&&this.menuHide(i)}},menuInit:function(t){if(!t.dataSM("in-mega")){t.hasClass("mega-menu")&&t.find("ul").dataSM("in-mega",!0);for(var e=2,i=t[0];(i=i.parentNode.parentNode)!=this.$root[0];)e++;var s=t.prevAll("a").eq(-1);s.length||(s=t.prevAll().find("a").eq(-1)),s.addClass("has-submenu").dataSM("sub",t),t.dataSM("parent-a",s).dataSM("level",e).parent().dataSM("sub",t);var o=s.attr("id")||this.accessIdPrefix+ ++this.idInc,a=t.attr("id")||this.accessIdPrefix+ ++this.idInc;s.attr({id:o,"aria-haspopup":"true","aria-controls":a,"aria-expanded":"false"}),t.attr({id:a,role:"group","aria-hidden":"true","aria-labelledby":o,"aria-expanded":"false"}),this.opts.subIndicators&&s[this.opts.subIndicatorsPos](this.$subArrow.clone())}},menuPosition:function(t){var e,i,s=t.dataSM("parent-a"),o=s.closest("li"),a=o.parent(),n=t.dataSM("level"),r=this.getWidth(t),h=this.getHeight(t),u=s.offset(),l=u.left,c=u.top,d=this.getWidth(s),m=this.getHeight(s),p=$(window),f=p.scrollLeft(),v=p.scrollTop(),b=this.getViewportWidth(),S=this.getViewportHeight(),g=a.parent().is("[data-sm-horizontal-sub]")||2==n&&!a.hasClass("sm-vertical"),M=this.opts.rightToLeftSubMenus&&!o.is("[data-sm-reverse]")||!this.opts.rightToLeftSubMenus&&o.is("[data-sm-reverse]"),w=2==n?this.opts.mainMenuSubOffsetX:this.opts.subMenusSubOffsetX,T=2==n?this.opts.mainMenuSubOffsetY:this.opts.subMenusSubOffsetY;if(g?(e=M?d-r-w:w,i=this.opts.bottomToTopSubMenus?-h-T:m+T):(e=M?w-r:d-w,i=this.opts.bottomToTopSubMenus?m-T-h:T),this.opts.keepInViewport){var y=l+e,I=c+i;if(M&&f>y?e=g?f-y+e:d-w:!M&&y+r>f+b&&(e=g?f+b-r-y+e:w-r),g||(S>h&&I+h>v+S?i+=v+S-h-I:(h>=S||v>I)&&(i+=v-I)),g&&(I+h>v+S+.49||v>I)||!g&&h>S+.49){var x=this;t.dataSM("scroll-arrows")||t.dataSM("scroll-arrows",$([$('')[0],$('')[0]]).on({mouseenter:function(){t.dataSM("scroll").up=$(this).hasClass("scroll-up"),x.menuScroll(t)},mouseleave:function(e){x.menuScrollStop(t),x.menuScrollOut(t,e)},"mousewheel DOMMouseScroll":function(t){t.preventDefault()}}).insertAfter(t));var A=".smartmenus_scroll";if(t.dataSM("scroll",{y:this.cssTransforms3d?0:i-m,step:1,itemH:m,subH:h,arrowDownH:this.getHeight(t.dataSM("scroll-arrows").eq(1))}).on(getEventsNS({mouseover:function(e){x.menuScrollOver(t,e)},mouseout:function(e){x.menuScrollOut(t,e)},"mousewheel DOMMouseScroll":function(e){x.menuScrollMousewheel(t,e)}},A)).dataSM("scroll-arrows").css({top:"auto",left:"0",marginLeft:e+(parseInt(t.css("border-left-width"))||0),width:r-(parseInt(t.css("border-left-width"))||0)-(parseInt(t.css("border-right-width"))||0),zIndex:t.css("z-index")}).eq(g&&this.opts.bottomToTopSubMenus?0:1).show(),this.isFixed()){var C={};C[touchEvents?"touchstart touchmove touchend":"pointerdown pointermove pointerup MSPointerDown MSPointerMove MSPointerUp"]=function(e){x.menuScrollTouch(t,e)},t.css({"touch-action":"none","-ms-touch-action":"none"}).on(getEventsNS(C,A))}}}t.css({top:"auto",left:"0",marginLeft:e,marginTop:i-m})},menuScroll:function(t,e,i){var s,o=t.dataSM("scroll"),a=t.dataSM("scroll-arrows"),n=o.up?o.upEnd:o.downEnd;if(!e&&o.momentum){if(o.momentum*=.92,s=o.momentum,.5>s)return this.menuScrollStop(t),void 0}else s=i||(e||!this.opts.scrollAccelerate?this.opts.scrollStep:Math.floor(o.step));var r=t.dataSM("level");if(this.activatedItems[r-1]&&this.activatedItems[r-1].dataSM("sub")&&this.activatedItems[r-1].dataSM("sub").is(":visible")&&this.menuHideSubMenus(r-1),o.y=o.up&&o.y>=n||!o.up&&n>=o.y?o.y:Math.abs(n-o.y)>s?o.y+(o.up?s:-s):n,t.css(this.cssTransforms3d?{"-webkit-transform":"translate3d(0, "+o.y+"px, 0)",transform:"translate3d(0, "+o.y+"px, 0)"}:{marginTop:o.y}),mouse&&(o.up&&o.y>o.downEnd||!o.up&&o.y0;t.dataSM("scroll-arrows").eq(i?0:1).is(":visible")&&(t.dataSM("scroll").up=i,this.menuScroll(t,!0))}e.preventDefault()},menuScrollOut:function(t,e){mouse&&(/^scroll-(up|down)/.test((e.relatedTarget||"").className)||(t[0]==e.relatedTarget||$.contains(t[0],e.relatedTarget))&&this.getClosestMenu(e.relatedTarget)==t[0]||t.dataSM("scroll-arrows").css("visibility","hidden"))},menuScrollOver:function(t,e){if(mouse&&!/^scroll-(up|down)/.test(e.target.className)&&this.getClosestMenu(e.target)==t[0]){this.menuScrollRefreshData(t);var i=t.dataSM("scroll"),s=$(window).scrollTop()-t.dataSM("parent-a").offset().top-i.itemH;t.dataSM("scroll-arrows").eq(0).css("margin-top",s).end().eq(1).css("margin-top",s+this.getViewportHeight()-i.arrowDownH).end().css("visibility","visible")}},menuScrollRefreshData:function(t){var e=t.dataSM("scroll"),i=$(window).scrollTop()-t.dataSM("parent-a").offset().top-e.itemH;this.cssTransforms3d&&(i=-(parseFloat(t.css("margin-top"))-i)),$.extend(e,{upEnd:i,downEnd:i+this.getViewportHeight()-e.subH})},menuScrollStop:function(t){return this.scrollTimeout?(cancelAnimationFrame(this.scrollTimeout),this.scrollTimeout=0,t.dataSM("scroll").step=1,!0):void 0},menuScrollTouch:function(t,e){if(e=e.originalEvent,isTouchEvent(e)){var i=this.getTouchPoint(e);if(this.getClosestMenu(i.target)==t[0]){var s=t.dataSM("scroll");if(/(start|down)$/i.test(e.type))this.menuScrollStop(t)?(e.preventDefault(),this.$touchScrollingSub=t):this.$touchScrollingSub=null,this.menuScrollRefreshData(t),$.extend(s,{touchStartY:i.pageY,touchStartTime:e.timeStamp});else if(/move$/i.test(e.type)){var o=void 0!==s.touchY?s.touchY:s.touchStartY;if(void 0!==o&&o!=i.pageY){this.$touchScrollingSub=t;var a=i.pageY>o;void 0!==s.up&&s.up!=a&&$.extend(s,{touchStartY:i.pageY,touchStartTime:e.timeStamp}),$.extend(s,{up:a,touchY:i.pageY}),this.menuScroll(t,!0,Math.abs(i.pageY-o))}e.preventDefault()}else void 0!==s.touchY&&((s.momentum=15*Math.pow(Math.abs(i.pageY-s.touchStartY)/(e.timeStamp-s.touchStartTime),2))&&(this.menuScrollStop(t),this.menuScroll(t),e.preventDefault()),delete s.touchY)}}},menuShow:function(t){if((t.dataSM("beforefirstshowfired")||(t.dataSM("beforefirstshowfired",!0),this.$root.triggerHandler("beforefirstshow.smapi",t[0])!==!1))&&this.$root.triggerHandler("beforeshow.smapi",t[0])!==!1&&(t.dataSM("shown-before",!0),canAnimate&&t.stop(!0,!0),!t.is(":visible"))){var e=t.dataSM("parent-a"),i=this.isCollapsible();if((this.opts.keepHighlighted||i)&&e.addClass("highlighted"),i)t.removeClass("sm-nowrap").css({zIndex:"",width:"auto",minWidth:"",maxWidth:"",top:"",left:"",marginLeft:"",marginTop:""});else{if(t.css("z-index",this.zIndexInc=(this.zIndexInc||this.getStartZIndex())+1),(this.opts.subMenusMinWidth||this.opts.subMenusMaxWidth)&&(t.css({width:"auto",minWidth:"",maxWidth:""}).addClass("sm-nowrap"),this.opts.subMenusMinWidth&&t.css("min-width",this.opts.subMenusMinWidth),this.opts.subMenusMaxWidth)){var s=this.getWidth(t);t.css("max-width",this.opts.subMenusMaxWidth),s>this.getWidth(t)&&t.removeClass("sm-nowrap").css("width",this.opts.subMenusMaxWidth)}this.menuPosition(t)}var o=function(){t.css("overflow","")};i?canAnimate&&this.opts.collapsibleShowFunction?this.opts.collapsibleShowFunction.call(this,t,o):t.show(this.opts.collapsibleShowDuration,o):canAnimate&&this.opts.showFunction?this.opts.showFunction.call(this,t,o):t.show(this.opts.showDuration,o),e.attr("aria-expanded","true"),t.attr({"aria-expanded":"true","aria-hidden":"false"}),this.visibleSubMenus.push(t),this.$root.triggerHandler("show.smapi",t[0])}},popupHide:function(t){this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0);var e=this;this.hideTimeout=setTimeout(function(){e.menuHideAll()},t?1:this.opts.hideTimeout)},popupShow:function(t,e){if(!this.opts.isPopup)return alert('SmartMenus jQuery Error:\n\nIf you want to show this menu via the "popupShow" method, set the isPopup:true option.'),void 0;if(this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0),this.$root.dataSM("shown-before",!0),canAnimate&&this.$root.stop(!0,!0),!this.$root.is(":visible")){this.$root.css({left:t,top:e});var i=this,s=function(){i.$root.css("overflow","")};canAnimate&&this.opts.showFunction?this.opts.showFunction.call(this,this.$root,s):this.$root.show(this.opts.showDuration,s),this.visibleSubMenus[0]=this.$root}},refresh:function(){this.destroy(!0),this.init(!0)},rootKeyDown:function(t){if(this.handleEvents())switch(t.keyCode){case 27:var e=this.activatedItems[0];if(e){this.menuHideAll(),e[0].focus();var i=e.dataSM("sub");i&&this.menuHide(i)}break;case 32:var s=$(t.target);if(s.is("a")&&this.handleItemEvents(s)){var i=s.dataSM("sub");i&&!i.is(":visible")&&(this.itemClick({currentTarget:t.target}),t.preventDefault())}}},rootOut:function(t){if(this.handleEvents()&&!this.isTouchMode()&&t.target!=this.$root[0]&&(this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0),!this.opts.showOnClick||!this.opts.hideOnClick)){var e=this;this.hideTimeout=setTimeout(function(){e.menuHideAll()},this.opts.hideTimeout)}},rootOver:function(t){this.handleEvents()&&!this.isTouchMode()&&t.target!=this.$root[0]&&this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0)},winResize:function(t){if(this.handleEvents()){if(!("onorientationchange"in window)||"orientationchange"==t.type){var e=this.isCollapsible();this.wasCollapsible&&e||(this.activatedItems.length&&this.activatedItems[this.activatedItems.length-1][0].blur(),this.menuHideAll()),this.wasCollapsible=e}}else if(this.$disableOverlay){var i=this.$root.offset();this.$disableOverlay.css({top:i.top,left:i.left,width:this.$root.outerWidth(),height:this.$root.outerHeight()})}}}}),$.fn.dataSM=function(t,e){return e?this.data(t+"_smartmenus",e):this.data(t+"_smartmenus")},$.fn.removeDataSM=function(t){return this.removeData(t+"_smartmenus")},$.fn.smartmenus=function(options){if("string"==typeof options){var args=arguments,method=options;return Array.prototype.shift.call(args),this.each(function(){var t=$(this).data("smartmenus");t&&t[method]&&t[method].apply(t,args)})}return this.each(function(){var dataOpts=$(this).data("sm-options")||null;if(dataOpts)try{dataOpts=eval("("+dataOpts+")")}catch(e){dataOpts=null,alert('ERROR\n\nSmartMenus jQuery init:\nInvalid "data-sm-options" attribute value syntax.')}new $.SmartMenus(this,$.extend({},$.fn.smartmenus.defaults,options,dataOpts))})},$.fn.smartmenus.defaults={isPopup:!1,mainMenuSubOffsetX:0,mainMenuSubOffsetY:0,subMenusSubOffsetX:0,subMenusSubOffsetY:0,subMenusMinWidth:"10em",subMenusMaxWidth:"20em",subIndicators:!0,subIndicatorsPos:"append",subIndicatorsText:"",scrollStep:30,scrollAccelerate:!0,showTimeout:250,hideTimeout:500,showDuration:0,showFunction:null,hideDuration:0,hideFunction:function(t,e){t.fadeOut(200,e)},collapsibleShowDuration:0,collapsibleShowFunction:function(t,e){t.slideDown(200,e)},collapsibleHideDuration:0,collapsibleHideFunction:function(t,e){t.slideUp(200,e)},showOnClick:!1,hideOnClick:!0,noMouseOver:!1,keepInViewport:!0,keepHighlighted:!0,markCurrentItem:!1,markCurrentTree:!0,rightToLeftSubMenus:!1,bottomToTopSubMenus:!1,collapsibleBehavior:"default"},$}); \ No newline at end of file diff --git a/doxygen/junk__gen_8py.html b/doxygen/junk__gen_8py.html new file mode 100644 index 0000000..d56644c --- /dev/null +++ b/doxygen/junk__gen_8py.html @@ -0,0 +1,124 @@ + + + + + + + +OMG-Fuscator: junk_gen.py File Reference + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
junk_gen.py File Reference
+
+
+ +

Go to the source code of this file.

+ + + + +

+Classes

class  utils.junk_gen.JunkGenerator
 
+ + + + + +

+Namespaces

namespace  utils
 
namespace  utils.junk_gen
 
+
+
+ + + + diff --git a/doxygen/junk__gen_8py.js b/doxygen/junk__gen_8py.js new file mode 100644 index 0000000..1325a1c --- /dev/null +++ b/doxygen/junk__gen_8py.js @@ -0,0 +1,4 @@ +var junk__gen_8py = +[ + [ "utils.junk_gen.JunkGenerator", "classutils_1_1junk__gen_1_1JunkGenerator.html", "classutils_1_1junk__gen_1_1JunkGenerator" ] +]; \ No newline at end of file diff --git a/doxygen/junk__gen_8py_source.html b/doxygen/junk__gen_8py_source.html new file mode 100644 index 0000000..5cdc659 --- /dev/null +++ b/doxygen/junk__gen_8py_source.html @@ -0,0 +1,195 @@ + + + + + + + +OMG-Fuscator: junk_gen.py Source File + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
junk_gen.py
+
+
+Go to the documentation of this file.
1"""
+
2@file utils/junk_gen.py
+
3@brief Junk code generation utilities for OMG-Fuscator.
+
4@details Generates random noise statements and multi-line snippets for obfuscation.
+
5"""
+
6
+
7import random
+
8import string
+
9from utils.name_gen import NameGenerator
+
10
+
+ +
12 """
+
13 @brief Produces pseudo-random junk code.
+
14 @param name_generator Name generator used for variable identifiers.
+
15 """
+
+
16 def __init__(self, name_generator: NameGenerator):
+
17 """
+
18 @brief Constructor.
+
19 @param name_generator NameGenerator instance used to create junk variable names.
+
20 """
+
21 self.name_generator = name_generator
+
22
+
+
+
23 def add_junk(self) -> str:
+
24 """
+
25 @brief Generate a random multi-line junk code snippet.
+
26 @return Python source string with one or more lines.
+
27 """
+
28 var1 = self.name_generator.generate_name()
+
29 var2 = self.name_generator.generate_name()
+
30
+
31 example_strings = ["HelloWorld", "CryptoMagic", "XxX_Obf_42", "DataStorm", "RandomStr", "TestString"]
+
32 s1 = random.choice(example_strings)
+
33 s2 = random.choice(example_strings)
+
34
+
35 multi_line_junks = [
+
36 f"{var1} = chr({random.randint(65, 90)}) + chr({random.randint(65, 90)})",
+
37 f"{var1} = sum([{random.randint(1,10)} for _ in range({random.randint(1,5)})])",
+
38 f"{var1} = len(bytes([{random.randint(65,90)}, {random.randint(65,90)}, {random.randint(65,90)}]))",
+
39 f"if chr({random.randint(65,90)}).isupper(): {var1} = {random.randint(0, 999)}",
+
40 f"{var1} = bytes([{random.randint(65,90)}] * {random.randint(1,3)})",
+
41 f"{var1} = ord(chr({random.randint(65,90)})) - {random.randint(1,10)}",
+
42
+
43 f"{var1} = '{s1}'.lower()\n{var2} = '{s2}'.upper()",
+
44 f"{var1} = [chr(random.randint(65,90)) for _ in range({random.randint(2,5)})]\n{var2} = ''.join({var1})",
+
45 f"{var1} = {random.randint(1,10)} ** {random.randint(1,3)}\n{var2} = {var1} % {random.randint(1,10)}",
+
46 f"{var1} = [{random.randint(1,5)} for _ in range({random.randint(3,5)})]\nif len({var1}) > {random.randint(1,4)}: {var2} = sum({var1})",
+
47 f"{var1} = {{ {random.randint(1,10)} : '{s1}' }}\n{var2} = {var1}.get({random.randint(1,10)}, None)",
+
48 f"{var1} = set(range({random.randint(2,5)}))\n{var2} = set(range({random.randint(2,5)}))\n{var1}.intersection({var2})"
+
49 ]
+
50 return random.choice(multi_line_junks)
+
51
+
+
+
52 def generate_junk(self) -> str:
+
53 """
+
54 @brief Generate a single-line junk statement.
+
55 @return Python source string for a single assignment or expression.
+
56 """
+
57 var_name = self.name_generator.generate_name()
+
58 junk_code = [
+
59 f"{var_name} = {random.randint(0, 100)}",
+
60 f"{var_name} = '{''.join(random.choices(string.ascii_letters, k=10))}'",
+
61 f"{var_name} = {random.randint(0, 100)} + {random.randint(0, 100)}",
+
62 f"{var_name} = {random.randint(0, 100)} * {random.randint(0, 100)}",
+
63 f"{var_name} = {random.randint(0, 100)} - {random.randint(0, 100)}",
+
64 f"{var_name} = {random.randint(0, 100)} / {random.randint(1, 100)}",
+
65 f"{var_name} = '{''.join(random.choices(string.ascii_letters + string.digits, k=15))}'",
+
66 f"{var_name} = {random.randint(0, 100)} % {random.randint(1, 100)}",
+
67 f"{var_name} = {random.randint(0, 100)} ** {random.randint(0, 5)}",
+
68 f"{var_name} = {random.randint(0, 100)} // {random.randint(1, 100)}"
+
69 ]
+
70 return random.choice(junk_code)
+
+
+ + + +
__init__(self, NameGenerator name_generator)
Definition junk_gen.py:16
+ + +
+
+ + + + diff --git a/doxygen/main_8py.html b/doxygen/main_8py.html new file mode 100644 index 0000000..14f6ce1 --- /dev/null +++ b/doxygen/main_8py.html @@ -0,0 +1,122 @@ + + + + + + + +OMG-Fuscator: main.py File Reference + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
main.py File Reference
+
+
+ +

Go to the source code of this file.

+ + + + +

+Namespaces

namespace  main
 
+ + + +

+Functions

 main.main ()
 
+
+
+ + + + diff --git a/doxygen/main_8py.js b/doxygen/main_8py.js new file mode 100644 index 0000000..1de8bbc --- /dev/null +++ b/doxygen/main_8py.js @@ -0,0 +1,4 @@ +var main_8py = +[ + [ "main", "main_8py.html#a3140e9a5b6a71ffbf498198cfc471b88", null ] +]; \ No newline at end of file diff --git a/doxygen/main_8py_source.html b/doxygen/main_8py_source.html new file mode 100644 index 0000000..0c78d32 --- /dev/null +++ b/doxygen/main_8py_source.html @@ -0,0 +1,212 @@ + + + + + + + +OMG-Fuscator: main.py Source File + + + + + + + + + + + + + +
+
+ + + + + + +
+
OMG-Fuscator +
+
Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
+
+
+ + + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
main.py
+
+
+Go to the documentation of this file.
1"""
+
2@file main.py
+
3@brief Command-line interface for OMG-Fuscator.
+
4@details Parses CLI arguments, runs obfuscation via AdvancedObfuscator, and prints or writes output.
+
5"""
+
6
+
7import argparse
+
8import sys
+
9from pathlib import Path
+
10from obfuscator import AdvancedObfuscator
+
11
+
+
12def main():
+
13 """
+
14 @brief CLI entrypoint.
+
15 @details Handles --test demo, reads input file, runs obfuscator, and writes output.
+
16 @arg -i, --input Path to input .py file (required unless --test).
+
17 @arg -o, --output Output file path (default: input_stem_obfuscated.py).
+
18 @arg -v, --verbose Verbose console logging.
+
19 @arg --test Run built-in demo instead of file-based obfuscation.
+
20 """
+
21 parser = argparse.ArgumentParser(description="OMG-Fuscator: Advanced Python Code Obfuscator")
+
22 parser.add_argument("-i", "--input", type=str, help="Input Python file path")
+
23 parser.add_argument("-o", "--output", type=str, help="Output file path (default: input_obfuscated.py)")
+
24 parser.add_argument("--test", action="store_true", help="Run test with sample code")
+
25 parser.add_argument("-v", "--verbose", action="store_true", help="Enable verbose output")
+
26
+
27 args = parser.parse_args()
+
28
+
29 obfuscator = AdvancedObfuscator()
+
30
+
31 if args.test:
+
32 # Example test code that includes a top-level function
+
33 test_code = r'''
+
34def my_top_level_func(a, b):
+
35 return a + b
+
36
+
37def compare_versions(v1, v2):
+
38 return (v1 > v2) - (v1 < v2)
+
39
+
40def main():
+
41 print("my_top_level_func(2,3) =", my_top_level_func(2,3))
+
42 version = 2
+
43 latest = 1
+
44 if compare_versions(version, latest) > 0:
+
45 print("version is higher")
+
46 else:
+
47 print("version is not higher")
+
48
+
49main()
+
50 '''
+
51
+
52 if args.verbose:
+
53 print("Running in test mode with sample code...")
+
54
+
55 obfuscated = obfuscator.obfuscate(test_code)
+
56 print("Obfuscated test code:")
+
57 print(obfuscated)
+
58 print("\nExecuting obfuscated code:")
+
59 exec_namespace = {}
+
60 exec(obfuscated, exec_namespace, exec_namespace)
+
61 sys.exit(0)
+
62
+
63 if not args.input:
+
64 parser.error("Please provide an input file with -i or use --test")
+
65
+
66 in_path = Path(args.input)
+
67 if not in_path.exists():
+
68 parser.error(f"Input file not found: {in_path}")
+
69
+
70 if in_path.suffix != '.py':
+
71 parser.error("Input file must be a .py file")
+
72
+
73 out_path = Path(args.output) if args.output else in_path.parent / f"{in_path.stem}_obfuscated.py"
+
74 try:
+
75 if args.verbose:
+
76 print(f"Reading file: {in_path}")
+
77 with open(in_path, "r", encoding="utf-8") as fin:
+
78 src_code = fin.read()
+
79
+
80 if args.verbose:
+
81 print("Obfuscating...")
+
82 final_code = obfuscator.obfuscate(src_code)
+
83
+
84 if args.verbose:
+
85 print(f"Writing obfuscated code to: {out_path}")
+
86 with open(out_path, "w", encoding="utf-8") as fout:
+
87 fout.write(final_code)
+
88
+
89 print(f"Obfuscated code written to: {out_path}")
+
90
+
91 except Exception as e:
+
92 print(f"Error during obfuscation: {e}", file=sys.stderr)
+
93 sys.exit(1)
+
94
+
+
95if __name__ == "__main__":
+
96 main()
+ +
Definition main.py:1
+
main()
Definition main.py:12
+
+
+ + + + diff --git a/doxygen/menu.js b/doxygen/menu.js new file mode 100644 index 0000000..b0b2693 --- /dev/null +++ b/doxygen/menu.js @@ -0,0 +1,136 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @licend The above is the entire license notice for the JavaScript code in this file + */ +function initMenu(relPath,searchEnabled,serverSide,searchPage,search) { + function makeTree(data,relPath) { + var result=''; + if ('children' in data) { + result+='
    '; + for (var i in data.children) { + var url; + var link; + link = data.children[i].url; + if (link.substring(0,1)=='^') { + url = link.substring(1); + } else { + url = relPath+link; + } + result+='
  • '+ + data.children[i].text+''+ + makeTree(data.children[i],relPath)+'
  • '; + } + result+='
'; + } + return result; + } + var searchBoxHtml; + if (searchEnabled) { + if (serverSide) { + searchBoxHtml='
'+ + '
'+ + '
 '+ + ''+ + '
'+ + '
'+ + '
'+ + '
'; + } else { + searchBoxHtml='
'+ + ''+ + ' '+ + ''+ + ''+ + ''+ + ''+ + ''+ + '
'; + } + } + + $('#main-nav').before('
'+ + ''+ + ''+ + '
'); + $('#main-nav').append(makeTree(menudata,relPath)); + $('#main-nav').children(':first').addClass('sm sm-dox').attr('id','main-menu'); + if (searchBoxHtml) { + $('#main-menu').append('
  • '); + } + var $mainMenuState = $('#main-menu-state'); + var prevWidth = 0; + if ($mainMenuState.length) { + function initResizableIfExists() { + if (typeof initResizable==='function') initResizable(); + } + // animate mobile menu + $mainMenuState.change(function(e) { + var $menu = $('#main-menu'); + var options = { duration: 250, step: initResizableIfExists }; + if (this.checked) { + options['complete'] = function() { $menu.css('display', 'block') }; + $menu.hide().slideDown(options); + } else { + options['complete'] = function() { $menu.css('display', 'none') }; + $menu.show().slideUp(options); + } + }); + // set default menu visibility + function resetState() { + var $menu = $('#main-menu'); + var $mainMenuState = $('#main-menu-state'); + var newWidth = $(window).outerWidth(); + if (newWidth!=prevWidth) { + if ($(window).outerWidth()<768) { + $mainMenuState.prop('checked',false); $menu.hide(); + $('#searchBoxPos1').html(searchBoxHtml); + $('#searchBoxPos2').hide(); + } else { + $menu.show(); + $('#searchBoxPos1').empty(); + $('#searchBoxPos2').html(searchBoxHtml); + $('#searchBoxPos2').show(); + } + if (typeof searchBox!=='undefined') { + searchBox.CloseResultsWindow(); + } + prevWidth = newWidth; + } + } + $(window).ready(function() { resetState(); initResizableIfExists(); }); + $(window).resize(resetState); + } + $('#main-menu').smartmenus(); +} +/* @license-end */ diff --git a/doxygen/menudata.js b/doxygen/menudata.js new file mode 100644 index 0000000..de83ac4 --- /dev/null +++ b/doxygen/menudata.js @@ -0,0 +1,97 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @licend The above is the entire license notice for the JavaScript code in this file +*/ +var menudata={children:[ +{text:"Main Page",url:"index.html"}, +{text:"Namespaces",url:"namespaces.html",children:[ +{text:"Namespace List",url:"namespaces.html"}, +{text:"Namespace Members",url:"namespacemembers.html",children:[ +{text:"All",url:"namespacemembers.html"}, +{text:"Functions",url:"namespacemembers_func.html"}, +{text:"Variables",url:"namespacemembers_vars.html"}]}]}, +{text:"Classes",url:"annotated.html",children:[ +{text:"Class List",url:"annotated.html"}, +{text:"Class Index",url:"classes.html"}, +{text:"Class Hierarchy",url:"inherits.html"}, +{text:"Class Members",url:"functions.html",children:[ +{text:"All",url:"functions.html",children:[ +{text:"_",url:"functions.html#index__5F"}, +{text:"a",url:"functions.html#index_a"}, +{text:"b",url:"functions.html#index_b"}, +{text:"c",url:"functions.html#index_c"}, +{text:"d",url:"functions.html#index_d"}, +{text:"e",url:"functions.html#index_e"}, +{text:"f",url:"functions.html#index_f"}, +{text:"g",url:"functions.html#index_g"}, +{text:"h",url:"functions.html#index_h"}, +{text:"i",url:"functions.html#index_i"}, +{text:"j",url:"functions.html#index_j"}, +{text:"k",url:"functions.html#index_k"}, +{text:"l",url:"functions.html#index_l"}, +{text:"m",url:"functions.html#index_m"}, +{text:"n",url:"functions.html#index_n"}, +{text:"o",url:"functions.html#index_o"}, +{text:"p",url:"functions.html#index_p"}, +{text:"r",url:"functions.html#index_r"}, +{text:"s",url:"functions.html#index_s"}, +{text:"t",url:"functions.html#index_t"}, +{text:"u",url:"functions.html#index_u"}, +{text:"v",url:"functions.html#index_v"}]}, +{text:"Functions",url:"functions_func.html",children:[ +{text:"_",url:"functions_func.html#index__5F"}, +{text:"a",url:"functions_func.html#index_a"}, +{text:"b",url:"functions_func.html#index_b"}, +{text:"c",url:"functions_func.html#index_c"}, +{text:"d",url:"functions_func.html#index_d"}, +{text:"e",url:"functions_func.html#index_e"}, +{text:"f",url:"functions_func.html#index_f"}, +{text:"g",url:"functions_func.html#index_g"}, +{text:"h",url:"functions_func.html#index_h"}, +{text:"l",url:"functions_func.html#index_l"}, +{text:"o",url:"functions_func.html#index_o"}, +{text:"p",url:"functions_func.html#index_p"}, +{text:"r",url:"functions_func.html#index_r"}, +{text:"s",url:"functions_func.html#index_s"}, +{text:"v",url:"functions_func.html#index_v"}]}, +{text:"Variables",url:"functions_vars.html",children:[ +{text:"_",url:"functions_vars.html#index__5F"}, +{text:"a",url:"functions_vars.html#index_a"}, +{text:"c",url:"functions_vars.html#index_c"}, +{text:"d",url:"functions_vars.html#index_d"}, +{text:"e",url:"functions_vars.html#index_e"}, +{text:"f",url:"functions_vars.html#index_f"}, +{text:"g",url:"functions_vars.html#index_g"}, +{text:"i",url:"functions_vars.html#index_i"}, +{text:"j",url:"functions_vars.html#index_j"}, +{text:"k",url:"functions_vars.html#index_k"}, +{text:"m",url:"functions_vars.html#index_m"}, +{text:"n",url:"functions_vars.html#index_n"}, +{text:"p",url:"functions_vars.html#index_p"}, +{text:"r",url:"functions_vars.html#index_r"}, +{text:"s",url:"functions_vars.html#index_s"}, +{text:"t",url:"functions_vars.html#index_t"}, +{text:"u",url:"functions_vars.html#index_u"}, +{text:"v",url:"functions_vars.html#index_v"}]}]}]}, +{text:"Files",url:"files.html",children:[ +{text:"File List",url:"files.html"}]}]} diff --git a/doxygen/minus.svg b/doxygen/minus.svg new file mode 100644 index 0000000..f70d0c1 --- /dev/null +++ b/doxygen/minus.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/doxygen/minusd.svg b/doxygen/minusd.svg new file mode 100644 index 0000000..5f8e879 --- /dev/null +++ b/doxygen/minusd.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/doxygen/name__gen_8py.html b/doxygen/name__gen_8py.html new file mode 100644 index 0000000..1f950d7 --- /dev/null +++ b/doxygen/name__gen_8py.html @@ -0,0 +1,124 @@ + + + + + + + +OMG-Fuscator: name_gen.py File Reference + + + + + + + + + + + + + +
    +
    + + + + + + +
    +
    OMG-Fuscator +
    +
    Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
    +
    +
    + + + + + + + +
    +
    + +
    +
    +
    + +
    + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + +
    + +
    name_gen.py File Reference
    +
    +
    + +

    Go to the source code of this file.

    + + + + +

    +Classes

    class  utils.name_gen.NameGenerator
     
    + + + + + +

    +Namespaces

    namespace  utils
     
    namespace  utils.name_gen
     
    +
    +
    + + + + diff --git a/doxygen/name__gen_8py.js b/doxygen/name__gen_8py.js new file mode 100644 index 0000000..0adbc2d --- /dev/null +++ b/doxygen/name__gen_8py.js @@ -0,0 +1,4 @@ +var name__gen_8py = +[ + [ "utils.name_gen.NameGenerator", "classutils_1_1name__gen_1_1NameGenerator.html", "classutils_1_1name__gen_1_1NameGenerator" ] +]; \ No newline at end of file diff --git a/doxygen/name__gen_8py_source.html b/doxygen/name__gen_8py_source.html new file mode 100644 index 0000000..3681c65 --- /dev/null +++ b/doxygen/name__gen_8py_source.html @@ -0,0 +1,167 @@ + + + + + + + +OMG-Fuscator: name_gen.py Source File + + + + + + + + + + + + + +
    +
    + + + + + + +
    +
    OMG-Fuscator +
    +
    Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
    +
    +
    + + + + + + + + +
    +
    + +
    +
    +
    + +
    + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + +
    +
    name_gen.py
    +
    +
    +Go to the documentation of this file.
    1"""
    +
    2@file utils/name_gen.py
    +
    3@brief Obfuscated identifier name generator.
    +
    4@details Provides NameGenerator that yields high-entropy-looking identifiers
    +
    5 and ensures uniqueness across a transformation session.
    +
    6"""
    +
    7import itertools
    +
    8from typing import Iterator, Set
    +
    9
    +
    + +
    11 """
    +
    12 @brief Generates unique obfuscated identifiers.
    +
    13 @details Uses patterned Cartesian products to create long, confusing names and
    +
    14 tracks used names to avoid collisions.
    +
    15 """
    +
    +
    16 def __init__(self):
    +
    17 """
    +
    18 @brief Initialize internal iterator and used-name set.
    +
    19 """
    + +
    21 self.used_names = set()
    +
    22
    +
    +
    +
    23 def _create_iterator(self) -> Iterator[str]:
    +
    24 """
    +
    25 @brief Iterator producing obfuscated identifier candidates.
    +
    26 @return Iterator[str] Infinite stream of names such as vIl1lO0o0Z2z2...
    +
    27 """
    +
    28 patterns = ['Il1l', 'O0o0', 'Z2z2', 'S5s5', 'B8b8', 'Q9q9']
    +
    29 for length in itertools.count(2): # Start with length=2, continue forever
    +
    30 for combo in itertools.product(patterns, repeat=length):
    +
    31 yield 'v' + ''.join(combo)
    +
    32
    +
    +
    +
    33 def generate_name(self) -> str:
    +
    34 """
    +
    35 @brief Produce a fresh, unique obfuscated name.
    +
    36 @return str Name guaranteed not to have been produced before by this instance.
    +
    37 """
    +
    38 while True:
    +
    39 candidate = next(self._name_iterator)
    +
    40 if candidate not in self.used_names:
    +
    41 self.used_names.add(candidate)
    +
    42 return candidate
    +
    +
    + +
    Iterator[str] _create_iterator(self)
    Definition name_gen.py:23
    + + + + +
    +
    + + + + diff --git a/doxygen/namespacemain.html b/doxygen/namespacemain.html new file mode 100644 index 0000000..3c28962 --- /dev/null +++ b/doxygen/namespacemain.html @@ -0,0 +1,228 @@ + + + + + + + +OMG-Fuscator: main Namespace Reference + + + + + + + + + + + + + +
    +
    + + + + + + +
    +
    OMG-Fuscator +
    +
    Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
    +
    +
    + + + + + + + +
    +
    + +
    +
    +
    + +
    + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + +
    + +
    main Namespace Reference
    +
    +
    + + + + +

    +Functions

     main ()
     
    +

    Detailed Description

    +
    @file main.py
    +@brief Command-line interface for OMG-Fuscator.
    +@details Parses CLI arguments, runs obfuscation via AdvancedObfuscator, and prints or writes output.
    +

    Function Documentation

    + +

    ◆ main()

    + +
    +
    + + + + + + + +
    main.main ()
    +
    +
    @brief CLI entrypoint.
    +@details Handles --test demo, reads input file, runs obfuscator, and writes output.
    +@arg -i, --input Path to input .py file (required unless --test).
    +@arg -o, --output Output file path (default: input_stem_obfuscated.py).
    +@arg -v, --verbose Verbose console logging.
    +@arg --test Run built-in demo instead of file-based obfuscation.
    +
    +

    Definition at line 12 of file main.py.

    +
    12def main():
    +
    13 """
    +
    14 @brief CLI entrypoint.
    +
    15 @details Handles --test demo, reads input file, runs obfuscator, and writes output.
    +
    16 @arg -i, --input Path to input .py file (required unless --test).
    +
    17 @arg -o, --output Output file path (default: input_stem_obfuscated.py).
    +
    18 @arg -v, --verbose Verbose console logging.
    +
    19 @arg --test Run built-in demo instead of file-based obfuscation.
    +
    20 """
    +
    21 parser = argparse.ArgumentParser(description="OMG-Fuscator: Advanced Python Code Obfuscator")
    +
    22 parser.add_argument("-i", "--input", type=str, help="Input Python file path")
    +
    23 parser.add_argument("-o", "--output", type=str, help="Output file path (default: input_obfuscated.py)")
    +
    24 parser.add_argument("--test", action="store_true", help="Run test with sample code")
    +
    25 parser.add_argument("-v", "--verbose", action="store_true", help="Enable verbose output")
    +
    26
    +
    27 args = parser.parse_args()
    +
    28
    +
    29 obfuscator = AdvancedObfuscator()
    +
    30
    +
    31 if args.test:
    +
    32 # Example test code that includes a top-level function
    +
    33 test_code = r'''
    +
    34def my_top_level_func(a, b):
    +
    35 return a + b
    +
    36
    +
    37def compare_versions(v1, v2):
    +
    38 return (v1 > v2) - (v1 < v2)
    +
    39
    +
    40def main():
    +
    41 print("my_top_level_func(2,3) =", my_top_level_func(2,3))
    +
    42 version = 2
    +
    43 latest = 1
    +
    44 if compare_versions(version, latest) > 0:
    +
    45 print("version is higher")
    +
    46 else:
    +
    47 print("version is not higher")
    +
    48
    +
    49main()
    +
    50 '''
    +
    51
    +
    52 if args.verbose:
    +
    53 print("Running in test mode with sample code...")
    +
    54
    +
    55 obfuscated = obfuscator.obfuscate(test_code)
    +
    56 print("Obfuscated test code:")
    +
    57 print(obfuscated)
    +
    58 print("\nExecuting obfuscated code:")
    +
    59 exec_namespace = {}
    +
    60 exec(obfuscated, exec_namespace, exec_namespace)
    +
    61 sys.exit(0)
    +
    62
    +
    63 if not args.input:
    +
    64 parser.error("Please provide an input file with -i or use --test")
    +
    65
    +
    66 in_path = Path(args.input)
    +
    67 if not in_path.exists():
    +
    68 parser.error(f"Input file not found: {in_path}")
    +
    69
    +
    70 if in_path.suffix != '.py':
    +
    71 parser.error("Input file must be a .py file")
    +
    72
    +
    73 out_path = Path(args.output) if args.output else in_path.parent / f"{in_path.stem}_obfuscated.py"
    +
    74 try:
    +
    75 if args.verbose:
    +
    76 print(f"Reading file: {in_path}")
    +
    77 with open(in_path, "r", encoding="utf-8") as fin:
    +
    78 src_code = fin.read()
    +
    79
    +
    80 if args.verbose:
    +
    81 print("Obfuscating...")
    +
    82 final_code = obfuscator.obfuscate(src_code)
    +
    83
    +
    84 if args.verbose:
    +
    85 print(f"Writing obfuscated code to: {out_path}")
    +
    86 with open(out_path, "w", encoding="utf-8") as fout:
    +
    87 fout.write(final_code)
    +
    88
    +
    89 print(f"Obfuscated code written to: {out_path}")
    +
    90
    +
    91 except Exception as e:
    +
    92 print(f"Error during obfuscation: {e}", file=sys.stderr)
    +
    93 sys.exit(1)
    +
    94
    +
    Definition main.py:1
    +
    +
    +
    +
    +
    + + + + diff --git a/doxygen/namespacemembers.html b/doxygen/namespacemembers.html new file mode 100644 index 0000000..4cb98c7 --- /dev/null +++ b/doxygen/namespacemembers.html @@ -0,0 +1,110 @@ + + + + + + + +OMG-Fuscator: Namespace Members + + + + + + + + + + + + + +
    +
    + + + + + + +
    +
    OMG-Fuscator +
    +
    Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
    +
    +
    + + + + + + + +
    +
    + +
    +
    +
    + +
    + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + +
    +
    Here is a list of all namespace members with links to the namespace documentation for each member:
    +
    +
    + + + + diff --git a/doxygen/namespacemembers_func.html b/doxygen/namespacemembers_func.html new file mode 100644 index 0000000..13a0c6a --- /dev/null +++ b/doxygen/namespacemembers_func.html @@ -0,0 +1,108 @@ + + + + + + + +OMG-Fuscator: Namespace Members + + + + + + + + + + + + + +
    +
    + + + + + + +
    +
    OMG-Fuscator +
    +
    Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
    +
    +
    + + + + + + + +
    +
    + +
    +
    +
    + +
    + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + +
    +
    Here is a list of all namespace functions with links to the namespace documentation for each function:
    +
    +
    + + + + diff --git a/doxygen/namespacemembers_vars.html b/doxygen/namespacemembers_vars.html new file mode 100644 index 0000000..bbd1c48 --- /dev/null +++ b/doxygen/namespacemembers_vars.html @@ -0,0 +1,106 @@ + + + + + + + +OMG-Fuscator: Namespace Members + + + + + + + + + + + + + +
    +
    + + + + + + +
    +
    OMG-Fuscator +
    +
    Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
    +
    +
    + + + + + + + +
    +
    + +
    +
    +
    + +
    + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + +
    +
    Here is a list of all namespace variables with links to the namespace documentation for each variable:
    +
    +
    + + + + diff --git a/doxygen/namespaceobfuscator.html b/doxygen/namespaceobfuscator.html new file mode 100644 index 0000000..d143181 --- /dev/null +++ b/doxygen/namespaceobfuscator.html @@ -0,0 +1,120 @@ + + + + + + + +OMG-Fuscator: obfuscator Namespace Reference + + + + + + + + + + + + + +
    +
    + + + + + + +
    +
    OMG-Fuscator +
    +
    Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
    +
    +
    + + + + + + + +
    +
    + +
    +
    +
    + +
    + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + +
    + +
    obfuscator Namespace Reference
    +
    +
    + + + + +

    +Classes

    class  AdvancedObfuscator
     
    +

    Detailed Description

    +
    @file obfuscator.py
    +@brief Core engine for OMG-Fuscator.
    +@details Orchestrates the full obfuscation pipeline: symbol analysis and renaming,
    +         string encryption, control-flow flattening, and junk code insertion.
    +         Provides debug instrumentation and JSON reporting when enabled.
    +
    +
    + + + + diff --git a/doxygen/namespaceobfuscator.js b/doxygen/namespaceobfuscator.js new file mode 100644 index 0000000..79490e8 --- /dev/null +++ b/doxygen/namespaceobfuscator.js @@ -0,0 +1,4 @@ +var namespaceobfuscator = +[ + [ "AdvancedObfuscator", "classobfuscator_1_1AdvancedObfuscator.html", "classobfuscator_1_1AdvancedObfuscator" ] +]; \ No newline at end of file diff --git a/doxygen/namespaces.html b/doxygen/namespaces.html new file mode 100644 index 0000000..9c01d6f --- /dev/null +++ b/doxygen/namespaces.html @@ -0,0 +1,141 @@ + + + + + + + +OMG-Fuscator: Namespace List + + + + + + + + + + + + + +
    +
    + + + + + + +
    +
    OMG-Fuscator +
    +
    Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
    +
    +
    + + + + + + + +
    +
    + +
    +
    +
    + +
    + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + +
    +
    Namespace List
    +
    +
    +
    Here is a list of all namespaces with brief descriptions:
    +
    +
    + + + + diff --git a/doxygen/namespaces_dup.js b/doxygen/namespaces_dup.js new file mode 100644 index 0000000..8cfd428 --- /dev/null +++ b/doxygen/namespaces_dup.js @@ -0,0 +1,9 @@ +var namespaces_dup = +[ + [ "main", "namespacemain.html", [ + [ "main", "namespacemain.html#a3140e9a5b6a71ffbf498198cfc471b88", null ] + ] ], + [ "obfuscator", "namespaceobfuscator.html", "namespaceobfuscator" ], + [ "transformers", "namespacetransformers.html", "namespacetransformers" ], + [ "utils", "namespaceutils.html", "namespaceutils" ] +]; \ No newline at end of file diff --git a/doxygen/namespacetransformers.html b/doxygen/namespacetransformers.html new file mode 100644 index 0000000..15386c2 --- /dev/null +++ b/doxygen/namespacetransformers.html @@ -0,0 +1,130 @@ + + + + + + + +OMG-Fuscator: transformers Namespace Reference + + + + + + + + + + + + + +
    +
    + + + + + + +
    +
    OMG-Fuscator +
    +
    Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
    +
    +
    + + + + + + + +
    +
    + +
    +
    +
    + +
    + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + +
    + +
    transformers Namespace Reference
    +
    +
    + + + + + + + + + + + + + + +

    +Namespaces

    namespace  attribute_transformer
     
    namespace  class_analyzer
     
    namespace  class_mapper
     
    namespace  control_flow
     
    namespace  rename
     
    namespace  symbol_tree
     
    +

    Detailed Description

    +
    @file transformers/__init__.py
    +@brief Package initializer for the transformers module.
    +@details Groups AST transformers and analyzers used by OMG-Fuscator, including
    +         renaming, control-flow flattening, class mapping, attribute handling,
    +         and symbol tree utilities.
    +
    +
    + + + + diff --git a/doxygen/namespacetransformers.js b/doxygen/namespacetransformers.js new file mode 100644 index 0000000..42245d1 --- /dev/null +++ b/doxygen/namespacetransformers.js @@ -0,0 +1,9 @@ +var namespacetransformers = +[ + [ "attribute_transformer", "namespacetransformers_1_1attribute__transformer.html", "namespacetransformers_1_1attribute__transformer" ], + [ "class_analyzer", "namespacetransformers_1_1class__analyzer.html", "namespacetransformers_1_1class__analyzer" ], + [ "class_mapper", "namespacetransformers_1_1class__mapper.html", "namespacetransformers_1_1class__mapper" ], + [ "control_flow", "namespacetransformers_1_1control__flow.html", "namespacetransformers_1_1control__flow" ], + [ "rename", "namespacetransformers_1_1rename.html", "namespacetransformers_1_1rename" ], + [ "symbol_tree", "namespacetransformers_1_1symbol__tree.html", "namespacetransformers_1_1symbol__tree" ] +]; \ No newline at end of file diff --git a/doxygen/namespacetransformers_1_1attribute__transformer.html b/doxygen/namespacetransformers_1_1attribute__transformer.html new file mode 100644 index 0000000..32700c4 --- /dev/null +++ b/doxygen/namespacetransformers_1_1attribute__transformer.html @@ -0,0 +1,119 @@ + + + + + + + +OMG-Fuscator: transformers.attribute_transformer Namespace Reference + + + + + + + + + + + + + +
    +
    + + + + + + +
    +
    OMG-Fuscator +
    +
    Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
    +
    +
    + + + + + + + +
    +
    + +
    +
    +
    + +
    + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + +
    + +
    transformers.attribute_transformer Namespace Reference
    +
    +
    + + + + +

    +Classes

    class  AttributeTransformer
     
    +

    Detailed Description

    +
    @file transformers/attribute_transformer.py
    +@brief Attribute access transformer for consistent class member renaming.
    +@details Ensures references like self.method and self.attr are kept consistent
    +         with class and attribute mappings produced by analysis.
    +
    +
    + + + + diff --git a/doxygen/namespacetransformers_1_1attribute__transformer.js b/doxygen/namespacetransformers_1_1attribute__transformer.js new file mode 100644 index 0000000..de628ae --- /dev/null +++ b/doxygen/namespacetransformers_1_1attribute__transformer.js @@ -0,0 +1,4 @@ +var namespacetransformers_1_1attribute__transformer = +[ + [ "AttributeTransformer", "classtransformers_1_1attribute__transformer_1_1AttributeTransformer.html", "classtransformers_1_1attribute__transformer_1_1AttributeTransformer" ] +]; \ No newline at end of file diff --git a/doxygen/namespacetransformers_1_1class__analyzer.html b/doxygen/namespacetransformers_1_1class__analyzer.html new file mode 100644 index 0000000..6a94f25 --- /dev/null +++ b/doxygen/namespacetransformers_1_1class__analyzer.html @@ -0,0 +1,224 @@ + + + + + + + +OMG-Fuscator: transformers.class_analyzer Namespace Reference + + + + + + + + + + + + + +
    +
    + + + + + + +
    +
    OMG-Fuscator +
    +
    Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
    +
    +
    + + + + + + + +
    +
    + +
    +
    +
    + +
    + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + +
    + +
    transformers.class_analyzer Namespace Reference
    +
    +
    + + + + + + +

    +Classes

    class  ClassAnalyzer
     
    class  ClassMethodMap
     
    + + + + + +

    +Functions

    Tuple[bool, str] get_method_name (ast.Attribute node)
     
     update_obfuscator_with_class_mappings (obfuscator, ClassMethodMap class_map)
     
    +

    Detailed Description

    +
    @file transformers/class_analyzer.py
    +@brief Class analysis utilities for consistent renaming.
    +@details Pre-analyzes classes, methods, attributes, and inheritance to build
    +         consistent mappings used by obfuscation transformers.
    +

    Function Documentation

    + +

    ◆ get_method_name()

    + +
    +
    + + + + + + + + +
    Tuple[bool, str] transformers.class_analyzer.get_method_name (ast.Attribute node)
    +
    +
    @brief Determine if an attribute is a self.method() call.
    +@param node Attribute node to check.
    +@return Tuple[bool, str] (is_self_method, method_name)
    +
    +

    Definition at line 201 of file class_analyzer.py.

    +
    201def get_method_name(node: ast.Attribute) -> Tuple[bool, str]:
    +
    202 """
    +
    203 @brief Determine if an attribute is a self.method() call.
    +
    204 @param node Attribute node to check.
    +
    205 @return Tuple[bool, str] (is_self_method, method_name)
    +
    206 """
    +
    207 if isinstance(node.value, ast.Name) and node.value.id == 'self':
    +
    208 return True, node.attr
    +
    209 return False, ""
    +
    210
    +
    211
    +
    +

    Referenced by transformers.class_analyzer.ClassAnalyzer.visit_Attribute().

    + +
    +
    + +

    ◆ update_obfuscator_with_class_mappings()

    + +
    +
    + + + + + + + + + + + + + + + + + + +
    transformers.class_analyzer.update_obfuscator_with_class_mappings ( obfuscator,
    ClassMethodMap class_map 
    )
    +
    +
    @brief Update obfuscator with class/method/attribute mappings.
    +@param obfuscator AdvancedObfuscator instance to update.
    +@param class_map ClassMethodMap mappings produced by analysis.
    +
    +

    Definition at line 212 of file class_analyzer.py.

    +
    212def update_obfuscator_with_class_mappings(obfuscator, class_map: ClassMethodMap):
    +
    213 """
    +
    214 @brief Update obfuscator with class/method/attribute mappings.
    +
    215 @param obfuscator AdvancedObfuscator instance to update.
    +
    216 @param class_map ClassMethodMap mappings produced by analysis.
    +
    217 """
    +
    218 # Update class name mappings in global_var_renames
    +
    219 for orig_name, obf_name in class_map.class_renames.items():
    +
    220 obfuscator.global_var_renames[orig_name] = obf_name
    +
    221
    +
    222 # Update class attr mapping with our analyzed data
    +
    223 for class_name, class_obf_name in class_map.class_renames.items():
    +
    224 # Initialize if needed
    +
    225 if class_obf_name not in obfuscator.class_attr_mapping:
    +
    226 obfuscator.class_attr_mapping[class_obf_name] = {}
    +
    227
    +
    228 # Copy method mappings
    +
    229 if class_name in class_map.class_methods:
    +
    230 for method, obf_method in class_map.class_methods[class_name].items():
    +
    231 obfuscator.class_attr_mapping[class_obf_name][method] = obf_method
    +
    232
    +
    233 # Copy attribute mappings
    +
    234 if class_name in class_map.class_attributes:
    +
    235 for attr, obf_attr in class_map.class_attributes[class_name].items():
    +
    236 obfuscator.class_attr_mapping[class_obf_name][attr] = obf_attr
    +
    +
    +
    +
    +
    + + + + diff --git a/doxygen/namespacetransformers_1_1class__analyzer.js b/doxygen/namespacetransformers_1_1class__analyzer.js new file mode 100644 index 0000000..af86065 --- /dev/null +++ b/doxygen/namespacetransformers_1_1class__analyzer.js @@ -0,0 +1,7 @@ +var namespacetransformers_1_1class__analyzer = +[ + [ "ClassAnalyzer", "classtransformers_1_1class__analyzer_1_1ClassAnalyzer.html", "classtransformers_1_1class__analyzer_1_1ClassAnalyzer" ], + [ "ClassMethodMap", "classtransformers_1_1class__analyzer_1_1ClassMethodMap.html", "classtransformers_1_1class__analyzer_1_1ClassMethodMap" ], + [ "get_method_name", "namespacetransformers_1_1class__analyzer.html#a6b97dea989b6eb9d37b5d9b53fae3b6d", null ], + [ "update_obfuscator_with_class_mappings", "namespacetransformers_1_1class__analyzer.html#a33c650248422029fa53952d08e4da438", null ] +]; \ No newline at end of file diff --git a/doxygen/namespacetransformers_1_1class__mapper.html b/doxygen/namespacetransformers_1_1class__mapper.html new file mode 100644 index 0000000..5b2fb33 --- /dev/null +++ b/doxygen/namespacetransformers_1_1class__mapper.html @@ -0,0 +1,221 @@ + + + + + + + +OMG-Fuscator: transformers.class_mapper Namespace Reference + + + + + + + + + + + + + +
    +
    + + + + + + +
    +
    OMG-Fuscator +
    +
    Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
    +
    +
    + + + + + + + +
    +
    + +
    +
    +
    + +
    + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + +
    + +
    transformers.class_mapper Namespace Reference
    +
    +
    + + + + + + + + +

    +Classes

    class  ClassMapAnalyzer
     
    class  ClassMapping
     
    class  ClassTransformer
     
    + + + +

    +Functions

    ast.AST apply_class_mapping (ast.AST tree, name_generator)
     
    + + + + + +

    +Variables

     level
     
     logger = logging.getLogger("ClassMapper")
     
    +

    Detailed Description

    +
    @file transformers/class_mapper.py
    +@brief Class, method, and attribute mapping analyzer and transformer.
    +@details Builds consistent rename mappings across classes, resolves inheritance,
    +         and applies the mappings back to the AST for coherent obfuscation.
    +

    Function Documentation

    + +

    ◆ apply_class_mapping()

    + +
    +
    + + + + + + + + + + + + + + + + + + +
    ast.AST transformers.class_mapper.apply_class_mapping (ast.AST tree,
     name_generator 
    )
    +
    +
    @brief Analyze and transform classes consistently.
    +@param tree Input AST.
    +@param name_generator Name generator used to create obfuscated identifiers.
    +@return Tuple[ast.AST, ClassMapping] Transformed AST and the mapping produced.
    +
    +

    Definition at line 341 of file class_mapper.py.

    +
    341def apply_class_mapping(tree: ast.AST, name_generator) -> ast.AST:
    +
    342 """
    +
    343 @brief Analyze and transform classes consistently.
    +
    344 @param tree Input AST.
    +
    345 @param name_generator Name generator used to create obfuscated identifiers.
    +
    346 @return Tuple[ast.AST, ClassMapping] Transformed AST and the mapping produced.
    +
    347 """
    +
    348 # First pass: analyze all classes
    +
    349 analyzer = ClassMapAnalyzer(name_generator)
    +
    350 mapping = analyzer.analyze(tree)
    +
    351
    +
    352 # Second pass: transform using the mapping
    +
    353 transformer = ClassTransformer(mapping)
    +
    354 transformed = transformer.visit(tree)
    +
    355
    +
    356 return transformed, mapping
    +
    +
    +
    +

    Variable Documentation

    + +

    ◆ level

    + +
    +
    + + + + +
    transformers.class_mapper.level
    +
    + +

    Definition at line 13 of file class_mapper.py.

    + +
    +
    + +

    ◆ logger

    + +
    +
    + + + + +
    transformers.class_mapper.logger = logging.getLogger("ClassMapper")
    +
    + +

    Definition at line 14 of file class_mapper.py.

    + +
    +
    +
    +
    + + + + diff --git a/doxygen/namespacetransformers_1_1class__mapper.js b/doxygen/namespacetransformers_1_1class__mapper.js new file mode 100644 index 0000000..fe1f9ff --- /dev/null +++ b/doxygen/namespacetransformers_1_1class__mapper.js @@ -0,0 +1,9 @@ +var namespacetransformers_1_1class__mapper = +[ + [ "ClassMapAnalyzer", "classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html", "classtransformers_1_1class__mapper_1_1ClassMapAnalyzer" ], + [ "ClassMapping", "classtransformers_1_1class__mapper_1_1ClassMapping.html", "classtransformers_1_1class__mapper_1_1ClassMapping" ], + [ "ClassTransformer", "classtransformers_1_1class__mapper_1_1ClassTransformer.html", "classtransformers_1_1class__mapper_1_1ClassTransformer" ], + [ "apply_class_mapping", "namespacetransformers_1_1class__mapper.html#a799073dc76d04c46febc20f3f88ff430", null ], + [ "level", "namespacetransformers_1_1class__mapper.html#a9ce72747d2040877bfa3d561bbcfb046", null ], + [ "logger", "namespacetransformers_1_1class__mapper.html#a77f334648be077cc4cf07b5862cc34f1", null ] +]; \ No newline at end of file diff --git a/doxygen/namespacetransformers_1_1control__flow.html b/doxygen/namespacetransformers_1_1control__flow.html new file mode 100644 index 0000000..1a43a55 --- /dev/null +++ b/doxygen/namespacetransformers_1_1control__flow.html @@ -0,0 +1,160 @@ + + + + + + + +OMG-Fuscator: transformers.control_flow Namespace Reference + + + + + + + + + + + + + +
    +
    + + + + + + +
    +
    OMG-Fuscator +
    +
    Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
    +
    +
    + + + + + + + +
    +
    + +
    +
    +
    + +
    + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + +
    + +
    transformers.control_flow Namespace Reference
    +
    +
    + + + + +

    +Classes

    class  ControlFlowFlattener
     
    + + + + + +

    +Variables

     level
     
     logger = logging.getLogger("ControlFlowFlattener")
     
    +

    Detailed Description

    +
    @file transformers/control_flow.py
    +@brief Control-flow flattening transformer.
    +@details Converts structured control flow into a state-machine with a while/dispatch
    +         loop to hinder static analysis, and can emit debug telemetry in debug mode.
    +

    Variable Documentation

    + +

    ◆ level

    + +
    +
    + + + + +
    transformers.control_flow.level
    +
    + +

    Definition at line 13 of file control_flow.py.

    + +
    +
    + +

    ◆ logger

    + +
    +
    + + + + +
    transformers.control_flow.logger = logging.getLogger("ControlFlowFlattener")
    +
    + +

    Definition at line 14 of file control_flow.py.

    + +
    +
    +
    +
    + + + + diff --git a/doxygen/namespacetransformers_1_1control__flow.js b/doxygen/namespacetransformers_1_1control__flow.js new file mode 100644 index 0000000..4915ba8 --- /dev/null +++ b/doxygen/namespacetransformers_1_1control__flow.js @@ -0,0 +1,6 @@ +var namespacetransformers_1_1control__flow = +[ + [ "ControlFlowFlattener", "classtransformers_1_1control__flow_1_1ControlFlowFlattener.html", "classtransformers_1_1control__flow_1_1ControlFlowFlattener" ], + [ "level", "namespacetransformers_1_1control__flow.html#a8c90b886e8d2a91a19bc062aebcd5682", null ], + [ "logger", "namespacetransformers_1_1control__flow.html#a6509497a1f3193babfae90f14a285aa3", null ] +]; \ No newline at end of file diff --git a/doxygen/namespacetransformers_1_1rename.html b/doxygen/namespacetransformers_1_1rename.html new file mode 100644 index 0000000..c2909ac --- /dev/null +++ b/doxygen/namespacetransformers_1_1rename.html @@ -0,0 +1,160 @@ + + + + + + + +OMG-Fuscator: transformers.rename Namespace Reference + + + + + + + + + + + + + +
    +
    + + + + + + +
    +
    OMG-Fuscator +
    +
    Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
    +
    +
    + + + + + + + +
    +
    + +
    +
    +
    + +
    + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + +
    + +
    transformers.rename Namespace Reference
    +
    +
    + + + + +

    +Classes

    class  RenameTransformer
     
    + + + + + +

    +Variables

     level
     
     logger = logging.getLogger("RenameTransformer")
     
    +

    Detailed Description

    +
    @file transformers/rename.py
    +@brief Identifier renaming and string literal encryption transformer.
    +@details Performs scoped variable/function renaming, consistent class/method/attribute
    +         remapping, and in-place string encryption producing runtime decryption code.
    +

    Variable Documentation

    + +

    ◆ level

    + +
    +
    + + + + +
    transformers.rename.level
    +
    + +

    Definition at line 14 of file rename.py.

    + +
    +
    + +

    ◆ logger

    + +
    +
    + + + + +
    transformers.rename.logger = logging.getLogger("RenameTransformer")
    +
    + +

    Definition at line 15 of file rename.py.

    + +
    +
    +
    +
    + + + + diff --git a/doxygen/namespacetransformers_1_1rename.js b/doxygen/namespacetransformers_1_1rename.js new file mode 100644 index 0000000..08f982f --- /dev/null +++ b/doxygen/namespacetransformers_1_1rename.js @@ -0,0 +1,6 @@ +var namespacetransformers_1_1rename = +[ + [ "RenameTransformer", "classtransformers_1_1rename_1_1RenameTransformer.html", "classtransformers_1_1rename_1_1RenameTransformer" ], + [ "level", "namespacetransformers_1_1rename.html#a2cbae0d4878e456bd1322692636887a3", null ], + [ "logger", "namespacetransformers_1_1rename.html#a8d3edc6223d05ff25d552b11ceca5aa7", null ] +]; \ No newline at end of file diff --git a/doxygen/namespacetransformers_1_1symbol__tree.html b/doxygen/namespacetransformers_1_1symbol__tree.html new file mode 100644 index 0000000..09eb58a --- /dev/null +++ b/doxygen/namespacetransformers_1_1symbol__tree.html @@ -0,0 +1,173 @@ + + + + + + + +OMG-Fuscator: transformers.symbol_tree Namespace Reference + + + + + + + + + + + + + +
    +
    + + + + + + +
    +
    OMG-Fuscator +
    +
    Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
    +
    +
    + + + + + + + +
    +
    + +
    +
    +
    + +
    + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + +
    + +
    transformers.symbol_tree Namespace Reference
    +
    +
    + + + + + + + + + + + + + + + + +

    +Classes

    class  ClassScope
     
    class  ModuleScope
     
    class  Scope
     
    class  Symbol
     
    class  SymbolTree
     
    class  SymbolTreeBuilder
     
    class  SymbolType
     
    + + + + + +

    +Variables

     level
     
     logger = logging.getLogger("SymbolTree")
     
    +

    Detailed Description

    +
    @file transformers/symbol_tree.py
    +@brief Global symbol tree and scope tracking.
    +@details Builds a hierarchical representation of scopes (module, class, function),
    +         tracks symbols, imports, references, and inheritance; generates rename
    +         mappings consumed by the obfuscation pipeline.
    +

    Variable Documentation

    + +

    ◆ level

    + +
    +
    + + + + +
    transformers.symbol_tree.level
    +
    + +

    Definition at line 14 of file symbol_tree.py.

    + +
    +
    + +

    ◆ logger

    + +
    +
    + + + + +
    transformers.symbol_tree.logger = logging.getLogger("SymbolTree")
    +
    + +

    Definition at line 15 of file symbol_tree.py.

    + +
    +
    +
    +
    + + + + diff --git a/doxygen/namespacetransformers_1_1symbol__tree.js b/doxygen/namespacetransformers_1_1symbol__tree.js new file mode 100644 index 0000000..729f3d7 --- /dev/null +++ b/doxygen/namespacetransformers_1_1symbol__tree.js @@ -0,0 +1,12 @@ +var namespacetransformers_1_1symbol__tree = +[ + [ "ClassScope", "classtransformers_1_1symbol__tree_1_1ClassScope.html", "classtransformers_1_1symbol__tree_1_1ClassScope" ], + [ "ModuleScope", "classtransformers_1_1symbol__tree_1_1ModuleScope.html", "classtransformers_1_1symbol__tree_1_1ModuleScope" ], + [ "Scope", "classtransformers_1_1symbol__tree_1_1Scope.html", "classtransformers_1_1symbol__tree_1_1Scope" ], + [ "Symbol", "classtransformers_1_1symbol__tree_1_1Symbol.html", "classtransformers_1_1symbol__tree_1_1Symbol" ], + [ "SymbolTree", "classtransformers_1_1symbol__tree_1_1SymbolTree.html", "classtransformers_1_1symbol__tree_1_1SymbolTree" ], + [ "SymbolTreeBuilder", "classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html", "classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder" ], + [ "SymbolType", "classtransformers_1_1symbol__tree_1_1SymbolType.html", "classtransformers_1_1symbol__tree_1_1SymbolType" ], + [ "level", "namespacetransformers_1_1symbol__tree.html#a6dfa45a6fa455a60c68cd968e9da90b5", null ], + [ "logger", "namespacetransformers_1_1symbol__tree.html#acff3629ca6817ec50dfe5bdc75f58745", null ] +]; \ No newline at end of file diff --git a/doxygen/namespaceutils.html b/doxygen/namespaceutils.html new file mode 100644 index 0000000..4b6e370 --- /dev/null +++ b/doxygen/namespaceutils.html @@ -0,0 +1,123 @@ + + + + + + + +OMG-Fuscator: utils Namespace Reference + + + + + + + + + + + + + +
    +
    + + + + + + +
    +
    OMG-Fuscator +
    +
    Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
    +
    +
    + + + + + + + +
    +
    + +
    +
    +
    + +
    + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + +
    + +
    utils Namespace Reference
    +
    +
    + + + + + + + + +

    +Namespaces

    namespace  encryption
     
    namespace  junk_gen
     
    namespace  name_gen
     
    +

    Detailed Description

    +
    @file utils/__init__.py
    +@brief Package initializer for utility helpers.
    +@details Exposes helper modules used by OMG-Fuscator (encryption, junk generation,
    +         and obfuscated name generation).
    +
    +
    + + + + diff --git a/doxygen/namespaceutils.js b/doxygen/namespaceutils.js new file mode 100644 index 0000000..f65644f --- /dev/null +++ b/doxygen/namespaceutils.js @@ -0,0 +1,6 @@ +var namespaceutils = +[ + [ "encryption", "namespaceutils_1_1encryption.html", "namespaceutils_1_1encryption" ], + [ "junk_gen", "namespaceutils_1_1junk__gen.html", "namespaceutils_1_1junk__gen" ], + [ "name_gen", "namespaceutils_1_1name__gen.html", "namespaceutils_1_1name__gen" ] +]; \ No newline at end of file diff --git a/doxygen/namespaceutils_1_1encryption.html b/doxygen/namespaceutils_1_1encryption.html new file mode 100644 index 0000000..5cdff39 --- /dev/null +++ b/doxygen/namespaceutils_1_1encryption.html @@ -0,0 +1,120 @@ + + + + + + + +OMG-Fuscator: utils.encryption Namespace Reference + + + + + + + + + + + + + +
    +
    + + + + + + +
    +
    OMG-Fuscator +
    +
    Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
    +
    +
    + + + + + + + +
    +
    + +
    +
    +
    + +
    + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + +
    + +
    utils.encryption Namespace Reference
    +
    +
    + + + + +

    +Classes

    class  StringEncryptor
     
    +

    Detailed Description

    +
    @file utils/encryption.py
    +@brief String encryption utilities for OMG-Fuscator.
    +@details Provides the StringEncryptor used by the obfuscation pipeline to transform
    +         string literals into runtime-decrypted expressions, making static analysis
    +         significantly harder.
    +
    +
    + + + + diff --git a/doxygen/namespaceutils_1_1encryption.js b/doxygen/namespaceutils_1_1encryption.js new file mode 100644 index 0000000..2730572 --- /dev/null +++ b/doxygen/namespaceutils_1_1encryption.js @@ -0,0 +1,4 @@ +var namespaceutils_1_1encryption = +[ + [ "StringEncryptor", "classutils_1_1encryption_1_1StringEncryptor.html", "classutils_1_1encryption_1_1StringEncryptor" ] +]; \ No newline at end of file diff --git a/doxygen/namespaceutils_1_1junk__gen.html b/doxygen/namespaceutils_1_1junk__gen.html new file mode 100644 index 0000000..2fc06ea --- /dev/null +++ b/doxygen/namespaceutils_1_1junk__gen.html @@ -0,0 +1,118 @@ + + + + + + + +OMG-Fuscator: utils.junk_gen Namespace Reference + + + + + + + + + + + + + +
    +
    + + + + + + +
    +
    OMG-Fuscator +
    +
    Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
    +
    +
    + + + + + + + +
    +
    + +
    +
    +
    + +
    + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + +
    + +
    utils.junk_gen Namespace Reference
    +
    +
    + + + + +

    +Classes

    class  JunkGenerator
     
    +

    Detailed Description

    +
    @file utils/junk_gen.py
    +@brief Junk code generation utilities for OMG-Fuscator.
    +@details Generates random noise statements and multi-line snippets for obfuscation.
    +
    +
    + + + + diff --git a/doxygen/namespaceutils_1_1junk__gen.js b/doxygen/namespaceutils_1_1junk__gen.js new file mode 100644 index 0000000..7c9a593 --- /dev/null +++ b/doxygen/namespaceutils_1_1junk__gen.js @@ -0,0 +1,4 @@ +var namespaceutils_1_1junk__gen = +[ + [ "JunkGenerator", "classutils_1_1junk__gen_1_1JunkGenerator.html", "classutils_1_1junk__gen_1_1JunkGenerator" ] +]; \ No newline at end of file diff --git a/doxygen/namespaceutils_1_1name__gen.html b/doxygen/namespaceutils_1_1name__gen.html new file mode 100644 index 0000000..a2e23f5 --- /dev/null +++ b/doxygen/namespaceutils_1_1name__gen.html @@ -0,0 +1,119 @@ + + + + + + + +OMG-Fuscator: utils.name_gen Namespace Reference + + + + + + + + + + + + + +
    +
    + + + + + + +
    +
    OMG-Fuscator +
    +
    Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
    +
    +
    + + + + + + + +
    +
    + +
    +
    +
    + +
    + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + +
    + +
    utils.name_gen Namespace Reference
    +
    +
    + + + + +

    +Classes

    class  NameGenerator
     
    +

    Detailed Description

    +
    @file utils/name_gen.py
    +@brief Obfuscated identifier name generator.
    +@details Provides NameGenerator that yields high-entropy-looking identifiers
    +         and ensures uniqueness across a transformation session.
    +
    +
    + + + + diff --git a/doxygen/namespaceutils_1_1name__gen.js b/doxygen/namespaceutils_1_1name__gen.js new file mode 100644 index 0000000..4d214d1 --- /dev/null +++ b/doxygen/namespaceutils_1_1name__gen.js @@ -0,0 +1,4 @@ +var namespaceutils_1_1name__gen = +[ + [ "NameGenerator", "classutils_1_1name__gen_1_1NameGenerator.html", "classutils_1_1name__gen_1_1NameGenerator" ] +]; \ No newline at end of file diff --git a/doxygen/nav_f.png b/doxygen/nav_f.png new file mode 100644 index 0000000000000000000000000000000000000000..72a58a529ed3a9ed6aa0c51a79cf207e026deee2 GIT binary patch literal 153 zcmeAS@N?(olHy`uVBq!ia0vp^j6iI`!2~2XGqLUlQVE_ejv*C{Z|{2ZH7M}7UYxc) zn!W8uqtnIQ>_z8U literal 0 HcmV?d00001 diff --git a/doxygen/nav_fd.png b/doxygen/nav_fd.png new file mode 100644 index 0000000000000000000000000000000000000000..032fbdd4c54f54fa9a2e6423b94ef4b2ebdfaceb GIT binary patch literal 169 zcmeAS@N?(olHy`uVBq!ia0vp^j6iI`!2~2XGqLUlQU#tajv*C{Z|C~*H7f|XvG1G8 zt7aS*L7xwMeS}!z6R#{C5tIw-s~AJ==F^i}x3XyJseHR@yF& zerFf(Zf;Dd{+(0lDIROL@Sj-Ju2JQ8&-n%4%q?>|^bShc&lR?}7HeMo@BDl5N(aHY Uj$gdr1MOz;boFyt=akR{0D!zeaR2}S literal 0 HcmV?d00001 diff --git a/doxygen/nav_g.png b/doxygen/nav_g.png new file mode 100644 index 0000000000000000000000000000000000000000..2093a237a94f6c83e19ec6e5fd42f7ddabdafa81 GIT binary patch literal 95 zcmeAS@N?(olHy`uVBq!ia0vp^j6lrB!3HFm1ilyoDK$?Q$B+ufw|5PB85lU25BhtE tr?otc=hd~V+ws&_A@j8Fiv!KF$B+ufw|5=67#uj90@pIL wZ=Q8~_Ju`#59=RjDrmm`tMD@M=!-l18IR?&vFVdQ&MBb@0HFXL6W-eg#Jd_@e6*DPn)w;=|1H}Zvm9l6xXXB%>yL=NQU;mg M>FVdQ&MBb@0Bdt1Qvd(} literal 0 HcmV?d00001 diff --git a/doxygen/navtree.css b/doxygen/navtree.css new file mode 100644 index 0000000..69211d4 --- /dev/null +++ b/doxygen/navtree.css @@ -0,0 +1,149 @@ +#nav-tree .children_ul { + margin:0; + padding:4px; +} + +#nav-tree ul { + list-style:none outside none; + margin:0px; + padding:0px; +} + +#nav-tree li { + white-space:nowrap; + margin:0px; + padding:0px; +} + +#nav-tree .plus { + margin:0px; +} + +#nav-tree .selected { + background-image: url('tab_a.png'); + background-repeat:repeat-x; + color: var(--nav-text-active-color); + text-shadow: var(--nav-text-active-shadow); +} + +#nav-tree .selected .arrow { + color: var(--nav-arrow-selected-color); + text-shadow: none; +} + +#nav-tree img { + margin:0px; + padding:0px; + border:0px; + vertical-align: middle; +} + +#nav-tree a { + text-decoration:none; + padding:0px; + margin:0px; +} + +#nav-tree .label { + margin:0px; + padding:0px; + font: 12px var(--font-family-nav); +} + +#nav-tree .label a { + padding:2px; +} + +#nav-tree .selected a { + text-decoration:none; + color:var(--nav-text-active-color); +} + +#nav-tree .children_ul { + margin:0px; + padding:0px; +} + +#nav-tree .item { + margin:0px; + padding:0px; +} + +#nav-tree { + padding: 0px 0px; + font-size:14px; + overflow:auto; +} + +#doc-content { + overflow:auto; + display:block; + padding:0px; + margin:0px; + -webkit-overflow-scrolling : touch; /* iOS 5+ */ +} + +#side-nav { + padding:0 6px 0 0; + margin: 0px; + display:block; + position: absolute; + left: 0px; + width: $width; + overflow : hidden; +} + +.ui-resizable .ui-resizable-handle { + display:block; +} + +.ui-resizable-e { + background-image:var(--nav-splitbar-image); + background-size:100%; + background-repeat:repeat-y; + background-attachment: scroll; + cursor:ew-resize; + height:100%; + right:0; + top:0; + width:6px; +} + +.ui-resizable-handle { + display:none; + font-size:0.1px; + position:absolute; + z-index:1; +} + +#nav-tree-contents { + margin: 6px 0px 0px 0px; +} + +#nav-tree { + background-repeat:repeat-x; + background-color: var(--nav-background-color); + -webkit-overflow-scrolling : touch; /* iOS 5+ */ +} + +#nav-sync { + position:absolute; + top:5px; + right:24px; + z-index:0; +} + +#nav-sync img { + opacity:0.3; +} + +#nav-sync img:hover { + opacity:0.9; +} + +@media print +{ + #nav-tree { display: none; } + div.ui-resizable-handle { display: none; position: relative; } +} + diff --git a/doxygen/navtree.js b/doxygen/navtree.js new file mode 100644 index 0000000..93dd3d4 --- /dev/null +++ b/doxygen/navtree.js @@ -0,0 +1,559 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @licend The above is the entire license notice for the JavaScript code in this file + */ +var navTreeSubIndices = new Array(); +var arrowDown = '▼'; +var arrowRight = '►'; + +function getData(varName) +{ + var i = varName.lastIndexOf('/'); + var n = i>=0 ? varName.substring(i+1) : varName; + return eval(n.replace(/\-/g,'_')); +} + +function stripPath(uri) +{ + return uri.substring(uri.lastIndexOf('/')+1); +} + +function stripPath2(uri) +{ + var i = uri.lastIndexOf('/'); + var s = uri.substring(i+1); + var m = uri.substring(0,i+1).match(/\/d\w\/d\w\w\/$/); + return m ? uri.substring(i-6) : s; +} + +function hashValue() +{ + return $(location).attr('hash').substring(1).replace(/[^\w\-]/g,''); +} + +function hashUrl() +{ + return '#'+hashValue(); +} + +function pathName() +{ + return $(location).attr('pathname').replace(/[^-A-Za-z0-9+&@#/%?=~_|!:,.;\(\)]/g, ''); +} + +function localStorageSupported() +{ + try { + return 'localStorage' in window && window['localStorage'] !== null && window.localStorage.getItem; + } + catch(e) { + return false; + } +} + +function storeLink(link) +{ + if (!$("#nav-sync").hasClass('sync') && localStorageSupported()) { + window.localStorage.setItem('navpath',link); + } +} + +function deleteLink() +{ + if (localStorageSupported()) { + window.localStorage.setItem('navpath',''); + } +} + +function cachedLink() +{ + if (localStorageSupported()) { + return window.localStorage.getItem('navpath'); + } else { + return ''; + } +} + +function getScript(scriptName,func) +{ + var head = document.getElementsByTagName("head")[0]; + var script = document.createElement('script'); + script.id = scriptName; + script.type = 'text/javascript'; + script.onload = func; + script.src = scriptName+'.js'; + head.appendChild(script); +} + +function createIndent(o,domNode,node,level) +{ + var level=-1; + var n = node; + while (n.parentNode) { level++; n=n.parentNode; } + if (node.childrenData) { + var imgNode = document.createElement("span"); + imgNode.className = 'arrow'; + imgNode.style.paddingLeft=(16*level).toString()+'px'; + imgNode.innerHTML=arrowRight; + node.plus_img = imgNode; + node.expandToggle = document.createElement("a"); + node.expandToggle.href = "javascript:void(0)"; + node.expandToggle.onclick = function() { + if (node.expanded) { + $(node.getChildrenUL()).slideUp("fast"); + node.plus_img.innerHTML=arrowRight; + node.expanded = false; + } else { + expandNode(o, node, false, true); + } + } + node.expandToggle.appendChild(imgNode); + domNode.appendChild(node.expandToggle); + } else { + var span = document.createElement("span"); + span.className = 'arrow'; + span.style.width = 16*(level+1)+'px'; + span.innerHTML = ' '; + domNode.appendChild(span); + } +} + +var animationInProgress = false; + +function gotoAnchor(anchor,aname,updateLocation) +{ + var pos, docContent = $('#doc-content'); + var ancParent = $(anchor.parent()); + if (ancParent.hasClass('memItemLeft') || + ancParent.hasClass('memtitle') || + ancParent.hasClass('fieldname') || + ancParent.hasClass('fieldtype') || + ancParent.is(':header')) + { + pos = ancParent.position().top; + } else if (anchor.position()) { + pos = anchor.position().top; + } + if (pos) { + var dist = Math.abs(Math.min( + pos-docContent.offset().top, + docContent[0].scrollHeight- + docContent.height()-docContent.scrollTop())); + animationInProgress=true; + docContent.animate({ + scrollTop: pos + docContent.scrollTop() - docContent.offset().top + },Math.max(50,Math.min(500,dist)),function(){ + if (updateLocation) window.location.href=aname; + animationInProgress=false; + }); + } +} + +function newNode(o, po, text, link, childrenData, lastNode) +{ + var node = new Object(); + node.children = Array(); + node.childrenData = childrenData; + node.depth = po.depth + 1; + node.relpath = po.relpath; + node.isLast = lastNode; + + node.li = document.createElement("li"); + po.getChildrenUL().appendChild(node.li); + node.parentNode = po; + + node.itemDiv = document.createElement("div"); + node.itemDiv.className = "item"; + + node.labelSpan = document.createElement("span"); + node.labelSpan.className = "label"; + + createIndent(o,node.itemDiv,node,0); + node.itemDiv.appendChild(node.labelSpan); + node.li.appendChild(node.itemDiv); + + var a = document.createElement("a"); + node.labelSpan.appendChild(a); + node.label = document.createTextNode(text); + node.expanded = false; + a.appendChild(node.label); + if (link) { + var url; + if (link.substring(0,1)=='^') { + url = link.substring(1); + link = url; + } else { + url = node.relpath+link; + } + a.className = stripPath(link.replace('#',':')); + if (link.indexOf('#')!=-1) { + var aname = '#'+link.split('#')[1]; + var srcPage = stripPath(pathName()); + var targetPage = stripPath(link.split('#')[0]); + a.href = srcPage!=targetPage ? url : "javascript:void(0)"; + a.onclick = function(){ + storeLink(link); + if (!$(a).parent().parent().hasClass('selected')) + { + $('.item').removeClass('selected'); + $('.item').removeAttr('id'); + $(a).parent().parent().addClass('selected'); + $(a).parent().parent().attr('id','selected'); + } + var anchor = $(aname); + gotoAnchor(anchor,aname,true); + }; + } else { + a.href = url; + a.onclick = function() { storeLink(link); } + } + } else { + if (childrenData != null) + { + a.className = "nolink"; + a.href = "javascript:void(0)"; + a.onclick = node.expandToggle.onclick; + } + } + + node.childrenUL = null; + node.getChildrenUL = function() { + if (!node.childrenUL) { + node.childrenUL = document.createElement("ul"); + node.childrenUL.className = "children_ul"; + node.childrenUL.style.display = "none"; + node.li.appendChild(node.childrenUL); + } + return node.childrenUL; + }; + + return node; +} + +function showRoot() +{ + var headerHeight = $("#top").height(); + var footerHeight = $("#nav-path").height(); + var windowHeight = $(window).height() - headerHeight - footerHeight; + (function (){ // retry until we can scroll to the selected item + try { + var navtree=$('#nav-tree'); + navtree.scrollTo('#selected',100,{offset:-windowHeight/2}); + } catch (err) { + setTimeout(arguments.callee, 0); + } + })(); +} + +function expandNode(o, node, imm, setFocus) +{ + if (node.childrenData && !node.expanded) { + if (typeof(node.childrenData)==='string') { + var varName = node.childrenData; + getScript(node.relpath+varName,function(){ + node.childrenData = getData(varName); + expandNode(o, node, imm, setFocus); + }); + } else { + if (!node.childrenVisited) { + getNode(o, node); + } + $(node.getChildrenUL()).slideDown("fast"); + node.plus_img.innerHTML = arrowDown; + node.expanded = true; + if (setFocus) { + $(node.expandToggle).focus(); + } + } + } +} + +function glowEffect(n,duration) +{ + n.addClass('glow').delay(duration).queue(function(next){ + $(this).removeClass('glow');next(); + }); +} + +function highlightAnchor() +{ + var aname = hashUrl(); + var anchor = $(aname); + if (anchor.parent().attr('class')=='memItemLeft'){ + var rows = $('.memberdecls tr[class$="'+hashValue()+'"]'); + glowEffect(rows.children(),300); // member without details + } else if (anchor.parent().attr('class')=='fieldname'){ + glowEffect(anchor.parent().parent(),1000); // enum value + } else if (anchor.parent().attr('class')=='fieldtype'){ + glowEffect(anchor.parent().parent(),1000); // struct field + } else if (anchor.parent().is(":header")) { + glowEffect(anchor.parent(),1000); // section header + } else { + glowEffect(anchor.next(),1000); // normal member + } +} + +function selectAndHighlight(hash,n) +{ + var a; + if (hash) { + var link=stripPath(pathName())+':'+hash.substring(1); + a=$('.item a[class$="'+link+'"]'); + } + if (a && a.length) { + a.parent().parent().addClass('selected'); + a.parent().parent().attr('id','selected'); + highlightAnchor(); + } else if (n) { + $(n.itemDiv).addClass('selected'); + $(n.itemDiv).attr('id','selected'); + } + var topOffset=5; + if (typeof page_layout!=='undefined' && page_layout==1) { + topOffset+=$('#top').outerHeight(); + } + if ($('#nav-tree-contents .item:first').hasClass('selected')) { + topOffset+=25; + } + $('#nav-sync').css('top',topOffset+'px'); + showRoot(); +} + +function showNode(o, node, index, hash) +{ + if (node && node.childrenData) { + if (typeof(node.childrenData)==='string') { + var varName = node.childrenData; + getScript(node.relpath+varName,function(){ + node.childrenData = getData(varName); + showNode(o,node,index,hash); + }); + } else { + if (!node.childrenVisited) { + getNode(o, node); + } + $(node.getChildrenUL()).css({'display':'block'}); + node.plus_img.innerHTML = arrowDown; + node.expanded = true; + var n = node.children[o.breadcrumbs[index]]; + if (index+11) hash = '#'+parts[1].replace(/[^\w\-]/g,''); + else hash=''; + } + if (hash.match(/^#l\d+$/)) { + var anchor=$('a[name='+hash.substring(1)+']'); + glowEffect(anchor.parent(),1000); // line number + hash=''; // strip line number anchors + } + var url=root+hash; + var i=-1; + while (NAVTREEINDEX[i+1]<=url) i++; + if (i==-1) { i=0; root=NAVTREE[0][1]; } // fallback: show index + if (navTreeSubIndices[i]) { + gotoNode(o,i,root,hash,relpath) + } else { + getScript(relpath+'navtreeindex'+i,function(){ + navTreeSubIndices[i] = eval('NAVTREEINDEX'+i); + if (navTreeSubIndices[i]) { + gotoNode(o,i,root,hash,relpath); + } + }); + } +} + +function showSyncOff(n,relpath) +{ + n.html(''); +} + +function showSyncOn(n,relpath) +{ + n.html(''); +} + +function toggleSyncButton(relpath) +{ + var navSync = $('#nav-sync'); + if (navSync.hasClass('sync')) { + navSync.removeClass('sync'); + showSyncOff(navSync,relpath); + storeLink(stripPath2(pathName())+hashUrl()); + } else { + navSync.addClass('sync'); + showSyncOn(navSync,relpath); + deleteLink(); + } +} + +var loadTriggered = false; +var readyTriggered = false; +var loadObject,loadToRoot,loadUrl,loadRelPath; + +$(window).on('load',function(){ + if (readyTriggered) { // ready first + navTo(loadObject,loadToRoot,loadUrl,loadRelPath); + showRoot(); + } + loadTriggered=true; +}); + +function initNavTree(toroot,relpath) +{ + var o = new Object(); + o.toroot = toroot; + o.node = new Object(); + o.node.li = document.getElementById("nav-tree-contents"); + o.node.childrenData = NAVTREE; + o.node.children = new Array(); + o.node.childrenUL = document.createElement("ul"); + o.node.getChildrenUL = function() { return o.node.childrenUL; }; + o.node.li.appendChild(o.node.childrenUL); + o.node.depth = 0; + o.node.relpath = relpath; + o.node.expanded = false; + o.node.isLast = true; + o.node.plus_img = document.createElement("span"); + o.node.plus_img.className = 'arrow'; + o.node.plus_img.innerHTML = arrowRight; + + if (localStorageSupported()) { + var navSync = $('#nav-sync'); + if (cachedLink()) { + showSyncOff(navSync,relpath); + navSync.removeClass('sync'); + } else { + showSyncOn(navSync,relpath); + } + navSync.click(function(){ toggleSyncButton(relpath); }); + } + + if (loadTriggered) { // load before ready + navTo(o,toroot,hashUrl(),relpath); + showRoot(); + } else { // ready before load + loadObject = o; + loadToRoot = toroot; + loadUrl = hashUrl(); + loadRelPath = relpath; + readyTriggered=true; + } + + $(window).bind('hashchange', function(){ + if (window.location.hash && window.location.hash.length>1){ + var a; + if ($(location).attr('hash')){ + var clslink=stripPath(pathName())+':'+hashValue(); + a=$('.item a[class$="'+clslink.replace(/ + + + + + + +OMG-Fuscator: obfuscator.py File Reference + + + + + + + + + + + + + +
    +
    + + + + + + +
    +
    OMG-Fuscator +
    +
    Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
    +
    +
    + + + + + + + +
    +
    + +
    +
    +
    + +
    + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + +
    + +
    obfuscator.py File Reference
    +
    +
    + +

    Go to the source code of this file.

    + + + + +

    +Classes

    class  obfuscator.AdvancedObfuscator
     
    + + + +

    +Namespaces

    namespace  obfuscator
     
    +
    +
    + + + + diff --git a/doxygen/obfuscator_8py.js b/doxygen/obfuscator_8py.js new file mode 100644 index 0000000..fd40d79 --- /dev/null +++ b/doxygen/obfuscator_8py.js @@ -0,0 +1,4 @@ +var obfuscator_8py = +[ + [ "obfuscator.AdvancedObfuscator", "classobfuscator_1_1AdvancedObfuscator.html", "classobfuscator_1_1AdvancedObfuscator" ] +]; \ No newline at end of file diff --git a/doxygen/obfuscator_8py_source.html b/doxygen/obfuscator_8py_source.html new file mode 100644 index 0000000..58278b1 --- /dev/null +++ b/doxygen/obfuscator_8py_source.html @@ -0,0 +1,463 @@ + + + + + + + +OMG-Fuscator: obfuscator.py Source File + + + + + + + + + + + + + +
    +
    + + + + + + +
    +
    OMG-Fuscator +
    +
    Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
    +
    +
    + + + + + + + + +
    +
    + +
    +
    +
    + +
    + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + +
    +
    obfuscator.py
    +
    +
    +Go to the documentation of this file.
    1"""
    +
    2@file obfuscator.py
    +
    3@brief Core engine for OMG-Fuscator.
    +
    4@details Orchestrates the full obfuscation pipeline: symbol analysis and renaming,
    +
    5 string encryption, control-flow flattening, and junk code insertion.
    +
    6 Provides debug instrumentation and JSON reporting when enabled.
    +
    7"""
    +
    8
    +
    9import ast
    +
    10import random
    +
    11import json
    +
    12import os
    +
    13from datetime import datetime
    +
    14
    +
    15from transformers.rename import RenameTransformer
    +
    16from transformers.control_flow import ControlFlowFlattener
    +
    17from transformers.class_analyzer import ClassAnalyzer, update_obfuscator_with_class_mappings
    +
    18from transformers.attribute_transformer import AttributeTransformer
    +
    19from transformers.symbol_tree import SymbolTreeBuilder, SymbolTree
    +
    20from utils.name_gen import NameGenerator
    +
    21from utils.junk_gen import JunkGenerator
    +
    22from transformers.class_mapper import apply_class_mapping
    +
    23
    +
    24
    +
    + +
    26 """
    +
    27 @brief Core obfuscation engine orchestrating all transformations.
    +
    28 @details Coordinates name generation, symbol tree construction, AST transformations
    +
    29 for renaming and string encryption, control-flow flattening, and final
    +
    30 code generation with junk injection. Optionally records detailed debug data.
    +
    31 """
    +
    +
    32 def __init__(self, debug_mode=False):
    +
    33 self.used_names = set()
    + +
    35
    +
    36 # Generate keys for string encryption
    +
    37 self.primary_key = bytes([random.randint(65, 90) for _ in range(16)])
    +
    38 self.secondary_key = bytes([random.randint(65, 90) for _ in range(8)])
    +
    39 self.salt = bytes([random.randint(65, 90) for _ in range(4)])
    +
    40
    +
    41 # Symbol tree for global tracking of all symbols
    +
    42 self.symbol_tree = None
    +
    43
    +
    44 # Legacy mappings for backward compatibility
    + + +
    47
    +
    48 # Initialize junk generator
    + +
    50
    +
    51 # Debugging flags and data structures
    +
    52 self.debug_mode = debug_mode
    +
    53 self.debug_data = {
    +
    54 "timestamp": datetime.now().isoformat(),
    +
    55 "transformations": [],
    +
    56 "class_mappings": {},
    +
    57 "variable_mappings": {},
    +
    58 "method_mappings": {},
    +
    59 "string_encryption": [],
    +
    60 "issues_detected": [],
    +
    61 "control_flow_stats": {},
    +
    62 "junk_stats": {"count": 0, "snippets": []}
    +
    63 }
    +
    64
    +
    +
    +
    65 def log_debug(self, category, data):
    +
    66 """
    +
    67 @brief Append a structured debug entry if debug mode is enabled.
    +
    68 @param category Logical stage or component name.
    +
    69 @param data Arbitrary JSON-serializable payload to record.
    +
    70 """
    +
    71 if self.debug_mode:
    +
    72 self.debug_data["transformations"].append({
    +
    73 "stage": category,
    +
    74 "data": data,
    +
    75 "timestamp": datetime.now().isoformat()
    +
    76 })
    +
    77
    +
    +
    +
    78 def detect_issues(self):
    +
    79 """
    +
    80 @brief Run integrity checks and record any issues to debug data.
    +
    81 @details Aggregates issues from the symbol tree and legacy name-collision
    +
    82 checks to help diagnose transformation inconsistencies.
    +
    83 """
    +
    84 if not self.debug_mode:
    +
    85 return
    +
    86
    +
    87 # First check issues in the symbol tree
    +
    88 if self.symbol_tree:
    +
    89 symbol_tree_issues = self.symbol_tree.check_for_issues()
    +
    90 for issue in symbol_tree_issues:
    +
    91 self.debug_data["issues_detected"].append(issue)
    +
    92
    +
    93 # Legacy checks for backwards compatibility
    +
    94 used_renames = set()
    +
    95 duplicates = []
    +
    96
    +
    97 for orig, renamed in self.global_var_renames.items():
    +
    98 if renamed in used_renames:
    +
    99 duplicates.append(renamed)
    +
    100 used_renames.add(renamed)
    +
    101
    +
    102 # Check if our renamed values match any original names (could lead to conflicts)
    +
    103 if renamed in self.global_var_renames.keys():
    +
    104 self.debug_data["issues_detected"].append({
    +
    105 "type": "name_collision",
    +
    106 "info": f"Renamed value '{renamed}' matches an original name"
    +
    107 })
    +
    108
    +
    109 if duplicates:
    +
    110 self.debug_data["issues_detected"].append({
    +
    111 "type": "duplicate_names",
    +
    112 "names": duplicates
    +
    113 })
    +
    114
    +
    +
    +
    115 def _build_symbol_tree(self, tree: ast.AST) -> SymbolTree:
    +
    116 """
    +
    117 @brief Build a global symbol tree from the parsed AST.
    +
    118 @param tree Parsed AST of the input source.
    +
    119 @return SymbolTree Populated symbol tree with rename mappings and metadata.
    +
    120 """
    +
    121 if self.debug_mode:
    +
    122 self.log_debug("symbol_tree_building", "Building global symbol tree")
    +
    123
    +
    124 builder = SymbolTreeBuilder()
    +
    125 symbol_tree = builder.build_tree(tree)
    +
    126
    +
    127 # Apply name generator to all symbols
    +
    128 symbol_tree.apply_name_generator(self.name_generator)
    +
    129
    +
    130 # Populate legacy mappings for backward compatibility
    +
    131 rename_mapping = symbol_tree.get_rename_mapping()
    +
    132
    +
    133 # Update class and method mappings
    +
    134 for class_name, class_obf_name in rename_mapping["classes"].items():
    +
    135 self.global_var_renames[class_name] = class_obf_name
    +
    136
    +
    137 # Initialize class_attr_mapping entry
    +
    138 if class_obf_name not in self.class_attr_mapping:
    +
    139 self.class_attr_mapping[class_obf_name] = {}
    +
    140
    +
    141 # Copy method mappings
    +
    142 if class_name in rename_mapping["methods"]:
    +
    143 for method_name, method_obf_name in rename_mapping["methods"][class_name].items():
    +
    144 self.class_attr_mapping[class_obf_name][method_name] = method_obf_name
    +
    145
    +
    146 # Copy attribute mappings
    +
    147 if class_name in rename_mapping["attributes"]:
    +
    148 for attr_name, attr_obf_name in rename_mapping["attributes"][class_name].items():
    +
    149 self.class_attr_mapping[class_obf_name][attr_name] = attr_obf_name
    +
    150
    +
    151 # Update function and variable mappings
    +
    152 self.global_var_renames.update(rename_mapping["functions"])
    +
    153 self.global_var_renames.update(rename_mapping["variables"])
    +
    154
    +
    155 if self.debug_mode:
    +
    156 self.log_debug("symbol_tree_stats", {
    +
    157 "classes": len(rename_mapping["classes"]),
    +
    158 "methods": sum(len(methods) for methods in rename_mapping["methods"].values()),
    +
    159 "attributes": sum(len(attrs) for attrs in rename_mapping["attributes"].values()),
    +
    160 "functions": len(rename_mapping["functions"]),
    +
    161 "variables": len(rename_mapping["variables"])
    +
    162 })
    +
    163
    +
    164 return symbol_tree
    +
    165
    +
    +
    +
    166 def _rename_and_encrypt(self, tree: ast.AST) -> ast.AST:
    +
    167 """
    +
    168 @brief Rename identifiers and encrypt string literals in the AST.
    +
    169 @param tree Input AST prior to control-flow transformations.
    +
    170 @return ast.AST Transformed AST with consistent renames and encrypted strings.
    +
    171 """
    +
    172 # First, build a comprehensive symbol tree
    +
    173 self.symbol_tree = self._build_symbol_tree(tree)
    +
    174
    +
    175 # Now perform the main transformation with consistent mappings
    +
    176 transformer = RenameTransformer(
    +
    177 self.name_generator,
    +
    178 self.global_var_renames,
    + +
    180 self.primary_key,
    +
    181 self.secondary_key,
    +
    182 self.salt,
    +
    183 debug_mode=self.debug_mode
    +
    184 )
    +
    185
    +
    186 tree = transformer.visit(tree)
    +
    187
    +
    188 # Capture debug data from transformer if available
    +
    189 if self.debug_mode and hasattr(transformer, 'debug_data'):
    +
    190 self.debug_data["variable_mappings"] = transformer.debug_data.get("variable_mappings", {})
    +
    191 self.debug_data["string_encryption"] = transformer.debug_data.get("string_encryption", [])
    +
    192
    +
    193 ast.fix_missing_locations(tree)
    +
    194 return tree
    +
    195
    +
    +
    +
    196 def _flatten_control_flow(self, tree: ast.AST) -> ast.AST:
    +
    197 """
    +
    198 @brief Flatten control flow into a state-machine dispatch form.
    +
    199 @param tree AST after renaming/encryption.
    +
    200 @return ast.AST Transformed AST with flattened control flow.
    +
    201 """
    +
    202 flattener = ControlFlowFlattener(debug_mode=self.debug_mode)
    +
    203 tree = flattener.visit(tree)
    +
    204
    +
    205 # Capture debug data from flattener if available
    +
    206 if self.debug_mode and hasattr(flattener, 'debug_data'):
    +
    207 self.debug_data["control_flow_stats"] = flattener.debug_data
    +
    208
    +
    209 ast.fix_missing_locations(tree)
    +
    210 return tree
    +
    211
    +
    +
    +
    212 def _generate_final_code(self, tree: ast.AST) -> str:
    +
    213 """
    +
    214 @brief Generate final Python source from the AST and inject junk code.
    +
    215 @param tree AST after all transformations.
    +
    216 @return str Final obfuscated Python source code.
    +
    217 """
    +
    218 lines = ast.unparse(tree).split('\n')
    +
    219 in_multiline = False
    +
    220 skip_for_n = 0
    +
    221 junk_count = 0
    +
    222 junk_snippets = []
    +
    223
    +
    224 def in_try_block(ls, ci):
    +
    225 c_line = ls[ci]
    +
    226 c_strip = c_line.lstrip()
    +
    227 c_indent = len(c_line) - len(c_strip)
    +
    228 saw_try = False
    +
    229 for idx in range(ci - 1, -1, -1):
    +
    230 l = ls[idx]
    +
    231 s = l.lstrip()
    +
    232 i_amount = len(l) - len(s)
    +
    233 if s.startswith(("except ", "finally:")) and i_amount <= c_indent:
    +
    234 break
    +
    235 if s.startswith("try:") and i_amount <= c_indent:
    +
    236 saw_try = True
    +
    237 break
    +
    238 return saw_try
    +
    239
    +
    240 # We add these two lines at the top to ensure random is imported
    +
    241 result = ["import random"]
    +
    242
    +
    243 for i, line in enumerate(lines):
    +
    244 strip = line.lstrip()
    +
    245 if '"""' in strip or "'''" in strip:
    +
    246 in_multiline = not in_multiline
    +
    247
    +
    248 # Conditions to inject junk
    +
    249 can_inject = (
    +
    250 not in_multiline
    +
    251 and not in_try_block(lines, i)
    +
    252 and skip_for_n == 0
    +
    253 and not strip.startswith(
    +
    254 (
    +
    255 "def ", "class ", "@", "try:", "except ", "finally:",
    +
    256 "import ", "from ", "elif ", "else:", "return", "raise",
    +
    257 "pass", "break", "continue"
    +
    258 )
    +
    259 )
    +
    260 )
    +
    261 if can_inject:
    +
    262 junk = self.junk_gen.generate_junk()
    +
    263 result.append(junk)
    +
    264 junk_snippets.append(junk)
    +
    265 junk_count += 1
    +
    266 skip_for_n = random.randint(5, 15)
    +
    267 else:
    +
    268 skip_for_n = max(0, skip_for_n - 1)
    +
    269
    +
    270 result.append(line)
    +
    271
    +
    272 if self.debug_mode:
    +
    273 self.debug_data["junk_stats"]["count"] = junk_count
    +
    274 self.debug_data["junk_stats"]["snippets"] = junk_snippets
    +
    275
    +
    276 return '\n'.join(result)
    +
    277
    +
    +
    +
    278 def obfuscate(self, code: str) -> str:
    +
    279 """
    +
    280 @brief End-to-end obfuscation entry point.
    +
    281 @param code Original Python source code.
    +
    282 @return str Obfuscated Python source code.
    +
    283 """
    +
    284 tree = ast.parse(code)
    +
    285
    +
    286 # Step 1: Rename and encrypt
    +
    287 tree = self._rename_and_encrypt(tree)
    +
    288
    +
    289 # Step 2: Flatten control flow
    +
    290 tree = self._flatten_control_flow(tree)
    +
    291
    +
    292 # Step 3: Generate final obfuscated code
    +
    293 final_code = self._generate_final_code(tree)
    +
    294
    +
    295 if self.debug_mode:
    +
    296 debug_output_path = os.path.join("debug", f"debug_{self.debug_data['timestamp']}.json")
    +
    297 os.makedirs(os.path.dirname(debug_output_path), exist_ok=True)
    +
    298 with open(debug_output_path, "w") as debug_file:
    +
    299 json.dump(self.debug_data, debug_file, indent=4)
    +
    300
    +
    301 return final_code
    +
    +
    + +
    str obfuscate(self, str code)
    + +
    SymbolTree _build_symbol_tree(self, ast.AST tree)
    + + + + + + + + +
    ast.AST _flatten_control_flow(self, ast.AST tree)
    +
    __init__(self, debug_mode=False)
    Definition obfuscator.py:32
    + +
    ast.AST _rename_and_encrypt(self, ast.AST tree)
    +
    str _generate_final_code(self, ast.AST tree)
    +
    log_debug(self, category, data)
    Definition obfuscator.py:65
    + + + + + + + + + + + + + + + +
    +
    + + + + diff --git a/doxygen/open.png b/doxygen/open.png new file mode 100644 index 0000000000000000000000000000000000000000..30f75c7efe2dd0c9e956e35b69777a02751f048b GIT binary patch literal 123 zcmeAS@N?(olHy`uVBq!ia0vp^oFL4>1|%O$WD@{VPM$7~Ar*{o?;hlAFyLXmaDC0y znK1_#cQqJWPES%4Uujug^TE?jMft$}Eq^WaR~)%f)vSNs&gek&x%A9X9sM + + + + + + + + diff --git a/doxygen/plusd.svg b/doxygen/plusd.svg new file mode 100644 index 0000000..0c65bfe --- /dev/null +++ b/doxygen/plusd.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/doxygen/rename_8py.html b/doxygen/rename_8py.html new file mode 100644 index 0000000..2a0dac3 --- /dev/null +++ b/doxygen/rename_8py.html @@ -0,0 +1,132 @@ + + + + + + + +OMG-Fuscator: rename.py File Reference + + + + + + + + + + + + + +
    +
    + + + + + + +
    +
    OMG-Fuscator +
    +
    Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
    +
    +
    + + + + + + + +
    +
    + +
    +
    +
    + +
    + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + +
    + +
    rename.py File Reference
    +
    +
    + +

    Go to the source code of this file.

    + + + + +

    +Classes

    class  transformers.rename.RenameTransformer
     
    + + + + + +

    +Namespaces

    namespace  transformers
     
    namespace  transformers.rename
     
    + + + + + +

    +Variables

     transformers.rename.level
     
     transformers.rename.logger = logging.getLogger("RenameTransformer")
     
    +
    +
    + + + + diff --git a/doxygen/rename_8py.js b/doxygen/rename_8py.js new file mode 100644 index 0000000..bff85e9 --- /dev/null +++ b/doxygen/rename_8py.js @@ -0,0 +1,6 @@ +var rename_8py = +[ + [ "transformers.rename.RenameTransformer", "classtransformers_1_1rename_1_1RenameTransformer.html", "classtransformers_1_1rename_1_1RenameTransformer" ], + [ "level", "rename_8py.html#a2cbae0d4878e456bd1322692636887a3", null ], + [ "logger", "rename_8py.html#a8d3edc6223d05ff25d552b11ceca5aa7", null ] +]; \ No newline at end of file diff --git a/doxygen/rename_8py_source.html b/doxygen/rename_8py_source.html new file mode 100644 index 0000000..93049a9 --- /dev/null +++ b/doxygen/rename_8py_source.html @@ -0,0 +1,627 @@ + + + + + + + +OMG-Fuscator: rename.py Source File + + + + + + + + + + + + + +
    +
    + + + + + + +
    +
    OMG-Fuscator +
    +
    Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
    +
    +
    + + + + + + + + +
    +
    + +
    +
    +
    + +
    + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + +
    +
    rename.py
    +
    +
    +Go to the documentation of this file.
    1"""
    +
    2@file transformers/rename.py
    +
    3@brief Identifier renaming and string literal encryption transformer.
    +
    4@details Performs scoped variable/function renaming, consistent class/method/attribute
    +
    5 remapping, and in-place string encryption producing runtime decryption code.
    +
    6"""
    +
    7
    +
    8import ast
    +
    9from utils.encryption import StringEncryptor
    +
    10from utils.name_gen import NameGenerator
    +
    11import logging
    +
    12
    +
    13# Configure logging
    +
    14logging.basicConfig(level=logging.INFO)
    +
    15logger = logging.getLogger("RenameTransformer")
    +
    16
    +
    +
    17class RenameTransformer(ast.NodeTransformer):
    +
    18 """
    +
    19 @brief AST transformer for renaming and string encryption.
    +
    20 @details Maintains scope stacks, global mappings, class method/attribute maps, and
    +
    21 collects key-setup code for runtime decryption. Can emit debug telemetry.
    +
    22 """
    +
    +
    23 def __init__(self, name_generator, global_var_renames, class_attr_mapping,
    +
    24 primary_key, secondary_key, salt, debug_mode=False):
    +
    25 self.name_generator = name_generator
    +
    26 self.global_var_renames = global_var_renames
    +
    27 self.class_attr_mapping = class_attr_mapping
    +
    28
    +
    29 # String encryption
    +
    30 self.encryptor = StringEncryptor(primary_key, secondary_key, salt)
    +
    31
    +
    32 # We'll collect any code needed for key setup (from encrypt_string calls).
    + +
    34
    +
    35 # Each element is a dict that maps old_name -> new_name for the local scope
    +
    36 self.scope_stack = [{}]
    +
    37
    +
    38 # For class/attribute rename support
    +
    39 self.in_class = False
    + +
    41 # Add this to track methods in each class
    + +
    43 # Add a first-pass flag to help with method detection
    +
    44 self.first_pass = True
    +
    45
    +
    46 # Debug data if debug mode is enabled
    +
    47 self.debug_mode = debug_mode
    +
    48 if self.debug_mode:
    +
    49 self.debug_data = {
    +
    50 "variable_mappings": {},
    +
    51 "string_encryption": [],
    +
    52 "renamed_nodes": 0,
    +
    53 "issues": []
    +
    54 }
    +
    55
    +
    +
    +
    56 def log_debug(self, category: str, data: any):
    +
    57 """Log debugging information if debug mode is on."""
    +
    58 if self.debug_mode:
    +
    59 if category not in self.debug_data:
    +
    60 self.debug_data[category] = []
    +
    61 self.debug_data[category].append(data)
    +
    62
    +
    +
    +
    63 def visit_Module(self, node: ast.Module) -> ast.Module:
    +
    64 """
    +
    65 Enhanced module visitor to properly handle global variables
    +
    66 AND top-level function definitions for consistent renaming.
    +
    67
    +
    68 Now includes a two-pass strategy for classes to ensure method consistency.
    +
    69 """
    +
    70 # First pass: detect methods in classes
    +
    71 if self.first_pass:
    +
    72 self.first_pass = False
    +
    73 # First scan all classes and methods recursively
    +
    74 for stmt in ast.walk(node):
    +
    75 if isinstance(stmt, ast.ClassDef):
    +
    76 self.scan_class_methods(stmt)
    +
    77
    +
    78 # Rest of the code remains the same...
    +
    79 # First pass: detect top-level assignments, globals, AND function definitions
    +
    80 for stmt in node.body:
    +
    81 # 1. If a global statement
    +
    82 if isinstance(stmt, ast.Global):
    +
    83 for name in stmt.names:
    +
    84 if name not in self.global_var_renames:
    +
    85 self.global_var_renames[name] = self.name_generator.generate_name()
    +
    86
    +
    87 # 2. If a top-level assignment
    +
    88 elif isinstance(stmt, ast.Assign):
    +
    89 for target in stmt.targets:
    +
    90 if isinstance(target, ast.Name):
    +
    91 if target.id not in self.global_var_renames:
    +
    92 self.global_var_renames[target.id] = self.name_generator.generate_name()
    +
    93
    +
    94 # 3. If a top-level function definition
    +
    95 elif isinstance(stmt, ast.FunctionDef):
    +
    96 # Skip special (dunder) methods to avoid messing up e.g. __init__
    +
    97 if not (stmt.name.startswith('__') and stmt.name.endswith('__')):
    +
    98 if stmt.name not in self.global_var_renames:
    +
    99 self.global_var_renames[stmt.name] = self.name_generator.generate_name()
    +
    100
    +
    101 # Create a new body that starts with any needed imports
    +
    102 new_body = [
    +
    103 ast.parse("import base64").body[0],
    +
    104 ast.parse("import random").body[0]
    +
    105 ]
    +
    106
    +
    107 # Transform the module body
    +
    108 transformed_body = []
    +
    109 for item in node.body:
    +
    110 visited = self.visit(item)
    +
    111 if isinstance(visited, list):
    +
    112 transformed_body.extend(visited)
    +
    113 else:
    +
    114 transformed_body.append(visited)
    +
    115
    +
    116 # If there's any key setup code, parse & insert that
    +
    117 if self.key_setup_code:
    +
    118 setup_nodes = ast.parse('\n'.join(self.key_setup_code)).body
    +
    119 new_body.extend(setup_nodes)
    +
    120
    +
    121 new_body.extend(transformed_body)
    +
    122 node.body = new_body
    +
    123 return node
    +
    124
    +
    +
    +
    125 def scan_class_methods(self, node):
    +
    126 """
    +
    127 Pre-scan a class to identify and map all its methods before actual renaming.
    +
    128 """
    +
    129 class_name = node.name
    +
    130 # Create a mapping entry for this class if not exists
    +
    131 if class_name not in self.class_method_mapping:
    +
    132 self.class_method_mapping[class_name] = {}
    +
    133
    +
    134 # Scan all method definitions in the class
    +
    135 for item in node.body:
    +
    136 if isinstance(item, ast.FunctionDef):
    +
    137 method_name = item.name
    +
    138 # Skip dunder methods
    +
    139 if not (method_name.startswith('__') and method_name.endswith('__')):
    +
    140 # Generate a consistent obfuscated name for this method
    +
    141 new_name = self.name_generator.generate_name()
    +
    142 self.class_method_mapping[class_name][method_name] = new_name
    +
    143
    +
    +
    +
    144 def _push_scope(self):
    +
    145 self.scope_stack.append({})
    +
    146
    +
    +
    +
    147 def _pop_scope(self):
    +
    148 self.scope_stack.pop()
    +
    149
    +
    +
    +
    150 def visit_Global(self, node: ast.Global) -> ast.Global:
    +
    151 """
    +
    152 Handle global statement declarations by:
    +
    153 1. Adding the variable names to global_var_renames if not already there
    +
    154 2. Adding them to the current scope to mark them as global
    +
    155 """
    +
    156 for name in node.names:
    +
    157 # If this global name hasn't been seen before, generate a new obfuscated name
    +
    158 if name not in self.global_var_renames:
    +
    159 self.global_var_renames[name] = self.name_generator.generate_name()
    +
    160
    +
    161 # Mark this name as global in the current scope
    +
    162 self.scope_stack[-1][name] = self.global_var_renames[name]
    +
    163
    +
    164 # Update the global statement with obfuscated names
    +
    165 node.names = [self.global_var_renames[name] for name in node.names]
    +
    166 return node
    +
    167
    +
    +
    +
    168 def visit_ListComp(self, node: ast.ListComp) -> ast.ListComp:
    +
    169 self._push_scope()
    +
    170 for gen in node.generators:
    +
    171 gen = self.visit(gen)
    +
    172 node.elt = self.visit(node.elt)
    +
    173 self._pop_scope()
    +
    174 return node
    +
    175
    +
    +
    +
    176 def visit_SetComp(self, node: ast.SetComp) -> ast.SetComp:
    +
    177 self._push_scope()
    +
    178 for gen in node.generators:
    +
    179 gen = self.visit(gen)
    +
    180 node.elt = self.visit(node.elt)
    +
    181 self._pop_scope()
    +
    182 return node
    +
    183
    +
    +
    +
    184 def visit_DictComp(self, node: ast.DictComp) -> ast.DictComp:
    +
    185 self._push_scope()
    +
    186 for gen in node.generators:
    +
    187 gen = self.visit(gen)
    +
    188 node.key = self.visit(node.key)
    +
    189 node.value = self.visit(node.value)
    +
    190 self._pop_scope()
    +
    191 return node
    +
    192
    +
    +
    +
    193 def visit_GeneratorExp(self, node: ast.GeneratorExp) -> ast.GeneratorExp:
    +
    194 self._push_scope()
    +
    195 for gen in node.generators:
    +
    196 gen = self.visit(gen)
    +
    197 node.elt = self.visit(node.elt)
    +
    198 self._pop_scope()
    +
    199 return node
    +
    200
    +
    +
    +
    201 def visit_comprehension(self, node: ast.comprehension) -> ast.comprehension:
    +
    202 if isinstance(node.target, ast.Name):
    +
    203 if node.target.id not in self.global_var_renames:
    +
    204 new_name = self.name_generator.generate_name()
    +
    205 self.scope_stack[-1][node.target.id] = new_name
    +
    206 node.target.id = new_name
    +
    207 else:
    +
    208 node.target = self.visit(node.target)
    +
    209
    +
    210 node.iter = self.visit(node.iter)
    +
    211 node.ifs = [self.visit(i) for i in node.ifs]
    +
    212 return node
    +
    213
    +
    +
    +
    214 def visit_Name(self, node: ast.Name) -> ast.AST:
    +
    215 """
    +
    216 Handle variable names and function names in calls.
    +
    217 1. If it's a known global/ top-level function, use global_var_renames.
    +
    218 2. Otherwise, handle locally within scope_stack.
    +
    219 """
    +
    220 if node.id in self.global_var_renames:
    +
    221 node.id = self.global_var_renames[node.id]
    +
    222 return node
    +
    223
    +
    224 # Check if this name is marked as global in any scope
    +
    225 for scope in self.scope_stack:
    +
    226 if node.id in scope and node.id in self.global_var_renames:
    +
    227 node.id = self.global_var_renames[node.id]
    +
    228 return node
    +
    229
    +
    230 # Otherwise, handle local variables
    +
    231 if isinstance(node.ctx, ast.Store):
    +
    232 if self.in_class and not isinstance(node.ctx, ast.Param):
    +
    233 # Class attribute
    +
    234 if node.id not in self.scope_stack[-1]:
    +
    235 new_name = self.name_generator.generate_name()
    +
    236 self.scope_stack[-1][node.id] = new_name
    +
    237 if self.current_class_name:
    +
    238 self.class_attr_mapping[self.current_class_name][node.id] = new_name
    +
    239 node.id = self.scope_stack[-1][node.id]
    +
    240 else:
    +
    241 # Regular variable assignment
    +
    242 if node.id not in self.scope_stack[-1]:
    +
    243 self.scope_stack[-1][node.id] = self.name_generator.generate_name()
    +
    244 node.id = self.scope_stack[-1][node.id]
    +
    245 else:
    +
    246 # Load context
    +
    247 for scope in reversed(self.scope_stack):
    +
    248 if node.id in scope:
    +
    249 node.id = scope[node.id]
    +
    250 break
    +
    251
    +
    252 return node
    +
    253
    +
    +
    +
    254 def visit_ClassDef(self, node: ast.ClassDef) -> ast.ClassDef:
    +
    255 has_bases = len(node.bases) > 0
    +
    256 self.scope_stack[-1]['_has_bases'] = has_bases
    +
    257 prev_in_class = self.in_class
    +
    258 prev_class_name = self.current_class_name
    +
    259
    +
    260 self.in_class = True
    +
    261 new_class_name = self.name_generator.generate_name()
    +
    262 self.scope_stack[-1][node.name] = new_class_name
    +
    263 self.current_class_name = new_class_name
    +
    264 self.class_attr_mapping[new_class_name] = {}
    +
    265
    +
    266 # Transfer method mappings from the original class name to the renamed one
    +
    267 if node.name in self.class_method_mapping:
    +
    268 self.class_method_mapping[new_class_name] = self.class_method_mapping[node.name]
    +
    269 del self.class_method_mapping[node.name]
    +
    270
    +
    271 self.scope_stack.append({})
    +
    272 node.bases = [self.visit(base) for base in node.bases]
    +
    273 node.body = [self.visit(b) for b in node.body]
    +
    274
    +
    275 self.scope_stack[-2][node.name] = new_class_name
    +
    276 node.name = new_class_name
    +
    277
    +
    278 self.in_class = prev_in_class
    +
    279 self.current_class_name = prev_class_name
    +
    280 self.scope_stack.pop()
    +
    281 return node
    +
    282
    +
    +
    +
    283 def visit_FunctionDef(self, node: ast.FunctionDef) -> ast.FunctionDef:
    +
    284 """
    +
    285 Make sure top-level function definitions also get renamed
    +
    286 if they're in global_var_renames.
    +
    287 """
    +
    288 is_special = node.name.startswith('__') and node.name.endswith('__')
    +
    289 has_bases = any(('_has_bases' in scope and scope['_has_bases']) for scope in self.scope_stack)
    +
    290
    +
    291 # Save original name for later
    +
    292 orig_name = node.name
    +
    293
    +
    294 self._push_scope()
    +
    295
    +
    296 # Handle arguments (skip renaming for self if method):
    +
    297 if self.in_class and len(node.args.args) > 0:
    +
    298 self.scope_stack[-1][node.args.args[0].arg] = node.args.args[0].arg
    +
    299 for arg in node.args.args[1:]:
    +
    300 if arg.arg not in self.global_var_renames:
    +
    301 new_arg_name = self.name_generator.generate_name()
    +
    302 self.scope_stack[-1][arg.arg] = new_arg_name
    +
    303 arg.arg = new_arg_name
    +
    304 else:
    +
    305 for arg in node.args.args:
    +
    306 if arg.arg not in self.global_var_renames:
    +
    307 new_arg_name = self.name_generator.generate_name()
    +
    308 self.scope_stack[-1][arg.arg] = new_arg_name
    +
    309 arg.arg = new_arg_name
    +
    310
    +
    311 # Visit body
    +
    312 node.body = [self.visit(n) for n in node.body]
    +
    313
    +
    314 # --------------------------------
    +
    315 # NEW LOGIC: Actually rename the func if it's top-level
    +
    316 # or if we want to rename it anyway (and not dunder).
    +
    317 # --------------------------------
    +
    318 if not is_special:
    +
    319 # If the function was declared top-level and recognized in global_var_renames,
    +
    320 # then rename using that. Otherwise generate a brand new obfuscated name.
    +
    321 if node.name in self.global_var_renames:
    +
    322 node.name = self.global_var_renames[node.name]
    +
    323 elif self.in_class and not has_bases:
    +
    324 # For class methods, use the name we saved earlier
    +
    325 if self.current_class_name and orig_name in self.class_method_mapping.get(self.current_class_name, {}):
    +
    326 node.name = self.class_method_mapping[self.current_class_name][orig_name]
    +
    327 else:
    +
    328 new_fn_name = self.name_generator.generate_name()
    +
    329 self.scope_stack[-2][node.name] = new_fn_name
    +
    330 node.name = new_fn_name
    +
    331
    +
    332 self._pop_scope()
    +
    333 return node
    +
    334
    +
    +
    +
    335 def visit_Attribute(self, node: ast.Attribute) -> ast.AST:
    +
    336 """
    +
    337 Handle attribute access for renaming:
    +
    338 1. Map method calls on self to the corresponding renamed methods
    +
    339 2. Preserve external/inherited method names
    +
    340 3. Rename self.attribute for class-defined attributes
    +
    341 """
    +
    342 # First visit any nested expressions
    +
    343 node = self.generic_visit(node)
    +
    344
    +
    345 # Check if this is a self.something attribute access
    +
    346 if isinstance(node.value, ast.Name) and node.value.id == 'self':
    +
    347 # Check all class methods across all classes (more robust)
    +
    348 for class_name, methods in self.class_method_mapping.items():
    +
    349 if node.attr in methods:
    +
    350 # We found a match in our method mapping
    +
    351 node.attr = methods[node.attr]
    +
    352 return node
    +
    353
    +
    354 # If we're in a class context, apply class-specific logic
    +
    355 if self.current_class_name:
    +
    356 # Case 1: Is it a call to one of our renamed methods?
    +
    357 class_methods = self.class_method_mapping.get(self.current_class_name, {})
    +
    358 if node.attr in class_methods:
    +
    359 node.attr = class_methods[node.attr]
    +
    360 return node
    +
    361
    +
    362 # Case 2: Is it an external method call with Qt-style naming?
    +
    363 is_external_method = (
    +
    364 node.attr[0].islower() and
    +
    365 any(c.isupper() for c in node.attr) and
    +
    366 not node.attr.startswith('__')
    +
    367 )
    +
    368 if is_external_method:
    +
    369 return node
    +
    370
    +
    371 # Case 3: Handle normal class attributes
    +
    372 attr_map = self.class_attr_mapping.get(self.current_class_name, {})
    +
    373 if node.attr not in attr_map:
    +
    374 attr_map[node.attr] = self.name_generator.generate_name()
    +
    375 node.attr = attr_map[node.attr]
    +
    376
    +
    377 return node
    +
    378
    +
    +
    +
    379 def visit_Subscript(self, node: ast.Subscript) -> ast.AST:
    +
    380 node.value = self.visit(node.value)
    +
    381 if isinstance(node.slice, ast.AST):
    +
    382 self.visit(node.slice)
    +
    383 return node
    +
    384
    +
    +
    +
    385 def visit_Constant(self, node: ast.Constant) -> ast.AST:
    +
    386 """
    +
    387 Encrypt string literals into a multi-step XOR, then base85 decode at runtime.
    +
    388 """
    +
    389 if isinstance(node.value, str):
    +
    390 encoded, key_setup, modifier = self.encryptor.encrypt_string(node.value)
    +
    391 if key_setup not in self.key_setup_code:
    +
    392 self.key_setup_code.append(key_setup)
    +
    393
    +
    394 decrypt_str = (
    +
    395 f"bytes(("
    +
    396 f"k2^k1^m for k1,k2,m in zip("
    +
    397 f"bytes(c^k for c,k in zip(base64.b85decode('{encoded}'),"
    +
    398 f"_sk*((len(base64.b85decode('{encoded}'))//8)+1))),"
    +
    399 f"_pk*((len(base64.b85decode('{encoded}'))//8)+1),"
    +
    400 f"bytes.fromhex('{modifier}')*((len(base64.b85decode('{encoded}'))//8)+1)))"
    +
    401 f").decode()"
    +
    402 )
    +
    403 return ast.parse(decrypt_str).body[0].value
    +
    404
    +
    405 return node
    +
    406
    +
    +
    +
    407 def visit_Import(self, node: ast.Import) -> ast.AST:
    +
    408 return self.generic_visit(node)
    +
    409
    +
    +
    +
    410 def visit_ImportFrom(self, node: ast.ImportFrom) -> ast.AST:
    +
    411 return self.generic_visit(node)
    +
    412
    +
    +
    +
    413 def visit_Call(self, node: ast.Call) -> ast.Call:
    +
    414 """
    +
    415 Handle super() calls specifically to ensure class names are properly updated.
    +
    416 """
    +
    417 # First visit all arguments and the function itself
    +
    418 node = self.generic_visit(node)
    +
    419
    +
    420 # Check if this is a super() call
    +
    421 if isinstance(node.func, ast.Name) and node.func.id == 'super':
    +
    422 # For super() with no args in Python 3
    +
    423 if not node.args:
    +
    424 return node
    +
    425
    +
    426 # For super(Class, self) style calls
    +
    427 if len(node.args) >= 1 and isinstance(node.args[0], ast.Name):
    +
    428 class_name = node.args[0].id
    +
    429 # Look for the renamed class in all scopes
    +
    430 for scope in reversed(self.scope_stack):
    +
    431 if class_name in scope:
    +
    432 node.args[0].id = scope[class_name]
    +
    433 break
    +
    434
    +
    435 return node
    +
    +
    + + +
    ast.comprehension visit_comprehension(self, ast.comprehension node)
    Definition rename.py:201
    +
    log_debug(self, str category, any data)
    Definition rename.py:56
    + +
    ast.DictComp visit_DictComp(self, ast.DictComp node)
    Definition rename.py:184
    + +
    ast.SetComp visit_SetComp(self, ast.SetComp node)
    Definition rename.py:176
    + +
    __init__(self, name_generator, global_var_renames, class_attr_mapping, primary_key, secondary_key, salt, debug_mode=False)
    Definition rename.py:24
    + +
    ast.FunctionDef visit_FunctionDef(self, ast.FunctionDef node)
    Definition rename.py:283
    + +
    ast.ListComp visit_ListComp(self, ast.ListComp node)
    Definition rename.py:168
    +
    ast.Call visit_Call(self, ast.Call node)
    Definition rename.py:413
    +
    ast.AST visit_Name(self, ast.Name node)
    Definition rename.py:214
    +
    ast.GeneratorExp visit_GeneratorExp(self, ast.GeneratorExp node)
    Definition rename.py:193
    +
    ast.AST visit_Attribute(self, ast.Attribute node)
    Definition rename.py:335
    + +
    ast.AST visit_Import(self, ast.Import node)
    Definition rename.py:407
    +
    ast.ClassDef visit_ClassDef(self, ast.ClassDef node)
    Definition rename.py:254
    + +
    ast.AST visit_Subscript(self, ast.Subscript node)
    Definition rename.py:379
    + + + + + +
    ast.AST visit_Constant(self, ast.Constant node)
    Definition rename.py:385
    +
    ast.Global visit_Global(self, ast.Global node)
    Definition rename.py:150
    +
    ast.AST visit_ImportFrom(self, ast.ImportFrom node)
    Definition rename.py:410
    + +
    ast.Module visit_Module(self, ast.Module node)
    Definition rename.py:63
    + + + + +
    +
    + + + + diff --git a/doxygen/resize.js b/doxygen/resize.js new file mode 100644 index 0000000..aaeb6fc --- /dev/null +++ b/doxygen/resize.js @@ -0,0 +1,155 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @licend The above is the entire license notice for the JavaScript code in this file + */ +var once=1; +function initResizable() +{ + var cookie_namespace = 'doxygen'; + var sidenav,navtree,content,header,barWidth=6,desktop_vp=768,titleHeight; + + function readSetting(cookie) + { + if (window.chrome) { + var val = localStorage.getItem(cookie_namespace+'_width'); + if (val) return val; + } else { + var myCookie = cookie_namespace+"_"+cookie+"="; + if (document.cookie) { + var index = document.cookie.indexOf(myCookie); + if (index != -1) { + var valStart = index + myCookie.length; + var valEnd = document.cookie.indexOf(";", valStart); + if (valEnd == -1) { + valEnd = document.cookie.length; + } + var val = document.cookie.substring(valStart, valEnd); + return val; + } + } + } + return 250; + } + + function writeSetting(cookie, val) + { + if (window.chrome) { + localStorage.setItem(cookie_namespace+"_width",val); + } else { + var date = new Date(); + date.setTime(date.getTime()+(10*365*24*60*60*1000)); // default expiration is one week + expiration = date.toGMTString(); + document.cookie = cookie_namespace + "_" + cookie + "=" + val + "; SameSite=Lax; expires=" + expiration+"; path=/"; + } + } + + function resizeWidth() + { + var windowWidth = $(window).width() + "px"; + var sidenavWidth = $(sidenav).outerWidth(); + content.css({marginLeft:parseInt(sidenavWidth)+"px"}); + if (typeof page_layout!=='undefined' && page_layout==1) { + footer.css({marginLeft:parseInt(sidenavWidth)+"px"}); + } + writeSetting('width',sidenavWidth-barWidth); + } + + function restoreWidth(navWidth) + { + var windowWidth = $(window).width() + "px"; + content.css({marginLeft:parseInt(navWidth)+barWidth+"px"}); + if (typeof page_layout!=='undefined' && page_layout==1) { + footer.css({marginLeft:parseInt(navWidth)+barWidth+"px"}); + } + sidenav.css({width:navWidth + "px"}); + } + + function resizeHeight() + { + var headerHeight = header.outerHeight(); + var footerHeight = footer.outerHeight(); + var windowHeight = $(window).height(); + var contentHeight,navtreeHeight,sideNavHeight; + if (typeof page_layout==='undefined' || page_layout==0) { /* DISABLE_INDEX=NO */ + contentHeight = windowHeight - headerHeight - footerHeight; + navtreeHeight = contentHeight; + sideNavHeight = contentHeight; + } else if (page_layout==1) { /* DISABLE_INDEX=YES */ + contentHeight = windowHeight - footerHeight; + navtreeHeight = windowHeight - headerHeight; + sideNavHeight = windowHeight; + } + content.css({height:contentHeight + "px"}); + navtree.css({height:navtreeHeight + "px"}); + sidenav.css({height:sideNavHeight + "px"}); + if (location.hash.slice(1)) { + (document.getElementById(location.hash.slice(1))||document.body).scrollIntoView(); + } + } + + function collapseExpand() + { + var newWidth; + if (sidenav.width()>0) { + newWidth=0; + } + else { + var width = readSetting('width'); + newWidth = (width>250 && width<$(window).width()) ? width : 250; + } + restoreWidth(newWidth); + var sidenavWidth = $(sidenav).outerWidth(); + writeSetting('width',sidenavWidth-barWidth); + } + + header = $("#top"); + sidenav = $("#side-nav"); + content = $("#doc-content"); + navtree = $("#nav-tree"); + footer = $("#nav-path"); + $(".side-nav-resizable").resizable({resize: function(e, ui) { resizeWidth(); } }); + $(sidenav).resizable({ minWidth: 0 }); + $(window).resize(function() { resizeHeight(); }); + var device = navigator.userAgent.toLowerCase(); + var touch_device = device.match(/(iphone|ipod|ipad|android)/); + if (touch_device) { /* wider split bar for touch only devices */ + $(sidenav).css({ paddingRight:'20px' }); + $('.ui-resizable-e').css({ width:'20px' }); + $('#nav-sync').css({ right:'34px' }); + barWidth=20; + } + var width = readSetting('width'); + if (width) { restoreWidth(width); } else { resizeWidth(); } + resizeHeight(); + var url = location.href; + var i=url.indexOf("#"); + if (i>=0) window.location.hash=url.substr(i); + var _preventDefault = function(evt) { evt.preventDefault(); }; + $("#splitbar").bind("dragstart", _preventDefault).bind("selectstart", _preventDefault); + if (once) { + $(".ui-resizable-handle").dblclick(collapseExpand); + once=0 + } + $(window).on('load',resizeHeight); +} +/* @license-end */ diff --git a/doxygen/search/all_0.js b/doxygen/search/all_0.js new file mode 100644 index 0000000..1ddd644 --- /dev/null +++ b/doxygen/search/all_0.js @@ -0,0 +1,16 @@ +var searchData= +[ + ['_5f_5finit_5f_5f_0',['__init__',['../classtransformers_1_1attribute__transformer_1_1AttributeTransformer.html#a8bc2a45cb2e19075483d7b5b9c98ed50',1,'transformers.attribute_transformer.AttributeTransformer.__init__()'],['../classutils_1_1name__gen_1_1NameGenerator.html#aff640e7a1a975e664ca4fe3a54ec2cfb',1,'utils.name_gen.NameGenerator.__init__()'],['../classutils_1_1junk__gen_1_1JunkGenerator.html#ad1c240cacad785c775dfeddc9eea76b5',1,'utils.junk_gen.JunkGenerator.__init__()'],['../classutils_1_1encryption_1_1StringEncryptor.html#aeeab3fb282428a253a857668c8ad7545',1,'utils.encryption.StringEncryptor.__init__()'],['../classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#adb9a525c0003b90a619179e8c9d42f4f',1,'transformers.symbol_tree.SymbolTreeBuilder.__init__()'],['../classtransformers_1_1symbol__tree_1_1SymbolTree.html#ae5a94636b396b77c05857572823b1285',1,'transformers.symbol_tree.SymbolTree.__init__()'],['../classtransformers_1_1symbol__tree_1_1ModuleScope.html#a08701d98e737973214f9370291b63188',1,'transformers.symbol_tree.ModuleScope.__init__()'],['../classtransformers_1_1symbol__tree_1_1ClassScope.html#a359688eee5249d7f4c8929ab5348115f',1,'transformers.symbol_tree.ClassScope.__init__()'],['../classtransformers_1_1symbol__tree_1_1Scope.html#a46787477db922894246fecb5c12486b4',1,'transformers.symbol_tree.Scope.__init__()'],['../classtransformers_1_1rename_1_1RenameTransformer.html#a41c7ff17fad58c5d75f9b42c3bae8b98',1,'transformers.rename.RenameTransformer.__init__()'],['../classtransformers_1_1control__flow_1_1ControlFlowFlattener.html#a08a538261912ba3c8ec059dd8f528732',1,'transformers.control_flow.ControlFlowFlattener.__init__()'],['../classtransformers_1_1class__mapper_1_1ClassTransformer.html#af7356231305781d4b6287bde4fe38f9e',1,'transformers.class_mapper.ClassTransformer.__init__()'],['../classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html#ad196ea0fd82543968f2514f4cebbba94',1,'transformers.class_mapper.ClassMapAnalyzer.__init__()'],['../classtransformers_1_1class__mapper_1_1ClassMapping.html#a9327faa5f8de53e9da48588245d332ba',1,'transformers.class_mapper.ClassMapping.__init__()'],['../classtransformers_1_1class__analyzer_1_1ClassAnalyzer.html#a4145a8d6f13f330351df501d2c2acbef',1,'transformers.class_analyzer.ClassAnalyzer.__init__()'],['../classtransformers_1_1class__analyzer_1_1ClassMethodMap.html#a26346b25523894f82d2e483b6da187fd',1,'transformers.class_analyzer.ClassMethodMap.__init__()'],['../classobfuscator_1_1AdvancedObfuscator.html#aaffc65fd026066b5db7b28c767113b2b',1,'obfuscator.AdvancedObfuscator.__init__()'],['../classtransformers_1_1symbol__tree_1_1Symbol.html#a391a0c0a2d4a4a88690b287c2c0901a9',1,'transformers.symbol_tree.Symbol.__init__(self, str name, SymbolType symbol_type, ast.AST node=None)']]], + ['_5f_5frepr_5f_5f_1',['__repr__',['../classtransformers_1_1symbol__tree_1_1Symbol.html#ab98bc4a99007d752ce57d203a022706f',1,'transformers.symbol_tree.Symbol.__repr__()'],['../classtransformers_1_1symbol__tree_1_1Scope.html#af3b53a662c490b6d028b629d05661f08',1,'transformers.symbol_tree.Scope.__repr__()']]], + ['_5fbuild_5fsymbol_5ftree_2',['_build_symbol_tree',['../classobfuscator_1_1AdvancedObfuscator.html#a424ba5de0c9a2ea94ffe39f58b6a04b8',1,'obfuscator::AdvancedObfuscator']]], + ['_5fcreate_5fiterator_3',['_create_iterator',['../classutils_1_1name__gen_1_1NameGenerator.html#a2a43fa241cee73c532a98c366fe7df71',1,'utils::name_gen::NameGenerator']]], + ['_5fensure_5fcomplete_5fmethod_5fmapping_4',['_ensure_complete_method_mapping',['../classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html#af584a55f0c308a55d109181485e1ae76',1,'transformers::class_mapper::ClassMapAnalyzer']]], + ['_5fensure_5fconsistent_5fmethod_5fmapping_5',['_ensure_consistent_method_mapping',['../classtransformers_1_1class__analyzer_1_1ClassAnalyzer.html#a525167f88e08ed9d456beb58698a5861',1,'transformers::class_analyzer::ClassAnalyzer']]], + ['_5fflatten_5fcontrol_5fflow_6',['_flatten_control_flow',['../classobfuscator_1_1AdvancedObfuscator.html#aab379b03fecc184395d84df866849bdb',1,'obfuscator::AdvancedObfuscator']]], + ['_5fgenerate_5ffinal_5fcode_7',['_generate_final_code',['../classobfuscator_1_1AdvancedObfuscator.html#ac72c695b2382f94015e9133254c60ba8',1,'obfuscator::AdvancedObfuscator']]], + ['_5fname_5fiterator_8',['_name_iterator',['../classutils_1_1name__gen_1_1NameGenerator.html#ae45ad0a202daf1572a4f76cf79e791e7',1,'utils::name_gen::NameGenerator']]], + ['_5fpop_5fscope_9',['_pop_scope',['../classtransformers_1_1rename_1_1RenameTransformer.html#abdbb42558625854c0535dfb7610ec136',1,'transformers::rename::RenameTransformer']]], + ['_5fpush_5fscope_10',['_push_scope',['../classtransformers_1_1rename_1_1RenameTransformer.html#acd49db2a6b3c22d6eaaec55ddcc95620',1,'transformers::rename::RenameTransformer']]], + ['_5frename_5fand_5fencrypt_11',['_rename_and_encrypt',['../classobfuscator_1_1AdvancedObfuscator.html#ac5445e1980a8addc56b5e9e4b134f2a7',1,'obfuscator::AdvancedObfuscator']]], + ['_5fresolve_5finheritance_12',['_resolve_inheritance',['../classtransformers_1_1class__analyzer_1_1ClassAnalyzer.html#a7bc086b8807e7b51c4237d0b20b35c88',1,'transformers.class_analyzer.ClassAnalyzer._resolve_inheritance()'],['../classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html#a34c03faa2fef07c3a5f0e56745b8e799',1,'transformers.class_mapper.ClassMapAnalyzer._resolve_inheritance()']]] +]; diff --git a/doxygen/search/all_1.js b/doxygen/search/all_1.js new file mode 100644 index 0000000..c6253fb --- /dev/null +++ b/doxygen/search/all_1.js @@ -0,0 +1,22 @@ +var searchData= +[ + ['add_5fattribute_0',['add_attribute',['../classtransformers_1_1symbol__tree_1_1ClassScope.html#a279fe21a8a95cd5b3b3c64d699922aa3',1,'transformers::symbol_tree::ClassScope']]], + ['add_5fbase_5fclass_1',['add_base_class',['../classtransformers_1_1symbol__tree_1_1ClassScope.html#a802567dd6aeb95d3c45929992cbe4ce8',1,'transformers::symbol_tree::ClassScope']]], + ['add_5fchild_5fscope_2',['add_child_scope',['../classtransformers_1_1symbol__tree_1_1Scope.html#a0081ee771c31639c01b2b1da2616100c',1,'transformers::symbol_tree::Scope']]], + ['add_5ffrom_5fimport_3',['add_from_import',['../classtransformers_1_1symbol__tree_1_1ModuleScope.html#a28659edddf055d62956a87218c564c46',1,'transformers::symbol_tree::ModuleScope']]], + ['add_5fimport_4',['add_import',['../classtransformers_1_1symbol__tree_1_1ModuleScope.html#af789af3957432b1d74e19d2e945aea80',1,'transformers::symbol_tree::ModuleScope']]], + ['add_5fjunk_5',['add_junk',['../classutils_1_1junk__gen_1_1JunkGenerator.html#ad5fdca002e6e7b5e5de74b6836a26887',1,'utils::junk_gen::JunkGenerator']]], + ['add_5fmethod_6',['add_method',['../classtransformers_1_1symbol__tree_1_1ClassScope.html#ad8149b754ff7a1a122a8735b733b3853',1,'transformers::symbol_tree::ClassScope']]], + ['add_5freference_7',['add_reference',['../classtransformers_1_1symbol__tree_1_1Symbol.html#a77426bdaaddd0c9a5f5cf2939af5e82d',1,'transformers.symbol_tree.Symbol.add_reference()'],['../classtransformers_1_1symbol__tree_1_1SymbolTree.html#ab45a75613adc005d160afbc3a5d4034c',1,'transformers.symbol_tree.SymbolTree.add_reference()']]], + ['add_5fsymbol_8',['add_symbol',['../classtransformers_1_1symbol__tree_1_1Scope.html#abfdd86fbdb9eb9f43e59407433981217',1,'transformers.symbol_tree.Scope.add_symbol()'],['../classtransformers_1_1symbol__tree_1_1SymbolTree.html#a059c692815d67b54786eeae7a69a699d',1,'transformers.symbol_tree.SymbolTree.add_symbol()']]], + ['advancedobfuscator_9',['AdvancedObfuscator',['../classobfuscator_1_1AdvancedObfuscator.html',1,'obfuscator']]], + ['analyze_10',['analyze',['../classtransformers_1_1class__analyzer_1_1ClassAnalyzer.html#a8a4d1b9cb7d27cbe667e8317d482b5b6',1,'transformers.class_analyzer.ClassAnalyzer.analyze()'],['../classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html#a13817b3df73643f9bb8b9601e3e040cb',1,'transformers.class_mapper.ClassMapAnalyzer.analyze()']]], + ['and_20diagnostics_11',['Debugging and diagnostics',['../index.html#autotoc_md7',1,'']]], + ['and_20limitations_12',['Notes and limitations',['../index.html#autotoc_md8',1,'']]], + ['apply_5fclass_5fmapping_13',['apply_class_mapping',['../namespacetransformers_1_1class__mapper.html#a799073dc76d04c46febc20f3f88ff430',1,'transformers::class_mapper']]], + ['apply_5fname_5fgenerator_14',['apply_name_generator',['../classtransformers_1_1symbol__tree_1_1SymbolTree.html#ab21d8bdd7653df8f0cddf0fbb1f916b2',1,'transformers::symbol_tree::SymbolTree']]], + ['argument_15',['ARGUMENT',['../classtransformers_1_1symbol__tree_1_1SymbolType.html#afe39c27276fa3655e49323158a3e87ca',1,'transformers::symbol_tree::SymbolType']]], + ['attribute_16',['ATTRIBUTE',['../classtransformers_1_1symbol__tree_1_1SymbolType.html#a03194cf85b1f80973db4dec5365f6b52',1,'transformers::symbol_tree::SymbolType']]], + ['attribute_5ftransformer_2epy_17',['attribute_transformer.py',['../attribute__transformer_8py.html',1,'']]], + ['attributetransformer_18',['AttributeTransformer',['../classtransformers_1_1attribute__transformer_1_1AttributeTransformer.html',1,'transformers::attribute_transformer']]] +]; diff --git a/doxygen/search/all_10.js b/doxygen/search/all_10.js new file mode 100644 index 0000000..1ae4382 --- /dev/null +++ b/doxygen/search/all_10.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['pop_5fscope_0',['pop_scope',['../classtransformers_1_1symbol__tree_1_1SymbolTree.html#ac3622dfd3cf0c24f591974f4daf542b7',1,'transformers::symbol_tree::SymbolTree']]], + ['primary_5fkey_1',['primary_key',['../classobfuscator_1_1AdvancedObfuscator.html#a6b389da576cc61f0404f71d31768ea80',1,'obfuscator.AdvancedObfuscator.primary_key'],['../classutils_1_1encryption_1_1StringEncryptor.html#a3359e4b96fb9553a0c9cc4184fc2c434',1,'utils.encryption.StringEncryptor.primary_key']]], + ['project_20structure_2',['Project structure',['../index.html#autotoc_md6',1,'']]], + ['push_5fscope_3',['push_scope',['../classtransformers_1_1symbol__tree_1_1SymbolTree.html#a552a46afd0e3e2eed55366a9d0b037b6',1,'transformers::symbol_tree::SymbolTree']]] +]; diff --git a/doxygen/search/all_11.js b/doxygen/search/all_11.js new file mode 100644 index 0000000..0db9cfe --- /dev/null +++ b/doxygen/search/all_11.js @@ -0,0 +1,9 @@ +var searchData= +[ + ['readme_2emd_0',['README.md',['../README_8md.html',1,'']]], + ['rename_2epy_1',['rename.py',['../rename_8py.html',1,'']]], + ['renametransformer_2',['RenameTransformer',['../classtransformers_1_1rename_1_1RenameTransformer.html',1,'transformers::rename']]], + ['requirements_3',['Requirements',['../index.html#autotoc_md2',1,'']]], + ['resolve_5finheritance_4',['resolve_inheritance',['../classtransformers_1_1symbol__tree_1_1SymbolTree.html#af5a83401d437658d233d32f15071305c',1,'transformers::symbol_tree::SymbolTree']]], + ['root_5fscope_5',['root_scope',['../classtransformers_1_1symbol__tree_1_1SymbolTree.html#a69923f85f26cb752607ec256796647be',1,'transformers::symbol_tree::SymbolTree']]] +]; diff --git a/doxygen/search/all_12.js b/doxygen/search/all_12.js new file mode 100644 index 0000000..8032029 --- /dev/null +++ b/doxygen/search/all_12.js @@ -0,0 +1,20 @@ +var searchData= +[ + ['salt_0',['salt',['../classobfuscator_1_1AdvancedObfuscator.html#aef1166ac92f95772a86271833cf0dc8d',1,'obfuscator.AdvancedObfuscator.salt'],['../classutils_1_1encryption_1_1StringEncryptor.html#a46597c8e3f7981b5f55ca974a5355dd3',1,'utils.encryption.StringEncryptor.salt']]], + ['scan_5fclass_5fmethods_1',['scan_class_methods',['../classtransformers_1_1rename_1_1RenameTransformer.html#ab87d8148ef510b4803c4332deff663d5',1,'transformers::rename::RenameTransformer']]], + ['scope_2',['Scope',['../classtransformers_1_1symbol__tree_1_1Scope.html',1,'transformers::symbol_tree']]], + ['scope_5fstack_3',['scope_stack',['../classtransformers_1_1rename_1_1RenameTransformer.html#a41eded65457e873912b6874d6a0c2909',1,'transformers::rename::RenameTransformer']]], + ['scope_5ftype_4',['scope_type',['../classtransformers_1_1symbol__tree_1_1Scope.html#afcd5b42c282fac61354d80897b5c751e',1,'transformers::symbol_tree::Scope']]], + ['secondary_5fkey_5',['secondary_key',['../classutils_1_1encryption_1_1StringEncryptor.html#ac923cfbf0a09c75e6bb0cea01cde8cd8',1,'utils.encryption.StringEncryptor.secondary_key'],['../classobfuscator_1_1AdvancedObfuscator.html#a5a777b8774460385c5640e6a7fd8abd3',1,'obfuscator.AdvancedObfuscator.secondary_key']]], + ['state_5fvar_5fname_6',['state_var_name',['../classtransformers_1_1control__flow_1_1ControlFlowFlattener.html#aee799638015280dec91b61e46efc6a95',1,'transformers::control_flow::ControlFlowFlattener']]], + ['states_7',['states',['../classtransformers_1_1control__flow_1_1ControlFlowFlattener.html#a58c53389a3591f693045f05e6aff79ab',1,'transformers::control_flow::ControlFlowFlattener']]], + ['stringencryptor_8',['StringEncryptor',['../classutils_1_1encryption_1_1StringEncryptor.html',1,'utils::encryption']]], + ['structure_9',['Project structure',['../index.html#autotoc_md6',1,'']]], + ['symbol_10',['Symbol',['../classtransformers_1_1symbol__tree_1_1Symbol.html',1,'transformers::symbol_tree']]], + ['symbol_5ftree_11',['symbol_tree',['../classobfuscator_1_1AdvancedObfuscator.html#a663f90581cbf805979af75ac48f400a3',1,'obfuscator::AdvancedObfuscator']]], + ['symbol_5ftree_2epy_12',['symbol_tree.py',['../symbol__tree_8py.html',1,'']]], + ['symbol_5ftype_13',['symbol_type',['../classtransformers_1_1symbol__tree_1_1Symbol.html#aa4a20656cbca365de328bb0f33b89ff0',1,'transformers::symbol_tree::Symbol']]], + ['symboltree_14',['SymbolTree',['../classtransformers_1_1symbol__tree_1_1SymbolTree.html',1,'transformers::symbol_tree']]], + ['symboltreebuilder_15',['SymbolTreeBuilder',['../classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html',1,'transformers::symbol_tree']]], + ['symboltype_16',['SymbolType',['../classtransformers_1_1symbol__tree_1_1SymbolType.html',1,'transformers::symbol_tree']]] +]; diff --git a/doxygen/search/all_13.js b/doxygen/search/all_13.js new file mode 100644 index 0000000..ee734da --- /dev/null +++ b/doxygen/search/all_13.js @@ -0,0 +1,12 @@ +var searchData= +[ + ['transformers_0',['transformers',['../namespacetransformers.html',1,'']]], + ['transformers_2f_5f_5finit_5f_5f_2epy_1',['__init__.py',['../transformers_2____init_____8py.html',1,'']]], + ['transformers_3a_3aattribute_5ftransformer_2',['attribute_transformer',['../namespacetransformers_1_1attribute__transformer.html',1,'transformers']]], + ['transformers_3a_3aclass_5fanalyzer_3',['class_analyzer',['../namespacetransformers_1_1class__analyzer.html',1,'transformers']]], + ['transformers_3a_3aclass_5fmapper_4',['class_mapper',['../namespacetransformers_1_1class__mapper.html',1,'transformers']]], + ['transformers_3a_3acontrol_5fflow_5',['control_flow',['../namespacetransformers_1_1control__flow.html',1,'transformers']]], + ['transformers_3a_3arename_6',['rename',['../namespacetransformers_1_1rename.html',1,'transformers']]], + ['transformers_3a_3asymbol_5ftree_7',['symbol_tree',['../namespacetransformers_1_1symbol__tree.html',1,'transformers']]], + ['tree_8',['tree',['../classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#aeedf41282ae721713024904629c2c8a4',1,'transformers::symbol_tree::SymbolTreeBuilder']]] +]; diff --git a/doxygen/search/all_14.js b/doxygen/search/all_14.js new file mode 100644 index 0000000..0e96381 --- /dev/null +++ b/doxygen/search/all_14.js @@ -0,0 +1,11 @@ +var searchData= +[ + ['update_5fobfuscator_5fwith_5fclass_5fmappings_0',['update_obfuscator_with_class_mappings',['../namespacetransformers_1_1class__analyzer.html#a33c650248422029fa53952d08e4da438',1,'transformers::class_analyzer']]], + ['usage_1',['usage',['../index.html#autotoc_md4',1,'CLI usage'],['../index.html#autotoc_md5',1,'Library usage']]], + ['used_5fnames_2',['used_names',['../classobfuscator_1_1AdvancedObfuscator.html#a9df466e5d1c16e8f5209573b5283fd2e',1,'obfuscator.AdvancedObfuscator.used_names'],['../classutils_1_1name__gen_1_1NameGenerator.html#ab773c0140d1b4ef0654215de2c2b37df',1,'utils.name_gen.NameGenerator.used_names']]], + ['utils_3',['utils',['../namespaceutils.html',1,'']]], + ['utils_2f_5f_5finit_5f_5f_2epy_4',['__init__.py',['../utils_2____init_____8py.html',1,'']]], + ['utils_3a_3aencryption_5',['encryption',['../namespaceutils_1_1encryption.html',1,'utils']]], + ['utils_3a_3ajunk_5fgen_6',['junk_gen',['../namespaceutils_1_1junk__gen.html',1,'utils']]], + ['utils_3a_3aname_5fgen_7',['name_gen',['../namespaceutils_1_1name__gen.html',1,'utils']]] +]; diff --git a/doxygen/search/all_15.js b/doxygen/search/all_15.js new file mode 100644 index 0000000..b0ea049 --- /dev/null +++ b/doxygen/search/all_15.js @@ -0,0 +1,32 @@ +var searchData= +[ + ['variable_0',['VARIABLE',['../classtransformers_1_1symbol__tree_1_1SymbolType.html#ad9d2f0f2f9c17ba5c68a15d0c18cbb41',1,'transformers::symbol_tree::SymbolType']]], + ['visit_5farguments_1',['visit_arguments',['../classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#a565b94a735a3899055141b19bdcdd7e0',1,'transformers::symbol_tree::SymbolTreeBuilder']]], + ['visit_5fassign_2',['visit_assign',['../classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#a1a43a6e373b68b4bfee55ea12f96fdb0',1,'transformers.symbol_tree.SymbolTreeBuilder.visit_Assign()'],['../classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html#afdc5a0eb9fd40b5d0e9b70cea0de1f72',1,'transformers.class_mapper.ClassMapAnalyzer.visit_Assign(self, ast.Assign node)']]], + ['visit_5fassign_5fin_5fclass_3',['visit_assign_in_class',['../classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html#afd6498b69da44c6ec6e0b2afa725c67f',1,'transformers::class_mapper::ClassMapAnalyzer']]], + ['visit_5fattribute_4',['visit_attribute',['../classtransformers_1_1attribute__transformer_1_1AttributeTransformer.html#abe7e476c5bb7ecf22c0c5f7747cd1a9e',1,'transformers.attribute_transformer.AttributeTransformer.visit_Attribute()'],['../classtransformers_1_1class__analyzer_1_1ClassAnalyzer.html#ab4fe116f7c092817a6cf585f965dd745',1,'transformers.class_analyzer.ClassAnalyzer.visit_Attribute()'],['../classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html#a6ba0759719762c8b373d3009b7caed98',1,'transformers.class_mapper.ClassMapAnalyzer.visit_Attribute()'],['../classtransformers_1_1class__mapper_1_1ClassTransformer.html#a18fb4582603ee59841361810858c680e',1,'transformers.class_mapper.ClassTransformer.visit_Attribute()'],['../classtransformers_1_1rename_1_1RenameTransformer.html#a89a7f9a7f5c45440346c798fc8840ac7',1,'transformers.rename.RenameTransformer.visit_Attribute()'],['../classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#a50731af5433062399d9d9be18e3c65f5',1,'transformers.symbol_tree.SymbolTreeBuilder.visit_Attribute()']]], + ['visit_5fattribute_5fassign_5',['visit_attribute_assign',['../classtransformers_1_1class__analyzer_1_1ClassAnalyzer.html#a691ad5c2629a84762bf0f8ae82735021',1,'transformers::class_analyzer::ClassAnalyzer']]], + ['visit_5fattribute_5fassignment_6',['visit_attribute_assignment',['../classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#a4347feddd371651de92d2a27521b7db4',1,'transformers::symbol_tree::SymbolTreeBuilder']]], + ['visit_5fbreak_7',['visit_Break',['../classtransformers_1_1control__flow_1_1ControlFlowFlattener.html#a0af6bdcc5f0423e92bbaff8f11134ee9',1,'transformers::control_flow::ControlFlowFlattener']]], + ['visit_5fcall_8',['visit_Call',['../classtransformers_1_1rename_1_1RenameTransformer.html#a6dc39dff4863373a67b4095f234793dc',1,'transformers::rename::RenameTransformer']]], + ['visit_5fclassdef_9',['visit_classdef',['../classtransformers_1_1attribute__transformer_1_1AttributeTransformer.html#aa0bde339bf61f794e984dd890db8fd91',1,'transformers.attribute_transformer.AttributeTransformer.visit_ClassDef()'],['../classtransformers_1_1class__analyzer_1_1ClassAnalyzer.html#a07cf975c27127718a00327be06695e5b',1,'transformers.class_analyzer.ClassAnalyzer.visit_ClassDef()'],['../classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html#aeebda718232e13cd5a3e583db024da6f',1,'transformers.class_mapper.ClassMapAnalyzer.visit_ClassDef()'],['../classtransformers_1_1class__mapper_1_1ClassTransformer.html#a54db45ae6b1b4e8ffdf6c56ae4c67fd3',1,'transformers.class_mapper.ClassTransformer.visit_ClassDef()'],['../classtransformers_1_1rename_1_1RenameTransformer.html#a9d9392f24ca47278859f5e46da1bce45',1,'transformers.rename.RenameTransformer.visit_ClassDef()'],['../classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#ac2a538f11fab8831b20026881c148744',1,'transformers.symbol_tree.SymbolTreeBuilder.visit_ClassDef()']]], + ['visit_5fcomprehension_10',['visit_comprehension',['../classtransformers_1_1rename_1_1RenameTransformer.html#a0660f79cdf349288c43d6fc49ae23a2c',1,'transformers::rename::RenameTransformer']]], + ['visit_5fconstant_11',['visit_Constant',['../classtransformers_1_1rename_1_1RenameTransformer.html#ad81bc6a0c7abb3094b23b6dc03ecfd29',1,'transformers::rename::RenameTransformer']]], + ['visit_5fcontinue_12',['visit_Continue',['../classtransformers_1_1control__flow_1_1ControlFlowFlattener.html#a3f96cc0e595090bd445525dacc81a52e',1,'transformers::control_flow::ControlFlowFlattener']]], + ['visit_5fdictcomp_13',['visit_DictComp',['../classtransformers_1_1rename_1_1RenameTransformer.html#a1fa5c552e136af25f432f975094b7cbf',1,'transformers::rename::RenameTransformer']]], + ['visit_5ffor_14',['visit_For',['../classtransformers_1_1control__flow_1_1ControlFlowFlattener.html#a336fefe281452a4cefb0017de41f6cb5',1,'transformers::control_flow::ControlFlowFlattener']]], + ['visit_5ffunctiondef_15',['visit_functiondef',['../classtransformers_1_1class__mapper_1_1ClassTransformer.html#a0a61d0cd34072cb712df523d6fc504e3',1,'transformers.class_mapper.ClassTransformer.visit_FunctionDef()'],['../classtransformers_1_1control__flow_1_1ControlFlowFlattener.html#a708096f6acd688fa597f7695d9eea010',1,'transformers.control_flow.ControlFlowFlattener.visit_FunctionDef()'],['../classtransformers_1_1rename_1_1RenameTransformer.html#a4309d59dde0369e0b8476b8d6b84d500',1,'transformers.rename.RenameTransformer.visit_FunctionDef()'],['../classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#a52448d9c2f26302f3fec276aac37a19b',1,'transformers.symbol_tree.SymbolTreeBuilder.visit_FunctionDef()']]], + ['visit_5fgeneratorexp_16',['visit_GeneratorExp',['../classtransformers_1_1rename_1_1RenameTransformer.html#a771a06f14514e325c016778767307274',1,'transformers::rename::RenameTransformer']]], + ['visit_5fglobal_17',['visit_Global',['../classtransformers_1_1rename_1_1RenameTransformer.html#ae366228dc64c18fa26f2ba7fa6453444',1,'transformers::rename::RenameTransformer']]], + ['visit_5fif_18',['visit_If',['../classtransformers_1_1control__flow_1_1ControlFlowFlattener.html#ac394afa0ffcadb438bf3419375480ba8',1,'transformers::control_flow::ControlFlowFlattener']]], + ['visit_5fimport_19',['visit_import',['../classtransformers_1_1rename_1_1RenameTransformer.html#a99663ce64c7051d684d84cf8fd1dca5a',1,'transformers.rename.RenameTransformer.visit_Import()'],['../classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#a662cfd0c23a2b7578efe656479c75269',1,'transformers.symbol_tree.SymbolTreeBuilder.visit_Import()']]], + ['visit_5fimportfrom_20',['visit_importfrom',['../classtransformers_1_1rename_1_1RenameTransformer.html#ae4a3532894dd265babf99765ca109dc6',1,'transformers.rename.RenameTransformer.visit_ImportFrom()'],['../classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#ae098863349f3088291bf86dbe0275590',1,'transformers.symbol_tree.SymbolTreeBuilder.visit_ImportFrom()']]], + ['visit_5flistcomp_21',['visit_ListComp',['../classtransformers_1_1rename_1_1RenameTransformer.html#a6583f4eb358270431dda81d0d939162d',1,'transformers::rename::RenameTransformer']]], + ['visit_5fmethod_5fdef_22',['visit_method_def',['../classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html#a6bcd45016a2ae5cb4be6a3cb942bdf9d',1,'transformers::class_mapper::ClassMapAnalyzer']]], + ['visit_5fmodule_23',['visit_module',['../classtransformers_1_1rename_1_1RenameTransformer.html#af219e2b8032497024cf99f76578eea8b',1,'transformers.rename.RenameTransformer.visit_Module()'],['../classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#a5706641787b556edc011c99fc5233b01',1,'transformers.symbol_tree.SymbolTreeBuilder.visit_Module()']]], + ['visit_5fname_24',['visit_name',['../classtransformers_1_1rename_1_1RenameTransformer.html#a6ffe49f1216346f0727df849dae7163a',1,'transformers.rename.RenameTransformer.visit_Name()'],['../classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#add1ec41f47e2b9d45d01ddaa8848a846',1,'transformers.symbol_tree.SymbolTreeBuilder.visit_Name()']]], + ['visit_5freturn_25',['visit_Return',['../classtransformers_1_1control__flow_1_1ControlFlowFlattener.html#ae1e8400d54ec1b75fdc514cd1609120f',1,'transformers::control_flow::ControlFlowFlattener']]], + ['visit_5fsetcomp_26',['visit_SetComp',['../classtransformers_1_1rename_1_1RenameTransformer.html#a29d393746b1977c8181a439c51207bf1',1,'transformers::rename::RenameTransformer']]], + ['visit_5fsubscript_27',['visit_Subscript',['../classtransformers_1_1rename_1_1RenameTransformer.html#ab4fcef7ad6262e7595e449738e977a5d',1,'transformers::rename::RenameTransformer']]], + ['visit_5fwhile_28',['visit_While',['../classtransformers_1_1control__flow_1_1ControlFlowFlattener.html#aed99b58ddd8e19899955f356323d7a71',1,'transformers::control_flow::ControlFlowFlattener']]] +]; diff --git a/doxygen/search/all_2.js b/doxygen/search/all_2.js new file mode 100644 index 0000000..1969a34 --- /dev/null +++ b/doxygen/search/all_2.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['build_5ftree_0',['build_tree',['../classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#a32eb8339c1450dc3def80e5bc94974ee',1,'transformers::symbol_tree::SymbolTreeBuilder']]] +]; diff --git a/doxygen/search/all_3.js b/doxygen/search/all_3.js new file mode 100644 index 0000000..52da6d3 --- /dev/null +++ b/doxygen/search/all_3.js @@ -0,0 +1,25 @@ +var searchData= +[ + ['check_5ffor_5fissues_0',['check_for_issues',['../classtransformers_1_1symbol__tree_1_1SymbolTree.html#a5a585fa57a9f8fd224cf4d55b8180a78',1,'transformers::symbol_tree::SymbolTree']]], + ['class_1',['CLASS',['../classtransformers_1_1symbol__tree_1_1SymbolType.html#a7f25c4e953938b6761f49360f014c9da',1,'transformers::symbol_tree::SymbolType']]], + ['class_5fanalyzer_2epy_2',['class_analyzer.py',['../class__analyzer_8py.html',1,'']]], + ['class_5fattr_5fmapping_3',['class_attr_mapping',['../classtransformers_1_1rename_1_1RenameTransformer.html#ac4975f5038d05ec36f550bf6706e4d84',1,'transformers.rename.RenameTransformer.class_attr_mapping'],['../classtransformers_1_1attribute__transformer_1_1AttributeTransformer.html#a2a45c1b9df1d719347a72d72cbb2891c',1,'transformers.attribute_transformer.AttributeTransformer.class_attr_mapping'],['../classobfuscator_1_1AdvancedObfuscator.html#aef5016cadd430585e9e3bf6cd651766b',1,'obfuscator.AdvancedObfuscator.class_attr_mapping']]], + ['class_5fmapper_2epy_4',['class_mapper.py',['../class__mapper_8py.html',1,'']]], + ['class_5fmethod_5fmapping_5',['class_method_mapping',['../classtransformers_1_1rename_1_1RenameTransformer.html#ab89f9fee976059e47e655e21952dc010',1,'transformers::rename::RenameTransformer']]], + ['class_5frenames_6',['class_renames',['../classtransformers_1_1attribute__transformer_1_1AttributeTransformer.html#ade8fc4fc84a3bdddfd346bc95b711f13',1,'transformers::attribute_transformer::AttributeTransformer']]], + ['classanalyzer_7',['ClassAnalyzer',['../classtransformers_1_1class__analyzer_1_1ClassAnalyzer.html',1,'transformers::class_analyzer']]], + ['classmapanalyzer_8',['ClassMapAnalyzer',['../classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html',1,'transformers::class_mapper']]], + ['classmapping_9',['ClassMapping',['../classtransformers_1_1class__mapper_1_1ClassMapping.html',1,'transformers::class_mapper']]], + ['classmethodmap_10',['ClassMethodMap',['../classtransformers_1_1class__analyzer_1_1ClassMethodMap.html',1,'transformers::class_analyzer']]], + ['classscope_11',['ClassScope',['../classtransformers_1_1symbol__tree_1_1ClassScope.html',1,'transformers::symbol_tree']]], + ['classtransformer_12',['ClassTransformer',['../classtransformers_1_1class__mapper_1_1ClassTransformer.html',1,'transformers::class_mapper']]], + ['cli_20usage_13',['CLI usage',['../index.html#autotoc_md4',1,'']]], + ['control_5fflow_2epy_14',['control_flow.py',['../control__flow_8py.html',1,'']]], + ['controlflowflattener_15',['ControlFlowFlattener',['../classtransformers_1_1control__flow_1_1ControlFlowFlattener.html',1,'transformers::control_flow']]], + ['current_5fblock_5fid_16',['current_block_id',['../classtransformers_1_1control__flow_1_1ControlFlowFlattener.html#a703ccda2bc9fbe6c10ca4070a0e6940d',1,'transformers::control_flow::ControlFlowFlattener']]], + ['current_5fclass_17',['current_class',['../classtransformers_1_1attribute__transformer_1_1AttributeTransformer.html#ad8426d8acb4d7fd20e18468414a15d5c',1,'transformers.attribute_transformer.AttributeTransformer.current_class'],['../classtransformers_1_1class__analyzer_1_1ClassAnalyzer.html#a602830de65e4ef41bcb031062d9bb169',1,'transformers.class_analyzer.ClassAnalyzer.current_class'],['../classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html#ac0d803c97db3802b92b824d036b14bcc',1,'transformers.class_mapper.ClassMapAnalyzer.current_class'],['../classtransformers_1_1class__mapper_1_1ClassTransformer.html#a4cfb94377152b62a164976d6bd5e2fc5',1,'transformers.class_mapper.ClassTransformer.current_class'],['../classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#ac65977004ca9efc10798bf3ba482456e',1,'transformers.symbol_tree.SymbolTreeBuilder.current_class']]], + ['current_5fclass_5fname_18',['current_class_name',['../classtransformers_1_1rename_1_1RenameTransformer.html#afdd8f38035ed680a0c28236d51c1cd69',1,'transformers::rename::RenameTransformer']]], + ['current_5ffunction_5fargs_19',['current_function_args',['../classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#ae91f0ddf23926d9bd4c46a448248d006',1,'transformers::symbol_tree::SymbolTreeBuilder']]], + ['current_5fmethod_20',['current_method',['../classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html#ad185e02d3dc16d55b1b6ad232203ef35',1,'transformers::class_mapper::ClassMapAnalyzer']]], + ['current_5fscope_21',['current_scope',['../classtransformers_1_1symbol__tree_1_1SymbolTree.html#ab61ebd1549ee934fa7e468407a410b14',1,'transformers::symbol_tree::SymbolTree']]] +]; diff --git a/doxygen/search/all_4.js b/doxygen/search/all_4.js new file mode 100644 index 0000000..7b58947 --- /dev/null +++ b/doxygen/search/all_4.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['debug_5fdata_0',['debug_data',['../classobfuscator_1_1AdvancedObfuscator.html#a4c05fe283ed840c34d9a4b1b8b90297b',1,'obfuscator.AdvancedObfuscator.debug_data'],['../classtransformers_1_1control__flow_1_1ControlFlowFlattener.html#a451d4b05a74909802cbde2220cf9a013',1,'transformers.control_flow.ControlFlowFlattener.debug_data'],['../classtransformers_1_1rename_1_1RenameTransformer.html#a2c367ecd7eb38ba4600dda4671b0ab37',1,'transformers.rename.RenameTransformer.debug_data']]], + ['debug_5finfo_1',['debug_info',['../classtransformers_1_1class__mapper_1_1ClassMapping.html#a1fa5906a282c1ed833160badb1f674a2',1,'transformers::class_mapper::ClassMapping']]], + ['debug_5fmode_2',['debug_mode',['../classobfuscator_1_1AdvancedObfuscator.html#a755ab23358e464b4a4d8ea144d84c5db',1,'obfuscator.AdvancedObfuscator.debug_mode'],['../classtransformers_1_1control__flow_1_1ControlFlowFlattener.html#a8113e193915bc1952bc25d039693e38a',1,'transformers.control_flow.ControlFlowFlattener.debug_mode'],['../classtransformers_1_1rename_1_1RenameTransformer.html#a285d017ddc69b2f8b20824251e8ddad4',1,'transformers.rename.RenameTransformer.debug_mode']]], + ['debugging_20and_20diagnostics_3',['Debugging and diagnostics',['../index.html#autotoc_md7',1,'']]], + ['detect_5fissues_4',['detect_issues',['../classobfuscator_1_1AdvancedObfuscator.html#aa5653d0e597359d527b772223acb9c54',1,'obfuscator::AdvancedObfuscator']]], + ['diagnostics_5',['Debugging and diagnostics',['../index.html#autotoc_md7',1,'']]], + ['documentation_6',['Documentation',['../index.html#autotoc_md10',1,'']]] +]; diff --git a/doxygen/search/all_5.js b/doxygen/search/all_5.js new file mode 100644 index 0000000..384fed7 --- /dev/null +++ b/doxygen/search/all_5.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['encrypt_5fstring_0',['encrypt_string',['../classutils_1_1encryption_1_1StringEncryptor.html#a6c2cacc40f85e399dee8e47e20f81739',1,'utils::encryption::StringEncryptor']]], + ['encryption_2epy_1',['encryption.py',['../encryption_8py.html',1,'']]], + ['encryptor_2',['encryptor',['../classtransformers_1_1rename_1_1RenameTransformer.html#ae8272a419a6f3c2ea0ab6b8cc42e376e',1,'transformers::rename::RenameTransformer']]] +]; diff --git a/doxygen/search/all_6.js b/doxygen/search/all_6.js new file mode 100644 index 0000000..9677f51 --- /dev/null +++ b/doxygen/search/all_6.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['features_0',['Features',['../index.html#autotoc_md1',1,'']]], + ['first_5fpass_1',['first_pass',['../classtransformers_1_1rename_1_1RenameTransformer.html#aa61f87dcb4066c6e3676e39a309a523d',1,'transformers::rename::RenameTransformer']]], + ['flatten_5fblocks_2',['flatten_blocks',['../classtransformers_1_1control__flow_1_1ControlFlowFlattener.html#af8cf7ecbaf8d1fdc4127dfecca51c022',1,'transformers::control_flow::ControlFlowFlattener']]], + ['function_3',['FUNCTION',['../classtransformers_1_1symbol__tree_1_1SymbolType.html#a747e62c99ce5d23c7978cd7558eeffbc',1,'transformers::symbol_tree::SymbolType']]], + ['fuscator_4',['OMG-Fuscator',['../index.html',1,'']]] +]; diff --git a/doxygen/search/all_7.js b/doxygen/search/all_7.js new file mode 100644 index 0000000..cdb4f16 --- /dev/null +++ b/doxygen/search/all_7.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['generate_5fjunk_0',['generate_junk',['../classutils_1_1junk__gen_1_1JunkGenerator.html#a0302efd5f4dda3da3c02280d9739d4d3',1,'utils::junk_gen::JunkGenerator']]], + ['generate_5fjunk_5fcode_1',['generate_junk_code',['../classtransformers_1_1control__flow_1_1ControlFlowFlattener.html#a4c787cc400a0a7ab154c09388e016946',1,'transformers::control_flow::ControlFlowFlattener']]], + ['generate_5fname_2',['generate_name',['../classutils_1_1name__gen_1_1NameGenerator.html#ac05b7a033f2ccb1a238b7e5e0877e2c6',1,'utils::name_gen::NameGenerator']]], + ['get_5fmethod_5fname_3',['get_method_name',['../namespacetransformers_1_1class__analyzer.html#a6b97dea989b6eb9d37b5d9b53fae3b6d',1,'transformers::class_analyzer']]], + ['get_5fqualified_5fname_4',['get_qualified_name',['../classtransformers_1_1symbol__tree_1_1Scope.html#a72bf2569e37369e3f845ac2441080a9d',1,'transformers::symbol_tree::Scope']]], + ['get_5frename_5fmapping_5',['get_rename_mapping',['../classtransformers_1_1symbol__tree_1_1SymbolTree.html#aad251f8dde7939c5194c6cfc4caf62a5',1,'transformers::symbol_tree::SymbolTree']]], + ['global_5fvar_5frenames_6',['global_var_renames',['../classobfuscator_1_1AdvancedObfuscator.html#a3ec1e13df931c1508ce87c1d43319d9e',1,'obfuscator.AdvancedObfuscator.global_var_renames'],['../classtransformers_1_1rename_1_1RenameTransformer.html#a8d691eb384ad7616eda40956de5bb95e',1,'transformers.rename.RenameTransformer.global_var_renames']]] +]; diff --git a/doxygen/search/all_8.js b/doxygen/search/all_8.js new file mode 100644 index 0000000..4bc71ef --- /dev/null +++ b/doxygen/search/all_8.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['hide_5fbyte_0',['hide_byte',['../classutils_1_1encryption_1_1StringEncryptor.html#a182add66c3f8039da6f1accf0b52c3c3',1,'utils::encryption::StringEncryptor']]] +]; diff --git a/doxygen/search/all_9.js b/doxygen/search/all_9.js new file mode 100644 index 0000000..743a5e3 --- /dev/null +++ b/doxygen/search/all_9.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['import_0',['IMPORT',['../classtransformers_1_1symbol__tree_1_1SymbolType.html#a5414ea5b01801f342af004f241afa62a',1,'transformers::symbol_tree::SymbolType']]], + ['in_5fattribute_5fctx_1',['in_attribute_ctx',['../classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#a2085ee40b893a6a08ce7c4dab5734ba2',1,'transformers::symbol_tree::SymbolTreeBuilder']]], + ['in_5fclass_2',['in_class',['../classtransformers_1_1rename_1_1RenameTransformer.html#a44a154d4cf962916a1d861e12d593642',1,'transformers::rename::RenameTransformer']]], + ['in_5fclass_5fdef_3',['in_class_def',['../classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#a7be7f365eb0a88520418350d0489198c',1,'transformers::symbol_tree::SymbolTreeBuilder']]], + ['installation_4',['Installation',['../index.html#autotoc_md3',1,'']]], + ['is_5fimported_5',['is_imported',['../classtransformers_1_1symbol__tree_1_1Symbol.html#a83a7262213d2f81c6493a8a4daedb81a',1,'transformers::symbol_tree::Symbol']]], + ['is_5fobfuscatable_6',['is_obfuscatable',['../classtransformers_1_1symbol__tree_1_1Symbol.html#a6220ff5bd5621ab52c59a6b240eddd0d',1,'transformers::symbol_tree::Symbol']]] +]; diff --git a/doxygen/search/all_a.js b/doxygen/search/all_a.js new file mode 100644 index 0000000..68f5005 --- /dev/null +++ b/doxygen/search/all_a.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['junk_5fgen_0',['junk_gen',['../classobfuscator_1_1AdvancedObfuscator.html#aaae69f3be557e46d9538d68caa5f2959',1,'obfuscator::AdvancedObfuscator']]], + ['junk_5fgen_2epy_1',['junk_gen.py',['../junk__gen_8py.html',1,'']]], + ['junkgenerator_2',['JunkGenerator',['../classutils_1_1junk__gen_1_1JunkGenerator.html',1,'utils::junk_gen']]] +]; diff --git a/doxygen/search/all_b.js b/doxygen/search/all_b.js new file mode 100644 index 0000000..0f94bdf --- /dev/null +++ b/doxygen/search/all_b.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['key_5fsetup_5fcode_0',['key_setup_code',['../classtransformers_1_1rename_1_1RenameTransformer.html#a15d28a47a1cde0841e7395822acc1763',1,'transformers::rename::RenameTransformer']]] +]; diff --git a/doxygen/search/all_c.js b/doxygen/search/all_c.js new file mode 100644 index 0000000..a18e7f1 --- /dev/null +++ b/doxygen/search/all_c.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['level_0',['level',['../namespacetransformers_1_1class__mapper.html#a9ce72747d2040877bfa3d561bbcfb046',1,'transformers.class_mapper.level'],['../namespacetransformers_1_1control__flow.html#a8c90b886e8d2a91a19bc062aebcd5682',1,'transformers.control_flow.level'],['../namespacetransformers_1_1rename.html#a2cbae0d4878e456bd1322692636887a3',1,'transformers.rename.level'],['../namespacetransformers_1_1symbol__tree.html#a6dfa45a6fa455a60c68cd968e9da90b5',1,'transformers.symbol_tree.level']]], + ['library_20usage_1',['Library usage',['../index.html#autotoc_md5',1,'']]], + ['license_2',['License',['../index.html#autotoc_md9',1,'']]], + ['limitations_3',['Notes and limitations',['../index.html#autotoc_md8',1,'']]], + ['log_5fdebug_4',['log_debug',['../classobfuscator_1_1AdvancedObfuscator.html#add2f1a570ef241ad62e977d434973ddf',1,'obfuscator.AdvancedObfuscator.log_debug()'],['../classtransformers_1_1control__flow_1_1ControlFlowFlattener.html#a53e89d0d92bb71c22e2721272c27c35c',1,'transformers.control_flow.ControlFlowFlattener.log_debug()'],['../classtransformers_1_1rename_1_1RenameTransformer.html#a0d8e460a12ba4bf74a95882aa6bb3835',1,'transformers.rename.RenameTransformer.log_debug()']]], + ['logger_5',['logger',['../namespacetransformers_1_1class__mapper.html#a77f334648be077cc4cf07b5862cc34f1',1,'transformers.class_mapper.logger'],['../namespacetransformers_1_1control__flow.html#a6509497a1f3193babfae90f14a285aa3',1,'transformers.control_flow.logger'],['../namespacetransformers_1_1rename.html#a8d3edc6223d05ff25d552b11ceca5aa7',1,'transformers.rename.logger'],['../namespacetransformers_1_1symbol__tree.html#acff3629ca6817ec50dfe5bdc75f58745',1,'transformers.symbol_tree.logger']]], + ['lookup_6',['lookup',['../classtransformers_1_1symbol__tree_1_1Scope.html#aea26fa0ade2ce3d7f82cf28a7fec0d16',1,'transformers::symbol_tree::Scope']]] +]; diff --git a/doxygen/search/all_d.js b/doxygen/search/all_d.js new file mode 100644 index 0000000..a60b9e7 --- /dev/null +++ b/doxygen/search/all_d.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['main_0',['main',['../namespacemain.html',1,'main'],['../namespacemain.html#a3140e9a5b6a71ffbf498198cfc471b88',1,'main.main()']]], + ['main_2epy_1',['main.py',['../main_8py.html',1,'']]], + ['mapping_2',['mapping',['../classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html#a93c02ece387c4611fa249e808f39bf10',1,'transformers.class_mapper.ClassMapAnalyzer.mapping'],['../classtransformers_1_1class__mapper_1_1ClassTransformer.html#a02e62f7a280ff5bfabb39f312c0f58fc',1,'transformers.class_mapper.ClassTransformer.mapping']]], + ['method_3',['METHOD',['../classtransformers_1_1symbol__tree_1_1SymbolType.html#a0a47aadbdfff9fca91e0f2944dd8fd17',1,'transformers::symbol_tree::SymbolType']]], + ['method_5fmap_4',['method_map',['../classtransformers_1_1class__analyzer_1_1ClassAnalyzer.html#a739a5193c309c36bd99184aba762a790',1,'transformers::class_analyzer::ClassAnalyzer']]], + ['module_5',['MODULE',['../classtransformers_1_1symbol__tree_1_1SymbolType.html#a9afafe6de92dc3689de599a44fb53f06',1,'transformers::symbol_tree::SymbolType']]], + ['modulescope_6',['ModuleScope',['../classtransformers_1_1symbol__tree_1_1ModuleScope.html',1,'transformers::symbol_tree']]] +]; diff --git a/doxygen/search/all_e.js b/doxygen/search/all_e.js new file mode 100644 index 0000000..6ec7527 --- /dev/null +++ b/doxygen/search/all_e.js @@ -0,0 +1,9 @@ +var searchData= +[ + ['name_0',['name',['../classtransformers_1_1symbol__tree_1_1Symbol.html#ab704c166075e326fa3d0cc1d3cb3d48e',1,'transformers.symbol_tree.Symbol.name'],['../classtransformers_1_1symbol__tree_1_1Scope.html#ab08134920b738ab813bcd04724cc3696',1,'transformers.symbol_tree.Scope.name']]], + ['name_5fgen_2epy_1',['name_gen.py',['../name__gen_8py.html',1,'']]], + ['name_5fgenerator_2',['name_generator',['../classobfuscator_1_1AdvancedObfuscator.html#abaeb1135a6445bef98ac6574f827d6df',1,'obfuscator.AdvancedObfuscator.name_generator'],['../classtransformers_1_1class__analyzer_1_1ClassAnalyzer.html#ae2b710d2e7aa346663d6086b95b0230d',1,'transformers.class_analyzer.ClassAnalyzer.name_generator'],['../classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html#ad4df47c9f65fc7cc70ac7159b7116278',1,'transformers.class_mapper.ClassMapAnalyzer.name_generator'],['../classtransformers_1_1rename_1_1RenameTransformer.html#a04dd79b46f0e252cc1c55f10e63ad938',1,'transformers.rename.RenameTransformer.name_generator'],['../classutils_1_1junk__gen_1_1JunkGenerator.html#a6edc8f910180d399302e33b48a0346ee',1,'utils.junk_gen.JunkGenerator.name_generator']]], + ['namegenerator_3',['NameGenerator',['../classutils_1_1name__gen_1_1NameGenerator.html',1,'utils::name_gen']]], + ['node_4',['node',['../classtransformers_1_1symbol__tree_1_1Symbol.html#ac9a2c001371dbb1876e4d5eb2f618aed',1,'transformers.symbol_tree.Symbol.node'],['../classtransformers_1_1symbol__tree_1_1Scope.html#a51ed89fe0be033cd0643a4d943a1f12b',1,'transformers.symbol_tree.Scope.node']]], + ['notes_20and_20limitations_5',['Notes and limitations',['../index.html#autotoc_md8',1,'']]] +]; diff --git a/doxygen/search/all_f.js b/doxygen/search/all_f.js new file mode 100644 index 0000000..16a3474 --- /dev/null +++ b/doxygen/search/all_f.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['obfuscate_0',['obfuscate',['../classobfuscator_1_1AdvancedObfuscator.html#a0bae5229abba4f829e01b84cb9c9ffd7',1,'obfuscator::AdvancedObfuscator']]], + ['obfuscator_1',['obfuscator',['../namespaceobfuscator.html',1,'']]], + ['obfuscator_2epy_2',['obfuscator.py',['../obfuscator_8py.html',1,'']]], + ['omg_20fuscator_3',['OMG-Fuscator',['../index.html',1,'']]] +]; diff --git a/doxygen/search/classes_0.js b/doxygen/search/classes_0.js new file mode 100644 index 0000000..fae21b2 --- /dev/null +++ b/doxygen/search/classes_0.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['advancedobfuscator_0',['AdvancedObfuscator',['../classobfuscator_1_1AdvancedObfuscator.html',1,'obfuscator']]], + ['attributetransformer_1',['AttributeTransformer',['../classtransformers_1_1attribute__transformer_1_1AttributeTransformer.html',1,'transformers::attribute_transformer']]] +]; diff --git a/doxygen/search/classes_1.js b/doxygen/search/classes_1.js new file mode 100644 index 0000000..a2e9ba9 --- /dev/null +++ b/doxygen/search/classes_1.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['classanalyzer_0',['ClassAnalyzer',['../classtransformers_1_1class__analyzer_1_1ClassAnalyzer.html',1,'transformers::class_analyzer']]], + ['classmapanalyzer_1',['ClassMapAnalyzer',['../classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html',1,'transformers::class_mapper']]], + ['classmapping_2',['ClassMapping',['../classtransformers_1_1class__mapper_1_1ClassMapping.html',1,'transformers::class_mapper']]], + ['classmethodmap_3',['ClassMethodMap',['../classtransformers_1_1class__analyzer_1_1ClassMethodMap.html',1,'transformers::class_analyzer']]], + ['classscope_4',['ClassScope',['../classtransformers_1_1symbol__tree_1_1ClassScope.html',1,'transformers::symbol_tree']]], + ['classtransformer_5',['ClassTransformer',['../classtransformers_1_1class__mapper_1_1ClassTransformer.html',1,'transformers::class_mapper']]], + ['controlflowflattener_6',['ControlFlowFlattener',['../classtransformers_1_1control__flow_1_1ControlFlowFlattener.html',1,'transformers::control_flow']]] +]; diff --git a/doxygen/search/classes_2.js b/doxygen/search/classes_2.js new file mode 100644 index 0000000..e8cbfea --- /dev/null +++ b/doxygen/search/classes_2.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['junkgenerator_0',['JunkGenerator',['../classutils_1_1junk__gen_1_1JunkGenerator.html',1,'utils::junk_gen']]] +]; diff --git a/doxygen/search/classes_3.js b/doxygen/search/classes_3.js new file mode 100644 index 0000000..2c9d966 --- /dev/null +++ b/doxygen/search/classes_3.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['modulescope_0',['ModuleScope',['../classtransformers_1_1symbol__tree_1_1ModuleScope.html',1,'transformers::symbol_tree']]] +]; diff --git a/doxygen/search/classes_4.js b/doxygen/search/classes_4.js new file mode 100644 index 0000000..d286cb0 --- /dev/null +++ b/doxygen/search/classes_4.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['namegenerator_0',['NameGenerator',['../classutils_1_1name__gen_1_1NameGenerator.html',1,'utils::name_gen']]] +]; diff --git a/doxygen/search/classes_5.js b/doxygen/search/classes_5.js new file mode 100644 index 0000000..763eee3 --- /dev/null +++ b/doxygen/search/classes_5.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['renametransformer_0',['RenameTransformer',['../classtransformers_1_1rename_1_1RenameTransformer.html',1,'transformers::rename']]] +]; diff --git a/doxygen/search/classes_6.js b/doxygen/search/classes_6.js new file mode 100644 index 0000000..8241825 --- /dev/null +++ b/doxygen/search/classes_6.js @@ -0,0 +1,9 @@ +var searchData= +[ + ['scope_0',['Scope',['../classtransformers_1_1symbol__tree_1_1Scope.html',1,'transformers::symbol_tree']]], + ['stringencryptor_1',['StringEncryptor',['../classutils_1_1encryption_1_1StringEncryptor.html',1,'utils::encryption']]], + ['symbol_2',['Symbol',['../classtransformers_1_1symbol__tree_1_1Symbol.html',1,'transformers::symbol_tree']]], + ['symboltree_3',['SymbolTree',['../classtransformers_1_1symbol__tree_1_1SymbolTree.html',1,'transformers::symbol_tree']]], + ['symboltreebuilder_4',['SymbolTreeBuilder',['../classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html',1,'transformers::symbol_tree']]], + ['symboltype_5',['SymbolType',['../classtransformers_1_1symbol__tree_1_1SymbolType.html',1,'transformers::symbol_tree']]] +]; diff --git a/doxygen/search/close.svg b/doxygen/search/close.svg new file mode 100644 index 0000000..337d6cc --- /dev/null +++ b/doxygen/search/close.svg @@ -0,0 +1,18 @@ + + + + + + diff --git a/doxygen/search/files_0.js b/doxygen/search/files_0.js new file mode 100644 index 0000000..d93bcfe --- /dev/null +++ b/doxygen/search/files_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['attribute_5ftransformer_2epy_0',['attribute_transformer.py',['../attribute__transformer_8py.html',1,'']]] +]; diff --git a/doxygen/search/files_1.js b/doxygen/search/files_1.js new file mode 100644 index 0000000..791f95f --- /dev/null +++ b/doxygen/search/files_1.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['class_5fanalyzer_2epy_0',['class_analyzer.py',['../class__analyzer_8py.html',1,'']]], + ['class_5fmapper_2epy_1',['class_mapper.py',['../class__mapper_8py.html',1,'']]], + ['control_5fflow_2epy_2',['control_flow.py',['../control__flow_8py.html',1,'']]] +]; diff --git a/doxygen/search/files_2.js b/doxygen/search/files_2.js new file mode 100644 index 0000000..c5a73c1 --- /dev/null +++ b/doxygen/search/files_2.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['encryption_2epy_0',['encryption.py',['../encryption_8py.html',1,'']]] +]; diff --git a/doxygen/search/files_3.js b/doxygen/search/files_3.js new file mode 100644 index 0000000..1494bad --- /dev/null +++ b/doxygen/search/files_3.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['junk_5fgen_2epy_0',['junk_gen.py',['../junk__gen_8py.html',1,'']]] +]; diff --git a/doxygen/search/files_4.js b/doxygen/search/files_4.js new file mode 100644 index 0000000..01a0bf7 --- /dev/null +++ b/doxygen/search/files_4.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['main_2epy_0',['main.py',['../main_8py.html',1,'']]] +]; diff --git a/doxygen/search/files_5.js b/doxygen/search/files_5.js new file mode 100644 index 0000000..a89d3ca --- /dev/null +++ b/doxygen/search/files_5.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['name_5fgen_2epy_0',['name_gen.py',['../name__gen_8py.html',1,'']]] +]; diff --git a/doxygen/search/files_6.js b/doxygen/search/files_6.js new file mode 100644 index 0000000..334cd0c --- /dev/null +++ b/doxygen/search/files_6.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['obfuscator_2epy_0',['obfuscator.py',['../obfuscator_8py.html',1,'']]] +]; diff --git a/doxygen/search/files_7.js b/doxygen/search/files_7.js new file mode 100644 index 0000000..276b39b --- /dev/null +++ b/doxygen/search/files_7.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['readme_2emd_0',['README.md',['../README_8md.html',1,'']]], + ['rename_2epy_1',['rename.py',['../rename_8py.html',1,'']]] +]; diff --git a/doxygen/search/files_8.js b/doxygen/search/files_8.js new file mode 100644 index 0000000..2777bd8 --- /dev/null +++ b/doxygen/search/files_8.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['symbol_5ftree_2epy_0',['symbol_tree.py',['../symbol__tree_8py.html',1,'']]] +]; diff --git a/doxygen/search/files_9.js b/doxygen/search/files_9.js new file mode 100644 index 0000000..20b650d --- /dev/null +++ b/doxygen/search/files_9.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['transformers_2f_5f_5finit_5f_5f_2epy_0',['__init__.py',['../transformers_2____init_____8py.html',1,'']]] +]; diff --git a/doxygen/search/files_a.js b/doxygen/search/files_a.js new file mode 100644 index 0000000..3cabfa0 --- /dev/null +++ b/doxygen/search/files_a.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['utils_2f_5f_5finit_5f_5f_2epy_0',['__init__.py',['../utils_2____init_____8py.html',1,'']]] +]; diff --git a/doxygen/search/functions_0.js b/doxygen/search/functions_0.js new file mode 100644 index 0000000..9ef221f --- /dev/null +++ b/doxygen/search/functions_0.js @@ -0,0 +1,15 @@ +var searchData= +[ + ['_5f_5finit_5f_5f_0',['__init__',['../classtransformers_1_1attribute__transformer_1_1AttributeTransformer.html#a8bc2a45cb2e19075483d7b5b9c98ed50',1,'transformers.attribute_transformer.AttributeTransformer.__init__()'],['../classutils_1_1name__gen_1_1NameGenerator.html#aff640e7a1a975e664ca4fe3a54ec2cfb',1,'utils.name_gen.NameGenerator.__init__()'],['../classutils_1_1junk__gen_1_1JunkGenerator.html#ad1c240cacad785c775dfeddc9eea76b5',1,'utils.junk_gen.JunkGenerator.__init__()'],['../classutils_1_1encryption_1_1StringEncryptor.html#aeeab3fb282428a253a857668c8ad7545',1,'utils.encryption.StringEncryptor.__init__()'],['../classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#adb9a525c0003b90a619179e8c9d42f4f',1,'transformers.symbol_tree.SymbolTreeBuilder.__init__()'],['../classtransformers_1_1symbol__tree_1_1SymbolTree.html#ae5a94636b396b77c05857572823b1285',1,'transformers.symbol_tree.SymbolTree.__init__()'],['../classtransformers_1_1symbol__tree_1_1ModuleScope.html#a08701d98e737973214f9370291b63188',1,'transformers.symbol_tree.ModuleScope.__init__()'],['../classtransformers_1_1symbol__tree_1_1ClassScope.html#a359688eee5249d7f4c8929ab5348115f',1,'transformers.symbol_tree.ClassScope.__init__()'],['../classtransformers_1_1symbol__tree_1_1Scope.html#a46787477db922894246fecb5c12486b4',1,'transformers.symbol_tree.Scope.__init__()'],['../classtransformers_1_1rename_1_1RenameTransformer.html#a41c7ff17fad58c5d75f9b42c3bae8b98',1,'transformers.rename.RenameTransformer.__init__()'],['../classtransformers_1_1control__flow_1_1ControlFlowFlattener.html#a08a538261912ba3c8ec059dd8f528732',1,'transformers.control_flow.ControlFlowFlattener.__init__()'],['../classtransformers_1_1class__mapper_1_1ClassTransformer.html#af7356231305781d4b6287bde4fe38f9e',1,'transformers.class_mapper.ClassTransformer.__init__()'],['../classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html#ad196ea0fd82543968f2514f4cebbba94',1,'transformers.class_mapper.ClassMapAnalyzer.__init__()'],['../classtransformers_1_1class__mapper_1_1ClassMapping.html#a9327faa5f8de53e9da48588245d332ba',1,'transformers.class_mapper.ClassMapping.__init__()'],['../classtransformers_1_1class__analyzer_1_1ClassAnalyzer.html#a4145a8d6f13f330351df501d2c2acbef',1,'transformers.class_analyzer.ClassAnalyzer.__init__()'],['../classtransformers_1_1class__analyzer_1_1ClassMethodMap.html#a26346b25523894f82d2e483b6da187fd',1,'transformers.class_analyzer.ClassMethodMap.__init__()'],['../classobfuscator_1_1AdvancedObfuscator.html#aaffc65fd026066b5db7b28c767113b2b',1,'obfuscator.AdvancedObfuscator.__init__()'],['../classtransformers_1_1symbol__tree_1_1Symbol.html#a391a0c0a2d4a4a88690b287c2c0901a9',1,'transformers.symbol_tree.Symbol.__init__(self, str name, SymbolType symbol_type, ast.AST node=None)']]], + ['_5f_5frepr_5f_5f_1',['__repr__',['../classtransformers_1_1symbol__tree_1_1Symbol.html#ab98bc4a99007d752ce57d203a022706f',1,'transformers.symbol_tree.Symbol.__repr__()'],['../classtransformers_1_1symbol__tree_1_1Scope.html#af3b53a662c490b6d028b629d05661f08',1,'transformers.symbol_tree.Scope.__repr__()']]], + ['_5fbuild_5fsymbol_5ftree_2',['_build_symbol_tree',['../classobfuscator_1_1AdvancedObfuscator.html#a424ba5de0c9a2ea94ffe39f58b6a04b8',1,'obfuscator::AdvancedObfuscator']]], + ['_5fcreate_5fiterator_3',['_create_iterator',['../classutils_1_1name__gen_1_1NameGenerator.html#a2a43fa241cee73c532a98c366fe7df71',1,'utils::name_gen::NameGenerator']]], + ['_5fensure_5fcomplete_5fmethod_5fmapping_4',['_ensure_complete_method_mapping',['../classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html#af584a55f0c308a55d109181485e1ae76',1,'transformers::class_mapper::ClassMapAnalyzer']]], + ['_5fensure_5fconsistent_5fmethod_5fmapping_5',['_ensure_consistent_method_mapping',['../classtransformers_1_1class__analyzer_1_1ClassAnalyzer.html#a525167f88e08ed9d456beb58698a5861',1,'transformers::class_analyzer::ClassAnalyzer']]], + ['_5fflatten_5fcontrol_5fflow_6',['_flatten_control_flow',['../classobfuscator_1_1AdvancedObfuscator.html#aab379b03fecc184395d84df866849bdb',1,'obfuscator::AdvancedObfuscator']]], + ['_5fgenerate_5ffinal_5fcode_7',['_generate_final_code',['../classobfuscator_1_1AdvancedObfuscator.html#ac72c695b2382f94015e9133254c60ba8',1,'obfuscator::AdvancedObfuscator']]], + ['_5fpop_5fscope_8',['_pop_scope',['../classtransformers_1_1rename_1_1RenameTransformer.html#abdbb42558625854c0535dfb7610ec136',1,'transformers::rename::RenameTransformer']]], + ['_5fpush_5fscope_9',['_push_scope',['../classtransformers_1_1rename_1_1RenameTransformer.html#acd49db2a6b3c22d6eaaec55ddcc95620',1,'transformers::rename::RenameTransformer']]], + ['_5frename_5fand_5fencrypt_10',['_rename_and_encrypt',['../classobfuscator_1_1AdvancedObfuscator.html#ac5445e1980a8addc56b5e9e4b134f2a7',1,'obfuscator::AdvancedObfuscator']]], + ['_5fresolve_5finheritance_11',['_resolve_inheritance',['../classtransformers_1_1class__analyzer_1_1ClassAnalyzer.html#a7bc086b8807e7b51c4237d0b20b35c88',1,'transformers.class_analyzer.ClassAnalyzer._resolve_inheritance()'],['../classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html#a34c03faa2fef07c3a5f0e56745b8e799',1,'transformers.class_mapper.ClassMapAnalyzer._resolve_inheritance()']]] +]; diff --git a/doxygen/search/functions_1.js b/doxygen/search/functions_1.js new file mode 100644 index 0000000..ad34d06 --- /dev/null +++ b/doxygen/search/functions_1.js @@ -0,0 +1,15 @@ +var searchData= +[ + ['add_5fattribute_0',['add_attribute',['../classtransformers_1_1symbol__tree_1_1ClassScope.html#a279fe21a8a95cd5b3b3c64d699922aa3',1,'transformers::symbol_tree::ClassScope']]], + ['add_5fbase_5fclass_1',['add_base_class',['../classtransformers_1_1symbol__tree_1_1ClassScope.html#a802567dd6aeb95d3c45929992cbe4ce8',1,'transformers::symbol_tree::ClassScope']]], + ['add_5fchild_5fscope_2',['add_child_scope',['../classtransformers_1_1symbol__tree_1_1Scope.html#a0081ee771c31639c01b2b1da2616100c',1,'transformers::symbol_tree::Scope']]], + ['add_5ffrom_5fimport_3',['add_from_import',['../classtransformers_1_1symbol__tree_1_1ModuleScope.html#a28659edddf055d62956a87218c564c46',1,'transformers::symbol_tree::ModuleScope']]], + ['add_5fimport_4',['add_import',['../classtransformers_1_1symbol__tree_1_1ModuleScope.html#af789af3957432b1d74e19d2e945aea80',1,'transformers::symbol_tree::ModuleScope']]], + ['add_5fjunk_5',['add_junk',['../classutils_1_1junk__gen_1_1JunkGenerator.html#ad5fdca002e6e7b5e5de74b6836a26887',1,'utils::junk_gen::JunkGenerator']]], + ['add_5fmethod_6',['add_method',['../classtransformers_1_1symbol__tree_1_1ClassScope.html#ad8149b754ff7a1a122a8735b733b3853',1,'transformers::symbol_tree::ClassScope']]], + ['add_5freference_7',['add_reference',['../classtransformers_1_1symbol__tree_1_1Symbol.html#a77426bdaaddd0c9a5f5cf2939af5e82d',1,'transformers.symbol_tree.Symbol.add_reference()'],['../classtransformers_1_1symbol__tree_1_1SymbolTree.html#ab45a75613adc005d160afbc3a5d4034c',1,'transformers.symbol_tree.SymbolTree.add_reference()']]], + ['add_5fsymbol_8',['add_symbol',['../classtransformers_1_1symbol__tree_1_1Scope.html#abfdd86fbdb9eb9f43e59407433981217',1,'transformers.symbol_tree.Scope.add_symbol()'],['../classtransformers_1_1symbol__tree_1_1SymbolTree.html#a059c692815d67b54786eeae7a69a699d',1,'transformers.symbol_tree.SymbolTree.add_symbol()']]], + ['analyze_9',['analyze',['../classtransformers_1_1class__analyzer_1_1ClassAnalyzer.html#a8a4d1b9cb7d27cbe667e8317d482b5b6',1,'transformers.class_analyzer.ClassAnalyzer.analyze()'],['../classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html#a13817b3df73643f9bb8b9601e3e040cb',1,'transformers.class_mapper.ClassMapAnalyzer.analyze()']]], + ['apply_5fclass_5fmapping_10',['apply_class_mapping',['../namespacetransformers_1_1class__mapper.html#a799073dc76d04c46febc20f3f88ff430',1,'transformers::class_mapper']]], + ['apply_5fname_5fgenerator_11',['apply_name_generator',['../classtransformers_1_1symbol__tree_1_1SymbolTree.html#ab21d8bdd7653df8f0cddf0fbb1f916b2',1,'transformers::symbol_tree::SymbolTree']]] +]; diff --git a/doxygen/search/functions_10.js b/doxygen/search/functions_10.js new file mode 100644 index 0000000..5cbd82d --- /dev/null +++ b/doxygen/search/functions_10.js @@ -0,0 +1,31 @@ +var searchData= +[ + ['visit_5farguments_0',['visit_arguments',['../classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#a565b94a735a3899055141b19bdcdd7e0',1,'transformers::symbol_tree::SymbolTreeBuilder']]], + ['visit_5fassign_1',['visit_assign',['../classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html#afdc5a0eb9fd40b5d0e9b70cea0de1f72',1,'transformers.class_mapper.ClassMapAnalyzer.visit_Assign()'],['../classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#a1a43a6e373b68b4bfee55ea12f96fdb0',1,'transformers.symbol_tree.SymbolTreeBuilder.visit_Assign()']]], + ['visit_5fassign_5fin_5fclass_2',['visit_assign_in_class',['../classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html#afd6498b69da44c6ec6e0b2afa725c67f',1,'transformers::class_mapper::ClassMapAnalyzer']]], + ['visit_5fattribute_3',['visit_attribute',['../classtransformers_1_1attribute__transformer_1_1AttributeTransformer.html#abe7e476c5bb7ecf22c0c5f7747cd1a9e',1,'transformers.attribute_transformer.AttributeTransformer.visit_Attribute()'],['../classtransformers_1_1class__analyzer_1_1ClassAnalyzer.html#ab4fe116f7c092817a6cf585f965dd745',1,'transformers.class_analyzer.ClassAnalyzer.visit_Attribute()'],['../classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html#a6ba0759719762c8b373d3009b7caed98',1,'transformers.class_mapper.ClassMapAnalyzer.visit_Attribute()'],['../classtransformers_1_1class__mapper_1_1ClassTransformer.html#a18fb4582603ee59841361810858c680e',1,'transformers.class_mapper.ClassTransformer.visit_Attribute()'],['../classtransformers_1_1rename_1_1RenameTransformer.html#a89a7f9a7f5c45440346c798fc8840ac7',1,'transformers.rename.RenameTransformer.visit_Attribute()'],['../classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#a50731af5433062399d9d9be18e3c65f5',1,'transformers.symbol_tree.SymbolTreeBuilder.visit_Attribute()']]], + ['visit_5fattribute_5fassign_4',['visit_attribute_assign',['../classtransformers_1_1class__analyzer_1_1ClassAnalyzer.html#a691ad5c2629a84762bf0f8ae82735021',1,'transformers::class_analyzer::ClassAnalyzer']]], + ['visit_5fattribute_5fassignment_5',['visit_attribute_assignment',['../classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#a4347feddd371651de92d2a27521b7db4',1,'transformers::symbol_tree::SymbolTreeBuilder']]], + ['visit_5fbreak_6',['visit_Break',['../classtransformers_1_1control__flow_1_1ControlFlowFlattener.html#a0af6bdcc5f0423e92bbaff8f11134ee9',1,'transformers::control_flow::ControlFlowFlattener']]], + ['visit_5fcall_7',['visit_Call',['../classtransformers_1_1rename_1_1RenameTransformer.html#a6dc39dff4863373a67b4095f234793dc',1,'transformers::rename::RenameTransformer']]], + ['visit_5fclassdef_8',['visit_classdef',['../classtransformers_1_1attribute__transformer_1_1AttributeTransformer.html#aa0bde339bf61f794e984dd890db8fd91',1,'transformers.attribute_transformer.AttributeTransformer.visit_ClassDef()'],['../classtransformers_1_1class__analyzer_1_1ClassAnalyzer.html#a07cf975c27127718a00327be06695e5b',1,'transformers.class_analyzer.ClassAnalyzer.visit_ClassDef()'],['../classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html#aeebda718232e13cd5a3e583db024da6f',1,'transformers.class_mapper.ClassMapAnalyzer.visit_ClassDef()'],['../classtransformers_1_1class__mapper_1_1ClassTransformer.html#a54db45ae6b1b4e8ffdf6c56ae4c67fd3',1,'transformers.class_mapper.ClassTransformer.visit_ClassDef()'],['../classtransformers_1_1rename_1_1RenameTransformer.html#a9d9392f24ca47278859f5e46da1bce45',1,'transformers.rename.RenameTransformer.visit_ClassDef()'],['../classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#ac2a538f11fab8831b20026881c148744',1,'transformers.symbol_tree.SymbolTreeBuilder.visit_ClassDef()']]], + ['visit_5fcomprehension_9',['visit_comprehension',['../classtransformers_1_1rename_1_1RenameTransformer.html#a0660f79cdf349288c43d6fc49ae23a2c',1,'transformers::rename::RenameTransformer']]], + ['visit_5fconstant_10',['visit_Constant',['../classtransformers_1_1rename_1_1RenameTransformer.html#ad81bc6a0c7abb3094b23b6dc03ecfd29',1,'transformers::rename::RenameTransformer']]], + ['visit_5fcontinue_11',['visit_Continue',['../classtransformers_1_1control__flow_1_1ControlFlowFlattener.html#a3f96cc0e595090bd445525dacc81a52e',1,'transformers::control_flow::ControlFlowFlattener']]], + ['visit_5fdictcomp_12',['visit_DictComp',['../classtransformers_1_1rename_1_1RenameTransformer.html#a1fa5c552e136af25f432f975094b7cbf',1,'transformers::rename::RenameTransformer']]], + ['visit_5ffor_13',['visit_For',['../classtransformers_1_1control__flow_1_1ControlFlowFlattener.html#a336fefe281452a4cefb0017de41f6cb5',1,'transformers::control_flow::ControlFlowFlattener']]], + ['visit_5ffunctiondef_14',['visit_functiondef',['../classtransformers_1_1class__mapper_1_1ClassTransformer.html#a0a61d0cd34072cb712df523d6fc504e3',1,'transformers.class_mapper.ClassTransformer.visit_FunctionDef()'],['../classtransformers_1_1control__flow_1_1ControlFlowFlattener.html#a708096f6acd688fa597f7695d9eea010',1,'transformers.control_flow.ControlFlowFlattener.visit_FunctionDef()'],['../classtransformers_1_1rename_1_1RenameTransformer.html#a4309d59dde0369e0b8476b8d6b84d500',1,'transformers.rename.RenameTransformer.visit_FunctionDef()'],['../classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#a52448d9c2f26302f3fec276aac37a19b',1,'transformers.symbol_tree.SymbolTreeBuilder.visit_FunctionDef()']]], + ['visit_5fgeneratorexp_15',['visit_GeneratorExp',['../classtransformers_1_1rename_1_1RenameTransformer.html#a771a06f14514e325c016778767307274',1,'transformers::rename::RenameTransformer']]], + ['visit_5fglobal_16',['visit_Global',['../classtransformers_1_1rename_1_1RenameTransformer.html#ae366228dc64c18fa26f2ba7fa6453444',1,'transformers::rename::RenameTransformer']]], + ['visit_5fif_17',['visit_If',['../classtransformers_1_1control__flow_1_1ControlFlowFlattener.html#ac394afa0ffcadb438bf3419375480ba8',1,'transformers::control_flow::ControlFlowFlattener']]], + ['visit_5fimport_18',['visit_import',['../classtransformers_1_1rename_1_1RenameTransformer.html#a99663ce64c7051d684d84cf8fd1dca5a',1,'transformers.rename.RenameTransformer.visit_Import()'],['../classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#a662cfd0c23a2b7578efe656479c75269',1,'transformers.symbol_tree.SymbolTreeBuilder.visit_Import(self, ast.Import node)']]], + ['visit_5fimportfrom_19',['visit_importfrom',['../classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#ae098863349f3088291bf86dbe0275590',1,'transformers.symbol_tree.SymbolTreeBuilder.visit_ImportFrom()'],['../classtransformers_1_1rename_1_1RenameTransformer.html#ae4a3532894dd265babf99765ca109dc6',1,'transformers.rename.RenameTransformer.visit_ImportFrom(self, ast.ImportFrom node)']]], + ['visit_5flistcomp_20',['visit_ListComp',['../classtransformers_1_1rename_1_1RenameTransformer.html#a6583f4eb358270431dda81d0d939162d',1,'transformers::rename::RenameTransformer']]], + ['visit_5fmethod_5fdef_21',['visit_method_def',['../classtransformers_1_1class__mapper_1_1ClassMapAnalyzer.html#a6bcd45016a2ae5cb4be6a3cb942bdf9d',1,'transformers::class_mapper::ClassMapAnalyzer']]], + ['visit_5fmodule_22',['visit_module',['../classtransformers_1_1rename_1_1RenameTransformer.html#af219e2b8032497024cf99f76578eea8b',1,'transformers.rename.RenameTransformer.visit_Module()'],['../classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#a5706641787b556edc011c99fc5233b01',1,'transformers.symbol_tree.SymbolTreeBuilder.visit_Module()']]], + ['visit_5fname_23',['visit_name',['../classtransformers_1_1rename_1_1RenameTransformer.html#a6ffe49f1216346f0727df849dae7163a',1,'transformers.rename.RenameTransformer.visit_Name()'],['../classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#add1ec41f47e2b9d45d01ddaa8848a846',1,'transformers.symbol_tree.SymbolTreeBuilder.visit_Name()']]], + ['visit_5freturn_24',['visit_Return',['../classtransformers_1_1control__flow_1_1ControlFlowFlattener.html#ae1e8400d54ec1b75fdc514cd1609120f',1,'transformers::control_flow::ControlFlowFlattener']]], + ['visit_5fsetcomp_25',['visit_SetComp',['../classtransformers_1_1rename_1_1RenameTransformer.html#a29d393746b1977c8181a439c51207bf1',1,'transformers::rename::RenameTransformer']]], + ['visit_5fsubscript_26',['visit_Subscript',['../classtransformers_1_1rename_1_1RenameTransformer.html#ab4fcef7ad6262e7595e449738e977a5d',1,'transformers::rename::RenameTransformer']]], + ['visit_5fwhile_27',['visit_While',['../classtransformers_1_1control__flow_1_1ControlFlowFlattener.html#aed99b58ddd8e19899955f356323d7a71',1,'transformers::control_flow::ControlFlowFlattener']]] +]; diff --git a/doxygen/search/functions_2.js b/doxygen/search/functions_2.js new file mode 100644 index 0000000..1969a34 --- /dev/null +++ b/doxygen/search/functions_2.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['build_5ftree_0',['build_tree',['../classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html#a32eb8339c1450dc3def80e5bc94974ee',1,'transformers::symbol_tree::SymbolTreeBuilder']]] +]; diff --git a/doxygen/search/functions_3.js b/doxygen/search/functions_3.js new file mode 100644 index 0000000..a4cd1af --- /dev/null +++ b/doxygen/search/functions_3.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['check_5ffor_5fissues_0',['check_for_issues',['../classtransformers_1_1symbol__tree_1_1SymbolTree.html#a5a585fa57a9f8fd224cf4d55b8180a78',1,'transformers::symbol_tree::SymbolTree']]] +]; diff --git a/doxygen/search/functions_4.js b/doxygen/search/functions_4.js new file mode 100644 index 0000000..22f3203 --- /dev/null +++ b/doxygen/search/functions_4.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['debug_5finfo_0',['debug_info',['../classtransformers_1_1class__mapper_1_1ClassMapping.html#a1fa5906a282c1ed833160badb1f674a2',1,'transformers::class_mapper::ClassMapping']]], + ['detect_5fissues_1',['detect_issues',['../classobfuscator_1_1AdvancedObfuscator.html#aa5653d0e597359d527b772223acb9c54',1,'obfuscator::AdvancedObfuscator']]] +]; diff --git a/doxygen/search/functions_5.js b/doxygen/search/functions_5.js new file mode 100644 index 0000000..f1647ff --- /dev/null +++ b/doxygen/search/functions_5.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['encrypt_5fstring_0',['encrypt_string',['../classutils_1_1encryption_1_1StringEncryptor.html#a6c2cacc40f85e399dee8e47e20f81739',1,'utils::encryption::StringEncryptor']]] +]; diff --git a/doxygen/search/functions_6.js b/doxygen/search/functions_6.js new file mode 100644 index 0000000..0fc5040 --- /dev/null +++ b/doxygen/search/functions_6.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['flatten_5fblocks_0',['flatten_blocks',['../classtransformers_1_1control__flow_1_1ControlFlowFlattener.html#af8cf7ecbaf8d1fdc4127dfecca51c022',1,'transformers::control_flow::ControlFlowFlattener']]] +]; diff --git a/doxygen/search/functions_7.js b/doxygen/search/functions_7.js new file mode 100644 index 0000000..b468faa --- /dev/null +++ b/doxygen/search/functions_7.js @@ -0,0 +1,9 @@ +var searchData= +[ + ['generate_5fjunk_0',['generate_junk',['../classutils_1_1junk__gen_1_1JunkGenerator.html#a0302efd5f4dda3da3c02280d9739d4d3',1,'utils::junk_gen::JunkGenerator']]], + ['generate_5fjunk_5fcode_1',['generate_junk_code',['../classtransformers_1_1control__flow_1_1ControlFlowFlattener.html#a4c787cc400a0a7ab154c09388e016946',1,'transformers::control_flow::ControlFlowFlattener']]], + ['generate_5fname_2',['generate_name',['../classutils_1_1name__gen_1_1NameGenerator.html#ac05b7a033f2ccb1a238b7e5e0877e2c6',1,'utils::name_gen::NameGenerator']]], + ['get_5fmethod_5fname_3',['get_method_name',['../namespacetransformers_1_1class__analyzer.html#a6b97dea989b6eb9d37b5d9b53fae3b6d',1,'transformers::class_analyzer']]], + ['get_5fqualified_5fname_4',['get_qualified_name',['../classtransformers_1_1symbol__tree_1_1Scope.html#a72bf2569e37369e3f845ac2441080a9d',1,'transformers::symbol_tree::Scope']]], + ['get_5frename_5fmapping_5',['get_rename_mapping',['../classtransformers_1_1symbol__tree_1_1SymbolTree.html#aad251f8dde7939c5194c6cfc4caf62a5',1,'transformers::symbol_tree::SymbolTree']]] +]; diff --git a/doxygen/search/functions_8.js b/doxygen/search/functions_8.js new file mode 100644 index 0000000..4bc71ef --- /dev/null +++ b/doxygen/search/functions_8.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['hide_5fbyte_0',['hide_byte',['../classutils_1_1encryption_1_1StringEncryptor.html#a182add66c3f8039da6f1accf0b52c3c3',1,'utils::encryption::StringEncryptor']]] +]; diff --git a/doxygen/search/functions_9.js b/doxygen/search/functions_9.js new file mode 100644 index 0000000..919ff5e --- /dev/null +++ b/doxygen/search/functions_9.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['log_5fdebug_0',['log_debug',['../classobfuscator_1_1AdvancedObfuscator.html#add2f1a570ef241ad62e977d434973ddf',1,'obfuscator.AdvancedObfuscator.log_debug()'],['../classtransformers_1_1control__flow_1_1ControlFlowFlattener.html#a53e89d0d92bb71c22e2721272c27c35c',1,'transformers.control_flow.ControlFlowFlattener.log_debug()'],['../classtransformers_1_1rename_1_1RenameTransformer.html#a0d8e460a12ba4bf74a95882aa6bb3835',1,'transformers.rename.RenameTransformer.log_debug()']]], + ['lookup_1',['lookup',['../classtransformers_1_1symbol__tree_1_1Scope.html#aea26fa0ade2ce3d7f82cf28a7fec0d16',1,'transformers::symbol_tree::Scope']]] +]; diff --git a/doxygen/search/functions_a.js b/doxygen/search/functions_a.js new file mode 100644 index 0000000..2879980 --- /dev/null +++ b/doxygen/search/functions_a.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['main_0',['main',['../namespacemain.html#a3140e9a5b6a71ffbf498198cfc471b88',1,'main']]] +]; diff --git a/doxygen/search/functions_b.js b/doxygen/search/functions_b.js new file mode 100644 index 0000000..dbaf5ec --- /dev/null +++ b/doxygen/search/functions_b.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['obfuscate_0',['obfuscate',['../classobfuscator_1_1AdvancedObfuscator.html#a0bae5229abba4f829e01b84cb9c9ffd7',1,'obfuscator::AdvancedObfuscator']]] +]; diff --git a/doxygen/search/functions_c.js b/doxygen/search/functions_c.js new file mode 100644 index 0000000..6684427 --- /dev/null +++ b/doxygen/search/functions_c.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['pop_5fscope_0',['pop_scope',['../classtransformers_1_1symbol__tree_1_1SymbolTree.html#ac3622dfd3cf0c24f591974f4daf542b7',1,'transformers::symbol_tree::SymbolTree']]], + ['push_5fscope_1',['push_scope',['../classtransformers_1_1symbol__tree_1_1SymbolTree.html#a552a46afd0e3e2eed55366a9d0b037b6',1,'transformers::symbol_tree::SymbolTree']]] +]; diff --git a/doxygen/search/functions_d.js b/doxygen/search/functions_d.js new file mode 100644 index 0000000..92d6efa --- /dev/null +++ b/doxygen/search/functions_d.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['resolve_5finheritance_0',['resolve_inheritance',['../classtransformers_1_1symbol__tree_1_1SymbolTree.html#af5a83401d437658d233d32f15071305c',1,'transformers::symbol_tree::SymbolTree']]] +]; diff --git a/doxygen/search/functions_e.js b/doxygen/search/functions_e.js new file mode 100644 index 0000000..c253ffe --- /dev/null +++ b/doxygen/search/functions_e.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['scan_5fclass_5fmethods_0',['scan_class_methods',['../classtransformers_1_1rename_1_1RenameTransformer.html#ab87d8148ef510b4803c4332deff663d5',1,'transformers::rename::RenameTransformer']]] +]; diff --git a/doxygen/search/functions_f.js b/doxygen/search/functions_f.js new file mode 100644 index 0000000..42ed3f7 --- /dev/null +++ b/doxygen/search/functions_f.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['update_5fobfuscator_5fwith_5fclass_5fmappings_0',['update_obfuscator_with_class_mappings',['../namespacetransformers_1_1class__analyzer.html#a33c650248422029fa53952d08e4da438',1,'transformers::class_analyzer']]] +]; diff --git a/doxygen/search/mag.svg b/doxygen/search/mag.svg new file mode 100644 index 0000000..ffb6cf0 --- /dev/null +++ b/doxygen/search/mag.svg @@ -0,0 +1,24 @@ + + + + + + + diff --git a/doxygen/search/mag_d.svg b/doxygen/search/mag_d.svg new file mode 100644 index 0000000..4122773 --- /dev/null +++ b/doxygen/search/mag_d.svg @@ -0,0 +1,24 @@ + + + + + + + diff --git a/doxygen/search/mag_sel.svg b/doxygen/search/mag_sel.svg new file mode 100644 index 0000000..553dba8 --- /dev/null +++ b/doxygen/search/mag_sel.svg @@ -0,0 +1,31 @@ + + + + + + + + + diff --git a/doxygen/search/mag_seld.svg b/doxygen/search/mag_seld.svg new file mode 100644 index 0000000..c906f84 --- /dev/null +++ b/doxygen/search/mag_seld.svg @@ -0,0 +1,31 @@ + + + + + + + + + diff --git a/doxygen/search/namespaces_0.js b/doxygen/search/namespaces_0.js new file mode 100644 index 0000000..7ccf739 --- /dev/null +++ b/doxygen/search/namespaces_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['main_0',['main',['../namespacemain.html',1,'']]] +]; diff --git a/doxygen/search/namespaces_1.js b/doxygen/search/namespaces_1.js new file mode 100644 index 0000000..1dd7de2 --- /dev/null +++ b/doxygen/search/namespaces_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['obfuscator_0',['obfuscator',['../namespaceobfuscator.html',1,'']]] +]; diff --git a/doxygen/search/namespaces_2.js b/doxygen/search/namespaces_2.js new file mode 100644 index 0000000..32686e6 --- /dev/null +++ b/doxygen/search/namespaces_2.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['transformers_0',['transformers',['../namespacetransformers.html',1,'']]], + ['transformers_3a_3aattribute_5ftransformer_1',['attribute_transformer',['../namespacetransformers_1_1attribute__transformer.html',1,'transformers']]], + ['transformers_3a_3aclass_5fanalyzer_2',['class_analyzer',['../namespacetransformers_1_1class__analyzer.html',1,'transformers']]], + ['transformers_3a_3aclass_5fmapper_3',['class_mapper',['../namespacetransformers_1_1class__mapper.html',1,'transformers']]], + ['transformers_3a_3acontrol_5fflow_4',['control_flow',['../namespacetransformers_1_1control__flow.html',1,'transformers']]], + ['transformers_3a_3arename_5',['rename',['../namespacetransformers_1_1rename.html',1,'transformers']]], + ['transformers_3a_3asymbol_5ftree_6',['symbol_tree',['../namespacetransformers_1_1symbol__tree.html',1,'transformers']]] +]; diff --git a/doxygen/search/namespaces_3.js b/doxygen/search/namespaces_3.js new file mode 100644 index 0000000..f3ce8c8 --- /dev/null +++ b/doxygen/search/namespaces_3.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['utils_0',['utils',['../namespaceutils.html',1,'']]], + ['utils_3a_3aencryption_1',['encryption',['../namespaceutils_1_1encryption.html',1,'utils']]], + ['utils_3a_3ajunk_5fgen_2',['junk_gen',['../namespaceutils_1_1junk__gen.html',1,'utils']]], + ['utils_3a_3aname_5fgen_3',['name_gen',['../namespaceutils_1_1name__gen.html',1,'utils']]] +]; diff --git a/doxygen/search/pages_0.js b/doxygen/search/pages_0.js new file mode 100644 index 0000000..0568757 --- /dev/null +++ b/doxygen/search/pages_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['fuscator_0',['OMG-Fuscator',['../index.html',1,'']]] +]; diff --git a/doxygen/search/pages_1.js b/doxygen/search/pages_1.js new file mode 100644 index 0000000..cb6a133 --- /dev/null +++ b/doxygen/search/pages_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['omg_20fuscator_0',['OMG-Fuscator',['../index.html',1,'']]] +]; diff --git a/doxygen/search/search.css b/doxygen/search/search.css new file mode 100644 index 0000000..19f76f9 --- /dev/null +++ b/doxygen/search/search.css @@ -0,0 +1,291 @@ +/*---------------- Search Box positioning */ + +#main-menu > li:last-child { + /* This
  • object is the parent of the search bar */ + display: flex; + justify-content: center; + align-items: center; + height: 36px; + margin-right: 1em; +} + +/*---------------- Search box styling */ + +.SRPage * { + font-weight: normal; + line-height: normal; +} + +dark-mode-toggle { + margin-left: 5px; + display: flex; + float: right; +} + +#MSearchBox { + display: inline-block; + white-space : nowrap; + background: var(--search-background-color); + border-radius: 0.65em; + box-shadow: var(--search-box-shadow); + z-index: 102; +} + +#MSearchBox .left { + display: inline-block; + vertical-align: middle; + height: 1.4em; +} + +#MSearchSelect { + display: inline-block; + vertical-align: middle; + width: 20px; + height: 19px; + background-image: var(--search-magnification-select-image); + margin: 0 0 0 0.3em; + padding: 0; +} + +#MSearchSelectExt { + display: inline-block; + vertical-align: middle; + width: 10px; + height: 19px; + background-image: var(--search-magnification-image); + margin: 0 0 0 0.5em; + padding: 0; +} + + +#MSearchField { + display: inline-block; + vertical-align: middle; + width: 7.5em; + height: 19px; + margin: 0 0.15em; + padding: 0; + line-height: 1em; + border:none; + color: var(--search-foreground-color); + outline: none; + font-family: var(--font-family-search); + -webkit-border-radius: 0px; + border-radius: 0px; + background: none; +} + +@media(hover: none) { + /* to avoid zooming on iOS */ + #MSearchField { + font-size: 16px; + } +} + +#MSearchBox .right { + display: inline-block; + vertical-align: middle; + width: 1.4em; + height: 1.4em; +} + +#MSearchClose { + display: none; + font-size: inherit; + background : none; + border: none; + margin: 0; + padding: 0; + outline: none; + +} + +#MSearchCloseImg { + padding: 0.3em; + margin: 0; +} + +.MSearchBoxActive #MSearchField { + color: var(--search-active-color); +} + + + +/*---------------- Search filter selection */ + +#MSearchSelectWindow { + display: none; + position: absolute; + left: 0; top: 0; + border: 1px solid var(--search-filter-border-color); + background-color: var(--search-filter-background-color); + z-index: 10001; + padding-top: 4px; + padding-bottom: 4px; + -moz-border-radius: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); +} + +.SelectItem { + font: 8pt var(--font-family-search); + padding-left: 2px; + padding-right: 12px; + border: 0px; +} + +span.SelectionMark { + margin-right: 4px; + font-family: var(--font-family-monospace); + outline-style: none; + text-decoration: none; +} + +a.SelectItem { + display: block; + outline-style: none; + color: var(--search-filter-foreground-color); + text-decoration: none; + padding-left: 6px; + padding-right: 12px; +} + +a.SelectItem:focus, +a.SelectItem:active { + color: var(--search-filter-foreground-color); + outline-style: none; + text-decoration: none; +} + +a.SelectItem:hover { + color: var(--search-filter-highlight-text-color); + background-color: var(--search-filter-highlight-bg-color); + outline-style: none; + text-decoration: none; + cursor: pointer; + display: block; +} + +/*---------------- Search results window */ + +iframe#MSearchResults { + /*width: 60ex;*/ + height: 15em; +} + +#MSearchResultsWindow { + display: none; + position: absolute; + left: 0; top: 0; + border: 1px solid var(--search-results-border-color); + background-color: var(--search-results-background-color); + z-index:10000; + width: 300px; + height: 400px; + overflow: auto; +} + +/* ----------------------------------- */ + + +#SRIndex { + clear:both; +} + +.SREntry { + font-size: 10pt; + padding-left: 1ex; +} + +.SRPage .SREntry { + font-size: 8pt; + padding: 1px 5px; +} + +div.SRPage { + margin: 5px 2px; + background-color: var(--search-results-background-color); +} + +.SRChildren { + padding-left: 3ex; padding-bottom: .5em +} + +.SRPage .SRChildren { + display: none; +} + +.SRSymbol { + font-weight: bold; + color: var(--search-results-foreground-color); + font-family: var(--font-family-search); + text-decoration: none; + outline: none; +} + +a.SRScope { + display: block; + color: var(--search-results-foreground-color); + font-family: var(--font-family-search); + font-size: 8pt; + text-decoration: none; + outline: none; +} + +a.SRSymbol:focus, a.SRSymbol:active, +a.SRScope:focus, a.SRScope:active { + text-decoration: underline; +} + +span.SRScope { + padding-left: 4px; + font-family: var(--font-family-search); +} + +.SRPage .SRStatus { + padding: 2px 5px; + font-size: 8pt; + font-style: italic; + font-family: var(--font-family-search); +} + +.SRResult { + display: none; +} + +div.searchresults { + margin-left: 10px; + margin-right: 10px; +} + +/*---------------- External search page results */ + +.pages b { + color: white; + padding: 5px 5px 3px 5px; + background-image: var(--nav-gradient-active-image-parent); + background-repeat: repeat-x; + text-shadow: 0 1px 1px #000000; +} + +.pages { + line-height: 17px; + margin-left: 4px; + text-decoration: none; +} + +.hl { + font-weight: bold; +} + +#searchresults { + margin-bottom: 20px; +} + +.searchpages { + margin-top: 10px; +} + diff --git a/doxygen/search/search.js b/doxygen/search/search.js new file mode 100644 index 0000000..6fd40c6 --- /dev/null +++ b/doxygen/search/search.js @@ -0,0 +1,840 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @licend The above is the entire license notice for the JavaScript code in this file + */ +function convertToId(search) +{ + var result = ''; + for (i=0;i do a search + { + this.Search(); + } + } + + this.OnSearchSelectKey = function(evt) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==40 && this.searchIndex0) // Up + { + this.searchIndex--; + this.OnSelectItem(this.searchIndex); + } + else if (e.keyCode==13 || e.keyCode==27) + { + e.stopPropagation(); + this.OnSelectItem(this.searchIndex); + this.CloseSelectionWindow(); + this.DOMSearchField().focus(); + } + return false; + } + + // --------- Actions + + // Closes the results window. + this.CloseResultsWindow = function() + { + this.DOMPopupSearchResultsWindow().style.display = 'none'; + this.DOMSearchClose().style.display = 'none'; + this.Activate(false); + } + + this.CloseSelectionWindow = function() + { + this.DOMSearchSelectWindow().style.display = 'none'; + } + + // Performs a search. + this.Search = function() + { + this.keyTimeout = 0; + + // strip leading whitespace + var searchValue = this.DOMSearchField().value.replace(/^ +/, ""); + + var code = searchValue.toLowerCase().charCodeAt(0); + var idxChar = searchValue.substr(0, 1).toLowerCase(); + if ( 0xD800 <= code && code <= 0xDBFF && searchValue > 1) // surrogate pair + { + idxChar = searchValue.substr(0, 2); + } + + var jsFile; + + var idx = indexSectionsWithContent[this.searchIndex].indexOf(idxChar); + if (idx!=-1) + { + var hexCode=idx.toString(16); + jsFile = this.resultsPath + indexSectionNames[this.searchIndex] + '_' + hexCode + '.js'; + } + + var loadJS = function(url, impl, loc){ + var scriptTag = document.createElement('script'); + scriptTag.src = url; + scriptTag.onload = impl; + scriptTag.onreadystatechange = impl; + loc.appendChild(scriptTag); + } + + var domPopupSearchResultsWindow = this.DOMPopupSearchResultsWindow(); + var domSearchBox = this.DOMSearchBox(); + var domPopupSearchResults = this.DOMPopupSearchResults(); + var domSearchClose = this.DOMSearchClose(); + var resultsPath = this.resultsPath; + + var handleResults = function() { + document.getElementById("Loading").style.display="none"; + if (typeof searchData !== 'undefined') { + createResults(resultsPath); + document.getElementById("NoMatches").style.display="none"; + } + + if (idx!=-1) { + searchResults.Search(searchValue); + } else { // no file with search results => force empty search results + searchResults.Search('===='); + } + + if (domPopupSearchResultsWindow.style.display!='block') + { + domSearchClose.style.display = 'inline-block'; + var left = getXPos(domSearchBox) + 150; + var top = getYPos(domSearchBox) + 20; + domPopupSearchResultsWindow.style.display = 'block'; + left -= domPopupSearchResults.offsetWidth; + var maxWidth = document.body.clientWidth; + var maxHeight = document.body.clientHeight; + var width = 300; + if (left<10) left=10; + if (width+left+8>maxWidth) width=maxWidth-left-8; + var height = 400; + if (height+top+8>maxHeight) height=maxHeight-top-8; + domPopupSearchResultsWindow.style.top = top + 'px'; + domPopupSearchResultsWindow.style.left = left + 'px'; + domPopupSearchResultsWindow.style.width = width + 'px'; + domPopupSearchResultsWindow.style.height = height + 'px'; + } + } + + if (jsFile) { + loadJS(jsFile, handleResults, this.DOMPopupSearchResultsWindow()); + } else { + handleResults(); + } + + this.lastSearchValue = searchValue; + } + + // -------- Activation Functions + + // Activates or deactivates the search panel, resetting things to + // their default values if necessary. + this.Activate = function(isActive) + { + if (isActive || // open it + this.DOMPopupSearchResultsWindow().style.display == 'block' + ) + { + this.DOMSearchBox().className = 'MSearchBoxActive'; + this.searchActive = true; + } + else if (!isActive) // directly remove the panel + { + this.DOMSearchBox().className = 'MSearchBoxInactive'; + this.searchActive = false; + this.lastSearchValue = '' + this.lastResultsPage = ''; + this.DOMSearchField().value = ''; + } + } +} + +// ----------------------------------------------------------------------- + +// The class that handles everything on the search results page. +function SearchResults(name) +{ + // The number of matches from the last run of . + this.lastMatchCount = 0; + this.lastKey = 0; + this.repeatOn = false; + + // Toggles the visibility of the passed element ID. + this.FindChildElement = function(id) + { + var parentElement = document.getElementById(id); + var element = parentElement.firstChild; + + while (element && element!=parentElement) + { + if (element.nodeName.toLowerCase() == 'div' && element.className == 'SRChildren') + { + return element; + } + + if (element.nodeName.toLowerCase() == 'div' && element.hasChildNodes()) + { + element = element.firstChild; + } + else if (element.nextSibling) + { + element = element.nextSibling; + } + else + { + do + { + element = element.parentNode; + } + while (element && element!=parentElement && !element.nextSibling); + + if (element && element!=parentElement) + { + element = element.nextSibling; + } + } + } + } + + this.Toggle = function(id) + { + var element = this.FindChildElement(id); + if (element) + { + if (element.style.display == 'block') + { + element.style.display = 'none'; + } + else + { + element.style.display = 'block'; + } + } + } + + // Searches for the passed string. If there is no parameter, + // it takes it from the URL query. + // + // Always returns true, since other documents may try to call it + // and that may or may not be possible. + this.Search = function(search) + { + if (!search) // get search word from URL + { + search = window.location.search; + search = search.substring(1); // Remove the leading '?' + search = unescape(search); + } + + search = search.replace(/^ +/, ""); // strip leading spaces + search = search.replace(/ +$/, ""); // strip trailing spaces + search = search.toLowerCase(); + search = convertToId(search); + + var resultRows = document.getElementsByTagName("div"); + var matches = 0; + + var i = 0; + while (i < resultRows.length) + { + var row = resultRows.item(i); + if (row.className == "SRResult") + { + var rowMatchName = row.id.toLowerCase(); + rowMatchName = rowMatchName.replace(/^sr\d*_/, ''); // strip 'sr123_' + + if (search.length<=rowMatchName.length && + rowMatchName.substr(0, search.length)==search) + { + row.style.display = 'block'; + matches++; + } + else + { + row.style.display = 'none'; + } + } + i++; + } + document.getElementById("Searching").style.display='none'; + if (matches == 0) // no results + { + document.getElementById("NoMatches").style.display='block'; + } + else // at least one result + { + document.getElementById("NoMatches").style.display='none'; + } + this.lastMatchCount = matches; + return true; + } + + // return the first item with index index or higher that is visible + this.NavNext = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index++; + } + return focusItem; + } + + this.NavPrev = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index--; + } + return focusItem; + } + + this.ProcessKeys = function(e) + { + if (e.type == "keydown") + { + this.repeatOn = false; + this.lastKey = e.keyCode; + } + else if (e.type == "keypress") + { + if (!this.repeatOn) + { + if (this.lastKey) this.repeatOn = true; + return false; // ignore first keypress after keydown + } + } + else if (e.type == "keyup") + { + this.lastKey = 0; + this.repeatOn = false; + } + return this.lastKey!=0; + } + + this.Nav = function(evt,itemIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + var newIndex = itemIndex-1; + var focusItem = this.NavPrev(newIndex); + if (focusItem) + { + var child = this.FindChildElement(focusItem.parentNode.parentNode.id); + if (child && child.style.display == 'block') // children visible + { + var n=0; + var tmpElem; + while (1) // search for last child + { + tmpElem = document.getElementById('Item'+newIndex+'_c'+n); + if (tmpElem) + { + focusItem = tmpElem; + } + else // found it! + { + break; + } + n++; + } + } + } + if (focusItem) + { + focusItem.focus(); + } + else // return focus to search field + { + document.getElementById("MSearchField").focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = itemIndex+1; + var focusItem; + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem && elem.style.display == 'block') // children visible + { + focusItem = document.getElementById('Item'+itemIndex+'_c0'); + } + if (!focusItem) focusItem = this.NavNext(newIndex); + if (focusItem) focusItem.focus(); + } + else if (this.lastKey==39) // Right + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'block'; + } + else if (this.lastKey==37) // Left + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'none'; + } + else if (this.lastKey==27) // Escape + { + e.stopPropagation(); + searchBox.CloseResultsWindow(); + document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } + + this.NavChild = function(evt,itemIndex,childIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + if (childIndex>0) + { + var newIndex = childIndex-1; + document.getElementById('Item'+itemIndex+'_c'+newIndex).focus(); + } + else // already at first child, jump to parent + { + document.getElementById('Item'+itemIndex).focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = childIndex+1; + var elem = document.getElementById('Item'+itemIndex+'_c'+newIndex); + if (!elem) // last child, jump to parent next parent + { + elem = this.NavNext(itemIndex+1); + } + if (elem) + { + elem.focus(); + } + } + else if (this.lastKey==27) // Escape + { + e.stopPropagation(); + searchBox.CloseResultsWindow(); + document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } +} + +function setKeyActions(elem,action) +{ + elem.setAttribute('onkeydown',action); + elem.setAttribute('onkeypress',action); + elem.setAttribute('onkeyup',action); +} + +function setClassAttr(elem,attr) +{ + elem.setAttribute('class',attr); + elem.setAttribute('className',attr); +} + +function createResults(resultsPath) +{ + var results = document.getElementById("SRResults"); + results.innerHTML = ''; + for (var e=0; e-{AmhX=Jf(#6djGiuzAr*{o?=JLmPLyc> z_*`QK&+BH@jWrYJ7>r6%keRM@)Qyv8R=enp0jiI>aWlGyB58O zFVR20d+y`K7vDw(hJF3;>dD*3-?v=<8M)@x|EEGLnJsniYK!2U1 Y!`|5biEc?d1`HDhPgg&ebxsLQ02F6;9RL6T literal 0 HcmV?d00001 diff --git a/doxygen/splitbard.png b/doxygen/splitbard.png new file mode 100644 index 0000000000000000000000000000000000000000..8367416d757fd7b6dc4272b6432dc75a75abd068 GIT binary patch literal 282 zcmeAS@N?(olHy`uVBq!ia0vp^Yzz!63>-{AmhX=Jf@VhhFKy35^fiT zT~&lUj3=cDh^%3HDY9k5CEku}PHXNoNC(_$U3XPb&Q*ME25pT;2(*BOgAf<+R$lzakPG`kF31()Fx{L5Wrac|GQzjeE= zueY1`Ze{#x<8=S|`~MgGetGce)#vN&|J{Cd^tS%;tBYTo?+^d68<#n_Y_xx`J||4O V@QB{^CqU0Kc)I$ztaD0e0svEzbJzd? literal 0 HcmV?d00001 diff --git a/doxygen/symbol__tree_8py.html b/doxygen/symbol__tree_8py.html new file mode 100644 index 0000000..363fd95 --- /dev/null +++ b/doxygen/symbol__tree_8py.html @@ -0,0 +1,144 @@ + + + + + + + +OMG-Fuscator: symbol_tree.py File Reference + + + + + + + + + + + + + +
    +
    + + + + + + +
    +
    OMG-Fuscator +
    +
    Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
    +
    +
    + + + + + + + +
    +
    + +
    +
    +
    + +
    + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + +
    + +
    symbol_tree.py File Reference
    +
    + +
    + + + + diff --git a/doxygen/symbol__tree_8py.js b/doxygen/symbol__tree_8py.js new file mode 100644 index 0000000..e851d80 --- /dev/null +++ b/doxygen/symbol__tree_8py.js @@ -0,0 +1,12 @@ +var symbol__tree_8py = +[ + [ "transformers.symbol_tree.ClassScope", "classtransformers_1_1symbol__tree_1_1ClassScope.html", "classtransformers_1_1symbol__tree_1_1ClassScope" ], + [ "transformers.symbol_tree.ModuleScope", "classtransformers_1_1symbol__tree_1_1ModuleScope.html", "classtransformers_1_1symbol__tree_1_1ModuleScope" ], + [ "transformers.symbol_tree.Scope", "classtransformers_1_1symbol__tree_1_1Scope.html", "classtransformers_1_1symbol__tree_1_1Scope" ], + [ "transformers.symbol_tree.Symbol", "classtransformers_1_1symbol__tree_1_1Symbol.html", "classtransformers_1_1symbol__tree_1_1Symbol" ], + [ "transformers.symbol_tree.SymbolTree", "classtransformers_1_1symbol__tree_1_1SymbolTree.html", "classtransformers_1_1symbol__tree_1_1SymbolTree" ], + [ "transformers.symbol_tree.SymbolTreeBuilder", "classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder.html", "classtransformers_1_1symbol__tree_1_1SymbolTreeBuilder" ], + [ "transformers.symbol_tree.SymbolType", "classtransformers_1_1symbol__tree_1_1SymbolType.html", "classtransformers_1_1symbol__tree_1_1SymbolType" ], + [ "level", "symbol__tree_8py.html#a6dfa45a6fa455a60c68cd968e9da90b5", null ], + [ "logger", "symbol__tree_8py.html#acff3629ca6817ec50dfe5bdc75f58745", null ] +]; \ No newline at end of file diff --git a/doxygen/symbol__tree_8py_source.html b/doxygen/symbol__tree_8py_source.html new file mode 100644 index 0000000..c0ae094 --- /dev/null +++ b/doxygen/symbol__tree_8py_source.html @@ -0,0 +1,816 @@ + + + + + + + +OMG-Fuscator: symbol_tree.py Source File + + + + + + + + + + + + + +
    +
    + + + + + + +
    +
    OMG-Fuscator +
    +
    Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
    +
    +
    + + + + + + + + +
    +
    + +
    +
    +
    + +
    + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + +
    +
    symbol_tree.py
    +
    +
    +Go to the documentation of this file.
    1"""
    +
    2@file transformers/symbol_tree.py
    +
    3@brief Global symbol tree and scope tracking.
    +
    4@details Builds a hierarchical representation of scopes (module, class, function),
    +
    5 tracks symbols, imports, references, and inheritance; generates rename
    +
    6 mappings consumed by the obfuscation pipeline.
    +
    7"""
    +
    8import ast
    +
    9from typing import Dict, Set, List, Optional, Union, Tuple
    +
    10import logging
    +
    11from enum import Enum
    +
    12
    +
    13# Configure logging
    +
    14logging.basicConfig(level=logging.INFO)
    +
    15logger = logging.getLogger("SymbolTree")
    +
    16
    +
    17
    +
    +
    18class SymbolType(Enum):
    +
    19 """Defines the different types of symbols that can be tracked."""
    +
    20 VARIABLE = "variable"
    +
    21 FUNCTION = "function"
    +
    22 CLASS = "class"
    +
    23 METHOD = "method"
    +
    24 ARGUMENT = "argument"
    +
    25 ATTRIBUTE = "attribute"
    +
    26 MODULE = "module"
    +
    27 IMPORT = "import"
    +
    28
    +
    29
    +
    +
    +
    30class Symbol:
    +
    31 """Represents a symbol in the code with its name, type and other metadata."""
    +
    32
    +
    +
    33 def __init__(self, name: str, symbol_type: SymbolType, node: ast.AST = None):
    +
    34 self.name = name # Original name
    +
    35 self.obfuscated_name: Optional[str] = None # Obfuscated name (if assigned)
    +
    36 self.symbol_type = symbol_type
    +
    37 self.node = node # AST node where this symbol is defined
    +
    38 self.references: List[ast.AST] = [] # AST nodes where this symbol is referenced
    +
    39 self.parent: Optional['Scope'] = None # Parent scope
    +
    40 self.is_obfuscatable = True # Whether this symbol should be obfuscated
    +
    41
    +
    42 # Additional attributes for specific symbol types
    +
    43 self.is_imported = False # Whether this symbol was imported
    +
    44 self.original_module: Optional[str] = None # If imported, the module it was imported from
    +
    45
    +
    +
    +
    46 def add_reference(self, node: ast.AST):
    +
    47 """Add a reference to this symbol."""
    +
    48 self.references.append(node)
    +
    49
    +
    +
    +
    50 def __repr__(self):
    +
    51 return f"<Symbol {self.name} [{self.symbol_type.value}] {'→ ' + self.obfuscated_name if self.obfuscated_name else ''} refs:{len(self.references)}>"
    +
    52
    +
    53
    +
    +
    +
    +
    54class Scope:
    +
    55 """
    +
    56 Represents a scope in the code, such as a module, function, class, or comprehension.
    +
    57 """
    +
    +
    58 def __init__(self, name: str, scope_type: str, node: ast.AST = None):
    +
    59 self.name = name
    +
    60 self.scope_type = scope_type
    +
    61 self.node = node
    +
    62
    +
    63 # Maps: symbol name -> Symbol object
    +
    64 self.symbols: Dict[str, Symbol] = {}
    +
    65
    +
    66 # Child scopes within this scope
    +
    67 self.children: List['Scope'] = []
    +
    68
    +
    69 # Parent scope (None for the global/module scope)
    +
    70 self.parent: Optional['Scope'] = None
    +
    71
    +
    +
    +
    72 def add_symbol(self, symbol: Symbol) -> Symbol:
    +
    73 """Add a symbol to this scope and return it."""
    +
    74 self.symbols[symbol.name] = symbol
    +
    75 symbol.parent = self
    +
    76 return symbol
    +
    77
    +
    +
    +
    78 def add_child_scope(self, scope: 'Scope') -> 'Scope':
    +
    79 """Add a child scope to this scope and return it."""
    +
    80 self.children.append(scope)
    +
    81 scope.parent = self
    +
    82 return scope
    +
    83
    +
    +
    +
    84 def lookup(self, name: str) -> Optional[Symbol]:
    +
    85 """Look up a symbol in this scope, or in parent scopes."""
    +
    86 if name in self.symbols:
    +
    87 return self.symbols[name]
    +
    88 elif self.parent:
    +
    89 return self.parent.lookup(name)
    +
    90 return None
    +
    91
    +
    +
    +
    92 def get_qualified_name(self) -> str:
    +
    93 """Get the fully qualified name of this scope."""
    +
    94 if self.parent and self.parent.name:
    +
    95 return f"{self.parent.get_qualified_name()}.{self.name}"
    +
    96 return self.name
    +
    97
    +
    +
    +
    98 def __repr__(self):
    +
    99 return f"<Scope {self.get_qualified_name()} [{self.scope_type}] symbols:{len(self.symbols)} children:{len(self.children)}>"
    +
    100
    +
    101
    +
    +
    +
    + +
    103 """A specialized scope for classes with additional tracking for inheritance."""
    +
    104
    +
    +
    105 def __init__(self, name: str, node: ast.ClassDef):
    +
    106 super().__init__(name, "class", node)
    +
    107 self.base_classes: List[str] = [] # Names of base classes
    +
    108 self.methods: Dict[str, Symbol] = {} # Methods defined in this class
    +
    109 self.attributes: Dict[str, Symbol] = {} # Attributes defined in this class
    +
    110
    +
    +
    +
    111 def add_base_class(self, base_name: str):
    +
    112 """Add a base class to this class's inheritance list."""
    +
    113 if base_name not in self.base_classes:
    +
    114 self.base_classes.append(base_name)
    +
    115
    +
    +
    +
    116 def add_method(self, method: Symbol) -> Symbol:
    +
    117 """Add a method to this class."""
    +
    118 self.methods[method.name] = method
    +
    119 return self.add_symbol(method)
    +
    120
    +
    +
    +
    121 def add_attribute(self, attr: Symbol) -> Symbol:
    +
    122 """Add an attribute to this class."""
    +
    123 self.attributes[attr.name] = attr
    +
    124 return self.add_symbol(attr)
    +
    125
    +
    126
    +
    +
    +
    + +
    128 """A specialized scope for modules with additional tracking for imports."""
    +
    129
    +
    +
    130 def __init__(self, name: str, node: ast.Module):
    +
    131 super().__init__(name, "module", node)
    +
    132 self.imports: Dict[str, str] = {} # Import alias -> original name
    +
    133 self.from_imports: Dict[str, Dict[str, str]] = {} # Module -> {alias -> original name}
    +
    134
    +
    +
    +
    135 def add_import(self, alias: str, original: str):
    +
    136 """Add an import to this module."""
    +
    137 self.imports[alias] = original
    +
    138
    +
    +
    +
    139 def add_from_import(self, module: str, alias: str, original: str):
    +
    140 """Add a from-import to this module."""
    +
    141 if module not in self.from_imports:
    +
    142 self.from_imports[module] = {}
    +
    143 self.from_imports[module][alias] = original
    +
    144
    +
    145
    +
    +
    +
    + +
    147 """
    +
    148 Global symbol tree that maintains a hierarchy of scopes and symbols
    +
    149 across the entire codebase.
    +
    150 """
    +
    151
    +
    +
    152 def __init__(self):
    +
    153 # The root scope is a special module scope named "__root__"
    +
    154 self.root_scope = ModuleScope("__root__", None)
    +
    155 # Current scope being processed
    + +
    157 # Track classes for inheritance resolution
    +
    158 self.classes: Dict[str, ClassScope] = {}
    +
    159 # Track all symbols by their fully qualified name
    +
    160 self.all_symbols: Dict[str, Symbol] = {}
    +
    161 # Track imports for proper resolution
    +
    162 self.imports: Dict[str, str] = {} # alias -> module
    +
    163
    +
    +
    +
    164 def push_scope(self, name: str, scope_type: str, node: ast.AST) -> Scope:
    +
    165 """Create a new scope and make it the current scope."""
    +
    166 if scope_type == "class":
    +
    167 new_scope = ClassScope(name, node)
    +
    168 elif scope_type == "module":
    +
    169 new_scope = ModuleScope(name, node)
    +
    170 else:
    +
    171 new_scope = Scope(name, scope_type, node)
    +
    172
    +
    173 self.current_scope.add_child_scope(new_scope)
    +
    174 self.current_scope = new_scope
    +
    175
    +
    176 # If this is a class, track it
    +
    177 if scope_type == "class":
    +
    178 fully_qualified = new_scope.get_qualified_name()
    +
    179 self.classes[fully_qualified] = new_scope
    +
    180 # Also track with just the class name for simpler lookups
    +
    181 self.classes[name] = new_scope
    +
    182
    +
    183 return new_scope
    +
    184
    +
    +
    +
    185 def pop_scope(self) -> Scope:
    +
    186 """Exit the current scope and return to its parent."""
    +
    187 old_scope = self.current_scope
    +
    188 if self.current_scope.parent:
    +
    189 self.current_scope = self.current_scope.parent
    +
    190 return old_scope
    +
    191
    +
    +
    +
    192 def add_symbol(self, name: str, symbol_type: SymbolType, node: ast.AST = None) -> Symbol:
    +
    193 """Add a symbol to the current scope."""
    +
    194 symbol = Symbol(name, symbol_type, node)
    +
    195 self.current_scope.add_symbol(symbol)
    +
    196
    +
    197 # Track in the global map
    +
    198 qualified_name = f"{self.current_scope.get_qualified_name()}.{name}"
    +
    199 self.all_symbols[qualified_name] = symbol
    +
    200
    +
    201 # If this is a method in a class scope
    +
    202 if symbol_type == SymbolType.METHOD and isinstance(self.current_scope, ClassScope):
    +
    203 self.current_scope.add_method(symbol)
    +
    204 # If this is an attribute in a class scope
    +
    205 elif symbol_type == SymbolType.ATTRIBUTE and isinstance(self.current_scope, ClassScope):
    +
    206 self.current_scope.add_attribute(symbol)
    +
    207
    +
    208 return symbol
    +
    209
    +
    +
    +
    210 def add_reference(self, name: str, node: ast.AST):
    +
    211 """Add a reference to a symbol."""
    +
    212 symbol = self.current_scope.lookup(name)
    +
    213 if symbol:
    +
    214 symbol.add_reference(node)
    +
    215
    +
    +
    + +
    217 """
    +
    218 Resolve inheritance relationships between classes to ensure
    +
    219 consistent method and attribute renaming.
    +
    220 """
    +
    221 def resolve_class(class_scope: ClassScope, visited=None):
    +
    222 if visited is None:
    +
    223 visited = set()
    +
    224
    +
    225 # Skip if already visited to prevent infinite recursion
    +
    226 if class_scope.name in visited:
    +
    227 return
    +
    228 visited.add(class_scope.name)
    +
    229
    +
    230 # Process each base class
    +
    231 for base_name in class_scope.base_classes:
    +
    232 # Skip if the base class is not in our tree (e.g., external library)
    +
    233 if base_name not in self.classes:
    +
    234 continue
    +
    235
    +
    236 base_scope = self.classes[base_name]
    +
    237 # Resolve the base class first
    +
    238 resolve_class(base_scope, visited)
    +
    239
    +
    240 # Copy method symbols from base to derived if not overridden
    +
    241 for method_name, method_symbol in base_scope.methods.items():
    +
    242 if method_name not in class_scope.methods:
    +
    243 # Create a new symbol in the derived class that references the base class method
    +
    244 derived_method = Symbol(method_name, SymbolType.METHOD)
    +
    245 class_scope.add_method(derived_method)
    +
    246
    +
    247 # Use the same obfuscated name as the base class method
    +
    248 # (even if the base class method hasn't been obfuscated yet)
    +
    249 derived_method.obfuscated_name = method_symbol.obfuscated_name
    +
    250
    +
    251 # Process all classes
    +
    252 for class_scope in self.classes.values():
    +
    253 resolve_class(class_scope)
    +
    254
    +
    +
    +
    255 def check_for_issues(self) -> List[Dict]:
    +
    256 """Check for potential issues in the symbol tree."""
    +
    257 issues = []
    +
    258
    +
    259 # Check for duplicated obfuscated names
    +
    260 obfuscated_names = {}
    +
    261 for qualified_name, symbol in self.all_symbols.items():
    +
    262 if not symbol.obfuscated_name:
    +
    263 continue
    +
    264
    +
    265 if symbol.obfuscated_name in obfuscated_names:
    +
    266 issues.append({
    +
    267 "type": "duplicate_obfuscated_name",
    +
    268 "obfuscated_name": symbol.obfuscated_name,
    +
    269 "symbols": [qualified_name, obfuscated_names[symbol.obfuscated_name]]
    +
    270 })
    +
    271 else:
    +
    272 obfuscated_names[symbol.obfuscated_name] = qualified_name
    +
    273
    +
    274 # Check for inconsistent method obfuscation in inheritance hierarchies
    +
    275 for class_name, class_scope in self.classes.items():
    +
    276 for base_name in class_scope.base_classes:
    +
    277 if base_name not in self.classes:
    +
    278 continue
    +
    279
    +
    280 base_scope = self.classes[base_name]
    +
    281 for method_name, method_symbol in base_scope.methods.items():
    +
    282 if method_name in class_scope.methods:
    +
    283 derived_method = class_scope.methods[method_name]
    +
    284 if (method_symbol.obfuscated_name and derived_method.obfuscated_name and
    +
    285 method_symbol.obfuscated_name != derived_method.obfuscated_name):
    +
    286 issues.append({
    +
    287 "type": "inconsistent_method_obfuscation",
    +
    288 "method_name": method_name,
    +
    289 "base_class": base_name,
    +
    290 "derived_class": class_name,
    +
    291 "base_obfuscated": method_symbol.obfuscated_name,
    +
    292 "derived_obfuscated": derived_method.obfuscated_name
    +
    293 })
    +
    294
    +
    295 return issues
    +
    296
    +
    +
    +
    297 def apply_name_generator(self, name_generator):
    +
    298 """
    +
    299 Apply a name generator to all symbols that need obfuscation.
    +
    300 Ensures consistent renaming across the entire codebase.
    +
    301 """
    +
    302 # First, handle classes
    +
    303 for class_scope in self.classes.values():
    +
    304 class_symbol = self.current_scope.lookup(class_scope.name)
    +
    305 if class_symbol and class_symbol.is_obfuscatable:
    +
    306 class_symbol.obfuscated_name = name_generator.generate_name()
    +
    307
    +
    308 # Then handle methods to ensure consistency across inheritance
    + +
    310
    +
    311 # Apply to all other symbols
    +
    312 for symbol in self.all_symbols.values():
    +
    313 # Skip if already obfuscated or not obfuscatable
    +
    314 if symbol.obfuscated_name or not symbol.is_obfuscatable:
    +
    315 continue
    +
    316
    +
    317 # Skip special names
    +
    318 if symbol.name.startswith("__") and symbol.name.endswith("__"):
    +
    319 continue
    +
    320
    +
    321 symbol.obfuscated_name = name_generator.generate_name()
    +
    322
    +
    +
    +
    323 def get_rename_mapping(self) -> Dict[str, Dict[str, str]]:
    +
    324 """
    +
    325 Get a mapping for all symbols to their obfuscated names,
    +
    326 organized by symbol type for use in transformers.
    +
    327 """
    +
    328 mapping = {
    +
    329 "variables": {},
    +
    330 "functions": {},
    +
    331 "classes": {},
    +
    332 "methods": {},
    +
    333 "attributes": {}
    +
    334 }
    +
    335
    +
    336 for symbol in self.all_symbols.values():
    +
    337 if not symbol.obfuscated_name:
    +
    338 continue
    +
    339
    +
    340 if symbol.symbol_type == SymbolType.VARIABLE:
    +
    341 mapping["variables"][symbol.name] = symbol.obfuscated_name
    +
    342 elif symbol.symbol_type == SymbolType.FUNCTION:
    +
    343 mapping["functions"][symbol.name] = symbol.obfuscated_name
    +
    344 elif symbol.symbol_type == SymbolType.CLASS:
    +
    345 mapping["classes"][symbol.name] = symbol.obfuscated_name
    +
    346 elif symbol.symbol_type == SymbolType.METHOD:
    +
    347 # For methods, we need the class name
    +
    348 if isinstance(symbol.parent, ClassScope):
    +
    349 class_name = symbol.parent.name
    +
    350 if class_name not in mapping["methods"]:
    +
    351 mapping["methods"][class_name] = {}
    +
    352 mapping["methods"][class_name][symbol.name] = symbol.obfuscated_name
    +
    353 elif symbol.symbol_type == SymbolType.ATTRIBUTE:
    +
    354 # For attributes, we need the class name
    +
    355 if isinstance(symbol.parent, ClassScope):
    +
    356 class_name = symbol.parent.name
    +
    357 if class_name not in mapping["attributes"]:
    +
    358 mapping["attributes"][class_name] = {}
    +
    359 mapping["attributes"][class_name][symbol.name] = symbol.obfuscated_name
    +
    360
    +
    361 return mapping
    +
    362
    +
    363
    +
    +
    +
    +
    364class SymbolTreeBuilder(ast.NodeVisitor):
    +
    365 """
    +
    366 Builds a symbol tree by visiting all nodes in the AST.
    +
    367 """
    +
    368
    +
    +
    369 def __init__(self):
    + +
    371
    +
    372 # Track whether we're in a class definition
    +
    373 self.in_class_def = False
    +
    374 self.current_class = None
    +
    375
    +
    376 # Track function augments to avoid creating symbols for them twice
    + +
    378
    +
    379 # Track whether we're in an attribute context
    +
    380 self.in_attribute_ctx = False
    +
    381
    +
    +
    +
    382 def visit_Module(self, node: ast.Module):
    +
    383 """Process a module node."""
    +
    384 self.tree.push_scope("__main__", "module", node)
    +
    385 # Visit all statements in the module
    +
    386 for stmt in node.body:
    +
    387 self.visit(stmt)
    +
    388 self.tree.pop_scope()
    +
    389
    +
    +
    +
    390 def visit_ClassDef(self, node: ast.ClassDef):
    +
    391 """Process a class definition."""
    +
    392 # Create a new class scope
    +
    393 class_scope = self.tree.push_scope(node.name, "class", node)
    +
    394
    +
    395 # Add class to current scope's symbols
    +
    396 self.tree.add_symbol(node.name, SymbolType.CLASS, node)
    +
    397
    +
    398 # Track base classes
    +
    399 for base in node.bases:
    +
    400 if isinstance(base, ast.Name):
    +
    401 class_scope.add_base_class(base.id)
    +
    402 # Track reference to the base class
    +
    403 self.tree.add_reference(base.id, base)
    +
    404
    +
    405 # Save previous state and update current state
    +
    406 prev_in_class = self.in_class_def
    +
    407 prev_class = self.current_class
    +
    408 self.in_class_def = True
    +
    409 self.current_class = node.name
    +
    410
    +
    411 # Visit class body
    +
    412 for item in node.body:
    +
    413 self.visit(item)
    +
    414
    +
    415 # Restore previous state
    +
    416 self.in_class_def = prev_in_class
    +
    417 self.current_class = prev_class
    +
    418
    +
    419 # Exit class scope
    +
    420 self.tree.pop_scope()
    +
    421
    +
    +
    +
    422 def visit_FunctionDef(self, node: ast.FunctionDef):
    +
    423 """Process a function definition."""
    +
    424 # Determine if this is a method or a regular function
    +
    425 symbol_type = SymbolType.METHOD if self.in_class_def else SymbolType.FUNCTION
    +
    426
    +
    427 # Add function/method to current scope's symbols
    +
    428 self.tree.add_symbol(node.name, symbol_type, node)
    +
    429
    +
    430 # Create a new function scope
    +
    431 self.tree.push_scope(node.name, "function", node)
    +
    432
    +
    433 # Clear current function arguments set
    +
    434 self.current_function_args = set()
    +
    435
    +
    436 # Process arguments
    +
    437 self.visit(node.args)
    +
    438
    +
    439 # Visit function body
    +
    440 for item in node.body:
    +
    441 self.visit(item)
    +
    442
    +
    443 # Exit function scope
    +
    444 self.tree.pop_scope()
    +
    445
    +
    +
    +
    446 def visit_arguments(self, node: ast.arguments):
    +
    447 """Process function arguments."""
    +
    448 # Process positional arguments
    +
    449 for arg in node.args:
    +
    450 self.current_function_args.add(arg.arg)
    +
    451 self.tree.add_symbol(arg.arg, SymbolType.ARGUMENT, arg)
    +
    452
    +
    453 # Process vararg (e.g., *args)
    +
    454 if node.vararg:
    +
    455 self.current_function_args.add(node.vararg.arg)
    +
    456 self.tree.add_symbol(node.vararg.arg, SymbolType.ARGUMENT, node.vararg)
    +
    457
    +
    458 # Process keyword arguments
    +
    459 for kwarg in node.kwonlyargs:
    +
    460 self.current_function_args.add(kwarg.arg)
    +
    461 self.tree.add_symbol(kwarg.arg, SymbolType.ARGUMENT, kwarg)
    +
    462
    +
    463 # Process kwarg (e.g., **kwargs)
    +
    464 if node.kwarg:
    +
    465 self.current_function_args.add(node.kwarg.arg)
    +
    466 self.tree.add_symbol(node.kwarg.arg, SymbolType.ARGUMENT, node.kwarg)
    +
    467
    +
    +
    +
    468 def visit_Assign(self, node: ast.Assign):
    +
    469 """Process an assignment statement."""
    +
    470 # Visit the right side first to capture any variable references
    +
    471 self.visit(node.value)
    +
    472
    +
    473 # Now visit the targets (left-hand side)
    +
    474 for target in node.targets:
    +
    475 # Handle attribute assignment (e.g., self.x = value)
    +
    476 if isinstance(target, ast.Attribute):
    +
    477 self.visit_attribute_assignment(target)
    +
    478 # Handle simple name assignment
    +
    479 elif isinstance(target, ast.Name):
    +
    480 # Only add symbol if it's not already a function argument
    +
    481 if target.id not in self.current_function_args:
    +
    482 self.tree.add_symbol(target.id, SymbolType.VARIABLE, target)
    +
    483 # Handle other target types (e.g., subscripts, tuples)
    +
    484 else:
    +
    485 self.visit(target)
    +
    486
    +
    +
    +
    487 def visit_attribute_assignment(self, node: ast.Attribute):
    +
    488 """Process attribute assignment (e.g., self.x = value)."""
    +
    489 # Check if this is a self.attr assignment in a class
    +
    490 if (isinstance(node.value, ast.Name) and node.value.id == 'self'
    +
    491 and self.in_class_def and self.current_class):
    +
    492 # Add attribute to the current class
    +
    493 self.tree.add_symbol(node.attr, SymbolType.ATTRIBUTE, node)
    +
    494 else:
    +
    495 # Visit the left side to capture any variable references
    +
    496 self.visit(node.value)
    +
    497
    +
    +
    +
    498 def visit_Name(self, node: ast.Name):
    +
    499 """Process a name (variable reference)."""
    +
    500 # This is a variable/function/class reference, not a definition
    +
    501 if isinstance(node.ctx, ast.Load):
    +
    502 self.tree.add_reference(node.id, node)
    +
    503
    +
    +
    +
    504 def visit_Attribute(self, node: ast.Attribute):
    +
    505 """Process attribute access (e.g., obj.attr)."""
    +
    506 # Track that we're in an attribute context
    +
    507 prev_in_attribute_ctx = self.in_attribute_ctx
    +
    508 self.in_attribute_ctx = True
    +
    509
    +
    510 # Visit the left side
    +
    511 self.visit(node.value)
    +
    512
    +
    513 # Handle self.attr access in a class
    +
    514 if (isinstance(node.value, ast.Name) and node.value.id == 'self'
    +
    515 and self.in_class_def and self.current_class):
    +
    516 # The attribute might be accessed before it's assigned, so we need to ensure it's in the symbol table
    +
    517 class_scope = self.tree.classes.get(self.current_class)
    +
    518 if class_scope and node.attr not in class_scope.attributes:
    +
    519 self.tree.add_symbol(node.attr, SymbolType.ATTRIBUTE, node)
    +
    520
    +
    521 # Restore previous state
    +
    522 self.in_attribute_ctx = prev_in_attribute_ctx
    +
    523
    +
    +
    +
    524 def visit_Import(self, node: ast.Import):
    +
    525 """Process an import statement."""
    +
    526 for item in node.names:
    +
    527 # The imported name should not be obfuscated
    +
    528 symbol = self.tree.add_symbol(item.asname or item.name, SymbolType.IMPORT, node)
    +
    529 symbol.is_obfuscatable = False
    +
    530 symbol.is_imported = True
    +
    531
    +
    532 # Track the import
    +
    533 if isinstance(self.tree.current_scope, ModuleScope):
    +
    534 module_scope = self.tree.current_scope
    +
    535 module_scope.add_import(item.asname or item.name, item.name)
    +
    536
    +
    +
    +
    537 def visit_ImportFrom(self, node: ast.ImportFrom):
    +
    538 """Process a from-import statement."""
    +
    539 for item in node.names:
    +
    540 # The imported name should not be obfuscated
    +
    541 symbol = self.tree.add_symbol(item.asname or item.name, SymbolType.IMPORT, node)
    +
    542 symbol.is_obfuscatable = False
    +
    543 symbol.is_imported = True
    +
    544 symbol.original_module = node.module
    +
    545
    +
    546 # Track the import
    +
    547 if isinstance(self.tree.current_scope, ModuleScope):
    +
    548 module_scope = self.tree.current_scope
    +
    549 module_scope.add_from_import(node.module, item.asname or item.name, item.name)
    +
    550
    +
    +
    551 # Add more visit methods for other AST node types as needed
    +
    552
    +
    +
    553 def build_tree(self, tree: ast.AST) -> SymbolTree:
    +
    554 """Build the symbol tree from the AST."""
    +
    555 self.visit(tree)
    +
    556 # Perform final processing
    +
    557 self.tree.resolve_inheritance()
    +
    558 return self.tree
    +
    +
    + +
    Symbol add_attribute(self, Symbol attr)
    +
    __init__(self, str name, ast.ClassDef node)
    +
    add_base_class(self, str base_name)
    +
    Symbol add_method(self, Symbol method)
    + +
    __init__(self, str name, ast.Module node)
    +
    add_from_import(self, str module, str alias, str original)
    +
    add_import(self, str alias, str original)
    + +
    'Scope' add_child_scope(self, 'Scope' scope)
    +
    __init__(self, str name, str scope_type, ast.AST node=None)
    + + + +
    Symbol add_symbol(self, Symbol symbol)
    +
    Optional[Symbol] lookup(self, str name)
    + + + + + +
    SymbolTree build_tree(self, ast.AST tree)
    +
    visit_attribute_assignment(self, ast.Attribute node)
    +
    visit_Attribute(self, ast.Attribute node)
    +
    visit_FunctionDef(self, ast.FunctionDef node)
    +
    visit_arguments(self, ast.arguments node)
    + + + +
    visit_ClassDef(self, ast.ClassDef node)
    + + + +
    visit_ImportFrom(self, ast.ImportFrom node)
    + + + +
    Symbol add_symbol(self, str name, SymbolType symbol_type, ast.AST node=None)
    +
    Scope push_scope(self, str name, str scope_type, ast.AST node)
    + + +
    Dict[str, Dict[str, str]] get_rename_mapping(self)
    +
    apply_name_generator(self, name_generator)
    +
    add_reference(self, str name, ast.AST node)
    + + + + + + +
    __init__(self, str name, SymbolType symbol_type, ast.AST node=None)
    + +
    add_reference(self, ast.AST node)
    + + + + + +
    +
    + + + + diff --git a/doxygen/sync_off.png b/doxygen/sync_off.png new file mode 100644 index 0000000000000000000000000000000000000000..3b443fc62892114406e3d399421b2a881b897acc GIT binary patch literal 853 zcmV-b1FHOqP)oT|#XixUYy%lpuf3i8{fX!o zUyDD0jOrAiT^tq>fLSOOABs-#u{dV^F$b{L9&!2=9&RmV;;8s^x&UqB$PCj4FdKbh zoB1WTskPUPu05XzFbA}=KZ-GP1fPpAfSs>6AHb12UlR%-i&uOlTpFNS7{jm@mkU1V zh`nrXr~+^lsV-s1dkZOaI|kYyVj3WBpPCY{n~yd%u%e+d=f%`N0FItMPtdgBb@py; zq@v6NVArhyTC7)ULw-Jy8y42S1~4n(3LkrW8mW(F-4oXUP3E`e#g**YyqI7h-J2zK zK{m9##m4ri!7N>CqQqCcnI3hqo1I;Yh&QLNY4T`*ptiQGozK>FF$!$+84Z`xwmeMh zJ0WT+OH$WYFALEaGj2_l+#DC3t7_S`vHpSivNeFbP6+r50cO8iu)`7i%Z4BTPh@_m3Tk!nAm^)5Bqnr%Ov|Baunj#&RPtRuK& z4RGz|D5HNrW83-#ydk}tVKJrNmyYt-sTxLGlJY5nc&Re zU4SgHNPx8~Yxwr$bsju?4q&%T1874xxzq+_%?h8_ofw~(bld=o3iC)LUNR*BY%c0y zWd_jX{Y8`l%z+ol1$@Qa?Cy!(0CVIEeYpKZ`(9{z>3$CIe;pJDQk$m3p}$>xBm4lb zKo{4S)`wdU9Ba9jJbVJ0C=SOefZe%d$8=2r={nu<_^a3~>c#t_U6dye5)JrR(_a^E f@}b6j1K9lwFJq@>o)+Ry00000NkvXXu0mjfWa5j* literal 0 HcmV?d00001 diff --git a/doxygen/sync_on.png b/doxygen/sync_on.png new file mode 100644 index 0000000000000000000000000000000000000000..e08320fb64e6fa33b573005ed6d8fe294e19db76 GIT binary patch literal 845 zcmV-T1G4;yP)Y;xxyHF2B5Wzm| zOOGupOTn@c(JmBOl)e;XMNnZuiTJP>rM8<|Q`7I_))aP?*T)ow&n59{}X4$3Goat zgjs?*aasfbrokzG5cT4K=uG`E14xZl@z)F={P0Y^?$4t z>v!teRnNZym<6h{7sLyF1V0HsfEl+l6TrZpsfr1}luH~F7L}ktXu|*uVX^RG$L0`K zWs3j|0tIvVe(N%_?2{(iCPFGf#B6Hjy6o&}D$A%W%jfO8_W%ZO#-mh}EM$LMn7joJ z05dHr!5Y92g+31l<%i1(=L1a1pXX+OYnalY>31V4K}BjyRe3)9n#;-cCVRD_IG1fT zOKGeNY8q;TL@K{dj@D^scf&VCs*-Jb>8b>|`b*osv52-!A?BpbYtTQBns5EAU**$m zSnVSm(teh>tQi*S*A>#ySc=n;`BHz`DuG4&g4Kf8lLhca+zvZ7t7RflD6-i-mcK=M z!=^P$*u2)bkY5asG4gsss!Hn%u~>}kIW`vMs%lJLH+u*9<4PaV_c6U`KqWXQH%+Nu zTv41O(^ZVi@qhjQdG!fbZw&y+2o!iYymO^?ud3{P*HdoX83YV*Uu_HB=?U&W9%AU# z80}k1SS-CXTU7dcQlsm<^oYLxVSseqY6NO}dc`Nj?8vrhNuCdm@^{a3AQ_>6myOj+ z`1RsLUXF|dm|3k7s2jD(B{rzE>WI2scH8i1;=O5Cc9xB3^aJk%fQjqsu+kH#0=_5a z0nCE8@dbQa-|YIuUVvG0L_IwHMEhOj$Mj4Uq05 X8=0q~qBNan00000NkvXXu0mjfptF>5 literal 0 HcmV?d00001 diff --git a/doxygen/tab_a.png b/doxygen/tab_a.png new file mode 100644 index 0000000000000000000000000000000000000000..3b725c41c5a527a3a3e40097077d0e206a681247 GIT binary patch literal 142 zcmeAS@N?(olHy`uVBq!ia0vp^j6kfy!2~3aiye;!QlXwMjv*C{Z|8b*H5dputLHD# z=<0|*y7z(Vor?d;H&?EG&cXR}?!j-Lm&u1OOI7AIF5&c)RFE;&p0MYK>*Kl@eiymD r@|NpwKX@^z+;{u_Z~trSBfrMKa%3`zocFjEXaR$#tDnm{r-UW|TZ1%4 literal 0 HcmV?d00001 diff --git a/doxygen/tab_ad.png b/doxygen/tab_ad.png new file mode 100644 index 0000000000000000000000000000000000000000..e34850acfc24be58da6d2fd1ccc6b29cc84fe34d GIT binary patch literal 135 zcmeAS@N?(olHy`uVBq!ia0vp^j6kfy!2~3aiye;!QhuH;jv*C{Z|5d*H3V=pKi{In zd2jxLclDRPylmD}^l7{QOtL{vUjO{-WqItb5sQp2h-99b8^^Scr-=2mblCdZuUm?4 jzOJvgvt3{(cjKLW5(A@0qPS@<&}0TrS3j3^P6y&q2{!U5bk+Tso_B!YCpDh>v z{CM*1U8YvQRyBUHt^Ju0W_sq-?;9@_4equ-bavTs=gk796zopr0EBT&m;e9( literal 0 HcmV?d00001 diff --git a/doxygen/tab_s.png b/doxygen/tab_s.png new file mode 100644 index 0000000000000000000000000000000000000000..ab478c95b67371d700a20869f7de1ddd73522d50 GIT binary patch literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^j6kfy!2~3aiye;!QuUrLjv*C{Z|^p8HaRdjTwH7) zC?wLlL}}I{)n%R&r+1}IGmDnq;&J#%V6)9VsYhS`O^BVBQlxOUep0c$RENLq#g8A$ z)z7%K_bI&n@J+X_=x}fJoEKed-$<>=ZI-;YrdjIl`U`uzuDWSP?o#Dmo{%SgM#oan kX~E1%D-|#H#QbHoIja2U-MgvsK&LQxy85}Sb4q9e0Efg%P5=M^ literal 0 HcmV?d00001 diff --git a/doxygen/tab_sd.png b/doxygen/tab_sd.png new file mode 100644 index 0000000000000000000000000000000000000000..757a565ced4730f85c833fb2547d8e199ae68f19 GIT binary patch literal 188 zcmeAS@N?(olHy`uVBq!ia0vp^j6kfy!2~3aiye;!Qq7(&jv*C{Z|_!fH5o7*c=%9% zcILh!EA=pAQKdx-Cdiev=v{eg{8Ht<{e8_NAN~b=)%W>-WDCE0PyDHGemi$BoXwcK z{>e9^za6*c1ilttWw&V+U;WCPlV9{LdC~Ey%_H(qj`xgfES(4Yz5jSTZfCt`4E$0YRsR*S^mTCR^;V&sxC8{l_Cp7w8-YPgg&ebxsLQ00$vXK>z>% literal 0 HcmV?d00001 diff --git a/doxygen/tabs.css b/doxygen/tabs.css new file mode 100644 index 0000000..df7944b --- /dev/null +++ b/doxygen/tabs.css @@ -0,0 +1 @@ +.sm{position:relative;z-index:9999}.sm,.sm ul,.sm li{display:block;list-style:none;margin:0;padding:0;line-height:normal;direction:ltr;text-align:left;-webkit-tap-highlight-color:rgba(0,0,0,0)}.sm-rtl,.sm-rtl ul,.sm-rtl li{direction:rtl;text-align:right}.sm>li>h1,.sm>li>h2,.sm>li>h3,.sm>li>h4,.sm>li>h5,.sm>li>h6{margin:0;padding:0}.sm ul{display:none}.sm li,.sm a{position:relative}.sm a{display:block}.sm a.disabled{cursor:not-allowed}.sm:after{content:"\00a0";display:block;height:0;font:0px/0 serif;clear:both;visibility:hidden;overflow:hidden}.sm,.sm *,.sm *:before,.sm *:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.main-menu-btn{position:relative;display:inline-block;width:36px;height:36px;text-indent:36px;margin-left:8px;white-space:nowrap;overflow:hidden;cursor:pointer;-webkit-tap-highlight-color:rgba(0,0,0,0)}.main-menu-btn-icon,.main-menu-btn-icon:before,.main-menu-btn-icon:after{position:absolute;top:50%;left:2px;height:2px;width:24px;background:var(--nav-menu-button-color);-webkit-transition:all 0.25s;transition:all 0.25s}.main-menu-btn-icon:before{content:'';top:-7px;left:0}.main-menu-btn-icon:after{content:'';top:7px;left:0}#main-menu-state:checked~.main-menu-btn .main-menu-btn-icon{height:0}#main-menu-state:checked~.main-menu-btn .main-menu-btn-icon:before{top:0;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}#main-menu-state:checked~.main-menu-btn .main-menu-btn-icon:after{top:0;-webkit-transform:rotate(45deg);transform:rotate(45deg)}#main-menu-state{position:absolute;width:1px;height:1px;margin:-1px;border:0;padding:0;overflow:hidden;clip:rect(1px, 1px, 1px, 1px)}#main-menu-state:not(:checked)~#main-menu{display:none}#main-menu-state:checked~#main-menu{display:block}@media (min-width: 768px){.main-menu-btn{position:absolute;top:-99999px}#main-menu-state:not(:checked)~#main-menu{display:block}}.sm-dox{background-image:var(--nav-gradient-image)}.sm-dox a,.sm-dox a:focus,.sm-dox a:hover,.sm-dox a:active{padding:0px 12px;padding-right:43px;font-family:var(--font-family-nav);font-size:13px;font-weight:bold;line-height:36px;text-decoration:none;text-shadow:var(--nav-text-normal-shadow);color:var(--nav-text-normal-color);outline:none}.sm-dox a:hover{background-image:var(--nav-gradient-active-image);background-repeat:repeat-x;color:var(--nav-text-hover-color);text-shadow:var(--nav-text-hover-shadow)}.sm-dox a.current{color:#D23600}.sm-dox a.disabled{color:#bbb}.sm-dox a span.sub-arrow{position:absolute;top:50%;margin-top:-14px;left:auto;right:3px;width:28px;height:28px;overflow:hidden;font:bold 12px/28px monospace !important;text-align:center;text-shadow:none;background:var(--nav-menu-toggle-color);border-radius:5px}.sm-dox a span.sub-arrow:before{display:block;content:'+'}.sm-dox a.highlighted span.sub-arrow:before{display:block;content:'-'}.sm-dox>li:first-child>a,.sm-dox>li:first-child>:not(ul) a{border-radius:5px 5px 0 0}.sm-dox>li:last-child>a,.sm-dox>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul{border-radius:0 0 5px 5px}.sm-dox>li:last-child>a.highlighted,.sm-dox>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted{border-radius:0}.sm-dox ul{background:var(--nav-menu-background-color)}.sm-dox ul a,.sm-dox ul a:focus,.sm-dox ul a:hover,.sm-dox ul a:active{font-size:12px;border-left:8px solid transparent;line-height:36px;text-shadow:none;background-color:var(--nav-menu-background-color);background-image:none}.sm-dox ul a:hover{background-image:var(--nav-gradient-active-image);background-repeat:repeat-x;color:var(--nav-text-hover-color);text-shadow:0px 1px 1px #000}.sm-dox ul ul a,.sm-dox ul ul a:hover,.sm-dox ul ul a:focus,.sm-dox ul ul a:active{border-left:16px solid transparent}.sm-dox ul ul ul a,.sm-dox ul ul ul a:hover,.sm-dox ul ul ul a:focus,.sm-dox ul ul ul a:active{border-left:24px solid transparent}.sm-dox ul ul ul ul a,.sm-dox ul ul ul ul a:hover,.sm-dox ul ul ul ul a:focus,.sm-dox ul ul ul ul a:active{border-left:32px solid transparent}.sm-dox ul ul ul ul ul a,.sm-dox ul ul ul ul ul a:hover,.sm-dox ul ul ul ul ul a:focus,.sm-dox ul ul ul ul ul a:active{border-left:40px solid transparent}@media (min-width: 768px){.sm-dox ul{position:absolute;width:12em}.sm-dox li{float:left}.sm-dox.sm-rtl li{float:right}.sm-dox ul li,.sm-dox.sm-rtl ul li,.sm-dox.sm-vertical li{float:none}.sm-dox a{white-space:nowrap}.sm-dox ul a,.sm-dox.sm-vertical a{white-space:normal}.sm-dox .sm-nowrap>li>a,.sm-dox .sm-nowrap>li>:not(ul) a{white-space:nowrap}.sm-dox{padding:0 10px;background-image:var(--nav-gradient-image);line-height:36px}.sm-dox a span.sub-arrow{top:50%;margin-top:-2px;right:12px;width:0;height:0;border-width:4px;border-style:solid dashed dashed dashed;border-color:var(--nav-text-normal-color) transparent transparent transparent;background:transparent;border-radius:0}.sm-dox a,.sm-dox a:focus,.sm-dox a:active,.sm-dox a:hover,.sm-dox a.highlighted{padding:0px 12px;background-image:var(--nav-separator-image);background-repeat:no-repeat;background-position:right;border-radius:0 !important}.sm-dox a:hover{background-image:var(--nav-gradient-active-image);background-repeat:repeat-x;color:var(--nav-text-hover-color);text-shadow:var(--nav-text-hover-shadow)}.sm-dox a:hover span.sub-arrow{border-color:var(--nav-text-hover-color) transparent transparent transparent}.sm-dox a.has-submenu{padding-right:24px}.sm-dox li{border-top:0}.sm-dox>li>ul:before,.sm-dox>li>ul:after{content:'';position:absolute;top:-18px;left:30px;width:0;height:0;overflow:hidden;border-width:9px;border-style:dashed dashed solid dashed;border-color:transparent transparent #bbb transparent}.sm-dox>li>ul:after{top:-16px;left:31px;border-width:8px;border-color:transparent transparent var(--nav-menu-background-color) transparent}.sm-dox ul{border:1px solid #bbb;padding:5px 0;background:var(--nav-menu-background-color);border-radius:5px !important;box-shadow:0 5px 9px rgba(0,0,0,0.2)}.sm-dox ul a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-color:transparent transparent transparent var(--nav-menu-foreground-color);border-style:dashed dashed dashed solid}.sm-dox ul a,.sm-dox ul a:hover,.sm-dox ul a:focus,.sm-dox ul a:active,.sm-dox ul a.highlighted{color:var(--nav-menu-foreground-color);background-image:none;border:0 !important;color:var(--nav-menu-foreground-color);background-image:none}.sm-dox ul a:hover{background-image:var(--nav-gradient-active-image);background-repeat:repeat-x;color:var(--nav-text-hover-color);text-shadow:var(--nav-text-hover-shadow)}.sm-dox ul a:hover span.sub-arrow{border-color:transparent transparent transparent var(--nav-text-hover-color)}.sm-dox span.scroll-up,.sm-dox span.scroll-down{position:absolute;display:none;visibility:hidden;overflow:hidden;background:var(--nav-menu-background-color);height:36px}.sm-dox span.scroll-up:hover,.sm-dox span.scroll-down:hover{background:#eee}.sm-dox span.scroll-up:hover span.scroll-up-arrow,.sm-dox span.scroll-up:hover span.scroll-down-arrow{border-color:transparent transparent #D23600 transparent}.sm-dox span.scroll-down:hover span.scroll-down-arrow{border-color:#D23600 transparent transparent transparent}.sm-dox span.scroll-up-arrow,.sm-dox span.scroll-down-arrow{position:absolute;top:0;left:50%;margin-left:-6px;width:0;height:0;overflow:hidden;border-width:6px;border-style:dashed dashed solid dashed;border-color:transparent transparent var(--nav-menu-foreground-color) transparent}.sm-dox span.scroll-down-arrow{top:8px;border-style:solid dashed dashed dashed;border-color:var(--nav-menu-foreground-color) transparent transparent transparent}.sm-dox.sm-rtl a.has-submenu{padding-right:12px;padding-left:24px}.sm-dox.sm-rtl a span.sub-arrow{right:auto;left:12px}.sm-dox.sm-rtl.sm-vertical a.has-submenu{padding:10px 20px}.sm-dox.sm-rtl.sm-vertical a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-rtl>li>ul:before{left:auto;right:30px}.sm-dox.sm-rtl>li>ul:after{left:auto;right:31px}.sm-dox.sm-rtl ul a.has-submenu{padding:10px 20px !important}.sm-dox.sm-rtl ul a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-vertical{padding:10px 0;border-radius:5px}.sm-dox.sm-vertical a{padding:10px 20px}.sm-dox.sm-vertical a:hover,.sm-dox.sm-vertical a:focus,.sm-dox.sm-vertical a:active,.sm-dox.sm-vertical a.highlighted{background:#fff}.sm-dox.sm-vertical a.disabled{background-image:var(--nav-gradient-image)}.sm-dox.sm-vertical a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-style:dashed dashed dashed solid;border-color:transparent transparent transparent #555}.sm-dox.sm-vertical>li>ul:before,.sm-dox.sm-vertical>li>ul:after{display:none}.sm-dox.sm-vertical ul a{padding:10px 20px}.sm-dox.sm-vertical ul a:hover,.sm-dox.sm-vertical ul a:focus,.sm-dox.sm-vertical ul a:active,.sm-dox.sm-vertical ul a.highlighted{background:#eee}.sm-dox.sm-vertical ul a.disabled{background:var(--nav-menu-background-color)}} diff --git a/doxygen/transformers_2____init_____8py.html b/doxygen/transformers_2____init_____8py.html new file mode 100644 index 0000000..a055ede --- /dev/null +++ b/doxygen/transformers_2____init_____8py.html @@ -0,0 +1,116 @@ + + + + + + + +OMG-Fuscator: __init__.py File Reference + + + + + + + + + + + + + +
    +
    + + + + + + +
    +
    OMG-Fuscator +
    +
    Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
    +
    +
    + + + + + + + +
    +
    + +
    +
    +
    + +
    + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + +
    + +
    __init__.py File Reference
    +
    +
    + +

    Go to the source code of this file.

    + + + + +

    +Namespaces

    namespace  transformers
     
    +
    +
    + + + + diff --git a/doxygen/transformers_2____init_____8py_source.html b/doxygen/transformers_2____init_____8py_source.html new file mode 100644 index 0000000..baa276a --- /dev/null +++ b/doxygen/transformers_2____init_____8py_source.html @@ -0,0 +1,118 @@ + + + + + + + +OMG-Fuscator: __init__.py Source File + + + + + + + + + + + + + +
    +
    + + + + + + +
    +
    OMG-Fuscator +
    +
    Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
    +
    +
    + + + + + + + + +
    +
    + +
    +
    +
    + +
    + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + +
    +
    transformers/__init__.py
    +
    +
    +Go to the documentation of this file.
    1"""
    +
    2@file transformers/__init__.py
    +
    3@brief Package initializer for the transformers module.
    +
    4@details Groups AST transformers and analyzers used by OMG-Fuscator, including
    +
    5 renaming, control-flow flattening, class mapping, attribute handling,
    +
    6 and symbol tree utilities.
    +
    7"""
    +
    +
    + + + + diff --git a/doxygen/utils_2____init_____8py.html b/doxygen/utils_2____init_____8py.html new file mode 100644 index 0000000..63f1d43 --- /dev/null +++ b/doxygen/utils_2____init_____8py.html @@ -0,0 +1,116 @@ + + + + + + + +OMG-Fuscator: __init__.py File Reference + + + + + + + + + + + + + +
    +
    + + + + + + +
    +
    OMG-Fuscator +
    +
    Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
    +
    +
    + + + + + + + +
    +
    + +
    +
    +
    + +
    + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + +
    + +
    __init__.py File Reference
    +
    +
    + +

    Go to the source code of this file.

    + + + + +

    +Namespaces

    namespace  utils
     
    +
    +
    + + + + diff --git a/doxygen/utils_2____init_____8py_source.html b/doxygen/utils_2____init_____8py_source.html new file mode 100644 index 0000000..70d54b7 --- /dev/null +++ b/doxygen/utils_2____init_____8py_source.html @@ -0,0 +1,117 @@ + + + + + + + +OMG-Fuscator: __init__.py Source File + + + + + + + + + + + + + +
    +
    + + + + + + +
    +
    OMG-Fuscator +
    +
    Advanced Python obfuscator (renaming, string encryption, control-flow flattening)
    +
    +
    + + + + + + + + +
    +
    + +
    +
    +
    + +
    + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + +
    +
    utils/__init__.py
    +
    +
    +Go to the documentation of this file.
    1"""
    +
    2@file utils/__init__.py
    +
    3@brief Package initializer for utility helpers.
    +
    4@details Exposes helper modules used by OMG-Fuscator (encryption, junk generation,
    +
    5 and obfuscated name generation).
    +
    6"""
    +
    +
    + + + +