如何在Visual Studio Xamarin中使用Phoenix Protector

时间:2019-03-25 15:59:14

标签: xamarin obfuscation

根据我在ildasm中看到的内容,在DLL上使用Phoenix Protector后,生成的混淆DLL似乎变得非常模糊。 Dotfuscator Community Edition并非如此。

我可以在VS的Post Build部分中放置命令行以调用Phoenix Protector,然后将生成的DLL复制回主发行目录。

但是,当我这样做时,链接器失败:找不到特定的过程。

关于如何在打包用于Android的DLL中使用Phoenix Protector的任何想法。

1 个答案:

答案 0 :(得分:0)

我已经尝试过将它与xamarin结合使用并进行构建,但是该应用程序无法在我的三星上启动。所以我真的不知道是什么问题。

在这里,我将为您提供一种使用方法。

首先创建一个项目并为其命名,例如Tasker

创建一个名称为Locker的类,当使用多个平台时,这是importend。

using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;


namespace Tasker
{
    public abstract class Locker : Task
    {
        public string ApplicationPath { get; set; }
        public string Source { get; set; }
        protected string DllSource { get; set; }
        protected string settingsPath { get; set; }
        protected string TaskLocker { get; set; }
        public bool Hidden { get; set; }
        public bool StayOpen { get; set; }
        protected void Lock()
        {
            try
            {
                File.WriteAllText(TaskLocker, "true");
            }
            catch
            {

            }
        }

        protected void Release()
        {
            try
            {
                 File.Delete(TaskLocker);
            }
            catch
            {

            }
        }

        protected bool Await()
        {
            try
            {
                return File.Exists(TaskLocker) && !string.IsNullOrWhiteSpace(File.ReadAllText(TaskLocker));
            }
            catch
            {
                return true;
            }
        }


        protected void DeleteFolder(string dir)
        {
            if (Directory.Exists(dir))
            {
                var dic = new DirectoryInfo(dir);
                foreach (var file in dic.GetFiles("*.*", SearchOption.AllDirectories))
                    file.Delete();
                try
                {
                    dic.Delete(true);
                }
                catch
                {

                }
            }
        }

        protected bool SetDllSource()
        {
            DllSource = Source.Replace("\\bin\\", "\\obj\\");
            var dllFile = Path.GetFileName(Source);
            if (!File.Exists(DllSource))
            {
                base.Log.LogMessage(MessageImportance.High, DllSource + " Could not be found. Please rebuild agen, will try search for the right dll");
                var d = new DirectoryInfo(Path.GetDirectoryName(DllSource)).GetFiles($"*{dllFile}*", SearchOption.AllDirectories).FirstOrDefault(); // fix for mono
                if (d == null)
                {
                    base.Log.LogMessage(MessageImportance.High, DllSource + " Could not be found. Please rebuild agen ");
                    return false;
                }
                else DllSource = d.FullName;
                base.Log.LogMessage(MessageImportance.High, "will use this dll instead:" + DllSource);
            }
            return true;
        }
    }
}

现在创建一个名称为Phoenix_Protector的类,该类继承自locker

using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading;

namespace Tasker
{
    public class Phoenix_Protector : Locker
    {
        static string CalculateMD5(string filename)
        {
            using (var md5 = MD5.Create())
            {
                using (var stream = File.OpenRead(filename))
                {
                    var hash = md5.ComputeHash(stream);
                    return BitConverter.ToString(hash).Replace("-", "");
                }
            }
        }

        static string ToBase64String(string msg)
        {
            var hash = Encoding.Unicode.GetBytes(msg + "\0");
            return Convert.ToBase64String(hash);
        }

        private void CreateProjectFile()
        {
            if (!File.Exists(settingsPath))
            {
                var msg = DllSource.Trim();
                var base64String = ToBase64String(msg);
                var hash = CalculateMD5(msg);

                var str = new StringBuilder()
                    .AppendLine("<?xml version=\"1.0\" ?>")
                    .AppendLine("<PROJECT Version=\"1\">")
                    .AppendLine("    <FILES>")
                    .AppendLine("        <FILE>")
                    .AppendLine("           <SOURCE>")
                    .AppendLine("               " + base64String)
                    .AppendLine("           </SOURCE>")
                    .AppendLine("           <CHECKSUM>" + hash + "</CHECKSUM>")
                    .AppendLine("            <DOTNET>")
                    .AppendLine("               <OBFUSCATE_NAMES>TRUE</OBFUSCATE_NAMES>")
                    .AppendLine("               <OBFUSCATE_PUBLIC_NAMES>FALSE</OBFUSCATE_PUBLIC_NAMES>")
                    .AppendLine("               <OBFUSCATE_FIELDS>TRUE</OBFUSCATE_FIELDS>")
                    .AppendLine("               <OBFUSCATE_PROPERTIES>FALSE</OBFUSCATE_PROPERTIES>")
                    .AppendLine("               <EXCLUDE_NAMES>FALSE</EXCLUDE_NAMES>")
                    .AppendLine("               <NO_OBFUSCATION_ARRAY></NO_OBFUSCATION_ARRAY>")
                    .AppendLine("               <OBFUSCATE_STRINGS>TRUE</OBFUSCATE_STRINGS>")
                    .AppendLine("               <CODE_SCRAMBLE>FALSE</CODE_SCRAMBLE>")
                    .AppendLine("               <REMOVE_SNS>FALSE</REMOVE_SNS>")
                    .AppendLine("            </DOTNET>")
                    .AppendLine("        </FILE>")
                    .AppendLine("    </FILES>")
                    .AppendLine("</PROJECT>");

                File.WriteAllText(settingsPath, str.ToString());

            }
        }

