通过 DTM_SETSYSTEMTIME 更新另一个进程中的 dateTimePicker

发布于 2024-10-18 00:13:22 字数 499 浏览 1 评论 0原文

我正在尝试使用 DTM_SETSYSTEMTIME 更新另一个应用程序中的 dateTimeController 。

bool retVal = false;
ushort GDT_VALID = 0;

SYSTEMTIME td = new SYSTEMTIME();
td.wYear = 1990;
td.wMonth = 4;
td.wDay = 2;
td.wDayOfWeek = 0;
td.wHour = 0;
td.wMilliseconds = 0;
td.wMinute = 0;
td.wSecond = 0;

int erc = SendMessage(handle, DTM_SETSYSTEMTIME, GDT_VALID, ref td);

不幸的是,尝试失败了,选择器没有更新,每次返回值都为零。 重要的是,在我执行 SendMessage 命令后,具有 dataTimePicker 的应用程序有时会给出非法内存访问异常的错误消息。

有人能帮我解决这个问题吗?

I am trying to update the dateTimeController in another application using DTM_SETSYSTEMTIME.

bool retVal = false;
ushort GDT_VALID = 0;

SYSTEMTIME td = new SYSTEMTIME();
td.wYear = 1990;
td.wMonth = 4;
td.wDay = 2;
td.wDayOfWeek = 0;
td.wHour = 0;
td.wMilliseconds = 0;
td.wMinute = 0;
td.wSecond = 0;

int erc = SendMessage(handle, DTM_SETSYSTEMTIME, GDT_VALID, ref td);

Unfortunately the attempt was failed, the picker is not updated, every time return value is zero.
Important thing is occasionally the application having the dataTimePicker gives an error message that illegal memory access exception after I execute the SendMessage command.

Can anybody help me to fix this up ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

蔚蓝源自深海 2024-10-25 00:13:22

是的,无法工作。 SendMessage 的第四个参数是指向 SYSTEMTIME 的指针。该指针值仅在您的进程中有效,而不是在拥有该控件的进程中有效。使用该指针值使目标应用程序崩溃是很有可能的。您需要

  • 在目标进程上调用 OpenProcess() 来获取其句柄
  • 调用 VirtualAllocEx() 在目标进程中分配内存
  • 调用 WriteProcessMemory() 将 SYSTEMTIME 值从进程复制到目标进程
  • 调用 SendMessage,使用指针值您从 VirtualAllocEx
  • 调用 VirtualFreeEx() 来释放内存,
  • 调用 CloseHandle() 来释放进程句柄。

这里可能会出现很多问题,首先是 UAC 阻止您执行这些高度特权的 API 函数。这个函数的名字很适合谷歌,你应该很容易找到示例代码。

Yes, cannot work. The 4th argument to SendMessage is a pointer to SYSTEMTIME. The pointer value is only valid in your process, not the one that owns the control. Crashing the target app with that pointer value is quite possible. You will need to

  • call OpenProcess() on the target process to obtain its handle
  • call VirtualAllocEx() to allocate memory in the target process
  • call WriteProcessMemory() to copy the SYSTEMTIME value from your process to the target process
  • call SendMessage, using the pointer value you got from VirtualAllocEx
  • call VirtualFreeEx() to release the memory
  • call CloseHandle() to release the process handle.

Lots of things that can go wrong here, starting with UAC stopping you from executing these highly privileged API functions. The function names google well, you should have little trouble finding sample code.

失而复得 2024-10-25 00:13:22

您的信息对我解决问题非常有帮助。以下是代码。

private static bool injectMemory(IntPtr windowHandle, byte[] buffer, out IntPtr hndProc, out IntPtr lpAddress)
    {
        hndProc = IntPtr.Zero;
        lpAddress = IntPtr.Zero;
        //open local process object
        Process mainWindowProcess = FindProcess(windowHandle);
        hndProc = OpenProcess(
            (0x2 | 0x8 | 0x10 | 0x20 | 0x400), //create thread, query info, operation 
            //write, and read 
            1,
            (uint)mainWindowProcess.Id);
        if (hndProc == (IntPtr)0)
        {
            Console.WriteLine("Unable to attach process");
            return false;
        }
        //allocate memory for process object
        lpAddress = VirtualAllocEx(hndProc, (IntPtr)null, (uint)buffer.Length,
             AllocationType.Commit | AllocationType.Reserve, MemoryProtection.ExecuteReadWrite);
        if (lpAddress == (IntPtr)0)
        {
            Console.WriteLine("Unable to allocate memory to target proces");
            return false;
        }
        //wite data
        uint wrotelen = 0;
        WriteProcessMemory(hndProc, lpAddress, buffer, (uint)buffer.Length, out wrotelen);
        if (Marshal.GetLastWin32Error() != 0)
        {
            Console.WriteLine("Unable to write memory to process.");
            return false;
        }
        return true;
    }

方法被调用,

        int structMemLen =  Marshal.SizeOf(typeof(SYSTEMTIME));
        byte[] buffer = new byte[structMemLen];
        ushort GDT_VALID = 0;
        SYSTEMTIME sysTime = new SYSTEMTIME();
        //Assign the values as you prefer

        IntPtr dataPtr = Marshal.AllocHGlobal(structMemLen);
        Marshal.StructureToPtr(sysTime, dataPtr, true);
        Marshal.Copy(dataPtr, buffer, 0, structMemLen);
        Marshal.FreeHGlobal(dataPtr);

        IntPtr hndProc = IntPtr.Zero;
        IntPtr lpAddress = IntPtr.Zero;
        injectMemory(mainWindowHandle, buffer, out hndProc, out lpAddress); 
        SendMessage(handle, DTM_SETSYSTEMTIME, (IntPtr)GDT_VALID, lpAddress);
        CloseHandle(hndProc);

Your information is really helpful for me to fix my issue. Following is the code.

private static bool injectMemory(IntPtr windowHandle, byte[] buffer, out IntPtr hndProc, out IntPtr lpAddress)
    {
        hndProc = IntPtr.Zero;
        lpAddress = IntPtr.Zero;
        //open local process object
        Process mainWindowProcess = FindProcess(windowHandle);
        hndProc = OpenProcess(
            (0x2 | 0x8 | 0x10 | 0x20 | 0x400), //create thread, query info, operation 
            //write, and read 
            1,
            (uint)mainWindowProcess.Id);
        if (hndProc == (IntPtr)0)
        {
            Console.WriteLine("Unable to attach process");
            return false;
        }
        //allocate memory for process object
        lpAddress = VirtualAllocEx(hndProc, (IntPtr)null, (uint)buffer.Length,
             AllocationType.Commit | AllocationType.Reserve, MemoryProtection.ExecuteReadWrite);
        if (lpAddress == (IntPtr)0)
        {
            Console.WriteLine("Unable to allocate memory to target proces");
            return false;
        }
        //wite data
        uint wrotelen = 0;
        WriteProcessMemory(hndProc, lpAddress, buffer, (uint)buffer.Length, out wrotelen);
        if (Marshal.GetLastWin32Error() != 0)
        {
            Console.WriteLine("Unable to write memory to process.");
            return false;
        }
        return true;
    }

Method is called by,

        int structMemLen =  Marshal.SizeOf(typeof(SYSTEMTIME));
        byte[] buffer = new byte[structMemLen];
        ushort GDT_VALID = 0;
        SYSTEMTIME sysTime = new SYSTEMTIME();
        //Assign the values as you prefer

        IntPtr dataPtr = Marshal.AllocHGlobal(structMemLen);
        Marshal.StructureToPtr(sysTime, dataPtr, true);
        Marshal.Copy(dataPtr, buffer, 0, structMemLen);
        Marshal.FreeHGlobal(dataPtr);

        IntPtr hndProc = IntPtr.Zero;
        IntPtr lpAddress = IntPtr.Zero;
        injectMemory(mainWindowHandle, buffer, out hndProc, out lpAddress); 
        SendMessage(handle, DTM_SETSYSTEMTIME, (IntPtr)GDT_VALID, lpAddress);
        CloseHandle(hndProc);
我要还你自由 2024-10-25 00:13:22
using System;
using System.Security;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Runtime.ConstrainedExecution;

