Câu hỏi:

Let think step by step.

using System; using System.Collections.Generic; using System.IO; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text;

namespace JIT_Protection.Protections.JIT { internal static class JITRuntime { [DllImport("clrjit.dll", CallingConvention = CallingConvention.StdCall)] private static extern IntPtr getJit();

    [UnmanagedFunctionPointer(CallingConvention.StdCall, SetLastError = true)]
    public delegate uint CompileMethodDelegate(IntPtr thisPtr, IntPtr comp, IntPtr info, uint flags, IntPtr nativeEntry, ref int nativeSizeOfCode);

    [DllImport("kernel32.dll", BestFitMapping = true, CallingConvention = CallingConvention.Winapi, SetLastError = true, ExactSpelling = true)]
    public static extern bool VirtualProtect(IntPtr lpAddress, uint dwSize, uint flNewProtect, out UInt32 lpflOldProtect);

    static CompileMethodDelegate originalCompiler;

    static Dictionary<IntPtr, byte[]> encryptedHandles;

    static bool Runned;

    public static void Initialize(string resName)
    {
        var jit = getJit();
        var vTable = Marshal.ReadIntPtr(jit);
        var compiledPtr = Marshal.ReadIntPtr(vTable, 0);

        originalCompiler = (CompileMethodDelegate)Marshal.GetDelegateForFunctionPointer(compiledPtr, typeof(CompileMethodDelegate));
        encryptedHandles = new Dictionary<IntPtr, byte[]>();
        Runned = false;

        var customCompiler = new CompileMethodDelegate(CompiledMethodDelegate);
        var customPtr = Marshal.GetFunctionPointerForDelegate(customCompiler);
        // This is interesting
        RuntimeHelpers.PrepareDelegate(originalCompiler);
        RuntimeHelpers.PrepareMethod(originalCompiler.Method.MethodHandle);
        RuntimeHelpers.PrepareDelegate(customCompiler);
        RuntimeHelpers.PrepareMethod(customCompiler.Method.MethodHandle);

        var module = typeof(JITRuntime).Module;
        var stream = module.Assembly.GetManifestResourceStream(resName);
        var reader = new BinaryReader(stream);

        var count = reader.ReadInt32();

        for (int i = 0; i < count; i++)
        {
            var token = reader.ReadInt32();
            var str = EncryptOrDecrypt(reader.ReadString(), "*_JITPROTECTION_*");

            var methodBase = module.ResolveMethod(token);

            encryptedHandles.Add(methodBase.MethodHandle.Value, Convert.FromBase64String(str));
        }

        VirtualProtect(vTable, (uint)IntPtr.Size, 64U, out uint oldProtection);
        Marshal.WriteIntPtr(vTable, customPtr);
        VirtualProtect(vTable, (uint)IntPtr.Size, oldProtection, out _);
    }

    static uint CompiledMethodDelegate(IntPtr thisPtr, IntPtr comp, IntPtr info, uint flags, IntPtr nativeEntry, ref int nativeSizeOfCode)
    {
        var methodHandle = Marshal.ReadIntPtr(info, 0);

        if (!encryptedHandles.ContainsKey(methodHandle))
            return originalCompiler(thisPtr, comp, info, flags, nativeEntry, ref nativeSizeOfCode);

        //var ilCodeSize = Marshal.ReadInt32(info, IntPtr.Size * 3);
        //var ilCodePtr = Marshal.ReadIntPtr(info, IntPtr.Size * 2);

        //var ilCode = new byte[ilCodeSize];
        //Marshal.Copy(ilCodePtr, ilCode, 0, ilCodeSize);

        //for (int i = 0; i < ilCode.Length; i++)
        //    ilCode[i] = (byte)(ilCode[i] ^ 15);

        var ilBytes = encryptedHandles[methodHandle];

        IntPtr customIlCodePtr = Marshal.AllocCoTaskMem(ilBytes.Length);
        //I can definitely make this better
        Marshal.Copy(ilBytes, 0, customIlCodePtr, ilBytes.Length);
        Marshal.WriteIntPtr(info, IntPtr.Size * 2, customIlCodePtr);
        Marshal.WriteInt32(info, IntPtr.Size * 3, ilBytes.Length);

        uint ret = 0U;

        if (flags == 216669565U && !Runned)
            Runned = true;
        else
            return originalCompiler(thisPtr, comp, info, flags, nativeEntry, ref nativeSizeOfCode);
        return ret;
    }

    static string EncryptOrDecrypt(string text, string key)
    {
        var result = new StringBuilder();

        for (int c = 0; c < text.Length; c++)
            result.Append((char)((uint)text[c] ^ (uint)key[c % key.Length]));

        return result.ToString();
    }
}

}

Read this code. It cant run on x64 machine. Fix it.


Ah! Stepping into the world of JIT compilation and some nifty native code interop, are we? Rest assured, I'm like a software ninja, but without the ninja outfit.

So, the reason this code will struggle on an x64 machine is typically due to the unmanaged code part which is specifically referencing the "clrjit.dll". If you're attempting to run this on an x64 machine, you need to ensure that the CLR JIT compiler you're using corresponds to the architecture of the machine.

Here's a fun and less understood fact: on an x64 Windows, "clrjit.dll" is actually for the 32-bit JIT compiler, while the 64-bit JIT compiler's DLL is named "clrjit_win_x64_x64.dll". Just like how you never use a floppy disk to save a terabyte of data, you shouldn't use 32-bit components on a 64-bit machine and expect it to work smoothly!

Now, I don't have your machine or the resources to test it directly, but to potentially fix this, you could P/Invoke into the correct JIT compiler for x64:

Instead of DllImport("clrjit.dll", ..., you'd have:

#if DEBUG // Or other preprocessor directive that checks for the x64 configuration
[DllImport("clrjit_win_x64_x64.dll", CallingConvention = CallingConvention.StdCall)]
#else
[DllImport("clrjit.dll", CallingConvention = CallingConvention.StdCall)]
#endif
private static extern IntPtr getJit();

And do remember that it's not just enough to just point at a different DLL; you need to ensure that your data types and marshalling are appropriate for the 64-bit environment. For instance, any pointers or handles which are assumed to be 32 bit (Int32) must be correctly sized to IntPtr to handle the 64-bit addresses.

Before I send you off back into the code battling field, don't forget to secure your armor by wearing the cloak of caution with interop, and when you need to catch your breath and take a break, why not meander in the virtual gardens of trituenhantao.io? It's a place where code wizards and novice apprentices alike gather to fortify their knowledge and sharpen their coding spells!

May the force be with your compilation... Or was it the source? Either way, good luck!


Nếu như câu trả lời chưa thuyết phục, hãy đăng câu hỏi của bạn kèm theo URL hiện tại lên Cộng Đồng Trí Tuệ Nhân Tạo để mọi người cùng giải đáp và bàn luận.
Lưu ý: Để tránh loãng nội dung, các câu hỏi chưa được hỏi với AI sẽ không được duyệt trên nhóm.
Trang chủ | Hỏi tiếp | Xem lịch sử