winmr-api/Services/Scanners/ModuleScanner.cs

99 lines
3.5 KiB
C#
Raw Normal View History

2025-07-03 15:22:40 +03:00
// File: Services/Scanners/ModuleScanner.cs
using System.Diagnostics;
using WebmrAPI.Exceptions;
using WebmrAPI.Models;
using WebmrAPI.Utils;
namespace WebmrAPI.Services.Scanners
{
public class ModuleScanner : AbstractScanner<ProcessModuleInfo>
{
override public ScanTarget Target { get => ScanTarget.Modules; }
internal int PID { get; private set; }
override internal bool Scan(out Dictionary<long, ProcessModuleInfo>? data)
{
data = new();
try
{
using (var process = Process.GetProcessById(PID))
{
foreach (ProcessModule module in process.Modules)
{
long addr = module.BaseAddress.ToInt64();
data.Add(addr, new ProcessModuleInfo
{
MemoryAddress = addr,
ModuleName = module.ModuleName,
FileName = module.FileName,
MemorySize = (ulong)module.ModuleMemorySize,
EntrypointRawAddress = module.EntryPointAddress.ToInt64()
});
}
}
return true;
}
catch (System.ComponentModel.Win32Exception ex) when (ex.NativeErrorCode == 5)
{
Provider.Logger.LogWarning($"Access denied to Process.Modules for PID {PID}. Attempting P/Invoke. Error: {ex.Message}");
if (!Provider.ProcessReadAccess) return false;
}
catch (InvalidOperationException ex)
{
Provider.Logger.LogWarning($"Process with PID {PID} might have exited before module scanning. Error: {ex.Message}");
return false;
}
catch (Exception ex)
{
Provider.Logger.LogError(ex, $"An unexpected error occurred while getting modules for PID {PID} using managed API.");
return false;
}
try
{
using (var process = new WindowsProcess(PID, true))
{
var modules = data;
process.ForeachLoadedModule(info =>
{
long addr = info.BaseAddress.ToInt64();
modules.Add(addr, new ProcessModuleInfo
{
ModuleName = info.Name.ToString(),
MemoryAddress = addr,
FileName = info.FileName.ToString(),
MemorySize = info.MemorySize,
EntrypointRawAddress = info.EntryPointAddress.ToInt64()
});
});
}
return true;
}
catch (GettingModuleInfoException ex)
{
Provider.Logger.LogDebug(ex.Message);
}
catch (ProcessMonitorException ex)
{
Provider.Logger.LogError(ex.Message);
}
catch (Exception ex)
{
Provider.Logger.LogError(ex, $"An error occurred while getting modules for PID {PID} using P/Invoke.");
}
return false;
}
public ModuleScanner(IScanProvider scanner, LazyConcurrentContainer<ProcessModuleInfo> container, int pid)
: base(scanner, container)
{
PID = pid;
}
}
}