Skip to content
Muzzarino edited this page Jan 23, 2021 · 13 revisions

Getting Started

This is a small, quick article to help you get started with HMMCodes.

Table of Contents

Creating a code

HMMCodes start with an identifier for whether the program is a code or a patch.
The identifiers are the following.

Code
Patch

The identifier must be followed by a string literal for the program name.

Examples

Code "Example Code"
// Program code here
Patch "Example Patch"
// Program code here

Code vs Patch

The difference between code and patch are the following.

  • Code

    • Codes are executed every time a frame is drawn.
  • Patch

    • Patches are executed before any application code is called. Note that any writings with a read memory returns zero instead.

Optional attributes

  • by: The by attribute is used by Hedge Mod Manager to display the author of the code.

    Example

    Code "Example Code" by "Sajid"

Memory

Reading Memory

The following methods are exposed for reading from a memory address.

char[] Read(System.IntPtr address, System.IntPtr count)

T Read<T>(long address) where T : unmanaged
T Read<T>(System.IntPtr address) where T : unmanaged

Example

// Read a floating point value from the specified memory location and output it to the console.
System.Console.WriteLine(Read<float>(memoryLocation));

Writing Memory

The following methods are exposed for writing to a memory address.

void Write<T>(long address, T data) where T : unmanaged
void Write<T>(long address, params T[] data) where T : unmanaged

void WriteProtected<T>(long address, T data) where T : unmanaged
void WriteProtected<T>(long address, params T[] data) where T : unmanaged

Examples

// Write a 64bit long with the value of 1337 at the specified memory location
Write(memoryLocation, 1337L); // Implicitly Write<long>(memoryLocation, 1337);

// Write a single byte with the value of 5 at the specified memory location.
Write<byte>(memoryLocation, 5); // Implicitly cast 5 to byte
Write(memoryLocation, (byte)5); // Explicit cast; Will write the same value

// Note: For writing to a protected region of memory use WriteProtected

// Write an array of bytes at the specified memory location
Write(memoryLocation, new byte[] { 1, 3, 3, 7 }); 
// The above is the same as writing
// Write<byte>(memoryLocation, new byte[] { 1, 3, 3, 7 });

Assembly Code Injection

HMMCodes provides functions for assembling x86 or x86-64 code at runtime and injecting them.

The following functions are used for hooking assembly code.

// Instructions: The instructions to assemble.
// address: The address to insert the hook at
// behavior: The behavior of the hooked code
//// HookBehavior.Before: Call the hooked code before the original code is done.
//// HookBehavior.After: Call the hooked code after the original code is done (default).
//// HookBehavior.Replace: Completely get rid of the original code. 
void WriteAsmHook(string instructions, long address, HookBehavior behavior)
void WriteAsmHook(long address, HookBehavior behavior, params string[] instructions)

public enum HookBehavior
{
    Before, After, Replace
}

Examples

// Write an asm hook at the specified address that replaces the original code
WriteAsmHook(@"mov eax, eax
              xor eax, eax", hookAddress, HookBehavior.Replace);

// string[] overload example
// The assembled code for this would be called after the original code is done executing.
WriteAsmHook(hookAddress, HookBehavior.After, "xor eax, eax", "mov eax, eax")