├── .gitattributes ├── .gitignore ├── README.md ├── examples ├── JObfuscatorExample.py ├── JObfuscatorExampleIsDemo.py └── JObfuscatorExampleSimple.py ├── jobfuscator ├── __init__.py └── jobfuscator.py └── setup.py /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | # PyInstaller 28 | # Usually these files are written by a python script from a template 29 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 30 | *.manifest 31 | *.spec 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *,cover 46 | .hypothesis/ 47 | 48 | # Translations 49 | *.mo 50 | *.pot 51 | 52 | # Django stuff: 53 | *.log 54 | local_settings.py 55 | 56 | # Flask instance folder 57 | instance/ 58 | 59 | # Scrapy stuff: 60 | .scrapy 61 | 62 | # Sphinx documentation 63 | docs/_build/ 64 | 65 | # PyBuilder 66 | target/ 67 | 68 | # IPython Notebook 69 | .ipynb_checkpoints 70 | 71 | # pyenv 72 | .python-version 73 | 74 | # celery beat schedule file 75 | celerybeat-schedule 76 | 77 | # dotenv 78 | .env 79 | 80 | # virtualenv 81 | venv/ 82 | ENV/ 83 | 84 | # Spyder project settings 85 | .spyderproject 86 | 87 | # Rope project settings 88 | .ropeproject 89 | 90 | # ========================= 91 | # Operating System Files 92 | # ========================= 93 | 94 | # OSX 95 | # ========================= 96 | 97 | .DS_Store 98 | .AppleDouble 99 | .LSOverride 100 | 101 | # Thumbnails 102 | ._* 103 | 104 | # Files that might appear in the root of a volume 105 | .DocumentRevisions-V100 106 | .fseventsd 107 | .Spotlight-V100 108 | .TemporaryItems 109 | .Trashes 110 | .VolumeIcon.icns 111 | 112 | # Directories potentially created on remote AFP share 113 | .AppleDB 114 | .AppleDesktop 115 | Network Trash Folder 116 | Temporary Items 117 | .apdisk 118 | 119 | # Windows 120 | # ========================= 121 | 122 | # Windows image file caches 123 | Thumbs.db 124 | ehthumbs.db 125 | 126 | # Folder config file 127 | Desktop.ini 128 | 129 | # Recycle Bin used on file shares 130 | $RECYCLE.BIN/ 131 | 132 | # Windows Installer files 133 | *.cab 134 | *.msi 135 | *.msm 136 | *.msp 137 | 138 | # Windows shortcuts 139 | *.lnk 140 | 141 | # Builds 142 | build 143 | dist 144 | *.egg-info 145 | .idea 146 | *.bat -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JObfuscator — Java Source Code Obfuscation & Protection (Python Module) 2 | 3 | **JObfuscator** is a source code obfuscator for the Java programming language. It can protect your Java source code and algorithms from hacking, cracking, reverse engineering, decompilation, and technology theft. 4 | 5 | JObfuscator employs a variety of obfuscation techniques to protect & conceal the true functionality of your Java source code. 6 | 7 | It renames all variables and methods, obfuscates the code flow by making it non-linear, and encrypts all strings with our cutting-edge polymorphic [string encryption](https://www.stringencrypt.com) engine. 8 | 9 | More technical details, downloads, documentation available at: 10 | 11 | https://www.pelock.com/products/jobfuscator 12 | 13 | ![JObfuscator Java Obfuscator Windows Client](https://www.pelock.com/img/en/products/jobfuscator/jobfuscator-java-obfuscator-obfuscation-1-0-main.png) 14 | 15 | It's available for Windows & Linux (requires Mono): 16 | 17 | https://www.pelock.com/products/jobfuscator/download 18 | 19 | Multiple programming APIs available: 20 | 21 | https://www.pelock.com/products/jobfuscator/api 22 | 23 | An online obfuscator interface: 24 | 25 | https://www.pelock.com/jobfuscator/ 26 | 27 | ## Java decompilation is a huge problem 28 | 29 | Applications written in Java and compiled to `JAR`, `WAR` or `CLASS` formats are vulnerable to decompilation. 30 | 31 | There are a number of [decompilers](https://www.pelock.com/articles/reverse-engineering-tools-review#disassemblers-and-decompilers) that can almost completely recreate the compiled code back to Java source. 32 | 33 | The problem is that the compiled Java code is written as a so-called [bytecode](https://en.wikipedia.org/wiki/Java_bytecode) for the [JVM](https://en.wikipedia.org/wiki/Java_virtual_machine) (as opposed to the native CPU code like `x86` or `x86-64`). 34 | 35 | In addition to being perfectly [perfectly documented](https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html), this form of code allows for very accurate reproduction of the original instructions in high-level Java source code. 36 | 37 | 38 | ## What can Java decompilers do? 39 | 40 | Take a look at this example: 41 | 42 | ![Java JAD Decompiler](https://www.pelock.com/img/en/products/jobfuscator/java-jad-decompiler-decompilation.png) 43 | 44 | This is **decompiled** Java code! All the variable, property and method names are readable. You can even easily navigate through the entire decompiled project, jumping from one class to another. 45 | 46 | Are you surprised? It could be your software analyzed by the competition, hackers, crackers or anyone else. 47 | 48 | ## Technology & Intellectual Property (IP) Theft 49 | 50 | What could they do with it? Most of the time, the software or its algorithms are stolen or replicated in competing products. 51 | 52 | In some other cases, the software gets cracked, clearly visible license checks in decompiled source code are patched or even the entire cracked software is recompiled and published on pirate sites. 53 | 54 | ## Java source code obfuscation 55 | 56 | Obfuscation is the process of transforming Java source code into a **protected** version of itself. 57 | 58 | The functionality remains **unchanged**, everything works the same, but the source code and the final compiled bytecode are protected from reverse engineering analysis, even after the decompilation. 59 | 60 | ### Sample Java source code before obfuscation 61 | 62 | ```java 63 | import java.util.*; 64 | import java.lang.*; 65 | import java.io.*; 66 | 67 | // 68 | // you must include custom annotations to enable 69 | // entire class or a single method obfuscation 70 | // 71 | @Obfuscate 72 | class Ideone 73 | { 74 | //@Obfuscate 75 | public static double calculateSD(double numArray[]) 76 | { 77 | double sum = 0.0, standardDeviation = 0.0; 78 | int length = numArray.length; 79 | 80 | for(double num : numArray) { 81 | sum += num; 82 | } 83 | 84 | double mean = sum/length; 85 | 86 | for(double num: numArray) { 87 | standardDeviation += Math.pow(num - mean, 2); 88 | } 89 | 90 | return Math.sqrt(standardDeviation/length); 91 | } 92 | 93 | // 94 | // selective obfuscation strategies can be applied 95 | // for the entire class or a single method (by default 96 | // all obfuscation strategies are enabled when you 97 | // use @Obfuscate annotation alone) 98 | // 99 | //@Obfuscate( 100 | // ints_math_crypt = true, 101 | // crypt_strings = true, 102 | // rename_methods = false, 103 | // rename_variables = true, 104 | // shuffle_methods = true, 105 | // mix_code_flow = true, 106 | // ints_to_arrays = true, 107 | // dbls_to_arrays = true 108 | // ) 109 | public static void main(String[] args) { 110 | 111 | double[] numArray = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 112 | double SD = calculateSD(numArray); 113 | 114 | System.out.format("Standard Deviation = %.6f", SD); 115 | } 116 | } 117 | ``` 118 | 119 | ### The same Java source code after the obfuscation 120 | 121 | ```java 122 | //////////////////////////////////////////////////////////////////////////////// 123 | // 124 | // An output from JObfuscator v1.04 - Bartosz Wójcik 125 | // 126 | // Website : https://www.pelock.com/products/jobfuscator 127 | // Version : v1.04 128 | // Params : /MixCodeFlow /RenMethods /RenVars /ShuffleMethods /IntsMathCrypt 129 | // /CryptStr /IntsToArray /DblsToArray 130 | // New lines : Windows (CRLF - \r\n) 131 | // Date : 05.08.2021 132 | // 133 | //////////////////////////////////////////////////////////////////////////////// 134 | 135 | import java.util.*; 136 | import java.lang.*; 137 | import java.io.*; 138 | import java.lang.Math.*; 139 | 140 | class Ideone { 141 | 142 | public static void main(String[] args) { 143 | double[] var_3643 = { 11.281129091070447, 8.215990040064463, 9.335603284152908, 6.577895383020224, 7.877805395297853, 0.9548404018895811, 5.272519318820092, 12.245640663335054, 1.9976550397430217, 10.498728922195335, 4.456573802948024, 2.6442660372556444, 3.7216852394828073 }; 144 | double[] POCKKZB_FGNQQA = { 8.38801852183473, 2.284191901516045, 5.084540489182378, 1.674058425502392, 6.582113966026355, 4.535954119796876, 9.655576838937206, 0.9057730473532776, 12.594924738730645, 7.746648086079376, 11.98098322298382, 3.255923593789993, 10.419132138693842 }; 145 | int[] BQ__Y_IAsVbM2emsVuNM_ = { 7, 3, 5, 1, 2, 6, 8, 12, 9, 0, 4, 11, 10 }; 146 | double[] jY__n3HVSq_WnFXQMnt = { 4.522937188633843, 7.63592787991592, 9.711938391204889, 12.329314329092874, 1.1257488711853099, 11.26843992090746, 0.20656899168837578, 8.596210417144972, 6.313987076769585, 2.726188726136701, 5.437577113574992, 10.94073555701292, 3.2325862076196463 }; 147 | int[] var_801 = { 6, 10, 4, 5, 0, 12, 3, 8, 7, 9, 1, 11, 2 }; 148 | double[] var_3117 = { 1.59679966392783E9, 5.09464, 1.7081, 1.59679967201455E9, 8221.83558, 0.6956, 81286.37426, 11.30573, 1.87014187726384E9, 0.0, 0.30216, 1.93861225375307E9, 1.61031449284985E9 }; 149 | double[] p_vc56jpND__QGGjzT4_Wo7 = { 1.8560312987803957, 2.4090487677657637, 0.8107141612789537 }; 150 | int[] CLOHOQ_TOCOXGBRWY_PVBHFAV = { 0, 2, 1 }; 151 | int[] g_hFqjbczKirudqjb = { 1, 0, 2 }; 152 | int[] A7c7WIo__fQMQjM_lR = { 1, 0, 2 }; 153 | int[] fKzmro = { 0, 1, 2 }; 154 | double[] pFlxasazuVysmwcpkfm = { 1.7137421654720035, 0.880784281506382, 2.044091478491187 }; 155 | double[] b_9rz1_gUCNc_ceKC = { 25.495116489488254, 65535.73197007176, 0.7422593232260603 }; 156 | int mZwtvvepUboureeved = (int) (-var_3117[var_801[(int) (jY__n3HVSq_WnFXQMnt[BQ__Y_IAsVbM2emsVuNM_[(int) (POCKKZB_FGNQQA[(int) (var_3643[4])])]])]] + Math.log(var_3117[var_801[(int) (jY__n3HVSq_WnFXQMnt[BQ__Y_IAsVbM2emsVuNM_[(int) (POCKKZB_FGNQQA[(int) (var_3643[11])])]])]])); 157 | double kW2_ZQnBOs9VL_mjKXcB__4 = var_3117[var_801[(int) (jY__n3HVSq_WnFXQMnt[BQ__Y_IAsVbM2emsVuNM_[(int) (POCKKZB_FGNQQA[(int) (var_3643[6])])]])]]; 158 | double[] _KnlkZiv_t6Ohx_xWp_9M = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 159 | mZwtvvepUboureeved = (int) (var_3117[var_801[(int) (jY__n3HVSq_WnFXQMnt[BQ__Y_IAsVbM2emsVuNM_[(int) (POCKKZB_FGNQQA[(int) (var_3643[8])])]])]] - Math.sinh(var_3117[var_801[(int) (jY__n3HVSq_WnFXQMnt[BQ__Y_IAsVbM2emsVuNM_[(int) (POCKKZB_FGNQQA[(int) (var_3643[2])])]])]])); 160 | while (mZwtvvepUboureeved != (int) (var_3117[var_801[(int) (jY__n3HVSq_WnFXQMnt[BQ__Y_IAsVbM2emsVuNM_[(int) (POCKKZB_FGNQQA[(int) (var_3643[3])])]])]] + Math.sin(var_3117[var_801[(int) (jY__n3HVSq_WnFXQMnt[BQ__Y_IAsVbM2emsVuNM_[(int) (POCKKZB_FGNQQA[(int) (var_3643[9])])]])]]))) { 161 | switch(mZwtvvepUboureeved) { 162 | case 1678784867: 163 | String var_1767 = ""; 164 | int[] _KhlYbJNlonwV_I_OOZKAb_ = { 0x0052, 0x0073, 0x005C, 0x0069, 0x005B, 0x005E, 0x006D, 0x005B, 0x001F, 0x0033, 0x0050, 0x0061, 0x0050, 0x005E, 0x006B, 0x0056, 0x004E, 0x004D, 0x001F, 0x003A, 0x001F, 0x001A, 0x0001, 0x0009, 0x0055 }; 165 | for (int x0Qc_6t8YSu__UjlP_hUC6M6 = (int) (b_9rz1_gUCNc_ceKC[(int) (pFlxasazuVysmwcpkfm[fKzmro[A7c7WIo__fQMQjM_lR[g_hFqjbczKirudqjb[CLOHOQ_TOCOXGBRWY_PVBHFAV[(int) (p_vc56jpND__QGGjzT4_Wo7[var_801[(int) (jY__n3HVSq_WnFXQMnt[BQ__Y_IAsVbM2emsVuNM_[(int) (POCKKZB_FGNQQA[(int) (var_3643[3])])]])]])]]]]])]), _bFfGZu_kuSY5dNkBN_ku_tU = (int) (b_9rz1_gUCNc_ceKC[(int) (pFlxasazuVysmwcpkfm[fKzmro[A7c7WIo__fQMQjM_lR[g_hFqjbczKirudqjb[CLOHOQ_TOCOXGBRWY_PVBHFAV[(int) (p_vc56jpND__QGGjzT4_Wo7[var_801[(int) (jY__n3HVSq_WnFXQMnt[BQ__Y_IAsVbM2emsVuNM_[(int) (POCKKZB_FGNQQA[(int) (var_3643[3])])]])]])]]]]])]); x0Qc_6t8YSu__UjlP_hUC6M6 < (int) (b_9rz1_gUCNc_ceKC[(int) (pFlxasazuVysmwcpkfm[fKzmro[A7c7WIo__fQMQjM_lR[g_hFqjbczKirudqjb[CLOHOQ_TOCOXGBRWY_PVBHFAV[(int) (p_vc56jpND__QGGjzT4_Wo7[var_801[(int) (jY__n3HVSq_WnFXQMnt[BQ__Y_IAsVbM2emsVuNM_[(int) (POCKKZB_FGNQQA[(int) (var_3643[9])])]])]])]]]]])]); x0Qc_6t8YSu__UjlP_hUC6M6++) { 166 | _bFfGZu_kuSY5dNkBN_ku_tU = _KhlYbJNlonwV_I_OOZKAb_[x0Qc_6t8YSu__UjlP_hUC6M6]; 167 | _bFfGZu_kuSY5dNkBN_ku_tU ^= x0Qc_6t8YSu__UjlP_hUC6M6; 168 | _bFfGZu_kuSY5dNkBN_ku_tU += x0Qc_6t8YSu__UjlP_hUC6M6; 169 | _bFfGZu_kuSY5dNkBN_ku_tU++; 170 | var_1767 += (char) (_bFfGZu_kuSY5dNkBN_ku_tU & (int) (b_9rz1_gUCNc_ceKC[(int) (pFlxasazuVysmwcpkfm[fKzmro[A7c7WIo__fQMQjM_lR[g_hFqjbczKirudqjb[CLOHOQ_TOCOXGBRWY_PVBHFAV[(int) (p_vc56jpND__QGGjzT4_Wo7[var_801[(int) (jY__n3HVSq_WnFXQMnt[BQ__Y_IAsVbM2emsVuNM_[(int) (POCKKZB_FGNQQA[(int) (var_3643[12])])]])]])]]]]])])); 171 | } 172 | System.out.format(var_1767, kW2_ZQnBOs9VL_mjKXcB__4); 173 | mZwtvvepUboureeved = (int) (var_3117[var_801[(int) (jY__n3HVSq_WnFXQMnt[BQ__Y_IAsVbM2emsVuNM_[(int) (POCKKZB_FGNQQA[(int) (var_3643[10])])]])]] - Math.log(var_3117[var_801[(int) (jY__n3HVSq_WnFXQMnt[BQ__Y_IAsVbM2emsVuNM_[(int) (POCKKZB_FGNQQA[(int) (var_3643[5])])]])]])); 174 | break; 175 | case 68470377: 176 | kW2_ZQnBOs9VL_mjKXcB__4 = SrwgvFunc(_KnlkZiv_t6Ohx_xWp_9M); 177 | mZwtvvepUboureeved -= -(int) (var_3117[var_801[(int) (jY__n3HVSq_WnFXQMnt[BQ__Y_IAsVbM2emsVuNM_[(int) (POCKKZB_FGNQQA[(int) (var_3643[1])])]])]] - Math.cosh(var_3117[var_801[(int) (jY__n3HVSq_WnFXQMnt[BQ__Y_IAsVbM2emsVuNM_[(int) (POCKKZB_FGNQQA[(int) (var_3643[12])])]])]])); 178 | break; 179 | case 1938612253: 180 | double[] var_2915 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 181 | mZwtvvepUboureeved += -(int) (var_3117[var_801[(int) (jY__n3HVSq_WnFXQMnt[BQ__Y_IAsVbM2emsVuNM_[(int) (POCKKZB_FGNQQA[(int) (var_3643[0])])]])]] - Math.acos(var_3117[var_801[(int) (jY__n3HVSq_WnFXQMnt[BQ__Y_IAsVbM2emsVuNM_[(int) (POCKKZB_FGNQQA[(int) (var_3643[7])])]])]])); 182 | break; 183 | } 184 | } 185 | } 186 | 187 | public static double SrwgvFunc(double[] numArray) { 188 | double[] hXbuzlw = { 10.104687460635152, 14.863255212498105, 0.21565589122677703, 16.92136884299982, 8.284692818502851, 12.82669846485655, 15.403473564468571, 7.030894818830625, 9.171975582854735, 19.391816756528755, 11.864284748161538, 2.226792621794286, 13.24428454752136, 6.78017800635685, 20.155440287615413, 18.27510090243092, 3.589298943371685, 4.152627738386547, 5.665271866480059, 17.704844863089786, 1.0649770468512563 }; 189 | double[] var_575 = { 1.0296391297689236, 15.726628357412975, 20.92993527990269, 5.173619116590729, 7.844535074545817, 6.009394167087513, 16.086142381371435, 9.063044736138085, 4.990968854206419, 0.4740423015646155, 10.092369822585235, 19.48145881150217, 12.423331723670914, 13.445497843589065, 2.206559166836813, 8.16258487934631, 14.436447989183236, 11.161001228043002, 3.7977942067981534, 18.27965827256959, 17.307170323906416 }; 190 | int[] ZTEHAAYPJ_BISQMK = { 10, 3, 18, 6, 17, 9, 13, 15, 4, 16, 1, 12, 0, 19, 2, 14, 7, 8, 11, 20, 5 }; 191 | double[] iPlwrvpWkihvhctOrtubm = { 18.347247829648513, 15.993259210013832, 10.384509235580781, 7.659966773454712, 16.24894028024241, 14.250989627900879, 6.770226899219857, 8.283226421492104, 5.968118628152126, 1.3646389169586972, 2.717989641816233, 9.456551089444694, 11.143709780182407, 17.63249476052649, 13.72219811303589, 12.966327271855473, 3.0874626146986275, 0.861290055418454, 19.982579577626073, 20.466740193225053, 4.800445667758794 }; 192 | int[] var_2798 = { 14, 18, 16, 7, 5, 20, 15, 17, 10, 3, 13, 8, 2, 4, 9, 0, 1, 19, 12, 6, 11 }; 193 | int[] _w4ACl_Eb5iuB8tKft_ = { 6, 0, 16, 4, 9, 7, 1, 15, 2, 18, 20, 19, 10, 11, 12, 14, 17, 3, 8, 5, 13 }; 194 | double[] hFhzzxalpCshbolybyAslokrjo = { 0.7181203868509979, 2.9664637532667175, 9.515313299638107, 11.028323637923771, 6.390764892028182, 1.6030539747361725, 13.602130216656779, 18.414734494486385, 12.120766708284188, 7.961180222338676, 19.660846284473546, 5.578285135296968, 10.026225747743108, 15.49952117540782, 8.311906496462326, 14.44368335473346, 16.140307679070638, 17.004912894121887, 4.181691213350765, 20.99407023105516, 3.8834204842296294 }; 195 | int[] VAJLMKZ_MXMVAU_OHBRFS = { 7, 5, 10, 9, 1, 8, 11, 20, 17, 12, 0, 14, 13, 15, 16, 2, 6, 18, 3, 19, 4 }; 196 | double[] sAddoktk = { 1.6917277213165E9, 8079980.36161, 1.39348949767438E9, 45675.0865, 4.90983645E8, 15.9049, 7.80728377E8, 7.8073028200948E8, 8.68929906E8, 7.2918859851708E8, 5.04406, 1.24329286210753E9, 4.8208860701707E8, 2.9335, 43629.12742, 0.0, 3.4975, 6.65968, 6.2370634220671E8, 3.21790680933E7, 1.14826593649877E9 }; 197 | int var_921 = (int) Math.max(sAddoktk[VAJLMKZ_MXMVAU_OHBRFS[(int) (hFhzzxalpCshbolybyAslokrjo[_w4ACl_Eb5iuB8tKft_[var_2798[(int) (iPlwrvpWkihvhctOrtubm[ZTEHAAYPJ_BISQMK[(int) (var_575[(int) (hXbuzlw[0])])]])]]])]], sAddoktk[VAJLMKZ_MXMVAU_OHBRFS[(int) (hFhzzxalpCshbolybyAslokrjo[_w4ACl_Eb5iuB8tKft_[var_2798[(int) (iPlwrvpWkihvhctOrtubm[ZTEHAAYPJ_BISQMK[(int) (var_575[(int) (hXbuzlw[0])])]])]]])]]); 198 | double var_3498 = sAddoktk[VAJLMKZ_MXMVAU_OHBRFS[(int) (hFhzzxalpCshbolybyAslokrjo[_w4ACl_Eb5iuB8tKft_[var_2798[(int) (iPlwrvpWkihvhctOrtubm[ZTEHAAYPJ_BISQMK[(int) (var_575[(int) (hXbuzlw[0])])]])]]])]], g_pCbzjagbHcxgvwbj = sAddoktk[VAJLMKZ_MXMVAU_OHBRFS[(int) (hFhzzxalpCshbolybyAslokrjo[_w4ACl_Eb5iuB8tKft_[var_2798[(int) (iPlwrvpWkihvhctOrtubm[ZTEHAAYPJ_BISQMK[(int) (var_575[(int) (hXbuzlw[0])])]])]]])]]; 199 | int var_2533 = (int) (sAddoktk[VAJLMKZ_MXMVAU_OHBRFS[(int) (hFhzzxalpCshbolybyAslokrjo[_w4ACl_Eb5iuB8tKft_[var_2798[(int) (iPlwrvpWkihvhctOrtubm[ZTEHAAYPJ_BISQMK[(int) (var_575[(int) (hXbuzlw[11])])]])]]])]] - Math.exp(sAddoktk[VAJLMKZ_MXMVAU_OHBRFS[(int) (hFhzzxalpCshbolybyAslokrjo[_w4ACl_Eb5iuB8tKft_[var_2798[(int) (iPlwrvpWkihvhctOrtubm[ZTEHAAYPJ_BISQMK[(int) (var_575[(int) (hXbuzlw[18])])]])]]])]])); 200 | double var_60 = sAddoktk[VAJLMKZ_MXMVAU_OHBRFS[(int) (hFhzzxalpCshbolybyAslokrjo[_w4ACl_Eb5iuB8tKft_[var_2798[(int) (iPlwrvpWkihvhctOrtubm[ZTEHAAYPJ_BISQMK[(int) (var_575[(int) (hXbuzlw[0])])]])]]])]]; 201 | var_921 = (int) (sAddoktk[VAJLMKZ_MXMVAU_OHBRFS[(int) (hFhzzxalpCshbolybyAslokrjo[_w4ACl_Eb5iuB8tKft_[var_2798[(int) (iPlwrvpWkihvhctOrtubm[ZTEHAAYPJ_BISQMK[(int) (var_575[(int) (hXbuzlw[4])])]])]]])]] + Math.log1p(sAddoktk[VAJLMKZ_MXMVAU_OHBRFS[(int) (hFhzzxalpCshbolybyAslokrjo[_w4ACl_Eb5iuB8tKft_[var_2798[(int) (iPlwrvpWkihvhctOrtubm[ZTEHAAYPJ_BISQMK[(int) (var_575[(int) (hXbuzlw[2])])]])]]])]])); 202 | while (var_921 != (int) Math.max(sAddoktk[VAJLMKZ_MXMVAU_OHBRFS[(int) (hFhzzxalpCshbolybyAslokrjo[_w4ACl_Eb5iuB8tKft_[var_2798[(int) (iPlwrvpWkihvhctOrtubm[ZTEHAAYPJ_BISQMK[(int) (var_575[(int) (hXbuzlw[13])])]])]]])]], sAddoktk[VAJLMKZ_MXMVAU_OHBRFS[(int) (hFhzzxalpCshbolybyAslokrjo[_w4ACl_Eb5iuB8tKft_[var_2798[(int) (iPlwrvpWkihvhctOrtubm[ZTEHAAYPJ_BISQMK[(int) (var_575[(int) (hXbuzlw[3])])]])]]])]])) { 203 | switch(var_921) { 204 | case 1691727732: 205 | g_pCbzjagbHcxgvwbj = sAddoktk[VAJLMKZ_MXMVAU_OHBRFS[(int) (hFhzzxalpCshbolybyAslokrjo[_w4ACl_Eb5iuB8tKft_[var_2798[(int) (iPlwrvpWkihvhctOrtubm[ZTEHAAYPJ_BISQMK[(int) (var_575[(int) (hXbuzlw[0])])]])]]])]]; 206 | var_921 += -(int) Math.min(sAddoktk[VAJLMKZ_MXMVAU_OHBRFS[(int) (hFhzzxalpCshbolybyAslokrjo[_w4ACl_Eb5iuB8tKft_[var_2798[(int) (iPlwrvpWkihvhctOrtubm[ZTEHAAYPJ_BISQMK[(int) (var_575[(int) (hXbuzlw[6])])]])]]])]], sAddoktk[VAJLMKZ_MXMVAU_OHBRFS[(int) (hFhzzxalpCshbolybyAslokrjo[_w4ACl_Eb5iuB8tKft_[var_2798[(int) (iPlwrvpWkihvhctOrtubm[ZTEHAAYPJ_BISQMK[(int) (var_575[(int) (hXbuzlw[17])])]])]]])]]); 207 | break; 208 | case 623706361: 209 | for (double KVCJGC : numArray) { 210 | g_pCbzjagbHcxgvwbj += Math.pow(KVCJGC - var_60, (int) (sAddoktk[VAJLMKZ_MXMVAU_OHBRFS[(int) (hFhzzxalpCshbolybyAslokrjo[_w4ACl_Eb5iuB8tKft_[var_2798[(int) (iPlwrvpWkihvhctOrtubm[ZTEHAAYPJ_BISQMK[(int) (var_575[(int) (hXbuzlw[15])])]])]]])]] - Math.log10(sAddoktk[VAJLMKZ_MXMVAU_OHBRFS[(int) (hFhzzxalpCshbolybyAslokrjo[_w4ACl_Eb5iuB8tKft_[var_2798[(int) (iPlwrvpWkihvhctOrtubm[ZTEHAAYPJ_BISQMK[(int) (var_575[(int) (hXbuzlw[10])])]])]]])]]))); 211 | } 212 | var_921 += (int) (Math.cos(sAddoktk[VAJLMKZ_MXMVAU_OHBRFS[(int) (hFhzzxalpCshbolybyAslokrjo[_w4ACl_Eb5iuB8tKft_[var_2798[(int) (iPlwrvpWkihvhctOrtubm[ZTEHAAYPJ_BISQMK[(int) (var_575[(int) (hXbuzlw[1])])]])]]])]]) + sAddoktk[VAJLMKZ_MXMVAU_OHBRFS[(int) (hFhzzxalpCshbolybyAslokrjo[_w4ACl_Eb5iuB8tKft_[var_2798[(int) (iPlwrvpWkihvhctOrtubm[ZTEHAAYPJ_BISQMK[(int) (var_575[(int) (hXbuzlw[14])])]])]]])]]); 213 | break; 214 | case 910999355: 215 | var_2533 = numArray.length; 216 | var_921 -= (int) Math.max(sAddoktk[VAJLMKZ_MXMVAU_OHBRFS[(int) (hFhzzxalpCshbolybyAslokrjo[_w4ACl_Eb5iuB8tKft_[var_2798[(int) (iPlwrvpWkihvhctOrtubm[ZTEHAAYPJ_BISQMK[(int) (var_575[(int) (hXbuzlw[5])])]])]]])]], sAddoktk[VAJLMKZ_MXMVAU_OHBRFS[(int) (hFhzzxalpCshbolybyAslokrjo[_w4ACl_Eb5iuB8tKft_[var_2798[(int) (iPlwrvpWkihvhctOrtubm[ZTEHAAYPJ_BISQMK[(int) (var_575[(int) (hXbuzlw[12])])]])]]])]]); 217 | break; 218 | case 2017195859: 219 | var_921 += -(int) (sAddoktk[VAJLMKZ_MXMVAU_OHBRFS[(int) (hFhzzxalpCshbolybyAslokrjo[_w4ACl_Eb5iuB8tKft_[var_2798[(int) (iPlwrvpWkihvhctOrtubm[ZTEHAAYPJ_BISQMK[(int) (var_575[(int) (hXbuzlw[20])])]])]]])]] + Math.sinh(sAddoktk[VAJLMKZ_MXMVAU_OHBRFS[(int) (hFhzzxalpCshbolybyAslokrjo[_w4ACl_Eb5iuB8tKft_[var_2798[(int) (iPlwrvpWkihvhctOrtubm[ZTEHAAYPJ_BISQMK[(int) (var_575[(int) (hXbuzlw[7])])]])]]])]])); 220 | break; 221 | case 420015710: 222 | for (double var_854 : numArray) { 223 | var_3498 += var_854; 224 | } 225 | var_921 -= -(int) (sAddoktk[VAJLMKZ_MXMVAU_OHBRFS[(int) (hFhzzxalpCshbolybyAslokrjo[_w4ACl_Eb5iuB8tKft_[var_2798[(int) (iPlwrvpWkihvhctOrtubm[ZTEHAAYPJ_BISQMK[(int) (var_575[(int) (hXbuzlw[9])])]])]]])]] - Math.cbrt(sAddoktk[VAJLMKZ_MXMVAU_OHBRFS[(int) (hFhzzxalpCshbolybyAslokrjo[_w4ACl_Eb5iuB8tKft_[var_2798[(int) (iPlwrvpWkihvhctOrtubm[ZTEHAAYPJ_BISQMK[(int) (var_575[(int) (hXbuzlw[19])])]])]]])]])); 226 | break; 227 | case 1663307788: 228 | var_60 = var_3498 / var_2533; 229 | var_921 = (int) (Math.exp(sAddoktk[VAJLMKZ_MXMVAU_OHBRFS[(int) (hFhzzxalpCshbolybyAslokrjo[_w4ACl_Eb5iuB8tKft_[var_2798[(int) (iPlwrvpWkihvhctOrtubm[ZTEHAAYPJ_BISQMK[(int) (var_575[(int) (hXbuzlw[16])])]])]]])]]) + sAddoktk[VAJLMKZ_MXMVAU_OHBRFS[(int) (hFhzzxalpCshbolybyAslokrjo[_w4ACl_Eb5iuB8tKft_[var_2798[(int) (iPlwrvpWkihvhctOrtubm[ZTEHAAYPJ_BISQMK[(int) (var_575[(int) (hXbuzlw[8])])]])]]])]]); 230 | break; 231 | } 232 | } 233 | return Math.sqrt(g_pCbzjagbHcxgvwbj / var_2533); 234 | } 235 | } 236 | ``` 237 | 238 | Would you even be able to tell what the obfuscated code does if you didn't know about the original source code? 239 | 240 | ## Protect your Java projects & algorithms 241 | 242 | Take no chances, use **JObfuscator** to obfuscate and protect your Java projects and algorithms. 243 | 244 | Our company has a long history in obfuscation technologies and code obfuscators (see our [x86 Assembly](https://www.pelock.com/products/obfuscator) & [AutoIt](https://www.pelock.com/products/autoit-obfuscator) obfuscators). 245 | 246 | We actively bugfix, research and develop new obfuscation strategies for our tools. 247 | 248 | You can count on our expertise and support in this field. 249 | 250 | ### Installation 251 | 252 | The preferred way of WebApi interface installation is via [pip](https://pypi.org/project/pip/). 253 | 254 | Run: 255 | 256 | ``` 257 | pip install jobfuscator 258 | ``` 259 | 260 | or 261 | 262 | ``` 263 | python3 -m pip install jobfuscator 264 | ``` 265 | 266 | And then add this import to your source code: 267 | 268 | ```python 269 | from jobfuscator import JObfuscator 270 | ``` 271 | 272 | Installation package is available at https://pypi.org/project/jobfuscator/ 273 | 274 | 275 | ### Example of obfuscating Java source code using default options 276 | 277 | ```python 278 | #!/usr/bin/env python 279 | 280 | ############################################################################### 281 | # 282 | # JObfuscator WebApi interface usage example. 283 | # 284 | # In this example we will obfuscate sample source with default options. 285 | # 286 | # Version : v1.04 287 | # Language : Python 288 | # Author : Bartosz Wójcik 289 | # Web page : https://www.pelock.com 290 | # 291 | ############################################################################### 292 | 293 | # 294 | # include JObfuscator module 295 | # 296 | from jobfuscator import JObfuscator 297 | 298 | # 299 | # if you don't want to use Python module, you can import directly from the file 300 | # 301 | #from pelock.jobfuscator import JObfuscator 302 | 303 | # 304 | # create JObfuscator class instance (we are using our activation key) 305 | # 306 | myJObfuscator = JObfuscator("ABCD-ABCD-ABCD-ABCD") 307 | 308 | # 309 | # source code in Java format 310 | # 311 | sourceCode = """import java.util.*; 312 | import java.lang.*; 313 | import java.io.*; 314 | 315 | // 316 | // you must include custom annotation 317 | // to enable entire class or a single 318 | // method obfuscation 319 | // 320 | @Obfuscate 321 | class Ideone 322 | { 323 | //@Obfuscate 324 | public static double calculateSD(double numArray[]) 325 | { 326 | double sum = 0.0, standardDeviation = 0.0; 327 | int length = numArray.length; 328 | 329 | for(double num : numArray) { 330 | sum += num; 331 | } 332 | 333 | double mean = sum/length; 334 | 335 | for(double num: numArray) { 336 | standardDeviation += Math.pow(num - mean, 2); 337 | } 338 | 339 | return Math.sqrt(standardDeviation/length); 340 | } 341 | 342 | // 343 | // selective obfuscation strategies 344 | // can be applied for the entire 345 | // class or a single method (by 346 | // default all obfuscation strategies 347 | // are enabled when you use @Obfuscate 348 | // annotation alone) 349 | // 350 | //@Obfuscate( 351 | // ints_math_crypt = true, 352 | // crypt_strings = true, 353 | // rename_methods = false, 354 | // rename_variables = true, 355 | // shuffle_methods = true, 356 | // mix_code_flow = true, 357 | // ints_to_arrays = true, 358 | // dbls_to_arrays = true 359 | // ) 360 | public static void main(String[] args) { 361 | 362 | double[] numArray = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 363 | double SD = calculateSD(numArray); 364 | 365 | System.out.format("Standard Deviation = %.6f", SD); 366 | } 367 | }""" 368 | 369 | # 370 | # by default all obfuscation options are enabled, so we can just simply call 371 | # 372 | result = myJObfuscator.obfuscate_java_source(sourceCode) 373 | 374 | # 375 | # it's also possible to pass a Java source file path instead of a string with the source e.g. 376 | # 377 | # result = myJObfuscator.obfuscate_java_file("/path/to/project/source.java") 378 | 379 | # 380 | # result[] array holds the obfuscation results as well as other information 381 | # 382 | # result["error"] - error code 383 | # result["output"] - obfuscated code 384 | # result["demo"] - was it used in demo mode (invalid or empty activation key was used) 385 | # result["credits_left"] - usage credits left after this operation 386 | # result["credits_total"] - total number of credits for this activation code 387 | # result["expired"] - if this was the last usage credit for the activation key it will be set to True 388 | # 389 | if result and "error" in result: 390 | 391 | # display obfuscated code 392 | if result["error"] == JObfuscator.ERROR_SUCCESS: 393 | 394 | # format output code for HTML display 395 | print(result["output"]) 396 | 397 | else: 398 | print(f'An error occurred, error code: {result["error"]}') 399 | 400 | else: 401 | print("Something unexpected happen while trying to obfuscate the code.") 402 | ``` 403 | 404 | ### An example of obfuscating Java source code with customized obfuscation strategies 405 | 406 | ```python 407 | #!/usr/bin/env python 408 | 409 | ############################################################################### 410 | # 411 | # JObfuscator WebApi interface usage example. 412 | # 413 | # In this example we will obfuscate sample source with custom options. 414 | # 415 | # Version : v1.04 416 | # Language : Python 417 | # Author : Bartosz Wójcik 418 | # Web page : https://www.pelock.com 419 | # 420 | ############################################################################### 421 | 422 | # 423 | # include JObfuscator module 424 | # 425 | from jobfuscator import JObfuscator 426 | 427 | # 428 | # if you don't want to use Python module, you can import directly from the file 429 | # 430 | #from pelock.jobfuscator import JObfuscator 431 | 432 | # 433 | # create JObfuscator class instance (we are using our activation key) 434 | # 435 | myJObfuscator = JObfuscator("ABCD-ABCD-ABCD-ABCD") 436 | 437 | # 438 | # global obfuscation options 439 | # 440 | # when disabled will discard any @Obfuscate annotation declaration 441 | # in the Java source code 442 | # 443 | # you can disable a particular obfuscation strategy globally if it 444 | # fails or you don't want to use it without modifying the source codes 445 | # 446 | # by default all obfuscation strategies are enabled 447 | # 448 | 449 | # 450 | # should the source code be compressed (both input & compressed) 451 | # 452 | myJObfuscator.enableCompression = True 453 | 454 | # 455 | # change linear code execution flow to non-linear version 456 | # 457 | myJObfuscator.mixCodeFlow = True 458 | 459 | # 460 | # rename variable names to random string values 461 | # 462 | myJObfuscator.renameVariables = True 463 | 464 | # 465 | # rename method names to random string values 466 | # 467 | myJObfuscator.renameMethods = True 468 | 469 | # 470 | # shuffle order of methods in the output source 471 | # 472 | myJObfuscator.shuffleMethods = True 473 | 474 | # 475 | # encrypt integers using more than 15 floating point math functions from the java.lang.Math.* class 476 | # 477 | myJObfuscator.intsMathCrypt = True 478 | 479 | # 480 | # encrypt strings using polymorphic encryption algorithms 481 | # 482 | myJObfuscator.cryptStrings = True 483 | 484 | # 485 | # for each method, extract all possible integers from the code and store them in an array 486 | # 487 | myJObfuscator.intsToArrays = True 488 | 489 | # 490 | # for each method, extract all possible doubles from the code and store them in an array 491 | # 492 | myJObfuscator.dblsToArrays = True 493 | 494 | # 495 | # source code in Java format 496 | # 497 | sourceCode = """import java.util.*; 498 | import java.lang.*; 499 | import java.io.*; 500 | 501 | // 502 | // you must include custom annotation 503 | // to enable entire class or a single 504 | // method obfuscation 505 | // 506 | @Obfuscate 507 | class Ideone 508 | { 509 | //@Obfuscate 510 | public static double calculateSD(double numArray[]) 511 | { 512 | double sum = 0.0, standardDeviation = 0.0; 513 | int length = numArray.length; 514 | 515 | for(double num : numArray) { 516 | sum += num; 517 | } 518 | 519 | double mean = sum/length; 520 | 521 | for(double num: numArray) { 522 | standardDeviation += Math.pow(num - mean, 2); 523 | } 524 | 525 | return Math.sqrt(standardDeviation/length); 526 | } 527 | 528 | // 529 | // selective obfuscation strategies 530 | // can be applied for the entire 531 | // class or a single method (by 532 | // default all obfuscation strategies 533 | // are enabled when you use @Obfuscate 534 | // annotation alone) 535 | // 536 | //@Obfuscate( 537 | // ints_math_crypt = true, 538 | // crypt_strings = true, 539 | // rename_methods = false, 540 | // rename_variables = true, 541 | // shuffle_methods = true, 542 | // mix_code_flow = true, 543 | // ints_to_arrays = true, 544 | // dbls_to_arrays = true 545 | // ) 546 | public static void main(String[] args) { 547 | 548 | double[] numArray = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 549 | double SD = calculateSD(numArray); 550 | 551 | System.out.format("Standard Deviation = %.6f", SD); 552 | } 553 | }""" 554 | 555 | # 556 | # by default all obfuscation options are enabled, so we can just simply call 557 | # 558 | result = myJObfuscator.obfuscate_java_source(sourceCode) 559 | 560 | # 561 | # result[] array holds the obfuscation results as well as other information 562 | # 563 | # result["error"] - error code 564 | # result["output"] - obfuscated code 565 | # result["demo"] - was it used in demo mode (invalid or empty activation key was used) 566 | # result["credits_left"] - usage credits left after this operation 567 | # result["credits_total"] - total number of credits for this activation code 568 | # result["expired"] - if this was the last usage credit for the activation key it will be set to True 569 | # 570 | if result and "error" in result: 571 | 572 | # display obfuscated code 573 | if result["error"] == JObfuscator.ERROR_SUCCESS: 574 | 575 | # format output code for HTML display 576 | print(result["output"]) 577 | else: 578 | print(f'An error occurred, error code: {result["error"]}') 579 | 580 | else: 581 | print("Something unexpected happen while trying to obfuscate the code.") 582 | ``` 583 | 584 | #### Example of how to check the activation key status 585 | 586 | ```python 587 | #!/usr/bin/env python 588 | 589 | ############################################################################### 590 | # 591 | # JObfuscator WebApi interface usage example. 592 | # 593 | # In this example we will verify our activation key status. 594 | # 595 | # Version : v1.01 596 | # Language : Python 597 | # Author : Bartosz Wójcik 598 | # Web page : https://www.pelock.com 599 | # 600 | ############################################################################### 601 | 602 | # 603 | # include JObfuscator module 604 | # 605 | from jobfuscator import JObfuscator 606 | 607 | # 608 | # if you don't want to use Python module, you can import directly from the file 609 | # 610 | #from pelock.jobfuscator import JObfuscator 611 | 612 | # 613 | # create JObfuscator class instance (we are using our activation key) 614 | # 615 | myJObfuscator = JObfuscator("ABCD-ABCD-ABCD-ABCD") 616 | 617 | # 618 | # login to the service 619 | # 620 | result = myJObfuscator.login() 621 | 622 | # 623 | # result[] array holds the information about the license 624 | # 625 | # result["demo"] - is it a demo mode (invalid or empty activation key was used) 626 | # result["credits_left"] - usage credits left after this operation 627 | # result["credits_total"] - total number of credits for this activation code 628 | # result["string_limit"] - max. source code size allowed (it's 1500 bytes for demo mode) 629 | # 630 | if result: 631 | 632 | print(f'Demo version status - {"True" if result["demo"] else "False"}') 633 | print(f'Usage credits left - {result["credits_left"]}') 634 | print(f'Total usage credits - {result["credits_total"]}') 635 | print(f'Max. source code size - {result["string_limit"]}') 636 | 637 | else: 638 | print("Something unexpected happen while trying to login to the service.") 639 | ``` 640 | 641 | ## Use Java Obfuscator Online 642 | 643 | Online interface for the JObfuscator is available at: 644 | 645 | https://www.pelock.com/jobfuscator/ 646 | 647 | ## Windows & Linux GUI client and command line version 648 | 649 | JObfuscator also comes with full GUI version for Windows and Linux (requires [Mono](https://www.mono-project.com/)). 650 | 651 | You can download it at: 652 | 653 | https://www.pelock.com/products/jobfuscator/download 654 | 655 | An additional command line version is included in the installation package. 656 | 657 | It is compatible with Windows (.NET) and Linux (Mono). 658 | 659 | ### Main JObfuscator window 660 | 661 | ![JObfuscator Java Obfuscator Windows Client](https://www.pelock.com/img/en/products/jobfuscator/jobfuscator-java-obfuscator-obfuscation-1-0-main.png) 662 | 663 | ### Obfuscation options: 664 | 665 | ![JObfuscator Java Obfuscator Obfuscation Options](https://www.pelock.com/img/en/products/jobfuscator/jobfuscator-java-obfuscator-obfuscation-1-0-options.png) 666 | 667 | ### Obfuscated Java code 668 | 669 | ![JObfuscator Obfuscated Java Code](https://www.pelock.com/img/en/products/jobfuscator/jobfuscator-java-obfuscator-obfuscation-1-0-obfuscated.png) 670 | 671 | ### JObfuscator command line version 672 | 673 | ![JObfuscator Command Line Version](https://www.pelock.com//img/en/products/jobfuscator/jobfuscator-java-obfuscator-obfuscation-1-0-console-comand-line.png) 674 | 675 | Java obfuscation can be integrated into your build process or any other batch operation using the JObfuscator command line version. 676 | 677 | Bartosz Wójcik 678 | 679 | * Visit my site at — https://www.pelock.com 680 | * Twitter — https://twitter.com/PELock 681 | * GitHub — https://github.com/PELock -------------------------------------------------------------------------------- /examples/JObfuscatorExample.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | ############################################################################### 4 | # 5 | # JObfuscator WebApi interface usage example. 6 | # 7 | # In this example we will obfuscate sample source with custom options. 8 | # 9 | # Version : v1.04 10 | # Language : Python 11 | # Author : Bartosz Wójcik 12 | # Web page : https://www.pelock.com 13 | # 14 | ############################################################################### 15 | 16 | # 17 | # include JObfuscator module 18 | # 19 | from jobfuscator import JObfuscator 20 | 21 | # 22 | # if you don't want to use Python module, you can import directly from the file 23 | # 24 | #from pelock.jobfuscator import JObfuscator 25 | 26 | # 27 | # create JObfuscator class instance (we are using our activation key) 28 | # 29 | myJObfuscator = JObfuscator("ABCD-ABCD-ABCD-ABCD") 30 | 31 | # 32 | # global obfuscation options 33 | # 34 | # when disabled will discard any @Obfuscate annotation declaration 35 | # in the Java source code 36 | # 37 | # you can disable a particular obfuscation strategy globally if it 38 | # fails or you don't want to use it without modifying the source codes 39 | # 40 | # by default all obfuscation strategies are enabled 41 | # 42 | 43 | # 44 | # should the source code be compressed (both input & compressed) 45 | # 46 | myJObfuscator.enableCompression = True 47 | 48 | # 49 | # change linear code execution flow to non-linear version 50 | # 51 | myJObfuscator.mixCodeFlow = True 52 | 53 | # 54 | # rename variable names to random string values 55 | # 56 | myJObfuscator.renameVariables = True 57 | 58 | # 59 | # rename method names to random string values 60 | # 61 | myJObfuscator.renameMethods = True 62 | 63 | # 64 | # shuffle order of methods in the output source 65 | # 66 | myJObfuscator.shuffleMethods = True 67 | 68 | # 69 | # encrypt integers using more than 15 floating point math functions from the java.lang.Math.* class 70 | # 71 | myJObfuscator.intsMathCrypt = True 72 | 73 | # 74 | # encrypt strings using polymorphic encryption algorithms 75 | # 76 | myJObfuscator.cryptStrings = True 77 | 78 | # 79 | # for each method, extract all possible integers from the code and store them in an array 80 | # 81 | myJObfuscator.intsToArrays = True 82 | 83 | # 84 | # for each method, extract all possible doubles from the code and store them in an array 85 | # 86 | myJObfuscator.dblsToArrays = True 87 | 88 | # 89 | # source code in Java format 90 | # 91 | sourceCode = """import java.util.*; 92 | import java.lang.*; 93 | import java.io.*; 94 | 95 | // 96 | // you must include custom annotation 97 | // to enable entire class or a single 98 | // method obfuscation 99 | // 100 | @Obfuscate 101 | class Ideone 102 | { 103 | //@Obfuscate 104 | public static double calculateSD(double numArray[]) 105 | { 106 | double sum = 0.0, standardDeviation = 0.0; 107 | int length = numArray.length; 108 | 109 | for(double num : numArray) { 110 | sum += num; 111 | } 112 | 113 | double mean = sum/length; 114 | 115 | for(double num: numArray) { 116 | standardDeviation += Math.pow(num - mean, 2); 117 | } 118 | 119 | return Math.sqrt(standardDeviation/length); 120 | } 121 | 122 | // 123 | // selective obfuscation strategies 124 | // can be applied for the entire 125 | // class or a single method (by 126 | // default all obfuscation strategies 127 | // are enabled when you use @Obfuscate 128 | // annotation alone) 129 | // 130 | //@Obfuscate( 131 | // ints_math_crypt = true, 132 | // crypt_strings = true, 133 | // rename_methods = false, 134 | // rename_variables = true, 135 | // shuffle_methods = true, 136 | // mix_code_flow = true, 137 | // ints_to_arrays = true, 138 | // dbls_to_arrays = true 139 | // ) 140 | public static void main(String[] args) { 141 | 142 | double[] numArray = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 143 | double SD = calculateSD(numArray); 144 | 145 | System.out.format("Standard Deviation = %.6f", SD); 146 | } 147 | }""" 148 | 149 | # 150 | # by default all obfuscation options are enabled, so we can just simply call 151 | # 152 | result = myJObfuscator.obfuscate_java_source(sourceCode) 153 | 154 | # 155 | # result[] array holds the obfuscation results as well as other information 156 | # 157 | # result["error"] - error code 158 | # result["output"] - obfuscated code 159 | # result["demo"] - was it used in demo mode (invalid or empty activation key was used) 160 | # result["credits_left"] - usage credits left after this operation 161 | # result["credits_total"] - total number of credits for this activation code 162 | # result["expired"] - if this was the last usage credit for the activation key it will be set to True 163 | # 164 | if result and "error" in result: 165 | 166 | # display obfuscated code 167 | if result["error"] == JObfuscator.ERROR_SUCCESS: 168 | 169 | # format output code for HTML display 170 | print(result["output"]) 171 | else: 172 | print(f'An error occurred, error code: {result["error"]}') 173 | 174 | else: 175 | print("Something unexpected happen while trying to obfuscate the code.") 176 | -------------------------------------------------------------------------------- /examples/JObfuscatorExampleIsDemo.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | ############################################################################### 4 | # 5 | # JObfuscator WebApi interface usage example. 6 | # 7 | # In this example we will verify our activation key status. 8 | # 9 | # Version : v1.04 10 | # Language : Python 11 | # Author : Bartosz Wójcik 12 | # Web page : https://www.pelock.com 13 | # 14 | ############################################################################### 15 | 16 | # 17 | # include JObfuscator module 18 | # 19 | from jobfuscator import JObfuscator 20 | 21 | # 22 | # if you don't want to use Python module, you can import directly from the file 23 | # 24 | #from pelock.jobfuscator import JObfuscator 25 | 26 | # 27 | # create JObfuscator class instance (we are using our activation key) 28 | # 29 | myJObfuscator = JObfuscator("ABCD-ABCD-ABCD-ABCD") 30 | 31 | # 32 | # login to the service 33 | # 34 | result = myJObfuscator.login() 35 | 36 | # 37 | # result[] array holds the information about the license 38 | # 39 | # result["demo"] - is it a demo mode (invalid or empty activation key was used) 40 | # result["credits_left"] - usage credits left after this operation 41 | # result["credits_total"] - total number of credits for this activation code 42 | # result["string_limit"] - max. source code size allowed (it's 1500 bytes for demo mode) 43 | # 44 | if result: 45 | 46 | print(f'Demo version status - {"True" if result["demo"] else "False"}') 47 | print(f'Usage credits left - {result["credits_left"]}') 48 | print(f'Total usage credits - {result["credits_total"]}') 49 | print(f'Max. source code size - {result["string_limit"]}') 50 | 51 | else: 52 | print("Something unexpected happen while trying to login to the service.") 53 | -------------------------------------------------------------------------------- /examples/JObfuscatorExampleSimple.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | ############################################################################### 4 | # 5 | # JObfuscator WebApi interface usage example. 6 | # 7 | # In this example we will obfuscate sample source with default options. 8 | # 9 | # Version : v1.04 10 | # Language : Python 11 | # Author : Bartosz Wójcik 12 | # Web page : https://www.pelock.com 13 | # 14 | ############################################################################### 15 | 16 | # 17 | # include JObfuscator module 18 | # 19 | from jobfuscator import JObfuscator 20 | 21 | # 22 | # if you don't want to use Python module, you can import directly from the file 23 | # 24 | #from pelock.jobfuscator import JObfuscator 25 | 26 | # 27 | # create JObfuscator class instance (we are using our activation key) 28 | # 29 | myJObfuscator = JObfuscator("ABCD-ABCD-ABCD-ABCD") 30 | 31 | # 32 | # source code in Java format 33 | # 34 | sourceCode = """import java.util.*; 35 | import java.lang.*; 36 | import java.io.*; 37 | 38 | // 39 | // you must include custom annotation 40 | // to enable entire class or a single 41 | // method obfuscation 42 | // 43 | @Obfuscate 44 | class Ideone 45 | { 46 | //@Obfuscate 47 | public static double calculateSD(double numArray[]) 48 | { 49 | double sum = 0.0, standardDeviation = 0.0; 50 | int length = numArray.length; 51 | 52 | for(double num : numArray) { 53 | sum += num; 54 | } 55 | 56 | double mean = sum/length; 57 | 58 | for(double num: numArray) { 59 | standardDeviation += Math.pow(num - mean, 2); 60 | } 61 | 62 | return Math.sqrt(standardDeviation/length); 63 | } 64 | 65 | // 66 | // selective obfuscation strategies 67 | // can be applied for the entire 68 | // class or a single method (by 69 | // default all obfuscation strategies 70 | // are enabled when you use @Obfuscate 71 | // annotation alone) 72 | // 73 | //@Obfuscate( 74 | // ints_math_crypt = true, 75 | // crypt_strings = true, 76 | // rename_methods = false, 77 | // rename_variables = true, 78 | // shuffle_methods = true, 79 | // mix_code_flow = true, 80 | // ints_to_arrays = true, 81 | // dbls_to_arrays = true 82 | // ) 83 | public static void main(String[] args) { 84 | 85 | double[] numArray = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 86 | double SD = calculateSD(numArray); 87 | 88 | System.out.format("Standard Deviation = %.6f", SD); 89 | } 90 | }""" 91 | 92 | # 93 | # by default all obfuscation options are enabled, so we can just simply call 94 | # 95 | result = myJObfuscator.obfuscate_java_source(sourceCode) 96 | 97 | # 98 | # it's also possible to pass a Java source file path instead of a string with the source e.g. 99 | # 100 | # result = myJObfuscator.obfuscate_java_file("/path/to/project/source.java") 101 | 102 | # 103 | # result[] array holds the obfuscation results as well as other information 104 | # 105 | # result["error"] - error code 106 | # result["output"] - obfuscated code 107 | # result["demo"] - was it used in demo mode (invalid or empty activation key was used) 108 | # result["credits_left"] - usage credits left after this operation 109 | # result["credits_total"] - total number of credits for this activation code 110 | # result["expired"] - if this was the last usage credit for the activation key it will be set to True 111 | # 112 | if result and "error" in result: 113 | 114 | # display obfuscated code 115 | if result["error"] == JObfuscator.ERROR_SUCCESS: 116 | 117 | # format output code for HTML display 118 | print(result["output"]) 119 | 120 | else: 121 | print(f'An error occurred, error code: {result["error"]}') 122 | 123 | else: 124 | print("Something unexpected happen while trying to obfuscate the code.") 125 | -------------------------------------------------------------------------------- /jobfuscator/__init__.py: -------------------------------------------------------------------------------- 1 | from jobfuscator.jobfuscator import * 2 | -------------------------------------------------------------------------------- /jobfuscator/jobfuscator.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | ############################################################################### 4 | # 5 | # JObfuscator is a source code obfuscator for the Java programming language. 6 | # Obfuscate and protect your Java source code and algorithms from hacking, 7 | # cracking, reverse engineering, decompilation, and technology theft. 8 | # 9 | # JObfuscator provides advanced Java source code parsing based on AST trees, 10 | # multiple advanced obfuscation strategies are available. 11 | # 12 | # Version : JObfuscator v1.04 13 | # Python : Python v3 14 | # Dependencies : requests (https://pypi.python.org/pypi/requests/) 15 | # Author : Bartosz Wójcik (support@pelock.com) 16 | # Project : https://www.pelock.com/products/jobfuscator 17 | # Homepage : https://www.pelock.com 18 | # 19 | ############################################################################### 20 | 21 | import zlib 22 | import base64 23 | 24 | # required external package - install with "pip install requests" 25 | import requests 26 | 27 | 28 | class JObfuscator(object): 29 | """JObfuscator module""" 30 | 31 | # 32 | # @var string default JObfuscator WebApi endpoint 33 | # 34 | API_URL = "https://www.pelock.com/api/jobfuscator/v1" 35 | 36 | # 37 | # @var string WebApi key for the service 38 | # 39 | _apiKey = "" 40 | 41 | # 42 | # @var bool should the source code be compressed 43 | # 44 | enableCompression = True 45 | 46 | # 47 | # @var bool change linear code execution flow to non-linear version 48 | # 49 | mixCodeFlow = True 50 | 51 | # 52 | # @var bool rename variable names to random string values 53 | # 54 | renameVariables = True 55 | 56 | # 57 | # @var bool rename method names to random string values 58 | # 59 | renameMethods = True 60 | 61 | # 62 | # @var bool shuffle functions order in the output source 63 | # 64 | shuffleMethods = True 65 | 66 | # 67 | # @var bool encrypt integers using more than 15 floating point math functions from the java.lang.Math.* class 68 | # 69 | intsMathCrypt = True 70 | 71 | # 72 | # @var bool encrypt strings using polymorphic encryption algorithms 73 | # 74 | cryptStrings = True 75 | 76 | # 77 | # @var bool for each method, extract all possible integers from the code and store them in an array 78 | # 79 | intsToArrays = True 80 | 81 | # 82 | # @var bool for each method, extract all possible doubles from the code and store them in an array 83 | # 84 | dblsToArrays = True 85 | 86 | # 87 | # @var integer success 88 | # 89 | ERROR_SUCCESS = 0 90 | 91 | # 92 | # @var integer invalid size for source code (it's 1500 bytes max. for demo version) 93 | # 94 | ERROR_INPUT_SIZE = 1 95 | 96 | # 97 | # @var integer input source is empty 98 | # 99 | ERROR_INPUT = 2 100 | 101 | # 102 | # @var integer Java source code parsing error 103 | # 104 | ERROR_PARSING = 3 105 | 106 | # 107 | # @var integer Java parsed code obfuscation error 108 | # 109 | ERROR_OBFUSCATION = 4 110 | 111 | # 112 | # @var integer error while generating output code 113 | # 114 | ERROR_OUTPUT = 5 115 | 116 | def __init__(self, api_key=None, enable_all_obfuscation_options=True): 117 | """Initialize JObfuscator class 118 | 119 | :param api_key: Activation key for the service (it can be empty for demo mode) 120 | :param enable_all_obfuscation_options: Enable or disable all of the obfuscation options 121 | """ 122 | 123 | self._apiKey = api_key 124 | 125 | self.enableCompression = enable_all_obfuscation_options 126 | self.mixCodeFlow = enable_all_obfuscation_options 127 | self.renameVariables = enable_all_obfuscation_options 128 | self.renameMethods = enable_all_obfuscation_options 129 | self.shuffleMethods = enable_all_obfuscation_options 130 | self.intsMathCrypt = enable_all_obfuscation_options 131 | self.cryptStrings = enable_all_obfuscation_options 132 | self.intsToArrays = enable_all_obfuscation_options 133 | self.dblsToArrays = enable_all_obfuscation_options 134 | 135 | def login(self): 136 | """Login to the service and get the information about the current license limits 137 | 138 | :return: An array with the results or False on error 139 | :rtype: bool,dict 140 | """ 141 | 142 | # parameters 143 | params = {"command": "login"} 144 | 145 | return self.post_request(params) 146 | 147 | def obfuscate_java_file(self, java_file_path): 148 | """Obfuscate Java source code file using provided parameters 149 | 150 | :param java_file_path: Java source code *.java file path 151 | :return: An array with the results or False on error 152 | :rtype: bool,dict 153 | """ 154 | 155 | source_file = open(java_file_path, 'r') 156 | source = source_file.read() 157 | source_file.close() 158 | 159 | if not source: 160 | return False 161 | 162 | return self.obfuscate_java_source(source) 163 | 164 | def obfuscate_java_source(self, java_source): 165 | """Obfuscate Java source code using provided parameters 166 | 167 | :param java_source: Java source code 168 | :return: An array with the results or False on error 169 | :rtype: bool,dict 170 | """ 171 | 172 | # additional parameters 173 | params_array = {"command": "obfuscate", "source": java_source} 174 | 175 | return self.post_request(params_array) 176 | 177 | def post_request(self, params_array): 178 | """Send a POST request to the server 179 | 180 | :param params_array: An array with the parameters 181 | :return: An array with the results or false on error 182 | :rtype: bool,dict 183 | """ 184 | 185 | # add activation key to the parameters array 186 | if self._apiKey: 187 | params_array["key"] = self._apiKey 188 | 189 | # 190 | # obfuscation strategies 191 | # 192 | if self.mixCodeFlow: 193 | params_array["mix_code_flow"] = "1" 194 | if self.renameVariables: 195 | params_array["rename_variables"] = "1" 196 | if self.renameMethods: 197 | params_array["rename_methods"] = "1" 198 | if self.shuffleMethods: 199 | params_array["shuffle_methods"] = "1" 200 | if self.intsMathCrypt: 201 | params_array["ints_math_crypt"] = "1" 202 | if self.cryptStrings: 203 | params_array["crypt_strings"] = "1" 204 | if self.intsToArrays: 205 | params_array["ints_to_arrays"] = "1" 206 | if self.dblsToArrays: 207 | params_array["dbls_to_arrays"] = "1" 208 | 209 | # 210 | # check if compression is enabled 211 | # 212 | if "source" in params_array and self.enableCompression and params_array["source"]: 213 | 214 | compressed_data = zlib.compress(bytes(params_array["source"], 'utf-8'), 9) 215 | base64_encoded_data = base64.b64encode(compressed_data).decode() 216 | 217 | params_array["source"] = base64_encoded_data 218 | params_array["compression"] = "1" 219 | 220 | response = requests.post(self.API_URL, data=params_array) 221 | 222 | # no response at all or an invalid response code 223 | if not response or not response.ok: 224 | return False 225 | 226 | # decode to json array 227 | result = response.json() 228 | 229 | # depack output code back into the string 230 | if "output" in result and self.enableCompression and result["error"] == self.ERROR_SUCCESS: 231 | 232 | result["output"] = str(zlib.decompress(base64.b64decode(result["output"])), "utf-8") 233 | 234 | # return original JSON response code 235 | return result 236 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | with open("README.md", "r", encoding="utf-8") as fh: 4 | long_description = fh.read() 5 | 6 | setuptools.setup(name='jobfuscator', 7 | 8 | version='1.0.4', 9 | 10 | description='JObfuscator is a source code obfuscator for the Java programming language. Obfuscate and protect your Java source code and algorithms from hacking, cracking, reverse engineering, decompilation, and technology theft. JObfuscator provides advanced Java source code parsing based on AST trees, multiple advanced obfuscation strategies are available.', 11 | long_description=long_description, 12 | long_description_content_type="text/markdown", 13 | 14 | keywords="java jar war class source obfuscator obfuscation obfuscate decompile decompiler decompilation", 15 | 16 | url='https://www.pelock.com', 17 | 18 | author='Bartosz Wójcik', 19 | author_email='support@pelock.com', 20 | 21 | license='Apache-2.0', 22 | 23 | packages=['jobfuscator'], 24 | 25 | install_requires=[ 26 | 'requests', 27 | ], 28 | 29 | zip_safe=False, 30 | 31 | classifiers=[ 32 | "Development Status :: 5 - Production/Stable", 33 | "Topic :: Software Development :: Libraries :: Python Modules", 34 | "Topic :: Security", 35 | "Natural Language :: English", 36 | "License :: OSI Approved :: Apache Software License", 37 | "Programming Language :: Python :: 3", 38 | "Programming Language :: Java" 39 | ], 40 | ) --------------------------------------------------------------------------------