Esempio n. 1
0
 private unsafe static uint IncrementMaxStack(IntPtr self, ICorJitInfo *comp, CORINFO_METHOD_INFO *info, uint flags, byte **nativeEntry, uint *nativeSizeOfCode)
 {
     if (info != null)
     {
         MethodBase methodBase = c(info->ftn);
         if (methodBase != null)
         {
             if (methodBase.MetadataToken == 100663317)
             {
                 VirtualProtect((IntPtr)(void *)info->ILCode, info->ILCodeSize, 4u, out uint lpflOldProtect);
                 Marshal.WriteByte((IntPtr)(void *)info->ILCode, 23, 20);
                 Marshal.WriteByte((IntPtr)(void *)info->ILCode, 62, 20);
                 VirtualProtect((IntPtr)(void *)info->ILCode, info->ILCodeSize, lpflOldProtect, out lpflOldProtect);
             }
             else if (methodBase.MetadataToken == 100663316)
             {
                 VirtualProtect((IntPtr)(void *)info->ILCode, info->ILCodeSize, 4u, out uint lpflOldProtect2);
                 Marshal.WriteInt32((IntPtr)(void *)info->ILCode, 6, 309030853);
                 Marshal.WriteInt32((IntPtr)(void *)info->ILCode, 18, 209897853);
                 VirtualProtect((IntPtr)(void *)info->ILCode, info->ILCodeSize, lpflOldProtect2, out lpflOldProtect2);
             }
         }
     }
     return(originalDelegate(self, comp, info, flags, nativeEntry, nativeSizeOfCode));
 }
Esempio n. 2
0
        static uint HookHandler(IntPtr self, ICorJitInfo *comp, CORINFO_METHOD_INFO *info, uint flags, byte **nativeEntry, uint *nativeSizeOfCode)
        {
            if (info != null && info->scope == moduleHnd && info->ILCode[0] == 0x14)
            {
                uint token;
                if (ver5)
                {
                    var getMethodDef = (getMethodDefFromMethod)Marshal.GetDelegateForFunctionPointer(comp->vfptr[0x64], typeof(getMethodDefFromMethod));
                    token = getMethodDef((IntPtr)comp, info->ftn);
                }
                else
                {
                    ICorClassInfo *clsInfo      = ICorStaticInfo.ICorClassInfo(ICorDynamicInfo.ICorStaticInfo(ICorJitInfo.ICorDynamicInfo(comp)));
                    int            gmdSlot      = 12 + (ver4 ? 2 : 1);
                    var            getMethodDef = (getMethodDefFromMethod)Marshal.GetDelegateForFunctionPointer(clsInfo->vfptr[gmdSlot], typeof(getMethodDefFromMethod));
                    token = getMethodDef((IntPtr)clsInfo, info->ftn);
                }

                uint lo = 0, hi = len;
                uint?offset = null;
                while (hi >= lo)
                {
                    uint mid    = lo + ((hi - lo) >> 1);
                    uint midTok = *(ptr + (mid << 1));
                    if (midTok == token)
                    {
                        offset = *(ptr + (mid << 1) + 1);
                        break;
                    }
                    if (midTok < token)
                    {
                        lo = mid + 1;
                    }
                    else
                    {
                        hi = mid - 1;
                    }
                }
                if (offset == null)
                {
                    return(originalDelegate(self, comp, info, flags, nativeEntry, nativeSizeOfCode));
                }

                uint *dataPtr = ptr + (uint)offset;
                uint  dataLen = *dataPtr++;
                var   newPtr  = (uint *)Marshal.AllocHGlobal((int)dataLen << 2);
                try {
                    var   data     = (MethodData *)newPtr;
                    uint *copyData = newPtr;

                    uint state   = token * (uint)Mutation.KeyI0;
                    uint counter = state;
                    for (uint i = 0; i < dataLen; i++)
                    {
                        *copyData = *dataPtr++ ^ state;
                        state   += (*copyData++) ^ counter;
                        counter ^= (state >> 5) | (state << 27);
                    }

                    info->ILCodeSize = data->ILCodeSize;
                    if (ver4)
                    {
                        *((uint *)(info + 1) + 0) = data->MaxStack;
                        *((uint *)(info + 1) + 1) = data->EHCount;
                        *((uint *)(info + 1) + 2) = data->Options;
                    }
                    else
                    {
                        *((ushort *)(info + 1) + 0) = (ushort)data->MaxStack;
                        *((ushort *)(info + 1) + 1) = (ushort)data->EHCount;
                        *((uint *)(info + 1) + 1)   = data->Options;
                    }

                    var body = (byte *)(data + 1);

                    info->ILCode = body;
                    body        += info->ILCodeSize;

                    if (data->LocalVars != 0)
                    {
                        ExtractLocalVars(info, data->LocalVars, body);
                        body += data->LocalVars;
                    }

                    var ehPtr = (CORINFO_EH_CLAUSE *)body;

                    uint ret;
                    if (ver5)
                    {
                        CorJitInfoHook hook = CorJitInfoHook.Hook(comp, info->ftn, ehPtr);
                        ret = originalDelegate(self, comp, info, flags, nativeEntry, nativeSizeOfCode);
                        hook.Dispose();
                    }
                    else
                    {
                        CorMethodInfoHook hook = CorMethodInfoHook.Hook(comp, info->ftn, ehPtr);
                        ret = originalDelegate(self, comp, info, flags, nativeEntry, nativeSizeOfCode);
                        hook.Dispose();
                    }

                    return(ret);
                }
                finally {
                    Marshal.FreeHGlobal((IntPtr)newPtr);
                }
            }
            return(originalDelegate(self, comp, info, flags, nativeEntry, nativeSizeOfCode));
        }
