You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

注入类型与方法时遭遇Parent Does not Exist Error问题求助

排查"Parent Does not Exist Error"并实现方法替换

首先,咱们先拆解你遇到的Parent Does not Exist Error的核心原因,再一步步修正代码:

问题根源分析

  • 类型关联缺失:你创建的TypeDefUser("Simpy")没有设置有效的Parent属性,dnlib要求所有类型必须关联父节点(顶级类的父节点是模块的GlobalType),InjectHelper在注入校验时会因为找不到父节点抛出错误。
  • 元数据Token跨模块不兼容:你用当前AppDomain中typeof(Simpy).MetadataToken去解析另一个模块(moduleDefMD)的类型是错误的——不同模块的元数据Token是独立的,跨模块解析会得到无效的类型定义。
  • 注入流程顺序冲突:你手动将目标类型添加到模块后再调用InjectHelper,这和InjectHelper的预期流程不符,它通常会自行处理类型的关联与模块添加操作。

解决方案与修正后的代码

步骤1:修正类型注入逻辑

先从源模块中正确获取Simpy类型,再创建目标类型容器,由InjectHelper完成父节点关联和注入操作。

步骤2:精准替换目标方法

调整指令遍历逻辑,专门查找调用System.Convert.FromBase64String的位置,替换为Simpy.Simp调用。

完整修正代码

// 加载包含Simpy类型的源模块
ModuleDefMD sourceModule = ModuleDefMD.Load(typeof(runtime).Module);
// 从源模块直接查找Simpy类型(避免跨模块元数据Token问题)
TypeDef sourceSimpyType = sourceModule.Types.First(t => t.Name == "Simpy");

// 目标模块(你需要修改的目标模块实例,替换为你的moduleDef变量)
// 创建目标类型容器,指定基类为Object,暂不添加到模块
TypeDef targetSimpyType = new TypeDefUser(null, "Simpy", sourceModule.CorLibTypes.Object.TypeDefOrRef);
targetSimpyType.Attributes = TypeAttributes.AutoLayout | TypeAttributes.Class | TypeAttributes.Public;

// 执行类型与方法注入,获取注入后的定义集合
IEnumerable<IDnlibDef> injectedDefs = InjectHelper.Inject(sourceSimpyType, targetSimpyType, moduleDef);
// 提取注入后的Simp方法
MethodDef simpMethod = (MethodDef)injectedDefs.Single(m => m.Name == "Simp");
// 将方法导入到目标模块(确保调用时的兼容性)
var importedSimpMethod = moduleDef.Import(simpMethod);

// 遍历目标模块所有方法,替换FromBase64String调用
foreach (TypeDef type in moduleDef.Types)
{
    foreach (MethodDef method in type.Methods)
    {
        if (method.Body == null) continue;
        
        method.Body.SimplifyBranches();
        var instructions = method.Body.Instructions;
        
        // 查找调用System.Convert.FromBase64String的指令
        for (int i = 0; i < instructions.Count; i++)
        {
            Instruction instr = instructions[i];
            if (instr.OpCode == OpCodes.Call && instr.Operand is IMethodDefOrRef methodRef)
            {
                // 匹配目标方法的完整签名
                if (methodRef.FullName == "System.String System.Convert::FromBase64String(System.String)")
                {
                    // 替换为调用注入后的Simp方法
                    instr.Operand = importedSimpMethod;
                    // 若Simp方法签名与FromBase64String不一致,需额外调整参数/返回值指令
                }
            }
        }
        
        // 还原方法体的分支结构优化
        method.Body.OptimizeBranches();
    }
}

关键修正点说明

  • 正确获取源类型:直接从源模块按名称查找Simpy类型,彻底避免跨模块元数据Token不兼容的问题。
  • 自动关联父节点:创建TypeDefUser时指定基类,InjectHelper会自动设置Parent为目标模块的GlobalType,解决"Parent Does not Exist"错误。
  • 精准替换目标方法:专门匹配System.Convert.FromBase64String的调用指令,直接替换操作数为注入后的Simp方法,完全贴合你的需求。
  • 修复方法体结构:修改指令后调用OptimizeBranches(),确保方法体的分支逻辑保持正确。

内容的提问来源于stack exchange,提问作者Yung Samzy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 06:32:49