99 lines
3.5 KiB
C#
99 lines
3.5 KiB
C#
|
// 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;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|