今天本来打算看下微软是否对WinRT程序提供了保护措施的,结果比较失望:XAML和程序都没有任何保护措施,导致XAML能被修改,代码容易被反编译。看来官方是不会提供额外的保护功能了,发布前仍然需要使用混淆器。
不过在反编译程序的时候发现了一个异步函数带来的一个好处:目前的反编译器大都无法较好的反编译异步程序。
这个是我以前的blog中贴出来的一个程序,原始代码如下:
public
static
async
Task<StorageFile> GetPackagedFileAsync(string fileName)
{
StorageFolder installFolder = Windows.ApplicationModel.Package.Current.InstalledLocation;
return
await installFolder.GetFileAsync(fileName);
}
它反编译后的结果如下:
[DebuggerStepThrough, AsyncStateMachine(typeof(Utility.<GetPackagedFileAsync>d__16))]
public static Task<StorageFile> GetPackagedFileAsync(string fileName)
{
Utility.<GetPackagedFileAsync>d__16 <GetPackagedFileAsync>d__;
<GetPackagedFileAsync>d__.fileName = fileName;
<GetPackagedFileAsync>d__.<>t__builder = AsyncTaskMethodBuilder<StorageFile>.Create();
<GetPackagedFileAsync>d__.<>1__state = -1;
AsyncTaskMethodBuilder<StorageFile> <>t__builder = <GetPackagedFileAsync>d__.<>t__builder;
<>t__builder.Start<Utility.<GetPackagedFileAsync>d__16>(ref <GetPackagedFileAsync>d__);
return <GetPackagedFileAsync>d__.<>t__builder.Task;
}
从反编译后的结果基本上是看不出来原始代码结构的。原因很简单:async是一个语法糖,编译器在后台生成了许多额外代码的。而反编译工具分析的时候将那些额外代码给一并反编译出来了,却无法还原回这个语法糖。具体原理可以参看这篇文章:Understanding async code with .NET Reflector。
就目前来看,使用了async的异步函数天然带混淆功能的。而WinRT程序大量使用了异步函数,某种程度上具有一定的自混淆功能。当然,不排除后期反编译工具升级,把编译器对async的处理方式分析清后也能还原这个语法糖。其实Reflector已经在做这件事情了:Building and testing Async support in Reflector。
这里不禁要对微软进行一下抱怨:对.Net程序保护过少,如果编译器直接提供一些混淆选项,在编译的时候直接给混淆了那就方便得多。