        public override bool Execute()
        {
            var directory = Path.GetDirectoryName(Source);
            var dllDirNew = Path.Combine(directory, Path.GetFileNameWithoutExtension(Source));
            var applicationPath = Path.GetDirectoryName(ApplicationPath);
            var name = Path.GetFileName(ApplicationPath);
            var nettype = directory.Split('\\').Last();
            settingsPath = Path.Combine(new DirectoryInfo(Path.GetDirectoryName(Source)).Parent.Parent.FullName, nettype + "_Obfuscation_Project.ppe");
            TaskLocker = Path.Combine(new DirectoryInfo(Path.GetDirectoryName(Source)).Parent.Parent.FullName, "lock.config");
            if (!SetDllSource())
            {
                return false;
            }

            DeleteFolder(dllDirNew);
            base.Log.LogMessage(MessageImportance.High, "Process:" + DllSource);

            Directory.CreateDirectory(dllDirNew);
            CreateProjectFile();
            while (Await())
                Thread.Sleep(300);
            Lock();
            var args = $"-p \"{settingsPath}\" \"{dllDirNew}\" {(StayOpen ? "/K" : "")}";

            var process = new Process
            {
                StartInfo = new ProcessStartInfo()
                {
                    Arguments = args,
                    FileName = name,
                    WorkingDirectory = applicationPath,
                    WindowStyle = Hidden ? ProcessWindowStyle.Hidden : ProcessWindowStyle.Normal
                }
            };

            var exited = false;
            process.EnableRaisingEvents = true;
            process.Exited += new EventHandler((o, e) =>
            {
                exited = true;
            });
            string counter = ".";
            base.Log.LogMessage(MessageImportance.High, "Obfuscation-Start:" + Source);
            base.Log.LogMessage(MessageImportance.High, "ApplicationWorkingDirectory:" + applicationPath);
            base.Log.LogMessage(MessageImportance.High, "ApplicationFileName:" + name);
            base.Log.LogMessage(MessageImportance.High, "Args:" + args);
            process.Start();
            const int SleepAmount = 100;
            var elapsedTime = 0;
            while (!exited)
            {
                base.Log.LogMessage(MessageImportance.High, counter);
                counter += ".";
                elapsedTime += SleepAmount;
                Thread.Sleep(SleepAmount);
            }

            Thread.Sleep(1000);
            var files = new DirectoryInfo(dllDirNew).GetFiles("*.*", SearchOption.AllDirectories);
            if (files.Any())
            {
                foreach (var file in files)
                {
                    if (Source.Contains(file.Name))
                    {
                        base.Log.LogMessage(MessageImportance.High, $"Copy:{file.FullName} To {Source}");
                        File.Delete(Source);
                        file.CopyTo(Source, true);
                    }
                    else
                    {
                        //var xName = file.Name.Contains("appExtension") ? $"{autoName}.{file.Name}" : file.Name;


                        base.Log.LogMessage(MessageImportance.High, $"Copy:{file.FullName} To {Path.Combine(directory, file.Name)}");
                        File.Delete(Path.Combine(directory, file.Name));
                        file.CopyTo(Path.Combine(directory, file.Name), true);
                    }
                }

                DeleteFolder(dllDirNew);
            }

            base.Log.LogMessage(MessageImportance.High, "Obfuscation-Finish:" + Source);
            Release();
            return true;
        }
    }
}

这是UserTask

现在创建一个Obfuscation.props文件并将其保存在解决方案的根文件夹中。

<?xml version="1.0" encoding="utf-8" ?>
<Project>
 <UsingTask TaskName="Tasker.Phoenix_Protector" AssemblyFile="E:\Projects\Tasker\bin\Release\netstandard2.0\tasker.dll" />
 </Project>

现在在您的项目文件(csproj)的底部添加这些行。

  <Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="'$(Configuration)'=='Release'">
    <Phoenix_Protector ApplicationPath="C:\Program Files (x86)\NTCore\Phoenix Protector\Phoenix_Protector.exe" Source="$(TargetPath)" />
  </Target>

  <Import Condition="Exists('..\Obfuscation.props')" Project="..\Obfuscation.props" />

让我知道它的运行方式。我的意思是,如果您的应用启动了,那么我认为一切正常。 ddl模糊处理和解决方案构建。我也可以创建我的apk并安装它,但是我的应用程序崩溃了,我尚未对此进行调查。

当我混淆dll时,我都不能使用progaurd。这不仅发生在Phoenix_Protector中,而且还发生在其他Obfuscate应用程序中。

我还应该提到您应该将Phoenix Protector重命名为Phoenix_Protector,否则命令行将无法正常工作。