hitmasu / jitex Goto Github PK
View Code? Open in Web Editor NEWA library to modify MSIL and native code at runtime
License: MIT License
A library to modify MSIL and native code at runtime
License: MIT License
When try recompile virtual methods, they are overwriting ctor pointers.
Intercept call on "simple methods"
public [void, primitive] [instance, static] Method([NoParameters, PrimitiveParameters]){}
Intercept call when method has generic parameters.
public [instance|static] TMethod Method<TMethod>(TType parameter){}
Detour can be enable and disable by default. When some method are intercepted, Jitex can disable them, but when method are resolve by Detour, that can't be done currently.
In ResolveDetour, a DetourContext can be returned, so developers can call Enable and Disable detour from DetourContext.
When try intercept a generic method, a exception will raise:
Fatal error. Internal CLR error. (0x80131506)
at System.RuntimeMethodHandle.InvokeMethod(System.Object, System.Object[], System.Signature, Boolean, Boolean)
at System.Reflection.RuntimeMethodInfo.Invoke(System.Object, System.Reflection.BindingFlags, System.Reflection.Binder, System.Object[], System.Globalization.CultureInfo)
at System.Reflection.MethodBase.Invoke(System.Object, System.Object[])
at Jitex.Utils.MethodHelper.GetMethodFromHandle(IntPtr)
at Jitex.Intercept.CallManager..ctor(IntPtr, System.Object[] ByRef, Boolean)
at Program.Sum.Jitex.SumJitex(IntPtr, Int32, Int32)
at HelloWorldJitex.Program.Main(System.String[])
How to reproduce:
static void Main(string[] args)
{
JitexManager.AddMethodResolver(MethodResolver);
JitexManager.AddInterceptor(InterceptorCallAsync);
Sum<int>(5, 5);
}
public static int Sum<T>(int n1, int n2) => n1 + n2;
private static async ValueTask InterceptorCallAsync(CallContext context)
{
}
private static void MethodResolver(MethodContext context)
{
if (context.Method.Name == "Sum")
context.InterceptCall();
}
If a method was compiled before Jitex installed, Jitex will can't capture that method after install, because he is already compiled by JIT and will not be compiled again.
To bypass that limitation, we can allow developers force a recompile of a method to JIT when Jitex is already enabled.
Jitex doesn't run on ARM64 CPU. That's because the trampoline, which is necessary to prepare the delegate, is entirely written for X64.
Jitex/src/Jitex/Utils/MemoryHelper.cs
Lines 15 to 21 in 666c73a
Implementing a trampoline using ARM64 instructions should be sufficient.
Currently, Jitex only expects one 'ret' instruction AND as the last instruction in the body. When the method has multiple 'ret' instructions, we're not covering all paths.
Example:
MSIL Body from DateTime.Now:
[0] = {Instruction} call System.DateTime get_UtcNow()
[1] = {Instruction} stloc.0
[2] = {Instruction} ldloc.0
[3] = {Instruction} ldloca.s 2
[4] = {Instruction} call System.TimeSpan GetDateTimeNowUtcOffsetFromUtc(System.DateTime, Boolean ByRef)
[5] = {Instruction} stloc.s 4
[6] = {Instruction} ldloca.s 4
[7] = {Instruction} call Int64 get_Ticks()
[8] = {Instruction} stloc.1
[9] = {Instruction} ldloca.s 0
[10] = {Instruction} call Int64 get_Ticks()
[11] = {Instruction} ldloc.1
[12] = {Instruction} add
[13] = {Instruction} stloc.3
[14] = {Instruction} ldloc.3
[15] = {Instruction} ldc.i8 3155378975999999999
[16] = {Instruction} bgt.un.s 37
[17] = {Instruction} ldloc.2
[18] = {Instruction} brtrue.s 17
[19] = {Instruction} ldloc.3
[20] = {Instruction} ldc.i8 -9223372036854775808
[21] = {Instruction} or
[22] = {Instruction} newobj Void .ctor(UInt64)
[23] = {Instruction} ret <------------------------------------- HERE
[24] = {Instruction} ldloc.3
[25] = {Instruction} ldc.i8 -4611686018427387904
[26] = {Instruction} or
[27] = {Instruction} newobj Void .ctor(UInt64)
[28] = {Instruction} ret <------------------------------------- AND HERE
[29] = {Instruction} ldloc.3
[30] = {Instruction} ldc.i4.0
[31] = {Instruction} conv.i8
[32] = {Instruction} blt.s 11
[33] = {Instruction} ldc.i8 -6067993060854775809
[34] = {Instruction} br.s 9
[35] = {Instruction} ldc.i8 -9223372036854775808
[36] = {Instruction} newobj Void .ctor(UInt64)
[37] = {Instruction} ret <------------------------------- WE JUST EXPECTED THIS RET
That will cause an unexpected return.
Intercept call when method has non-primitive type:
public [instance|static] object Method(object parameter){}
Currently, Jitex don't have any log to help debug or get information about runtime. Adding log will help to understand some cenarious and fix some bugs.
After force recompiling a method (without replacing it or anything) subsequent calls to the method throw access violation exception
MethodHelper.ForceRecompile is not working when method is virtual:
public virtual void MethodVirtual(){}
MethodHelper.ForceRecompile(MethodVirtual); //Not working
That's because change pointer from method when he's virtual, it's not enough. It's necessary overwrite pointer on vtable of his type too.
Intercept call when method has async/await implementation.
public [async] [Task|ValueTask] MethodAsync(){}
When publish app with option "Produce single file" checked, an exception "System.NotSupportedException: Invalid Framework" raises.
When try recompile a virtual method, his functional pointer is not filled with zero.
Example:
async Task StubAsync(){}
//Class <StubAsync>
//Method MoveNext();
MoveNext is virtual and not working with MethodHelper.ForceRecompile();
Add support to event after compile method:
JitexManager.OnMethodCompiled += (methodCompiled) =>
{
//code...
};
using Jitex;
JitexManager.AddMethodResolver(context =>
{
Console.WriteLine(context.Method.Name);
if (context.Method.Name.Contains("main", StringComparison.OrdinalIgnoreCase))
{
Console.WriteLine();
}
});
var manifestResourceStream = Assembly.GetCallingAssembly().GetManifestResourceStream("xxxx");
I use latest 6.4.1 .net core is 6.0
I want to Interceptor GetManifestResourceStream return my Stream
but result is
get_IsEnabled
get_IsEnabled
.cctor
Initialize
LoadRuntimeImplFromPath
op_Equality
are there something I got miss? waiting for your help
Allow to modify value from parameter|return directly when has ref or out attribute.
public [static|instance] ref [type] Method([ref|out] parameter){}
Hi!
This is a great project and work. I have a question about Jitex: can it be used for methods that have already been JIT-compiled? Because many times, we may not know in advance which methods need to be intercepted; it's only during the program's runtime that we discover the methods that need to be intercepted, and by that time, they may have already been JIT-compiled. I would like to know if Jitex can be applied in such a scenario. If it is currently not supported, are there any plans to implement this feature in the future?
Thank you for reading!
Hi,I have watched this Rep for a long time.
At first you are palnning to add support for Net Frameworks, But now it seems it will never be none.
However, some similar reps exists.
My question is how can I inject your lib to an existing assembly?
I can inject a managed lib on Net Frameworks, but i donot konw how does it work on Net5 and above,
IF we can inject Jitex to an existing assembly, there are lots of awesome work we can do .
Add support to new version of .NET
When Jitex intercepts a method, we don't add any exception handling. Therefore, if the method throws an exception, the Interceptor will be interrupted without a return or calling ReleaseTask.
Eg.:
public int IsEven(int number) {
//Jitex interceptor implementation...
if (context.ProceedCall) {
if (number == 0)
throw new InvalidOperationException();
result = number % 0 == 1;
}
callManager.ReleaseTask();
}
Should be:
public int IsEven(int number) {
//Jitex interceptor implementation...
if (context.ProceedCall) {
try {
if (number == 0)
throw new InvalidOperationException();
result = number % 0 == 1;
} catch (Exception ex) {
context.SetException(ex);
}
}
if (context.Exception != null)
throw context.Exception;
callManager.ReleaseTask();
}
Add possibility to enable and disable Jitex hooks.
Hello Dear, how many changes do I need make to add x86 .net6/7 support?
.NET 8 has been officially released, and I upgraded my project to .NET 8 yesterday. I've found that Jitex throws an error and doesn't work. Is there a plan to support .NET 8, and if so, when can we expect it to be implemented?
For example, I want to intercept HttpWebRequest.GetResponse() ,but always failed.
And I do a lot of reaserch and find out that classes and methods that inherit from MarshalByRefObject are not patchable at runtime. Since MarshalByRefObject acts as a proxy class.
Is there really no way to solve it?
I want to hook the two methods of System.Text.Encoding.
public virtual string GetString(byte[] bytes)
public virtual string GetString(byte[] bytes, int index, int count)
JitexManager.MethodResolver += context =>
{
Trace.WriteLine($"{context.Method.DeclaringType.Name} {context.Method.Name}" );
};
There is no output of the two methods.
And I try to do the following:
var methods = Type.GetType("System.Text.Encoding").GetMethods().Where(w => w.Name == "GetString");
foreach (var method in methods)
{
MethodHelper.ForceRecompile(method); //Force recompile
}
And the app just crashes.
Could you pls show me a good example? Thank you!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.