namespace DateTimePicker.Helpers
{
    [Flags]
    public enum ProcessAccessFlags : uint
    {
        All = 0x001F0FFF,
        Terminate = 0x00000001,
        CreateThread = 0x00000002,
        VirtualMemoryOperation = 0x00000008,
        VirtualMemoryRead = 0x00000010,
        VirtualMemoryWrite = 0x00000020,
        DuplicateHandle = 0x00000040,
        CreateProcess = 0x000000080,
        SetQuota = 0x00000100,
        SetInformation = 0x00000200,
        QueryInformation = 0x00000400,
        QueryLimitedInformation = 0x00001000,
        Synchronize = 0x00100000
    }

    [Flags]
    public enum AllocationType : uint
    {
        Commit = 0x1000,
        Reserve = 0x2000,
        Decommit = 0x4000,
        Release = 0x8000,
        Reset = 0x80000,
        Physical = 0x400000,
        TopDown = 0x100000,
        WriteWatch = 0x200000,
        LargePages = 0x20000000
    }

    [Flags]
    public enum MemoryProtection : uint
    {
        Execute = 0x10,
        ExecuteRead = 0x20,
        ExecuteReadWrite = 0x40,
        ExecuteWriteCopy = 0x80,
        NoAccess = 0x01,
        ReadOnly = 0x02,
        ReadWrite = 0x04,
        WriteCopy = 0x08,
        GuardModifierflag = 0x100,
        NoCacheModifierflag = 0x200,
        WriteCombineModifierflag = 0x400
    }

    public class DateTimePickerNativeMethods
    {
        private const int DTM_GETSYSTEMTIME = 0x1001;
        private const int DTM_SETSYSTEMTIME = 0x1002;

        public static DateTime GetDateTime(IntPtr hwnd)
        {
            var hProcess = TryOpenProcess(hwnd);
            var typeSize = Marshal.SizeOf(typeof(SYSTEMTIME));

            var hMem = VirtualAllocEx(hProcess, IntPtr.Zero, (uint)typeSize, (uint)(AllocationType.Commit | AllocationType.Reserve), (uint)MemoryProtection.ReadWrite);
            var lResult = NativeMethods.SendMessage(hwnd, DTM_GETSYSTEMTIME, IntPtr.Zero, hMem);
            var address = Marshal.AllocHGlobal(typeSize);
            if (ReadProcessMemory(hProcess, hMem, address, typeSize, out IntPtr lpNumberOfBytesRead) == false)
            {
                throw new Exception();
            }

            var systemtime = (SYSTEMTIME)Marshal.PtrToStructure(address, typeof(SYSTEMTIME));

            Marshal.FreeHGlobal(address);
            VirtualFreeEx(hProcess, hMem, typeSize, AllocationType.Decommit | AllocationType.Release);
            CloseHandle(hProcess);

            return new DateTime(systemtime.Year, systemtime.Month, systemtime.Day, systemtime.Hour, systemtime.Minute, systemtime.Second);
        }

        public static void SetDateTime(IntPtr hwnd, DateTime dateTime)
        {
            var typeSize = Marshal.SizeOf(typeof(SYSTEMTIME));
            var buffer = new byte[typeSize];

            var data = Marshal.AllocHGlobal(typeSize);
            Marshal.StructureToPtr(new SYSTEMTIME(dateTime), data, true);
            Marshal.Copy(data, buffer, 0, typeSize);
            Marshal.FreeHGlobal(data);

            CreateMemory(hwnd, buffer, out IntPtr hwndProc, out IntPtr lpAddress);
            NativeMethods.SendMessage(hwnd, DTM_SETSYSTEMTIME, IntPtr.Zero, lpAddress);
            CloseHandle(hwndProc);
        }

        private static void CreateMemory(IntPtr windowHandle, byte[] buffer, out IntPtr hwndProc, out IntPtr lpAddress)
        {
            hwndProc = TryOpenProcess(windowHandle);
            lpAddress = TryGetLParamAddress(hwndProc, buffer.Length);
            TryWriteProcessMemory(hwndProc, lpAddress, buffer);
        }        

        private static IntPtr TryOpenProcess(IntPtr hwnd)
        {
            var process = FindProcess(hwnd);
            var hwndProcess = OpenProcess(process, ProcessAccessFlags.All);
            if (hwndProcess == IntPtr.Zero)
            {
                throw new Exception("failed to open process");
            }
            return hwndProcess;
        }

