示例#1
0
        public void Patch()
        {
            HelperClass.SetLogger(logger);
            MethodDefinition setBlocksMethod = HelperClass.findMember <MethodDefinition>(module, "GameManager", false,
                                                                                         HelperClass.MemberNameComparer <MethodDefinition>("SetBlocksRPC"));
            PropertyDefinition worldProperty = HelperClass.findMember <PropertyDefinition>(module, "GameManager", false,
                                                                                           HelperClass.MemberNameComparer <PropertyDefinition>("World"));

            if (setBlocksMethod != null && worldProperty != null)
            {
                MethodBody         body = setBlocksMethod.Body;
                ILProcessor        proc = body.GetILProcessor();
                List <Instruction> hook = HookHelper.Instance.prepareEventHook(setBlocksMethod, "SetBlocksEvent", new Instruction[][] {
                    new Instruction[] { proc.Create(OpCodes.Ldc_I4_0), proc.Create(OpCodes.Box, module.Import(mscorlibModule.GetType("System.Boolean"))) },
                    new Instruction[] { proc.Create(OpCodes.Ldarg_1) },
                    new Instruction[] { proc.Create(OpCodes.Ldarg_0), proc.Create(OpCodes.Call, module.Import(worldProperty.GetMethod)) },
                });
                hook.Add(proc.Create(OpCodes.Dup));
                hook.Add(proc.Create(OpCodes.Ldc_I4_0));
                hook.Add(proc.Create(OpCodes.Ldelem_Ref));
                hook.Add(proc.Create(OpCodes.Unbox_Any, module.Import(mscorlibModule.GetType("System.Boolean"))));
                int jmp1_sindex = hook.Count; hook.Add(null);                 //Brfalse
                hook.Add(proc.Create(OpCodes.Pop));
                hook.Add(proc.Create(OpCodes.Ret));
                int jmp1_tindex = hook.Count;
                hook.Add(proc.Create(OpCodes.Ldc_I4_1));
                hook.Add(proc.Create(OpCodes.Ldelem_Ref));
                hook.Add(proc.Create(OpCodes.Starg, 1));

                hook.Insert(jmp1_sindex, proc.Create(OpCodes.Brfalse, hook[jmp1_tindex])); hook.RemoveAt(jmp1_sindex + 1);
                HookHelper.insertAt(body, 0, hook.ToArray());
            }
        }
        public void Patch()
        {
            HelperClass.SetLogger(logger);

            MethodDefinition initChunkCluster = HelperClass.findMember <MethodDefinition>(module, "ChunkCluster", false,
                                                                                          HelperClass.MemberNameComparer <MethodDefinition>("Init"),
                                                                                          HelperClass.MethodParametersComparer("EnumChunkProviderId"));

            if (initChunkCluster == null)
            {
                return;
            }
            {
                int[] jumpsToDefault = HelperClass.FindOPCodePattern(initChunkCluster, new OpCode[] { OpCodes.Switch, OpCodes.Br }, 1);
                if (jumpsToDefault.Length == 0)
                {
                    logger.Error("ChunkCluster.Init has no switch (am I outdated?)!");
                    return;
                }
                if (jumpsToDefault.Length > 1)
                {
                    logger.Error("ChunkCluster.Init has multiple switches (am I outdated?)!");
                    return;
                }
                MethodBody body        = initChunkCluster.Body;
                int        targetIndex = body.Instructions.IndexOf((Instruction)body.Instructions[jumpsToDefault[0]].Operand);
                if (!HelperClass.MethodOPCodeComparer(new int[] { targetIndex, targetIndex + 1, targetIndex + 2 }, new OpCode[] { OpCodes.Ldarg_0, OpCodes.Ldnull, OpCodes.Stfld }, null).Execute(initChunkCluster))
                {
                    logger.Error("ChunkCluster.Init's default case is unknown (I am outdated!)!");
                    return;
                }

                ILProcessor        proc = body.GetILProcessor();
                List <Instruction> hook = HookHelper.Instance.prepareEventHook(initChunkCluster, "UnknownChunkProviderEvent", new Instruction[][] {
                    new Instruction[] { proc.Create(OpCodes.Ldarg_0) },
                    new Instruction[] { proc.Create(OpCodes.Ldc_I4_0), proc.Create(OpCodes.Box, module.Import(mscorlibModule.GetType("System.Boolean"))) },
                    new Instruction[] { proc.Create(OpCodes.Ldarg_1), proc.Create(OpCodes.Box, module.Import(mscorlibModule.GetType("System.Int32"))) },
                    new Instruction[] { proc.Create(OpCodes.Ldnull) },
                }); hook.Insert(0, proc.Create(OpCodes.Ldarg_0));
                hook.Add(proc.Create(OpCodes.Dup));
                hook.Add(proc.Create(OpCodes.Ldc_I4_1));
                hook.Add(proc.Create(OpCodes.Ldelem_Ref));
                hook.Add(proc.Create(OpCodes.Unbox_Any, module.Import(mscorlibModule.GetType("System.Boolean"))));
                int jmp1_sindex = hook.Count; hook.Add(null);                 //brtrue
                hook.Add(proc.Create(OpCodes.Pop));
                hook.Add(proc.Create(OpCodes.Br, body.Instructions[targetIndex + 1]));
                int jmp1_tindex = hook.Count;
                hook.Add(proc.Create(OpCodes.Ldc_I4_2));
                hook.Add(proc.Create(OpCodes.Ldelem_Ref));
                hook.Add(proc.Create(OpCodes.Br, body.Instructions[targetIndex + 2]));

                hook.RemoveAt(jmp1_sindex); hook.Insert(jmp1_sindex, proc.Create(OpCodes.Brtrue, hook[jmp1_tindex]));

                HookHelper.insertAt(body, targetIndex, hook.ToArray());
                body.Instructions[jumpsToDefault[0]].Operand = hook[0];
            }
        }
