I am trying to write to process memory, so I copied the code from a video.
But this video does not show the function "ReadInt32", can someone send me to finally be able to run this application?
ReadInt32(process, (IntPtr)address)
public static long GetRealAddress(IntPtr process, IntPtr baseAddress, int[] offsets)
{
var address = baseAddress.ToInt64();
foreach (var offset in offsets)
{
address = ReadInt32(process, (IntPtr)address) + offset;
}
return address;
}
Error Highlighted in Code:
Pointer: (The type is float)
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool ReadProcessMemory(IntPtr handle, IntPtr baseAddress,
byte[] buffer, int size, out IntPtr lpNumberOfBytesRead);
public static int ReadInt32(IntPtr processHandle, IntPtr address)
{
byte[] buffer = new byte[4];
ReadProcessMemory(processHandle, address,
buffer, buffer.Length, out IntPtr bytesRead);
// if this gives the wrong value:
// Array.Reverse(buffer);
var myInt = BitConverter.ToInt32(buffer, 0);
return myInt;
}
Related
I'm programming a local streaming service. And I need to use two different Process for Server Software (Do not ask why e.e). The "child" Process Makes The Hardwork and I need to get results, but the workflow are in milliseconds ('cause is a videogames stream service). I tried with: Process.OutputDataReceived EventHandler, but the results are a lot of text and the Console takes valious time to write.
Also I tried with FileStream, But by logic and research I knew that using MemoryStream is faster to store and obtain data. The problem is that I do not know how to obtain the data that the child process saves.
The next code is not bad, but it's just to let them know that I also try with that code:
Parent Process:
public class MemoryRead
{
Process process = null;
int bufferSize = 256000;
public MemoryRead(Process Process, int BufferSize){
process = Process;
bufferSize = BufferSize;
}
const int PROCESS_WM_READ = 0x0010;
[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);
public string GetString(int BytesAdress = 0x0046A3B8)
{
IntPtr processHandle = OpenProcess(PROCESS_WM_READ, false, process.Id);
int bytesRead = 0;
byte[] buffer = new byte[bufferSize];
ReadProcessMemory((int)processHandle, BytesAdress, buffer, buffer.Length, ref bytesRead);
return Encoding.UTF8.GetString(buffer);
}
}
Child Process:
GCHandle handler = GCHandle.Alloc(VideoData, GCHandleType.Pinned);
IntPtr address = handler.AddrOfPinnedObject();
Console.WriteLine((address.ToString()));
The Child Process returns a int "address", and I Get that with Process.OutputDataReceived EventHandler to Call MemoryRead.GetString(), but that returns null, Basically as if the address did not exist. I just want more options, also if they have nothing to do with MemoryStream.
Need to load this C++ method from a DLL in CSharp and I'm wondering which datatypes I have to use?
WORD FunA (BYTE Num, BYTE *pFrameTX, DWORD nbbitTX, BYTE
*pFrameRX, DWORD *pnbbitRX)
My first approach was:
[DllImport("Example.Dll")]
public static extern UInt16 FunA(byte Num, Byte[] pFrameTX, UInt32 nbbitTX, ref Byte[] pFrameRX, ref UInt32 pnbbitRX);
Byte[] toSend = new Byte[1], toReceive = new Byte[1024];
toSend[0] = 0x26;
UInt32 numberOfBitsReceived = 0;
FunA(Convert.ToByte(1), toSend, 0, ref toReceive, ref numberOfBitsReceived);
What's wrong here? Can someone help me to find the correct datatypes and calling usage?!
Thanks!
Guess you missed the ref modifier in front of pFrameTX.
[DllImport("Example.Dll")]
public static extern UInt16 FunA(byte Num, ref Byte[] pFrameTX, UInt32
nbbitTX, ref Byte[] pFrameRX, ref UInt32 pnbbitRX);
[DllImport("Example.Dll")]
public static extern UInt16 FunA(byte Num, IntPtr pFrameTX, UInt32
nbbitTX, IntPtr pFrameRX, ref UInt32 pnbbitRX);
// ...
Byte[] toSend = new Byte[1], toReceive = new Byte[1024];
toSend[0] = 0x26;
UInt32 numberOfBitsReceived = 0;
// reserve unmanaged memory for IntPtr
IntPtr toSendPtr = Marshal.AllocHGlobal(Marshal.SizeOf(toSend[0])*toSend.Length),
toReceivePtr = Marshal.AllocHGlobal(Marshal.SizeOf(toReceive[0])*toReceive.Length);
// copy send buffer to Unmanaged memory
Marshal.Copy(toSend, 0, toSendPtr, toSend.Length);
// call C++ DLL method
FunA(Convert.ToByte(1), toSendPtr, 0, toReceivePtr, ref numberOfBitsReceived);
// copy receive buffer from Unmanaged to managed memory
Marshal.Copy(toReceivePtr, toReceive, 0, numberOfBitsReveived/8);
// free memory
Marshal.FreeHGlobal(toSendPtr);
Marshal.FreeHGlobal(toReceivePtr);
I am reading directly from a disk using C# and pinvoking the kernel32 ReadFile method.i want just read a particular sector for save time but ReadFile read from first to N sector. How can read only own sector with my choice?
[StructLayout(LayoutKind.Sequential)]
public struct OVERLAPPED
{
public uint Internal;
public uint InternalHigh;
public uint Offset;
public uint OffsetHigh;
public int hEvent;
}
[DllImport("kernel32", SetLastError = true)]
static extern int CreateFile(string filename, uint desiredAccess, uint shareMode, IntPtr attributes, uint creationDisposition, uint flagsAndAttributes, IntPtr templateFile);
[DllImport("kernel32", SetLastError = true)]
public static extern Boolean CloseHandle(int handle);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern Boolean ReadFile(IntPtr hFile, Byte[] buffer, UInt32 BytesToRead, ref UInt32 BytedRead, OVERLAPPED OverLapped);
static int EIGHT_K = 8192;
static int FIVE_TWELVE_BYTES = 512;
static uint GENERIC_READ = 0x80000000;
static uint OPEN_EXISTING = 3;
static uint FILE_SHARE_READ = 1;
static uint FILE_SHARE_WRITE = 2;
[STAThread]
private void button1_Click(object sender, EventArgs e)
{
int fileHandle = 0;
bool returnVal = true;
try
{
// Open the device specified (Using the boot partition)
string deviceName = #"\\.\f:";
fileHandle = CreateFile(deviceName, GENERIC_READ,FILE_SHARE_READ | FILE_SHARE_WRITE, (IntPtr)0, OPEN_EXISTING, 0,(IntPtr)0);
if (fileHandle != -1)
{
Byte[] sector = new Byte[EIGHT_K];
UInt32 bytesRead = (uint)EIGHT_K;
OVERLAPPED ol = new OVERLAPPED();
// Can't get a FileStream ctor to work so I am using Win32 API ReadFile
bool worked = ReadFile((IntPtr)fileHandle, sector, (uint)EIGHT_K, ref bytesRead, ol);
return;
}
}
catch (Exception ex)
{
return;
}
finally
{
CloseHandle(fileHandle);
}
return;
}
I want to mark the DVD till required Original DVD to run the program.
Your OVERLAPPED struct is declared poorly and is incorrect in a 64 bit process. But in any case you don't need it. You are not performing overlapped I/O. Which is just as well because the declaration of ReadFile is incorrect. That function wants a pointer to an OVERLAPPED struct. You pass it by value.
In any case, you just don't need to consider overlapped I/O. So fix this issue by deleting the OVERLAPPED struct declaration from your code. And declare ReadFile like this:
[DllImport("kernel32.dll", SetLastError = true)]
public static extern Boolean ReadFile(IntPtr hFile, Byte[] buffer,
UInt32 BytesToRead, out UInt32 BytedRead, IntPtr Overlapped);
Pass IntPtr.Zero as the Overlapped parameter. And do make sure that you check the return value of ReadFile for an error.
The next step is to seek to a location in the file. Use SetFilePointerEx for that.
DllImport("kernel32.dll")]
static extern bool SetFilePointerEx(IntPtr hFile, long liDistanceToMove,
out long lpNewFilePointer, uint dwMoveMethod);
Consult the documentation for SetFilePointerEx to work out how to call this function.
Since you are using direct disk access, you will of course need to align the reads to sector boundaries.
I am using the method below to read bytes in memory. I want to read values in memory addresses which are very near each other. Previously I have been making individual calls for each byte in memory and adding the result to an array using a for loop. This became really inefficient, so instead I want to adapt the below code to read a large block of memory and then try to do an itteration through the array to pull out the bytes I want. I have spent a bit of time trying to work it out, but really struggling. FYI, this method reads a pointer, and then if that value is a pointer, it reads that pointer, and so forth until it gets to the static address then reads the byte value at that address.
[DllImport("kernel32", EntryPoint = "ReadProcessMemory")]
private static extern byte ReadProcessMemoryByte(int Handle, int Address, ref byte Value, int Size, ref int BytesRead);
public static byte ReadPointerByte(string EXENAME, int Pointer, int[] Offset)
{
byte Value = 0;
checked
{
try
{
Process[] Proc = Process.GetProcessesByName(EXENAME);
if (Proc.Length != 0)
{
int Bytes = 0;
int Handle = OpenProcess(PROCESS_ALL_ACCESS, 0, Proc[0].Id);
if (Handle != 0)
{
foreach (int i in Offset)
{
ReadProcessMemoryInteger((int)Handle, Pointer, ref Pointer, 4, ref Bytes);
Pointer += i;
}
ReadProcessMemoryByte((int)Handle, Pointer, ref Value, 2, ref Bytes);
CloseHandle(Handle);
}
}
}
catch
{ }
}
return Value;
}
What I have so far:
private void label1_Click(object sender, EventArgs e)
{
int[] valuesSeperated[200];
List<byte> PreArray = new List<byte>();
Process[] test = Process.GetProcessesByName("MyProcess"); //Get process handle
int baseAddress = test[0].MainModule.BaseAddress.ToInt32(); //Get base address
byte ReadX = MyClass.ReadPointerByte("MyProcess", BaseAddress, new int[] { 0xc, 0x0, 0x2 }); //call memory reading function (including memory offsets)
PreArray.Add(ReadX);
byte[] PreArrayToInt = PreArray.ToArray();
int[] MYConvertedBytes = PreArray ToInt.Select(x => (int)x).ToArray();
foreach (int i in MYConvertedBytes)
{
valuesSeperated // (don't really know what to do here, if the read was successful I would have a long number at [0], so now need to seperate these as if I had read each one in memory one at a time.
}
string TestString = MYConvertedBytes[0].ToString();
label1.Text = TestString;
}
So to summarize: I don't know how to read a larger block of memory (say 200 addresses at once) using the above method. I don't know how best to extract the values from the resulting array to form a new array that has the bytes now separated. Please ask if anything is unclear, I am quite new and really want to learn so any hints/help would be really appreciated.
Your interop signature looks completely wrong to me.
The c signature is:
BOOL WINAPI ReadProcessMemory(
__in HANDLE hProcess,
__in LPCVOID lpBaseAddress,
__out LPVOID lpBuffer,
__in SIZE_T nSize,
__out SIZE_T *lpNumberOfBytesRead
);
It should be something like:
[DllImport("kernel32", EntryPoint = "ReadProcessMemory",SetLastError=true)]
private static extern unsafe bool NativeReadProcessMemory(IntPtr processHandle, IntPtr baseAddress, byte* buffer, IntPtr size, out IntPtr bytesRead);
static unsafe void ReadProcessMemory(IntPtr processHandle, IntPtr baseAddress, byte[] buffer,int start, int size)
{
fixed(byte* pBuffer=buffer)
{
IntPtr bytesRead;
if(!NativeReadProcessMemory(processHandle, baseAddress, pBuffer+start,(IntPtr)size, out bytesRead))
throw new Win32Exception(Marshal.GetLastWin32Error());
if((int)bytesRead!=size)
throw new Exception("Incomplete read");//User better exception type here
}
}
I'm trying to use the RtlGetCompressionWorkSpaceSize and RtlCompressBuffer functions in a C# project.
Here is what I have so far:
class Program
{
const uint COMPRESSION_FORMAT_LZNT1 = 2;
const uint COMPRESSION_ENGINE_MAXIMUM = 0x100;
[DllImport("ntdll.dll")]
static extern uint RtlGetCompressionWorkSpaceSize(uint CompressionFormat, out uint pNeededBufferSize, out uint Unknown);
[DllImport("ntdll.dll")]
static extern uint RtlCompressBuffer(uint CompressionFormat, byte[] SourceBuffer, uint SourceBufferLength, out byte[] DestinationBuffer,
uint DestinationBufferLength, uint Unknown, out uint pDestinationSize, IntPtr WorkspaceBuffer);
static void Main(string[] args)
{
uint dwSize = 0;
uint dwRet = 0;
uint ret = RtlGetCompressionWorkSpaceSize(COMPRESSION_FORMAT_LZNT1 | COMPRESSION_ENGINE_MAXIMUM, out dwSize, out dwRet);
IntPtr pMem = Marshal.AllocHGlobal((int)dwSize);
byte[] buffer = new byte[1024];
byte[] outBuf = new byte[1024];
uint destSize = 0;
ret = RtlCompressBuffer(COMPRESSION_FORMAT_LZNT1 | COMPRESSION_ENGINE_MAXIMUM, buffer, 1024, out outBuf, 1024, 0, out destSize, pMem);
Console.Write(ret.ToString());
Console.Read();
}
}
RtlGetCompressionWorkSpaceSize works since it returns 0 (NT success code) but when I call RtlCompressBuffer I get a Memory Access Violation error.
EDIT: With help from David's answer I've fixed the issue and the correct code is below.
const ushort COMPRESSION_FORMAT_LZNT1 = 2;
const ushort COMPRESSION_ENGINE_MAXIMUM = 0x100;
[DllImport("ntdll.dll")]
static extern uint RtlGetCompressionWorkSpaceSize(ushort CompressionFormat, out uint pNeededBufferSize, out uint Unknown);
[DllImport("ntdll.dll")]
static extern uint RtlCompressBuffer(ushort CompressionFormat, byte[] SourceBuffer, int SourceBufferLength, byte[] DestinationBuffer,
int DestinationBufferLength, uint Unknown, out int pDestinationSize, IntPtr WorkspaceBuffer);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern IntPtr LocalAlloc(int uFlags, IntPtr sizetdwBytes);
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr LocalFree(IntPtr hMem);
internal static byte[] Compress(byte[] buffer)
{
var outBuf = new byte[buffer.Length * 6];
uint dwSize = 0, dwRet = 0;
uint ret = RtlGetCompressionWorkSpaceSize(COMPRESSION_FORMAT_LZNT1 | COMPRESSION_ENGINE_MAXIMUM, out dwSize, out dwRet);
if (ret != 0)
{
return null;
}
int dstSize = 0;
IntPtr hWork = LocalAlloc(0, new IntPtr(dwSize));
ret = RtlCompressBuffer(COMPRESSION_FORMAT_LZNT1 | COMPRESSION_ENGINE_MAXIMUM, buffer,
buffer.Length, outBuf, outBuf.Length, 0, out dstSize, hWork);
if (ret != 0)
{
return null;
}
LocalFree(hWork);
Array.Resize(ref outBuf, dstSize);
return outBuf;
}
You are very nearly there. The problem is this part of your P/invoke for RtlCompressBuffer:
out byte[] DestinationBuffer
The default marshalling for byte[] is for the array contents to marshalled in both directions, from managed to unmanaged, and then back again when the function returns. The C definition of RtlCompressBuffer is annotated with __out but that means that the array contents are __out rather than the pointer being __out.
Change your P/invoke to
byte[] DestinationBuffer
and similarly in the call to RtlCompressBuffer change out outBuf to outBuf and you should be good to go.
Be warned that your code as it stands will return an status code of STATUS_BUFFER_ALL_ZEROS so don't be tricked into thinking that this non-zero return value indicates failure.
One final point, the first parameter to both P/invokes, CompressionFormat, should be declared as ushort.