        private static IntPtr TryGetLParamAddress(IntPtr hwndProc, int length)
        {
            var lpAddress = VirtualAllocEx(
                hwndProc,
                (IntPtr)null,
                (uint)length,
                (uint)(AllocationType.Commit | AllocationType.Reserve),
                (uint)MemoryProtection.ExecuteReadWrite)
                ;

            if (lpAddress == IntPtr.Zero)
            {
                throw new Exception();
            }

            return lpAddress;
        }

        private static void TryWriteProcessMemory(IntPtr hwndProc, IntPtr lpAddress, byte[] buffer)
        {
            WriteProcessMemory(hwndProc, lpAddress, buffer, buffer.Length, out IntPtr wrotelen);
            if (Marshal.GetLastWin32Error() != 0)
            {
                throw new Exception();
            }
        }

        private static Process FindProcess(IntPtr windowHandle)
        {
            var automationElement = System.Windows.Automation.AutomationElement.FromHandle(windowHandle);
            var process = Process.GetProcessById(automationElement.Current.ProcessId);
            return process;
        }

        #region Win32 methods
        [DllImport("kernel32.dll", SetLastError = true)]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
        [SuppressUnmanagedCodeSecurity]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool CloseHandle(IntPtr hObject);

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, int nSize, out IntPtr lpNumberOfBytesWritten);

        [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
        public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern IntPtr OpenProcess(uint processAccess, bool bInheritHandle, uint processId);
        public static IntPtr OpenProcess(Process proc, ProcessAccessFlags flags)
        {
            return OpenProcess((uint)flags, false, (uint)proc.Id);
        }

        [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
        public static extern bool VirtualFreeEx(IntPtr hProcess, IntPtr lpAddress, int dwSize, AllocationType dwFreeType);

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer, int dwSize, out IntPtr lpNumberOfBytesRead);
        #endregion
    }
}
using System;
using System.Security;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Runtime.ConstrainedExecution;

namespace DateTimePicker.Helpers
{
    [Flags]
    public enum ProcessAccessFlags : uint
    {
        All = 0x001F0FFF,
        Terminate = 0x00000001,
        CreateThread = 0x00000002,
        VirtualMemoryOperation = 0x00000008,
        VirtualMemoryRead = 0x00000010,
        VirtualMemoryWrite = 0x00000020,
        DuplicateHandle = 0x00000040,
        CreateProcess = 0x000000080,
        SetQuota = 0x00000100,
        SetInformation = 0x00000200,
        QueryInformation = 0x00000400,
        QueryLimitedInformation = 0x00001000,
        Synchronize = 0x00100000
    }

    [Flags]
    public enum AllocationType : uint
    {
        Commit = 0x1000,
        Reserve = 0x2000,
        Decommit = 0x4000,
        Release = 0x8000,
        Reset = 0x80000,
        Physical = 0x400000,
        TopDown = 0x100000,
        WriteWatch = 0x200000,
        LargePages = 0x20000000
    }

    [Flags]
    public enum MemoryProtection : uint
    {
        Execute = 0x10,
        ExecuteRead = 0x20,
        ExecuteReadWrite = 0x40,
        ExecuteWriteCopy = 0x80,
        NoAccess = 0x01,
        ReadOnly = 0x02,
        ReadWrite = 0x04,
        WriteCopy = 0x08,
        GuardModifierflag = 0x100,
        NoCacheModifierflag = 0x200,
        WriteCombineModifierflag = 0x400
    }

    public class DateTimePickerNativeMethods
    {
        private const int DTM_GETSYSTEMTIME = 0x1001;
        private const int DTM_SETSYSTEMTIME = 0x1002;

