精易论坛

标题: 50¥求助可以hook到这个按钮触发事件 [打印本页]

作者: 叙利亚的咕咕鸡    时间: 2026-1-9 17:27
标题: 50¥求助可以hook到这个按钮触发事件
请问有没有大佬可以hook到这个按钮触发的事件
我是用的c#语言

/// <summary>
/// 重新加载所有NPC(优先M2Server窗口 → 兜底GameCenter.exe窗口)
/// </summary>
/// <returns>是否执行成功</returns>
public static bool ReloadMirServerNpc()
{
    try
    {
        if (!IsConnection)
        {
            throw new Exception("连接未开启,请先开启连接。");
        }

        // 定义窗口标题常量
        string M2ServerWindowTitle = "M2Server";
        string GameCenterWindowTitle = "GameCenter";
        string TMainmenuClassName = "TFormMain";

        IntPtr targetWindowHandle = IntPtr.Zero;
        string windowType = string.Empty;

        // 1. 优先查找M2Server窗口
        targetWindowHandle = FindWindow(null, M2ServerWindowTitle);
        if (targetWindowHandle != IntPtr.Zero)
        {
            windowType = "M2Server";
            Console.WriteLine($"找到M2Server窗口,句柄:0x{targetWindowHandle.ToInt64():X}");
        }
        else
        {
            // 2. 兜底查找GameCenter窗口
            targetWindowHandle = FindWindow(null, GameCenterWindowTitle);
            if (targetWindowHandle != IntPtr.Zero)
            {
                windowType = "GameCenter";
                Console.WriteLine($"找到GameCenter窗口,句柄:0x{targetWindowHandle.ToInt64():X}");
            }
        }

        // 3. 如果两个窗口都未找到,弹出错误提示
        if (targetWindowHandle == IntPtr.Zero)
        {
            string errorMsg = "未找到M2Server或GameCenter窗口,请确保服务端已启动!";
            throw new Exception(errorMsg);
        }

        IntPtr mainmenuHandle = FindWindowEx(targetWindowHandle, IntPtr.Zero, TMainmenuClassName, null);

        if (mainmenuHandle != IntPtr.Zero)
        {
            Console.WriteLine($"找到TMainmenu控件,句柄:0x{mainmenuHandle.ToInt64():X}");

            // 获取控件信息(可选)
            StringBuilder className = new StringBuilder(256);
            GetClassName(mainmenuHandle, className, className.Capacity);
            Console.WriteLine($"控件类名:{className}");

            // TODO: 在这里添加您的NPC重新加载逻辑
            // 例如:模拟点击菜单项、发送消息等操作

            // 示例:获取控件文本
            StringBuilder text = new StringBuilder(256);
            GetWindowText(mainmenuHandle, text, text.Capacity);
            Console.WriteLine($"控件文本:{text}");

            // 示例:模拟点击
            // SendMessage(mainmenuHandle, WM_LBUTTONDOWN, IntPtr.Zero, IntPtr.Zero);
            // SendMessage(mainmenuHandle, WM_LBUTTONUP, IntPtr.Zero, IntPtr.Zero);

            return true;
        }
        else
        {
            string errorMsg = $"在{windowType}窗口中未找到TMainmenu控件!";

            throw new Exception(errorMsg);
        }

    }
    catch (Exception ex)
    {
        throw ex;
    }
}

要如何才能取到这个事件执行方式呢?请大佬教一下,我本地有ce 和 64dbg,请大佬远程帮我调一下。传不上图片。。。

qq:745223613




作者: qf123    时间: 2026-1-9 17:39
  
