Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public static class ThreadUtil
- {
- /// <summary>
- /// Yields back a series of int32 values pulled from [basePtr - (addressesToReadBefore * 4)] to [basePtr + (addressesToReadAfter * 4)]
- /// </summary>
- /// <param name="hProc"></param>
- /// <param name="basePtr"></param>
- /// <param name="addressesToReadBefore"></param>
- /// <param name="addressesToReadAfter"></param>
- /// <returns></returns>
- public static IEnumerable<Tuple<long, int>> DumpStack32(IntPtr hProc, UIntPtr basePtr, int addressesToReadBefore, int addressesToReadAfter)
- {
- var bp = basePtr.ToUInt32();
- var bufferSizeForAddresses = Marshal.SizeOf(typeof(int)) * addressesToReadBefore;
- var startAddress = bp - bufferSizeForAddresses;
- var bufferSize = bufferSizeForAddresses + (addressesToReadAfter * Marshal.SizeOf(typeof(int)));
- var buffer = new byte[bufferSize];
- int bytesRead;
- ReadProcessMemory(hProc, new IntPtr(startAddress), buffer, bufferSize, out bytesRead);
- using (var br = new BinaryReader(new MemoryStream(buffer)))
- {
- for (int i = 0; i < (addressesToReadBefore + addressesToReadAfter); i++)
- {
- var offset = (i * 4);
- var addr = br.ReadInt32();
- yield return Tuple.Create(startAddress + offset, addr);
- }
- }
- }
- public static string WalkFrom(IntPtr hProc, string name, UIntPtr address, int goBack, int goFwd)
- {
- var sb = new StringBuilder();
- var addressRaw = address.ToUInt32();
- sb.AppendFormat("\t{0}:0x{1}", name, addressRaw.ToString("X")).AppendLine();
- var retAddrs = DumpStack32(hProc, address, goBack, goFwd);
- foreach (var retAddr in retAddrs)
- {
- var memLoc = retAddr.Item1;
- var offset = memLoc - addressRaw;
- var addr = retAddr.Item2;
- sb.AppendFormat("\t\tAddr 0x{0}[{1}{2}0x{3}]:0x{4}", memLoc.ToString("X"), name, offset < 0 ? "-" : "+", Math.Abs(offset).ToString("X"), addr.ToString("X")).AppendLine();
- }
- return sb.ToString();
- }
- public static string DumpThreadInfo(IntPtr hProc, IntPtr hThread, int framesBefore, int framesAfter)
- {
- var sb = new StringBuilder();
- var ctx = new CONTEXT { ContextFlags = (uint)CONTEXT_FLAGS.CONTEXT_ALL };
- GetThreadContext(hThread, ref ctx);
- sb.AppendFormat("hProc:0x{0} hThread:0x{1}", hProc.ToInt32().ToString("X"), hThread.ToInt32().ToString("X")).AppendLine();
- sb.AppendFormat("IP:0x{0}", ctx.Eip).AppendLine();
- sb.AppendFormat(WalkFrom(hProc, "EBP", new UIntPtr(ctx.Ebp), framesBefore, framesAfter)).AppendLine();
- sb.AppendFormat(WalkFrom(hProc, "ESP", new UIntPtr(ctx.Esp), framesBefore, framesAfter)).AppendLine();
- return sb.ToString();
- }
- #region P/Invoke Gobbledegook!
- #region enums
- [Flags]
- public enum ThreadAccess : int
- {
- TERMINATE = (0x0001),
- SUSPEND_RESUME = (0x0002),
- GET_CONTEXT = (0x0008),
- SET_CONTEXT = (0x0010),
- SET_INFORMATION = (0x0020),
- QUERY_INFORMATION = (0x0040),
- SET_THREAD_TOKEN = (0x0080),
- IMPERSONATE = (0x0100),
- DIRECT_IMPERSONATION = (0x0200)
- }
- public enum CONTEXT_FLAGS : uint
- {
- CONTEXT_i386 = 0x10000,
- CONTEXT_i486 = 0x10000, // same as i386
- CONTEXT_CONTROL = CONTEXT_i386 | 0x01, // SS:SP, CS:IP, FLAGS, BP
- CONTEXT_INTEGER = CONTEXT_i386 | 0x02, // AX, BX, CX, DX, SI, DI
- CONTEXT_SEGMENTS = CONTEXT_i386 | 0x04, // DS, ES, FS, GS
- CONTEXT_FLOATING_POINT = CONTEXT_i386 | 0x08, // 387 state
- CONTEXT_DEBUG_REGISTERS = CONTEXT_i386 | 0x10, // DB 0-3,6,7
- CONTEXT_EXTENDED_REGISTERS = CONTEXT_i386 | 0x20, // cpu specific extensions
- CONTEXT_FULL = CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS,
- CONTEXT_ALL = CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS | CONTEXT_EXTENDED_REGISTERS
- }
- public enum ProcessAccessFlags : int
- {
- All = 0x001F0FFF,
- Terminate = 0x00000001,
- CreateThread = 0x00000002,
- VMOperation = 0x00000008,
- VMRead = 0x00000010,
- VMWrite = 0x00000020,
- DupHandle = 0x00000040,
- SetInformation = 0x00000200,
- QueryInformation = 0x00000400,
- Synchronize = 0x00100000
- }
- #endregion
- #region structs
- [StructLayout(LayoutKind.Sequential)]
- public struct FLOATING_SAVE_AREA
- {
- public uint ControlWord;
- public uint StatusWord;
- public uint TagWord;
- public uint ErrorOffset;
- public uint ErrorSelector;
- public uint DataOffset;
- public uint DataSelector;
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 80)]
- public byte[] RegisterArea;
- public uint Cr0NpxState;
- }
- [StructLayout(LayoutKind.Sequential)]
- public struct CONTEXT
- {
- public uint ContextFlags; //set this to an appropriate value
- // Retrieved by CONTEXT_DEBUG_REGISTERS
- public uint Dr0;
- public uint Dr1;
- public uint Dr2;
- public uint Dr3;
- public uint Dr6;
- public uint Dr7;
- // Retrieved by CONTEXT_FLOATING_POINT
- public FLOATING_SAVE_AREA FloatSave;
- // Retrieved by CONTEXT_SEGMENTS
- public uint SegGs;
- public uint SegFs;
- public uint SegEs;
- public uint SegDs;
- // Retrieved by CONTEXT_INTEGER
- public uint Edi;
- public uint Esi;
- public uint Ebx;
- public uint Edx;
- public uint Ecx;
- public uint Eax;
- // Retrieved by CONTEXT_CONTROL
- public uint Ebp;
- public uint Eip;
- public uint SegCs;
- public uint EFlags;
- public uint Esp;
- public uint SegSs;
- // Retrieved by CONTEXT_EXTENDED_REGISTERS
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
- public byte[] ExtendedRegisters;
- }
- public struct BYTES
- {
- public byte BaseMid;
- public byte Flags1;
- public byte Flags2;
- public byte BaseHi;
- }
- public struct BITS
- {
- int Value;
- /// <summary>
- /// Max set value is 255 (11111111b)
- /// </summary>
- public int BaseMid
- {
- get { return (Value & 0xFF); }
- set { Value = (Value & unchecked((int)0xFFFFFF00)) | (value & 0xFF); }
- }
- /// <summary>
- /// Max set value is 31 (11111b)
- /// </summary>
- public int Type
- {
- get { return (Value & 0x1F00) >> 8; }
- set { Value = (Value & unchecked((int)0xFFFFE0FF)) | ((value & 0x1F) << 8); }
- }
- /// <summary>
- /// Max set value is 3 (11b)
- /// </summary>
- public int Dpl
- {
- get { return (Value & 0x6000) >> 13; }
- set { Value = (Value & unchecked((int)0xFFFF9FFF)) | ((value & 0x3) << 13); }
- }
- /// <summary>
- /// Max set value is 1 (1b)
- /// </summary>
- public int Pres
- {
- get { return (Value & 0x4000) >> 15; }
- set { Value = (Value & unchecked((int)0xFFFFBFFF)) | ((value & 0x1) << 15); }
- }
- /// <summary>
- /// Max set value is 15 (1111b)
- /// </summary>
- public int LimitHi
- {
- get { return (Value & 0xF0000) >> 16; }
- set { Value = (Value & unchecked((int)0xFFF0FFFF)) | ((value & 0xF) << 16); }
- }
- /// <summary>
- /// Max set value is 1 (1b)
- /// </summary>
- public int Sys
- {
- get { return (Value & 0x100000) >> 20; }
- set { Value = (Value & unchecked((int)0xFFEFFFFF)) | ((value & 0x1) << 20); }
- }
- /// <summary>
- /// Max set value is 1 (1b)
- /// </summary>
- public int Reserved_0
- {
- get { return (Value & 0x200000) >> 21; }
- set { Value = (Value & unchecked((int)0xFFDFFFFF)) | ((value & 0x1) << 21); }
- }
- /// <summary>
- /// Max set value is 1 (1b)
- /// </summary>
- public int Default_Big
- {
- get { return (Value & 0x400000) >> 22; }
- set { Value = (Value & unchecked((int)0xFFBFFFFF)) | ((value & 0x1) << 22); }
- }
- /// <summary>
- /// Max set value is 1 (1b)
- /// </summary>
- public int Granularity
- {
- get { return (Value & 0x800000) >> 23; }
- set { Value = (Value & unchecked((int)0xFF7FFFFF)) | ((value & 0x1) << 23); }
- }
- /// <summary>
- /// Max set value is 255 (11111111b)
- /// </summary>
- public int BaseHi
- {
- get { return (Value & unchecked((int)0xFF000000)) >> 24; }
- set { Value = (Value & unchecked((int)0xFFFFFF)) | ((value & 0xFF) << 24); }
- }
- }
- [StructLayout(LayoutKind.Explicit)]
- public struct HIGHWORD
- {
- [FieldOffset(0)]
- public BYTES Bytes;
- [FieldOffset(0)]
- public BITS Bits;
- }
- public struct LDT_ENTRY
- {
- public ushort LimitLow;
- public ushort BaseLow;
- public HIGHWORD HighWord;
- }
- [StructLayout(LayoutKind.Sequential)]
- public struct MEMORY_BASIC_INFORMATION
- {
- public IntPtr BaseAddress;
- public IntPtr AllocationBase;
- public uint AllocationProtect;
- public IntPtr RegionSize;
- public uint State;
- public uint Protect;
- public uint Type;
- }
- public enum AllocationProtect : uint
- {
- PAGE_EXECUTE = 0x00000010,
- PAGE_EXECUTE_READ = 0x00000020,
- PAGE_EXECUTE_READWRITE = 0x00000040,
- PAGE_EXECUTE_WRITECOPY = 0x00000080,
- PAGE_NOACCESS = 0x00000001,
- PAGE_READONLY = 0x00000002,
- PAGE_READWRITE = 0x00000004,
- PAGE_WRITECOPY = 0x00000008,
- PAGE_GUARD = 0x00000100,
- PAGE_NOCACHE = 0x00000200,
- PAGE_WRITECOMBINE = 0x00000400
- }
- #endregion
- #region general calls
- [DllImport("kernel32.dll", SetLastError = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool CloseHandle(IntPtr hObject);
- #endregion
- #region window calls
- [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
- public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
- [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
- public static extern int GetWindowTextLength(IntPtr hWnd);
- #endregion
- #region thread calls
- [DllImport("kernel32.dll")]
- public static extern bool TlsSetValue(uint dwTlsIndex, IntPtr lpTlsValue);
- [DllImport("kernel32.dll")]
- public static extern IntPtr TlsGetValue(uint dwTlsIndex);
- [DllImport("kernel32.dll")]
- public static extern uint SuspendThread(IntPtr hThread);
- [DllImport("kernel32.dll")]
- public static extern uint ResumeThread(IntPtr hThread);
- [DllImport("kernel32.dll", SetLastError = true)]
- public static extern bool GetThreadSelectorEntry(IntPtr hThread, uint dwSelector, out LDT_ENTRY lpSelectorEntry);
- [DllImport("kernel32.dll")]
- public static extern bool GetThreadContext(IntPtr hThread, ref CONTEXT lpContext);
- [DllImport("kernel32.dll")]
- public static extern IntPtr OpenThread(ThreadAccess dwDesiredAccess, bool bInheritHandle, uint dwThreadId);
- [DllImport("kernel32.dll")]
- public static extern void ExitThread(uint dwExitCode);
- [DllImport("user32.dll")]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool IsGUIThread([MarshalAs(UnmanagedType.Bool)] bool bConvert);
- [DllImport("kernel32.dll")]
- public static extern uint GetCurrentThreadId();
- [DllImport("user32.dll")]
- public static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach);
- [DllImport("user32.dll")]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool EnumThreadWindows(uint dwThreadId, EnumThreadDelegate lpfn, IntPtr lParam);
- public delegate bool EnumThreadDelegate(IntPtr hWnd, IntPtr lParam);
- public static void EnumThreadWindows(uint processId, Func<IntPtr, IntPtr, bool> callback)
- {
- EnumThreadWindows(processId, new EnumThreadDelegate(callback), IntPtr.Zero);
- }
- #endregion
- #region process and memory calls
- [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
- public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
- [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
- public static extern bool VirtualFreeEx(IntPtr hProcess, IntPtr lpAddress, UIntPtr dwSize, uint dwFreeType);
- [DllImport("kernel32.dll")]
- public static extern int VirtualQueryEx(
- IntPtr hProcess,
- IntPtr lpAddress,
- out MEMORY_BASIC_INFORMATION lpBuffer,
- uint dwLength);
- [DllImport("kernel32.dll", SetLastError = true)]
- public static extern bool ReadProcessMemory(
- IntPtr hProcess,
- IntPtr lpBaseAddress,
- [Out] byte[] lpBuffer,
- int dwSize,
- out int lpNumberOfBytesRead);
- [DllImport("kernel32.dll", SetLastError = true)]
- public static extern bool WriteProcessMemory(
- IntPtr hProcess,
- IntPtr lpBaseAddress,
- byte[] lpBuffer,
- uint nSize,
- out UIntPtr lpNumberOfBytesWritten);
- [DllImport("kernel32.dll")]
- public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
- #endregion
- #endregion
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement