コード例 #1
0
    /// <summary>
    /// Reads the NT_TIB area of a process, into an incomplete 32 bit representation of the original struct.
    /// </summary>
    /// <param name="process">The process to read.</param>
    /// <returns>Returns an incomplete 32 bit representation of NT_TIB.</returns>
    public static PInvokeStuff.NT_TIB GetTIB(Process process)
    {
        // Read TBI - prerequise for TIB
        PInvokeStuff.THREAD_BASIC_INFORMATION tbi = GetTBI(process);

        // Read NT_TIB equivalent memory area of the process directly into our NT_TIB struct
        PInvokeStuff.NT_TIB tib = ReadToType <PInvokeStuff.NT_TIB>(process.Handle, tbi.TebBaseAddress);

        return(tib);
    }
コード例 #2
0
    /// <summary>
    /// Returns the address of the ThreadStack0 special symbol.
    /// </summary>
    /// <param name="process">The target process</param>
    /// <returns>The memory address of ThreadStack0</returns>
    public static uint GetThreadStack0(Process process)
    {
        if (!Is32BitProcess(process.Handle))
        {
            throw new ArgumentException("Provided process is not 32 bit.");
        }

        const uint BytesToSample = 4096;                              // Arbitrary (?). 4096 should be enough for both x86 and x64; should be divisible by 4 (x86)

        PInvokeStuff.MODULEINFO mi  = GetKernel32ModuleInfo(process); // MODULEINFO delivers the Kernel32 module's load address and size (note that load address (lpBaseOfDll) is the same as the module handle)
        PInvokeStuff.NT_TIB     tib = GetTIB(process);                // NT_TIB delivers the stack base address of the process' main thread

        // Read sample byte array from the base of the main thread stack
        byte[] StackBaseSample = ReadToByteArray(process.Handle, (tib.StackBase - BytesToSample), BytesToSample);

        int i = 0; // Keep scope bigger than loop

        // ThreadStack0 is the first pointer in the main thread's stack that points inside the Kernel32 module.
        // To find it, we iterate through each 32 bit (4 byte) value in the stack sample, and check if it is in the target range.
        for (i = (StackBaseSample.Length / 4) - 1; i >= 0; --i)
        {
            UInt32 valueAtPosition = BitConverter.ToUInt32(StackBaseSample, i * 4);
            if (valueAtPosition >= (uint)mi.lpBaseOfDll &&
                valueAtPosition <= (uint)mi.lpBaseOfDll + mi.SizeOfImage)
            {
                break;
            }
        }

        if (i == 0) // If i reached zero, then iteration finished without finding a match
        {
            throw new Exceptions.LocalException(nameof(GetThreadStack0), "ThreadStack0 can't be found in the sampled " + BytesToSample + " bytes");
        }

        // Finally, calculate and return the actual ThreadStack0 address from index i
        return((uint)(tib.StackBase - BytesToSample + i * 4));
    }