Exemplo n.º 1
0
        private ObjectNode.ObjectData EncodeEHInfo()
        {
            var builder = new ObjectDataBuilder();
            builder.RequireInitialAlignment(1);

            int totalClauses = _ehClauses.Length;

            // Count the number of special markers that will be needed
            for (int i = 1; i < _ehClauses.Length; i++)
            {
                ref CORINFO_EH_CLAUSE clause = ref _ehClauses[i];
                ref CORINFO_EH_CLAUSE previousClause = ref _ehClauses[i - 1];
Exemplo n.º 2
0
        protected CORINFO_EH_CLAUSE[] GetAllExceptionHandlers(void *pICorJitInfo, CorMethodInfo methodInfo)
        {
            CORINFO_EH_CLAUSE[] clauses;

            if (methodInfo.ExceptionHandlerCount == 0)
            {
                return(null);
            }
            clauses = new CORINFO_EH_CLAUSE[methodInfo.ExceptionHandlerCount];
            for (uint i = 0; i < clauses.Length; i++)
            {
                GetEHInfo(pICorJitInfo, methodInfo.MethodHandle, i, out clauses[i]);
            }
            return(clauses);
        }
Exemplo n.º 3
0
        private ObjectNode.ObjectData EncodeEHInfo()
        {
            int totalClauses = _ehClauses.Length;

            byte[] ehInfoData = new byte[(int)EHInfoFields.Length * sizeof(uint) * totalClauses];

            for (int i = 0; i < totalClauses; i++)
            {
                ref CORINFO_EH_CLAUSE clause = ref _ehClauses[i];
                int clauseOffset             = (int)EHInfoFields.Length * sizeof(uint) * i;
                Array.Copy(BitConverter.GetBytes((uint)clause.Flags), 0, ehInfoData, clauseOffset + (int)EHInfoFields.Flags * sizeof(uint), sizeof(uint));
                Array.Copy(BitConverter.GetBytes((uint)clause.TryOffset), 0, ehInfoData, clauseOffset + (int)EHInfoFields.TryOffset * sizeof(uint), sizeof(uint));
                // JIT in fact returns the end offset in the length field
                Array.Copy(BitConverter.GetBytes((uint)(clause.TryLength)), 0, ehInfoData, clauseOffset + (int)EHInfoFields.TryEnd * sizeof(uint), sizeof(uint));
                Array.Copy(BitConverter.GetBytes((uint)clause.HandlerOffset), 0, ehInfoData, clauseOffset + (int)EHInfoFields.HandlerOffset * sizeof(uint), sizeof(uint));
                Array.Copy(BitConverter.GetBytes((uint)(clause.HandlerLength)), 0, ehInfoData, clauseOffset + (int)EHInfoFields.HandlerEnd * sizeof(uint), sizeof(uint));
                Array.Copy(BitConverter.GetBytes((uint)clause.ClassTokenOrOffset), 0, ehInfoData, clauseOffset + (int)EHInfoFields.ClassTokenOrOffset * sizeof(uint), sizeof(uint));
            }
Exemplo n.º 4
0
 void hookEHInfo(IntPtr self, IntPtr ftn, uint EHnumber, CORINFO_EH_CLAUSE* clause)
 {
     if (ftn == this.ftn)
     {
         *clause = clauses[EHnumber];
     }
     else
     {
         o_getEHinfo(self, ftn, EHnumber, clause);
     }
 }
Exemplo n.º 5
0
        public static CorMethodInfoHook Hook(ICorJitInfo* comp, IntPtr ftn, CORINFO_EH_CLAUSE[] clauses)
        {
            ICorMethodInfo* mtdInfo = ICorStaticInfo.ICorMethodInfo(ICorDynamicInfo.ICorStaticInfo(ICorJitInfo.ICorDynamicInfo(comp)));
            IntPtr* vfTbl = mtdInfo->vfptr;
            const int SLOT_NUM = 0x1B;
            IntPtr* newVfTbl = (IntPtr*)Marshal.AllocHGlobal(SLOT_NUM * IntPtr.Size);
            for (int i = 0; i < SLOT_NUM; i++)
                newVfTbl[i] = vfTbl[i];
            if (ehNum == -1)
                for (int i = 0; i < SLOT_NUM; i++)
                {
                    bool isEh = true;
                    for (byte* func = (byte*)vfTbl[i]; *func != 0xe9; func++)
                        if (IntPtr.Size == 8 ?
                            (*func == 0x48 && *(func + 1) == 0x81 && *(func + 2) == 0xe9) :
                             (*func == 0x83 && *(func + 1) == 0xe9))
                        {
                            isEh = false;
                            break;
                        }
                    if (isEh)
                    {
                        ehNum = i;
                        break;
                    }
                }

            CorMethodInfoHook ret = new CorMethodInfoHook()
            {
                ftn = ftn,
                info = mtdInfo,
                comp = comp,
                clauses = clauses,
                newVfTbl = newVfTbl,
                oriVfTbl = vfTbl
            };

            ret.n_getEHinfo = new getEHinfo(ret.hookEHInfo);
            ret.o_getEHinfo = Marshal.GetDelegateForFunctionPointer(vfTbl[ehNum], typeof(getEHinfo)) as getEHinfo;
            newVfTbl[ehNum] = Marshal.GetFunctionPointerForDelegate(ret.n_getEHinfo);

            mtdInfo->vfptr = newVfTbl;
            return ret;
        }
Exemplo n.º 6
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);
    }
Exemplo n.º 7
0
			public static CorJitInfoHook Hook(ICorJitInfo* comp, IntPtr ftn, CORINFO_EH_CLAUSE* clauses) {
				const int slotNum = 8;

				IntPtr* vfTbl = comp->vfptr;
				const int SLOT_NUM = 0x9E;
				var newVfTbl = (IntPtr*)Marshal.AllocHGlobal(SLOT_NUM * IntPtr.Size);
				for (int i = 0; i < SLOT_NUM; i++)
					newVfTbl[i] = vfTbl[i];

				var ret = new CorJitInfoHook {
					ftn = ftn,
					info = comp,
					clauses = clauses,
					newVfTbl = newVfTbl,
					oldVfTbl = vfTbl
				};

				ret.n_getEHinfo = ret.hookEHInfo;
				ret.o_getEHinfo = (getEHinfo)Marshal.GetDelegateForFunctionPointer(vfTbl[slotNum], typeof(getEHinfo));
				newVfTbl[slotNum] = Marshal.GetFunctionPointerForDelegate(ret.n_getEHinfo);

				comp->vfptr = newVfTbl;
				return ret;
			}
Exemplo n.º 8
0
 protected virtual void GetEHInfo(void *pICorJitInfo, void *methodHandle, uint ehIndex, out CORINFO_EH_CLAUSE clause)
 {
     _getEHInfo(VTableHelpers.AdjustThis_GetEHInfo(pICorJitInfo), methodHandle, ehIndex, out clause);
 }
Exemplo n.º 9
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));
        }
    }