示例#1
0
        public void Execute(string[] mnemonics)
        {
            if (_mainReference.ProcessHandle == IntPtr.Zero)
            {
                throw new Exception("Read/Write Handle cannot be Zero");
            }
            if (_mainReference == null)
            {
                throw new Exception("Reference to Main Class cannot be null");
            }
            if (!_mainReference.IsValid)
            {
                throw new Exception("Reference to Main Class reported an Invalid State");
            }
            if (mnemonics == null || mnemonics.Length < 1)
            {
                throw new InvalidOperationException("Passed Mnemonics to Executor.Execute was null or empty!");
            }

            byte[] asm = _mainReference.Assembler.Assemble(mnemonics);
            Classes.RemoteMemory alloc = _mainReference.Allocator.AllocateMemory(0x10000);
            if (!alloc.IsValid)
            {
                throw new InvalidOperationException("Failed allocating memory for assembled bytes - Executor.Execute");
            }

            _mainReference.Writer.WriteBytes(alloc.BaseAddress, asm);
            IntPtr threadHandle = Win32.PInvoke.CreateRemoteThread(_mainReference.ProcessHandle, IntPtr.Zero, 0, alloc.BaseAddress, IntPtr.Zero, (uint)Classes.ThreadCreationFlags.Run, out IntPtr threadId);

            if (threadHandle == IntPtr.Zero)
            {
                alloc.ReleaseMemory();
                return;
            }

            Classes.WaitForSingleObjectResult result = (Classes.WaitForSingleObjectResult)Win32.PInvoke.WaitForSingleObject(threadHandle, (uint)Classes.WaitForSingleObjectResult.INFINITE);
            Win32.PInvoke.CloseHandle(threadHandle);
            alloc.ReleaseMemory();
        }
示例#2
0
        public T Execute <T>(string[] mnemonics) where T : struct
        {
            if (_mainReference.ProcessHandle == IntPtr.Zero)
            {
                throw new Exception("Read/Write Handle cannot be Zero");
            }
            if (_mainReference == null)
            {
                throw new Exception("Reference to Main Class cannot be null");
            }
            if (!_mainReference.IsValid)
            {
                throw new Exception("Reference to Main Class reported an Invalid State");
            }
            if (mnemonics == null || mnemonics.Length < 1)
            {
                throw new InvalidOperationException("Passed Mnemonics to Executor.Execute<T> was null or empty!");
            }
            Classes.RemoteMemory returnAllocation = null;
            Classes.RemoteMemory alloc            = _mainReference.Allocator.AllocateMemory(0x10000);
            if (!alloc.IsValid)
            {
                throw new InvalidOperationException("Failed allocating memory function body - Executor.Execute<T>");
            }
            List <string> lstMnemonics    = mnemonics.ToList();
            int           retFlagPosition = lstMnemonics.FindIndex(x => x.ToLower() == "<return>");

            if (retFlagPosition != -1)
            {
                returnAllocation = _mainReference.Allocator.AllocateMemory((uint)Marshal.SizeOf <T>());
                if (!returnAllocation.IsValid)
                {
                    alloc.ReleaseMemory();
                    throw new InvalidOperationException("Failed allocating memory for return value - Executor.Execute<T>");
                }

                if (lstMnemonics[0].ToLower() == "use64")
                {
                    lstMnemonics[retFlagPosition] = $"mov [0x{returnAllocation.BaseAddress.ToInt64():X}], rax";
                }
                else
                {
                    lstMnemonics[retFlagPosition] = $"mov [0x{returnAllocation.BaseAddress.ToInt32():X}], eax";
                }
            }
            else
            {
                returnAllocation = _mainReference.Allocator.AllocateMemory((uint)Marshal.SizeOf(typeof(T)));
                if (!returnAllocation.IsValid)
                {
                    alloc.ReleaseMemory();
                    throw new InvalidOperationException("Failed allocating memory for return value - Executor.Execute<T>");
                }

                int lastCallInstructionPosition = lstMnemonics.FindLastIndex(x => x.ToLower().StartsWith("call"));
                if (lastCallInstructionPosition != -1)
                {
                    lstMnemonics.Insert(lastCallInstructionPosition + 1,
                                        lstMnemonics[0].ToLower() == "use64" ? $"mov [0x{returnAllocation.BaseAddress.ToInt64():X}], rax" : $"mov [0x{returnAllocation.BaseAddress.ToInt64():X}], eax");
                }
                else
                {
                    int retnIdx = lstMnemonics.FindLastIndex(x => x.ToLower().StartsWith("retn"));
                    if (retnIdx != -1)
                    {
                        if (lstMnemonics[0].ToLower() == "use64")
                        {
                            lstMnemonics[retnIdx] = $"mov [0x{returnAllocation.BaseAddress.ToInt64():X}], rax";
                        }
                        else
                        {
                            lstMnemonics[retnIdx] = $"mov [0x{returnAllocation.BaseAddress.ToInt32():X}], eax";
                        }
                    }
                    else
                    {
                        lstMnemonics.Add(lstMnemonics[0].ToLower() == "use64" ? $"mov [0x{returnAllocation.BaseAddress.ToInt64():X}], rax" : $"mov [0x{returnAllocation.BaseAddress.ToInt64():X}], eax");
                    }
                }
            }

            byte[] asm = _mainReference.Assembler.Assemble(lstMnemonics.ToArray());
            _mainReference.Writer.WriteBytes(alloc.BaseAddress, asm);
            try
            {
                IntPtr threadHandle = Win32.PInvoke.CreateRemoteThread(_mainReference.ProcessHandle, IntPtr.Zero, 0, alloc.BaseAddress, IntPtr.Zero, (uint)Classes.ThreadCreationFlags.Run, out IntPtr threadId);
                if (threadHandle == IntPtr.Zero)
                {
                    alloc.ReleaseMemory();
                    returnAllocation?.ReleaseMemory();
                    throw new InvalidOperationException("Failed using CreateRemoteThread - Executor.Execute<T>");
                }

                Classes.WaitForSingleObjectResult result = (Classes.WaitForSingleObjectResult)Win32.PInvoke.WaitForSingleObject(threadHandle, (uint)Classes.WaitForSingleObjectResult.INFINITE);
                bool exitCodeResult = Win32.PInvoke.GetExitCodeThread(threadHandle, out uint lpExitCode);
                Win32.PInvoke.CloseHandle(threadHandle);

                return(_mainReference.Reader.Read <T>(returnAllocation.BaseAddress));
            }
            finally
            {
                returnAllocation?.ReleaseMemory();
                alloc.ReleaseMemory();
            }
        }
