All Projects → Hitmasu → Jitex

Hitmasu / Jitex

Licence: MIT license
A library to modify MSIL and native code at runtime

Programming Languages

C#
18002 projects
smalltalk
420 projects

Labels

Projects that are alternatives of or similar to Jitex

Angelscript Jit Compiler
A Just-In-Time compiler for the AngelScript language on x86 processors.
Stars: ✭ 172 (+230.77%)
Mutual labels:  jit
Occa
JIT Compilation for Multiple Architectures: C++, OpenMP, CUDA, HIP, OpenCL, Metal
Stars: ✭ 230 (+342.31%)
Mutual labels:  jit
FastLua
Lua trace JIT compiler using LLVM-C
Stars: ✭ 22 (-57.69%)
Mutual labels:  jit
Minijit
A basic x86-64 JIT compiler written from scratch in stock Python
Stars: ✭ 185 (+255.77%)
Mutual labels:  jit
Jfs
Constraint solver based on coverage-guided fuzzing
Stars: ✭ 215 (+313.46%)
Mutual labels:  jit
Asmjit
Machine code generation for C++
Stars: ✭ 2,874 (+5426.92%)
Mutual labels:  jit
Wasm Micro Runtime
WebAssembly Micro Runtime (WAMR)
Stars: ✭ 2,440 (+4592.31%)
Mutual labels:  jit
vox
Vox language compiler. AOT / JIT / Linker. Zero dependencies
Stars: ✭ 288 (+453.85%)
Mutual labels:  jit
Cranelift
Cranelift code generator
Stars: ✭ 2,485 (+4678.85%)
Mutual labels:  jit
PowerUp
⚡ Decompilation Tools and High Productivity Utilities ⚡
Stars: ✭ 1,526 (+2834.62%)
Mutual labels:  jit
Jitboy
A Game Boy emulator with dynamic recompilation (JIT)
Stars: ✭ 190 (+265.38%)
Mutual labels:  jit
Vue Ssr Jit
A just in time compilation technique for server-side rendering
Stars: ✭ 209 (+301.92%)
Mutual labels:  jit
Lightbeam
Lightbeam has moved and now lives in the Wasmtime repository!
Stars: ✭ 253 (+386.54%)
Mutual labels:  jit
Fake
嵌入式脚本语言 Lightweight embedded scripting language
Stars: ✭ 172 (+230.77%)
Mutual labels:  jit
Suravi
Suravi is a small distribution of Ravi/Lua 5.3 with batteries such as cjson, lpeglabel, luasocket, penlight, torch7, luv, luaossl
Stars: ✭ 56 (+7.69%)
Mutual labels:  jit
Coreclr
CoreCLR is the runtime for .NET Core. It includes the garbage collector, JIT compiler, primitive data types and low-level classes.
Stars: ✭ 12,610 (+24150%)
Mutual labels:  jit
Openj9
Eclipse OpenJ9: A Java Virtual Machine for OpenJDK that's optimized for small footprint, fast start-up, and high throughput. Builds on Eclipse OMR (https://github.com/eclipse/omr) and combines with the Extensions for OpenJDK for OpenJ9 repo.
Stars: ✭ 2,802 (+5288.46%)
Mutual labels:  jit
JUDI.jl
Julia Devito inversion.
Stars: ✭ 71 (+36.54%)
Mutual labels:  jit
lc
JIT compiler for Scheme targeting x86-64 platforms
Stars: ✭ 24 (-53.85%)
Mutual labels:  jit
muparsersse
muparsersse a math parser for windows using just in time compilations of the expression
Stars: ✭ 14 (-73.08%)
Mutual labels:  jit

Jitex Jitex Build Nuget

A library to modify MSIL/Native code at runtime.

It's a library built in .NET Standard 2.0, works on all version >=.NET Core 2.0.

.NET Core (2.1 ~ 3.1) .NET 5~6 .NET Framework (4.6.1 ~ 4.8) Mono
Windows ✔️ ✔️ 🏗️ In development Not supported
Linux ✔️ ✔️ Not supported Not supported
MacOS ✔️ ✔️ Not supported​ Not supported

💚 .NET Framework as soon.


Jitex can help you replace code at runtime easily.

using System;
using Jitex;

JitexManager.AddMethodResolver(context =>
{
    if (context.Method.Name.Contains("Sum"))
        context.ResolveMethod<Func<int, int, int>>(Mul); //Replace Sum by Mul
});