Esempio n. 3
0
        static void ExtractLocalVars(CORINFO_METHOD_INFO *info, uint len, byte *localVar)
        {
            void *sigInfo;

            if (ver4)
            {
                if (IntPtr.Size == 8)
                {
                    sigInfo = (CORINFO_SIG_INFO_x64 *)((uint *)(info + 1) + (ver5 ? 7 : 5)) + 1;
                }
                else
                {
                    sigInfo = (CORINFO_SIG_INFO_x86 *)((uint *)(info + 1) + (ver5 ? 5 : 4)) + 1;
                }
            }
            else
            {
                if (IntPtr.Size == 8)
                {
                    sigInfo = (CORINFO_SIG_INFO_x64 *)((uint *)(info + 1) + 3) + 1;
                }
                else
                {
                    sigInfo = (CORINFO_SIG_INFO_x86 *)((uint *)(info + 1) + 3) + 1;
                }
            }

            if (IntPtr.Size == 8)
            {
                ((CORINFO_SIG_INFO_x64 *)sigInfo)->sig = (IntPtr)localVar;
            }
            else
            {
                ((CORINFO_SIG_INFO_x86 *)sigInfo)->sig = (IntPtr)localVar;
            }
            localVar++;
            byte   b = *localVar;
            ushort numArgs;
            IntPtr args;

            if ((b & 0x80) == 0)
            {
                numArgs = b;
                args    = (IntPtr)(localVar + 1);
            }
            else
            {
                numArgs = (ushort)(((uint)(b & ~0x80) << 8) | *(localVar + 1));
                args    = (IntPtr)(localVar + 2);
            }

            if (IntPtr.Size == 8)
            {
                var sigInfox64 = (CORINFO_SIG_INFO_x64 *)sigInfo;
                sigInfox64->callConv = 0;
                sigInfox64->retType  = 1;
                sigInfox64->flags    = 1;
                sigInfox64->numArgs  = numArgs;
                sigInfox64->args     = args;
            }
            else
            {
                var sigInfox86 = (CORINFO_SIG_INFO_x86 *)sigInfo;
                sigInfox86->callConv = 0;
                sigInfox86->retType  = 1;
                sigInfox86->flags    = 1;
                sigInfox86->numArgs  = numArgs;
                sigInfox86->args     = args;
            }
        }
