Hey there, I've been playing around with the D programming language lately, which is an pretty cool alternative to c and c++ (in my opinion).
I have created a simple memory manipulation class to test how easy it is to use for such things.
There's much room for improvements, but it works
Are there any other dudes around here using D ?
memory.d :
Code:
module hydra.memory;
import core.sys.windows.windows;
import imports.win32;
import std.string;
class memory
{
// ----------------------------------------------------------------------
// Constructors and Destructors
/**
* Destructor
*/
~this()
{
if(m_isAttached)
{
closeProcess();
}
}
// ----------------------------------------------------------------------
// Open Process
/**
* Opens a Process for editing
*
* Params:
* processId = the ID of the Process
*
* Throws: Exception on failure
*/
public void openProcess(uint processId)
{
if(!m_isAttached)
{
m_processHandle = OpenProcess(ProcessAccess.AllAccess, 0, processId);
if(!m_processHandle)
{
throw new Exception(std.string.format("Can't open Process with ID: %s -- Error: %s", processId, GetLastError()));
}
scope(success)
{
m_processId = processId;
m_isAttached = true;
}
scope(failure)
{
if(m_processHandle)
{
imports.win32.CloseHandle(m_processHandle);
}
}
}
else
{
closeProcess();
openProcess(processId);
}
}
// ----------------------------------------------------------------------
// Read and Write Memory
/**
* Writes the data to memory at the specified address
*
* Params:
* address = the memory address you want to read from
* value = the data you want to write
*
* Throws: Exception on failure
*/
void write(T)(DWORD address, T value)
{
if(!m_isAttached)
throw new Exception("Not attached to Process");
PDWORD bytesRead;
if(!WriteProcessMemory(cast(HANDLE)m_processHandle, cast(LPVOID)address, cast(LPCVOID)&value, cast(SIZE_T)(T.sizeof), cast(SIZE_T*)&bytesRead))
throw new Exception(std.string.format("Can't write memory at: %s -- Error: %s", address, GetLastError()));
}
/**
* Writes a char array to the specified address
*
* Params:
* address = the memory address you want to read from
* value = the string you want to write
*
* Throws: Exception on failure
*/
void writeString(DWORD address, char[1024] value)
{
if(!m_isAttached)
throw new Exception("Not attached to Process");
PDWORD bytesRead;
if(!WriteProcessMemory(cast(HANDLE)m_processHandle, cast(LPVOID)address, cast(LPCVOID)&value, cast(SIZE_T)(value.sizeof), cast(SIZE_T*)&bytesRead))
throw new Exception(std.string.format("Can't write memory at: %s -- Error: %s", address, GetLastError()));
}
/**
* Reads memory at the specified address
*
* Params:
* address = the memory address you want to read from
*
* Throws: Exception on failure
*/
T read(T)(DWORD address)
{
if(!m_isAttached)
throw new Exception("Not attached to Process");
T data;
PDWORD bytesRead;
if(!ReadProcessMemory(cast(HANDLE)m_processHandle, cast(PCVOID)address, cast(PVOID)&data, cast(DWORD)T.sizeof, cast(PDWORD)&bytesRead))
throw new Exception(std.string.format("Can't read memory at: %s -- Error: %s", address, GetLastError()));
return data;
}
/**
* Reads a char array at the specified address from memory
*
* Params:
* address = the memory address you want to read from
*
* Throws: Exception on failure
*/
char[1024] readString(DWORD address)
{
if(!m_isAttached)
throw new Exception("Not attached to Process");
char[1024] data;
PDWORD bytesRead;
if(!ReadProcessMemory(cast(HANDLE)m_processHandle, cast(PCVOID)address, cast(PVOID)&data, cast(DWORD)1024, cast(PDWORD)&bytesRead))
throw new Exception(std.string.format("Can't read memory at: %s -- Error: %s", address, GetLastError()));
return data;
}
/**
* Closes the open Process
*/
private void closeProcess()
{
if(m_isAttached)
{
if(!imports.win32.CloseHandle(m_processHandle))
throw new Exception(std.string.format("Can't close Process -- Error: %s", GetLastError()));
scope(success)
{
m_isAttached = false;
m_processId = 0;
}
}
}
private bool m_isAttached;
private uint m_processId;
private HANDLE m_processHandle;
}
win32.d :
Code:
module imports.win32;
import core.sys.windows.windows;
extern(Windows)
{
// ----------------------------------------------------------------------
// Vartypes
alias const(void)* PCVOID, LPCVOID;
// ----------------------------------------------------------------------
// Functions
HANDLE OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId);
BOOL ReadProcessMemory(HANDLE hProcess, LPCVOID lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesRead);
BOOL WriteProcessMemory(HANDLE hProcess, LPVOID lpBaseAddress, LPCVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesWritten);
BOOL CloseHandle(HANDLE);
// ----------------------------------------------------------------------
// Enums
enum ProcessAccess : DWORD
{
CreateThread = 0x0002,
SetSessionId = 0x0004,
VmOperation = 0x0008,
VmRead = 0x0010,
VmWrite = 0x0020,
DupHandle = 0x0040,
CreateProcess = 0x0080,
SetQuota = 0x0100,
SetInformation = 0x0200,
QueryInformation = 0x0400,
SuspendResume = 0x0800,
QueryLimitedInformation = 0x1000,
Synchronize = 0x100000,
Delete = 0x00010000,
ReadControl = 0x00020000,
WriteDac = 0x00040000,
WriteOwner = 0x00080000,
StandardRightsRequired = 0x000F0000,
AllAccess = StandardRightsRequired | Synchronize | 0xFFFF
}
}
Usage:
Code:
module main;
import std.stdio;
import hydra.memory;
void main(string[] args)
{
memory mem = new memory();
try
{
mem.openProcess(17484);
mem.read!(int)(0x1212);
}
catch(Exception ex)
{
writeln(ex.msg);
writeln(ex.info);
}
stdin.readln();
}
Feel free to criticize as much as you can