Example #1
0
        private void HookAndUpdate(MethodInfoRestoration m)
        {
            MethodInfo targetMethod  = m.OriginalMethod;
            MethodInfo replaceMethod = m.ReplacedMethod;

            byte[] ilCodes = new byte[5];
            ilCodes[0] = (byte)OpCodes.Jmp.Value;
            ilCodes[1] = (byte)(replaceMethod.MetadataToken & 0xFF);
            ilCodes[2] = (byte)(replaceMethod.MetadataToken >> 8 & 0xFF);
            ilCodes[3] = (byte)(replaceMethod.MetadataToken >> 16 & 0xFF);
            ilCodes[4] = (byte)(replaceMethod.MetadataToken >> 24 & 0xFF);

            InjectionHelper.UpdateILCodes(targetMethod, ilCodes);
        }
Example #2
0
        //private string GetExecutablePath(int ProcessId)
        //{
        //    var buffer = new StringBuilder(1024);
        //    IntPtr hprocess = OpenProcess(ProcessAccessFlags.QueryLimitedInformation,
        //                                  false, ProcessId);
        //    if (hprocess != IntPtr.Zero)
        //    {
        //        try
        //        {
        //            int size = buffer.Capacity;
        //            if (QueryFullProcessImageName(hprocess, 0, buffer, out size))
        //            {
        //                return buffer.ToString();
        //            }
        //        }
        //        finally
        //        {
        //            CloseHandle(hprocess);
        //        }
        //    }
        //    return string.Empty;
        //}



        private void SlamClassInternal(Type sourceType, Type replacementType)
        {
            var          methodReplacements = new List <MethodInfoRestoration>();
            BindingFlags bf = BindingFlags.FlattenHierarchy | BindingFlags.IgnoreReturn | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.SuppressChangeType;
            MethodInfo   methodFromSource = null;


            foreach (MethodInfo methodFromReplacement in replacementType.GetMethods(bf))
            {
                // premptive strike that needs to be replaced with better determiners
                if ((methodFromReplacement.Name == "ToString") || (methodFromReplacement.Name == "Dispose") || (methodFromReplacement.Name == "GetHashCode") || (methodFromReplacement.Name == "Equals") ||
                    (methodFromReplacement.Name == "ReferenceEquals") || (methodFromReplacement.Name == "GetType") || (methodFromReplacement.Name == "Finalize") || (methodFromReplacement.Name == "MemberwiseClone"))
                {
                    continue;
                }



                // check for SlamIngore attribute
                if (methodFromReplacement.GetCustomAttributes().Where(a => a.TypeId.ToString() == "Slam.DynamicInjection.SlamIgnore").Count > 0)
                {
                    continue;
                }

                methodFromSource = null;
                // make sure its one we actually can replace TODO: Add logging to those that cannot be
                if (
                    methodFromReplacement.GetMethodImplementationFlags() == MethodImplAttributes.IL ||
                    methodFromReplacement.GetMethodImplementationFlags() == MethodImplAttributes.NoInlining
                    )
                {
                    bool isOverLoaded = false;
                    var  replacementMethodParameterInfo = methodFromReplacement.GetParameters();
                    try
                    {
                        methodFromSource = sourceType.GetMethod(methodFromReplacement.Name.Replace("_Slam", ""), bf);
                    }

                    catch (System.Reflection.AmbiguousMatchException ambigous)
                    {
                        isOverLoaded = true;
                    }
                    if (isOverLoaded)
                    {
                        // this means that we have an overloaded method now we have to look more closely
                        var methods = sourceType.GetMethods(bf).Where(m => m.Name == methodFromReplacement.Name);

                        foreach (var method in methods)
                        {
                            var sourceMethodParameterInfo = method.GetParameters();
                            if (sourceMethodParameterInfo.Length == replacementMethodParameterInfo.Length)
                            {
                                bool found = true;
                                methodFromSource = null;
                                if (replacementMethodParameterInfo.Length == 0)
                                {
                                    methodFromSource = method;  // doing it below already
                                    break;
                                }

                                for (var i = 0; i < sourceMethodParameterInfo.Length; i++)
                                {
                                    if (sourceMethodParameterInfo[i].ParameterType != replacementMethodParameterInfo[i].ParameterType)
                                    {
                                        found = false;
                                    }
                                }

                                if (found)
                                {
                                    methodFromSource = method;
                                    break;
                                }
                            }
                        }
                    }


                    // let's store this stuff
                    MethodInfoRestoration methodInfoRestoration = new MethodInfoRestoration()
                    {
                        OriginalMethod = methodFromSource,
                        ReplacedMethod = methodFromReplacement,


                        OriginalMethodDetails = methodFromSource.GetMethodBody().GetILAsByteArray(),
                        ReplacedMethodDetails = methodFromReplacement.GetMethodBody().GetILAsByteArray(),
                    };
                    methodReplacements.Add(methodInfoRestoration);

                    // could move this out of the look if we preserve sourceType.
                    if (!ClassInfoRestoration.ContainsKey(sourceType.Name))
                    {
                        ClassInfoRestoration.Add(sourceType.Name, new List <MethodInfoRestoration>());
                    }

                    ClassInfoRestoration[sourceType.Name].Add(methodInfoRestoration);
                }
            }


            byte[] byteArrayOfNewFunction;

            // do IL work (for now doing it seperately
            foreach (var m in methodReplacements)
            {
                // check for slam vs. squirt
                if (
                    m.OriginalMethod.GetCustomAttributes()
                    .Where(a => a.TypeId.ToString() == "Slam.DynamicInjection.SlamSquirtee")
                    .Count > 0)
                {
                    int indexOfSquirtHere = m.ReplacedMethod.GetCustomAttribute <SlamSquirter>().InjectionIndex;
                    if (indexOfSquirtHere < 0 || indexOfSquirtHere > m.OriginalMethodDetails.Length)
                    {
                        throw new Exception("Index out of bounds");
                    }


                    byteArrayOfNewFunction = new byte[m.OriginalMethodDetails.Length + m.ReplacedMethodDetails.Length];

                    Array.Copy(m.OriginalMethodDetails, 0, byteArrayOfNewFunction, 0, indexOfSquirtHere);

                    Array.Copy(m.ReplacedMethodDetails, 0, byteArrayOfNewFunction, indexOfSquirtHere, m.ReplacedMethodDetails.Length);

                    Array.Copy(m.ReplacedMethodDetails, indexOfSquirtHere, byteArrayOfNewFunction, indexOfSquirtHere - 1 + m.ReplacedMethodDetails.Length, m.ReplacedMethodDetails.Length - indexOfSquirtHere);

                    //// then commit to the IL which is now in originalmethod details
                    InjectionHelper.UpdateILCodes(m.OriginalMethod, byteArrayOfNewFunction);

                    // output bytes
                    // squirtee
                    OutputIL(sourceType.Name, m.OriginalMethod.Name + " (Squirtee)", m.OriginalMethodDetails);
                    // squirter
                    OutputIL(sourceType.Name, m.OriginalMethod.Name + " (Squirter)", m.ReplacedMethodDetails);
                    // squirter
                    OutputIL(sourceType.Name, m.OriginalMethod.Name + " (New Squirtee)", byteArrayOfNewFunction);
                }
                else
                {
                    //   if (m.OriginalMethod.IsStatic) // OK to slam statics
                    InjectionHelper.UpdateILCodes(m.OriginalMethod, m.ReplacedMethodDetails);
                    //    else
                    //    {
                    //        HookAndUpdate(m);
                    //    }
                }
            }
        }