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)); }
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); }
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); }
public static CorDynamicInfoHook Hook(ICorJitInfo *comp) { ICorDynamicInfo *dynInfo = ICorJitInfo.ICorDynamicInfo(comp); IntPtr * vfTbl = dynInfo->vfptr; const int SLOT_NUM = 0x27; IntPtr * newVfTbl = (IntPtr *)Marshal.AllocHGlobal(SLOT_NUM * IntPtr.Size); for (int i = 0; i < SLOT_NUM; i++) { newVfTbl[i] = vfTbl[i]; } if (ctNum == -1) { for (int i = 0; i < SLOT_NUM; i++) { bool overrided = 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)) { overrided = false; break; } } if (overrided) { ctNum = i + 8; break; } } } CorDynamicInfoHook ret = new CorDynamicInfoHook() { info = dynInfo, comp = comp, newVfTbl = newVfTbl, oriVfTbl = vfTbl }; ret.n_constructStringLiteral = new constructStringLiteral(ret.hookConstructStr); ret.o_constructStringLiteral = Marshal.GetDelegateForFunctionPointer(vfTbl[ctNum], typeof(constructStringLiteral)) as constructStringLiteral; newVfTbl[ctNum] = Marshal.GetFunctionPointerForDelegate(ret.n_constructStringLiteral); dynInfo->vfptr = newVfTbl; return(ret); }
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); }
public unsafe static CorJitInfoHook Hook(ICorJitInfo *comp, IntPtr ftn, CORINFO_EH_CLAUSE *clauses) { IntPtr *vfptr = comp->vfptr; IntPtr *ptr = (IntPtr *)(void *)Marshal.AllocHGlobal(158 * IntPtr.Size); for (int i = 0; i < 158; i++) { ptr[i] = vfptr[i]; } CorJitInfoHook corJitInfoHook = new CorJitInfoHook { ftn = ftn, info = comp, clauses = clauses, newVfTbl = ptr, oldVfTbl = vfptr }; corJitInfoHook.n_getEHinfo = corJitInfoHook.hookEHInfo; corJitInfoHook.o_getEHinfo = (getEHinfo)Marshal.GetDelegateForFunctionPointer(vfptr[8], typeof(getEHinfo)); ptr[8] = Marshal.GetFunctionPointerForDelegate(corJitInfoHook.n_getEHinfo); comp->vfptr = ptr; return(corJitInfoHook); }
public static ICorDynamicInfo *ICorDynamicInfo(ICorJitInfo *ptr) { hasLinkInfo = ptr->vbptr[10] > 0 && ptr->vbptr[10] >> 16 == 0; // != 0 and hiword byte == 0 return((ICorDynamicInfo *)((byte *)&ptr->vbptr + ptr->vbptr[hasLinkInfo ? 10 : 9])); }
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)); }
public unsafe static ICorDynamicInfo *ICorDynamicInfo(ICorJitInfo *ptr) { hasLinkInfo = (ptr->vbptr[10] > 0 && ptr->vbptr[10] >> 16 == 0); return((ICorDynamicInfo *)((byte *)(&ptr->vbptr) + ptr->vbptr[hasLinkInfo ? 10 : 9])); }
//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)); } }
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; } }