int result = Sum(5, 5); //Output is 25
Console.WriteLine(result);

static int Sum(int n1, int n2) => n1 + n2;
static int Mul(int n1, int n2) => n1 * n2;

Support

Intercept call

using System;
using Jitex;

JitexManager.MethodResolver += context =>
{
    if (context.Method.Name.Contains("Sum"))
        context.InterceptCall();
};

//Every call from Sum, will be pass here.
JitexManager.Interceptor += async context =>
{
    //Get parameters passed in call
    int n1 = context.GetParameterValue<int>(0);
    int n2 = context.GetParameterValue<int>(1);

    n1 *= 10;
    n2 *= 10;

    //Override parameters value
    context.SetParameterValue(0, n1);
    context.SetParameterValue(1, n2);

    //Or we can just set return value
    context.SetReturnValue(100);
};

int result = Sum(5, 5); //Output is 100
Console.WriteLine(result);

int Sum(int n1, int n2) => n1 * n2;

Replace Method

/// <summary>
///     Take sum of 2 random numbers
/// </summary>
/// <returns></returns>
public static int SumReplace () 
{
  const string url = "https://www.random.org/integers/?num=2&min=1&max=999&col=2&base=10&format=plain&rnd=new";
  using HttpClient client = new HttpClient ();
  using HttpResponseMessage response = client.GetAsync (url).Result;
  string content = response.Content.ReadAsStringAsync ().Result;
    
  string[] columns = content.Split ("\t");
    
  int num1 = int.Parse (columns[0]);
  int num2 = int.Parse (columns[1]);
    
  return num1 + num2;
}

private static void MethodResolver (MethodContext context) 
{
  if (context.Method.Name == "Sum") {
    //Replace Sum to our SumReplace
    MethodInfo replaceSumMethod = typeof (Program).GetMethod (nameof (SumReplace));
    context.ResolveMethod (replaceSumMethod);
  }
}

Detour Method

private static void MethodResolver (MethodContext context) {
  if (context.Method.Name == "Sum") {
    //Detour by MethodInfo
    MethodInfo detourMethod = typeof (Program).GetMethod (nameof (SumDetour));
    context.ResolveDetour (detourMethod);
    //or
    context.ResolveDetour<Action> (SumDetour);

    //Detour by Action or Func
    Action<int, int> detourAction = (n1, n2) => {
      Console.WriteLine ("Detoured");
      Console.WriteLine (n1 + n2);
    };
    context.ResolveDetour (detourAction);

    //Detour by Address
    IntPtr addressMethod = default; //Address of method to execute.
    context.ResolveDetour (addressMethod);
  }
}

Replace MSIL

private static void MethodResolver (MethodContext context) 
{
  if (context.Method.Name == "Sum") {
    //num1 * num2
    byte[] newIL = {
    (byte) OpCodes.Ldarg_0.Value, //parameter num1
    (byte) OpCodes.Ldarg_1.Value, //parameter num2
    (byte) OpCodes.Mul.Value,
    (byte) OpCodes.Ret.Value
    };
      
    MethodBody body = new MethodBody (newIL, context.Method.Module);
    context.ResolveBody (body);
  }
}

Replace Native Code

private static void MethodResolver (MethodContext context) 
{
  if (context.Method.Name == "Sum") {
    Assembler assembler = new Assembler (64);

    //Replace with fatorial number:
    //int sum = num1+num2;
    //int fatorial = 1;
    //for(int i = 2; i <= sum; i++){
    //    fatorial *= i;
    //}
    //return fatorial;
    assembler.add (edx, ecx);
    assembler.mov (eax, 1);
    assembler.mov (ecx, 2);
    assembler.cmp (edx, 0x02);
    assembler.jl (assembler.@F);
    assembler.AnonymousLabel ();
    assembler.imul (eax, ecx);
    assembler.inc (ecx);
    assembler.cmp (ecx, edx);
    assembler.jle (assembler.@B);
    assembler.AnonymousLabel ();
    assembler.ret ();
      
    using MemoryStream ms = new MemoryStream ();
    assembler.Assemble (new StreamCodeWriter (ms), 0);
      
    byte[] asm = ms.ToArray ();
      
    context.ResolveNative (asm);
  }
}

Inject custom MetadataToken

You can inject a custom metadata too, in this way, you can "execute" metadatatoken not referenced in compile-time:

