Ejemplo n.º 1
0
        /// <summary>
        /// Creates a thread that runs in the remote process.
        /// </summary>
        /// <param name="address">
        /// A pointer to the application-defined function to be executed by the thread and represents
        /// the starting address of the thread in the remote process.
        /// </param>
        /// <param name="parameter">A variable to be passed to the thread function.</param>
        /// <param name="isStarted">Sets if the thread must be started just after being created.</param>
        /// <returns>A new instance of the <see cref="RemoteThread"/> class.</returns>
        public RemoteThread Create(IntPtr address, dynamic parameter, bool isStarted = true)
        {
            // Marshal the parameter
            var marshalledParameter = MarshalValue.Marshal(MemorySharp, parameter);

            //Create the thread
            var ret = ThreadCore.NtQueryInformationThread(
                ThreadCore.CreateRemoteThread(MemorySharp.Handle, address, marshalledParameter.Reference, ThreadCreationFlags.Suspended));

            // Get the native thread previously created
            // Loop until the native thread is retrieved
            ProcessThread nativeThread;

            do
            {
                nativeThread = MemorySharp.Threads.NativeThreads.FirstOrDefault(t => ret.ClientIdStruct.UniqueThread.IsEqual(t.Id));
            } while (nativeThread == null);

            // Find the managed object corresponding to this thread
            var result = new RemoteThread(MemorySharp, nativeThread, marshalledParameter);

            // If the thread must be started
            if (isStarted)
            {
                result.Resume();
            }
            return(result);
        }
Ejemplo n.º 2
0
        /// <summary>
        ///     Executes the assembly code located in the remote process at the specified address.
        /// </summary>
        /// <param name="address">The address where the assembly code is located.</param>
        /// <param name="callingConvention">The calling convention used to execute the assembly code with the parameters.</param>
        /// <param name="parameters">An array of parameters used to execute the assembly code.</param>
        /// <returns>The return value is the exit code of the thread created to execute the assembly code.</returns>
        public T Execute <T>(IntPtr address, Native.Types.CallingConventions callingConvention,
                             params dynamic[] parameters)
        {
            // Marshal the parameters
            var marshalledParameters =
                parameters.Select(p => MarshalValue.Marshal(Process, p)).Cast <IMarshalledValue>().ToArray();
            // Start a transaction
            AssemblyTransaction t;

            using (t = BeginTransaction())
            {
                // Get the object dedicated to create mnemonics for the given calling convention
                var calling = CallingConventionSelector.Get(callingConvention);
                // Push the parameters
                t.AddLine(calling.FormatParameters(marshalledParameters.Select(p => p.Reference).ToArray()));
                // Call the function
                t.AddLine(calling.FormatCalling(address));
                // Clean the parameters
                if (calling.Cleanup == CleanupTypes.Caller)
                {
                    t.AddLine(calling.FormatCleaning(marshalledParameters.Length));
                }
                // Add the return mnemonic
                t.AddLine("retn");
            }

            // Clean the marshalled parameters
            foreach (var parameter in marshalledParameters)
            {
                parameter.Dispose();
            }
            // Return the exit code
            return(t.GetExitCode <T>());
        }
Ejemplo n.º 3
0
        public void MarshalChar()
        {
            // Arrange
            var        sharp = Resources.MemorySharp;
            const char value = 'A';

            // Act
            using (var pointer = MarshalValue.Marshal(sharp, value))
            {
                // Assert
                Assert.AreEqual(0x41, pointer.Reference.ToInt32());
            }

            Resources.EndTests(sharp);
        }
Ejemplo n.º 4
0
        public void MarshalBoolean()
        {
            // Arrange
            var        sharp = Resources.MemorySharp;
            const bool value = true;

            // Act
            using (var pointer = MarshalValue.Marshal(sharp, value))
            {
                // Assert
                Assert.AreEqual(0x1, pointer.Reference.ToInt32());
            }

            Resources.EndTests(sharp);
        }
Ejemplo n.º 5
0
        public void MarshalFloat()
        {
            // Arrange
            var         sharp = Resources.MemorySharp;
            const float value = 1024f;

            // Act
            using (var pointer = MarshalValue.Marshal(sharp, value))
            {
                // Assert
                Assert.AreEqual(0x44800000, pointer.Reference.ToInt32());
            }

            Resources.EndTests(sharp);
        }
Ejemplo n.º 6
0
        public void MarshalInteger()
        {
            // Arrange
            var       sharp = Resources.MemorySharp;
            const int value = 1024;

            // Act
            using (var pointer = MarshalValue.Marshal(sharp, value))
            {
                // Assert
                Assert.AreEqual(value, pointer.Reference.ToInt32());
            }

            Resources.EndTests(sharp);
        }
Ejemplo n.º 7
0
        public void MarshalString()
        {
            // Arrange
            var          sharp = Resources.MemorySharp;
            const string path  = "If you read that, you're *really* like unit tests.";

            // Act
            using (var pointer = MarshalValue.Marshal(sharp, path))
            {
                // Assert
                Assert.AreEqual(path, pointer.Allocated.ReadString(0));
            }

            Resources.EndTests(sharp);
        }
Ejemplo n.º 8
0
        public void Marshal_CustomStruct()
        {
            // Arrange
            var sharp = Resources.MemorySharp;
            var value = Resources.CustomStruct;

            // Act
            using (var pointer = MarshalValue.Marshal(sharp, value))
            {
                // Assert
                Assert.AreEqual(Resources.CustomStruct.X, pointer.Allocated.Read <int>(0));
                Assert.AreEqual(Resources.CustomStruct.Y, pointer.Allocated.Read <int>(4));
                Assert.AreEqual(Resources.CustomStruct.Z, pointer.Allocated.Read <int>(8));
            }

            Resources.EndTests(sharp);
        }
Ejemplo n.º 9
0
        public RemoteThread Create(IntPtr address, dynamic parameter, bool isStarted = true)
        {
            var marshalledParameter = MarshalValue.Marshal(m_Process, parameter);

            ThreadHelper.CreateRemoteThread(m_Process.Handle, address, marshalledParameter.Reference, out int threadId, ThreadCreationFlags.Suspended);
            ProcessThread nativeThread;

            do
            {
                nativeThread = m_Process.Threads.NativeThreads.FirstOrDefault(t => t.Id == threadId);
            } while (nativeThread == null);
            var result = new RemoteThread(m_Process, nativeThread, marshalledParameter);

            if (isStarted)
            {
                result.Resume();
            }
            return(result);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Creates a thread that runs in the remote process.
        /// </summary>
        /// <param name="address">
        /// A pointer to the application-defined function to be executed by the thread and represents
        /// the starting address of the thread in the remote process.
        /// </param>
        /// <param name="parameter">A variable to be passed to the thread function.</param>
        /// <param name="isStarted">Sets if the thread must be started just after being created.</param>
        /// <returns>A new instance of the <see cref="RemoteThread"/> class.</returns>
        public RemoteThread Create(IntPtr address, dynamic parameter, bool isStarted = true)
        {
            // Marshal the parameter
            var marshalledParameter = MarshalValue.Marshal(MemorySharp, parameter);

            //Create the thread
            var ret = ThreadCore.NtQueryInformationThread(
                ThreadCore.CreateRemoteThread(MemorySharp.Handle, address, marshalledParameter.Reference, ThreadCreationFlags.Suspended));

            // Find the managed object corresponding to this thread
            var result = new RemoteThread(MemorySharp, MemorySharp.Threads.NativeThreads.First(t => t.Id == ret.ThreadId), marshalledParameter);

            // If the thread must be started
            if (isStarted)
            {
                result.Resume();
            }
            return(result);
        }
Ejemplo n.º 11
0
        /// <summary>
        ///     Creates a thread that runs in the remote process.
        /// </summary>
        /// <param name="address">
        ///     A pointer to the application-defined function to be executed by the thread and represents
        ///     the starting address of the thread in the remote process.
        /// </param>
        /// <param name="parameter">A variable to be passed to the thread function.</param>
        /// <param name="isStarted">Sets if the thread must be started just after being created.</param>
        /// <returns>A new instance of the <see cref="RemoteThread" /> class.</returns>
        public IRemoteThread Create(IntPtr address, dynamic parameter, bool isStarted = true)
        {
            // Marshal the parameter
            var marshalledParameter = MarshalValue.Marshal(_process, parameter);

            //Create the thread
            var ret = ThreadHelper.NtQueryInformationThread(
                ThreadHelper.CreateRemoteThread(_process.Handle, address, marshalledParameter.Reference,
                                                ThreadCreationFlags.Suspended));

            // Find the managed object corresponding to this thread
            var result = new RemoteThread(_process, _process.ThreadFactory.NativeThreads.First(t => t.Id == ret.ThreadId),
                                          marshalledParameter);

            if (isStarted)
            {
                result.Resume();
            }
            return(result);
        }
Ejemplo n.º 12
0
        public T Execute <T>(IntPtr address, CallingConvention callingConvention, params dynamic[] parameters)
        {
            var marshalledParameters = parameters.Select(p => MarshalValue.Marshal(m_Process, p)).Cast <IMarshalledValue>().ToArray();

            var calling = callingConvention == CallingConvention.Default ?
                          CallingConventionSelector.Get(m_Process.Is64Bit ? CallingConvention.FastCall64 : CallingConvention.StdCall) :
                          CallingConventionSelector.Get(m_Process.Is64Bit ? CallingConvention.FastCall64 : callingConvention);

            AssemblyTransaction t;

            using (t = BeginTransaction()) {
                t.Add(calling.FormatCall(address, marshalledParameters.Select(p => p.Reference).ToArray()));
            }

            foreach (var parameter in marshalledParameters)
            {
                parameter.Dispose();
            }

            return(t.GetExitCode <T>());
        }
Ejemplo n.º 13
0
        /// <summary>
        ///     Creates a thread that runs in the remote process.
        /// </summary>
        /// <param name="address">
        ///     A pointer to the application-defined function to be executed by the thread and represents
        ///     the starting address of the thread in the remote process.
        /// </param>
        /// <param name="parameter">A variable to be passed to the thread function.</param>
        /// <param name="isStarted">Sets if the thread must be started just after being created.</param>
        /// <returns>A new instance of the <see cref="RemoteThread" /> class.</returns>
        public IRemoteThread Create(IntPtr address, dynamic parameter, bool isStarted = true)
        {
            // Marshal the parameter
            var marshalledParameter = MarshalValue.Marshal(Process, parameter);

            //Create the thread
            var ret = ThreadHelper.NtQueryInformationThread(
                ThreadHelper.CreateRemoteThread(Process.Handle, address, marshalledParameter.Reference,
                                                ThreadCreationFlags.Suspended));

            // Find the managed object corresponding to this thread
            // TODO (int) cast may be unnecessary and/or problematic. Suggest coming back for proper fix later
            var result = new RemoteThread(Process, NativeThreads.First(t => t.Id == (int)ret.ClientId.UniqueThread),
                                          marshalledParameter);

            // If the thread must be started
            if (isStarted)
            {
                result.Resume();
            }
            return(result);
        }
Ejemplo n.º 14
0
        /// <summary>Calls method <paramref name="method" /> in SuperMemo</summary>
        /// <param name="method">The method to call</param>
        /// <param name="parameters">The method's parameters to pass along with the call</param>
        /// <returns>
        ///   The returned value (eax register) from the call to <paramref name="method" />
        /// </returns>
        protected int CallNativeMethod(NativeMethod method,
                                       dynamic[]    parameters)
        {
            SMA.Debug($"Executing native method {Enum.GetName(typeof(NativeMethod), method)}.");

            if (parameters == null)
            {
                OnException(new ArgumentNullException(nameof(parameters), $"CallNativeMethod: Called with null 'parameters' for method {method}"));
                return(-1);
            }

            // Possible null reference on parameters
            var marshalledParameters = new IMarshalledValue[parameters.Length];

            for (var i = 0; i < parameters.Length; i++)
            {
                var p             = parameters[i];
                var dynMarshalled = MarshalValue.Marshal(_smProcess, p);

                if (dynMarshalled is IMarshalledValue marshalled)
                {
                    marshalledParameters[i] = marshalled;
                }

                else
                {
                    OnException(new ArgumentException($"CallNativeMethod: Parameter n°{i} '{p}' could not be marshalled for method {method}",
                                                      nameof(p)));
                    return(-1);
                }
            }

            try
            {
                switch (method)
                {
                case NativeMethod.AppendAndAddElementFromText:
                    var elWdw  = marshalledParameters[0].Reference.ToInt32();
                    var elType = marshalledParameters[1].Reference.ToInt32();
                    var elDesc = marshalledParameters[2].Reference.ToInt32();

                    // elWdw.AppendElement(elType, automatic: false);
                    int elemId = Delphi.registerCall3(_callTable[NativeMethod.ElWdw_AppendElement],
                                                      elWdw,
                                                      elType,
                                                      0);

                    if (elemId <= 0)
                    {
                        return(-1);
                    }

                    // elWdw.AddElementFromText(elDesc);
                    int res = Delphi.registerCall2(_callTable[NativeMethod.ElWdw_AddElementFromText],
                                                   elWdw,
                                                   elDesc);

                    return(res > 0 ? elemId : -1);

                case NativeMethod.PostponeRepetition:
                    elWdw = marshalledParameters[0].Reference.ToInt32();
                    var interval = marshalledParameters[1].Reference.ToInt32();

                    // elWdw.ExecuteUncommittedRepetition(inclTopics: true, forceDisplay: false);
                    Delphi.registerCall3(_callTable[NativeMethod.ElWdw_ExecuteUncommittedRepetition],
                                         elWdw,
                                         1,
                                         0);

                    // elWdw.ScheduleInInterval(interval);
                    Delphi.registerCall2(_callTable[NativeMethod.ElWdw_ScheduleInInterval],
                                         elWdw,
                                         interval);

                    // elWdw.SetElementState(DisplayState.Display);
                    //registerCall2(_callTable[NativeMethod.ElWdw_SetElementState],
                    //              elWdw,
                    //              2);

                    // elWdw.NextElementInLearningQueue()
                    Delphi.registerCall1(_callTable[NativeMethod.ElWdw_NextElementInLearningQueue],
                                         elWdw);

                    return(1);

                case NativeMethod.ForceRepetitionAndResume:
                    elWdw    = marshalledParameters[0].Reference.ToInt32();
                    interval = marshalledParameters[1].Reference.ToInt32();
                    var adjustPriority = marshalledParameters[2].Reference.ToInt32();

                    // elWdw.ForceRepetitionExt(interval, adjustPriority);
                    Delphi.registerCall3(_callTable[NativeMethod.ElWdw_ForceRepetitionExt],
                                         elWdw,
                                         interval,
                                         adjustPriority);

                    // elWdw.NextElementInLearningQueue();
                    Delphi.registerCall1(_callTable[NativeMethod.ElWdw_NextElementInLearningQueue],
                                         elWdw);

                    // elWdw.RestoreLearningMode();
                    Delphi.registerCall1(_callTable[NativeMethod.ElWdw_RestoreLearningMode],
                                         elWdw);

                    return(1);
                }

                switch (parameters.Length)
                {
                case 1:
                    return(Delphi.registerCall1(_callTable[method],
                                                marshalledParameters[0].Reference.ToInt32()));

                case 2:
                    return(Delphi.registerCall2(_callTable[method],
                                                marshalledParameters[0].Reference.ToInt32(),
                                                marshalledParameters[1].Reference.ToInt32()));

                case 3:
                    return(Delphi.registerCall3(_callTable[method],
                                                marshalledParameters[0].Reference.ToInt32(),
                                                marshalledParameters[1].Reference.ToInt32(),
                                                marshalledParameters[2].Reference.ToInt32()));

                case 4:
                    return(Delphi.registerCall4(_callTable[method],
                                                marshalledParameters[0].Reference.ToInt32(),
                                                marshalledParameters[1].Reference.ToInt32(),
                                                marshalledParameters[2].Reference.ToInt32(),
                                                marshalledParameters[3].Reference.ToInt32()));

                case 5:
                    return(Delphi.registerCall5(_callTable[method],
                                                marshalledParameters[0].Reference.ToInt32(),
                                                marshalledParameters[1].Reference.ToInt32(),
                                                marshalledParameters[2].Reference.ToInt32(),
                                                marshalledParameters[3].Reference.ToInt32(),
                                                marshalledParameters[4].Reference.ToInt32()));

                case 6:
                    return(Delphi.registerCall6(_callTable[method],
                                                marshalledParameters[0].Reference.ToInt32(),
                                                marshalledParameters[1].Reference.ToInt32(),
                                                marshalledParameters[2].Reference.ToInt32(),
                                                marshalledParameters[3].Reference.ToInt32(),
                                                marshalledParameters[4].Reference.ToInt32(),
                                                marshalledParameters[5].Reference.ToInt32()));

                default:
                    throw new NotImplementedException($"No execution path to handle {parameters.Length} parameters.");
                }
            }
            finally
            {
                foreach (var param in marshalledParameters)
                {
                    param.Dispose();
                }
            }
        }
Ejemplo n.º 15
0
        protected int CallNativeMethod(NativeMethod method,
                                       dynamic[]    parameters)
        {
            var marshalledParameters =
                parameters.Select(p => MarshalValue.Marshal(_smProcess,
                                                            p))
                .Cast <IMarshalledValue>().ToArray();

            try
            {
                switch (method)
                {
                case NativeMethod.AppendAndAddElementFromText:
                    var elWdw  = marshalledParameters[0].Reference.ToInt32();
                    var elType = marshalledParameters[1].Reference.ToInt32();
                    var elDesc = marshalledParameters[2].Reference.ToInt32();

                    // elWdw.AppendElement(elType, automatic: false);
                    int elemId = Delphi.registerCall3(_callTable[NativeMethod.ElWdwAppendElement],
                                                      elWdw,
                                                      elType,
                                                      0);

                    if (elemId <= 0)
                    {
                        return(-1);
                    }

                    // elWdw.AddElementFromText(elDesc);
                    int res = Delphi.registerCall2(_callTable[NativeMethod.ElWdwAddElementFromText],
                                                   elWdw,
                                                   elDesc);

                    return(res > 0 ? elemId : -1);


                case NativeMethod.PostponeRepetition:
                    elWdw = marshalledParameters[0].Reference.ToInt32();
                    var interval = marshalledParameters[1].Reference.ToInt32();

                    // elWdw.ExecuteUncommitedRepetition(inclTopics: true, forceDisplay: false);
                    Delphi.registerCall3(_callTable[NativeMethod.ElWdwExecuteUncommitedRepetition],
                                         elWdw,
                                         1,
                                         0);

                    // elWdw.ScheduleInInterval(interval);
                    Delphi.registerCall2(_callTable[NativeMethod.ElWdwScheduleInInterval],
                                         elWdw,
                                         interval);

                    // elWdw.SetElementState(DisplayState.Display);
                    //registerCall2(_callTable[NativeMethod.ElWdwSetElementState],
                    //              elWdw,
                    //              2);

                    // elWdw.NextElementInLearningQueue()
                    Delphi.registerCall1(_callTable[NativeMethod.ElWdwNextElementInLearningQueue],
                                         elWdw);

                    return(1);

                case NativeMethod.ForceRepetitionAndResume:
                    elWdw    = marshalledParameters[0].Reference.ToInt32();
                    interval = marshalledParameters[1].Reference.ToInt32();
                    var adjustPriority = marshalledParameters[2].Reference.ToInt32();

                    // elWdw.ForceRepetitionExt(interval, adjustPriority);
                    Delphi.registerCall3(_callTable[NativeMethod.ElWdwForceRepetitionExt],
                                         elWdw,
                                         interval,
                                         adjustPriority);

                    // elWdw.NextElementInLearningQueue();
                    Delphi.registerCall1(_callTable[NativeMethod.ElWdwNextElementInLearningQueue],
                                         elWdw);

                    // elWdw.RestoreLearningMode();
                    Delphi.registerCall1(_callTable[NativeMethod.ElWdwRestoreLearningMode],
                                         elWdw);

                    return(1);
                }

                switch (parameters.Length)
                {
                case 1:
                    return(Delphi.registerCall1(_callTable[method],
                                                marshalledParameters[0].Reference.ToInt32()));

                case 2:
                    return(Delphi.registerCall2(_callTable[method],
                                                marshalledParameters[0].Reference.ToInt32(),
                                                marshalledParameters[1].Reference.ToInt32()));

                case 3:
                    return(Delphi.registerCall3(_callTable[method],
                                                marshalledParameters[0].Reference.ToInt32(),
                                                marshalledParameters[1].Reference.ToInt32(),
                                                marshalledParameters[2].Reference.ToInt32()));

                case 4:
                    return(Delphi.registerCall4(_callTable[method],
                                                marshalledParameters[0].Reference.ToInt32(),
                                                marshalledParameters[1].Reference.ToInt32(),
                                                marshalledParameters[2].Reference.ToInt32(),
                                                marshalledParameters[3].Reference.ToInt32()));

                case 5:
                    return(Delphi.registerCall5(_callTable[method],
                                                marshalledParameters[0].Reference.ToInt32(),
                                                marshalledParameters[1].Reference.ToInt32(),
                                                marshalledParameters[2].Reference.ToInt32(),
                                                marshalledParameters[3].Reference.ToInt32(),
                                                marshalledParameters[4].Reference.ToInt32()));

                case 6:
                    return(Delphi.registerCall6(_callTable[method],
                                                marshalledParameters[0].Reference.ToInt32(),
                                                marshalledParameters[1].Reference.ToInt32(),
                                                marshalledParameters[2].Reference.ToInt32(),
                                                marshalledParameters[3].Reference.ToInt32(),
                                                marshalledParameters[4].Reference.ToInt32(),
                                                marshalledParameters[5].Reference.ToInt32()));

                default:
                    throw new NotImplementedException($"No execution path to handle {parameters.Length} parameters.");
                }
            }
            finally
            {
                foreach (var param in marshalledParameters)
                {
                    param.Dispose();
                }
            }
        }
Ejemplo n.º 16
0
        protected int CallNativeMethod(NativeMethod method,
                                       dynamic[]    parameters)
        {
            var marshalledParameters =
                parameters.Select(p => MarshalValue.Marshal(SMProcess,
                                                            p))
                .Cast <IMarshalledValue>().ToArray();

            try
            {
                switch (method)
                {
                case NativeMethod.AppendAndAddElementFromText:
                    var elWdw  = marshalledParameters[0].Reference.ToInt32();
                    var elType = marshalledParameters[1].Reference.ToInt32();
                    var elDesc = marshalledParameters[2].Reference.ToInt32();

                    int elemId = registerCall3(CallTable[NativeMethod.ElWdwAppendElement],
                                               elWdw,
                                               elType,
                                               0);

                    if (elemId <= 0)
                    {
                        return(-1);
                    }

                    int res = registerCall2(CallTable[NativeMethod.ElWdwAddElementFromText],
                                            elWdw,
                                            elDesc);

                    return(res > 0 ? elemId : -1);
                }

                switch (parameters.Length)
                {
                case 1:
                    return(registerCall1(CallTable[method],
                                         marshalledParameters[0].Reference.ToInt32()));

                case 2:
                    return(registerCall2(CallTable[method],
                                         marshalledParameters[0].Reference.ToInt32(),
                                         marshalledParameters[1].Reference.ToInt32()));

                case 3:
                    return(registerCall3(CallTable[method],
                                         marshalledParameters[0].Reference.ToInt32(),
                                         marshalledParameters[1].Reference.ToInt32(),
                                         marshalledParameters[2].Reference.ToInt32()));

                case 4:
                    return(registerCall4(CallTable[method],
                                         marshalledParameters[0].Reference.ToInt32(),
                                         marshalledParameters[1].Reference.ToInt32(),
                                         marshalledParameters[2].Reference.ToInt32(),
                                         marshalledParameters[3].Reference.ToInt32()));

                case 5:
                    return(registerCall5(CallTable[method],
                                         marshalledParameters[0].Reference.ToInt32(),
                                         marshalledParameters[1].Reference.ToInt32(),
                                         marshalledParameters[2].Reference.ToInt32(),
                                         marshalledParameters[3].Reference.ToInt32(),
                                         marshalledParameters[4].Reference.ToInt32()));

                case 6:
                    return(registerCall6(CallTable[method],
                                         marshalledParameters[0].Reference.ToInt32(),
                                         marshalledParameters[1].Reference.ToInt32(),
                                         marshalledParameters[2].Reference.ToInt32(),
                                         marshalledParameters[3].Reference.ToInt32(),
                                         marshalledParameters[4].Reference.ToInt32(),
                                         marshalledParameters[5].Reference.ToInt32()));

                default:
                    throw new NotImplementedException($"No execution path to handle {parameters.Length} parameters.");
                }
            }
            finally
            {
                foreach (var param in marshalledParameters)
                {
                    param.Dispose();
                }
            }
        }