Ejemplo n.º 1
0
            [SecurityCritical] // Req'd on .NET 4.0
            private static unsafe IntPtr FindTimeOutOptionAddress()
            {
                try
                {
                    var 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;
                    var end = (byte *)sectionAddr + sectionSize;
                    for (; p < end; p++)
                    {
                        try
                        {
                            var 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 {
                    var peInfo = PEInfo.GetCLR();
                    if (peInfo == null)
                    {
                        return(false);
                    }
                    if (!peInfo.FindSection(".text", out IntPtr sectionAddr, out uint sectionSize))
                    {
                        return(false);
                    }

                    const int MAX_COUNTS = 50;
                    byte *    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;
                        }

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

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

                this.profilerControlBlock = new IntPtr((byte *)foundAddr - (IntPtr.Size + 4));
                return(true);
            }
            [HandleProcessCorruptedStateExceptions, SecurityCritical]             // Req'd on .NET 4.0
            private unsafe IntPtr FindAttacherThreadProc()
            {
                try {
                    var peInfo = PEInfo.GetCLR();
                    if (peInfo == null)
                    {
                        return(IntPtr.Zero);
                    }
                    if (!peInfo.FindSection(".text", out IntPtr sectionAddr, out uint sectionSize))
                    {
                        return(IntPtr.Zero);
                    }

                    byte *p     = (byte *)sectionAddr;
                    byte *start = p;
                    byte *end   = (byte *)sectionAddr + sectionSize;

                    if (IntPtr.Size == 4)
                    {
                        for (; p < end; p++)
                        {
                            // Find this code:
                            //	50+r				push reg
                            //	50+r				push reg
                            //	50+r				push reg
                            //	68 XX XX XX XX		push offset ThreadProc
                            //	50+r				push reg
                            //	50+r				push reg
                            //	FF 15 XX XX XX XX	call dword ptr [mem] // CreateThread()

                            byte push = *p;
                            if (push < 0x50 || push > 0x57)
                            {
                                continue;
                            }
                            if (p[1] != push || p[2] != push || p[8] != push || p[9] != push)
                            {
                                continue;
                            }
                            if (p[3] != 0x68)
                            {
                                continue;
                            }
                            if (p[10] != 0xFF || p[11] != 0x15)
                            {
                                continue;
                            }

                            var threadProc = new IntPtr((void *)*(uint *)(p + 4));
                            if (!CheckThreadProc(start, end, threadProc))
                            {
                                continue;
                            }

                            return(threadProc);
                        }
                    }
                    else
                    {
                        for (; p < end; p++)
                        {
                            // Find this code:
                            //	45 33 C9				xor r9d,r9d
                            //	4C 8D 05 XX XX XX XX	lea r8,ThreadProc
                            //	33 D2					xor edx,edx
                            //	33 C9					xor ecx,ecx
                            //	FF 15 XX XX XX XX		call dword ptr [mem] // CreateThread()

                            if (*p != 0x45 && p[1] != 0x33 && p[2] != 0xC9)
                            {
                                continue;
                            }
                            if (p[3] != 0x4C && p[4] != 0x8D && p[5] != 0x05)
                            {
                                continue;
                            }
                            if (p[10] != 0x33 && p[11] != 0xD2)
                            {
                                continue;
                            }
                            if (p[12] != 0x33 && p[13] != 0xC9)
                            {
                                continue;
                            }
                            if (p[14] != 0xFF && p[15] != 0x15)
                            {
                                continue;
                            }

                            var threadProc = new IntPtr(p + 10 + *(int *)(p + 6));
                            if (!CheckThreadProc(start, end, threadProc))
                            {
                                continue;
                            }

                            return(threadProc);
                        }
                    }
                }
                catch { }

                return(IntPtr.Zero);
            }
            [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

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

                    byte *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 {
                    var peInfo = PEInfo.GetCLR();
                    if (peInfo == null)
                    {
                        return(false);
                    }
                    if (!peInfo.FindSection(".text", out IntPtr sectionAddr, out uint sectionSize))
                    {
                        return(false);
                    }

                    const int MAX_COUNTS = 50;
                    byte *    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;
                        }

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

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

                this.profilerStatusFlag = foundAddr;
                return(true);
            }
        [HandleProcessCorruptedStateExceptions, SecurityCritical]         // Req'd on .NET 4.0
        private static unsafe IntPtr FindDebuggerRCThreadAddress(Info info)
        {
            uint pid = GetCurrentProcessId();

            try {
                var peInfo = PEInfo.GetCLR();
                if (peInfo == null)
                {
                    return(IntPtr.Zero);
                }
                if (!peInfo.FindSection(".data", out IntPtr sectionAddr, out uint sectionSize))
                {
                    return(IntPtr.Zero);
                }

                // Try to find the Debugger instance location in the data section
                byte *p   = (byte *)sectionAddr;
                byte *end = (byte *)sectionAddr + sectionSize;
                for (; p + IntPtr.Size <= end; p += IntPtr.Size)
                {
                    IntPtr pDebugger = *(IntPtr *)p;
                    if (pDebugger == IntPtr.Zero)
                    {
                        continue;
                    }

                    try {
                        // All allocations are pointer-size aligned
                        if (!PEInfo.IsAlignedPointer(pDebugger))
                        {
                            continue;
                        }

                        // Make sure pid is correct
                        uint pid2 = *(uint *)((byte *)pDebugger + info.Debugger_pid);
                        if (pid != pid2)
                        {
                            continue;
                        }

                        IntPtr pDebuggerRCThread = *(IntPtr *)((byte *)pDebugger + info.Debugger_pDebuggerRCThread);

                        // All allocations are pointer-size aligned
                        if (!PEInfo.IsAlignedPointer(pDebuggerRCThread))
                        {
                            continue;
                        }

                        // Make sure it points back to Debugger
                        IntPtr pDebugger2 = *(IntPtr *)((byte *)pDebuggerRCThread + info.DebuggerRCThread_pDebugger);
                        if (pDebugger != pDebugger2)
                        {
                            continue;
                        }

                        return(pDebuggerRCThread);
                    }
                    catch { }
                }
            }
            catch { }

            return(IntPtr.Zero);
        }