示例#3
0
        public void Patch()
        {
            HelperClass.SetLogger(logger);
            MethodDefinition onGameInit = HelperClass.findMember <MethodDefinition>(skModule, "SurvivalKit.SKMain", false,
                                                                                    HelperClass.MemberNameComparer <MethodDefinition>("onGameInit"));
            MethodDefinition onGameEnable = HelperClass.findMember <MethodDefinition>(skModule, "SurvivalKit.SKMain", false,
                                                                                      HelperClass.MemberNameComparer <MethodDefinition>("onGameEnable"));
            MethodDefinition onGameDisable = HelperClass.findMember <MethodDefinition>(skModule, "SurvivalKit.SKMain", false,
                                                                                       HelperClass.MemberNameComparer <MethodDefinition>("onGameDisable"));

            if (onGameInit == null || onGameEnable == null || onGameDisable == null)
            {
                return;
            }

            MethodDefinition initMethod = HelperClass.findMember <MethodDefinition>(module, "ConnectionManager", false,
                                                                                    HelperClass.MemberNameComparer <MethodDefinition>(".cctor"));
            MethodDefinition awakeMethod = HelperClass.findMember <MethodDefinition>(module, "GameManager", false,
                                                                                     HelperClass.MemberNameComparer <MethodDefinition>("Awake"));
            MethodDefinition cleanupMethod = HelperClass.findMember <MethodDefinition>(module, "GameManager", false,
                                                                                       HelperClass.MemberNameComparer <MethodDefinition>("Cleanup"));

            if (initMethod == null || awakeMethod == null || cleanupMethod == null)
            {
                return;
            }

            {
                ILProcessor proc = initMethod.Body.GetILProcessor();
                proc.InsertBefore(initMethod.Body.Instructions[0], proc.Create(OpCodes.Call, module.Import(onGameInit)));
            }
            {
                ILProcessor proc = awakeMethod.Body.GetILProcessor();
                Instruction lastInstr;
                proc.InsertBefore(awakeMethod.Body.Instructions[0], (lastInstr = proc.Create(OpCodes.Ldarg_0)));
                proc.InsertAfter(lastInstr, proc.Create(OpCodes.Call, module.Import(onGameEnable)));
            }
            {
                ILProcessor proc = cleanupMethod.Body.GetILProcessor();
                Instruction lastInstr;
                proc.InsertBefore(cleanupMethod.Body.Instructions[0], (lastInstr = proc.Create(OpCodes.Ldarg_0)));
                proc.InsertAfter(lastInstr, proc.Create(OpCodes.Call, module.Import(onGameDisable)));
            }
        }
