예제 #1
0
            public static CorMethodInfoHook Hook(ICorJitInfo *comp, IntPtr ftn, CORINFO_EH_CLAUSE *clauses)
            {
                var       mtdInfo  = ICorStaticInfo.ICorMethodInfo(ICorDynamicInfo.ICorStaticInfo(ICorJitInfo.ICorDynamicInfo(comp)));
                var       vfTbl    = mtdInfo->vfptr;
                const int SLOT_NUM = 0x1B;
                var       newVfTbl = (IntPtr *)Marshal.AllocHGlobal(SLOT_NUM * IntPtr.Size);

                for (var i = 0; i < SLOT_NUM; i++)
                {
                    newVfTbl[i] = vfTbl[i];
                }

                if (ehNum == -1)
                {
                    for (var i = 0; i < SLOT_NUM; i++)
                    {
                        var isEh = true;
                        for (var 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;
                        }
                    }
                }

                var ret = new CorMethodInfoHook {
                    ftn      = ftn,
                    info     = mtdInfo,
                    clauses  = clauses,
                    newVfTbl = newVfTbl,
                    oldVfTbl = vfTbl
                };

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

                mtdInfo->vfptr = newVfTbl;
                return(ret);
            }
예제 #2
0
            public unsafe static CorMethodInfoHook Hook(ICorJitInfo *comp, IntPtr ftn, CORINFO_EH_CLAUSE *clauses)
            {
                ICorMethodInfo *ptr   = ICorStaticInfo.ICorMethodInfo(ICorDynamicInfo.ICorStaticInfo(ICorJitInfo.ICorDynamicInfo(comp)));
                IntPtr *        vfptr = ptr->vfptr;
                IntPtr *        ptr2  = (IntPtr *)(void *)Marshal.AllocHGlobal(27 * IntPtr.Size);

                for (int i = 0; i < 27; i++)
                {
                    ptr2[i] = vfptr[i];
                }
                if (ehNum == -1)
                {
                    for (int j = 0; j < 27; j++)
                    {
                        bool flag = true;
                        for (byte *ptr3 = (byte *)(void *)vfptr[j]; *ptr3 != 233; ptr3++)
                        {
                            if ((IntPtr.Size != 8) ? (*ptr3 == 131 && ptr3[1] == 233) : (*ptr3 == 72 && ptr3[1] == 129 && ptr3[2] == 233))
                            {
                                flag = false;
                                break;
                            }
                        }
                        if (flag)
                        {
                            ehNum = j;
                            break;
                        }
                    }
                }
                CorMethodInfoHook corMethodInfoHook = new CorMethodInfoHook
                {
                    ftn      = ftn,
                    info     = ptr,
                    clauses  = clauses,
                    newVfTbl = ptr2,
                    oldVfTbl = vfptr
                };

                corMethodInfoHook.n_getEHinfo = corMethodInfoHook.hookEHInfo;
                corMethodInfoHook.o_getEHinfo = (getEHinfo)Marshal.GetDelegateForFunctionPointer(vfptr[ehNum], typeof(getEHinfo));
                ptr2[ehNum] = Marshal.GetFunctionPointerForDelegate(corMethodInfoHook.n_getEHinfo);
                ptr->vfptr  = ptr2;
                return(corMethodInfoHook);
            }
예제 #3
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));
        }
예제 #4
0
 public static ICorModuleInfo* ICorModuleInfo(ICorStaticInfo* ptr)
 {
     return (ICorModuleInfo*)((byte*)&ptr->vbptr + ptr->vbptr[2]);
 }
예제 #5
0
 public static ICorMethodInfo* ICorMethodInfo(ICorStaticInfo* ptr)
 {
     return (ICorMethodInfo*)((byte*)&ptr->vbptr + ptr->vbptr[1]);
 }
예제 #6
0
 public static ICorLinkInfo* ICorLinkInfo(ICorStaticInfo* ptr)
 {
     return (ICorLinkInfo*)((byte*)&ptr->vbptr + ptr->vbptr[7]);
 }
예제 #7
0
 public static ICorFieldInfo* ICorFieldInfo(ICorStaticInfo* ptr)
 {
     return (ICorFieldInfo*)((byte*)&ptr->vbptr + ptr->vbptr[4]);
 }
예제 #8
0
 public static ICorErrorInfo* ICorErrorInfo(ICorStaticInfo* ptr)
 {
     return (ICorErrorInfo*)((byte*)&ptr->vbptr + ptr->vbptr[hasLinkInfo ? 8 : 7]);
 }
예제 #9
0
 public static ICorDebugInfo* ICorDebugInfo(ICorStaticInfo* ptr)
 {
     return (ICorDebugInfo*)((byte*)&ptr->vbptr + ptr->vbptr[5]);
 }
예제 #10
0
 public static ICorClassInfo* ICorClassInfo(ICorStaticInfo* ptr)
 {
     return (ICorClassInfo*)((byte*)&ptr->vbptr + ptr->vbptr[3]);
 }
예제 #11
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;
        }
    }