예제 #1
0
        public static unsafe void HijackUnmanagedMethod(void *target, void *hook, HijackContextBase context)
        {
            for (int idx = 0; idx < 64; idx++)
            {
                context.Backup[idx] = ((Byte *)target)[idx];
            }

            // We need to replace at least 13 byte, for `mov rax, [addr]`, `jmp rax`, and `push rax` instruction.
            const int       minimumCount = 13;
            MigrationResult result       = context.MigrateInstruction((IntPtr)target, (IntPtr)context.Buffer, minimumCount);

            Debug.Assert(result.SrcOffset >= minimumCount);

            context.ReplacedByteCount = result.SrcOffset;

            Kernel32.VirtualProtectEx(
                Process.GetCurrentProcess().Handle, (IntPtr)target, (UIntPtr)result.SrcOffset,
                Kernel32.PageProtection.ExecuteReadWrite, out Kernel32.PageProtection originalProtection);

            ((Byte *)context.Buffer)[result.DstOffset] = 0x50; // push rax
            InsertJump(context.Buffer + result.DstOffset + 1, (Byte *)target + result.SrcOffset - 1);

            InsertJump(target, hook);
            ((Byte *)target)[result.SrcOffset - 1] = 0x58; // pop rax

            Kernel32.VirtualProtectEx(
                Process.GetCurrentProcess().Handle, (IntPtr)target, (UIntPtr)result.SrcOffset,
                originalProtection, out _);
        }
예제 #2
0
        public static unsafe void RestoreManagedMethod(MethodInfo target, HijackContextBase context)
        {
            Byte *pTargetMethod = (Byte *)target.MethodHandle.GetFunctionPointer();

            if (pTargetMethod[0] == 0xE9)
            {
                Int32 rel32 = *(Int32 *)(pTargetMethod + 1);
                pTargetMethod += rel32 + 5;
            }

            RestoreUnmanagedMethod(pTargetMethod, context);
        }
예제 #3
0
        public static unsafe void RestoreUnmanagedMethod(void *target, HijackContextBase context)
        {
            Kernel32.VirtualProtectEx(
                Process.GetCurrentProcess().Handle, (IntPtr)target, (UIntPtr)context.ReplacedByteCount,
                Kernel32.PageProtection.ExecuteReadWrite, out Kernel32.PageProtection originalProtection);

            if (context.IsDisposed)
            {
                throw new ObjectDisposedException("context is already disposed. Is method already restored?");
            }

            for (int idx = 0; idx < context.ReplacedByteCount; idx++)
            {
                ((Byte *)target)[idx] = context.Backup[idx];
            }

            context.Dispose();

            Kernel32.VirtualProtectEx(
                Process.GetCurrentProcess().Handle, (IntPtr)target, (UIntPtr)context.ReplacedByteCount,
                originalProtection, out _);
        }
예제 #4
0
        public static unsafe void HijackUnmanagedMethod(void *target, MethodInfo hook, HijackContextBase context)
        {
            Byte *pHookMethod = (Byte *)hook.MethodHandle.GetFunctionPointer();

            HijackUnmanagedMethod(target, pHookMethod, context);
        }
예제 #5
0
        // TODO: Extract all AMD64-related logics to other helper class

        public static unsafe void HijackManagedMethod(MethodInfo target, MethodInfo hook, HijackContextBase context)
        {
            // Make sure method is jitted already.
            RuntimeHelpers.PrepareMethod(hook.MethodHandle);

            Byte *pTargetMethod = (Byte *)target.MethodHandle.GetFunctionPointer();

            // TODO: make allocation free way to allocate decoder.
            Decoder d = Decoder.Create(64, new BytePtrCodeReader(pTargetMethod));

            Instruction inst = d.Decode();

            switch (inst.Code)
            {
            case Code.Jmp_rel32_64:
                pTargetMethod += inst.Immediate32to64;
                break;
            }

            HijackUnmanagedMethod(pTargetMethod, hook, context);
        }