توضح هذه المقالة تجربة الاستخدام القتالي لـ obfuscator ConfuserEx 0.6.0 لحماية خدمة .Net ضمن Windows و Mono. لقد كان عام 2016 ، ولكن أعتقد أن الموضوع لم يفقد أهميته الآن.
ConfuserEx ( http://yck1509.github.io/ConfuserEx/ ) هو أحد أدوات التعتيم المجانية مفتوحة المصدر لـ .Net. يدعم Windows .NET Framework و Mono.
يحتوي على عدد كبير من الوحدات النمطية التي تنفذ طرقًا مختلفة لحماية التعليمات البرمجية (إعادة التسمية ، والتشويش على تدفق التنفيذ ، وتشفير الموارد والثوابت ، والحماية من التصحيح والتنميط ، والغلاف). يتيح لك ConfuserEx توسيع الوظائف عن طريق كتابة وحدات الأمان الخاصة بك.
يسمح لك الكود المفتوح المصدر بتعديل نظام الحماية ، وتغيير توقيع المُعتِم ، مما يجعل من الصعب على برامج إزالة التشويش والهندسة العكسية اليدوية.
توثيق
يحتوي المشروع على وثائق مفصلة إلى حد ما بتنسيق WiKi .
واجهة المستخدم
يدعم ConfuserEx وضع سطر الأوامر وواجهة المستخدم.
وضع سطر الأوامر
ConfuserEx\bin\Confuser.CLI.exe
ConfuserEx.CLI: No input files specified.
Usage:
Confuser.CLI -n|noPause <project configuration>
Confuser.CLI -n|noPause -o|out=<output directory> <modules>
-n|noPause : no pause after finishing protection.
-o|out : specifies output directory.
-probe : specifies probe directory.
-plugin : specifies plugin path.
-debug : specifies debug symbol generation.</source>
ConfuserEx\bin\Confuser.CLI.exe -n LicenseManagerService.crproj
[INFO] ConfuserEx v0.6.0-custom Copyright (C) Ki 2014
[INFO] Running on Microsoft Windows NT 6.1.7601 Service Pack 1, .NET Framework v4.0.30319.0, 64 bits
[DEBUG] Discovering plugins...
[INFO] Discovered 10 protections, 1 packers.
[DEBUG] Resolving component dependency...
[INFO] Loading input modules...
[INFO] Loading 'LicenseManagerService\bin\x86\Release\LicenseManagerService.exe'...
[INFO] Initializing...
[DEBUG] Building pipeline...
[INFO] Resolving dependencies...
[DEBUG] Checking Strong Name...
[DEBUG] Creating global .cctors...
[DEBUG] Executing 'Name analysis' phase...
[DEBUG] Building VTables & identifier list...
[DEBUG] Analyzing...
[INFO] Processing module 'LicenseManagerService.exe'...
[DEBUG] Executing 'Invalid metadata addition' phase...
[DEBUG] Executing 'Renaming' phase...
[DEBUG] Renaming...
[DEBUG] Executing 'Anti-debug injection' phase...
[DEBUG] Executing 'Anti-dump injection' phase...
[DEBUG] Executing 'Anti-ILDasm marking' phase...
[DEBUG] Executing 'Encoding reference proxies' phase...
[DEBUG] Executing 'Constant encryption helpers injection' phase...
[DEBUG] Executing 'Resource encryption helpers injection' phase...
[DEBUG] Executing 'Constants encoding' phase...
[DEBUG] Executing 'Anti-tamper helpers injection' phase...
[DEBUG] Executing 'Control flow mangling' phase...
[DEBUG] Executing 'Post-renaming' phase...
[DEBUG] Executing 'Anti-tamper metadata preparation' phase...
[DEBUG] Executing 'Packer info extraction' phase...
[INFO] Writing module 'LicenseManagerService.exe'...
[DEBUG] Encrypting resources...
[INFO] Finalizing...
[INFO] Packing...
[DEBUG] Encrypting modules...
[INFO] Protecting packer stub...
[DEBUG] Discovering plugins...
[INFO] Discovered 11 protections, 1 packers.
[DEBUG] Resolving component dependency...
[INFO] Loading input modules...
[INFO] Loading 'LicenseManagerService\bin\x86\Release\LicenseManagerService.exe'...
[INFO] Initializing...
[DEBUG] Building pipeline...
[INFO] Resolving dependencies...
[DEBUG] Checking Strong Name...
[DEBUG] Creating global .cctors...
[DEBUG] Executing 'Name analysis' phase...
[DEBUG] Building VTables & identifier list...
[DEBUG] Analyzing...
[INFO] Processing module 'LicenseManagerService.exe'...
[DEBUG] Executing 'Packer info encoding' phase...
[DEBUG] Executing 'Invalid metadata addition' phase...
[DEBUG] Executing 'Renaming' phase...
[DEBUG] Renaming...
[DEBUG] Executing 'Anti-debug injection' phase...
[DEBUG] Executing 'Anti-dump injection' phase...
[DEBUG] Executing 'Anti-ILDasm marking' phase...
[DEBUG] Executing 'Encoding reference proxies' phase...
[DEBUG] Executing 'Constant encryption helpers injection' phase...
[DEBUG] Executing 'Resource encryption helpers injection' phase...
[DEBUG] Executing 'Constants encoding' phase...
[DEBUG] Executing 'Anti-tamper helpers injection' phase...
[DEBUG] Executing 'Control flow mangling' phase...
[DEBUG] Executing 'Post-renaming' phase...
[DEBUG] Executing 'Anti-tamper metadata preparation' phase...
[DEBUG] Executing 'Packer info extraction' phase...
[INFO] Writing module 'LicenseManagerService.exe'...
[DEBUG] Encrypting resources...
[INFO] Finalizing...
[DEBUG] Saving to 'C:\Users\pash76\AppData\Local\Temp\ehwkjzxt.brh\mqqtgvji.gxk\LicenseManagerService\bin\x86\Release\LicenseManagerService.exe'...
[DEBUG] Executing 'Export symbol map' phase...
[INFO] Finish protecting packer stub.
[DEBUG] Saving to 'D:\pash76\Develop\License_manager\Confused\LicenseManagerService\bin\x86\Release\LicenseManagerService.exe'...
[DEBUG] Executing 'Export symbol map' phase...
[INFO] Done.
Finished at 9:35, 0:03 elapsed.
ملف المشروع
تم وصف هيكل ملف المشروع في الوثائق . يحتوي ملف المشروع على وصف للتجمعات التي تحتاج إلى الحماية ، وإعدادات وحدات الحماية النمطية والقواعد التي يتم من خلالها تطبيق وحدات الحماية لحماية التجميعات.
تسمح لك القواعد بالتطبيق الانتقائي (أو عدم تطبيق) وحدات الحماية على أجزاء مختلفة من الكود. أثناء التعتيم ، يتم فحص القاعدة للتحقق من قابليتها للتطبيق على عنصر الكود المحمي الحالي. في هذه الحالة ، يتم تقييم امتثال ما يسمى بتوقيع عنصر الكود للقاعدة. يمكن أن تحتوي القواعد على تعبيرات منطقية معقدة .
<project outputDir=".\Confused" baseDir=".\" xmlns="http://confuser.codeplex.com">
<rule pattern="true" inherit="false">
<protection id="anti ildasm" />
<protection id="anti tamper" action="remove" />
<protection id="constants">
<argument name="mode" value="dynamic" />
<argument name="decoderCount" value="13" />
<argument name="elements" value="SIP" />
<argument name="cfg" value="false" />
</protection>
<protection id="ctrl flow" />
<protection id="anti dump" action="remove" />
<protection id="anti debug" />
<protection id="invalid metadata" action="remove" />
<protection id="ref proxy" />
<protection id="resources">
<argument name="mode" value="dynamic" />
</protection>
<protection id="rename">
<argument name="mode" value="sequential" />
</protection>
</rule>
<packer id="compressor">
<argument name="key" value="dynamic" />
<argument name="compat" value="true" />
</packer>
<module path="LicenseManagerService\bin\x86\Release\LicenseManagerService.exe">
<rule pattern="
match('UAVLicenseManager\.CentOSSystemInfoProvider::ShellCommand.*')
or match(' ?LicenseManagerService\.Program(::)?')
or match(' ?LicenseManagerService\.UAVLicenseManagerService(::)?')
or (
match(' ?UAVLicenseManager\.License(::)?')
and is-public()
and (member-type('type') or member-type('field') or member-type('property'))
)
or match(' ?UAVLicenseManager\.LicenseKey(::)?')
or match(' ?UAVLicenseManager\.LicenseOwner(::)?')
or match(' ?UAVLicenseManager\.Location(::)?')
or match(' ?UAVLicenseManager\.LicenseLimit(::)?')
" inherit="true">
<protection id="rename" action="remove" />
</rule>
</module>
</project>
Name Protection Reflection . , .
mono, mono. , .
| Windows | Mono | |
|---|---|---|
| Anti Debug Protection | ![]() |
![]() |
| Anti Dump Protection | ![]() |
![]() |
| Anti IL Dasm Protection | ![]() |
![]() |
| Anti Tamper Protection | ![]() |
![]() |
| Compressor | ![]() |
( ) |
| Constants Protection | ![]() |
( cfg ) |
| Control Flow Protection | ![]() |
![]() |
| Invalid Metadata Protection | ![]() |
![]() |
| Name Protection | ![]() |
![]() |
| Reference Proxy Protection | ![]() |
![]() |
| Resources Protection | ![]() |
![]() |
, , IL-. dotPeek ConfuserEx. , dotPeek .

ConfuserEx. , ConfusedByAttribute. -.
ConfuserEx\src\Confuser.Core\ConfuserEngine.cs
static void Inspection(ConfuserContext context) {
context.Logger.Info("Resolving dependencies...");
foreach (var dependency in context.Modules
.SelectMany(module => module.GetAssemblyRefs().Select(asmRef => Tuple.Create(asmRef, module)))) {
try {
AssemblyDef assembly = context.Resolver.ResolveThrow(dependency.Item1, dependency.Item2);
}
catch (AssemblyResolveException ex) {
context.Logger.ErrorException("Failed to resolve dependency of '" + dependency.Item2.Name + "'.", ex);
throw new ConfuserException(ex);
}
}
context.Logger.Debug("Checking Strong Name...");
foreach (ModuleDefMD module in context.Modules) {
var snKey = context.Annotations.Get<StrongNameKey>(module, Marker.SNKey);
if (snKey == null && module.IsStrongNameSigned)
context.Logger.WarnFormat("[{0}] SN Key is not provided for a signed module, the output may not be working.", module.Name);
else if (snKey != null && !module.IsStrongNameSigned)
context.Logger.WarnFormat("[{0}] SN Key is provided for an unsigned module, the output may not be working.", module.Name);
else if (snKey != null && module.IsStrongNameSigned &&
!module.Assembly.PublicKey.Data.SequenceEqual(snKey.PublicKey))
context.Logger.WarnFormat("[{0}] Provided SN Key and signed module's public key do not match, the output may not be working.", module.Name);
}
var marker = context.Registry.GetService<IMarkerService>();
context.Logger.Debug("Creating global .cctors...");
foreach (ModuleDefMD module in context.Modules) {
TypeDef modType = module.GlobalType;
if (modType == null) {
modType = new TypeDefUser("", "<Module>", null);
modType.Attributes = TypeAttributes.AnsiClass;
module.Types.Add(modType);
marker.Mark(modType, null);
}
MethodDef cctor = modType.FindOrCreateStaticConstructor();
if (!marker.IsMarked(cctor))
marker.Mark(cctor, null);
}
//context.Logger.Debug("Watermarking...");
//foreach (ModuleDefMD module in context.Modules) {
// TypeRef attrRef = module.CorLibTypes.GetTypeRef("System", "Attribute");
// var attrType = new TypeDefUser("", "ConfusedByAttribute", attrRef);
// module.Types.Add(attrType);
// marker.Mark(attrType, null);
// var ctor = new MethodDefUser(
// ".ctor",
// MethodSig.CreateInstance(module.CorLibTypes.Void, module.CorLibTypes.String),
// MethodImplAttributes.Managed,
// MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName);
// ctor.Body = new CilBody();
// ctor.Body.MaxStack = 1;
// ctor.Body.Instructions.Add(OpCodes.Ldarg_0.ToInstruction());
// ctor.Body.Instructions.Add(OpCodes.Call.ToInstruction(new MemberRefUser(module, ".ctor", MethodSig.CreateInstance(module.CorLibTypes.Void), attrRef)));
// ctor.Body.Instructions.Add(OpCodes.Ret.ToInstruction());
// attrType.Methods.Add(ctor);
// marker.Mark(ctor, null);
// var attr = new CustomAttribute(ctor);
// attr.ConstructorArguments.Add(new CAArgument(module.CorLibTypes.String, Version));
// module.CustomAttributes.Add(attr);
//}
}
, .net ConfuserEx. koi.
ConfuserEx\src\Confuser.Protections\Compress\Compressor.cs
ConfuserEx\src\Confuser.Runtime\Compressor.cs
ConfuserEx\src\Confuser.Protections\Compress\ExtractPhase.cs
ConfuserEx\src\Confuser.Protections\Compress\StubProtection.cs
( dotPeek). .
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
[assembly: InternalsVisibleTo("LicenseManagerServiceTests")]
namespace LicenseManagerService
{
static class Program
{
/// <summary>
/// .
/// </summary>
///
static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new UAVLicenseManagerService()
};
ServiceBase.Run(ServicesToRun);
}
}
}
dotPeek

