public void Restore() { if (OriginalBytes != null && OriginalBytes.Length > 0) { if (SuspendNeeded) { // Suspend try { MiniMem.SuspendProcess(); var suspendFlag = true; MiniMem.WriteBytes(TrampolineOrigin, OriginalBytes); if (suspendFlag && SuspendNeeded) { MiniMem.ResumeProcess(); } } catch { MiniMem.WriteBytes(TrampolineOrigin, OriginalBytes); } } else { MiniMem.WriteBytes(TrampolineOrigin, OriginalBytes); } } AllocatedMemory?.ReleaseMemory(); }
public static bool IsValid(this IntPtr ptr, ProcModule module = null) { if (MiniMem.AttachedProcess.ProcessHandle == IntPtr.Zero) { throw new Exception("Please attach to the game first!"); } if (ptr == IntPtr.Zero) { return(false); } if (module != null) { return(ptr.ToInt32() >= module.BaseAddress.ToInt32() && ptr.ToInt32() <= module.EndAddress.ToInt32()); } ProcModule pm = MiniMem.FindProcessModule(MiniMem.AttachedProcess.ProcessObject.ProcessName); // Get "main" module if (pm != null) { return(ptr.ToInt32() >= pm.BaseAddress.ToInt32() && ptr.ToInt32() <= pm.EndAddress.ToInt32()); } return(ptr != IntPtr.Zero); }
public static void CallbackLoop() { while (!bCallbackThreadExitFlag) { if (MiniMem.ActiveCallbacks.Count < 1 || MiniMem.AttachedProcess.ProcessHandle == IntPtr.Zero) { Thread.Sleep(500); continue; } Debug.WriteLine($"[CALLBACK MONITOR] {MiniMem.ActiveCallbacks.Count} registered item(s) in Callback Monitor"); for (int i = MiniMem.ActiveCallbacks.Count - 1; i >= 0; i--) { if (bCallbackThreadExitFlag) { break; } CallbackObject cObj = MiniMem.ActiveCallbacks[i]; if (cObj.ObjectCallback == null) { continue; } if (cObj.ptr_HitCounter == IntPtr.Zero) { continue; } if (MiniMem.AttachedProcess.ProcessHandle == IntPtr.Zero) { continue; } uint r = MiniMem.ReadMemory <uint>(cObj.ptr_HitCounter.ToInt64()); if (r != cObj.LastValue) { MiniMem.ActiveCallbacks.Remove(cObj); cObj.LastValue = r; MiniMem.ActiveCallbacks.Add(cObj); cObj.ObjectCallback?.Invoke(cObj); } } if (bCallbackThreadExitFlag) { break; } Thread.Sleep(25); } bCallbackThreadExitFlag = false; }
/// <summary> /// Frees the memory accociated with this object /// </summary> /// <returns></returns> public bool ReleaseMemory() { return(MiniMem.FreeMemory(Pointer, Size)); }
public static bool Find(byte[] data, Byte[] pattern, out List <long> offsetsFound, long optionalOffsetResult = 0, bool optionalAbsoluteResult = false, long moduleBase = 0L, ReturnType returnType = ReturnType.ADDRESS) { int HARD_CAP_RESULT_AMOUNT = 25; var offsetsFoundInternal = new List <long>(); if (data == null || pattern == null) { offsetsFound = null; return(false); } var patternSize = pattern.LongLength; if (data.LongLength == 0 || patternSize == 0) { offsetsFound = null; return(false); } for (long i = 0, pos = 0; i < data.LongLength; i++) { if (matchByte(data[i], ref pattern[pos])) //check if the current data byte matches the current pattern byte { pos++; if (pos != patternSize) { continue; } var internalOffsetFound = i - patternSize + 1; if (optionalAbsoluteResult) { internalOffsetFound += moduleBase; } if (optionalOffsetResult != 0) { internalOffsetFound += optionalOffsetResult; } switch (returnType) { case ReturnType.ADDRESS: offsetsFoundInternal.Add(internalOffsetFound); break; case ReturnType.READ4BYTES: byte[] byteSequence4 = MiniMem.ReadBytes(optionalAbsoluteResult ? internalOffsetFound : moduleBase + internalOffsetFound, 4); offsetsFoundInternal.Add((long)BitConverter.ToInt32(byteSequence4, 0)); break; case ReturnType.READ8BYTES: byte[] byteSequence9 = MiniMem.ReadBytes(optionalAbsoluteResult ? internalOffsetFound : moduleBase + internalOffsetFound, 8); offsetsFoundInternal.Add(BitConverter.ToInt64(byteSequence9, 0)); break; } pos = 0; if (offsetsFoundInternal.Count >= HARD_CAP_RESULT_AMOUNT) { Debug.WriteLine($"Hard cap of {HARD_CAP_RESULT_AMOUNT} addresses have been hit so far with {data.LongLength - i} bytes left unread in buffer, stopping procedure ..."); break; } } else { i -= pos; pos = 0; //reset current pattern position } } offsetsFound = offsetsFoundInternal; return(offsetsFound.Count > 0); //return false; }