示例#4
0
		public void Patch()
		{
			HelperClass.SetLogger(null);
			//foreach RPC method in ConnectionManager
			foreach (MethodDefinition mdef in HelperClass.findMembers<MethodDefinition>(module, "ConnectionManager", HelperClass.MemberCustomAttributeComparer<MethodDefinition>("UnityEngine.RPC")))
			{
				if (mdef.HasBody)
				{
					Mono.Collections.Generic.Collection<ParameterDefinition> _params = mdef.Parameters;
					if (_params.Count == 0 || !_params[_params.Count - 1].ParameterType.FullName.Equals("UnityEngine.NetworkMessageInfo"))
					{
						ParameterDefinition messageInfoPardef = new ParameterDefinition("_messageInfo", ParameterAttributes.None,
							mdef.DeclaringType.Module.Import(unityModule.GetType("UnityEngine.NetworkMessageInfo")));
						mdef.Parameters.Add(messageInfoPardef);
					}

					ILProcessor proc = mdef.Body.GetILProcessor();
					List<Instruction[]> argLoaders = new List<Instruction[]>();
					argLoaders.Add(new Instruction[] {
						proc.Create(OpCodes.Ldc_I4_0),
						proc.Create(OpCodes.Box, module.Import(mscorlibModule.GetType("System.Boolean"))),
					});
					argLoaders.Add(new Instruction[] {
						proc.Create(OpCodes.Ldstr, mdef.Name),
					});
					List<Instruction> instrTmp = new List<Instruction>();
					for (int i = 0; i < _params.Count; i++)
					{
						ParameterDefinition param = _params[i];
						instrTmp.Clear();
						instrTmp.Add(proc.Create(OpCodes.Ldarg, param));
						if (param.ParameterType.IsValueType)
						{
							instrTmp.Add(proc.Create(OpCodes.Box, module.Import(param.ParameterType)));
						}
						argLoaders.Add(instrTmp.ToArray());
					}

					List<Instruction> hook = HookHelper.Instance.prepareEventHook(mdef, "RPCEvent", argLoaders.ToArray());
					for (int i = 0; i < _params.Count; i++)
					{
						ParameterDefinition param = _params[i];
						hook.Add(proc.Create(OpCodes.Dup));
						hook.Add(proc.Create(OpCodes.Ldc_I4, i + 2));
						hook.Add(proc.Create(OpCodes.Ldelem_Ref));
						if (param.ParameterType.IsValueType)
						{
							hook.Add(proc.Create(OpCodes.Unbox_Any, module.Import(param.ParameterType)));
						}
						else
						{
							hook.Add(proc.Create(OpCodes.Castclass, module.Import(param.ParameterType)));
						}
						hook.Add(proc.Create(OpCodes.Starg, param));
					}
					hook.Add(proc.Create(OpCodes.Ldc_I4_0));
					hook.Add(proc.Create(OpCodes.Ldelem_Ref));
					hook.Add(proc.Create(OpCodes.Unbox_Any, module.Import(mscorlibModule.GetType("System.Boolean"))));
					hook.Add(proc.Create(OpCodes.Brfalse, mdef.Body.Instructions[0]));
					hook.Add(proc.Create(OpCodes.Ret));
					HookHelper.insertAt(mdef.Body, 0, hook.ToArray());
				}
			}
		}
