Exemplo n.º 1
0
        internal static Span <byte> AssembleCall32(CallDescriptor32 callDescriptor)
        {
            var instructions = new List <byte>();

            foreach (var argument in callDescriptor.Arguments.Reverse())
            {
                if (argument <= sbyte.MaxValue)
                {
                    // push argument

                    instructions.AddRange(new byte[] { 0x6A, (byte)argument });
                }

                else
                {
                    // push argument

                    instructions.Add(0x68);

                    instructions.AddRange(BitConverter.GetBytes(argument));
                }
            }

            // mov eax, Address

            instructions.Add(0xB8);

            instructions.AddRange(BitConverter.GetBytes(callDescriptor.Address.ToInt32()));

            // call eax

            instructions.AddRange(new byte[] { 0xFF, 0xD0 });

            if (callDescriptor.ReturnAddress != IntPtr.Zero)
            {
                // mov ReturnAddress, eax

                instructions.Add(0xA3);

                instructions.AddRange(BitConverter.GetBytes(callDescriptor.ReturnAddress.ToInt32()));
            }

            // xor eax, eax

            instructions.AddRange(new byte[] { 0x33, 0xC0 });

            // ret

            instructions.Add(0xC3);

            return(instructions.ToArray());
        }
Exemplo n.º 2
0
        internal T CallRoutine <T>(IntPtr routineAddress, params dynamic[] arguments) where T : unmanaged
        {
            var returnAddress = Process.AllocateMemory(Unsafe.SizeOf <T>());

            // Create the shellcode used to call the routine

            Span <byte> shellcodeBytes;

            if (Process.GetArchitecture() == Architecture.X86)
            {
                var callDescriptor = new CallDescriptor32(routineAddress, Array.ConvertAll(arguments, argument => (int)argument), returnAddress);

                shellcodeBytes = CallAssembler.AssembleCall32(callDescriptor);
            }

            else
            {
                var routineDescriptor = new CallDescriptor64(routineAddress, Array.ConvertAll(arguments, argument => (long)argument), returnAddress);

                shellcodeBytes = CallAssembler.AssembleCall64(routineDescriptor);
            }

            try
            {
                // Write the shellcode bytes into the process

                var shellcodeBytesAddress = Process.AllocateMemory(shellcodeBytes.Length, true);

                try
                {
                    Process.WriteArray(shellcodeBytesAddress, shellcodeBytes);

                    // Create a thread to execute the shellcode

                    Process.CreateThread(shellcodeBytesAddress);
                }

                finally
                {
                    Process.FreeMemory(shellcodeBytesAddress);
                }

                return(Process.ReadStructure <T>(returnAddress));
            }

            finally
            {
                Process.FreeMemory(returnAddress);
            }
        }
Exemplo n.º 3
0
        internal void CallRoutine(IntPtr routineAddress, params dynamic[] arguments)
        {
            // Create the shellcode used to call the routine

            Span <byte> shellcodeBytes;

            if (Process.GetArchitecture() == Architecture.X86)
            {
                var callDescriptor = new CallDescriptor32(routineAddress, Array.ConvertAll(arguments, argument => (int)argument), IntPtr.Zero);

                shellcodeBytes = CallAssembler.AssembleCall32(callDescriptor);
            }

            else
            {
                var routineDescriptor = new CallDescriptor64(routineAddress, Array.ConvertAll(arguments, argument => (long)argument), IntPtr.Zero);

                shellcodeBytes = CallAssembler.AssembleCall64(routineDescriptor);
            }

            // Write the shellcode bytes into the process

            var shellcodeBytesAddress = Process.AllocateMemory(shellcodeBytes.Length, true);

            try
            {
                Process.WriteArray(shellcodeBytesAddress, shellcodeBytes);

                // Create a thread to execute the shellcode

                Process.CreateThread(shellcodeBytesAddress);
            }

            finally
            {
                Process.FreeMemory(shellcodeBytesAddress);
            }
        }