[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 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); }