示例#5
0
        private IInstructionGenerator ParseOpcode(XmlNode opNode)
        {
            XmlNode opcodeNode = opNode.Attributes["name"];

            if (opcodeNode == null)
            {
                throw new ArgumentException("xmlpatchers.xml : An opcode node doesn't define a name attribute!");
            }
            string opcodeName = opcodeNode.Value.ToLower();

            if (!opCodeList.ContainsKey(opcodeName))
            {
                throw new ArgumentException("xmlpatchers.xml : An invalid opcode was passed (" + opcodeNode.Value + ")!");
            }
            string opType = opNode.Attributes.ValueOf("opType").ToLower();
            string op     = opNode.Attributes.ValueOf("op");
            OpCode opcode = opCodeList[opcodeName];

            switch (opType)
            {
            case "sbyte":
                return(new InstructionGenerator(opcode, SByte.Parse(op), (_p, _i, _opcode, _operand) => _p.Create(opcode, (SByte)_operand)));

            case "byte":
                return(new InstructionGenerator(opcode, Byte.Parse(op), (_p, _i, _opcode, _operand) => _p.Create(opcode, (Byte)_operand)));

            case "int32":
            case "int":
                return(new InstructionGenerator(opcode, Int32.Parse(op), (_p, _i, _opcode, _operand) => _p.Create(opcode, (Int32)_operand)));

            case "int64":
            case "long":
                return(new InstructionGenerator(opcode, Int64.Parse(op), (_p, _i, _opcode, _operand) => _p.Create(opcode, (Int64)_operand)));

            case "single":
            case "float":
                return(new InstructionGenerator(opcode, Single.Parse(op), (_p, _i, _opcode, _operand) => _p.Create(opcode, (Single)_operand)));

            case "double":
                return(new InstructionGenerator(opcode, Double.Parse(op), (_p, _i, _opcode, _operand) => _p.Create(opcode, (Double)_operand)));

            case "string":
                return(new InstructionGenerator(opcode, op, (_p, _i, _opcode, _operand) => _p.Create(opcode, (string)_operand)));

            case "tref":
            {
                TypeDefinition typeDef = findType(op);
                if (typeDef == null)
                {
                    throw new ArgumentException("xmlpatchers.xml : Unable to find type \"" + op + "\"!");
                }
                return(new InstructionGenerator(opcode, module.Import(typeDef), (_p, _i, _opcode, _operand) => _p.Create(opcode, (TypeReference)_operand)));
            }

            case "fref":
            {
                string[] opSplit = op.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
                if (opSplit.Length != 2)
                {
                    throw new ArgumentException("xmlpatchers.xml : A fref operand has an illegal count of semicolons!");
                }

                TypeDefinition typeDef = findType(opSplit[0]);
                if (typeDef == null)
                {
                    throw new ArgumentException("xmlpatchers.xml : Unable to find type \"" + opSplit[0] + "\"!");
                }

                HelperClass.SetLogger(null);
                FieldDefinition fdef = HelperClass.findMember <FieldDefinition>(module, typeDef, false,
                                                                                HelperClass.MemberNameComparer <FieldDefinition>(opSplit[1]));
                HelperClass.SetLogger(logger);
                if (fdef == null)
                {
                    throw new ArgumentException("xmlpatchers.xml : Unable to find field \"" + (opSplit[0] + "." + opSplit[1]) + "\"!");
                }

                return(new InstructionGenerator(opcode, module.Import(fdef), (_p, _i, _opcode, _operand) => _p.Create(opcode, (FieldReference)_operand)));
            }

            case "mref":
            {
                string[] opSplit = op.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
                if (opSplit.Length != 2 && opSplit.Length != 3)
                {
                    throw new ArgumentException("xmlpatchers.xml : A fref operand has an illegal count of semicolons!");
                }

                TypeDefinition typeDef = findType(opSplit[0]);
                if (typeDef == null)
                {
                    throw new ArgumentException("xmlpatchers.xml : Unable to find type \"" + opSplit[0] + "\"!");
                }

                string[] _params = (opSplit.Length == 2) ? null : opSplit[2].Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
                //I don't always use 'var' but when I do, it would be odd not to.
                var methodComparers = new List <HelperClass.GenericFuncContainer <MethodDefinition, bool> >(opSplit.Length - 1);
                methodComparers.Add(HelperClass.MemberNameComparer <MethodDefinition>(opSplit[1]));
                if (_params != null)
                {
                    methodComparers.Add(HelperClass.MethodParametersComparer(_params));
                }
                HelperClass.SetLogger(null);
                MethodDefinition mdef = HelperClass.findMember <MethodDefinition>(module, typeDef, false, methodComparers.ToArray());
                HelperClass.SetLogger(logger);
                if (mdef == null)
                {
                    throw new ArgumentException("xmlpatchers.xml : Unable to find method \"" + (opSplit[0] + "." + opSplit[1]) + "\"!");
                }

                return(new InstructionGenerator(opcode, module.Import(mdef), (_p, _i, _opcode, _operand) => _p.Create(opcode, (MethodReference)_operand)));
            }

            case "instref":
                return(new InstructionGenerator(opcode, Int32.Parse(op), (_p, _i, _opcode, _operand) => {
                    int _targetIndex = (int)_operand;
                    if (_targetIndex >= _i.Count)
                    {
                        return null;
                    }
                    return _p.Create(_opcode, _i[_targetIndex]);
                }));

            case "none":
            case "":
                return(new NoOPInstructionGenerator(opcode));

            default:
                throw new ArgumentException("xmlpatchers.xml : Unknown operand type \"" + opType + "\"!");
            }
        }
