ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/RomCheater/trunk/Win32/Sojaner.MemoryScanner/MemoryProviers/BaseMemoryProvider.cs
Revision: 428
Committed: Tue May 28 13:32:28 2013 UTC (10 years, 6 months ago) by william
File size: 18426 byte(s)
Log Message:
+ fix memory scanner and memory providers to read and write process memory simulataneously without crashing due to null process handle
*** this has been done using ProcessMemoryChunk for all memory read/write operations
** we no longer need to open and close native handles to the process

File Contents

# Content
1 #region Logging Defines
2 // include this any class or method that required logging, and comment-out what is not needed
3
4 #region Enabled logging levels
5 #define LOGGING_ENABLE_INFO
6 #define LOGGING_ENABLE_WARN
7 #define LOGGING_ENABLE_DEBUG
8 #define LOGGING_ENABLE_VERBOSEDEBUG
9 #define LOGGING_ENABLE_ERROR
10 #define LOGGING_ENABLE_VERBOSEERROR
11 #define LOGGING_ENABLE_PROFILER
12 #endregion
13 #endregion
14 using System;
15 using System.Collections.Generic;
16 using System.Linq;
17 using System.Text;
18 using RomCheater.Logging;
19 using System.Diagnostics;
20 using RomCheater.PluginFramework.Interfaces;
21 using System.IO;
22 using RomCheater.PluginFramework.Events;
23
24 namespace Sojaner.MemoryScanner.MemoryProviers
25 {
26 #region public abstract class BaseMemoryProvider
27 public abstract class BaseMemoryProvider :
28 IPatchMemory,
29 IReadMemory,
30 IAcceptsProcess<Process>,
31 IAcceptsPlugin<IConfigPlugin>,
32 IMemoryReader,
33 IMemoryWriter,
34 IFileWriter,
35 IDisposable,
36 IAcceptsBytesReadEvent
37 {
38 private ProcessMemoryReader provider;
39 public BaseMemoryProvider() { this.AcceptedPlugin = null; this.AcceptedProcess = null; isClosed = true; isOpen = false; }
40 public BaseMemoryProvider(IConfigPlugin config) : this() { this.AcceptedPlugin = config; }
41 public BaseMemoryProvider(IConfigPlugin config, Process process) : this() { this.AcceptedPlugin = config; this.AcceptedProcess = process; }
42 public BaseMemoryProvider(IAcceptsProcessAndConfig pconfig) : this() { this.AcceptedPlugin = pconfig.AcceptedPlugin; this.AcceptedProcess = pconfig.AcceptedProcess; }
43
44
45 public event BaseEventHandler<OnBytesReadEventArgs> OnBytesRead;
46
47 private bool isOpen { get; set; }
48 private bool isClosed { get; set; }
49
50 private void provider_OnBytesRead(OnBytesReadEventArgs e)
51 {
52 e.Sender = this;
53 if (this.OnBytesRead != null)
54 this.OnBytesRead.Invoke(e);
55 }
56 #region Open/Close Provider
57 #region public virtual void OpenProvider()
58 public virtual void OpenProvider()
59 {
60 if (isOpen)
61 {
62 logger.Warn.WriteLine("Provider has already been opened.");
63 return;
64 }
65 try
66 {
67 provider = new ProcessMemoryReader();
68 provider.ReadProcess = this.AcceptedProcess;
69 //provider.OnBytesRead += new BaseEventHandler<OnBytesReadEventArgs>(provider_OnBytesRead);
70 if (provider.ReadProcess == null) { logger.Error.WriteLine("{0}.OpenProvider() Could not attach to process: {1}", "", this.GetType().Name, this.AcceptedProcess.ToString()); return; }
71 //provider.OpenProcess();
72 isOpen = true;
73 isClosed = false;
74 }
75 catch (Exception ex)
76 {
77 logger.Error.WriteLine("Failed to open provider: {0}{1}", System.Environment.NewLine, ex.ToString());
78 isOpen = false;
79 isClosed = true;
80 }
81 }
82 #endregion
83 #region public virtual void CloseProvider()
84 public virtual void CloseProvider()
85 {
86 if (isClosed)
87 {
88 logger.Warn.WriteLine("Provider has already been closed.");
89 return;
90 }
91 if (!isOpen)
92 {
93 logger.Warn.WriteLine("Provider cannot be closed, it was never opened...attempting to open provider.");
94 OpenProvider();
95 if (!isOpen)
96 {
97 logger.Warn.WriteLine("Could not open provider");
98 return;
99 }
100 }
101 try
102 {
103 //logger.VerboseDebug.WriteLine("CloseProvider(): System.Environment.StackTrace: {0}{1}", System.Environment.NewLine, System.Environment.StackTrace);
104 if (provider == null) return;
105 //provider.CloseHandle();
106 provider = null; // free any memory associated with the provider
107 isClosed = true;
108 isOpen = false;
109 }
110 catch (Exception ex)
111 {
112 logger.Error.WriteLine("Failed to close provider: {0}{1}", System.Environment.NewLine, ex.ToString());
113 isClosed = false;
114 if (isOpen)
115 {
116 throw new Exception("Provider is failed to close and still open.");
117 }
118 }
119 }
120 #endregion
121 #endregion
122
123 #region IAcceptsProcess<Process> Members
124 public Process AcceptedProcess { get; set; }
125 #endregion
126 #region IAcceptsPlugin<IConfigPlugin> Members
127 public IConfigPlugin AcceptedPlugin { get; set; }
128 #endregion
129 #region EnsureProviderIsOpen methods : log and/or throw errors
130 private bool EnsureProviderIsOpen() { return EnsureProviderIsOpenOrThrowError(); }
131 private bool EnsureProviderIsOpenOrLogError() { return EnsureProviderIsOpenOrThrowOrLogError(false, true); }
132 private bool EnsureProviderIsOpenOrThrowError() { return EnsureProviderIsOpenOrThrowOrLogError(true, true); }
133 private bool EnsureProviderIsOpenOrThrowOrLogError(bool ThrowError, bool LogError)
134 {
135 if (!isOpen)
136 {
137 try { throw new Exception("Memory operation could not be completed because the provider is not open"); }
138 catch (Exception ex)
139 {
140 if (LogError)
141 logger.Error.WriteLine(ex.ToString());
142 if (ThrowError)
143 throw ex;
144 return false;
145 }
146 }
147 return true;
148 }
149 #endregion
150
151 #region IPatchMemory members
152 #region public virtual bool PatchMemory(uint address, byte value)
153 public virtual bool PatchMemory(uint address, byte value)
154 {
155 if (!EnsureProviderIsOpen()) { return false; }
156 return provider.PatchMemory(address, value);
157 }
158 #endregion
159 #region public virtual bool PatchMemory(uint address, sbyte value)
160 public virtual bool PatchMemory(uint address, sbyte value)
161 {
162 if (!EnsureProviderIsOpen()) { return false; }
163 return provider.PatchMemory(address, value);
164 }
165 #endregion
166 #region public virtual bool PatchMemory(uint address, ushort value)
167 public virtual bool PatchMemory(uint address, ushort value)
168 {
169 if (!EnsureProviderIsOpen()) { return false; }
170 return provider.PatchMemory(address, value);
171 }
172 #endregion
173 #region public virtual bool PatchMemory(uint address, short value)
174 public virtual bool PatchMemory(uint address, short value)
175 {
176 if (!EnsureProviderIsOpen()) { return false; }
177 return provider.PatchMemory(address, value);
178 }
179 #endregion
180 #region public virtual bool PatchMemory(uint address, uint value)
181 public virtual bool PatchMemory(uint address, uint value)
182 {
183 if (!EnsureProviderIsOpen()) { return false; }
184 return provider.PatchMemory(address, value);
185 }
186 #endregion
187 #region public virtual bool PatchMemory(uint address, int value)
188 public virtual bool PatchMemory(uint address, int value)
189 {
190 if (!EnsureProviderIsOpen()) { return false; }
191 return provider.PatchMemory(address, value);
192 }
193 #endregion
194 #region public virtual bool PatchMemory(uint address, ulong value)
195 public virtual bool PatchMemory(uint address, ulong value)
196 {
197 if (!EnsureProviderIsOpen()) { return false; }
198 return provider.PatchMemory(address, value);
199 }
200 #endregion
201 #region public virtual bool PatchMemory(uint address, long value)
202 public virtual bool PatchMemory(uint address, long value)
203 {
204 if (!EnsureProviderIsOpen()) { return false; }
205 return provider.PatchMemory(address, value);
206 }
207 #endregion
208 #endregion
209
210 #region IReadMemory members
211 #region public virtual bool ReadMemory(uint address, out byte value)
212 public virtual bool ReadMemory(uint address, out byte value)
213 {
214 value = 0;
215 if (!EnsureProviderIsOpen()) { return false; }
216 return provider.ReadMemory(address, out value);
217 }
218 #endregion
219 #region public virtual bool ReadMemory(uint address, out sbyte value)
220 public virtual bool ReadMemory(uint address, out sbyte value)
221 {
222 value = 0;
223 if (!EnsureProviderIsOpen()) { return false; }
224 return provider.ReadMemory(address, out value);
225 }
226 #endregion
227 #region public virtual bool ReadMemory(uint address, out ushort value)
228 public virtual bool ReadMemory(uint address, out ushort value)
229 {
230 value = 0;
231 if (!EnsureProviderIsOpen()) { return false; }
232 return provider.ReadMemory(address, out value);
233 }
234 #endregion
235 #region public virtual bool ReadMemory(uint address, out short value)
236 public virtual bool ReadMemory(uint address, out short value)
237 {
238 value = 0;
239 if (!EnsureProviderIsOpen()) { return false; }
240 return provider.ReadMemory(address, out value);
241 }
242 #endregion
243 #region public virtual bool ReadMemory(uint address, out uint value)
244 public virtual bool ReadMemory(uint address, out uint value)
245 {
246 value = 0;
247 if (!EnsureProviderIsOpen()) { return false; }
248 return provider.ReadMemory(address, out value);
249 }
250 #endregion
251 #region public virtual bool ReadMemory(uint address, out int value)
252 public virtual bool ReadMemory(uint address, out int value)
253 {
254 value = 0;
255 if (!EnsureProviderIsOpen()) { return false; }
256 return provider.ReadMemory(address, out value);
257 }
258 #endregion
259 #region public virtual bool ReadMemory(uint address, out ulong value)
260 public virtual bool ReadMemory(uint address, out ulong value)
261 {
262 value = 0;
263 if (!EnsureProviderIsOpen()) { return false; }
264 return provider.ReadMemory(address, out value);
265 }
266 #endregion
267 #region public virtual bool ReadMemory(uint address, out long value)
268 public virtual bool ReadMemory(uint address, out long value)
269 {
270 value = 0;
271 if (!EnsureProviderIsOpen()) { return false; }
272 return provider.ReadMemory(address, out value);
273 }
274 #endregion
275 #endregion
276
277 #region IMemoryReader members
278 #region public virtual bool ReadFirstNonZeroByte(int MemoryAddress, uint bytesToRead, out int address)
279 public virtual bool ReadFirstNonZeroByte(int MemoryAddress, uint bytesToRead, out int address)
280 {
281 address = 0;
282 if (!EnsureProviderIsOpen()) { return false; }
283 try { provider.ReadFirstNonZeroByte(MemoryAddress, bytesToRead, out address); return true; }
284 catch { address = 0x00; return false; }
285 }
286 #endregion
287 #region public virtual void ReadProcessMemoryAtOnce(int MemoryAddress, uint bytesToRead, out int bytesRead, out byte[] data)
288 public virtual void ReadProcessMemoryAtOnce(uint MemoryAddress, uint bytesToRead, object UserState)
289 {
290 if (!EnsureProviderIsOpen()) { return; }
291 try { provider.ReadProcessMemoryAtOnce(MemoryAddress, bytesToRead, UserState); }
292 catch { }
293 }
294 public virtual void ReadProcessMemoryAtOnce(uint MemoryAddress, uint bytesToRead, out int bytesRead, out byte[] data)
295 {
296 bytesRead = 0x00;
297 data = new byte[bytesToRead];
298 if (!EnsureProviderIsOpen()) { return; }
299 try { provider.ReadProcessMemoryAtOnce(MemoryAddress, bytesToRead, out bytesRead, out data); }
300 catch { bytesRead = 0x00; data = new byte[] { }; }
301 }
302 #endregion
303 #region public virtual void ReadProcessMemory(int MemoryAddress, int bytesToRead, out int bytesRead, out byte[] data)
304 public virtual void ReadProcessMemory(uint MemoryAddress, uint bytesToRead, out int bytesRead, out byte[] data)
305 {
306 bytesRead = 0x00;
307 data = new byte[bytesToRead];
308 if (!EnsureProviderIsOpen()) { return; }
309 try { provider.ReadProcessMemory(MemoryAddress, bytesToRead, out bytesRead, out data); }
310 catch { bytesRead = 0x00; data = new byte[] { }; }
311 }
312 public virtual void ReadProcessMemory(int MemoryAddress, uint bytesToRead, out int bytesRead, out byte[] data)
313 {
314 bytesRead = 0x00;
315 data = new byte[bytesToRead];
316 if (!EnsureProviderIsOpen()) { return; }
317 try { provider.ReadProcessMemory(MemoryAddress, bytesToRead, out bytesRead, out data); }
318 catch { bytesRead = 0x00; data = new byte[] { }; }
319 }
320 #endregion
321 #region IMemoryWriter members
322 //#region public virtual void WriteProcessMemory(int MemoryAddress, byte byteToWrite, out int bytesWritten)
323 //public virtual void WriteProcessMemory(int MemoryAddress, byte byteToWrite, out int bytesWritten)
324 //{
325 // bytesWritten = 0;
326 // if (!EnsureProviderIsOpen()) { return; }
327 // try { provider.WriteProcessMemory(MemoryAddress, new byte[] { byteToWrite }, out bytesWritten); }
328 // catch { bytesWritten = 0x00; }
329 //}
330 //#endregion
331 #region public virtual void WriteProcessMemory(int MemoryAddress, byte[] bytesToWrite, out int bytesWritten)
332 public virtual void WriteProcessMemory(int MemoryAddress, byte[] bytesToWrite, out int bytesWritten)
333 {
334 bytesWritten = 0;
335 if (!EnsureProviderIsOpen()) { return; }
336 try { provider.WriteProcessMemory(MemoryAddress, bytesToWrite, out bytesWritten); }
337 catch { bytesWritten = 0x00; }
338 }
339 public virtual void WriteProcessMemory(uint MemoryAddress, byte[] bytesToWrite, out uint bytesWritten)
340 {
341 bytesWritten = 0;
342 if (!EnsureProviderIsOpen()) { return; }
343 try { provider.WriteProcessMemory(MemoryAddress, bytesToWrite, out bytesWritten); }
344 catch { bytesWritten = 0x00; }
345 }
346 #endregion
347 #endregion
348 #endregion
349 #region IFileWriter members
350 #region public virtual bool WriteProcessMemoryToFile(string filename, int MemoryAddress, uint bytesToRead, out int bytesRead)
351 public virtual bool WriteProcessMemoryToFile(string filename, int MemoryAddress, uint bytesToRead, out int bytesRead)
352 {
353 bytesRead = 0;
354 if (!EnsureProviderIsOpen()) { return false; }
355 try { provider.WriteProcessMemoryToFile(filename, MemoryAddress, bytesToRead, out bytesRead); return true; }
356 catch
357 { bytesRead = 0x00; return false; }
358 }
359 #endregion
360 #endregion
361
362 #region IDisposable Support
363 // Track whether Dispose has been called.
364 private bool disposed = false;
365 // Implement IDisposable.
366 // Do not make this method virtual.
367 // A derived class should not be able to override this method.
368 public void Dispose()
369 {
370 Dispose(true);
371 // This object will be cleaned up by the Dispose method.
372 // Therefore, you should call GC.SupressFinalize to
373 // take this object off the finalization queue
374 // and prevent finalization code for this object
375 // from executing a second time.
376 GC.SuppressFinalize(this);
377 }
378 // Dispose(bool disposing) executes in two distinct scenarios.
379 // If disposing equals true, the method has been called directly
380 // or indirectly by a user's code. Managed and unmanaged resources
381 // can be disposed.
382 // If disposing equals false, the method has been called by the
383 // runtime from inside the finalizer and you should not reference
384 // other objects. Only unmanaged resources can be disposed.
385 protected virtual void Dispose(bool disposing)
386 {
387 // Check to see if Dispose has already been called.
388 if (!this.disposed)
389 {
390 // If disposing equals true, dispose all managed
391 // and unmanaged resources.
392 if (disposing)
393 {
394 // Dispose managed resources.
395 //component.Dispose();
396 }
397
398 // Call the appropriate methods to clean up
399 // unmanaged resources here.
400 // If disposing is false,
401 // only the following code is executed.
402 if (!isClosed)
403 CloseProvider();
404 // Note disposing has been done.
405 disposed = true;
406
407 }
408 }
409 // Use C# destructor syntax for finalization code.
410 // This destructor will run only if the Dispose method
411 // does not get called.
412 // It gives your base class the opportunity to finalize.
413 // Do not provide destructors in types derived from this class.
414 ~BaseMemoryProvider()
415 {
416 // Do not re-create Dispose clean-up code here.
417 // Calling Dispose(false) is optimal in terms of
418 // readability and maintainability.
419 Dispose(false);
420 }
421 #endregion
422 }
423 #endregion
424 }