LogifyAlert client = LogifyAlert.Instance; client.ApiKey = "my-api-key"; client.StartExceptionsHandling();
[DllImport("kernel32.dll")] static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId); [DllImport("kernel32.dll", CharSet = CharSet.Auto)] static extern IntPtr GetModuleHandle(string lpModuleName); [DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)] static extern IntPtr GetProcAddress(IntPtr hModule, string procName); [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)] static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, AllocationType flAllocationType, uint flProtect); [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)] static extern bool VirtualFreeEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, AllocationType dwFreeType); [DllImport("kernel32.dll", SetLastError = true)] static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, out UIntPtr lpNumberOfBytesWritten); [DllImport("kernel32.dll")] static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId); [DllImport("kernel32.dll", SetLastError = true)] static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds); [DllImport("kernel32.dll", SetLastError = true)] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] [SuppressUnmanagedCodeSecurity] [return: MarshalAs(UnmanagedType.Bool)] static extern bool CloseHandle(IntPtr hObject); [Flags] public enum AllocationType { ReadWrite = 0x0004, Commit = 0x1000, Reserve = 0x2000, Decommit = 0x4000, Release = 0x8000, Reset = 0x80000, Physical = 0x400000, TopDown = 0x100000, WriteWatch = 0x200000, LargePages = 0x20000000 } public const uint PAGE_READWRITE = 4; public const UInt32 INFINITE = 0xFFFFFFFF;
int access = PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ; IntPtr procHandle = OpenProcess(access, false, dwProcessId); InjectDll(procHandle, BootstrapDllPath);
static Process AttachToTargetProcess(RunnerParameters parameters) { if (!String.IsNullOrEmpty(parameters.TargetProcessCommandLine)) return StartTargetProcess(parameters.TargetProcessCommandLine, parameters.TargetProcessArgs); else if (parameters.Pid != 0) { Process.EnterDebugMode(); return Process.GetProcessById(parameters.Pid); } else return null; }
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
static bool InjectDll(IntPtr procHandle, string dllName) { const string libName = "kernel32.dll"; const string procName = "LoadLibraryW"; IntPtr loadLibraryAddr = GetProcAddress(GetModuleHandle(libName), procName); if (loadLibraryAddr == IntPtr.Zero) { return false; } return MakeRemoteCall(procHandle, loadLibraryAddr, dllName); } static bool MakeRemoteCall(IntPtr procHandle, IntPtr methodAddr, string argument) { uint textSize = (uint)Encoding.Unicode.GetByteCount(argument); uint allocSize = textSize + 2; IntPtr allocMemAddress; AllocationType allocType = AllocationType.Commit | AllocationType.Reserve; allocMemAddress = VirtualAllocEx(procHandle, IntPtr.Zero, allocSize, allocType, PAGE_READWRITE); if (allocMemAddress == IntPtr.Zero) return false; UIntPtr bytesWritten; WriteProcessMemory(procHandle, allocMemAddress, Encoding.Unicode.GetBytes(argument), textSize, out bytesWritten); bool isOk = false; IntPtr threadHandle; threadHandle = CreateRemoteThread(procHandle, IntPtr.Zero, 0, methodAddr, allocMemAddress, 0, IntPtr.Zero); if (threadHandle != IntPtr.Zero) { WaitForSingleObject(threadHandle, Win32.INFINITE); isOk = true; } VirtualFreeEx(procHandle, allocMemAddress, allocSize, AllocationType.Release); if (threadHandle != IntPtr.Zero) Win32.CloseHandle(threadHandle); return isOk; }
HRESULT InjectDotNetAssembly( /* [in] */ LPCWSTR pwzAssemblyPath, /* [in] */ LPCWSTR pwzTypeName, /* [in] */ LPCWSTR pwzMethodName, /* [in] */ LPCWSTR pwzArgument ) { HRESULT result; ICLRMetaHost *metaHost = NULL; ICLRRuntimeInfo *runtimeInfo = NULL; ICLRRuntimeHost *runtimeHost = NULL; // Load .NET result = CLRCreateInstance(CLSID_CLRMetaHost, IID_PPV_ARGS(&metaHost)); result = metaHost->GetRuntime(L"v4.0.30319", IID_PPV_ARGS(&runtimeInfo)); result = runtimeInfo->GetInterface(CLSID_CLRRuntimeHost, IID_PPV_ARGS(&runtimeHost)); result = runtimeHost->Start(); // Execute managed assembly DWORD returnValue; result = runtimeHost->ExecuteInDefaultAppDomain( pwzAssemblyPath, pwzTypeName, pwzMethodName, pwzArgument, &returnValue); if (metaHost != NULL) metaHost->Release(); if (runtimeInfo != NULL) runtimeInfo->Release(); if (runtimeHost != NULL) runtimeHost->Release(); return result; }
static long GetMethodOffset(string dllPath, string methodName) { IntPtr hLib = Win32.LoadLibrary(dllPath); if (hLib == IntPtr.Zero) return 0; IntPtr call = Win32.GetProcAddress(hLib, methodName); if (call == IntPtr.Zero) return 0; long result = call.ToInt64() - hLib.ToInt64(); Win32.FreeLibrary(hLib); return result; }
static ulong GetRemoteModuleHandle(Process process, string moduleName) { int count = process.Modules.Count; for (int i = 0; i < count; i++) { ProcessModule module = process.Modules[i]; if (module.ModuleName == moduleName) return (ulong)module.BaseAddress; } return 0; }
long offset = GetMethodOffset(BootstrapDllPath, "InjectManagedAssembly"); InjectDll(procHandle, BootstrapDllPath); ulong baseAddr = GetRemoteModuleHandle(process, Path.GetFileName(BootstrapDllPath)); IntPtr remoteAddress = new IntPtr((long)(baseAddr + (ulong)offset));
HRESULT InjectManagedAssemblyCore(_In_ LPCWSTR lpCommand) { LPWSTR *szArgList; int argCount; szArgList = CommandLineToArgvW(lpCommand, &argCount); if (szArgList == NULL || argCount < 3) return E_FAIL; LPCWSTR param; if (argCount >= 4) param = szArgList[3]; else param = L""; HRESULT result = InjectDotNetAssembly( szArgList[0], szArgList[1], szArgList[2], param ); LocalFree(szArgList); return result; }
Environment.Is64BitProcess
[DllImport("kernel32.dll", CallingConvention = CallingConvention.Winapi)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool IsWow64Process([In] IntPtr process, [Out] out bool wow64Process); public static bool Is64BitProcess(Process process) { bool isWow64; if (!IsWow64Process(process.Handle, out isWow64)) { return false; } return !isWow64; } static bool IsCompatibleProcess(Process process) { if (!Environment.Is64BitOperatingSystem) return true; bool is64bitProcess = Is64BitProcess(process); return Environment.Is64BitProcess == is64bitProcess; }
public static int RunWinForms(string arg) { InitLogifyWinForms(); } static void InitLogifyWinForms() { MessageBox.Show("InitLogifyWinForms"); }
static void InitLogifyWinForms() { try { LogifyAlert client = LogifyAlert.Instance; client.ApiKey = "my-api-key"; client.StartExceptionsHandling(); } catch (Exception ex) { } }
void button2_Click(object sender, EventArgs e) { object o = null; o.ToString(); }
static void Main() { InitLogifyWinForms(); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); }
static void Main() { Thread thread = new Thread(InitLogifyWinForms); thread.Start(); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); }
public static int RunWinForms(string arg) { bool isOk = false; try { const int totalTimeout = 5000; const int smallTimeout = 1000; int count = totalTimeout / smallTimeout; for (int i = 0; i < count; i++) { if (Application.OpenForms == null || Application.OpenForms.Count <= 0) Thread.Sleep(smallTimeout); else { Delegate call = new InvokeDelegate(InitLogifyWinForms); Application.OpenForms[0].BeginInvoke(call); isOk = true; break; } } if (!isOk) { InitLogifyWinForms(); } return 0; } catch { return 1; } }
ExeConfigurationFileMap map = new ExeConfigurationFileMap(); map.ExeConfigFilename = configFileName; Configuration config = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="logifyAlert" type="DevExpress.Logify.LogifyConfigSection, Logify.Alert.Win"/> </configSections> <logifyAlert> <collectBreadcrumbs value="1" /> <breadcrumbsMaxCount value="500" /> <apiKey value="my-api-key"/> <confirmSend value="false"/> <offlineReportsEnabled value="false"/> <offlineReportsDirectory value="offlineReports"/> <offlineReportsCount value="10"/> </logifyAlert> </configuration>
LogifyRunner (C) 2017 DevExpress Inc.
Usage:
LogifyRunner.exe [--win] [--wpf] [--pid=value>] [--exec=value1, ...]
--win Target process is WinForms application
--wpf Target process is WPF application
--pid Target process ID. Runner will be attached to process with specified ID.
--exec Target process command line
NOTE: logify.config file should be placed to the same directory where the target process executable or LogifyRunner.exe is located.
Read more about config file format at: https://github.com/DevExpress/Logify.Alert.Clients/tree/develop/dotnet/Logify.Alert.Win#configuration
Source: https://habr.com/ru/post/343536/
All Articles