If there is a project in which you need to assemble code in a C# project, you found the right place. I’ll be using the flatassembler (https://flatassembler.net/) and it’s FASM.dll (which you can download in the forum https://board.flatassembler.net/topic.php?t=6239) to achieve this.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
// remove fixed(stackalloc) if buffer gets to big to fit on the stack or if safe context is needed, it is only used for performance here
fixed (byte* pBytes = stackalloc byte[64]) // 64 is the size of the buffer for the assembled instructions
{
    if (FasmAssemble("use32\nXOR EAX,EBX", pBytes, 64, 16, IntPtr.Zero) == 0)
    {
        FasmStateOk state = *(FasmStateOk*)pBytes;
        // assembled intructions will be in state.OutputData with the size of state.OutputLength
    }
    else
    {
        FasmStateError stateError = *(FasmStateError*)pBytes;
        // look at stateError.ErrorCode
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/// <summary>
/// FASM assembler library is used to assembly our injection stuff.
/// </summary>
/// <param name="szSource">Assembly instructions.</param>
/// <param name="lpMemory">Output bytes</param>
/// <param name="nSize">Output buffer size</param>
/// <param name="nPassesLimit">FASM pass limit</param>
/// <param name="hDisplayPipe">FASM display pipe</param>
/// <returns>FASM status struct pointer</returns>
[DllImport("FASM.dll", EntryPoint = "fasm_Assemble", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
private static extern int FasmAssemble(string szSource, byte* lpMemory, int nSize, int nPassesLimit, IntPtr hDisplayPipe);

/// <summary>
/// Get FASM assembler version.
/// </summary>
/// <returns>Version</returns>
[DllImport("FASM.dll", EntryPoint = "fasm_GetVersion", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
private static extern int FasmGetVersion();

[StructLayout(LayoutKind.Sequential)]
public unsafe struct FasmStateOk
{
    public int Condition { get; set; }

    public uint OutputLength { get; set; }

    public IntPtr OutputData { get; set; }
}

[StructLayout(LayoutKind.Sequential)]
public struct FasmStateError
{
    public int Condition { get; set; }

    public int ErrorCode { get; set; }
}