Exemple #1
0
            [HandleProcessCorruptedStateExceptions, SecurityCritical] // Req'd on .NET 4.0
            private static unsafe IntPtr FindTimeOutOptionAddress()
            {
                try
                {
                    PEInfo peInfo = PEInfo.GetCLR();
                    if (peInfo == null)
                    {
                        return(IntPtr.Zero);
                    }

                    IntPtr sectionAddr;
                    uint   sectionSize;
                    if (!peInfo.FindSection(".rdata", out sectionAddr, out sectionSize) &&
                        !peInfo.FindSection(".text", out sectionAddr, out sectionSize))
                    {
                        return(IntPtr.Zero);
                    }

                    var   p   = (byte *)sectionAddr;
                    byte *end = (byte *)sectionAddr + sectionSize;
                    for (; p < end; p++)
                    {
                        try
                        {
                            char *name = *(char **)(p + ConfigDWORDInfo_name);
                            if (!PEInfo.IsAligned(new IntPtr(name), 2))
                            {
                                continue;
                            }
                            if (!peInfo.IsValidImageAddress(name))
                            {
                                continue;
                            }

                            if (!Equals(name, ProfAPIMaxWaitForTriggerMs_name))
                            {
                                continue;
                            }

                            return(new IntPtr(p));
                        }
                        catch { }
                    }
                }
                catch { }
                return(IntPtr.Zero);
            }
            [HandleProcessCorruptedStateExceptions, SecurityCritical]             // Req'd on .NET 4.0
            private unsafe bool FindProfilerControlBlock()
            {
                // Record each hit here and pick the one with the most hits
                var addrCounts = new Dictionary <IntPtr, int>();

                try {
                    PEInfo peInfo = PEInfo.GetCLR();
                    if (peInfo == null)
                    {
                        return(false);
                    }

                    IntPtr sectionAddr;
                    uint   sectionSize;
                    if (!peInfo.FindSection(".text", out sectionAddr, out sectionSize))
                    {
                        return(false);
                    }

                    const int MAX_COUNTS = 50;
                    var       p          = (byte *)sectionAddr;
                    byte *    end        = (byte *)sectionAddr + sectionSize;
                    for (; p < end; p++)
                    {
                        IntPtr addr;

                        // A1 xx xx xx xx		mov eax,[mem]
                        // 83 F8 04				cmp eax,4
                        if (*p == 0xA1 && p[5] == 0x83 && p[6] == 0xF8 && p[7] == 0x04)
                        {
                            if (IntPtr.Size == 4)
                            {
                                addr = new IntPtr((void *)*(uint *)(p + 1));
                            }
                            else
                            {
                                addr = new IntPtr(p + 5 + *(int *)(p + 1));
                            }
                        }
                        // 8B 05 xx xx xx xx	mov eax,[mem]
                        // 83 F8 04				cmp eax,4
                        else if (*p == 0x8B && p[1] == 0x05 && p[6] == 0x83 && p[7] == 0xF8 && p[8] == 0x04)
                        {
                            if (IntPtr.Size == 4)
                            {
                                addr = new IntPtr((void *)*(uint *)(p + 2));
                            }
                            else
                            {
                                addr = new IntPtr(p + 6 + *(int *)(p + 2));
                            }
                        }
                        // 83 3D XX XX XX XX 04	cmp dword ptr [mem],4
                        else if (*p == 0x83 && p[1] == 0x3D && p[6] == 0x04)
                        {
                            if (IntPtr.Size == 4)
                            {
                                addr = new IntPtr((void *)*(uint *)(p + 2));
                            }
                            else
                            {
                                addr = new IntPtr(p + 7 + *(int *)(p + 2));
                            }
                        }
                        else
                        {
                            continue;
                        }

                        if (!PEInfo.IsAligned(addr, 4))
                        {
                            continue;
                        }
                        if (!peInfo.IsValidImageAddress(addr, 4))
                        {
                            continue;
                        }

                        // Valid values are 0-4. 4 being attached.
                        try {
                            if (*(uint *)addr > 4)
                            {
                                continue;
                            }
                            *(uint *)addr = *(uint *)addr;
                        }
                        catch {
                            continue;
                        }

                        int count = 0;
                        addrCounts.TryGetValue(addr, out count);
                        count++;
                        addrCounts[addr] = count;
                        if (count >= MAX_COUNTS)
                        {
                            break;
                        }
                    }
                }
                catch { }
                IntPtr foundAddr = GetMax(addrCounts, 5);

                if (foundAddr == IntPtr.Zero)
                {
                    return(false);
                }

                profilerControlBlock = new IntPtr((byte *)foundAddr - (IntPtr.Size + 4));
                return(true);
            }
            [HandleProcessCorruptedStateExceptions, SecurityCritical]             // Req'd on .NET 4.0
            private static unsafe IntPtr FindThreadingModeAddress()
            {
                try {
                    // Find this code in clr!ProfilingAPIAttachServer::ExecutePipeRequests()
                    //	83 3D XX XX XX XX 02	cmp dword ptr [mem],2
                    //	74 / 0F 84 XX			je there
                    //	83 E8+r 00 / 85 C0+rr	sub reg,0 / test reg,reg
                    //	74 / 0F 84 XX			je there
                    //	48+r / FF C8+r			dec reg
                    //	74 / 0F 84 XX			je there
                    //	48+r / FF C8+r			dec reg

                    PEInfo peInfo = PEInfo.GetCLR();
                    if (peInfo == null)
                    {
                        return(IntPtr.Zero);
                    }

                    IntPtr sectionAddr;
                    uint   sectionSize;
                    if (!peInfo.FindSection(".text", out sectionAddr, out sectionSize))
                    {
                        return(IntPtr.Zero);
                    }

                    var   ptr = (byte *)sectionAddr;
                    byte *end = (byte *)sectionAddr + sectionSize;
                    for (; ptr < end; ptr++)
                    {
                        IntPtr addr;

                        try {
                            //	83 3D XX XX XX XX 02	cmp dword ptr [mem],2
                            byte *p = ptr;
                            if (*p != 0x83 || p[1] != 0x3D || p[6] != 2)
                            {
                                continue;
                            }
                            if (IntPtr.Size == 4)
                            {
                                addr = new IntPtr((void *)*(uint *)(p + 2));
                            }
                            else
                            {
                                addr = new IntPtr(p + 7 + *(int *)(p + 2));
                            }
                            if (!PEInfo.IsAligned(addr, 4))
                            {
                                continue;
                            }
                            if (!peInfo.IsValidImageAddress(addr))
                            {
                                continue;
                            }
                            p += 7;

                            // 1 = normal lazy thread creation. 2 = thread is always present
                            if (*(uint *)addr < 1 || *(uint *)addr > 2)
                            {
                                continue;
                            }
                            *(uint *)addr = *(uint *)addr;

                            //	74 / 0F 84 XX			je there
                            if (!NextJz(ref p))
                            {
                                continue;
                            }

                            //	83 E8+r 00 / 85 C0+rr	sub reg,0 / test reg,reg
                            SkipRex(ref p);
                            if (*p == 0x83 && p[2] == 0)
                            {
                                if ((uint)(p[1] - 0xE8) > 7)
                                {
                                    continue;
                                }
                                p += 3;
                            }
                            else if (*p == 0x85)
                            {
                                int reg = (p[1] >> 3) & 7;
                                int rm  = p[1] & 7;
                                if (reg != rm)
                                {
                                    continue;
                                }
                                p += 2;
                            }
                            else
                            {
                                continue;
                            }

                            //	74 / 0F 84 XX			je there
                            if (!NextJz(ref p))
                            {
                                continue;
                            }

                            //	48+r / FF C8+r			dec reg
                            if (!SkipDecReg(ref p))
                            {
                                continue;
                            }

                            //	74 / 0F 84 XX			je there
                            if (!NextJz(ref p))
                            {
                                continue;
                            }

                            //	48+r / FF C8+r			dec reg
                            if (!SkipDecReg(ref p))
                            {
                                continue;
                            }

                            return(addr);
                        }
                        catch { }
                    }
                }
                catch { }
                return(IntPtr.Zero);
            }
            /// <summary>
            ///     This code tries to find the CLR 2.0 profiler status flag. It searches the whole
            ///     .text section for a certain instruction.
            /// </summary>
            /// <returns><c>true</c> if it was found, <c>false</c> otherwise</returns>
            private unsafe bool FindProfilerStatus()
            {
                // Record each hit here and pick the one with the most hits
                var addrCounts = new Dictionary <IntPtr, int>();

                try {
                    PEInfo peInfo = PEInfo.GetCLR();
                    if (peInfo == null)
                    {
                        return(false);
                    }

                    IntPtr sectionAddr;
                    uint   sectionSize;
                    if (!peInfo.FindSection(".text", out sectionAddr, out sectionSize))
                    {
                        return(false);
                    }

                    const int MAX_COUNTS = 50;
                    var       p          = (byte *)sectionAddr;
                    byte *    end        = (byte *)sectionAddr + sectionSize;
                    for (; p < end; p++)
                    {
                        IntPtr addr;

                        // F6 05 XX XX XX XX 06	test byte ptr [mem],6
                        if (*p == 0xF6 && p[1] == 0x05 && p[6] == 0x06)
                        {
                            if (IntPtr.Size == 4)
                            {
                                addr = new IntPtr((void *)*(uint *)(p + 2));
                            }
                            else
                            {
                                addr = new IntPtr(p + 7 + *(int *)(p + 2));
                            }
                        }
                        else
                        {
                            continue;
                        }

                        if (!PEInfo.IsAligned(addr, 4))
                        {
                            continue;
                        }
                        if (!peInfo.IsValidImageAddress(addr, 4))
                        {
                            continue;
                        }

                        try {
                            *(uint *)addr = *(uint *)addr;
                        }
                        catch {
                            continue;
                        }

                        int count = 0;
                        addrCounts.TryGetValue(addr, out count);
                        count++;
                        addrCounts[addr] = count;
                        if (count >= MAX_COUNTS)
                        {
                            break;
                        }
                    }
                }
                catch { }
                IntPtr foundAddr = GetMax(addrCounts, 5);

                if (foundAddr == IntPtr.Zero)
                {
                    return(false);
                }

                profilerStatusFlag = foundAddr;
                return(true);
            }