AgileDotNet 混淆代码调用错误函数
AgileDotNet obfuscated code calls the wrong function
在 c# 项目上 运行 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 会尝试调用它?如何调试这样的问题?
出现此异常的原因是代码使用 dynamic
类型,然后在此类实例上调用方法。
举个例子:
void Main()
{
dynamic t = new Test();
t.ActuallyNotPresentMethod();
}
public class Test
{
public void Execute() => "test".Dump();
}
这抛出:
RuntimeBinderException: 'UserQuery.Test' does not contain a definition for '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
来调用一个方法,并且这个字符串没有被混淆,因此包含原始的未混淆的方法名称。由于此方法不再以该名称存在,因此 运行time 活页夹在 运行time 抛出异常。
我不知道为什么 AgileDotNet 错过了动态。可能是它根本不处理 dynamic
,在这种情况下,您将不得不处理它。您应该联系 Secureteam 寻求帮助,以确定该工具能够提供什么(如果有的话)。
在 c# 项目上 运行 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 会尝试调用它?如何调试这样的问题?
出现此异常的原因是代码使用 dynamic
类型,然后在此类实例上调用方法。
举个例子:
void Main()
{
dynamic t = new Test();
t.ActuallyNotPresentMethod();
}
public class Test
{
public void Execute() => "test".Dump();
}
这抛出:
RuntimeBinderException: 'UserQuery.Test' does not contain a definition for '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
来调用一个方法,并且这个字符串没有被混淆,因此包含原始的未混淆的方法名称。由于此方法不再以该名称存在,因此 运行time 活页夹在 运行time 抛出异常。
我不知道为什么 AgileDotNet 错过了动态。可能是它根本不处理 dynamic
,在这种情况下,您将不得不处理它。您应该联系 Secureteam 寻求帮助,以确定该工具能够提供什么(如果有的话)。