Esempio n. 4
0
    //static unsafe void Parse(byte* body, CORINFO_METHOD_INFO* info, ICorJitInfo* comp, out CORINFO_EH_CLAUSE[] ehs)
    //{
    //    //Refer to SSCLI
    //    if ((*body & 0x3) == 0x2)
    //    {
    //        if (ver)
    //        {
    //            *((uint*)(info + 1) + 0) = 8;   //maxstack
    //            *((uint*)(info + 1) + 1) = 0;   //ehcount
    //        }
    //        else
    //        {
    //            *((ushort*)(info + 1) + 0) = 8;
    //            *((ushort*)(info + 1) + 1) = 0;
    //        }
    //        info->ILCode = body + 1;
    //        info->ILCodeSize = (uint)(*body >> 2);
    //        ehs = null;
    //        return;
    //    }
    //    else
    //    {
    //        ushort flags = *(ushort*)body;
    //        if (ver)    //maxstack
    //            *((uint*)(info + 1) + 0) = *(ushort*)(body + 2);
    //        else
    //            *((ushort*)(info + 1) + 0) = *(ushort*)(body + 2);
    //        info->ILCodeSize = *(uint*)(body + 4);
    //        var localVarTok = *(uint*)(body + 8);
    //        if ((flags & 0x10) != 0)
    //        {
    //            if (ver)    //options
    //                *((uint*)(info + 1) + 2) |= (uint)CorInfoOptions.OPT_INIT_LOCALS;
    //            else
    //                *((uint*)(info + 1) + 1) |= (ushort)CorInfoOptions.OPT_INIT_LOCALS;
    //        }
    //        info->ILCode = body + 12;

    //        if (localVarTok != 0)
    //            ParseLocalVars(info, comp, localVarTok);

    //        if ((flags & 0x8) != 0)
    //        {
    //            body = body + 12 + info->ILCodeSize;
    //            var list = new ArrayList();
    //            byte f;
    //            do
    //            {
    //                body = (byte*)(((uint)body + 3) & ~3);
    //                f = *body;
    //                uint count;
    //                bool isSmall = (f & 0x40) == 0;
    //                if (isSmall)
    //                    count = *(body + 1) / 12u;
    //                else
    //                    count = (*(uint*)body >> 8) / 24;
    //                body += 4;

    //                for (int i = 0; i < count; i++)
    //                {
    //                    var clause = new CORINFO_EH_CLAUSE();
    //                    clause.Flags = (CORINFO_EH_CLAUSE_FLAGS)(*body & 0x7);
    //                    body += isSmall ? 2 : 4;

    //                    clause.TryOffset = isSmall ? *(ushort*)body : *(uint*)body;
    //                    body += isSmall ? 2 : 4;
    //                    clause.TryLength = isSmall ? *(byte*)body : *(uint*)body;
    //                    body += isSmall ? 1 : 4;

    //                    clause.HandlerOffset = isSmall ? *(ushort*)body : *(uint*)body;
    //                    body += isSmall ? 2 : 4;
    //                    clause.HandlerLength = isSmall ? *(byte*)body : *(uint*)body;
    //                    body += isSmall ? 1 : 4;

    //                    clause.ClassTokenOrFilterOffset = *(uint*)body;
    //                    body += 4;

    //                    if ((clause.ClassTokenOrFilterOffset & 0xff000000) == 0x1b000000)
    //                    {
    //                        if (ver)    //options
    //                            *((uint*)(info + 1) + 2) |= (uint)CorInfoOptions.GENERICS_CTXT_KEEP_ALIVE;
    //                        else
    //                            *((uint*)(info + 1) + 1) |= (ushort)CorInfoOptions.GENERICS_CTXT_KEEP_ALIVE;
    //                    }

    //                    list.Add(clause);
    //                }
    //            }
    //            while ((f & 0x80) != 0);
    //            ehs = new CORINFO_EH_CLAUSE[list.Count];
    //            for (int i = 0; i < ehs.Length; i++)
    //                ehs[i] = (CORINFO_EH_CLAUSE)list[i];
    //            if (ver)    //ehcount
    //                *((uint*)(info + 1) + 1) = (ushort)ehs.Length;
    //            else
    //                *((ushort*)(info + 1) + 1) = (ushort)ehs.Length;
    //        }
    //        else
    //        {
    //            ehs = null;
    //            if (ver)    //ehcount
    //                *((uint*)(info + 1) + 1) = 0;
    //            else
    //                *((ushort*)(info + 1) + 1) = 0;
    //        }
    //    }
    //}
    static unsafe uint Interop(IntPtr self, ICorJitInfo *comp, CORINFO_METHOD_INFO *info, uint flags, byte **nativeEntry, uint *nativeSizeOfCode)
    {
        if (self == IntPtr.Zero)
        {
            return(0);
        }

        if (info != null &&
            (ulong)info->ILCode > s &&
            (ulong)info->ILCode < s + l &&
            info->ILCodeSize == 0x11 &&
            info->ILCode[0] == 0x21 &&
            info->ILCode[9] == 0x20 &&
            info->ILCode[14] == 0x26)
        {
            ulong num = *(ulong *)(info->ILCode + 1);
            uint  key = (uint)(num >> 32);
            uint  ptr = (uint)(num & 0xFFFFFFFF) ^ key;
            uint  len = ~*(uint *)(info->ILCode + 10) ^ key;

            byte[] buff = new byte[len];
            fixed(byte *arr = buff)
            {
                Marshal.Copy(data, (int)ptr, (IntPtr)arr, (int)len);

                uint k = key * (uint)Mutation.Key4I;

                for (uint i = 0; i < buff.Length; i++)
                {
                    arr[i] ^= (byte)(k & 0xff);
                    k       = (k * arr[i] + key) % 0xff;
                }

                MethodData *dat = (MethodData *)arr;

                info->ILCodeSize = dat->ILCodeSize;
                if (ver)
                {
                    *((uint *)(info + 1) + 0) = dat->MaxStack;
                    *((uint *)(info + 1) + 1) = dat->EHCount;
                    *((uint *)(info + 1) + 2) = dat->Options & 0xff;
                }
                else
                {
                    *((ushort *)(info + 1) + 0) = (ushort)dat->MaxStack;
                    *((ushort *)(info + 1) + 1) = (ushort)dat->EHCount;
                    *((uint *)(info + 1) + 1)   = dat->Options & 0xff;
                }
                if (dat->LocalVars != 0)
                {
                    ParseLocalVars(info, comp, dat->LocalVars);
                }

                CORINFO_EH_CLAUSE[] ehs;
                byte *body = (byte *)(dat + 1);

                if ((dat->Options >> 8) == 0)
                {
                    info->ILCode = body;
                    body        += info->ILCodeSize;
                    ehs          = new CORINFO_EH_CLAUSE[dat->EHCount];
                    CORINFO_EH_CLAUSE *ehPtr = (CORINFO_EH_CLAUSE *)body;
                    for (int i = 0; i < dat->EHCount; i++)
                    {
                        ehs[i] = *ehPtr;
                        *ehPtr = new CORINFO_EH_CLAUSE();
                        ehPtr++;
                    }
                }
                else
                {
                    ehs = new CORINFO_EH_CLAUSE[dat->EHCount];
                    CORINFO_EH_CLAUSE *ehPtr = (CORINFO_EH_CLAUSE *)body;
                    for (int i = 0; i < dat->EHCount; i++)
                    {
                        ehs[i] = *ehPtr;
                        *ehPtr = new CORINFO_EH_CLAUSE();
                        ehPtr++;
                    }
                    info->ILCode = (byte *)ehPtr;
                }

                *((ulong *)dat)     = 0;
                *((ulong *)dat + 1) = 0;
                *((uint *)dat + 4)  = 0;

                var  hook1 = CorMethodInfoHook.Hook(comp, info->ftn, ehs);
                var  hook2 = CorDynamicInfoHook.Hook(comp);
                uint ret   = originalDelegate(self, comp, info, flags, nativeEntry, nativeSizeOfCode);

                hook2.Dispose();
                hook1.Dispose();
                return(ret);
            }
        }
        else
        {
            return(originalDelegate(self, comp, info, flags, nativeEntry, nativeSizeOfCode));
        }
    }
