1414
1515namespace ReClassNET . Memory
1616{
17- public class RemoteProcess
17+ public class RemoteProcess : IDisposable
1818 {
19+ private readonly object processSync = new object ( ) ;
20+
1921 private readonly NativeHelper nativeHelper ;
2022 public NativeHelper NativeHelper => nativeHelper ;
2123
2224 private ProcessInfo process ;
23- public ProcessInfo Process
24- {
25- get { return process ; }
26- set { if ( process != value ) { process = value ; rttiCache . Clear ( ) ; ProcessChanged ? . Invoke ( this ) ; } }
27- }
25+ private IntPtr handle ;
26+ public ProcessInfo UnderlayingProcess => process ;
2827
2928 public delegate void RemoteProcessChangedEvent ( RemoteProcess sender ) ;
3029 public event RemoteProcessChangedEvent ProcessChanged ;
@@ -38,7 +37,7 @@ public ProcessInfo Process
3837 private readonly SymbolStore symbols = new SymbolStore ( ) ;
3938 public SymbolStore Symbols => symbols ;
4039
41- public bool IsValid => process != null && nativeHelper . IsProcessValid ( process . Handle ) ;
40+ public bool IsValid => process != null && nativeHelper . IsProcessValid ( handle ) ;
4241
4342 public RemoteProcess ( NativeHelper nativeHelper )
4443 {
@@ -47,6 +46,51 @@ public RemoteProcess(NativeHelper nativeHelper)
4746 this . nativeHelper = nativeHelper ;
4847 }
4948
49+ public void Dispose ( )
50+ {
51+ Close ( ) ;
52+ }
53+
54+ public void Open ( ProcessInfo info )
55+ {
56+ Contract . Requires ( info != null ) ;
57+
58+ if ( process != info )
59+ {
60+ lock ( processSync )
61+ {
62+ Close ( ) ;
63+
64+ rttiCache . Clear ( ) ;
65+
66+ process = info ;
67+
68+ handle = nativeHelper . OpenRemoteProcess ( process . Id , ProcessAccess . Full ) ;
69+ }
70+
71+ ProcessChanged ? . Invoke ( this ) ;
72+ }
73+ }
74+
75+ public void Close ( )
76+ {
77+ if ( process != null )
78+ {
79+ lock ( processSync )
80+ {
81+ //detach debugger, remove breakpoints
82+
83+ nativeHelper . CloseRemoteProcess ( handle ) ;
84+
85+ handle = IntPtr . Zero ;
86+
87+ process = null ;
88+ }
89+
90+ ProcessChanged ? . Invoke ( this ) ;
91+ }
92+ }
93+
5094 #region ReadMemory
5195
5296 /// <summary>Reads remote memory from the address into the buffer.</summary>
@@ -76,14 +120,14 @@ public bool ReadRemoteMemoryIntoBuffer(IntPtr address, ref byte[] buffer, int of
76120
77121 if ( ! IsValid )
78122 {
79- Process = null ;
123+ Close ( ) ;
80124
81125 buffer . FillWithZero ( ) ;
82126
83127 return false ;
84128 }
85129
86- return nativeHelper . ReadRemoteMemory ( Process . Handle , address , buffer , offset , length ) ;
130+ return nativeHelper . ReadRemoteMemory ( handle , address , buffer , offset , length ) ;
87131 }
88132
89133 /// <summary>Reads <paramref name="size"/> bytes from the address in the remote process.</summary>
@@ -344,7 +388,7 @@ public bool WriteRemoteMemory(IntPtr address, byte[] data)
344388 return false ;
345389 }
346390
347- return nativeHelper . WriteRemoteMemory ( Process . Handle , address , data , data . Length ) ;
391+ return nativeHelper . WriteRemoteMemory ( handle , address , data , data . Length ) ;
348392 }
349393
350394 /// <summary>Writes the given <paramref name="value"/> to the <paramref name="address"/> in the remote process.</summary>
@@ -417,6 +461,16 @@ public string GetNamedAddress(IntPtr address)
417461 return null ;
418462 }
419463
464+ public void EnumerateRemoteSectionsAndModules ( Action < Section > callbackSection , Action < Module > callbackModule )
465+ {
466+ if ( ! IsValid )
467+ {
468+ return ;
469+ }
470+
471+ nativeHelper . EnumerateRemoteSectionsAndModules ( handle , callbackSection , callbackModule ) ;
472+ }
473+
420474 /// <summary>Updates the process informations.</summary>
421475 public void UpdateProcessInformations ( )
422476 {
@@ -448,7 +502,7 @@ public Task UpdateProcessInformationsAsync()
448502 var newModules = new List < Module > ( ) ;
449503 var newSections = new List < Section > ( ) ;
450504
451- nativeHelper . EnumerateRemoteSectionsAndModules ( process . Handle , newSections . Add , newModules . Add ) ;
505+ EnumerateRemoteSectionsAndModules ( newSections . Add , newModules . Add ) ;
452506
453507 newModules . Sort ( ( m1 , m2 ) => m1 . Start . CompareTo ( m2 . Start ) ) ;
454508 newSections . Sort ( ( s1 , s2 ) => s1 . Start . CompareTo ( s2 . Start ) ) ;
@@ -535,5 +589,15 @@ public Task LoadAllSymbolsAsync(IProgress<Tuple<Module, IEnumerable<Module>>> pr
535589 TaskScheduler . FromCurrentSynchronizationContext ( )
536590 ) ;
537591 }
592+
593+ public void ControlRemoteProcess ( ControlRemoteProcessAction action )
594+ {
595+ if ( ! IsValid )
596+ {
597+ return ;
598+ }
599+
600+ nativeHelper . ControlRemoteProcess ( handle , action ) ;
601+ }
538602 }
539603}
0 commit comments