/// <summary> /// Reads a value from memory. /// </summary> /// <param name="dwAddress">Address at which value will be read.</param> /// <param name="bReverse">Determines whether bytes read will be reversed or not (Little endian or big endian). Usually 'false'.</param> /// <exception cref="Exception">Throws general exception on failure.</exception> /// <returns>Returns the value that was read from memory.</returns> /// <remarks>Sometimes one needs to read a value where the most significant bytes is not first (i.e. when reading a network packet from memory). In this case, one would specify 'true' for the bReverse parameter to get the value in a readable format.</remarks> public double ReadDouble(uint dwAddress, bool bReverse) { if (!this.m_bProcessOpen || this.m_hProcess == IntPtr.Zero) { throw new Exception("Process is not open for read/write."); } return(SMemory.ReadDouble(this.m_hProcess, dwAddress, bReverse)); }
/// <summary> /// Reads a value from memory. /// </summary> /// <param name="dwAddress">Address at which value will be read.</param> /// <exception cref="Exception">Throws general exception on failure.</exception> /// <returns>Returns the value that was read from memory.</returns> public sbyte ReadSByte(uint dwAddress) { if (!this.m_bProcessOpen || this.m_hProcess == IntPtr.Zero) { throw new Exception("Process is not open for read/write."); } return(SMemory.ReadSByte(this.m_hProcess, dwAddress)); }
/// <summary> /// Reads a value from memory. /// </summary> /// <param name="dwAddress">Address at which value will be read.</param> /// <param name="objType">Type of object to be read (hint: use Object.GetType() or typeof(ObjectType) macro).</param> /// <exception cref="Exception">Throws general exception on failure.</exception> /// <returns>Returns the value that was read from memory.</returns> public object ReadObject(uint dwAddress, Type objType) { if (!this.m_bProcessOpen || this.m_hProcess == IntPtr.Zero) { throw new Exception("Process is not open for read/write."); } return(SMemory.ReadObject(this.m_hProcess, dwAddress, objType)); }
/// <summary> /// Reads a value from memory /// </summary> /// <param name="dwAddress">Address at which value will be read.</param> /// <param name="nSize">Number of bytes to read from memory.</param> /// <exception cref="Exception">Throws general exception on failure.</exception> /// <returns>Returns the value that was read from memory.</returns> public byte[] ReadBytes(uint dwAddress, int nSize) { if (!this.m_bProcessOpen || this.m_hProcess == IntPtr.Zero) { throw new Exception("Process is not open for read/write."); } return(SMemory.ReadBytes(this.m_hProcess, dwAddress, nSize)); }
/// <summary> /// Injects a dll into a process by creating a remote thread on LoadLibrary. /// </summary> /// <param name="hProcess">Handle to the process into which dll will be injected.</param> /// <param name="szDllPath">Full path of the dll that will be injected.</param> /// <returns>Returns the base address of the injected dll on success, zero on failure.</returns> public static uint InjectDllCreateThread(IntPtr hProcess, string szDllPath) { if (hProcess == IntPtr.Zero) { throw new ArgumentNullException("hProcess"); } if (szDllPath.Length == 0) { throw new ArgumentNullException("szDllPath"); } if (!szDllPath.Contains("\\")) { szDllPath = System.IO.Path.GetFullPath(szDllPath); } if (!System.IO.File.Exists(szDllPath)) { throw new ArgumentException("DLL not found.", "szDllPath"); } uint dwBaseAddress = RETURN_ERROR; uint lpLoadLibrary; uint lpDll; IntPtr hThread; lpLoadLibrary = (uint)Imports.GetProcAddress(Imports.GetModuleHandle("kernel32.dll"), "LoadLibraryA"); if (lpLoadLibrary > 0) { lpDll = SMemory.AllocateMemory(hProcess); if (lpDll > 0) { if (SMemory.WriteASCIIString(hProcess, lpDll, szDllPath)) { hThread = SThread.CreateRemoteThread(hProcess, lpLoadLibrary, lpDll); //wait for thread handle to have signaled state //exit code will be equal to the base address of the dll if (SThread.WaitForSingleObject(hThread, 5000) == WaitValues.WAIT_OBJECT_0) { dwBaseAddress = SThread.GetExitCodeThread(hThread); } Imports.CloseHandle(hThread); } SMemory.FreeMemory(hProcess, lpDll); } } return(dwBaseAddress); }
/// <summary> /// Finds a pattern or signature inside another process. /// </summary> /// <param name="hProcess">Handle to the process in whose memory pattern will be found.</param> /// <param name="dwStart">Address on which the search will start.</param> /// <param name="nSize">Number of bytes in memory that will be searched.</param> /// <param name="bPattern">A byte-array representing the pattern to be found.</param> /// <param name="szMask">A string of 'x' (match), '!' (not-match), or '?' (wildcard).</param> /// <returns>Returns 0 on failure, or the address of the start of the pattern on success.</returns> public static uint FindPattern(IntPtr hProcess, uint dwStart, int nSize, byte[] bPattern, string szMask) { if (bPattern == null || bPattern.Length == 0) { throw new ArgumentNullException("bData"); } if (bPattern.Length != szMask.Length) { throw new ArgumentException("bData and szMask must be of the same size"); } byte[] bData = SMemory.ReadBytes(hProcess, dwStart, nSize); if (bData == null) { throw new Exception("Could not read memory in FindPattern."); } return((uint)(dwStart + FindPattern(bData, bPattern, szMask))); }
/// <summary> /// Assembles mnemonics and injects resulting bytecode into given process. /// </summary> /// <param name="hProcess">Handle to the process into which code will be injected.</param> /// <param name="dwAddress">Address at which code will be injected.</param> /// <param name="szAssembly">Assembly mnemonics to be assembled and injected.</param> /// <returns>Returns true on success, false on failure.</returns> public static bool InjectCode(IntPtr hProcess, uint dwAddress, string szAssembly) { byte[] bBytecode; if (hProcess == IntPtr.Zero || szAssembly.Length == 0 || dwAddress == 0) { return(false); } try { bBytecode = ManagedFasm.Assemble(szAssembly); } catch (Exception ex) { #if DEBUG Console.WriteLine(ex.Message); #endif return(false); } return(SMemory.WriteBytes(hProcess, dwAddress, bBytecode, bBytecode.Length)); }
/// <summary> /// Writes a value to another process' memory. /// </summary> /// <param name="dwAddress">Address at which value will be written.</param> /// <param name="Value">Value that will be written to memory.</param> /// <returns>Returns true on success, false on failure.</returns> public bool WriteInt(uint dwAddress, int Value) { return(SMemory.WriteInt(this.m_hProcess, dwAddress, Value)); }
/// <summary> /// Writes a value to another process' memory. /// </summary> /// <param name="dwAddress">Address at which value will be written.</param> /// <param name="Value">Value that will be written to memory.</param> /// <returns>Returns true on success, false on failure.</returns> public bool WriteUShort(uint dwAddress, ushort Value) { return(SMemory.WriteUShort(this.m_hProcess, dwAddress, Value)); }
/// <summary> /// Frees an allocated block of memory in the opened process. /// </summary> /// <param name="dwAddress">Base address of the block of memory to be freed.</param> /// <param name="nSize">Number of bytes to be freed. This must be zero (0) if using <see cref="MemoryFreeType.MEM_RELEASE"/>.</param> /// <param name="dwFreeType">Type of free operation to use. See <see cref="MemoryFreeType"/>.</param> /// <returns>Returns true on success, false on failure.</returns> public bool FreeMemory(uint dwAddress, int nSize, uint dwFreeType) { return(SMemory.FreeMemory(m_hProcess, dwAddress, nSize, dwFreeType)); }
/// <summary> /// Allocates memory inside the opened process. /// </summary> /// <param name="nSize">Number of bytes to allocate.</param> /// <param name="dwAllocationType">Type of memory allocation. See <see cref="MemoryAllocType"/>.</param> /// <param name="dwProtect">Type of memory protection. See <see cref="MemoryProtectType"/></param> /// <returns>Returns NULL on failure, or the base address of the allocated memory on success.</returns> public uint AllocateMemory(int nSize, uint dwAllocationType, uint dwProtect) { return(SMemory.AllocateMemory(m_hProcess, nSize, dwAllocationType, dwProtect)); }
/// <summary> /// Reads a value from memory. /// </summary> /// <param name="dwAddress">Address at which value will be read.</param> /// <param name="nLength">Maximum number of characters to be read.</param> /// <exception cref="Exception">Throws general exception on failure.</exception> /// <returns>Returns the value that was read from memory.</returns> public string ReadUnicodeString(uint dwAddress, int nLength) { return(SMemory.ReadUnicodeString(this.m_hProcess, dwAddress, nLength)); }
/// <summary> /// Assembles mnemonics and injects resulting bytecode into given process. /// </summary> /// <param name="hProcess">Handle to the process into which code will be injected.</param> /// <param name="szAssembly">Assembly mnemonics to be assembled and injected.</param> /// <returns>Returns zero on failure, otherwise a chunk of memory that has been allocated in the target process where code was injected.</returns> /// <remarks>Don't forget to free the memory allocated for the code when you are finished.</remarks> public static uint InjectCode(IntPtr hProcess, string szAssembly) { uint dwAddress = SMemory.AllocateMemory(hProcess); return((InjectCode(hProcess, dwAddress, szAssembly)) ? dwAddress : RETURN_ERROR); }
/// <summary> /// Writes a value to another process' memory. /// </summary> /// <param name="dwAddress">Address at which value will be written.</param> /// <param name="Value">Value that will be written to memory.</param> /// <returns>Returns true on success, false on failure.</returns> public bool WriteSByte(uint dwAddress, sbyte Value) { return(SMemory.WriteSByte(this.m_hProcess, dwAddress, Value)); }
/// <summary> /// Injects a dll into a process by hijacking the given thread and redirecting it to LoadLibrary. /// </summary> /// <param name="hProcess">Handle to process into which dll will be injected.</param> /// <param name="hThread">Handle to thread that will be hijacked.</param> /// <param name="szDllPath">Full path to the dll to be injected.</param> /// <returns>Returns the base address of the injected dll on success, zero on failure.</returns> public static uint InjectDllRedirectThread(IntPtr hProcess, IntPtr hThread, string szDllPath) { const uint INITIAL_EXIT_CODE = 0xFFFFFFFF; if (hProcess == IntPtr.Zero) { throw new ArgumentNullException("hProcess"); } if (hThread == IntPtr.Zero) { throw new ArgumentNullException("hThread"); } if (szDllPath.Length == 0) { throw new ArgumentNullException("szDllPath"); } if (!szDllPath.Contains("\\")) { szDllPath = System.IO.Path.GetFullPath(szDllPath); } if (!System.IO.File.Exists(szDllPath)) { throw new ArgumentException("DLL not found.", "szDllPath"); } uint dwBaseAddress = RETURN_ERROR; uint lpLoadLibrary, lpAsmStub; CONTEXT ctx; StringBuilder AssemblyStub = new StringBuilder(); ManagedFasm fasm = new ManagedFasm(hProcess); lpLoadLibrary = (uint)Imports.GetProcAddress(Imports.GetModuleHandle("kernel32.dll"), "LoadLibraryA"); if (lpLoadLibrary == 0) { return(RETURN_ERROR); } lpAsmStub = SMemory.AllocateMemory(hProcess); if (lpAsmStub == 0) { return(RETURN_ERROR); } if (SThread.SuspendThread(hThread) != uint.MaxValue) { ctx = SThread.GetThreadContext(hThread, CONTEXT_FLAGS.CONTEXT_CONTROL); if (ctx.Eip > 0) { try { //located at lpAsmStub+0, where we can monitor LoadLibrary's exit code. fasm.AddLine("lpExitCode dd 0x{0:X}", INITIAL_EXIT_CODE); //lpAsmStub+4, where the actual code part starts fasm.AddLine("push 0x{0:X}", ctx.Eip); fasm.AddLine("pushad"); fasm.AddLine("push szDllPath"); fasm.AddLine("call 0x{0:X}", lpLoadLibrary); fasm.AddLine("mov [lpExitCode], eax"); fasm.AddLine("popad"); fasm.AddLine("retn"); //dll path fasm.AddLine("szDllPath db \'{0}\',0", szDllPath); fasm.Inject(lpAsmStub); } catch { SMemory.FreeMemory(hProcess, lpAsmStub); SThread.ResumeThread(hThread); return(RETURN_ERROR); } ctx.ContextFlags = CONTEXT_FLAGS.CONTEXT_CONTROL; ctx.Eip = lpAsmStub + 4; //skip over lpExitCode data if (SThread.SetThreadContext(hThread, ctx)) { if (SThread.ResumeThread(hThread) != uint.MaxValue) { for (int i = 0; i < 400; i++) { System.Threading.Thread.Sleep(5); if ((dwBaseAddress = SMemory.ReadUInt(hProcess, lpAsmStub)) != INITIAL_EXIT_CODE) { break; } } } } } } if (fasm != null) { fasm.Dispose(); fasm = null; } SMemory.FreeMemory(hProcess, lpAsmStub); return(dwBaseAddress); }
/// <summary> /// Writes a value to another process' memory. /// </summary> /// <param name="dwAddress">Address at which value will be written.</param> /// <param name="Value">Value that will be written to memory.</param> /// <returns>Returns true on success, false on failure.</returns> public bool WriteUInt64(uint dwAddress, UInt64 Value) { return(SMemory.WriteUInt64(this.m_hProcess, dwAddress, Value)); }
/// <summary> /// Writes a value to another process' memory. /// </summary> /// <param name="dwAddress">Address at which value will be written.</param> /// <param name="Value">Value that will be written to memory.</param> /// <returns>Returns true on success, false on failure.</returns> public bool WriteUnicodeString(uint dwAddress, string Value) { return(SMemory.WriteUnicodeString(this.m_hProcess, dwAddress, Value)); }
/// <summary> /// Writes a value to another process' memory. /// </summary> /// <param name="dwAddress">Address at which value will be written.</param> /// <param name="Value">Value that will be written to memory.</param> /// <returns>Returns true on success, false on failure.</returns> public bool WriteObject(uint dwAddress, object Value) { return(SMemory.WriteObject(this.m_hProcess, dwAddress, Value, Value.GetType())); }
/// <summary> /// Writes a value to another process' memory. /// </summary> /// <param name="dwAddress">Address at which value will be written.</param> /// <param name="Value">Value that will be written to memory.</param> /// <param name="objType">Type of object to be written (hint: use Object.GetType() or typeof(ObjectType)).</param> /// <returns>Returns true on success, false on failure.</returns> public bool WriteObject(uint dwAddress, object Value, Type objType) { return(SMemory.WriteObject(this.m_hProcess, dwAddress, Value, objType)); }
/// <summary> /// Writes a value to another process' memory. /// </summary> /// <param name="dwAddress">Address at which value will be written.</param> /// <param name="Value">Value that will be written to memory.</param> /// <param name="nSize">Number of bytes to be written.</param> /// <returns>Returns true on success, false on failure.</returns> public bool WriteBytes(uint dwAddress, byte[] Value, int nSize) { return(SMemory.WriteBytes(this.m_hProcess, dwAddress, Value, nSize)); }
/// <summary> /// Writes a value to another process' memory. /// </summary> /// <param name="dwAddress">Address at which value will be written.</param> /// <param name="Value">Value that will be written to memory.</param> /// <returns>Returns true on success, false on failure.</returns> public bool WriteDouble(uint dwAddress, double Value) { return(SMemory.WriteDouble(this.m_hProcess, dwAddress, Value)); }