i want to edit an active app (edit a memory address),
on address 00498D45 i want to edit its value
currect value :
MOV BYTE PTR SS:[EBP-423],7
to
updated value:
MOV BYTE PTR SS:[EBP-423],8
what i got till now is this (searched about it on the net and this how far i got):
thanks in advance!
using System.Runtime.InteropServices;
[Flags]
public enum ProcessAccessFlags : uint
{
All = 0x001F0FFF,
Terminate = 0x00000001,
CreateThread = 0x00000002,
VMOperation = 0x00000008,
VMRead = 0x00000010,
VMWrite = 0x00000020,
DupHandle = 0x00000040,
SetInformation = 0x00000200,
QueryInformation = 0x00000400,
Synchronize = 0x00100000
}
[DllImport("kernel32.dll")]
private static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, int dwProcessId);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, out int lpNumberOfBytesWritten);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [Out] byte[] lpBuffer, int dwSize, out int lpNumberOfBytesRead);
[DllImport("kernel32.dll")]
public static extern Int32 CloseHandle(IntPtr hProcess);
Process process = Process.GetProcessesByName("My Apps Name").FirstOrDefault();
public static bool WriteMemory(Process process, int address, long value, out int bytesWritten)
{
IntPtr hProc = OpenProcess(ProcessAccessFlags.All, false, process.Id);
byte[] val = BitConverter.GetBytes(value);
bool worked = WriteProcessMemory(hProc, new IntPtr(address), val, (UInt32) val.LongLength, out bytesWritten);
CloseHandle(hProc);
return worked;
}
From your other question:
WriteMemory(Process process,00498D45 , MOV BYTE PTR SS:[EBP-423],8)
There are so many problems with this, I don't know where to begin. First of all, that's not anywhere near correct C# syntax.
You're calling a function, but you have Process there like it's a signature.
00498D45 is not a valid constant in any base. If you mean hex, (which you probably do since you're dealing with addresses) then like all other C-like languages, that should be expressed as 0x00498D45.
That's x86 assembly code in ASCII (but it's not in a string, you just have a mess). You can't just plop ASCII assembly code into another process's address space!
Perhaps you should do a little more research on how compilation, and assembly work when building a program, and the guts of what your CPU is actually doing when it's executing a program. Also, I recommend reading through the sample code you've very obviously taken from somewhere and try to understand it. You'll be way better off learning what's going on, than asking everyone to help fix the stuff you've cobbled together. </rant>
Anyway, after you assemble your code, it looks like this (re dis-assembled):
C68559FEFFFF08 mov byte [ebp-0x1a7],0x8
That means that your instruction is actually the string of bytes C6 85 59 FE FF FF 08. So that is what you need to write into your target application.
This is the basis of what you're trying to do:
byte[] new_instr = new byte[] {0xC6, 0x85, 0x59, 0xFE, 0xFF, 0xFF, 0x08};
IntPtr target_addr = (IntPtr)0x00498D45;
int bytesWritten;
WriteProcessMemory(hProcess, target_addr, new_instr, (UInt32)new_instr.Length, out bytesWritten);
The WriteMemory memory function you've copy-and-pasted won't help you here. The problem is, it only writes a long which is 4 bytes. You need to write 7 bytes. So you'll either have to modify that function to use a byte[] parameter, or do it yourself.
I admire your ambition, but you should really start a bit lower. Write some C# code to get yourself familiar with programming in a C-like language. Then write some C to get familiar with crashing when you don't do things perfectly. Then try dabbling in assembly - perhaps writing small inline pieces into your C code. Finally then, you'll be ready to go hacking around the instructions of other running processes.
You can use an injection library like MemorySharp (I'm the author). All these functions are wrapped within a handy API, integrating an assembler (FASM syntax). Thus this piece of code perform what you want :
using (var m = new MemorySharp(ApplicationFinder.FromProcessName("My App").First()))
{
m.Assembly.Inject("MOV BYTE [EBP-423],8", new IntPtr(0x00498D45));
}
Related
I have an error with reading the memory address of the game, where:
my code is this
public partial class MainWindow: Window
{
[DllImport ("kernel32.dll")]
public static extern IntPtr OpenProcess (int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
[DllImport ("kernel32.dll")]
public static extern bool ReadProcessMemory (int hProcess, int lpBaseAddress, byte [] lpBuffer, int dwSize, ref int lpNumberOfBytesRead);
const int PROCESS_WM_READ = 0x0010;
public MainWindow ()
{
arguments dir = new arguments ();
Process process = Process.GetProcessesByName (dir.proccessname) [0];
IntPtr processHandle = OpenProcess (PROCESS_WM_READ, false, process.Id);
int bytesRead = 0;
byte [] buffer = new byte [4];
ReadProcessMemory ((int) processHandle, dir.heal_Act, buffer, buffer.Length, ref bytesRead);
}
however, nothing reading appears:
in cheat engine read me the values
Read address with Cheat Engine
Where in the image appears the reading of the memory address and finally the value contained with 4 bytes in size
Read address with Cheat Engine
In addition, I do not know how the summation of the address is as shown in box 2 to obtain the contained value.
they could help me to propose the reading with the indicated address, since zero appears.
You need to run your process as administrator and you should compile this for the same architecture as the target process. If you're targetting x86, compile as x86.
Keep in mind your ReadProcessMemory define only takes 4 byte addresses as arguments, you will want to use IntPtr for the addresses so when you someday switch to x64 the args will be large enough for 64 bit pointers.
If these things don't solve your problem then you're offsets or addresses are wrong. In which case the best thing to do is to use the Visual Studio Debugger and compare what you see against what you see in Cheat Engine.
Also in your PROCESS_WM_READ you have a 'W' instead of a 'V'.
How do I monitor current ECX register in C# at given ASM opcode?
Say, I have a:
FF8.exe+69DD8 - push ecx
Using any ready debugger I can do a breakpoint at given opcode and watch registers.
But I need to make an automation software to:
Catch every time 'push ecx' is called and add it to table with the time it was called to know how often is it called.
It's something like cut-scene with different sounds being played, and we need to know what's the time the sounds are played, one after another
Why I can't use ready softwares for this?
Because when I breakpoint 'push ecx', (note: ecx register) and then step over I lose whole timing. I need to do a table with detailed times in which this opcode is accesed.
After four years I am getting back to respond to my own question- Yes, we have to create our own debugger.
It's as simple as calling P/Invoke:
[DllImport("kernel32.dll")]
public static extern bool DebugActiveProcess(int dwProcessId);
Get process id (pId) and call DebugActiveProcess:
Process[] processes = Process.GetProcessesByName(args[0]);
bool bAttached = pinvokes.DebugActiveProcess(processes[0].Id);
Create new struct of DEBUG_EVENT - it would contain all the data about breakpoint
Wait for debug event in a while loop:
WaitForDebugEvent(ref debug, 0xFFFFFFFF);
The breakpoint 0xCC opcode will trigger the EXCEPTION_BREAKPOINT. You now have the threadId associated with given exception. You have to now get the thread context by GetThreadContext- the CONTEXT structure will now contain CPU registers including ECX. You just need to add p/invoke for GetThreadContext and structure for CONTEXT. Full structure and an example can be seen here: http://www.pinvoke.net/default.aspx/kernel32/GetThreadContext.html
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool GetThreadContext(IntPtr hThread, ref CONTEXT lpContext);
The process code will break on every debugging event even on DLL_LOAD. To set a breakpoint at given address you have to actually write an INT 3 opcode. To do that you have to open process in R/W and inject 0xCC to process memory. Use OpenProcess p/invoke and WriteProcessMemory p/invoke:
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr OpenProcess(
ProcessAccessFlags processAccess,
bool bInheritHandle,
int processId
);
public static IntPtr OpenProcess(Process proc, ProcessAccessFlags flags)
{
return OpenProcess(flags, false, proc.Id);
}
[Flags]
public enum ProcessAccessFlags : uint
{
All = 0x001F0FFF,
Terminate = 0x00000001,
CreateThread = 0x00000002,
VirtualMemoryOperation = 0x00000008,
VirtualMemoryRead = 0x00000010,
VirtualMemoryWrite = 0x00000020,
DuplicateHandle = 0x00000040,
CreateProcess = 0x000000080,
SetQuota = 0x00000100,
SetInformation = 0x00000200,
QueryInformation = 0x00000400,
QueryLimitedInformation = 0x00001000,
Synchronize = 0x00100000
}
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool WriteProcessMemory(
IntPtr hProcess,
IntPtr lpBaseAddress,
byte[] lpBuffer,
Int32 nSize,
out IntPtr lpNumberOfBytesWritten);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool WriteProcessMemory(
IntPtr hProcess,
IntPtr lpBaseAddress,
[MarshalAs(UnmanagedType.AsAny)] object lpBuffer,
int dwSize,
out IntPtr lpNumberOfBytesWritten);
Now we have everything required to open, write opcode and break when any thread arrive on that position:
IntPtr procHwnd = pinvokes.OpenProcess(processes[0], pinvokes.ProcessAccessFlags.All);
WriteProcessMemory(procHwnd, new IntPtr(0x469DD8), new byte[] { 0xCC }, 1, out IntPtr lpnum);
the lpAddress should be absolute virtual address- that means that in the question there's FF8.exe+69DD8, so we need to get IMAGE_BASE for selected module which in this case is "FF8.exe" and then add 0x69DD8 to that IMAGE_BASE. Naturally every 32-bit non ASLR processes have IMAGE_BASE set at 0x400000. For ASLR activated processes you have to get process modules and get the BaseAddress like this:
foreach(var mod in processes[0].Modules)
{
if ((mod as ProcessModule).ModuleName == args[3])
{
image_base = (mod as ProcessModule).BaseAddress;
break;
}
}
where args[3] == "FF8.exe"- this should return 0x400000 for non-ASLR processes on 32bit
I have made a method that will read a multi-pointer by providing the wanted offsets + the start adress. (Code below). To summarize, Im trying to streamline this method and below I will explain my problem.
I have been strugling around with the conversion. The parameter is an IntPtr and the output of a read adress is an byte array, my first idea was: "Convert Byte array to IntPtr, reprocess it and finally convert the last read adress into a int32 (since the last adress is not a pointer it will never be read so converting here to Int32 should be allright)",
However that did not give a nice result. So currently Im stuck with the solution of converting Byte array to Int32, then Int32 to IntPtr. People do say that the bitconverter is a bad approach because it might cause issues on 64-bit platforms and I do also believe there is an approach that may give a better performence (since Im converting an object 2 times).
Finally if anyone think it would be possible to make a similar function in C++ and then P/Invoke it in C# (I guess it would be more efficient that way?) please tell me. (Im trying to adapt my programming knowledges. And find combination of languages very interesting)
[DllImport("kernel32.dll", EntryPoint = "ReadProcessMemory")]
public static extern Int32 ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress,
[In, Out] byte[] buffer, Int32 sizeout, out IntPtr lpNumberOfBytesRead);
public Int32 ReadBytes(IntPtr Handle, IntPtr Address, int[] Offsets, int BytesToRead = 4)
{
IntPtr ptrBytesRead;
byte[] value = new byte[BytesToRead];
ReadProcessMemory(Handle, Address, value, BytesToRead, out ptrBytesRead);
//Read Offsets
for (int i = 0; i < Offsets.Length; i++)
{
ReadProcessMemory(Handle,
new IntPtr(BitConverter.ToInt32(value, 0) + Offsets[i]),
value,
BytesToRead,
out ptrBytesRead);
}
return BitConverter.ToInt32(value, 0);
}
Any ideas to streamline this method would be very well appreciated! Thanks on advance!
As #usr stated, the performance of the code will be entirely dominated by the calls to ReadProcessMemory. You should not expect to improve the performance from its current level.
However, you can make the code much easier to read by avoiding byte arrays and BitConverter. Like this:
[DllImport("kernel32.dll", SetLastError = true)]
public static extern int ReadProcessMemory(
IntPtr hProcess,
IntPtr lpBaseAddress,
out IntPtr lpBuffer,
IntPtr nSize,
out IntPtr lpNumberOfBytesRead
);
private static IntPtr ReadProcessPointer(IntPtr hProcess, IntPtr Address)
{
IntPtr result;
IntPtr NumberOfBytesRead;
if (ReadProcessMemory(hProcess, Address, out result, (IntPtr)IntPtr.Size, out NumberOfBytesRead) == 0)
throw new Win32Exception();
return result;
}
public static IntPtr FollowPointers(IntPtr hProcess, IntPtr Address, int[] Offsets)
{
IntPtr ptr = ReadProcessPointer(hProcess, Address);
for (int i = 0; i < Offsets.Length; i++)
ptr = ReadProcessPointer(hProcess, ptr + Offsets[i]);
return ptr;
}
I'm working on application SFX / Protector in C# and i want the protected assembly to be executed from a byte array instead of writing it to hard disk, in order to be much harder for reverse engineering.
I have a program within a byte array ( which have a valid entry point ) and i want to execute it.
I found a similar question on this website on how can i do that, i know this can be done using the code snippet below but can someone please guide me on how can i run a program from a byte array using this ?
technically he below code let me do this :
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace DynamicX86
{
class Program
{
const uint PAGE_EXECUTE_READWRITE = 0x40;
const uint MEM_COMMIT = 0x1000;
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
private delegate int IntReturner();
static void Main(string[] args)
{
List<byte> bodyBuilder = new List<byte>();
bodyBuilder.Add(0xb8);
bodyBuilder.AddRange(BitConverter.GetBytes(42));
bodyBuilder.Add(0xc3);
byte[] body = bodyBuilder.ToArray();
IntPtr buf = VirtualAlloc(IntPtr.Zero, (uint)body.Length, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
Marshal.Copy(body, 0, buf, body.Length);
IntReturner ptr = (IntReturner)Marshal.GetDelegateForFunctionPointer(buf, typeof(IntReturner));
Console.WriteLine(ptr());
}
}
}
How can i implement this answer to run a program from array of bytes. I can't understand exactly what i can do with this code. Please help
This is a link where i found this answer :
Is it possible to execute an x86 assembly sequence from within C#?
Anyhelp would be highly appreciated.
What is the valid entry point and what is it's signature? How do you get these bytes from? Do you generate IL? If you do, perhaps it might be easier to simply do this.
What the code above is trying to do is allocate unmanaged memory, fill it with x86 instructions and then have .NET create a delegate from this "function pointer" and execute it - which is different from what you want.
I am using the FileRead API.
I used Windows 7 x64 and my code worked good and correct.
Now I installed a new Windows 7 x86 and VS2008 teamsuit and .NET 2, 3+SP1+SP2, 3.5, 3.5.1.
I run my code as Administrator but still encounter the follwoing error:
AccessViolationException(Attempted to read or write protected memory. This is often an indication that other memory is corrupt.)
int nread = 0;
uint handle;
byte[] buff = new byte[1024];
string driveRoot = string.Concat("\\\\.\\", driveLetter);
uint hRoot = CreateFile(driveRoot,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
IntPtr.Zero,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
IntPtr.Zero);
if (hRoot != -1)
handle = ReadFile(hRoot, buff, 1024, nread, new System.Threading.NativeOverlapped());
While I'm no C# guru, it appears to me that you're invoking ReadFile() with wrong parameters.
The 4th parameter must be a pointer to an integer that will receive the number of bytes read. You supply the integer itself (nread), not its address (&nread).
And unless you want asynchronous file I/O, the last parameter to ReadFile() must be a NULL pointer (or just 0).
See this example on MSDN.
I suspect that the main problem with your code is that you are requesting overlapped I/O but supplying a buffer that ceases to exist when ReadFile returns. It works on some systems an not others because the system decides whether or not to perform the operation asynchronously, and it may choose not to do async on one system and choose differently on another.
I'm sure you don't want overlapped I/O so you should simply pass NULL to the final parameter of ReadFile.
On the other hand, perhaps your code isn't working at all on the x64 system and never gets as far as an AV. Your handle types are mis-declared as 32 bit integers.
There are many other minor problems with your code. Here's an edited version of the code that corrects these errors. The P/invoke signatures were taken from pinvoke.net.
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr CreateFile(
string lpFileName,
uint dwDesiredAccess,
uint dwShareMode,
IntPtr SecurityAttributes,
uint dwCreationDisposition,
uint dwFlagsAndAttributes,
IntPtr hTemplateFile
);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool ReadFile(
IntPtr hFile,
[Out] byte[] lpBuffer,
uint nNumberOfBytesToRead,
out uint lpNumberOfBytesRead,
IntPtr lpOverlapped
);
static void Main(string[] args)
{
string physicalDrive = #"\\.\PhysicalDrive0";
IntPtr hFile = CreateFile(
physicalDrive,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
IntPtr.Zero,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
IntPtr.Zero
);
if (hFile.ToInt64() != INVALID_HANDLE_VALUE)
{
byte[] buff = new byte[1024];
uint nread;
if (ReadFile(hFile, buff, (uint)buff.Length, out nread, IntPtr.Zero))
Console.WriteLine("Read successful");
}
}
To summarise the errors in your code:
Incorrect use of 32 bit integers to store handles.
Your P/invoke declaration of ReadFile declares the lpNumberOfBytesRead incorrectly.
ReadFile does not return a handle, it returns a boolean indicating success of the function call.
Use of overlapped I/O which you do not want, and which cannot work with a marshalled byte[] buffer.
You must never call GetLastError from managed code (you did so in code shown in a comment). Instead call Marshal.GetLastWin32Error. The reasons are explained in the documentation for that method.