/// <summary>
///     Example of a external library to replace Sum.
/// </summary>
/// <remarks>
///     We replace Sum to return the PID of process running. To do this, normally we need
///     reference assembly (System.Diagnostics.Process) and class Process.
///     In this case, the original module, dont have any reference to namespace System.Diagnostics.Process.
///     As we pass the MetadataToken from Process.GetCurrentProcess().Id, its necessary resolve that manually,
///     because CLR dont have any information about that in original module.
/// </remarks>
public static class ExternLibrary
{
    private static MethodInfo _getCurrentProcess;
    private static MethodInfo _getterId;

    static ExternLibrary()
    {
        LoadAssemblyDiagnostics();
    }

    public static void Initialize()
    {
        JitexManager.AddMethodResolver(MethodResolver);
        JitexManager.AddTokenResolver(TokenResolver);
    }

    private static void LoadAssemblyDiagnostics()
    {
        string pathAssembly = Path.Combine(Directory.GetCurrentDirectory(), "../../../../", "System.Diagnostics.Process.dll");
        Assembly assemblyDiagnostics = Assembly.LoadFrom(pathAssembly);
        Type typeProcess = assemblyDiagnostics.GetType("System.Diagnostics.Process");
        _getCurrentProcess = typeProcess.GetMethod("GetCurrentProcess");
        _getterId = _getCurrentProcess.ReturnType.GetProperty("Id", BindingFlags.Public | BindingFlags.Instance).GetGetMethod();
    }

    private static void TokenResolver(TokenContext context)
    {
        if (context.TokenType == TokenKind.Method && context.Source.Name == "Sum")
        {
            if (context.MetadataToken == _getCurrentProcess.MetadataToken)
            {
                context.ResolveMethod(_getCurrentProcess);
            }
            else if (context.MetadataToken == _getterId.MetadataToken)
            {
                context.ResolveMethod(_getterId);
            }
        }
    }
    
    private static void MethodResolver(MethodContext context)
    {
        if (context.Method.Name == "Sum")
        {
            List<byte> newIl = new List<byte>();
            newIl.Add((byte)OpCodes.Call.Value);
            newIl.AddRange(BitConverter.GetBytes(_getCurrentProcess.MetadataToken));
            newIl.Add((byte)OpCodes.Call.Value);
            newIl.AddRange(BitConverter.GetBytes(_getterId.MetadataToken));
            newIl.Add((byte)OpCodes.Ret.Value);
            MethodBody methodBody = new MethodBody(newIl.ToArray(), _getCurrentProcess.Module);
            context.ResolveBody(methodBody);
        }
    }
}
static void Main (string[] args) {
    ExternLibrary.Initialize ();
    int result = Sum (1, 7);
    Console.WriteLine (result); //output is PID
}

Replace content string

private static void TokenResolver (TokenContext context) {
  if (context.TokenType == TokenKind.String && context.Content == "Hello World!")
    context.ResolveString ("H3110 W0RLD!");
}
static void Main (string[] args) {
    ExternLibrary.Initialize ();
    HelloWorld (); //output is H3110 W0RLD!
}

static void HelloWorld () {
    Console.WriteLine ("Hello World!");
}

Modules

Jitex can support modules. To create your own module, just extend JitexModule:

public class ModuleJitex : JitexModule
{
    protected override void MethodResolver(MethodContext context)
    {
        //...
    }

    protected override void TokenResolver(TokenContext context)
    {
        //...
    }
}

And load module:

JitexManager.LoadModule<ModuleJitex>();
//or...
JitexManager.LoadModule(typeof(ModuleJitex));

ASP.NET Core support

To load module in ASP.NET Core, just call UseModule in Configure (Startup.cs):

app.UseModule<ModuleJitex>();
app.UseModule<ModuleJitex1>();
app.UseModule<ModuleJitex2>();
//or
app.UseModule(typeof(ModuleJitex);

Proof of Concept

Nitter - A easy mocker for .NET

AutoMapper Patcher - A simple remover AutoMapper at runtime.

InAsm - Run assembly directly from a method.

Thanks

Replace methods was an idea to increase performance in .NET Applications. Searching a way to do that, i've found this hook implementation from @xoofx Writing a Managed JIT in C# with CoreCLR, which became core of Jitex.

Support

Logo

Icon made by iconixar from www.flaticon.com
I'm trying be better in english language too, so probably you will see some grammatical errors... Feel free to notify me.
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].