LicenseManagerService.Program, , Name Protection ( ). Control Flow Protection.
// Decompiled with JetBrains decompiler
// Type: LicenseManagerService.Program
// Assembly: LicenseManagerService, Version=1.0.5980.24716, Culture=neutral, PublicKeyToken=null
// MVID: A6EB17CC-65EE-4E2D-B66C-24E166429A4A
// Assembly location: D:\pash\Develop\License_manager\Confused\LicenseManagerService\bin\x86\Release\LicenseManagerService.exe
using System.Runtime.InteropServices;
using System.ServiceProcess;
namespace LicenseManagerService
{
internal static class Program
{
private static void Main()
{
ServiceBase[] serviceBaseArray1 = new ServiceBase[1]
{
(ServiceBase) new UAVLicenseManagerService()
};
label_1:
int num1 = 1005209177;
ServiceBase[] serviceBaseArray2;
while (true)
{
int num2 = 1280737639;
uint num3;
switch ((num3 = (uint) (num1 ^ num2)) % 3U)
{
case 0U:
goto label_1;
case 1U:
serviceBaseArray2 = serviceBaseArray1;
num1 = (int) num3 * 1248105312 ^ 483770479;
continue;
default:
goto label_4;
}
}
label_4:
Program.\u200E(serviceBaseArray2);
}
static void \u200E([In] ServiceBase[] obj0)
{
ServiceBase.Run(obj0);
}
}
}
private readonly string ShellCommandNetworkAdapterMACAddress =
@"ip -o link show | grep -m 1 'UP.*LOWER_UP.*ether\|LOWER_UP.*UP.*ether' | sed -n 's/.*ether \(.*\) brd.*/\1/p' | tr -d '\n[:blank:]'";

بالنسبة لجميع عناصر التعليمات البرمجية التي تبدأ بـ ShellCommand ، باستخدام القواعد الموجودة في ملف المشروع ، تم تعطيل وحدة حماية الاسم (يتم الاحتفاظ بالأسماء). يمكنك رؤية نتائج وحدة حماية الثوابت .
internal sealed class _ob : _qA
{
private readonly string ShellCommandNetworkAdapterMACAddress = \u003CModule\u003E.\u206E<string>(3331371713U);
private readonly string ShellCommandNetworkAdapterCaption = \u003CModule\u003E.\u206F<string>(4243712535U);</source>