        public static DateTime GetDateTime(IntPtr hwnd)
        {
            var hProcess = TryOpenProcess(hwnd);
            var typeSize = Marshal.SizeOf(typeof(SYSTEMTIME));

            var hMem = VirtualAllocEx(hProcess, IntPtr.Zero, (uint)typeSize, (uint)(AllocationType.Commit | AllocationType.Reserve), (uint)MemoryProtection.ReadWrite);
            var lResult = NativeMethods.SendMessage(hwnd, DTM_GETSYSTEMTIME, IntPtr.Zero, hMem);
            var address = Marshal.AllocHGlobal(typeSize);
            if (ReadProcessMemory(hProcess, hMem, address, typeSize, out IntPtr lpNumberOfBytesRead) == false)
            {
                throw new Exception();
            }

            var systemtime = (SYSTEMTIME)Marshal.PtrToStructure(address, typeof(SYSTEMTIME));

            Marshal.FreeHGlobal(address);
            VirtualFreeEx(hProcess, hMem, typeSize, AllocationType.Decommit | AllocationType.Release);
            CloseHandle(hProcess);

            return new DateTime(systemtime.Year, systemtime.Month, systemtime.Day, systemtime.Hour, systemtime.Minute, systemtime.Second);
        }

        public static void SetDateTime(IntPtr hwnd, DateTime dateTime)
        {
            var typeSize = Marshal.SizeOf(typeof(SYSTEMTIME));
            var buffer = new byte[typeSize];

            var data = Marshal.AllocHGlobal(typeSize);
            Marshal.StructureToPtr(new SYSTEMTIME(dateTime), data, true);
            Marshal.Copy(data, buffer, 0, typeSize);
            Marshal.FreeHGlobal(data);

            CreateMemory(hwnd, buffer, out IntPtr hwndProc, out IntPtr lpAddress);
            NativeMethods.SendMessage(hwnd, DTM_SETSYSTEMTIME, IntPtr.Zero, lpAddress);
            CloseHandle(hwndProc);
        }

        private static void CreateMemory(IntPtr windowHandle, byte[] buffer, out IntPtr hwndProc, out IntPtr lpAddress)
        {
            hwndProc = TryOpenProcess(windowHandle);
            lpAddress = TryGetLParamAddress(hwndProc, buffer.Length);
            TryWriteProcessMemory(hwndProc, lpAddress, buffer);
        }        

        private static IntPtr TryOpenProcess(IntPtr hwnd)
        {
            var process = FindProcess(hwnd);
            var hwndProcess = OpenProcess(process, ProcessAccessFlags.All);
            if (hwndProcess == IntPtr.Zero)
            {
                throw new Exception("failed to open process");
            }
            return hwndProcess;
        }

        private static IntPtr TryGetLParamAddress(IntPtr hwndProc, int length)
        {
            var lpAddress = VirtualAllocEx(
                hwndProc,
                (IntPtr)null,
                (uint)length,
                (uint)(AllocationType.Commit | AllocationType.Reserve),
                (uint)MemoryProtection.ExecuteReadWrite)
                ;

            if (lpAddress == IntPtr.Zero)
            {
                throw new Exception();
            }

            return lpAddress;
        }

        private static void TryWriteProcessMemory(IntPtr hwndProc, IntPtr lpAddress, byte[] buffer)
        {
            WriteProcessMemory(hwndProc, lpAddress, buffer, buffer.Length, out IntPtr wrotelen);
            if (Marshal.GetLastWin32Error() != 0)
            {
                throw new Exception();
            }
        }

        private static Process FindProcess(IntPtr windowHandle)
        {
            var automationElement = System.Windows.Automation.AutomationElement.FromHandle(windowHandle);
            var process = Process.GetProcessById(automationElement.Current.ProcessId);
            return process;
        }

        #region Win32 methods
        [DllImport("kernel32.dll", SetLastError = true)]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
        [SuppressUnmanagedCodeSecurity]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool CloseHandle(IntPtr hObject);

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, int nSize, out IntPtr lpNumberOfBytesWritten);

        [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
        public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern IntPtr OpenProcess(uint processAccess, bool bInheritHandle, uint processId);
        public static IntPtr OpenProcess(Process proc, ProcessAccessFlags flags)
        {
            return OpenProcess((uint)flags, false, (uint)proc.Id);
        }

        [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
        public static extern bool VirtualFreeEx(IntPtr hProcess, IntPtr lpAddress, int dwSize, AllocationType dwFreeType);

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer, int dwSize, out IntPtr lpNumberOfBytesRead);
        #endregion
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文