示例#6
0
        public void Patch()
        {
            HelperClass.SetLogger(null);             //HelperClass.OnError would otherwise show errors if a NetPackage class doesn't override Process,Read or Write
            TypeDefinition[] netPackageTypes = HelperClass.findTypes(module,
                                                                     HelperClass.CombinedComparer <MethodDefinition>(
                                                                         HelperClass.MemberNameComparer <MethodDefinition>("GetPackageType"),
                                                                         HelperClass.MethodReturnTypeComparer("PackageType"),
                                                                         HelperClass.MethodNegAttributeComparer(MethodAttributes.Abstract))
                                                                     );
            if (netPackageTypes == null || netPackageTypes.Length == 0)
            {
                logger.Error("Unable to find any NetPackage classes!");
                return;
            }

            foreach (TypeDefinition curPackageType in netPackageTypes)
            {
                MethodDefinition processMethod = HelperClass.findMember <MethodDefinition>(module, curPackageType, false,
                                                                                           HelperClass.MemberNameComparer <MethodDefinition>("Process"),
                                                                                           HelperClass.MethodReturnTypeComparer("System.Void"),
                                                                                           HelperClass.MethodParametersComparer("World", "INetConnectionCallbacks"));
                if (processMethod != null)
                {
                    MethodBody body = processMethod.Body;
                    if (body != null)
                    {
                        ILProcessor        proc      = body.GetILProcessor();
                        List <Instruction> eventHook = HookHelper.Instance.prepareEventHook(processMethod, "ProcessPacketEvent",
                                                                                            new Instruction[][] {
                            new Instruction[] {
                                proc.Create(OpCodes.Ldarg_0),
                            },
                            new Instruction[] {
                                proc.Create(OpCodes.Ldc_I4_0),
                                proc.Create(OpCodes.Box, module.Import(mscorlibModule.GetType("System.Boolean"))),
                            },
                            new Instruction[] {
                                proc.Create(OpCodes.Ldarg_1),
                            },
                            new Instruction[] {
                                proc.Create(OpCodes.Ldarg_2),
                            },
                        }
                                                                                            );
                        eventHook.Add(proc.Create(OpCodes.Ldc_I4_1));
                        eventHook.Add(proc.Create(OpCodes.Ldelem_Ref));
                        eventHook.Add(proc.Create(OpCodes.Unbox_Any, module.Import(mscorlibModule.GetType("System.Boolean"))));
                        eventHook.Add(proc.Create(OpCodes.Brfalse, body.Instructions[0]));
                        eventHook.Add(proc.Create(OpCodes.Ret));
                        HookHelper.insertAt(body, 0, eventHook.ToArray());
                    }
                }
                MethodDefinition readMethod = HelperClass.findMember <MethodDefinition>(module, curPackageType, false,
                                                                                        HelperClass.MemberNameComparer <MethodDefinition>("Read"),
                                                                                        HelperClass.MethodReturnTypeComparer("System.Void"),
                                                                                        HelperClass.MethodParametersComparer("System.IO.BinaryReader"));
                if (readMethod != null)
                {
                    MethodBody body = readMethod.Body;
                    if (body != null)
                    {
                        ILProcessor        proc      = body.GetILProcessor();
                        List <Instruction> eventHook = HookHelper.Instance.prepareEventHook(readMethod, "ReadPacketFromBufEvent",
                                                                                            new Instruction[][] {
                            new Instruction[] {
                                proc.Create(OpCodes.Ldarg_0),
                            },
                        }
                                                                                            );
                        eventHook.Add(proc.Create(OpCodes.Pop));
                        HookHelper.insertAt(body, body.Instructions.Count - 1, eventHook.ToArray());
                    }
                }
                MethodDefinition writeMethod = HelperClass.findMember <MethodDefinition>(module, curPackageType, false,
                                                                                         HelperClass.MemberNameComparer <MethodDefinition>("Write"),
                                                                                         HelperClass.MethodReturnTypeComparer("System.Void"),
                                                                                         HelperClass.MethodParametersComparer("System.IO.BinaryWriter"));
                if (writeMethod != null)
                {
                    MethodBody body = writeMethod.Body;
                    if (body != null)
                    {
                        ILProcessor        proc      = body.GetILProcessor();
                        List <Instruction> eventHook = HookHelper.Instance.prepareEventHook(writeMethod, "WritePacketToBufEvent",
                                                                                            new Instruction[][] {
                            new Instruction[] {
                                proc.Create(OpCodes.Ldarg_0),
                            },
                            new Instruction[] {
                                proc.Create(OpCodes.Ldc_I4_0),
                                proc.Create(OpCodes.Box, module.Import(mscorlibModule.GetType("System.Boolean"))),
                            },
                        }
                                                                                            );
                        eventHook.Add(proc.Create(OpCodes.Ldc_I4_1));
                        eventHook.Add(proc.Create(OpCodes.Ldelem_Ref));
                        eventHook.Add(proc.Create(OpCodes.Unbox_Any, module.Import(mscorlibModule.GetType("System.Boolean"))));
                        eventHook.Add(proc.Create(OpCodes.Brfalse, body.Instructions[0]));
                        eventHook.Add(proc.Create(OpCodes.Ret));
                        HookHelper.insertAt(body, 0, eventHook.ToArray());
                    }
                }
            }
        }