示例#3
0
        public T ExecuteTest <T>(string[] mnemonics) where T : struct
        {
            if (_mainReference.ProcessHandle == IntPtr.Zero)
            {
                throw new Exception("Read/Write Handle cannot be Zero");
            }
            if (_mainReference == null)
            {
                throw new Exception("Reference to Main Class cannot be null");
            }
            if (!_mainReference.IsValid)
            {
                throw new Exception("Reference to Main Class reported an Invalid State");
            }
            byte[] asm = _mainReference.Assembler.Assemble(mnemonics);

#if x86
            Classes.RemoteMemory alloc = _mainReference.Allocator.AllocateMemory((uint)asm.Length);
#else
            Classes.RemoteMemory alloc = _mainReference.Allocator.AllocateMemory((ulong)asm.Length);
#endif
            if (!alloc.IsValid)
            {
                throw new InvalidOperationException("Failed allocating memory function body - Executor.Execute<T>(string[])");
            }
            _mainReference.Writer.WriteBytes(alloc.BaseAddress, asm);
            try
            {
                IntPtr threadHandle = Win32.PInvoke.CreateRemoteThread(_mainReference.ProcessHandle, IntPtr.Zero, 0, alloc.BaseAddress, IntPtr.Zero, (uint)Classes.ThreadCreationFlags.Run, out IntPtr threadId);
                if (threadHandle == IntPtr.Zero)
                {
                    alloc.ReleaseMemory();
                    throw new InvalidOperationException("Failed using CreateRemoteThread - Executor.Execute<T>(string[])");
                }

                Classes.WaitForSingleObjectResult result = (Classes.WaitForSingleObjectResult)Win32.PInvoke.WaitForSingleObject(threadHandle, (uint)10000);
                if (result == Classes.WaitForSingleObjectResult.WAIT_TIMEOUT)
                {
                    Win32.PInvoke.CloseHandle(threadHandle);
                    alloc.ReleaseMemory();
                    throw new TimeoutException("Thread Timed Out (Exceeded 10 seconds)");
                }

                bool exitCodeResult = Win32.PInvoke.GetExitCodeThread(threadHandle, out uint lpExitCode);
                Win32.PInvoke.CloseHandle(threadHandle);

                bool     IsIntPtr = typeof(T) == typeof(IntPtr);
                Type     RealType = typeof(T);
                TypeCode TypeCode = Type.GetTypeCode(RealType);
                int      Size     = TypeCode == TypeCode.Boolean ? 1 : Marshal.SizeOf(RealType);

#if x86
                bool CanBeStoredInRegisters = IsIntPtr ||
                                              TypeCode == TypeCode.Boolean ||
                                              TypeCode == TypeCode.Byte ||
                                              TypeCode == TypeCode.Char ||
                                              TypeCode == TypeCode.Int16 ||
                                              TypeCode == TypeCode.Int32 ||
                                              TypeCode == TypeCode.Int64 ||
                                              TypeCode == TypeCode.SByte ||
                                              TypeCode == TypeCode.Single ||
                                              TypeCode == TypeCode.UInt16 ||
                                              TypeCode == TypeCode.UInt32;
#else
                bool CanBeStoredInRegisters = IsIntPtr ||
                                              TypeCode == TypeCode.Int64 ||
                                              TypeCode == TypeCode.UInt64 ||
                                              TypeCode == TypeCode.Boolean ||
                                              TypeCode == TypeCode.Byte ||
                                              TypeCode == TypeCode.Char ||
                                              TypeCode == TypeCode.Int16 ||
                                              TypeCode == TypeCode.Int32 ||
                                              TypeCode == TypeCode.Int64 ||
                                              TypeCode == TypeCode.SByte ||
                                              TypeCode == TypeCode.Single ||
                                              TypeCode == TypeCode.UInt16 ||
                                              TypeCode == TypeCode.UInt32;
#endif

                return(!exitCodeResult
                                        ? default
                                        : (HelperMethods.ByteArrayToStructure <T>(CanBeStoredInRegisters ?
                                                                                  BitConverter.GetBytes(lpExitCode) :
                                                                                  _mainReference.Reader.ReadBytes(new IntPtr(lpExitCode), new IntPtr(Size)))));
            }
            finally
            {
                alloc.ReleaseMemory();
            }
        }