首页 > 解决方案 > AgileDotNet 混淆代码调用错误函数

问题描述

在 ac# 项目上运行 AgileDotNet 后,我​​遇到了最不寻常的错误:

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'qVQ=.qLQ=' does not contain a definition for 'MyFunctionActualName'
   at CallSite.Target(Closure , CallSite , Type , Object , Object )
   at System.Dynamic.UpdateDelegates.UpdateAndExecute3[T0,T1,T2,TRet](CallSite site, T0 arg0, T1 arg1, T2 arg2)
   at ohM=.oQM=.<OnCallback>d__21.MoveNext()     Program.cs::OnCallback() #449

C# 试图通过函数的实际名称调用函数,即:MyFunctionActualName. 由于代码被混淆了,当然带有名称的函数MyFunctionActualName不再存在。为什么 AgileDotNet 尝试调用它?如何调试这样的问题?

标签: c#obfuscation

解决方案


此异常的原因是由于代码使用了该dynamic类型,然后在此类实例上调用了方法。

让我给你看一个例子:

void Main()
{
    dynamic t = new Test();
    t.ActuallyNotPresentMethod();
}

public class Test
{
    public void Execute() => "test".Dump();
}

这抛出:

RuntimeBinderException:“UserQuery.Test”不包含“ActuallyNotPresentMethod”的定义

让我们看一下它生成的 IL,该UserQuery部分来自LINQPad,我用来运行上面的示例并从以下获取 IL:

IL_0000:  newobj      UserQuery+Test..ctor
IL_0005:  stloc.0     
IL_0006:  ldsfld      UserQuery+<>o__4.<>p__0
IL_000B:  brtrue.s    IL_0041
IL_000D:  ldc.i4      00 01 00 00 
IL_0012:  ldstr       "ActuallyNotPresentMethod"
IL_0017:  ldnull      
IL_0018:  ldtoken     UserQuery
IL_001D:  call        System.Type.GetTypeFromHandle
IL_0022:  ldc.i4.1    
IL_0023:  newarr      Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo
IL_0028:  dup         
IL_0029:  ldc.i4.0    
IL_002A:  ldc.i4.0    
IL_002B:  ldnull      
IL_002C:  call        Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create
IL_0031:  stelem.ref  
IL_0032:  call        Microsoft.CSharp.RuntimeBinder.Binder.InvokeMember
IL_0037:  call        System.Runtime.CompilerServices.CallSite<System.Action<System.Runtime.CompilerServices.CallSite,System.Object>>.Create
IL_003C:  stsfld      UserQuery+<>o__4.<>p__0
IL_0041:  ldsfld      UserQuery+<>o__4.<>p__0
IL_0046:  ldfld       System.Runtime.CompilerServices.CallSite<System.Action<System.Runtime.CompilerServices.CallSite,System.Object>>.Target
IL_004B:  ldsfld      UserQuery+<>o__4.<>p__0
IL_0050:  ldloc.0     
IL_0051:  callvirt    System.Action<System.Runtime.CompilerServices.CallSite,System.Object>.Invoke
IL_0056:  ret   

如果你看这一行:

IL_0012:  ldstr       "ActuallyNotPresentMethod"

您可以看到要调用的方法的名称实际上作为字符串文字嵌入在 IL 中。

如果我们将代码更改为不使用dynamic,并调用Execute存在,我们得到:

IL_0000:  newobj      UserQuery+Test..ctor
IL_0005:  callvirt    UserQuery+Test.Execute
IL_000A:  ret  

你可以看到调用是完全不同的。

这解释了异常。该代码dynamic用于调用方法,并且此字符串未经过混淆处理,因此包含原始未混淆方法名称。由于该方法不再以该名称存在,因此运行时绑定程序会在运行时引发异常。

为什么,确切地说,AgileDotNet 错过了我不知道的动态。可能是它根本无法处理dynamic,在这种情况下,您将不得不处理它。您应该联系 Secureteam寻求帮助,以确定该工具能够提供什么(如果有的话)。


推荐阅读