using System;
using System.Text;
using System.Runtime.InteropServices;
using System.Threading;
public class MirServerNpcReloader
{
public static bool IsConnection { get; set; } = true;
public static class Win32Api
{
[DllImport ("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern IntPtr FindWindow (string lpClassName, string lpWindowName);
[DllImport ("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern IntPtr FindWindowEx (IntPtr hwndParent, IntPtr hwndChildAfter, string lpClassName, string lpWindowName);
[DllImport ("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern IntPtr SendMessage (IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
[DllImport ("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int GetClassName (IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
[DllImport ("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int GetWindowText (IntPtr hWnd, StringBuilder lpString, int nMaxCount);
public const uint BM_CLICK = 0x00F5;
public const uint WM_LBUTTONDOWN = 0x0201;
public const uint WM_LBUTTONUP = 0x0202;
}
public static bool ReloadMirServerNpc ()
{
try
{
if (!IsConnection)
{
throw new Exception ("连接未开启,请先开启连接。");
}
string M2ServerWindowTitle = "M2Server";
string GameCenterWindowTitle = "GameCenter";
string TMainmenuClassName = "TFormMain";
IntPtr targetWindowHandle = IntPtr.Zero;
string windowType = string.Empty;
targetWindowHandle = Win32Api.FindWindow (null, M2ServerWindowTitle);
if (targetWindowHandle != IntPtr.Zero)
{
windowType = "M2Server";
Console.WriteLine ($"找到M2Server窗口,句柄:0x{targetWindowHandle.ToInt64 ():X}");
}
else
{
targetWindowHandle = Win32Api.FindWindow (null, GameCenterWindowTitle);
if (targetWindowHandle != IntPtr.Zero)
{
windowType = "GameCenter";
Console.WriteLine ($"找到GameCenter窗口,句柄:0x{targetWindowHandle.ToInt64 ():X}");
}
}
if (targetWindowHandle == IntPtr.Zero)
{
string errorMsg = "未找到M2Server或GameCenter窗口,请确保服务端已启动!";
throw new Exception (errorMsg);
}
IntPtr mainmenuHandle = Win32Api.FindWindowEx (targetWindowHandle, IntPtr.Zero, TMainmenuClassName, null);
if (mainmenuHandle != IntPtr.Zero)
{
Console.WriteLine ($"找到TMainmenu控件,句柄:0x{mainmenuHandle.ToInt64 ():X}");
StringBuilder className = new StringBuilder (256);
Win32Api.GetClassName (mainmenuHandle, className, className.Capacity);
Console.WriteLine ($"控件类名:{className}");
StringBuilder text = new StringBuilder (256);
Win32Api.GetWindowText (mainmenuHandle, text, text.Capacity);
Console.WriteLine ($"控件文本:{text}");
IntPtr clickResult = Win32Api.SendMessage (mainmenuHandle, Win32Api.BM_CLICK, IntPtr.Zero, IntPtr.Zero);
if (clickResult != IntPtr.Zero)
{
Console.WriteLine ("成功发送按钮点击消息,触发NPC重载事件");
}
else
{
Win32Api.SendMessage (mainmenuHandle, Win32Api.WM_LBUTTONDOWN, IntPtr.Zero, IntPtr.Zero);
Thread.Sleep (50);
Win32Api.SendMessage (mainmenuHandle, Win32Api.WM_LBUTTONUP, IntPtr.Zero, IntPtr.Zero);
Console.WriteLine ("成功发送鼠标模拟消息,触发NPC重载事件");
}
return true;
}
else
{
string errorMsg = $"在{windowType}窗口中未找到TMainmenu控件!";
throw new Exception (errorMsg);
}
}
catch (Exception ex)
{
Console.WriteLine ($"执行失败:{ex.Message}");
throw;
}
}
public static class ButtonHook
{
private delegate IntPtr HookProc (int nCode, IntPtr wParam, IntPtr lParam);
private static HookProc _mouseHookProc;
private static IntPtr _mouseHookHandle = IntPtr.Zero;
private static IntPtr _targetControlHandle = IntPtr.Zero;
[DllImport ("user32.dll", SetLastError = true)]
private static extern IntPtr SetWindowsHookEx (int idHook, HookProc lpfn, IntPtr hMod, uint dwThreadId);
[DllImport ("user32.dll", SetLastError = true)]
private static extern bool UnhookWindowsHookEx (IntPtr hhk);
[DllImport ("user32.dll", SetLastError = true)]
private static extern IntPtr CallNextHookEx (IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
[DllImport ("kernel32.dll", SetLastError = true)]
private static extern IntPtr GetModuleHandle (string lpModuleName);
private const int WH_MOUSE_LL = 14;
private const int WM_LBUTTONUP = 0x0202;
[DllImport ("user32.dll", SetLastError = true)]
private static extern IntPtr WindowFromPoint (POINT pt);
[StructLayout (LayoutKind.Sequential)]
private struct POINT
{
public int x;
public int y;
}
[StructLayout (LayoutKind.Sequential)]
private struct MSLLHOOKSTRUCT
{
public POINT pt;
public uint mouseData;
public uint flags;
public uint time;
public IntPtr dwExtraInfo;
}
public static bool StartHook (IntPtr targetControlHandle)
{
_targetControlHandle = targetControlHandle;
if (_mouseHookHandle != IntPtr.Zero) return false;
_mouseHookProc = MouseHookCallback;
IntPtr moduleHandle = GetModuleHandle (null);
_mouseHookHandle = SetWindowsHookEx (WH_MOUSE_LL, _mouseHookProc, moduleHandle, 0);
return _mouseHookHandle != IntPtr.Zero;
}
public static bool StopHook ()
{
if (_mouseHookHandle == IntPtr.Zero) return true;
bool result = UnhookWindowsHookEx (_mouseHookHandle);
_mouseHookHandle = IntPtr.Zero;
return result;
}
private static IntPtr MouseHookCallback (int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && wParam.ToInt32 () == WM_LBUTTONUP)
{
MSLLHOOKSTRUCT mouseStruct = (MSLLHOOKSTRUCT)Marshal.PtrToStructure (lParam, typeof (MSLLHOOKSTRUCT));
IntPtr clickedHandle = WindowFromPoint (mouseStruct.pt);
if (clickedHandle == _targetControlHandle)
{
Console.WriteLine ("Hook到目标按钮触发事件!开始执行NPC重载...");
ReloadMirServerNpc ();
}
}
return CallNextHookEx (_mouseHookHandle, nCode, wParam, lParam);
}
}
public static void Main (string[] args)
{
IntPtr targetWindow = Win32Api.FindWindow (null, "M2Server");
if (targetWindow == IntPtr.Zero)
{
targetWindow = Win32Api.FindWindow (null, "GameCenter");
}
if (targetWindow != IntPtr.Zero)
{
IntPtr targetControl = Win32Api.FindWindowEx (targetWindow, IntPtr.Zero, "TFormMain", null);
if (targetControl != IntPtr.Zero)
{
bool hookStarted = ButtonHook.StartHook (targetControl);
Console.WriteLine (hookStarted ? "钩子启动成功,等待捕获按钮事件..." : "钩子启动失败");
}
}
ReloadMirServerNpc ();
Console.ReadLine ();
ButtonHook.StopHook ();
}
}


作者: 8657    时间: 2026-1-9 18:05
陪玩个人店铺小程
作者: 叙利亚的咕咕鸡    时间: 2026-1-9 18:57
qf123 发表于 2026-1-9 17:39
[e=0]using System;
using System.Text;
using System.Runtime.InteropServices;

你是问的ai的吗?

在M2Server窗口中未找到TMainmenu控件
找不到那个控件
作者: 叙利亚的咕咕鸡    时间: 2026-1-9 19:02
有没有大佬会传奇 m2 重新加载qmanage,qfunction,npc,数据库的?不用抓内存就点那几个按钮的也行




欢迎光临 精易论坛 (https://bbs.ijingyi.com/) Powered by Discuz! X3.4