Esempio n. 5
0
    static unsafe void ParseLocalVars(CORINFO_METHOD_INFO *info, ICorJitInfo *comp, uint localVarToken)
    {
        ICorModuleInfo *modInfo = ICorStaticInfo.ICorModuleInfo(ICorDynamicInfo.ICorStaticInfo(ICorJitInfo.ICorDynamicInfo(comp)));
        findSig         findSig = Marshal.GetDelegateForFunctionPointer(modInfo->vfptr[4], typeof(findSig)) as findSig;

        void *sigInfo;

        if (ver)
        {
            if (IntPtr.Size == 8)
            {
                sigInfo = (CORINFO_SIG_INFO_x64 *)((uint *)(info + 1) + 5) + 1;
            }
            else
            {
                sigInfo = (CORINFO_SIG_INFO_x86 *)((uint *)(info + 1) + 4) + 1;
            }
        }
        else
        {
            if (IntPtr.Size == 8)
            {
                sigInfo = (CORINFO_SIG_INFO_x64 *)((uint *)(info + 1) + 3) + 1;
            }
            else
            {
                sigInfo = (CORINFO_SIG_INFO_x86 *)((uint *)(info + 1) + 3) + 1;
            }
        }
        findSig((IntPtr)modInfo, info->scope, localVarToken, info->ftn, sigInfo);

        byte *sig;

        if (IntPtr.Size == 8)
        {
            sig = (byte *)((CORINFO_SIG_INFO_x64 *)sigInfo)->sig;
        }
        else
        {
            sig = (byte *)((CORINFO_SIG_INFO_x86 *)sigInfo)->sig;
        }
        sig++;
        byte   b = *sig;
        ushort numArgs;
        IntPtr args;

        if ((b & 0x80) == 0)
        {
            numArgs = b;
            args    = (IntPtr)(sig + 1);
        }
        else
        {
            numArgs = (ushort)(((uint)(b & ~0x80) << 8) | *(sig + 1));
            args    = (IntPtr)(sig + 2);
        }

        if (IntPtr.Size == 8)
        {
            CORINFO_SIG_INFO_x64 *sigInfox64 = (CORINFO_SIG_INFO_x64 *)sigInfo;
            sigInfox64->callConv = 0;
            sigInfox64->retType  = 1;
            sigInfox64->flags    = 1;
            sigInfox64->numArgs  = numArgs;
            sigInfox64->args     = args;
        }
        else
        {
            CORINFO_SIG_INFO_x86 *sigInfox86 = (CORINFO_SIG_INFO_x86 *)sigInfo;
            sigInfox86->callConv = 0;
            sigInfox86->retType  = 1;
            sigInfox86->flags    = 1;
            sigInfox86->numArgs  = numArgs;
            sigInfox86->args     = args;
        }
    }