Last active
August 15, 2021 16:10
-
-
Save XenocodeRCE/8a19f9926e1f99a7028d5cc7f4c2aa1c to your computer and use it in GitHub Desktop.
jobfuscator deob poc blog
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using Microsoft.CodeDom.Providers.DotNetCompilerPlatform; | |
| using System; | |
| using System.CodeDom.Compiler; | |
| using System.Collections.Generic; | |
| using System.Globalization; | |
| using System.Linq; | |
| using System.Net; | |
| using System.Text.RegularExpressions; | |
| using System.Threading; | |
| using System.Web; | |
| namespace JDeobfuscator | |
| { | |
| partial class Program | |
| { | |
| public static string obfuscatedCode = | |
| //public static double Cvrhllagj(double[] numArray) { | |
| @"double[] P_w8f_fgCeIaTRV_p_7ndn1q = { 12.458764457962426, 11.774898185844052, 0.04689317746733355, 1.2969850392387325, 10.611000853475497, 9.444500548246086, 3.0010750907231962, 8.214242224683236, 5.35369950946601, 2.2967911566451398, 6.337725947635746, 4.1084483812734645, 7.644315091317943 }; | |
| double[] sGCdYD_QW_Gul63_3CSg_ = { 0.49541834233909826, 11.108651132591769, 7.333755559903432, 6.312855145298063, 1.5379281965905527, 12.772400418512902, 8.309486663437598, 5.3210172938720985, 9.210460937962365, 2.363189009623283, 4.940208607912868, 10.77765599145965, 3.6289456913818885 }; | |
| int[] var_2298 = { 3, 9, 0, 2, 1, 12, 6, 5, 7, 11, 10, 8, 4 }; | |
| double[] EDDZK = { 7.6302934574042345, 0.48647822072817365, 3.7469304623780424, 12.890310694553246, 4.424076412168135, 2.2644183141716656, 6.920101302627346, 8.083165735359255, 5.165626087210683, 11.703452832675005, 10.738901075350242, 1.0883621127571155, 9.544276127666178 }; | |
| double[] g_tDidrpacwyeVyrhew = { 11.798076555261488, 8.72840963335931, 0.847652032382205, 12.10679943129788, 5.8222289639469365, 4.878753279512456, 10.99689186434766, 3.6408793996380444, 9.408845272345676, 7.918413795369193, 2.3988605196020854, 1.4930951762342022, 6.7899955325046655 }; | |
| int[] var_1154 = { 5, 8, 7, 1, 2, 11, 10, 3, 9, 12, 6, 4, 0 }; | |
| double[] ZICHO_IKOCUKWU_EGCSZ = { 6.775326581635852, 9.621039661701861, 12.952011031726164, 7.5069637614684535, 4.2261314021485346, 8.16884574736118, 1.9697586768349638, 5.801733765049773, 2.6365953406299067, 10.176009478815065, 3.685945767542533, 0.04414493793098155, 11.89560568784708 }; | |
| int[] tRajtwqypTizszcm = { 11, 6, 12, 10, 8, 3, 9, 1, 5, 0, 2, 4, 7 }; | |
| double[] g_aIpfzqie = { 7.032984234292641, 3.077571847567626, 1.304402294825222, 9.971923825808249, 2.013574193141939, 0.5363226958883169, 8.713747398802738, 6.78327741700414, 11.987125657521801, 10.74369246398476, 5.5968122609455895, 12.947441411228526, 4.006650348315246 }; | |
| double[] var_2151 = { 11.920731024798778, 9.592900712432833, 12.16861901516612, 3.2521783648818703, 4.239994892469965, 8.912937596299136, 0.95693862125048, 7.690758594164553, 1.9067848640629919, 5.450262221142008, 2.210675252862015, 10.034569234008435, 6.565508816559017 }; | |
| double[] var_374 = { 1.1366782944434E8, 1.13666273E8, 5.4788174587182E8, 1.18186762692505E9, 10.49125, 5.8241904281803E8, 3.57591, 4.0146879430169E8, 0.0, 8.3566175464046E8, 17.84958, 1.69642573461452E9, 1.15575422582617E9 }; | |
| int[] dZgpaaaqvq = { 0, 4, 5, 3, 2, 1 }; | |
| double[] BGUKAYXAD_BFMZSMVC = { 4.526450652360194, 2.456416333945702, 1.0330716052261302, 5.407718737871458, 3.9972967568629003, 0.6076960783622827 }; | |
| double[] Dex84zYkyGeLg__v1e_7 = { 2.527836620133729, 1.3533463614317913, 0.8179501060260149, 5.196922560109992, 3.185561580072823, 4.410568962313531 }; | |
| double[] a_1B_Qd551G_4e7U9Wb = { 0.7793633984621939, 5.307756442540827, 1.9408882313798674, 2.8015442173243805, 4.550867755450923, 3.690852883081302 }; | |
| int[] var_1444 = { 2, 4, 5, 1, 3, 0 }; | |
| double[] eXapdnpozvaRequrgourWyymkm = { 4.382221215354622, 1.6097981199813254, 0.08523247562916646, 3.44010515396284, 5.070403342886876, 2.6125009748617565 }; | |
| int[] var_1286 = { 2, 0, 4, 5, 1, 3 }; | |
| double[] var_2980 = { 14.472239053915706, 0.4626801974458849, 65535.27131860518, 25.960673081154674, 2.207841502966151, 21667.351884658172 }; | |
| int UHIQAXCIL_MESOZZ_TSQTEKKV = (int) (var_374[(int) (var_2151[(int) (g_aIpfzqie[tRajtwqypTizszcm[(int) (ZICHO_IKOCUKWU_EGCSZ[var_1154[(int) (g_tDidrpacwyeVyrhew[(int) (EDDZK[var_2298[(int) (sGCdYD_QW_Gul63_3CSg_[(int) (P_w8f_fgCeIaTRV_p_7ndn1q[4])])]])])]])]])])] - Math.sinh(var_374[(int) (var_2151[(int) (g_aIpfzqie[tRajtwqypTizszcm[(int) (ZICHO_IKOCUKWU_EGCSZ[var_1154[(int) (g_tDidrpacwyeVyrhew[(int) (EDDZK[var_2298[(int) (sGCdYD_QW_Gul63_3CSg_[(int) (P_w8f_fgCeIaTRV_p_7ndn1q[8])])]])])]])]])])])); | |
| double[] var_3457 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; | |
| double var_3878 = var_374[(int) (var_2151[(int) (g_aIpfzqie[tRajtwqypTizszcm[(int) (ZICHO_IKOCUKWU_EGCSZ[var_1154[(int) (g_tDidrpacwyeVyrhew[(int) (EDDZK[var_2298[(int) (sGCdYD_QW_Gul63_3CSg_[(int) (P_w8f_fgCeIaTRV_p_7ndn1q[2])])]])])]])]])])]; | |
| UHIQAXCIL_MESOZZ_TSQTEKKV = (int) (var_374[(int) (var_2151[(int) (g_aIpfzqie[tRajtwqypTizszcm[(int) (ZICHO_IKOCUKWU_EGCSZ[var_1154[(int) (g_tDidrpacwyeVyrhew[(int) (EDDZK[var_2298[(int) (sGCdYD_QW_Gul63_3CSg_[(int) (P_w8f_fgCeIaTRV_p_7ndn1q[9])])]])])]])]])])] + Math.sqrt(var_374[(int) (var_2151[(int) (g_aIpfzqie[tRajtwqypTizszcm[(int) (ZICHO_IKOCUKWU_EGCSZ[var_1154[(int) (g_tDidrpacwyeVyrhew[(int) (EDDZK[var_2298[(int) (sGCdYD_QW_Gul63_3CSg_[(int) (P_w8f_fgCeIaTRV_p_7ndn1q[10])])]])])]])]])])])); | |
| while (UHIQAXCIL_MESOZZ_TSQTEKKV != (int) (Math.sqrt(var_374[(int) (var_2151[(int) (g_aIpfzqie[tRajtwqypTizszcm[(int) (ZICHO_IKOCUKWU_EGCSZ[var_1154[(int) (g_tDidrpacwyeVyrhew[(int) (EDDZK[var_2298[(int) (sGCdYD_QW_Gul63_3CSg_[(int) (P_w8f_fgCeIaTRV_p_7ndn1q[1])])]])])]])]])])]) + var_374[(int) (var_2151[(int) (g_aIpfzqie[tRajtwqypTizszcm[(int) (ZICHO_IKOCUKWU_EGCSZ[var_1154[(int) (g_tDidrpacwyeVyrhew[(int) (EDDZK[var_2298[(int) (sGCdYD_QW_Gul63_3CSg_[(int) (P_w8f_fgCeIaTRV_p_7ndn1q[7])])]])])]])]])])])) { | |
| switch(UHIQAXCIL_MESOZZ_TSQTEKKV) { | |
| case 949352161: | |
| String var_3187 = ""; | |
| int[] W4_ZH_Lfcjn_XSCXp6g = { 0x5355, 0x52D1, 0x531D, 0x52E9, 0x5311, 0x531D, 0x52D9, 0x5311, 0x5421, 0x5391, 0x530D, 0x52C9, 0x52FD, 0x531D, 0x52D1, 0x52FD, 0x52E5, 0x52E9, 0x5421, 0x53AD, 0x5421, 0x540D, 0x53E9, 0x53C9, 0x5309 }; | |
| for (int var_1429 = (int) (var_2980[var_1286[(int) (eXapdnpozvaRequrgourWyymkm[var_1444[(int) (a_1B_Qd551G_4e7U9Wb[(int) (Dex84zYkyGeLg__v1e_7[(int) (BGUKAYXAD_BFMZSMVC[dZgpaaaqvq[(int) (var_2151[(int) (g_aIpfzqie[tRajtwqypTizszcm[(int) (ZICHO_IKOCUKWU_EGCSZ[var_1154[(int) (g_tDidrpacwyeVyrhew[(int) (EDDZK[var_2298[(int) (sGCdYD_QW_Gul63_3CSg_[(int) (P_w8f_fgCeIaTRV_p_7ndn1q[11])])]])])]])]])])]])])])]])]]), oaxYKroM5iU_KE_IxG8_ = (int) (var_2980[var_1286[(int) (eXapdnpozvaRequrgourWyymkm[var_1444[(int) (a_1B_Qd551G_4e7U9Wb[(int) (Dex84zYkyGeLg__v1e_7[(int) (BGUKAYXAD_BFMZSMVC[dZgpaaaqvq[(int) (var_2151[(int) (g_aIpfzqie[tRajtwqypTizszcm[(int) (ZICHO_IKOCUKWU_EGCSZ[var_1154[(int) (g_tDidrpacwyeVyrhew[(int) (EDDZK[var_2298[(int) (sGCdYD_QW_Gul63_3CSg_[(int) (P_w8f_fgCeIaTRV_p_7ndn1q[11])])]])])]])]])])]])])])]])]]); var_1429 < (int) (var_2980[var_1286[(int) (eXapdnpozvaRequrgourWyymkm[var_1444[(int) (a_1B_Qd551G_4e7U9Wb[(int) (Dex84zYkyGeLg__v1e_7[(int) (BGUKAYXAD_BFMZSMVC[dZgpaaaqvq[(int) (var_2151[(int) (g_aIpfzqie[tRajtwqypTizszcm[(int) (ZICHO_IKOCUKWU_EGCSZ[var_1154[(int) (g_tDidrpacwyeVyrhew[(int) (EDDZK[var_2298[(int) (sGCdYD_QW_Gul63_3CSg_[(int) (P_w8f_fgCeIaTRV_p_7ndn1q[0])])]])])]])]])])]])])])]])]]); var_1429++) { | |
| oaxYKroM5iU_KE_IxG8_ = W4_ZH_Lfcjn_XSCXp6g[var_1429]; | |
| oaxYKroM5iU_KE_IxG8_++; | |
| oaxYKroM5iU_KE_IxG8_ ^= (int) (var_2980[var_1286[(int) (eXapdnpozvaRequrgourWyymkm[var_1444[(int) (a_1B_Qd551G_4e7U9Wb[(int) (Dex84zYkyGeLg__v1e_7[(int) (BGUKAYXAD_BFMZSMVC[dZgpaaaqvq[(int) (var_2151[(int) (g_aIpfzqie[tRajtwqypTizszcm[(int) (ZICHO_IKOCUKWU_EGCSZ[var_1154[(int) (g_tDidrpacwyeVyrhew[(int) (EDDZK[var_2298[(int) (sGCdYD_QW_Gul63_3CSg_[(int) (P_w8f_fgCeIaTRV_p_7ndn1q[1])])]])])]])]])])]])])])]])]]); | |
| oaxYKroM5iU_KE_IxG8_ += (int) (var_2980[var_1286[(int) (eXapdnpozvaRequrgourWyymkm[var_1444[(int) (a_1B_Qd551G_4e7U9Wb[(int) (Dex84zYkyGeLg__v1e_7[(int) (BGUKAYXAD_BFMZSMVC[dZgpaaaqvq[(int) (var_2151[(int) (g_aIpfzqie[tRajtwqypTizszcm[(int) (ZICHO_IKOCUKWU_EGCSZ[var_1154[(int) (g_tDidrpacwyeVyrhew[(int) (EDDZK[var_2298[(int) (sGCdYD_QW_Gul63_3CSg_[(int) (P_w8f_fgCeIaTRV_p_7ndn1q[12])])]])])]])]])])]])])])]])]]); | |
| oaxYKroM5iU_KE_IxG8_ = (((oaxYKroM5iU_KE_IxG8_ & (int) (var_2980[var_1286[(int) (eXapdnpozvaRequrgourWyymkm[var_1444[(int) (a_1B_Qd551G_4e7U9Wb[(int) (Dex84zYkyGeLg__v1e_7[(int) (BGUKAYXAD_BFMZSMVC[dZgpaaaqvq[(int) (var_2151[(int) (g_aIpfzqie[tRajtwqypTizszcm[(int) (ZICHO_IKOCUKWU_EGCSZ[var_1154[(int) (g_tDidrpacwyeVyrhew[(int) (EDDZK[var_2298[(int) (sGCdYD_QW_Gul63_3CSg_[(int) (P_w8f_fgCeIaTRV_p_7ndn1q[1])])]])])]])]])])]])])])]])]])) >> (int) (var_2980[var_1286[(int) (eXapdnpozvaRequrgourWyymkm[var_1444[(int) (a_1B_Qd551G_4e7U9Wb[(int) (Dex84zYkyGeLg__v1e_7[(int) (BGUKAYXAD_BFMZSMVC[dZgpaaaqvq[(int) (var_2151[(int) (g_aIpfzqie[tRajtwqypTizszcm[(int) (ZICHO_IKOCUKWU_EGCSZ[var_1154[(int) (g_tDidrpacwyeVyrhew[(int) (EDDZK[var_2298[(int) (sGCdYD_QW_Gul63_3CSg_[(int) (P_w8f_fgCeIaTRV_p_7ndn1q[3])])]])])]])]])])]])])])]])]])) | (oaxYKroM5iU_KE_IxG8_ << (int) (var_2980[var_1286[(int) (eXapdnpozvaRequrgourWyymkm[var_1444[(int) (a_1B_Qd551G_4e7U9Wb[(int) (Dex84zYkyGeLg__v1e_7[(int) (BGUKAYXAD_BFMZSMVC[dZgpaaaqvq[(int) (var_2151[(int) (g_aIpfzqie[tRajtwqypTizszcm[(int) (ZICHO_IKOCUKWU_EGCSZ[var_1154[(int) (g_tDidrpacwyeVyrhew[(int) (EDDZK[var_2298[(int) (sGCdYD_QW_Gul63_3CSg_[(int) (P_w8f_fgCeIaTRV_p_7ndn1q[6])])]])])]])]])])]])])])]])]]))) & (int) (var_2980[var_1286[(int) (eXapdnpozvaRequrgourWyymkm[var_1444[(int) (a_1B_Qd551G_4e7U9Wb[(int) (Dex84zYkyGeLg__v1e_7[(int) (BGUKAYXAD_BFMZSMVC[dZgpaaaqvq[(int) (var_2151[(int) (g_aIpfzqie[tRajtwqypTizszcm[(int) (ZICHO_IKOCUKWU_EGCSZ[var_1154[(int) (g_tDidrpacwyeVyrhew[(int) (EDDZK[var_2298[(int) (sGCdYD_QW_Gul63_3CSg_[(int) (P_w8f_fgCeIaTRV_p_7ndn1q[1])])]])])]])]])])]])])])]])]]); | |
| var_3187 += (char) (oaxYKroM5iU_KE_IxG8_ & (int) (var_2980[var_1286[(int) (eXapdnpozvaRequrgourWyymkm[var_1444[(int) (a_1B_Qd551G_4e7U9Wb[(int) (Dex84zYkyGeLg__v1e_7[(int) (BGUKAYXAD_BFMZSMVC[dZgpaaaqvq[(int) (var_2151[(int) (g_aIpfzqie[tRajtwqypTizszcm[(int) (ZICHO_IKOCUKWU_EGCSZ[var_1154[(int) (g_tDidrpacwyeVyrhew[(int) (EDDZK[var_2298[(int) (sGCdYD_QW_Gul63_3CSg_[(int) (P_w8f_fgCeIaTRV_p_7ndn1q[1])])]])])]])]])])]])])])]])]])); | |
| } | |
| System.out.format(var_3187, var_3878); | |
| UHIQAXCIL_MESOZZ_TSQTEKKV -= (int) Math.min(var_374[(int) (var_2151[(int) (g_aIpfzqie[tRajtwqypTizszcm[(int) (ZICHO_IKOCUKWU_EGCSZ[var_1154[(int) (g_tDidrpacwyeVyrhew[(int) (EDDZK[var_2298[(int) (sGCdYD_QW_Gul63_3CSg_[(int) (P_w8f_fgCeIaTRV_p_7ndn1q[6])])]])])]])]])])], var_374[(int) (var_2151[(int) (g_aIpfzqie[tRajtwqypTizszcm[(int) (ZICHO_IKOCUKWU_EGCSZ[var_1154[(int) (g_tDidrpacwyeVyrhew[(int) (EDDZK[var_2298[(int) (sGCdYD_QW_Gul63_3CSg_[(int) (P_w8f_fgCeIaTRV_p_7ndn1q[3])])]])])]])]])])]); | |
| break; | |
| case 1696459731: | |
| double[] var_1115 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; | |
| UHIQAXCIL_MESOZZ_TSQTEKKV = (int) (var_374[(int) (var_2151[(int) (g_aIpfzqie[tRajtwqypTizszcm[(int) (ZICHO_IKOCUKWU_EGCSZ[var_1154[(int) (g_tDidrpacwyeVyrhew[(int) (EDDZK[var_2298[(int) (sGCdYD_QW_Gul63_3CSg_[(int) (P_w8f_fgCeIaTRV_p_7ndn1q[5])])]])])]])]])])] - Math.sqrt(var_374[(int) (var_2151[(int) (g_aIpfzqie[tRajtwqypTizszcm[(int) (ZICHO_IKOCUKWU_EGCSZ[var_1154[(int) (g_tDidrpacwyeVyrhew[(int) (EDDZK[var_2298[(int) (sGCdYD_QW_Gul63_3CSg_[(int) (P_w8f_fgCeIaTRV_p_7ndn1q[12])])]])])]])]])])])); | |
| break; | |
| case 401434416: | |
| var_3878 = Cvrhllagj(var_3457); | |
| UHIQAXCIL_MESOZZ_TSQTEKKV += (int) (var_374[(int) (var_2151[(int) (g_aIpfzqie[tRajtwqypTizszcm[(int) (ZICHO_IKOCUKWU_EGCSZ[var_1154[(int) (g_tDidrpacwyeVyrhew[(int) (EDDZK[var_2298[(int) (sGCdYD_QW_Gul63_3CSg_[(int) (P_w8f_fgCeIaTRV_p_7ndn1q[0])])]])])]])]])])] + Math.exp(var_374[(int) (var_2151[(int) (g_aIpfzqie[tRajtwqypTizszcm[(int) (ZICHO_IKOCUKWU_EGCSZ[var_1154[(int) (g_tDidrpacwyeVyrhew[(int) (EDDZK[var_2298[(int) (sGCdYD_QW_Gul63_3CSg_[(int) (P_w8f_fgCeIaTRV_p_7ndn1q[11])])]])])]])]])])])); | |
| break; | |
| } | |
| } | |
| "; | |
| static Dictionary<string, double[]> dic_double_array = new Dictionary<string, double[]>(); | |
| static Dictionary<string, int[]> dic_int_array = new Dictionary<string, int[]>(); | |
| static string[] deobCode; | |
| static int SwitchIndex; | |
| static string SwitchIndexName; | |
| static int switchTargetCount; | |
| static Dictionary<int, string> methodBlocks; | |
| static int SwitchFinalIndex; | |
| static List<string> solvedOrder; | |
| static Evaluator script; | |
| static void Main(string[] args) { | |
| script = new Evaluator(); | |
| //clean casts | |
| //obfuscatedCode = obfuscatedCode.Replace("(int) (", string.Empty); | |
| //obfuscatedCode = obfuscatedCode.Replace("])", "]"); | |
| //store as list | |
| deobCode = obfuscatedCode.Split(new[] { Environment.NewLine }, StringSplitOptions.None); | |
| //find switch index, JObfuscator locals are always above | |
| SwitchIndex = GrabSwitchIndex(); | |
| ///1st pass : clean loca int[] and double[] | |
| GrabArrayContent(); | |
| ReplaceArrayContent(); | |
| ReplaceCast(); | |
| ReplaceMaths(); | |
| CleanResidualExpressions(); | |
| //2nd pass : clean cflow | |
| GrabSwitchLocalIndexName(); | |
| GrabSwitchFinalIndex(); | |
| BuildCFGGraph(); | |
| SolveCFGTree(); | |
| CleanFlowDust(); | |
| //3rd pass : string encoding | |
| DecodeStrings(); | |
| Console.WriteLine(string.Join(Environment.NewLine, deobCode)); | |
| Console.WriteLine("==="); | |
| Console.WriteLine(string.Join(Environment.NewLine, solvedOrder)); | |
| Console.WriteLine("==="); | |
| Console.ReadKey(); | |
| } | |
| private static void DecodeStrings() { | |
| for (int i = 0; i < solvedOrder.Count; i++) { | |
| if (solvedOrder[i].Contains("String ") && solvedOrder[i + 1].Contains("int[]") && solvedOrder[i + 2].Contains("for")) { | |
| //we found str encryption... | |
| var count = CountInString(solvedOrder[i], "\""); | |
| if(count == 1) { | |
| solvedOrder[i] = solvedOrder[i].Replace("\"", " \"\""); | |
| } | |
| var varName = GetStringInBetween("String ", "=", solvedOrder[i], false, false).Trim(); | |
| int start = i + 0; | |
| i += 2; | |
| while (!solvedOrder[i].Contains("}")) { | |
| i++; | |
| } | |
| int end = i + 1; | |
| string eval = ""; | |
| for (int x = 7; x < end; x++) { | |
| eval += solvedOrder[x] + Environment.NewLine; | |
| } | |
| string decoded = EvaluateString(eval, varName).ToString(); | |
| solvedOrder[start] = $"String {varName} = \"{decoded}\";"; | |
| start++; | |
| int tot = end - start; | |
| for (int x = 0; x < tot; x++) { | |
| solvedOrder.RemoveAt(start); | |
| } | |
| } | |
| } | |
| } | |
| private static int CountInString(string v1, string v2) { | |
| int count = 0; | |
| char toFind = Convert.ToChar(v2); | |
| foreach (char c in v1) { | |
| if (c == toFind) { | |
| count++; | |
| } | |
| } | |
| return count; | |
| } | |
| private static void CleanResidualExpressions() { | |
| for (int i = 0; i < deobCode.Length; i++) { | |
| var currentLine = deobCode[i]; | |
| //qQ3afFIA__VZ15a_fC -= -(int) (946513270,07304 - 374107,07303932); | |
| if (currentLine.Contains("= (int) (")) { | |
| var splitted = currentLine.Split('='); | |
| var exp = splitted[1].Replace(",", "."); | |
| if (exp.EndsWith(") {")) | |
| exp = exp.Replace(") {", ""); | |
| object result = EvaluateExpression(exp); | |
| deobCode[i] = deobCode[i].Substring(0, deobCode[i].IndexOf("=")); | |
| deobCode[i] += $" = {result};"; | |
| Console.WriteLine($"Evaluated expression : ({exp}) to {result}"); | |
| }else if (currentLine.Contains("= -(int) (")) { | |
| var splitted = currentLine.Split('='); | |
| var exp = splitted[1].Replace(",", "."); | |
| if (exp.EndsWith(") {")) | |
| exp = exp.Replace(") {", ""); | |
| object result = EvaluateExpression(exp); | |
| deobCode[i] = deobCode[i].Substring(0, deobCode[i].IndexOf("=")); | |
| deobCode[i] += $" = {result};"; | |
| Console.WriteLine($"Evaluated expression : ({exp}) to {result}"); | |
| } | |
| } | |
| } | |
| private static object EvaluateExpression(string exp) { | |
| object result = script.EvaluateExpression(exp); | |
| return result; | |
| } | |
| private static object EvaluateString(string exp, string varName) { | |
| object result = script.EvaluateString(exp, varName); | |
| return result; | |
| } | |
| private static void CleanFlowDust() { | |
| var block = string.Join(Environment.NewLine, solvedOrder); | |
| var lines = block.Split(new[] { Environment.NewLine }, StringSplitOptions.None).ToList(); | |
| for (int i = 0; i < lines.Count; i++) { | |
| var current = lines[i]; | |
| if (current.Contains($"{SwitchIndexName}")) { | |
| lines.RemoveAt(i); | |
| } | |
| } | |
| solvedOrder.Clear(); | |
| solvedOrder = lines; | |
| } | |
| private static void GrabSwitchFinalIndex() { | |
| //while (qQ3afFIA__VZ15a_fC != (int) 535286808) { | |
| for (int i = 0; i < deobCode.Length; i++) { | |
| var current = deobCode[i]; | |
| if (current.Contains($"while ({SwitchIndexName} != ")) { | |
| SwitchFinalIndex = int.Parse(GetStringInBetween("(int)", ")", current, false, false)); | |
| Console.WriteLine($"Switch final index = {SwitchIndexName}"); | |
| return; | |
| } | |
| } | |
| } | |
| private static void SolveCFGTree() { | |
| solvedOrder = new List<string>(); | |
| var indexvalue = 0; | |
| List<int> visitedBloks = new List<int>(); | |
| for (int i = 0; i < SwitchIndex; i++) { | |
| var current = deobCode[i]; | |
| if (current.Contains($"{SwitchIndexName}")) { | |
| if (current.Contains("(int)")) | |
| current = current.Replace("(int)", ""); | |
| indexvalue = int.Parse(GetStringInBetween("=", ";", current, false, false)); | |
| } | |
| } | |
| if (!methodBlocks.ContainsKey(indexvalue)) | |
| throw new Exception($"Flow initial value is wrong, or cannot find matching case for value{indexvalue}"); | |
| label_001: | |
| var block = methodBlocks[indexvalue]; | |
| visitedBloks.Add(indexvalue); | |
| solvedOrder.Add(block); | |
| if (solvedOrder.Count == switchTargetCount) { | |
| return; | |
| } | |
| var blockcode = block.Split(new[] { Environment.NewLine }, StringSplitOptions.None); | |
| for (int i = 0; i < blockcode.Length; i++) { | |
| var current = blockcode[i]; | |
| if (current.Contains($"{SwitchIndexName}")) { | |
| if (current.Contains("(int)")) | |
| current = current.Replace("(int)", ""); | |
| var param = int.Parse(GetStringInBetween("=", ";", current, false, false)); | |
| var op = GetStringInBetween(SwitchIndexName, param.ToString(), current, false, false).Replace(" ", string.Empty); | |
| if (param == SwitchFinalIndex) | |
| return; | |
| switch (op) { | |
| case "=": | |
| indexvalue = param; | |
| goto label_001; | |
| case "= -": | |
| indexvalue = -param; | |
| goto label_001; | |
| case "-=": | |
| indexvalue -= param; | |
| goto label_001; | |
| case "-= -": | |
| indexvalue -= -param; | |
| goto label_001; | |
| case "+=": | |
| indexvalue += param; | |
| goto label_001; | |
| case "+= -": | |
| indexvalue += -param; | |
| goto label_001; | |
| case "^=": | |
| indexvalue ^= param; | |
| goto label_001; | |
| case "^= -": | |
| indexvalue ^= -param; | |
| goto label_001; | |
| } | |
| } | |
| } | |
| } | |
| private static void BuildCFGGraph() { | |
| methodBlocks = new Dictionary<int, string>(); | |
| var src = string.Join(Environment.NewLine, deobCode); | |
| switchTargetCount = Regex.Matches(src, "case").Count; | |
| for (int i = 0; i < switchTargetCount; i++) { | |
| var test = GetStringInBetween("case", "break", src, true, false); | |
| src = src.Replace(test, "//removed" + Environment.NewLine); | |
| var id = int.Parse(GetStringInBetween("case", ":", test, false, false)); | |
| test = test.Replace($"case {id}:", string.Empty); | |
| methodBlocks.Add(id, test); | |
| } | |
| } | |
| private static void GrabSwitchLocalIndexName() { | |
| for (int i = 0; i < deobCode.Length; i++) { | |
| var current = deobCode[i]; | |
| if (current.Contains("while (")) { | |
| SwitchIndexName = GetStringInBetween("while (", "!", current, false, false); | |
| Console.WriteLine($"Switch Index Name = {SwitchIndexName}"); | |
| return; | |
| } | |
| } | |
| } | |
| private static void ReplaceMaths() { | |
| for (int i = 0; i < deobCode.Length; i++) { | |
| var line = deobCode[i]; | |
| if (line.Contains("Math.")) { | |
| var splitted = line.Split(new[] { "Math." }, StringSplitOptions.None); | |
| foreach (var item in splitted) { | |
| if (item.Contains("sin(")) { | |
| var itemz = item.Split(new[] { "sin(" }, StringSplitOptions.None)[1]; | |
| if (!Char.IsDigit(itemz[0])) continue; | |
| string str = ""; | |
| var ind = 0; | |
| var current = itemz[ind]; | |
| while (current != ')' && current != ' ') { | |
| str += current; | |
| ind++; | |
| current = itemz[ind]; | |
| } | |
| var newdouble = Convert.ToDouble(str); | |
| var result = Math.Sin(newdouble).ToString(); | |
| obfuscatedCode = string.Join(Environment.NewLine, deobCode); | |
| var xe = obfuscatedCode.Replace($"Math.sin({str})", $"{result}"); | |
| if (xe == obfuscatedCode) continue; | |
| deobCode = xe.Split(new[] { Environment.NewLine }, StringSplitOptions.None); | |
| Console.WriteLine($"Math replaced sin({ str}) with {result}"); | |
| } else if (item.Contains("sinh(")) { | |
| var itemz = item.Split(new[] { "sinh(" }, StringSplitOptions.None)[1]; | |
| if (!Char.IsDigit(itemz[0])) continue; | |
| string str = ""; | |
| var ind = 0; | |
| var current = itemz[ind]; | |
| while (current != ')' && current != ' ') { | |
| str += current; | |
| ind++; | |
| current = itemz[ind]; | |
| } | |
| var newdouble = Convert.ToDouble(str); | |
| var result = Math.Sinh(newdouble).ToString(); | |
| obfuscatedCode = string.Join(Environment.NewLine, deobCode); | |
| var xe = obfuscatedCode.Replace($"Math.sinh({str})", $"{result}"); | |
| if (xe == obfuscatedCode) continue; | |
| deobCode = xe.Split(new[] { Environment.NewLine }, StringSplitOptions.None); | |
| Console.WriteLine($"Math replaced sinh({ str}) with {result}"); | |
| } else if (item.Contains("max(")) { | |
| var itemz = item.Split(new[] { "max(" }, StringSplitOptions.None)[1]; | |
| if (!Char.IsDigit(itemz[0])) continue; | |
| string str = ""; | |
| var ind = 0; | |
| var current = itemz[ind]; | |
| while (current != ')') { | |
| str += current; | |
| ind++; | |
| current = itemz[ind]; | |
| } | |
| str = str.TrimEnd(new char[] { ',' }); | |
| var num1 = Convert.ToDouble(str.Split(new[] { ", " }, StringSplitOptions.None)[0]); | |
| var num2 = Convert.ToDouble(str.Split(new[] { ", " }, StringSplitOptions.None)[1]); | |
| var result = Math.Max(num1, num2).ToString(); | |
| obfuscatedCode = string.Join(Environment.NewLine, deobCode); | |
| var xe = obfuscatedCode.Replace($"Math.max({str})", $"{result}"); | |
| if (xe == obfuscatedCode) continue; | |
| deobCode = xe.Split(new[] { Environment.NewLine }, StringSplitOptions.None); | |
| Console.WriteLine($"Math replaced max({ str}) with {result}"); | |
| } else if (item.Contains("min(")) { | |
| var itemz = item.Split(new[] { "min(" }, StringSplitOptions.None)[1]; | |
| if (!Char.IsDigit(itemz[0])) continue; | |
| string str = ""; | |
| var ind = 0; | |
| var current = itemz[ind]; | |
| while (current != ')') { | |
| str += current; | |
| ind++; | |
| current = itemz[ind]; | |
| } | |
| str = str.TrimEnd(new char[] { ',' }); | |
| var num1 = Convert.ToDouble(str.Split(new[] { ", " }, StringSplitOptions.None)[0]); | |
| var num2 = Convert.ToDouble(str.Split(new[] { ", " }, StringSplitOptions.None)[1]); | |
| var result = Math.Min(num1, num2).ToString(); | |
| obfuscatedCode = string.Join(Environment.NewLine, deobCode); | |
| var xe = obfuscatedCode.Replace($"Math.min({str})", $"{result}"); | |
| if (xe == obfuscatedCode) continue; | |
| deobCode = xe.Split(new[] { Environment.NewLine }, StringSplitOptions.None); | |
| Console.WriteLine($"Math replaced min({ str}) with {result}"); | |
| } else if (item.Contains("sqrt(")) { | |
| var itemz = item.Split(new[] { "sqrt(" }, StringSplitOptions.None)[1]; | |
| if (!Char.IsDigit(itemz[0])) continue; | |
| string str = ""; | |
| var ind = 0; | |
| var current = itemz[ind]; | |
| while (current != ')' && current != ' ') { | |
| str += current; | |
| ind++; | |
| current = itemz[ind]; | |
| } | |
| var newdouble = Convert.ToDouble(str); | |
| var result = Math.Sqrt(newdouble).ToString(); | |
| obfuscatedCode = string.Join(Environment.NewLine, deobCode); | |
| var xe = obfuscatedCode.Replace($"Math.sqrt({str})", $"{result}"); | |
| if (xe == obfuscatedCode) continue; | |
| deobCode = xe.Split(new[] { Environment.NewLine }, StringSplitOptions.None); | |
| Console.WriteLine($"Math replaced sqrt({ str}) with {result}"); | |
| } else if (item.Contains("expm1(")) { | |
| var itemz = item.Split(new[] { "expm1(" }, StringSplitOptions.None)[1]; | |
| if (!Char.IsDigit(itemz[0])) continue; | |
| string str = ""; | |
| var ind = 0; | |
| var current = itemz[ind]; | |
| while (current != ')' && current != ' ') { | |
| str += current; | |
| ind++; | |
| current = itemz[ind]; | |
| } | |
| var newdouble = Convert.ToDouble(str); | |
| var result = expm1(newdouble).ToString(); | |
| obfuscatedCode = string.Join(Environment.NewLine, deobCode); | |
| var xe = obfuscatedCode.Replace($"Math.expm1({str})", $"{result}"); | |
| if (xe == obfuscatedCode) continue; | |
| deobCode = xe.Split(new[] { Environment.NewLine }, StringSplitOptions.None); | |
| Console.WriteLine($"Math replaced expm1({ str}) with {result}"); | |
| } else if (item.Contains("cos(")) { | |
| var itemz = item.Split(new[] { "cos(" }, StringSplitOptions.None)[1]; | |
| if (!Char.IsDigit(itemz[0])) continue; | |
| string str = ""; | |
| var ind = 0; | |
| var current = itemz[ind]; | |
| while (current != ')' && current != ' ') { | |
| str += current; | |
| ind++; | |
| current = itemz[ind]; | |
| } | |
| var newdouble = Convert.ToDouble(str); | |
| var result = Math.Cos(newdouble).ToString(); | |
| obfuscatedCode = string.Join(Environment.NewLine, deobCode); | |
| var xe = obfuscatedCode.Replace($"Math.cos({str})", $"{result}"); | |
| if (xe == obfuscatedCode) continue; | |
| deobCode = xe.Split(new[] { Environment.NewLine }, StringSplitOptions.None); | |
| Console.WriteLine($"Math replaced cos({ str}) with {result}"); | |
| } else if (item.Contains("exp(")) { | |
| var itemz = item.Split(new[] { "exp(" }, StringSplitOptions.None)[1]; | |
| if (!Char.IsDigit(itemz[0])) continue; | |
| string str = ""; | |
| var ind = 0; | |
| var current = itemz[ind]; | |
| while (current != ')' && current != ' ') { | |
| str += current; | |
| ind++; | |
| current = itemz[ind]; | |
| } | |
| var newdouble = Convert.ToDouble(str); | |
| var result = Math.Exp(newdouble).ToString(); | |
| obfuscatedCode = string.Join(Environment.NewLine, deobCode); | |
| var xe = obfuscatedCode.Replace($"Math.exp({str})", $"{result}"); | |
| if (xe == obfuscatedCode) continue; | |
| deobCode = xe.Split(new[] { Environment.NewLine }, StringSplitOptions.None); | |
| Console.WriteLine($"Math replaced exp({ str}) with {result}"); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| private static void ReplaceCast() { | |
| for (int i = 0; i < deobCode.Length; i++) { | |
| var line = deobCode[i]; | |
| if(line.Contains("(int) (")){ | |
| foreach (var item in line.Split(new[] { "(int) (" }, StringSplitOptions.None)) { | |
| if (!Char.IsDigit(item[0])) continue; | |
| string str = ""; | |
| var ind = 0; | |
| var current = item[ind]; | |
| while (current != ')' && current != ' ') { | |
| str += current; | |
| ind++; | |
| current = item[ind]; | |
| } | |
| var newdouble = Convert.ToDouble(str); | |
| var toreplace = (int)newdouble; | |
| obfuscatedCode = string.Join(Environment.NewLine, deobCode); | |
| var xe = obfuscatedCode.Replace($"(int) ({str})", $"{toreplace}"); | |
| if (xe == obfuscatedCode) continue; | |
| deobCode = xe.Split(new[] { Environment.NewLine }, StringSplitOptions.None); | |
| Console.WriteLine($"(int) cast replaced (int)({ str}) with {toreplace}"); | |
| } | |
| } | |
| } | |
| } | |
| private static int GrabSwitchIndex() { | |
| for (int i = 0; i < deobCode.Length -1; i++) { | |
| if (deobCode[i].Contains("while") && deobCode[i+1].Contains("switch")) { | |
| return i; | |
| } | |
| } | |
| throw new Exception("Cannot find switch index"); | |
| } | |
| private static void ReplaceArrayContent() { | |
| foreach (var item in dic_double_array) { | |
| var name = item.Key; | |
| for (int i = 0; i < item.Value.Length; i++) { | |
| var value = item.Value; | |
| obfuscatedCode = string.Join(Environment.NewLine, deobCode); | |
| var xe = obfuscatedCode.Replace($"{name}[{i}]", $"{value[i]}"); | |
| if (xe == obfuscatedCode) continue; | |
| deobCode = xe.Split(new[] { Environment.NewLine }, StringSplitOptions.None); | |
| Console.WriteLine($"double[] replaced {name}[{i}] with {value[i]}"); | |
| ReplaceCast(); | |
| ReplaceArrayContent(); | |
| ReplaceCast(); | |
| } | |
| } | |
| foreach (var item in dic_int_array) { | |
| var name = item.Key; | |
| for (int i = 0; i < item.Value.Length; i++) { | |
| var value = item.Value; | |
| obfuscatedCode = string.Join(Environment.NewLine, deobCode); | |
| var xe = obfuscatedCode.Replace($"{name}[{i}]", $"{value[i]}"); | |
| if (xe == obfuscatedCode) continue; | |
| deobCode = xe.Split(new[] { Environment.NewLine }, StringSplitOptions.None); | |
| Console.WriteLine($"int[] replaced {name}[{i}] with {value[i]}"); | |
| ReplaceCast(); | |
| ReplaceArrayContent(); | |
| ReplaceCast(); | |
| } | |
| } | |
| } | |
| private static void GrabArrayContent() { | |
| for (int i = 0; i < SwitchIndex; i++) { | |
| if (!deobCode[i].Contains("=")) | |
| continue; | |
| var value = GetStringInBetween("{", "}", deobCode[i], false, false); | |
| if (value is null) | |
| continue; | |
| var name = GetStringInBetween("[]", "=", deobCode[i], false, false).Trim(); | |
| if (deobCode[i].Contains("int[]")) { | |
| List<int> tmp1 = new List<int>(); | |
| foreach (var item in value.Split(',')) { | |
| var itemm = item.Trim(); | |
| if (itemm.Contains("0x")) { | |
| int intValue = Convert.ToInt32(itemm, 16); | |
| tmp1.Add(intValue); | |
| } else { | |
| tmp1.Add(int.Parse(item.Trim())); | |
| } | |
| } | |
| dic_int_array.Add(name, tmp1.ToArray()); | |
| } else if (deobCode[i].Contains("double[]")) { | |
| List<double> tmp1 = new List<double>(); | |
| foreach (var item in value.Split(',')) { | |
| var v = item.Replace(".", ",").Trim(); | |
| var temp = ConvertToDouble(v); | |
| tmp1.Add(temp); | |
| } | |
| dic_double_array.Add(name, tmp1.ToArray()); | |
| } | |
| } | |
| } | |
| static double expm1(double x) { | |
| if (Math.Abs(x) < 1e-5) | |
| return x + 0.5 * x * x; | |
| else | |
| return Math.Exp(x) - 1.0; | |
| } | |
| public static IEnumerable<int> AllIndexesOf(string str, string searchstring) { | |
| int minIndex = str.IndexOf(searchstring); | |
| while (minIndex != -1) { | |
| yield return minIndex; | |
| minIndex = str.IndexOf(searchstring, minIndex + searchstring.Length); | |
| } | |
| } | |
| public static double ConvertToDouble(string s) { | |
| char systemSeparator = Thread.CurrentThread.CurrentCulture.NumberFormat.CurrencyDecimalSeparator[0]; | |
| double result = 0; | |
| try { | |
| if (s != null) | |
| if (!s.Contains(",")) | |
| result = double.Parse(s, CultureInfo.InvariantCulture); | |
| else | |
| result = Convert.ToDouble(s.Replace(".", systemSeparator.ToString()).Replace(",", systemSeparator.ToString())); | |
| } catch (Exception e) { | |
| try { | |
| result = Convert.ToDouble(s); | |
| } catch { | |
| try { | |
| result = Convert.ToDouble(s.Replace(",", ";").Replace(".", ",").Replace(";", ".")); | |
| } catch { | |
| throw new Exception("Wrong string-to-double format"); | |
| } | |
| } | |
| } | |
| return result; | |
| } | |
| public static string GetStringInBetween(string strBegin, string strEnd, string strSource, bool includeBegin, | |
| bool includeEnd) { | |
| string[] result = { string.Empty, string.Empty }; | |
| int iIndexOfBegin = strSource.IndexOf(strBegin); | |
| if (iIndexOfBegin != -1) { | |
| // include the Begin string if desired | |
| if (includeBegin) | |
| iIndexOfBegin -= strBegin.Length; | |
| strSource = strSource.Substring(iIndexOfBegin + strBegin.Length); | |
| int iEnd = strSource.IndexOf(strEnd); | |
| if (iEnd != -1) { | |
| // include the End string if desired | |
| if (includeEnd) | |
| iEnd += strEnd.Length; | |
| result[0] = strSource.Substring(0, iEnd); | |
| // advance beyond this segment | |
| if (iEnd + strEnd.Length < strSource.Length) | |
| result[1] = strSource.Substring(iEnd + strEnd.Length); | |
| } | |
| } else | |
| // stay where we are | |
| result[1] = strSource; | |
| return result[0]; | |
| } | |
| public class Evaluator | |
| { | |
| public CompilerParameters Parameters { get; set; } = new CompilerParameters() { | |
| CompilerOptions = "/unsafe", | |
| }; | |
| public Evaluator() { | |
| Parameters.ReferencedAssemblies.Add("System.dll"); | |
| Parameters.ReferencedAssemblies.Add("System.Core.dll"); | |
| Parameters.ReferencedAssemblies.Add("Microsoft.CSharp.dll"); | |
| Parameters.GenerateInMemory = true; | |
| } | |
| public CompilerResults Compile(string methodCode) { | |
| return new CSharpCodeProvider().CompileAssemblyFromSource(Parameters, methodCode); | |
| } | |
| public int EvaluateExpression(string expression) { | |
| if (!expression.EndsWith(";")) { | |
| expression += ";"; | |
| } | |
| string code = $@" | |
| public class A{{ | |
| public static int B() {{ | |
| int result = {expression} | |
| return result; | |
| }} | |
| }} | |
| "; | |
| var results = Compile(code); | |
| if (results.Errors.Count > 0) | |
| throw new Exception("Error during expression evaluation"); | |
| var methodInfo = results.CompiledAssembly.GetTypes().Single( | |
| t => t.GetMethods().Count() > 0 | |
| && t.GetMethods().Count(m => m.ReturnParameter.ParameterType == typeof(int)) > 0 | |
| && t.GetMethods().Count(m => m.Name == "B") > 0) | |
| .GetMethods()[0]; | |
| var mResult = (int)methodInfo.Invoke(null, null); | |
| return mResult; | |
| } | |
| public string EvaluateString(string expression, string variableName) { | |
| expression = expression.Replace("String", "string"); | |
| string code = $@" | |
| public class A{{ | |
| public static string B() {{ | |
| {expression} | |
| return {variableName}; | |
| }} | |
| }} | |
| "; | |
| var results = Compile(code); | |
| if (results.Errors.Count > 0) | |
| throw new Exception("Error during expression evaluation"); | |
| var methodInfo = results.CompiledAssembly.GetTypes().Single( | |
| t => t.GetMethods().Count() > 0 | |
| && t.GetMethods().Count(m => m.ReturnParameter.ParameterType == typeof(int)) > 0 | |
| && t.GetMethods().Count(m => m.Name == "B") > 0) | |
| .GetMethods()[0]; | |
| var mResult = (string)methodInfo.Invoke(null, null); | |
| return mResult; | |
| } | |
| } | |
| } | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
output :